Merge branch 'upstream-jeff' of git://git.kernel.org/pub/scm/linux/kernel/git/romieu...
authorJeff Garzik <jeff@garzik.org>
Wed, 24 Oct 2007 00:13:24 +0000 (20:13 -0400)
committerJeff Garzik <jeff@garzik.org>
Wed, 24 Oct 2007 00:13:24 +0000 (20:13 -0400)
2424 files changed:
.gitignore
CREDITS
Documentation/DocBook/Makefile
Documentation/DocBook/kernel-api.tmpl
Documentation/DocBook/mtdnand.tmpl
Documentation/IPMI.txt
Documentation/Intel-IOMMU.txt [new file with mode: 0644]
Documentation/SubmitChecklist
Documentation/SubmittingDrivers
Documentation/accounting/cgroupstats.txt [new file with mode: 0644]
Documentation/arm/Samsung-S3C24XX/DMA.txt
Documentation/atomic_ops.txt
Documentation/cachetlb.txt
Documentation/cdrom/cdrom-standard.tex
Documentation/cgroups.txt [new file with mode: 0644]
Documentation/cpu-hotplug.txt
Documentation/cpusets.txt
Documentation/device-mapper/dm-uevent.txt [new file with mode: 0644]
Documentation/devices.txt
Documentation/driver-model/devres.txt
Documentation/fb/deferred_io.txt
Documentation/feature-removal-schedule.txt
Documentation/filesystems/9p.txt
Documentation/filesystems/Exporting
Documentation/filesystems/Locking
Documentation/filesystems/ext3.txt
Documentation/filesystems/files.txt
Documentation/filesystems/proc.txt
Documentation/filesystems/sysfs.txt
Documentation/filesystems/vfs.txt
Documentation/i2c/i2c-protocol
Documentation/i386/boot.txt
Documentation/ia64/err_inject.txt
Documentation/input/atarikbd.txt
Documentation/input/ff.txt
Documentation/input/iforce-protocol.txt
Documentation/input/input-programming.txt
Documentation/isdn/CREDITS
Documentation/isdn/README.concap
Documentation/java.txt
Documentation/kbuild/kconfig-language.txt
Documentation/kbuild/makefiles.txt
Documentation/kdump/kdump.txt
Documentation/kernel-docs.txt
Documentation/kernel-parameters.txt
Documentation/lguest/Makefile
Documentation/lguest/lguest.c
Documentation/lguest/lguest.txt
Documentation/m68k/kernel-options.txt
Documentation/markers.txt [new file with mode: 0644]
Documentation/memory-barriers.txt
Documentation/memory-hotplug.txt
Documentation/mips/00-INDEX
Documentation/mips/AU1xxx_IDE.README
Documentation/mips/time.README [deleted file]
Documentation/mutex-design.txt
Documentation/networking/bcm43xx.txt
Documentation/networking/ip-sysctl.txt
Documentation/networking/rxrpc.txt
Documentation/networking/udplite.txt
Documentation/parport-lowlevel.txt
Documentation/power/basic-pm-debugging.txt
Documentation/power/freezing-of-tasks.txt
Documentation/power/interface.txt
Documentation/power/swsusp-and-swap-files.txt
Documentation/powerpc/eeh-pci-error-recovery.txt
Documentation/powerpc/mpc52xx-device-tree-bindings.txt
Documentation/scsi/aic79xx.txt
Documentation/scsi/aic7xxx.txt
Documentation/scsi/arcmsr_spec.txt
Documentation/scsi/ibmmca.txt
Documentation/sharedsubtree.txt
Documentation/sound/alsa/soc/DAI.txt
Documentation/sound/alsa/soc/clocking.txt
Documentation/sound/alsa/soc/codec.txt
Documentation/sound/alsa/soc/dapm.txt
Documentation/sound/alsa/soc/overview.txt
Documentation/sound/alsa/soc/platform.txt
Documentation/sound/alsa/soc/pops_clicks.txt
Documentation/sound/oss/es1371 [deleted file]
Documentation/spi/pxa2xx
Documentation/thinkpad-acpi.txt
Documentation/usb/usb-serial.txt
MAINTAINERS
Makefile
arch/alpha/Kconfig
arch/alpha/kernel/err_marvel.c
arch/alpha/kernel/err_titan.c
arch/alpha/kernel/osf_sys.c
arch/alpha/kernel/pci_iommu.c
arch/alpha/kernel/semaphore.c
arch/alpha/kernel/smp.c
arch/alpha/kernel/sys_alcor.c
arch/alpha/kernel/sys_sio.c
arch/alpha/kernel/traps.c
arch/alpha/lib/checksum.c
arch/alpha/lib/csum_partial_copy.c
arch/alpha/lib/fls.c
arch/alpha/mm/fault.c
arch/alpha/mm/init.c
arch/alpha/oprofile/Kconfig [deleted file]
arch/alpha/oprofile/op_impl.h
arch/arm/Kconfig
arch/arm/common/dmabounce.c
arch/arm/common/sharpsl_pm.c
arch/arm/kernel/process.c
arch/arm/kernel/ptrace.c
arch/arm/kernel/traps.c
arch/arm/mach-at91/gpio.c
arch/arm/mach-at91/pm.c
arch/arm/mach-omap1/irq.c
arch/arm/mach-omap1/pm.c
arch/arm/mach-omap2/pm.c
arch/arm/mach-omap2/timer-gp.c
arch/arm/mach-pnx4008/pm.c
arch/arm/mach-pxa/pm.c
arch/arm/mach-pxa/pxa25x.c
arch/arm/mach-pxa/pxa27x.c
arch/arm/mach-s3c2410/clock.c
arch/arm/mach-s3c2412/clock.c
arch/arm/mach-s3c2443/clock.c
arch/arm/mach-sa1100/pm.c
arch/arm/mm/alignment.c
arch/arm/mm/fault.c
arch/arm/nwfpe/fpopcode.h
arch/arm/oprofile/Kconfig [deleted file]
arch/arm/plat-omap/dma.c
arch/arm/plat-omap/gpio.c
arch/arm/plat-s3c24xx/pm.c
arch/avr32/Kconfig
arch/avr32/boards/atstk1000/atstk1002.c
arch/avr32/kernel/traps.c
arch/avr32/mach-at32ap/at32ap7000.c
arch/avr32/mach-at32ap/extint.c
arch/avr32/mach-at32ap/pm.h
arch/avr32/mach-at32ap/time-tc.c
arch/avr32/mm/fault.c
arch/blackfin/Kconfig
arch/blackfin/Makefile
arch/blackfin/boot/Makefile
arch/blackfin/boot/install.sh [new file with mode: 0644]
arch/blackfin/configs/BF527-EZKIT_defconfig [new file with mode: 0644]
arch/blackfin/configs/BF548-EZKIT_defconfig
arch/blackfin/kernel/Makefile
arch/blackfin/kernel/bfin_dma_5xx.c
arch/blackfin/kernel/bfin_gpio.c
arch/blackfin/kernel/dma-mapping.c
arch/blackfin/kernel/gptimers.c [new file with mode: 0644]
arch/blackfin/kernel/reboot.c
arch/blackfin/kernel/setup.c
arch/blackfin/kernel/traps.c
arch/blackfin/lib/Makefile
arch/blackfin/lib/udivdi3.S [new file with mode: 0644]
arch/blackfin/mach-bf527/Kconfig [new file with mode: 0644]
arch/blackfin/mach-bf527/Makefile [new file with mode: 0644]
arch/blackfin/mach-bf527/boards/Makefile [new file with mode: 0644]
arch/blackfin/mach-bf527/boards/eth_mac.c [new file with mode: 0644]
arch/blackfin/mach-bf527/boards/ezkit.c [new file with mode: 0644]
arch/blackfin/mach-bf527/cpu.c [new file with mode: 0644]
arch/blackfin/mach-bf527/dma.c [new file with mode: 0644]
arch/blackfin/mach-bf527/head.S [new file with mode: 0644]
arch/blackfin/mach-bf527/ints-priority.c [new file with mode: 0644]
arch/blackfin/mach-bf533/boards/cm_bf533.c
arch/blackfin/mach-bf533/boards/ezkit.c
arch/blackfin/mach-bf533/boards/generic_board.c
arch/blackfin/mach-bf533/boards/stamp.c
arch/blackfin/mach-bf537/boards/cm_bf537.c
arch/blackfin/mach-bf537/boards/generic_board.c
arch/blackfin/mach-bf537/boards/pnav10.c
arch/blackfin/mach-bf537/boards/stamp.c
arch/blackfin/mach-bf548/boards/ezkit.c
arch/blackfin/mach-bf548/dma.c
arch/blackfin/mach-bf561/boards/cm_bf561.c
arch/blackfin/mach-bf561/boards/ezkit.c
arch/blackfin/mach-bf561/boards/generic_board.c
arch/blackfin/mach-bf561/boards/tepla.c
arch/blackfin/mach-common/ints-priority-dc.c
arch/blackfin/mach-common/ints-priority-sc.c
arch/blackfin/mach-common/pm.c
arch/blackfin/oprofile/Kconfig [deleted file]
arch/cris/Kconfig
arch/cris/arch-v10/Kconfig
arch/cris/arch-v10/boot/compressed/misc.c
arch/cris/arch-v10/drivers/pcf8563.c
arch/cris/arch-v10/kernel/debugport.c
arch/cris/arch-v10/kernel/entry.S
arch/cris/arch-v10/kernel/fasttimer.c
arch/cris/arch-v10/kernel/irq.c
arch/cris/arch-v10/kernel/kgdb.c
arch/cris/arch-v10/kernel/process.c
arch/cris/arch-v10/kernel/shadows.c
arch/cris/arch-v10/lib/dram_init.S
arch/cris/arch-v10/lib/string.c
arch/cris/arch-v10/lib/usercopy.c
arch/cris/arch-v32/boot/compressed/misc.c
arch/cris/arch-v32/drivers/axisflashmap.c
arch/cris/arch-v32/drivers/i2c.c
arch/cris/arch-v32/drivers/nandflash.c
arch/cris/arch-v32/drivers/pcf8563.c
arch/cris/arch-v32/kernel/fasttimer.c
arch/cris/arch-v32/kernel/irq.c
arch/cris/arch-v32/kernel/process.c
arch/cris/arch-v32/kernel/signal.c
arch/cris/arch-v32/kernel/smp.c
arch/cris/arch-v32/kernel/time.c
arch/cris/arch-v32/kernel/traps.c
arch/cris/arch-v32/lib/dram_init.S
arch/cris/arch-v32/lib/string.c
arch/cris/arch-v32/lib/usercopy.c
arch/cris/arch-v32/mm/tlb.c
arch/cris/kernel/irq.c
arch/cris/mm/fault.c
arch/cris/mm/init.c
arch/cris/mm/tlb.c
arch/frv/Kconfig
arch/frv/kernel/irq-mb93091.c
arch/frv/kernel/irq-mb93093.c
arch/frv/kernel/irq-mb93493.c
arch/frv/kernel/irq.c
arch/frv/kernel/semaphore.c
arch/frv/kernel/time.c
arch/h8300/Kconfig
arch/h8300/Kconfig.debug
arch/h8300/kernel/irq.c
arch/h8300/kernel/time.c
arch/h8300/kernel/traps.c
arch/h8300/platform/h8s/ints.c
arch/h8300/platform/h8s/ints_h8s.c
arch/i386/Kconfig
arch/i386/Makefile
arch/ia64/Kconfig
arch/ia64/configs/sn2_defconfig
arch/ia64/hp/common/sba_iommu.c
arch/ia64/hp/sim/simscsi.c
arch/ia64/ia32/sys_ia32.c
arch/ia64/kernel/efi.c
arch/ia64/kernel/perfmon.c
arch/ia64/kernel/perfmon_default_smpl.c
arch/ia64/kernel/process.c
arch/ia64/kernel/setup.c
arch/ia64/kernel/signal.c
arch/ia64/kernel/time.c
arch/ia64/kernel/traps.c
arch/ia64/kernel/unaligned.c
arch/ia64/mm/fault.c
arch/ia64/mm/init.c
arch/ia64/oprofile/Kconfig [deleted file]
arch/ia64/sn/kernel/xpnet.c
arch/ia64/sn/pci/pci_dma.c
arch/m32r/Kconfig
arch/m32r/kernel/irq.c
arch/m32r/kernel/signal.c
arch/m32r/kernel/smp.c
arch/m32r/kernel/smpboot.c
arch/m32r/kernel/sys_m32r.c
arch/m32r/kernel/traps.c
arch/m32r/mm/fault.c
arch/m32r/oprofile/Kconfig [deleted file]
arch/m68k/Kconfig
arch/m68k/amiga/pcmcia.c
arch/m68k/ifpsp060/CHANGES
arch/m68k/ifpsp060/MISC
arch/m68k/ifpsp060/README
arch/m68k/ifpsp060/TEST.DOC
arch/m68k/ifpsp060/fplsp.doc
arch/m68k/ifpsp060/fpsp.doc
arch/m68k/ifpsp060/fskeleton.S
arch/m68k/ifpsp060/ilsp.doc
arch/m68k/ifpsp060/iskeleton.S
arch/m68k/ifpsp060/isp.doc
arch/m68k/ifpsp060/os.S
arch/m68k/ifpsp060/src/fplsp.S
arch/m68k/ifpsp060/src/fpsp.S
arch/m68k/ifpsp060/src/ftest.S
arch/m68k/ifpsp060/src/ilsp.S
arch/m68k/ifpsp060/src/isp.S
arch/m68k/ifpsp060/src/itest.S
arch/m68k/ifpsp060/src/pfpsp.S
arch/m68k/kernel/dma.c
arch/m68k/kernel/traps.c
arch/m68k/mac/config.c
arch/m68k/mac/iop.c
arch/m68k/mac/oss.c
arch/m68k/mac/via.c
arch/m68k/math-emu/fp_log.c
arch/m68k/mm/fault.c
arch/m68k/q40/q40ints.c
arch/m68k/sun3/mmu_emu.c
arch/m68k/tools/amiga/dmesg.c
arch/m68knommu/Kconfig
arch/m68knommu/Makefile
arch/m68knommu/defconfig
arch/m68knommu/kernel/setup.c
arch/m68knommu/kernel/signal.c
arch/m68knommu/kernel/time.c
arch/m68knommu/platform/5206/config.c
arch/m68knommu/platform/5206e/config.c
arch/m68knommu/platform/520x/config.c
arch/m68knommu/platform/523x/config.c
arch/m68knommu/platform/5249/config.c
arch/m68knommu/platform/5272/config.c
arch/m68knommu/platform/527x/config.c
arch/m68knommu/platform/528x/config.c
arch/m68knommu/platform/5307/config.c
arch/m68knommu/platform/5307/entry.S
arch/m68knommu/platform/5307/pit.c
arch/m68knommu/platform/5307/timers.c
arch/m68knommu/platform/532x/config.c
arch/m68knommu/platform/5407/config.c
arch/mips/Kconfig
arch/mips/Kconfig.debug
arch/mips/Makefile
arch/mips/au1000/Kconfig
arch/mips/au1000/pb1200/irqmap.c
arch/mips/basler/excite/excite_irq.c
arch/mips/bcm47xx/time.c
arch/mips/cobalt/Makefile
arch/mips/cobalt/setup.c
arch/mips/cobalt/time.c [new file with mode: 0644]
arch/mips/configs/ip27_defconfig
arch/mips/configs/mipssim_defconfig
arch/mips/configs/sb1250-swarm_defconfig
arch/mips/emma2rh/markeins/setup.c
arch/mips/jazz/irq.c
arch/mips/jazz/setup.c
arch/mips/jmr3927/rbhma3100/setup.c
arch/mips/kernel/Makefile
arch/mips/kernel/cevt-gt641xx.c [new file with mode: 0644]
arch/mips/kernel/cevt-r4k.c [new file with mode: 0644]
arch/mips/kernel/head.S
arch/mips/kernel/irixelf.c
arch/mips/kernel/irixsig.c
arch/mips/kernel/module.c
arch/mips/kernel/sysirix.c
arch/mips/kernel/time.c
arch/mips/kernel/traps.c
arch/mips/lemote/lm2e/setup.c
arch/mips/mips-boards/generic/time.c
arch/mips/mm/dma-default.c
arch/mips/mm/fault.c
arch/mips/oprofile/Kconfig [deleted file]
arch/mips/pci/pci-excite.c
arch/mips/pmc-sierra/Kconfig
arch/mips/pmc-sierra/msp71xx/msp_time.c
arch/mips/pmc-sierra/yosemite/setup.c
arch/mips/sgi-ip27/ip27-init.c
arch/mips/sgi-ip27/ip27-irq.c
arch/mips/sgi-ip27/ip27-timer.c
arch/mips/sgi-ip32/ip32-setup.c
arch/mips/sibyte/bcm1480/irq.c
arch/mips/sibyte/bcm1480/smp.c
arch/mips/sibyte/bcm1480/time.c
arch/mips/sibyte/sb1250/irq.c
arch/mips/sibyte/sb1250/smp.c
arch/mips/sibyte/sb1250/time.c
arch/mips/sibyte/swarm/setup.c
arch/mips/sni/pcimt.c
arch/mips/sni/time.c
arch/mips/tx4927/common/tx4927_setup.c
arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
arch/mips/tx4938/common/setup.c
arch/mips/vr41xx/Kconfig
arch/mips/vr41xx/common/init.c
arch/parisc/Kconfig
arch/parisc/Makefile
arch/parisc/configs/712_defconfig
arch/parisc/configs/a500_defconfig
arch/parisc/configs/b180_defconfig
arch/parisc/configs/c3000_defconfig
arch/parisc/defconfig
arch/parisc/hpux/gate.S
arch/parisc/kernel/asm-offsets.c
arch/parisc/kernel/entry.S
arch/parisc/kernel/head.S
arch/parisc/kernel/hpmc.S
arch/parisc/kernel/init_task.c
arch/parisc/kernel/pacache.S
arch/parisc/kernel/parisc_ksyms.c
arch/parisc/kernel/pci-dma.c
arch/parisc/kernel/pci.c
arch/parisc/kernel/processor.c
arch/parisc/kernel/signal.c
arch/parisc/kernel/smp.c
arch/parisc/kernel/sys_parisc32.c
arch/parisc/kernel/syscall.S
arch/parisc/kernel/syscall_table.S
arch/parisc/kernel/time.c
arch/parisc/kernel/traps.c
arch/parisc/kernel/unaligned.c
arch/parisc/kernel/unwind.c
arch/parisc/kernel/vmlinux.lds.S
arch/parisc/lib/Makefile
arch/parisc/lib/libgcc/Makefile [new file with mode: 0644]
arch/parisc/lib/libgcc/__ashldi3.c [new file with mode: 0644]
arch/parisc/lib/libgcc/__ashrdi3.c [new file with mode: 0644]
arch/parisc/lib/libgcc/__clzsi2.c [new file with mode: 0644]
arch/parisc/lib/libgcc/__divdi3.c [new file with mode: 0644]
arch/parisc/lib/libgcc/__divsi3.c [new file with mode: 0644]
arch/parisc/lib/libgcc/__lshrdi3.c [new file with mode: 0644]
arch/parisc/lib/libgcc/__moddi3.c [new file with mode: 0644]
arch/parisc/lib/libgcc/__modsi3.c [new file with mode: 0644]
arch/parisc/lib/libgcc/__muldi3.c [new file with mode: 0644]
arch/parisc/lib/libgcc/__udivdi3.c [new file with mode: 0644]
arch/parisc/lib/libgcc/__udivmoddi4.c [new file with mode: 0644]
arch/parisc/lib/libgcc/__udivmodsi4.c [new file with mode: 0644]
arch/parisc/lib/libgcc/__udivsi3.c [new file with mode: 0644]
arch/parisc/lib/libgcc/__umoddi3.c [new file with mode: 0644]
arch/parisc/lib/libgcc/__umodsi3.c [new file with mode: 0644]
arch/parisc/lib/libgcc/__umulsidi3.c [new file with mode: 0644]
arch/parisc/lib/libgcc/libgcc.h [new file with mode: 0644]
arch/parisc/lib/memcpy.c
arch/parisc/lib/milli/Makefile [new file with mode: 0644]
arch/parisc/lib/milli/divI.S [new file with mode: 0644]
arch/parisc/lib/milli/divU.S [new file with mode: 0644]
arch/parisc/lib/milli/div_const.S [new file with mode: 0644]
arch/parisc/lib/milli/dyncall.S [new file with mode: 0644]
arch/parisc/lib/milli/milli.S [new file with mode: 0644]
arch/parisc/lib/milli/milli.h [new file with mode: 0644]
arch/parisc/lib/milli/mulI.S [new file with mode: 0644]
arch/parisc/lib/milli/remI.S [new file with mode: 0644]
arch/parisc/lib/milli/remU.S [new file with mode: 0644]
arch/parisc/mm/fault.c
arch/parisc/mm/init.c
arch/parisc/oprofile/Kconfig [deleted file]
arch/powerpc/Kconfig
arch/powerpc/Kconfig.debug
arch/powerpc/boot/dts/bamboo.dts
arch/powerpc/boot/dts/lite5200.dts
arch/powerpc/boot/dts/lite5200b.dts
arch/powerpc/boot/dts/sequoia.dts
arch/powerpc/boot/dts/walnut.dts
arch/powerpc/boot/treeboot-walnut.c
arch/powerpc/configs/bamboo_defconfig
arch/powerpc/configs/cell_defconfig
arch/powerpc/configs/ebony_defconfig
arch/powerpc/configs/pmac32_defconfig
arch/powerpc/configs/ppc64_defconfig
arch/powerpc/configs/pseries_defconfig
arch/powerpc/configs/walnut_defconfig
arch/powerpc/kernel/asm-offsets.c
arch/powerpc/kernel/cpu_setup_6xx.S
arch/powerpc/kernel/dma_64.c
arch/powerpc/kernel/ibmebus.c
arch/powerpc/kernel/iommu.c
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/l2cr_6xx.S
arch/powerpc/kernel/machine_kexec.c
arch/powerpc/kernel/process.c
arch/powerpc/kernel/time.c
arch/powerpc/kernel/traps.c
arch/powerpc/mm/fault.c
arch/powerpc/oprofile/Kconfig [deleted file]
arch/powerpc/platforms/40x/Kconfig
arch/powerpc/platforms/44x/Kconfig
arch/powerpc/platforms/52xx/lite5200.c
arch/powerpc/platforms/52xx/lite5200_pm.c
arch/powerpc/platforms/52xx/mpc52xx_common.c
arch/powerpc/platforms/52xx/mpc52xx_pm.c
arch/powerpc/platforms/Kconfig
arch/powerpc/platforms/Kconfig.cputype
arch/powerpc/platforms/cell/spufs/file.c
arch/powerpc/platforms/celleb/scc_uhc.c
arch/powerpc/platforms/maple/setup.c
arch/powerpc/platforms/ps3/system-bus.c
arch/powerpc/platforms/pseries/ras.c
arch/powerpc/sysdev/bestcomm/bestcomm.c
arch/ppc/Kconfig
arch/ppc/boot/Makefile
arch/ppc/kernel/traps.c
arch/ppc/mm/fault.c
arch/ppc/platforms/chestnut.c
arch/s390/Kconfig
arch/s390/defconfig
arch/s390/kernel/ipl.c
arch/s390/kernel/process.c
arch/s390/kernel/smp.c
arch/s390/lib/uaccess_pt.c
arch/s390/mm/Makefile
arch/s390/mm/fault.c
arch/s390/mm/init.c
arch/s390/mm/pgtable.c [new file with mode: 0644]
arch/s390/mm/vmem.c
arch/s390/oprofile/Kconfig [deleted file]
arch/sh/Kconfig
arch/sh/boards/hp6xx/pm.c
arch/sh/kernel/machine_kexec.c
arch/sh/kernel/process.c
arch/sh/kernel/setup.c
arch/sh/kernel/signal.c
arch/sh/kernel/traps.c
arch/sh/mm/fault.c
arch/sh/oprofile/Kconfig [deleted file]
arch/sh64/Kconfig
arch/sh64/kernel/pci_sh5.c
arch/sh64/kernel/traps.c
arch/sh64/mm/fault.c
arch/sh64/oprofile/Kconfig [deleted file]
arch/sparc/Kconfig
arch/sparc/kernel/ioport.c
arch/sparc/kernel/of_device.c
arch/sparc/kernel/ptrace.c
arch/sparc/kernel/sys_sparc.c
arch/sparc/kernel/sys_sunos.c
arch/sparc/kernel/traps.c
arch/sparc/mm/io-unit.c
arch/sparc/mm/iommu.c
arch/sparc/mm/sun4c.c
arch/sparc/oprofile/Kconfig [deleted file]
arch/sparc64/Kconfig
arch/sparc64/Makefile
arch/sparc64/defconfig
arch/sparc64/kernel/Makefile
arch/sparc64/kernel/iommu.c
arch/sparc64/kernel/iommu_common.c
arch/sparc64/kernel/irq.c
arch/sparc64/kernel/ldc.c
arch/sparc64/kernel/of_device.c
arch/sparc64/kernel/pci.c
arch/sparc64/kernel/pci_common.c
arch/sparc64/kernel/pci_msi.c
arch/sparc64/kernel/pci_sun4v.c
arch/sparc64/kernel/sys_sunos32.c
arch/sparc64/kernel/traps.c
arch/sparc64/lib/atomic.S
arch/sparc64/lib/bitops.S
arch/sparc64/math-emu/Makefile
arch/sparc64/oprofile/Kconfig [deleted file]
arch/sparc64/solaris/misc.c
arch/um/Kconfig
arch/um/drivers/line.c
arch/um/drivers/null.c
arch/um/drivers/slip_kern.c
arch/um/drivers/slirp_kern.c
arch/um/drivers/stderr_console.c
arch/um/drivers/ubd_kern.c
arch/um/kernel/gmon_syms.c
arch/um/kernel/irq.c
arch/um/kernel/ptrace.c
arch/um/kernel/trap.c
arch/um/sys-i386/bug.c
arch/um/sys-i386/tls.c
arch/um/sys-x86_64/bug.c
arch/um/sys-x86_64/sysrq.c
arch/v850/Kconfig
arch/v850/kernel/me2.c
arch/v850/kernel/rte_mb_a_pci.c
arch/x86/boot/compressed/head_32.S
arch/x86/boot/compressed/misc_32.c
arch/x86/boot/compressed/misc_64.c
arch/x86/boot/header.S
arch/x86/ia32/ia32_binfmt.c
arch/x86/kernel/Makefile_32
arch/x86/kernel/Makefile_64
arch/x86/kernel/acpi/Makefile_32
arch/x86/kernel/acpi/boot.c
arch/x86/kernel/acpi/cstate.c
arch/x86/kernel/acpi/earlyquirk_32.c [deleted file]
arch/x86/kernel/acpi/processor.c
arch/x86/kernel/acpi/wakeup_32.S
arch/x86/kernel/acpi/wakeup_64.S
arch/x86/kernel/alternative.c
arch/x86/kernel/apic_32.c
arch/x86/kernel/apm_32.c
arch/x86/kernel/asm-offsets_32.c
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/centaur.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/cpu/cpufreq/Kconfig_32 [moved from arch/x86/kernel/cpu/cpufreq/Kconfig with 100% similarity]
arch/x86/kernel/cpu/cpufreq/Kconfig_64 [moved from arch/x86/kernel/cpufreq/Kconfig with 97% similarity]
arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c
arch/x86/kernel/cpu/cpufreq/e_powersaver.c
arch/x86/kernel/cpu/cpufreq/elanfreq.c
arch/x86/kernel/cpu/cpufreq/gx-suspmod.c
arch/x86/kernel/cpu/cpufreq/longhaul.c
arch/x86/kernel/cpu/cpufreq/longrun.c
arch/x86/kernel/cpu/cpufreq/p4-clockmod.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/powernow-k8.h
arch/x86/kernel/cpu/cpufreq/sc520_freq.c
arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
arch/x86/kernel/cpu/cyrix.c
arch/x86/kernel/cpu/intel_cacheinfo.c
arch/x86/kernel/cpu/mcheck/therm_throt.c
arch/x86/kernel/cpu/mtrr/cyrix.c
arch/x86/kernel/cpu/mtrr/generic.c
arch/x86/kernel/cpu/mtrr/main.c
arch/x86/kernel/cpu/perfctr-watchdog.c
arch/x86/kernel/cpu/proc.c
arch/x86/kernel/cpuid.c
arch/x86/kernel/crash_dump_32.c
arch/x86/kernel/e820_32.c
arch/x86/kernel/e820_64.c
arch/x86/kernel/early-quirks.c [moved from arch/x86/kernel/early-quirks_64.c with 88% similarity]
arch/x86/kernel/efi_32.c
arch/x86/kernel/genapic_64.c
arch/x86/kernel/genapic_flat_64.c
arch/x86/kernel/head64.c
arch/x86/kernel/head_32.S
arch/x86/kernel/hpet.c
arch/x86/kernel/i8253.c
arch/x86/kernel/i8259_32.c
arch/x86/kernel/init_task.c [moved from arch/x86/kernel/init_task_32.c with 79% similarity]
arch/x86/kernel/init_task_64.c [deleted file]
arch/x86/kernel/io_apic_32.c
arch/x86/kernel/io_apic_64.c
arch/x86/kernel/machine_kexec_32.c
arch/x86/kernel/machine_kexec_64.c
arch/x86/kernel/mce_64.c
arch/x86/kernel/mce_amd_64.c
arch/x86/kernel/microcode.c
arch/x86/kernel/mpparse_32.c
arch/x86/kernel/mpparse_64.c
arch/x86/kernel/msr.c
arch/x86/kernel/pci-calgary_64.c
arch/x86/kernel/pci-dma_64.c
arch/x86/kernel/pci-gart_64.c
arch/x86/kernel/pci-nommu_64.c
arch/x86/kernel/process_32.c
arch/x86/kernel/ptrace_32.c
arch/x86/kernel/quirks.c
arch/x86/kernel/reboot_64.c
arch/x86/kernel/reboot_fixups_32.c
arch/x86/kernel/setup64.c
arch/x86/kernel/setup_32.c
arch/x86/kernel/setup_64.c
arch/x86/kernel/signal_32.c
arch/x86/kernel/signal_64.c
arch/x86/kernel/smp_32.c
arch/x86/kernel/smp_64.c
arch/x86/kernel/smpboot_32.c
arch/x86/kernel/smpboot_64.c
arch/x86/kernel/summit_32.c
arch/x86/kernel/suspend_64.c
arch/x86/kernel/suspend_asm_64.S
arch/x86/kernel/traps_32.c
arch/x86/kernel/traps_64.c
arch/x86/kernel/tsc_32.c
arch/x86/kernel/tsc_64.c
arch/x86/kernel/vsyscall_64.c
arch/x86/lguest/Kconfig [new file with mode: 0644]
arch/x86/lguest/Makefile [new file with mode: 0644]
arch/x86/lguest/boot.c [moved from drivers/lguest/lguest.c with 93% similarity]
arch/x86/lguest/i386_head.S [moved from drivers/lguest/lguest_asm.S with 73% similarity]
arch/x86/lib/delay_32.c
arch/x86/lib/delay_64.c
arch/x86/lib/usercopy_32.c
arch/x86/mach-default/setup.c
arch/x86/mach-generic/default.c
arch/x86/mach-generic/probe.c
arch/x86/mach-voyager/voyager_smp.c
arch/x86/mach-voyager/voyager_thread.c
arch/x86/mm/boot_ioremap_32.c
arch/x86/mm/discontig_32.c
arch/x86/mm/fault_32.c
arch/x86/mm/fault_64.c
arch/x86/mm/numa_64.c
arch/x86/mm/pageattr_64.c
arch/x86/mm/srat_64.c
arch/x86/oprofile/backtrace.c
arch/x86/oprofile/op_x86_model.h
arch/x86/pci/irq.c
arch/x86/xen/Kconfig
arch/x86_64/.gitignore [new file with mode: 0644]
arch/x86_64/Kconfig
arch/x86_64/Makefile
arch/xtensa/Kconfig
arch/xtensa/boot/Makefile
arch/xtensa/kernel/traps.c
arch/xtensa/mm/fault.c
arch/xtensa/platform-iss/network.c
block/elevator.c
block/ll_rw_blk.c
crypto/api.c
crypto/digest.c
crypto/fcrypt.c
crypto/hmac.c
crypto/scatterwalk.c
crypto/scatterwalk.h
crypto/tcrypt.c
crypto/xcbc.c
drivers/Kconfig
drivers/Makefile
drivers/acpi/Kconfig
drivers/acpi/Makefile
drivers/acpi/ac.c
drivers/acpi/battery.c
drivers/acpi/bus.c
drivers/acpi/button.c
drivers/acpi/ec.c
drivers/acpi/events/evevent.c
drivers/acpi/hardware/hwregs.c
drivers/acpi/hardware/hwsleep.c
drivers/acpi/osl.c
drivers/acpi/processor_core.c
drivers/acpi/processor_idle.c
drivers/acpi/sbs.c
drivers/acpi/sbshc.c [new file with mode: 0644]
drivers/acpi/sbshc.h [new file with mode: 0644]
drivers/acpi/sleep/main.c
drivers/acpi/sleep/sleep.h
drivers/acpi/sleep/wakeup.c
drivers/acpi/tables/tbutils.c
drivers/acpi/thermal.c
drivers/acpi/video.c
drivers/ata/Kconfig
drivers/ata/Makefile
drivers/ata/ahci.c
drivers/ata/libata-core.c
drivers/ata/libata-scsi.c
drivers/ata/libata-sff.c
drivers/ata/pata_acpi.c
drivers/ata/pata_bf54x.c
drivers/ata/pata_cmd64x.c
drivers/ata/pata_cs5530.c
drivers/ata/pata_cs5535.c
drivers/ata/pata_cs5536.c
drivers/ata/pata_it821x.c
drivers/ata/pata_mpiix.c
drivers/ata/pata_ns87410.c
drivers/ata/pata_oldpiix.c
drivers/ata/pata_radisys.c
drivers/ata/pata_sc1200.c
drivers/ata/pata_sil680.c
drivers/ata/pata_via.c
drivers/ata/pdc_adma.c
drivers/ata/sata_fsl.c [new file with mode: 0644]
drivers/ata/sata_mv.c
drivers/ata/sata_sil24.c
drivers/ata/sata_sis.c
drivers/atm/firestream.c
drivers/base/dmapool.c
drivers/base/memory.c
drivers/base/power/trace.c
drivers/base/topology.c
drivers/block/DAC960.c
drivers/block/Kconfig
drivers/block/Makefile
drivers/block/cciss.c
drivers/block/cpqarray.c
drivers/block/cryptoloop.c
drivers/block/lguest_blk.c [deleted file]
drivers/block/loop.c
drivers/block/nbd.c
drivers/block/rd.c
drivers/block/sunvdc.c
drivers/block/sx8.c
drivers/block/ub.c
drivers/block/viodasd.c
drivers/block/virtio_blk.c [new file with mode: 0644]
drivers/block/xsysace.c
drivers/bluetooth/Kconfig
drivers/bluetooth/Makefile
drivers/bluetooth/bluecard_cs.c
drivers/bluetooth/bpa10x.c
drivers/bluetooth/bt3c_cs.c
drivers/bluetooth/btsdio.c [new file with mode: 0644]
drivers/bluetooth/btuart_cs.c
drivers/bluetooth/btusb.c [new file with mode: 0644]
drivers/bluetooth/dtl1_cs.c
drivers/bluetooth/hci_bcsp.c
drivers/bluetooth/hci_ldisc.c
drivers/bluetooth/hci_ll.c [new file with mode: 0644]
drivers/bluetooth/hci_uart.h
drivers/cdrom/cdrom.c
drivers/char/Kconfig
drivers/char/Makefile
drivers/char/apm-emulation.c
drivers/char/cyclades.c
drivers/char/drm/drm_bufs.c
drivers/char/drm/drm_drv.c
drivers/char/drm/drm_fops.c
drivers/char/drm/drm_hashtab.c
drivers/char/drm/drm_hashtab.h
drivers/char/drm/drm_lock.c
drivers/char/drm/drm_mm.c
drivers/char/drm/drm_os_linux.h
drivers/char/drm/drm_pci.c
drivers/char/drm/drm_sarea.h
drivers/char/drm/drm_sman.c
drivers/char/drm/drm_sman.h
drivers/char/drm/i810_dma.c
drivers/char/drm/i830_dma.c
drivers/char/drm/r128_drv.h
drivers/char/drm/radeon_irq.c
drivers/char/drm/radeon_state.c
drivers/char/drm/sis_mm.c
drivers/char/drm/via_mm.c
drivers/char/drm/via_verifier.h
drivers/char/esp.c
drivers/char/hvc_lguest.c [deleted file]
drivers/char/hw_random/omap-rng.c
drivers/char/i8k.c
drivers/char/ipmi/ipmi_msghandler.c
drivers/char/ipmi/ipmi_si_intf.c
drivers/char/ipmi/ipmi_watchdog.c
drivers/char/isicom.c
drivers/char/keyboard.c
drivers/char/moxa.c
drivers/char/mxser.c
drivers/char/mxser_new.c
drivers/char/n_tty.c
drivers/char/pty.c
drivers/char/random.c
drivers/char/rocket.c
drivers/char/rocket_int.h
drivers/char/sonypi.c
drivers/char/sx.c
drivers/char/sysrq.c
drivers/char/tty_io.c
drivers/char/tty_ioctl.c
drivers/char/virtio_console.c [new file with mode: 0644]
drivers/char/vt.c
drivers/cpuidle/Kconfig [new file with mode: 0644]
drivers/cpuidle/Makefile [new file with mode: 0644]
drivers/cpuidle/cpuidle.c [new file with mode: 0644]
drivers/cpuidle/cpuidle.h [new file with mode: 0644]
drivers/cpuidle/driver.c [new file with mode: 0644]
drivers/cpuidle/governor.c [new file with mode: 0644]
drivers/cpuidle/governors/Makefile [new file with mode: 0644]
drivers/cpuidle/governors/ladder.c [new file with mode: 0644]
drivers/cpuidle/governors/menu.c [new file with mode: 0644]
drivers/cpuidle/sysfs.c [new file with mode: 0644]
drivers/dma/ioat.c
drivers/dma/ioat_dca.c
drivers/dma/ioat_dma.c
drivers/dma/ioatdma.h
drivers/edac/edac_core.h
drivers/edac/pasemi_edac.c
drivers/firewire/fw-ohci.c
drivers/firewire/fw-transaction.c
drivers/firmware/dcdbas.h
drivers/hid/hidraw.c
drivers/hid/usbhid/hid-ff.c
drivers/hid/usbhid/usbkbd.c
drivers/hid/usbhid/usbmouse.c
drivers/hwmon/adm1026.c
drivers/hwmon/applesmc.c
drivers/hwmon/coretemp.c
drivers/hwmon/gl520sm.c
drivers/hwmon/hdaps.c
drivers/hwmon/hwmon-vid.c
drivers/hwmon/lm63.c
drivers/hwmon/sis5595.c
drivers/hwmon/via686a.c
drivers/hwmon/vt1211.c
drivers/hwmon/w83791d.c
drivers/hwmon/w83792d.c
drivers/i2c/algos/i2c-algo-bit.c
drivers/i2c/algos/i2c-algo-pca.c
drivers/i2c/algos/i2c-algo-pcf.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/i2c-elektor.c
drivers/i2c/busses/i2c-hydra.c
drivers/i2c/busses/i2c-ibm_iic.c
drivers/i2c/busses/i2c-omap.c
drivers/i2c/busses/i2c-parport-light.c
drivers/i2c/busses/i2c-parport.c
drivers/i2c/busses/i2c-pmcmsp.c
drivers/i2c/busses/i2c-pnx.c
drivers/i2c/busses/i2c-pxa.c
drivers/i2c/busses/i2c-via.c
drivers/i2c/busses/i2c-viapro.c
drivers/i2c/chips/menelaus.c
drivers/i2c/i2c-core.c
drivers/ide/Kconfig
drivers/ide/arm/bast-ide.c
drivers/ide/arm/icside.c
drivers/ide/arm/ide_arm.c
drivers/ide/arm/rapide.c
drivers/ide/cris/ide-cris.c
drivers/ide/h8300/ide-h8300.c
drivers/ide/ide-acpi.c
drivers/ide/ide-cd.c
drivers/ide/ide-disk.c
drivers/ide/ide-dma.c
drivers/ide/ide-io.c
drivers/ide/ide-iops.c
drivers/ide/ide-pnp.c
drivers/ide/ide-probe.c
drivers/ide/ide-proc.c
drivers/ide/ide-tape.c
drivers/ide/ide-taskfile.c
drivers/ide/ide.c
drivers/ide/legacy/ali14xx.c
drivers/ide/legacy/buddha.c
drivers/ide/legacy/dtc2278.c
drivers/ide/legacy/falconide.c
drivers/ide/legacy/gayle.c
drivers/ide/legacy/ht6560b.c
drivers/ide/legacy/ide-cs.c
drivers/ide/legacy/ide_platform.c
drivers/ide/legacy/macide.c
drivers/ide/legacy/q40ide.c
drivers/ide/legacy/qd65xx.c
drivers/ide/legacy/umc8672.c
drivers/ide/mips/au1xxx-ide.c
drivers/ide/mips/swarm.c
drivers/ide/pci/aec62xx.c
drivers/ide/pci/alim15x3.c
drivers/ide/pci/amd74xx.c
drivers/ide/pci/atiixp.c
drivers/ide/pci/cmd640.c
drivers/ide/pci/cmd64x.c
drivers/ide/pci/cs5520.c
drivers/ide/pci/cs5530.c
drivers/ide/pci/cs5535.c
drivers/ide/pci/cy82c693.c
drivers/ide/pci/delkin_cb.c
drivers/ide/pci/generic.c
drivers/ide/pci/hpt34x.c
drivers/ide/pci/hpt366.c
drivers/ide/pci/it8213.c
drivers/ide/pci/it821x.c
drivers/ide/pci/jmicron.c
drivers/ide/pci/ns87415.c
drivers/ide/pci/opti621.c
drivers/ide/pci/pdc202xx_new.c
drivers/ide/pci/pdc202xx_old.c
drivers/ide/pci/piix.c
drivers/ide/pci/rz1000.c
drivers/ide/pci/sc1200.c
drivers/ide/pci/scc_pata.c
drivers/ide/pci/serverworks.c
drivers/ide/pci/sgiioc4.c
drivers/ide/pci/siimage.c
drivers/ide/pci/sis5513.c
drivers/ide/pci/sl82c105.c
drivers/ide/pci/slc90e66.c
drivers/ide/pci/tc86c001.c
drivers/ide/pci/triflex.c
drivers/ide/pci/trm290.c
drivers/ide/pci/via82cxxx.c
drivers/ide/ppc/mpc8xx.c
drivers/ide/ppc/pmac.c
drivers/ide/setup-pci.c
drivers/ieee1394/dma.c
drivers/ieee1394/sbp2.c
drivers/infiniband/core/cma.c
drivers/infiniband/core/umem.c
drivers/infiniband/core/uverbs_cmd.c
drivers/infiniband/hw/ehca/ehca_classes.h
drivers/infiniband/hw/ehca/ehca_hca.c
drivers/infiniband/hw/ehca/ehca_main.c
drivers/infiniband/hw/ehca/ehca_mrmw.c
drivers/infiniband/hw/ehca/ehca_qp.c
drivers/infiniband/hw/ipath/ipath_dma.c
drivers/infiniband/hw/ipath/ipath_mr.c
drivers/infiniband/hw/mlx4/qp.c
drivers/infiniband/hw/mthca/mthca_cq.c
drivers/infiniband/hw/mthca/mthca_doorbell.h
drivers/infiniband/hw/mthca/mthca_eq.c
drivers/infiniband/hw/mthca/mthca_memfree.c
drivers/infiniband/hw/mthca/mthca_qp.c
drivers/infiniband/hw/mthca/mthca_srq.c
drivers/infiniband/ulp/ipoib/ipoib.h
drivers/infiniband/ulp/ipoib/ipoib_cm.c
drivers/infiniband/ulp/ipoib/ipoib_ib.c
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/infiniband/ulp/iser/iser_memory.c
drivers/input/evdev.c
drivers/input/fixp-arith.h
drivers/input/gameport/gameport.c
drivers/input/input.c
drivers/input/joydev.c
drivers/input/joystick/a3d.c
drivers/input/joystick/adi.c
drivers/input/joystick/amijoy.c
drivers/input/joystick/analog.c
drivers/input/joystick/cobra.c
drivers/input/joystick/db9.c
drivers/input/joystick/gamecon.c
drivers/input/joystick/gf2k.c
drivers/input/joystick/grip.c
drivers/input/joystick/grip_mp.c
drivers/input/joystick/guillemot.c
drivers/input/joystick/iforce/Makefile
drivers/input/joystick/iforce/iforce-main.c
drivers/input/joystick/iforce/iforce.h
drivers/input/joystick/interact.c
drivers/input/joystick/magellan.c
drivers/input/joystick/sidewinder.c
drivers/input/joystick/spaceball.c
drivers/input/joystick/spaceorb.c
drivers/input/joystick/stinger.c
drivers/input/joystick/tmdc.c
drivers/input/joystick/turbografx.c
drivers/input/joystick/twidjoy.c
drivers/input/joystick/warrior.c
drivers/input/joystick/xpad.c
drivers/input/keyboard/aaed2000_kbd.c
drivers/input/keyboard/amikbd.c
drivers/input/keyboard/atakbd.c
drivers/input/keyboard/atkbd.c
drivers/input/keyboard/bf54x-keys.c
drivers/input/keyboard/corgikbd.c
drivers/input/keyboard/gpio_keys.c
drivers/input/keyboard/hil_kbd.c
drivers/input/keyboard/hilkbd.c
drivers/input/keyboard/locomokbd.c
drivers/input/keyboard/newtonkbd.c
drivers/input/keyboard/omap-keypad.c
drivers/input/keyboard/pxa27x_keyboard.c
drivers/input/keyboard/spitzkbd.c
drivers/input/keyboard/stowaway.c
drivers/input/keyboard/sunkbd.c
drivers/input/keyboard/xtkbd.c
drivers/input/misc/Kconfig
drivers/input/misc/ati_remote.c
drivers/input/misc/ati_remote2.c
drivers/input/misc/atlas_btns.c
drivers/input/misc/cobalt_btns.c
drivers/input/misc/ixp4xx-beeper.c
drivers/input/misc/keyspan_remote.c
drivers/input/misc/m68kspkr.c
drivers/input/misc/pcspkr.c
drivers/input/misc/powermate.c
drivers/input/misc/sparcspkr.c
drivers/input/misc/yealink.c
drivers/input/mouse/alps.c
drivers/input/mouse/amimouse.c
drivers/input/mouse/appletouch.c
drivers/input/mouse/atarimouse.c
drivers/input/mouse/hil_ptr.c
drivers/input/mouse/inport.c
drivers/input/mouse/lifebook.c
drivers/input/mouse/logibm.c
drivers/input/mouse/pc110pad.c
drivers/input/mouse/psmouse-base.c
drivers/input/mouse/rpcmouse.c
drivers/input/mouse/sermouse.c
drivers/input/mouse/touchkit_ps2.c
drivers/input/mouse/vsxxxaa.c
drivers/input/mousedev.c
drivers/input/serio/i8042.c
drivers/input/serio/i8042.h
drivers/input/serio/serio.c
drivers/input/tablet/acecad.c
drivers/input/tablet/gtco.c
drivers/input/tablet/kbtab.c
drivers/input/tablet/wacom_sys.c
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/ads7846.c
drivers/input/touchscreen/corgi_ts.c
drivers/input/touchscreen/elo.c
drivers/input/touchscreen/fujitsu_ts.c
drivers/input/touchscreen/gunze.c
drivers/input/touchscreen/h3600_ts_input.c
drivers/input/touchscreen/hp680_ts_input.c
drivers/input/touchscreen/mk712.c
drivers/input/touchscreen/mtouch.c
drivers/input/touchscreen/penmount.c
drivers/input/touchscreen/touchright.c
drivers/input/touchscreen/touchwin.c
drivers/input/touchscreen/ucb1400_ts.c
drivers/input/touchscreen/usbtouchscreen.c
drivers/isdn/act2000/act2000_isa.c
drivers/isdn/gigaset/common.c
drivers/isdn/hardware/avm/b1.c
drivers/isdn/hardware/avm/b1dma.c
drivers/isdn/hardware/avm/c4.c
drivers/isdn/hardware/avm/t1isa.c
drivers/isdn/hardware/eicon/capifunc.c
drivers/isdn/hisax/amd7930_fn.c
drivers/isdn/hisax/enternow_pci.c
drivers/isdn/hisax/hfc_pci.c
drivers/isdn/hisax/isdnhdlc.c
drivers/isdn/hisax/isdnhdlc.h
drivers/isdn/hisax/jade.c
drivers/isdn/pcbit/capi.c
drivers/isdn/sc/debug.h [deleted file]
drivers/isdn/sc/includes.h
drivers/isdn/sc/init.c
drivers/kvm/Kconfig
drivers/kvm/kvm_main.c
drivers/kvm/lapic.c
drivers/kvm/mmu.c
drivers/kvm/vmx.c
drivers/kvm/x86_emulate.c
drivers/leds/leds-s3c24xx.c
drivers/lguest/Kconfig
drivers/lguest/Makefile
drivers/lguest/core.c
drivers/lguest/hypercalls.c
drivers/lguest/interrupts_and_traps.c
drivers/lguest/io.c [deleted file]
drivers/lguest/lg.h
drivers/lguest/lguest_bus.c [deleted file]
drivers/lguest/lguest_device.c [new file with mode: 0644]
drivers/lguest/lguest_user.c
drivers/lguest/page_tables.c
drivers/lguest/segments.c
drivers/lguest/x86/core.c [new file with mode: 0644]
drivers/lguest/x86/switcher_32.S [moved from drivers/lguest/switcher.S with 99% similarity]
drivers/macintosh/adbhid.c
drivers/macintosh/mac_hid.c
drivers/macintosh/mediabay.c
drivers/macintosh/via-pmu.c
drivers/md/Kconfig
drivers/md/Makefile
drivers/md/bitmap.c
drivers/md/dm-bio-list.h
drivers/md/dm-crypt.c
drivers/md/dm-delay.c
drivers/md/dm-emc.c
drivers/md/dm-hw-handler.c
drivers/md/dm-hw-handler.h
drivers/md/dm-ioctl.c
drivers/md/dm-log.c
drivers/md/dm-log.h
drivers/md/dm-mpath-hp-sw.c [new file with mode: 0644]
drivers/md/dm-mpath-rdac.c
drivers/md/dm-mpath.c
drivers/md/dm-path-selector.c
drivers/md/dm-raid1.c
drivers/md/dm-snap.c
drivers/md/dm-stripe.c
drivers/md/dm-table.c
drivers/md/dm-target.c
drivers/md/dm-uevent.c [new file with mode: 0644]
drivers/md/dm-uevent.h [new file with mode: 0644]
drivers/md/dm.c
drivers/md/kcopyd.c
drivers/md/md.c
drivers/md/raid1.c
drivers/md/raid5.c
drivers/media/common/ir-keymaps.c
drivers/media/common/saa7146_core.c
drivers/media/common/saa7146_hlp.c
drivers/media/dvb/bt8xx/bt878.c
drivers/media/dvb/cinergyT2/cinergyT2.c
drivers/media/dvb/dvb-core/dvb_ca_en50221.c
drivers/media/dvb/dvb-core/dvb_frontend.c
drivers/media/dvb/dvb-usb/dib0700_devices.c
drivers/media/dvb/dvb-usb/dvb-usb-remote.c
drivers/media/dvb/ttpci/av7110_ir.c
drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
drivers/media/dvb/ttusb-dec/ttusb_dec.c
drivers/media/radio/miropcm20-radio.c
drivers/media/radio/radio-gemtek.c
drivers/media/video/arv.c
drivers/media/video/bt8xx/bttv-cards.c
drivers/media/video/bt8xx/bttv-driver.c
drivers/media/video/bw-qcam.c
drivers/media/video/c-qcam.c
drivers/media/video/cpia.c
drivers/media/video/cpia2/cpia2_v4l.c
drivers/media/video/cx23885/cx23885-core.c
drivers/media/video/cx88/cx88-alsa.c
drivers/media/video/cx88/cx88-blackbird.c
drivers/media/video/cx88/cx88-dvb.c
drivers/media/video/cx88/cx88-mpeg.c
drivers/media/video/cx88/cx88-video.c
drivers/media/video/cx88/cx88-vp3054-i2c.c
drivers/media/video/cx88/cx88.h
drivers/media/video/em28xx/em28xx-core.c
drivers/media/video/em28xx/em28xx-video.c
drivers/media/video/et61x251/et61x251_core.c
drivers/media/video/ir-kbd-i2c.c
drivers/media/video/ivtv/ivtv-driver.c
drivers/media/video/ivtv/ivtv-driver.h
drivers/media/video/ivtv/ivtv-fileops.c
drivers/media/video/ivtv/ivtv-ioctl.c
drivers/media/video/ivtv/ivtv-streams.c
drivers/media/video/ivtv/ivtv-streams.h
drivers/media/video/ivtv/ivtv-udma.c
drivers/media/video/ivtv/ivtv-yuv.c
drivers/media/video/ivtv/ivtv-yuv.h
drivers/media/video/ivtv/ivtvfb.c
drivers/media/video/meye.c
drivers/media/video/meye.h
drivers/media/video/ov511.c
drivers/media/video/planb.c
drivers/media/video/pms.c
drivers/media/video/pvrusb2/pvrusb2-encoder.c
drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
drivers/media/video/pvrusb2/pvrusb2-hdw.c
drivers/media/video/pvrusb2/pvrusb2-v4l2.c
drivers/media/video/pwc/pwc-if.c
drivers/media/video/saa5246a.c
drivers/media/video/saa5249.c
drivers/media/video/saa7134/saa6752hs.c
drivers/media/video/saa7134/saa7134-core.c
drivers/media/video/saa7134/saa7134-empress.c
drivers/media/video/saa7134/saa7134-input.c
drivers/media/video/saa7134/saa7134-tvaudio.c
drivers/media/video/saa7134/saa7134-video.c
drivers/media/video/saa7134/saa7134.h
drivers/media/video/se401.c
drivers/media/video/sn9c102/sn9c102_core.c
drivers/media/video/stradis.c
drivers/media/video/stv680.c
drivers/media/video/tuner-core.c
drivers/media/video/usbvideo/konicawc.c
drivers/media/video/usbvideo/quickcam_messenger.c
drivers/media/video/usbvideo/usbvideo.c
drivers/media/video/usbvideo/vicam.c
drivers/media/video/usbvision/usbvision-video.c
drivers/media/video/v4l1-compat.c
drivers/media/video/v4l2-common.c
drivers/media/video/videobuf-core.c
drivers/media/video/videobuf-dma-sg.c
drivers/media/video/videocodec.c
drivers/media/video/videodev.c
drivers/media/video/vivi.c
drivers/media/video/w9966.c
drivers/media/video/w9968cf.c
drivers/media/video/zc0301/zc0301_core.c
drivers/media/video/zoran_card.c
drivers/media/video/zoran_driver.c
drivers/message/i2o/README
drivers/message/i2o/exec-osm.c
drivers/message/i2o/i2o_config.c
drivers/message/i2o/i2o_proc.c
drivers/message/i2o/iop.c
drivers/message/i2o/pci.c
drivers/mfd/Kconfig
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/misc/fujitsu-laptop.c [new file with mode: 0644]
drivers/misc/ibmasm/remote.c
drivers/misc/phantom.c
drivers/misc/sony-laptop.c
drivers/misc/thinkpad_acpi.c
drivers/misc/thinkpad_acpi.h
drivers/mmc/card/queue.c
drivers/mmc/host/at91_mci.c
drivers/mmc/host/au1xmmc.c
drivers/mmc/host/imxmmc.c
drivers/mmc/host/mmc_spi.c
drivers/mmc/host/mmci.h
drivers/mmc/host/omap.c
drivers/mmc/host/sdhci.c
drivers/mmc/host/tifm_sd.c
drivers/mmc/host/wbsd.c
drivers/mtd/chips/cfi_cmdset_0001.c
drivers/mtd/maps/Kconfig
drivers/mtd/nand/Kconfig
drivers/mtd/nand/diskonchip.c
drivers/mtd/nand/nand_base.c
drivers/mtd/nand/nand_ecc.c
drivers/mtd/nand/nandsim.c
drivers/mtd/nand/s3c2410.c
drivers/mtd/onenand/onenand_sim.c
drivers/mtd/ubi/wl.c
drivers/net/3c59x.c
drivers/net/8139too.c
drivers/net/Kconfig
drivers/net/Makefile
drivers/net/amd8111e.c
drivers/net/ariadne.c
drivers/net/ariadne.h
drivers/net/au1000_eth.c
drivers/net/ax88796.c
drivers/net/bnx2.c
drivers/net/bnx2_fw2.h
drivers/net/bonding/bond_3ad.c
drivers/net/bonding/bond_3ad.h
drivers/net/bonding/bond_sysfs.c
drivers/net/cpmac.c
drivers/net/cris/eth_v10.c
drivers/net/cxgb3/adapter.h
drivers/net/dm9000.c
drivers/net/e100.c
drivers/net/e1000/e1000_main.c
drivers/net/ehea/ehea_main.c
drivers/net/eth16i.c
drivers/net/fealnx.c
drivers/net/fec.c
drivers/net/forcedeth.c
drivers/net/fs_enet/fs_enet-main.c
drivers/net/fs_enet/fs_enet.h
drivers/net/gianfar.c
drivers/net/gianfar.h
drivers/net/hamradio/6pack.c
drivers/net/hamradio/Kconfig
drivers/net/hamradio/dmascc.c
drivers/net/ibm_newemac/mal.c
drivers/net/irda/actisys-sir.c
drivers/net/irda/actisys.c
drivers/net/irda/donauboe.c
drivers/net/irda/girbil-sir.c
drivers/net/irda/girbil.c
drivers/net/irda/irport.h
drivers/net/irda/irtty-sir.c
drivers/net/irda/nsc-ircc.c
drivers/net/irda/nsc-ircc.h
drivers/net/irda/tekram-sir.c
drivers/net/irda/tekram.c
drivers/net/irda/w83977af_ir.h
drivers/net/lguest_net.c [deleted file]
drivers/net/mac89x0.c
drivers/net/meth.h
drivers/net/mlx4/fw.c
drivers/net/mlx4/icm.c
drivers/net/myri10ge/myri10ge.c
drivers/net/natsemi.c
drivers/net/netxen/netxen_nic_main.c
drivers/net/niu.c
drivers/net/pcnet32.c
drivers/net/phy/mdio-bitbang.c
drivers/net/ppp_mppe.c
drivers/net/s2io-regs.h
drivers/net/s2io.c
drivers/net/s2io.h
drivers/net/sky2.c
drivers/net/smc911x.c
drivers/net/spider_net.c
drivers/net/tc35815.c
drivers/net/tg3.c
drivers/net/tg3.h
drivers/net/tsi108_eth.c
drivers/net/tulip/Kconfig
drivers/net/tulip/uli526x.c
drivers/net/tulip/winbond-840.c
drivers/net/usb/Kconfig
drivers/net/usb/mcs7830.c
drivers/net/via-velocity.c
drivers/net/virtio_net.c [new file with mode: 0644]
drivers/net/wireless/b43/main.c
drivers/net/wireless/b43legacy/main.c
drivers/net/wireless/bcm43xx/bcm43xx_leds.c
drivers/net/wireless/bcm43xx/bcm43xx_xmit.h
drivers/net/wireless/hostap/hostap_common.h
drivers/net/wireless/hostap/hostap_ioctl.c
drivers/net/wireless/ipw2100.c
drivers/net/wireless/ipw2100.h
drivers/net/wireless/ipw2200.c
drivers/net/wireless/iwlwifi/iwl-3945-rs.c
drivers/net/wireless/iwlwifi/iwl-3945.c
drivers/net/wireless/iwlwifi/iwl-4965-rs.c
drivers/net/wireless/iwlwifi/iwl-4965.c
drivers/net/wireless/iwlwifi/iwl3945-base.c
drivers/net/wireless/iwlwifi/iwl4965-base.c
drivers/net/wireless/iwlwifi/iwlwifi.h
drivers/net/wireless/netwave_cs.c
drivers/net/wireless/p54common.c
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt73usb.c
drivers/net/wireless/rtl8187_dev.c
drivers/net/wireless/zd1201.c
drivers/net/wireless/zd1211rw/zd_usb.c
drivers/net/xen-netfront.c
drivers/of/platform.c
drivers/parisc/ccio-dma.c
drivers/parisc/lba_pci.c
drivers/parisc/pdc_stable.c
drivers/parisc/sba_iommu.c
drivers/parisc/superio.c
drivers/parport/daisy.c
drivers/parport/procfs.c
drivers/pci/Makefile
drivers/pci/dmar.c [new file with mode: 0644]
drivers/pci/intel-iommu.c [new file with mode: 0644]
drivers/pci/intel-iommu.h [new file with mode: 0644]
drivers/pci/iova.c [new file with mode: 0644]
drivers/pci/iova.h [new file with mode: 0644]
drivers/pci/pci.h
drivers/pci/probe.c
drivers/pci/search.c
drivers/pcmcia/m32r_pcc.c
drivers/pcmcia/m8xx_pcmcia.c
drivers/power/apm_power.c
drivers/power/ds2760_battery.c
drivers/ps3/ps3av.c
drivers/ps3/ps3stor_lib.c
drivers/ps3/vuart.c
drivers/rtc/Kconfig
drivers/rtc/rtc-pl031.c
drivers/rtc/rtc-sa1100.c
drivers/rtc/rtc-sysfs.c
drivers/s390/block/dasd_3990_erp.c
drivers/s390/char/raw3270.c
drivers/s390/char/sclp_cpi.c
drivers/s390/char/tape_class.c
drivers/s390/char/tape_class.h
drivers/s390/char/vmlogrdr.c
drivers/s390/cio/chp.c
drivers/s390/cio/cmf.c
drivers/s390/cio/css.c
drivers/s390/cio/idset.c
drivers/s390/net/claw.c
drivers/s390/net/ctcmain.c
drivers/s390/net/qeth_main.c
drivers/s390/scsi/zfcp_aux.c
drivers/s390/scsi/zfcp_def.h
drivers/s390/scsi/zfcp_erp.c
drivers/sbus/char/vfc.h
drivers/sbus/char/vfc_dev.c
drivers/scsi/3w-9xxx.c
drivers/scsi/3w-xxxx.c
drivers/scsi/FlashPoint.c
drivers/scsi/Kconfig
drivers/scsi/NCR5380.c
drivers/scsi/NCR53C9x.c
drivers/scsi/NCR53c406a.c
drivers/scsi/aacraid/aachba.c
drivers/scsi/aacraid/aacraid.h
drivers/scsi/aha152x.c
drivers/scsi/aha1542.c
drivers/scsi/aic7xxx/cam.h
drivers/scsi/arcmsr/arcmsr_hba.c
drivers/scsi/atari_NCR5380.c
drivers/scsi/dc395x.c
drivers/scsi/eata_pio.c
drivers/scsi/fd_mcs.c
drivers/scsi/fdomain.c
drivers/scsi/gdth.c
drivers/scsi/ibmmca.c
drivers/scsi/ide-scsi.c
drivers/scsi/imm.c
drivers/scsi/in2000.c
drivers/scsi/ipr.c
drivers/scsi/ips.c
drivers/scsi/iscsi_tcp.c
drivers/scsi/libsas/sas_discover.c
drivers/scsi/lpfc/lpfc_sli.c
drivers/scsi/megaraid.c
drivers/scsi/megaraid/megaraid_mbox.c
drivers/scsi/nsp32.h
drivers/scsi/oktagon_esp.c
drivers/scsi/osst.c
drivers/scsi/pcmcia/nsp_cs.h
drivers/scsi/pcmcia/sym53c500_cs.c
drivers/scsi/ppa.c
drivers/scsi/ps3rom.c
drivers/scsi/qla4xxx/ql4_fw.h
drivers/scsi/qla4xxx/ql4_init.c
drivers/scsi/qla4xxx/ql4_iocb.c
drivers/scsi/qla4xxx/ql4_os.c
drivers/scsi/qlogicfas408.c
drivers/scsi/scsi_debug.c
drivers/scsi/scsi_lib.c
drivers/scsi/sd.c
drivers/scsi/seagate.c
drivers/scsi/sg.c
drivers/scsi/st.c
drivers/scsi/sun3_NCR5380.c
drivers/scsi/sym53c416.c
drivers/scsi/sym53c8xx_2/sym_fw2.h
drivers/scsi/tmscsim.c
drivers/scsi/ultrastor.c
drivers/scsi/wd33c93.c
drivers/scsi/wd33c93.h
drivers/scsi/wd7000.c
drivers/serial/Kconfig
drivers/serial/amba-pl011.c
drivers/serial/crisv10.c
drivers/serial/mcf.c [new file with mode: 0644]
drivers/serial/s3c2410.c
drivers/serial/serial_core.c
drivers/spi/mpc52xx_psc_spi.c
drivers/spi/spi_bfin5xx.c
drivers/spi/spi_imx.c
drivers/ssb/Kconfig
drivers/ssb/driver_mipscore.c
drivers/usb/class/cdc-acm.c
drivers/usb/core/devio.c
drivers/usb/core/endpoint.c
drivers/usb/core/hub.c
drivers/usb/core/message.c
drivers/usb/gadget/file_storage.c
drivers/usb/gadget/lh7a40x_udc.c
drivers/usb/host/ehci-hub.c
drivers/usb/host/ohci-s3c2410.c
drivers/usb/host/sl811-hcd.c
drivers/usb/image/Kconfig
drivers/usb/image/microtek.c
drivers/usb/misc/adutux.c
drivers/usb/misc/cytherm.c
drivers/usb/misc/emi26.c
drivers/usb/misc/emi62.c
drivers/usb/misc/iowarrior.c
drivers/usb/misc/phidgetmotorcontrol.c
drivers/usb/misc/usbtest.c
drivers/usb/serial/ChangeLog.history
drivers/usb/serial/Kconfig
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio.h
drivers/usb/serial/io_edgeport.c
drivers/usb/serial/ipaq.c
drivers/usb/serial/ipw.c
drivers/usb/serial/mos7720.c
drivers/usb/serial/oti6858.c
drivers/usb/serial/sierra.c
drivers/usb/storage/isd200.c
drivers/usb/storage/protocol.c
drivers/usb/storage/unusual_devs.h
drivers/usb/storage/usb.c
drivers/video/Kconfig
drivers/video/amifb.c
drivers/video/aty/atyfb_base.c
drivers/video/au1100fb.c
drivers/video/console/Kconfig
drivers/video/console/newport_con.c
drivers/video/cyber2000fb.c
drivers/video/geode/video_gx.c
drivers/video/gxt4500.c
drivers/video/intelfb/intelfbdrv.c
drivers/video/intelfb/intelfbhw.c
drivers/video/logo/logo.c
drivers/video/modedb.c
drivers/video/omap/Kconfig
drivers/video/omap/blizzard.c
drivers/video/omap/dispc.c
drivers/video/omap/hwa742.c
drivers/video/omap/rfbi.c
drivers/video/pnx4008/sdum.h
drivers/video/s3c2410fb.c
drivers/video/vermilion/vermilion.c
drivers/video/vermilion/vermilion.h
drivers/virtio/Kconfig [new file with mode: 0644]
drivers/virtio/Makefile [new file with mode: 0644]
drivers/virtio/config.c [new file with mode: 0644]
drivers/virtio/virtio.c [new file with mode: 0644]
drivers/virtio/virtio_ring.c [new file with mode: 0644]
drivers/w1/masters/ds1wm.c
drivers/watchdog/Kconfig [moved from drivers/char/watchdog/Kconfig with 100% similarity]
drivers/watchdog/Makefile [moved from drivers/char/watchdog/Makefile with 100% similarity]
drivers/watchdog/acquirewdt.c [moved from drivers/char/watchdog/acquirewdt.c with 100% similarity]
drivers/watchdog/advantechwdt.c [moved from drivers/char/watchdog/advantechwdt.c with 100% similarity]
drivers/watchdog/alim1535_wdt.c [moved from drivers/char/watchdog/alim1535_wdt.c with 100% similarity]
drivers/watchdog/alim7101_wdt.c [moved from drivers/char/watchdog/alim7101_wdt.c with 100% similarity]
drivers/watchdog/at32ap700x_wdt.c [moved from drivers/char/watchdog/at32ap700x_wdt.c with 100% similarity]
drivers/watchdog/at91rm9200_wdt.c [moved from drivers/char/watchdog/at91rm9200_wdt.c with 99% similarity]
drivers/watchdog/bfin_wdt.c [moved from drivers/char/watchdog/bfin_wdt.c with 100% similarity]
drivers/watchdog/booke_wdt.c [moved from drivers/char/watchdog/booke_wdt.c with 100% similarity]
drivers/watchdog/cpu5wdt.c [moved from drivers/char/watchdog/cpu5wdt.c with 100% similarity]
drivers/watchdog/davinci_wdt.c [moved from drivers/char/watchdog/davinci_wdt.c with 100% similarity]
drivers/watchdog/ep93xx_wdt.c [moved from drivers/char/watchdog/ep93xx_wdt.c with 100% similarity]
drivers/watchdog/eurotechwdt.c [moved from drivers/char/watchdog/eurotechwdt.c with 100% similarity]
drivers/watchdog/i6300esb.c [moved from drivers/char/watchdog/i6300esb.c with 98% similarity]
drivers/watchdog/iTCO_vendor_support.c [moved from drivers/char/watchdog/iTCO_vendor_support.c with 99% similarity]
drivers/watchdog/iTCO_wdt.c [moved from drivers/char/watchdog/iTCO_wdt.c with 100% similarity]
drivers/watchdog/ib700wdt.c [moved from drivers/char/watchdog/ib700wdt.c with 100% similarity]
drivers/watchdog/ibmasr.c [moved from drivers/char/watchdog/ibmasr.c with 100% similarity]
drivers/watchdog/indydog.c [moved from drivers/char/watchdog/indydog.c with 100% similarity]
drivers/watchdog/iop_wdt.c [moved from drivers/char/watchdog/iop_wdt.c with 100% similarity]
drivers/watchdog/ixp2000_wdt.c [moved from drivers/char/watchdog/ixp2000_wdt.c with 100% similarity]
drivers/watchdog/ixp4xx_wdt.c [moved from drivers/char/watchdog/ixp4xx_wdt.c with 100% similarity]
drivers/watchdog/ks8695_wdt.c [moved from drivers/char/watchdog/ks8695_wdt.c with 99% similarity]
drivers/watchdog/machzwd.c [moved from drivers/char/watchdog/machzwd.c with 100% similarity]
drivers/watchdog/mixcomwd.c [moved from drivers/char/watchdog/mixcomwd.c with 100% similarity]
drivers/watchdog/mpc5200_wdt.c [moved from drivers/char/watchdog/mpc5200_wdt.c with 98% similarity]
drivers/watchdog/mpc83xx_wdt.c [moved from drivers/char/watchdog/mpc83xx_wdt.c with 100% similarity]
drivers/watchdog/mpc8xx_wdt.c [moved from drivers/char/watchdog/mpc8xx_wdt.c with 100% similarity]
drivers/watchdog/mpcore_wdt.c [moved from drivers/char/watchdog/mpcore_wdt.c with 100% similarity]
drivers/watchdog/mtx-1_wdt.c [moved from drivers/char/watchdog/mtx-1_wdt.c with 100% similarity]
drivers/watchdog/mv64x60_wdt.c [moved from drivers/char/watchdog/mv64x60_wdt.c with 100% similarity]
drivers/watchdog/omap_wdt.c [moved from drivers/char/watchdog/omap_wdt.c with 99% similarity]
drivers/watchdog/omap_wdt.h [moved from drivers/char/watchdog/omap_wdt.h with 100% similarity]
drivers/watchdog/pc87413_wdt.c [moved from drivers/char/watchdog/pc87413_wdt.c with 100% similarity]
drivers/watchdog/pcwd.c [moved from drivers/char/watchdog/pcwd.c with 100% similarity]
drivers/watchdog/pcwd_pci.c [moved from drivers/char/watchdog/pcwd_pci.c with 100% similarity]
drivers/watchdog/pcwd_usb.c [moved from drivers/char/watchdog/pcwd_usb.c with 100% similarity]
drivers/watchdog/pnx4008_wdt.c [moved from drivers/char/watchdog/pnx4008_wdt.c with 100% similarity]
drivers/watchdog/rm9k_wdt.c [moved from drivers/char/watchdog/rm9k_wdt.c with 100% similarity]
drivers/watchdog/s3c2410_wdt.c [moved from drivers/char/watchdog/s3c2410_wdt.c with 100% similarity]
drivers/watchdog/sa1100_wdt.c [moved from drivers/char/watchdog/sa1100_wdt.c with 99% similarity]
drivers/watchdog/sbc60xxwdt.c [moved from drivers/char/watchdog/sbc60xxwdt.c with 100% similarity]
drivers/watchdog/sbc8360.c [moved from drivers/char/watchdog/sbc8360.c with 100% similarity]
drivers/watchdog/sbc_epx_c3.c [moved from drivers/char/watchdog/sbc_epx_c3.c with 100% similarity]
drivers/watchdog/sc1200wdt.c [moved from drivers/char/watchdog/sc1200wdt.c with 100% similarity]
drivers/watchdog/sc520_wdt.c [moved from drivers/char/watchdog/sc520_wdt.c with 100% similarity]
drivers/watchdog/scx200_wdt.c [moved from drivers/char/watchdog/scx200_wdt.c with 100% similarity]
drivers/watchdog/shwdt.c [moved from drivers/char/watchdog/shwdt.c with 100% similarity]
drivers/watchdog/smsc37b787_wdt.c [moved from drivers/char/watchdog/smsc37b787_wdt.c with 100% similarity]
drivers/watchdog/softdog.c [moved from drivers/char/watchdog/softdog.c with 100% similarity]
drivers/watchdog/w83627hf_wdt.c [moved from drivers/char/watchdog/w83627hf_wdt.c with 100% similarity]
drivers/watchdog/w83697hf_wdt.c [moved from drivers/char/watchdog/w83697hf_wdt.c with 99% similarity]
drivers/watchdog/w83877f_wdt.c [moved from drivers/char/watchdog/w83877f_wdt.c with 100% similarity]
drivers/watchdog/w83977f_wdt.c [moved from drivers/char/watchdog/w83977f_wdt.c with 100% similarity]
drivers/watchdog/wafer5823wdt.c [moved from drivers/char/watchdog/wafer5823wdt.c with 100% similarity]
drivers/watchdog/wd501p.h [moved from drivers/char/watchdog/wd501p.h with 100% similarity]
drivers/watchdog/wdrtas.c [moved from drivers/char/watchdog/wdrtas.c with 100% similarity]
drivers/watchdog/wdt.c [moved from drivers/char/watchdog/wdt.c with 100% similarity]
drivers/watchdog/wdt285.c [moved from drivers/char/watchdog/wdt285.c with 100% similarity]
drivers/watchdog/wdt977.c [moved from drivers/char/watchdog/wdt977.c with 100% similarity]
drivers/watchdog/wdt_pci.c [moved from drivers/char/watchdog/wdt_pci.c with 100% similarity]
drivers/xen/xenbus/xenbus_probe.c
drivers/zorro/zorro.ids
fs/9p/v9fs.c
fs/9p/vfs_inode.c
fs/Kconfig
fs/aio.c
fs/attr.c
fs/autofs/inode.c
fs/autofs/root.c
fs/autofs/waitq.c
fs/autofs4/autofs_i.h
fs/autofs4/inode.c
fs/autofs4/root.c
fs/autofs4/waitq.c
fs/binfmt_elf.c
fs/binfmt_elf_fdpic.c
fs/binfmt_em86.c
fs/binfmt_misc.c
fs/binfmt_script.c
fs/buffer.c
fs/cifs/CHANGES
fs/cifs/Makefile
fs/cifs/asn1.c
fs/cifs/cifs_debug.c
fs/cifs/cifsacl.c [new file with mode: 0644]
fs/cifs/cifsacl.h
fs/cifs/cifsencrypt.c
fs/cifs/cifsfs.c
fs/cifs/cifsfs.h
fs/cifs/cifsglob.h
fs/cifs/cifspdu.h
fs/cifs/cifsproto.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/dir.c
fs/cifs/export.c
fs/cifs/file.c
fs/cifs/inode.c
fs/cifs/link.c
fs/cifs/misc.c
fs/cifs/netmisc.c
fs/cifs/readdir.c
fs/cifs/sess.c
fs/cifs/smberr.h
fs/cifs/transport.c
fs/cifs/xattr.c
fs/coda/upcall.c
fs/compat_ioctl.c
fs/cramfs/inode.c
fs/dcache.c
fs/debugfs/inode.c
fs/dlm/user.c
fs/ecryptfs/crypto.c
fs/ecryptfs/inode.c
fs/ecryptfs/keystore.c
fs/efs/namei.c
fs/efs/super.c
fs/eventpoll.c
fs/exec.c
fs/exportfs/expfs.c
fs/ext2/dir.c
fs/ext2/super.c
fs/ext3/fsync.c
fs/ext3/inode.c
fs/ext3/resize.c
fs/ext3/super.c
fs/ext3/xattr.c
fs/ext4/balloc.c
fs/ext4/dir.c
fs/ext4/extents.c
fs/ext4/fsync.c
fs/ext4/group.h [new file with mode: 0644]
fs/ext4/ialloc.c
fs/ext4/inode.c
fs/ext4/namei.c
fs/ext4/resize.c
fs/ext4/super.c
fs/ext4/xattr.c
fs/fat/inode.c
fs/fcntl.c
fs/file_table.c
fs/fs-writeback.c
fs/fuse/dir.c
fs/fuse/file.c
fs/fuse/fuse_i.h
fs/fuse/inode.c
fs/gfs2/ops_export.c
fs/gfs2/ops_fstype.h
fs/inotify.c
fs/ioprio.c
fs/isofs/export.c
fs/isofs/inode.c
fs/isofs/isofs.h
fs/jbd/commit.c
fs/jbd/journal.c
fs/jbd/recovery.c
fs/jbd/transaction.c
fs/jbd2/commit.c
fs/jbd2/journal.c
fs/jbd2/recovery.c
fs/jbd2/revoke.c
fs/jbd2/transaction.c
fs/jffs2/acl.c
fs/jffs2/acl.h
fs/jffs2/debug.h
fs/jffs2/dir.c
fs/jffs2/file.c
fs/jffs2/fs.c
fs/jffs2/os-linux.h
fs/jffs2/write.c
fs/jfs/jfs_dtree.c
fs/jfs/jfs_inode.h
fs/jfs/namei.c
fs/jfs/super.c
fs/libfs.c
fs/namei.c
fs/namespace.c
fs/nfs/delegation.c
fs/nfs/dir.c
fs/nfs/file.c
fs/nfs/inode.c
fs/nfs/nfs4_fs.h
fs/nfs/nfs4proc.c
fs/nfs/nfs4state.c
fs/nfs/nfsroot.c
fs/nfs/proc.c
fs/nfs/unlink.c
fs/nfs/write.c
fs/nfsd/export.c
fs/nfsd/nfs4recover.c
fs/nfsd/nfsfh.c
fs/nfsd/vfs.c
fs/nls/nls_base.c
fs/ntfs/ChangeLog
fs/ntfs/namei.c
fs/ntfs/ntfs.h
fs/ntfs/sysctl.c
fs/ntfs/sysctl.h
fs/ocfs2/cluster/heartbeat.c
fs/ocfs2/cluster/masklog.h
fs/ocfs2/dcache.c
fs/ocfs2/dlm/dlmrecovery.c
fs/ocfs2/export.c
fs/ocfs2/export.h
fs/open.c
fs/pnode.h
fs/proc/array.c
fs/proc/base.c
fs/proc/inode.c
fs/proc/proc_misc.c
fs/proc/root.c
fs/reiserfs/bitmap.c
fs/reiserfs/inode.c
fs/reiserfs/journal.c
fs/reiserfs/prints.c
fs/reiserfs/resize.c
fs/reiserfs/stree.c
fs/reiserfs/super.c
fs/reiserfs/xattr.c
fs/select.c
fs/super.c
fs/sysfs/file.c
fs/xattr.c
fs/xfs/linux-2.6/xfs_export.c
fs/xfs/linux-2.6/xfs_export.h
fs/xfs/linux-2.6/xfs_ioctl.c
fs/xfs/linux-2.6/xfs_super.h
fs/xfs/xfs_dmops.c
fs/xfs/xfs_fs.h
fs/xfs/xfs_qmops.c
fs/xfs/xfs_vfsops.c
fs/xfs/xfs_vfsops.h
fs/xfs/xfs_vnodeops.c
fs/xfs/xfs_vnodeops.h
include/acpi/achware.h
include/acpi/acpi_bus.h
include/acpi/acpixf.h
include/acpi/actbl1.h
include/acpi/processor.h
include/asm-alpha/bitops.h
include/asm-alpha/ide.h
include/asm-alpha/scatterlist.h
include/asm-alpha/tlbflush.h
include/asm-arm/arch-aaec2000/aaec2000.h
include/asm-arm/arch-ixp4xx/io.h
include/asm-arm/arch-pxa/pm.h
include/asm-arm/bitops.h
include/asm-arm/dma-mapping.h
include/asm-arm/ide.h
include/asm-arm/scatterlist.h
include/asm-arm/tlbflush.h
include/asm-avr32/arch-at32ap/board.h
include/asm-avr32/bitops.h
include/asm-avr32/dma-mapping.h
include/asm-avr32/scatterlist.h
include/asm-avr32/tlbflush.h
include/asm-blackfin/bf5xx_timers.h [deleted file]
include/asm-blackfin/bfin-global.h
include/asm-blackfin/bitops.h
include/asm-blackfin/dma.h
include/asm-blackfin/gpio.h
include/asm-blackfin/gptimers.h [new file with mode: 0644]
include/asm-blackfin/ide.h
include/asm-blackfin/mach-bf527/anomaly.h
include/asm-blackfin/mach-bf527/bf527.h [new file with mode: 0644]
include/asm-blackfin/mach-bf527/bfin_serial_5xx.h [new file with mode: 0644]
include/asm-blackfin/mach-bf527/blackfin.h [new file with mode: 0644]
include/asm-blackfin/mach-bf527/cdefBF52x_base.h
include/asm-blackfin/mach-bf527/defBF527.h
include/asm-blackfin/mach-bf527/defBF52x_base.h
include/asm-blackfin/mach-bf527/dma.h [new file with mode: 0644]
include/asm-blackfin/mach-bf527/irq.h [new file with mode: 0644]
include/asm-blackfin/mach-bf527/mem_init.h [new file with mode: 0644]
include/asm-blackfin/mach-bf527/mem_map.h [new file with mode: 0644]
include/asm-blackfin/mach-bf527/portmux.h [new file with mode: 0644]
include/asm-blackfin/mach-bf548/defBF549.h
include/asm-blackfin/mach-bf548/defBF54x_base.h
include/asm-blackfin/mach-bf548/dma.h
include/asm-blackfin/processor.h
include/asm-blackfin/scatterlist.h
include/asm-blackfin/system.h
include/asm-blackfin/tlbflush.h
include/asm-cris/arch-v32/ide.h
include/asm-cris/bitops.h
include/asm-cris/posix_types.h
include/asm-cris/scatterlist.h
include/asm-cris/tlbflush.h
include/asm-frv/bitops.h
include/asm-frv/scatterlist.h
include/asm-frv/tlbflush.h
include/asm-generic/bitops.h
include/asm-generic/bitops/atomic.h
include/asm-generic/bitops/lock.h [new file with mode: 0644]
include/asm-generic/bitops/non-atomic.h
include/asm-generic/vmlinux.lds.h
include/asm-h8300/bitops.h
include/asm-h8300/scatterlist.h
include/asm-h8300/system.h
include/asm-h8300/tlbflush.h
include/asm-ia64/bitops.h
include/asm-ia64/cacheflush.h
include/asm-ia64/ide.h
include/asm-ia64/meminit.h
include/asm-ia64/pgtable.h
include/asm-ia64/scatterlist.h
include/asm-ia64/smp.h
include/asm-ia64/spinlock.h
include/asm-ia64/tlbflush.h
include/asm-m32r/bitops.h
include/asm-m32r/ide.h
include/asm-m32r/pgtable.h
include/asm-m32r/scatterlist.h
include/asm-m32r/tlbflush.h
include/asm-m68k/bitops.h
include/asm-m68k/ide.h
include/asm-m68k/scatterlist.h
include/asm-m68k/tlbflush.h
include/asm-m68knommu/bitops.h
include/asm-m68knommu/module.h
include/asm-m68knommu/scatterlist.h
include/asm-m68knommu/system.h
include/asm-m68knommu/tlbflush.h
include/asm-m68knommu/uaccess.h
include/asm-mips/bitops.h
include/asm-mips/fpu.h
include/asm-mips/gt64120.h
include/asm-mips/i8253.h
include/asm-mips/ip32/crime.h
include/asm-mips/ip32/mace.h
include/asm-mips/mach-generic/ide.h
include/asm-mips/mach-ip27/kernel-entry-init.h
include/asm-mips/pci/bridge.h
include/asm-mips/scatterlist.h
include/asm-mips/sibyte/sb1250.h
include/asm-mips/sni.h
include/asm-mips/time.h
include/asm-mips/tlbflush.h
include/asm-parisc/Kbuild
include/asm-parisc/bitops.h
include/asm-parisc/ide.h
include/asm-parisc/io.h
include/asm-parisc/page.h
include/asm-parisc/pci.h
include/asm-parisc/pdc.h
include/asm-parisc/pgtable.h
include/asm-parisc/prefetch.h
include/asm-parisc/rtc.h
include/asm-parisc/scatterlist.h
include/asm-parisc/semaphore.h
include/asm-parisc/tlbflush.h
include/asm-parisc/unistd.h
include/asm-powerpc/bitops.h
include/asm-powerpc/dma-mapping.h
include/asm-powerpc/ide.h
include/asm-powerpc/io.h
include/asm-powerpc/iommu.h
include/asm-powerpc/mmu_context.h
include/asm-powerpc/mpc52xx.h
include/asm-powerpc/paca.h
include/asm-powerpc/scatterlist.h
include/asm-powerpc/tlbflush.h
include/asm-ppc/mmu_context.h
include/asm-ppc/system.h
include/asm-ppc/time.h
include/asm-s390/bitops.h
include/asm-s390/cpu.h [new file with mode: 0644]
include/asm-s390/mmu_context.h
include/asm-s390/page.h
include/asm-s390/pgalloc.h
include/asm-s390/pgtable.h
include/asm-s390/processor.h
include/asm-s390/scatterlist.h
include/asm-s390/tlb.h
include/asm-s390/tlbflush.h
include/asm-sh/bitops.h
include/asm-sh/dma-mapping.h
include/asm-sh/scatterlist.h
include/asm-sh/se7751.h
include/asm-sh/systemh7751.h
include/asm-sh/tlbflush.h
include/asm-sh64/bitops.h
include/asm-sh64/dma-mapping.h
include/asm-sh64/ide.h
include/asm-sh64/scatterlist.h
include/asm-sh64/system.h
include/asm-sh64/tlbflush.h
include/asm-sparc/bitops.h
include/asm-sparc/ide.h
include/asm-sparc/ioctls.h
include/asm-sparc/of_platform.h
include/asm-sparc/scatterlist.h
include/asm-sparc/termbits.h
include/asm-sparc/termios.h
include/asm-sparc/tlbflush.h
include/asm-sparc64/backoff.h [new file with mode: 0644]
include/asm-sparc64/bitops.h
include/asm-sparc64/ide.h
include/asm-sparc64/ioctls.h
include/asm-sparc64/of_platform.h
include/asm-sparc64/scatterlist.h
include/asm-sparc64/smp.h
include/asm-sparc64/termbits.h
include/asm-sparc64/termios.h
include/asm-sparc64/tlbflush.h
include/asm-um/bitops.h
include/asm-um/tlbflush.h
include/asm-v850/bitops.h
include/asm-v850/scatterlist.h
include/asm-v850/system.h
include/asm-v850/tlbflush.h
include/asm-x86/Kbuild
include/asm-x86/acpi_32.h
include/asm-x86/bitops_32.h
include/asm-x86/bitops_64.h
include/asm-x86/bootparam.h
include/asm-x86/cacheflush.h
include/asm-x86/compat.h
include/asm-x86/desc_64.h
include/asm-x86/device.h
include/asm-x86/dma-mapping_32.h
include/asm-x86/e820.h
include/asm-x86/e820_32.h
include/asm-x86/e820_64.h
include/asm-x86/geode.h
include/asm-x86/hpet.h
include/asm-x86/ide.h
include/asm-x86/io_apic_64.h
include/asm-x86/ipi.h
include/asm-x86/irq_32.h
include/asm-x86/ist.h
include/asm-x86/lguest.h [new file with mode: 0644]
include/asm-x86/lguest_hcall.h [new file with mode: 0644]
include/asm-x86/msr-index.h
include/asm-x86/pgtable_32.h
include/asm-x86/pgtable_64.h
include/asm-x86/processor_32.h
include/asm-x86/processor_64.h
include/asm-x86/proto.h
include/asm-x86/ptrace_32.h
include/asm-x86/ptrace_64.h
include/asm-x86/scatterlist_32.h
include/asm-x86/scatterlist_64.h
include/asm-x86/smp_32.h
include/asm-x86/smp_64.h
include/asm-x86/suspend_64.h
include/asm-x86/system_32.h
include/asm-x86/tlbflush_32.h
include/asm-x86/tlbflush_64.h
include/asm-x86/topology_32.h
include/asm-x86/topology_64.h
include/asm-xtensa/bitops.h
include/asm-xtensa/dma-mapping.h
include/asm-xtensa/scatterlist.h
include/asm-xtensa/tlbflush.h
include/linux/Kbuild
include/linux/acpi.h
include/linux/aio.h
include/linux/apm_bios.h
include/linux/audit.h
include/linux/bit_spinlock.h
include/linux/bitmap.h
include/linux/bitops.h
include/linux/capability.h
include/linux/cdrom.h
include/linux/cgroup.h [new file with mode: 0644]
include/linux/cgroup_subsys.h [new file with mode: 0644]
include/linux/cgroupstats.h [new file with mode: 0644]
include/linux/clocksource.h
include/linux/compiler-gcc.h
include/linux/compiler.h
include/linux/console.h
include/linux/cpu.h
include/linux/cpu_acct.h [new file with mode: 0644]
include/linux/cpuidle.h [new file with mode: 0644]
include/linux/cpuset.h
include/linux/crypto.h
include/linux/cyclades.h
include/linux/dcache.h
include/linux/delayacct.h
include/linux/device-mapper.h
include/linux/dm-ioctl.h
include/linux/dma-mapping.h
include/linux/dmar.h [new file with mode: 0644]
include/linux/edd.h
include/linux/efi.h
include/linux/efs_fs.h
include/linux/exportfs.h
include/linux/ext2_fs.h
include/linux/ext3_fs.h
include/linux/ext4_fs.h
include/linux/ext4_fs_extents.h
include/linux/ext4_fs_i.h
include/linux/ext4_fs_sb.h
include/linux/ext4_jbd2.h
include/linux/filter.h
include/linux/freezer.h
include/linux/fs.h
include/linux/fsnotify.h
include/linux/fuse.h
include/linux/hid.h
include/linux/hrtimer.h
include/linux/i8042.h [new file with mode: 0644]
include/linux/ide.h
include/linux/init_task.h
include/linux/inotify.h
include/linux/input.h
include/linux/ipc.h
include/linux/ipmi.h
include/linux/ipmi_smi.h
include/linux/jbd.h
include/linux/jbd2.h
include/linux/kernel_stat.h
include/linux/kexec.h
include/linux/keyboard.h
include/linux/lguest.h
include/linux/lguest_bus.h [deleted file]
include/linux/lguest_launcher.h
include/linux/libata.h
include/linux/linkage.h
include/linux/list.h
include/linux/lockdep.h
include/linux/magic.h
include/linux/marker.h [new file with mode: 0644]
include/linux/memory.h
include/linux/mempolicy.h
include/linux/mlx4/doorbell.h
include/linux/mod_devicetable.h
include/linux/module.h
include/linux/msg.h
include/linux/net.h
include/linux/netdevice.h
include/linux/netfilter/xt_sctp.h
include/linux/nfs_fs.h
include/linux/notifier.h
include/linux/nsproxy.h
include/linux/of.h
include/linux/of_platform.h
include/linux/parport.h
include/linux/pci.h
include/linux/pci_ids.h
include/linux/phantom.h
include/linux/pid.h
include/linux/pid_namespace.h
include/linux/pm.h
include/linux/poison.h
include/linux/prefetch.h
include/linux/prio_heap.h [new file with mode: 0644]
include/linux/proc_fs.h
include/linux/reiserfs_fs.h
include/linux/reiserfs_fs_sb.h
include/linux/scatterlist.h
include/linux/sched.h
include/linux/screen_info.h
include/linux/security.h
include/linux/sem.h
include/linux/shm.h
include/linux/skbuff.h
include/linux/socket.h
include/linux/suspend.h
include/linux/sysctl.h
include/linux/taskstats.h
include/linux/tick.h
include/linux/types.h
include/linux/uinput.h
include/linux/videodev.h
include/linux/videodev2.h
include/linux/virtio.h [new file with mode: 0644]
include/linux/virtio_9p.h [new file with mode: 0644]
include/linux/virtio_blk.h [new file with mode: 0644]
include/linux/virtio_config.h [new file with mode: 0644]
include/linux/virtio_console.h [new file with mode: 0644]
include/linux/virtio_net.h [new file with mode: 0644]
include/linux/virtio_ring.h [new file with mode: 0644]
include/linux/vt.h
include/linux/workqueue.h
include/media/saa7146.h
include/media/v4l2-dev.h
include/net/9p/9p.h
include/net/bluetooth/hci.h
include/net/bluetooth/hci_core.h
include/net/bluetooth/l2cap.h
include/net/inet_frag.h
include/net/ipv6.h
include/net/irda/irttp.h
include/net/scm.h
include/net/sock.h
include/net/xfrm.h
include/sound/version.h
include/video/Kbuild
include/video/edid.h
include/video/sstfb.h
include/video/tdfx.h
init/Kconfig
init/do_mounts_rd.c
init/main.c
ipc/mqueue.c
ipc/msg.c
ipc/sem.c
ipc/shm.c
ipc/util.c
ipc/util.h
kernel/Kconfig.instrumentation [new file with mode: 0644]
kernel/Makefile
kernel/acct.c
kernel/audit.c
kernel/audit.h
kernel/audit_tree.c [new file with mode: 0644]
kernel/auditfilter.c
kernel/auditsc.c
kernel/capability.c
kernel/cgroup.c [new file with mode: 0644]
kernel/cgroup_debug.c [new file with mode: 0644]
kernel/compat.c
kernel/cpu.c
kernel/cpu_acct.c [new file with mode: 0644]
kernel/cpuset.c
kernel/delayacct.c
kernel/die_notifier.c [deleted file]
kernel/dma.c
kernel/exec_domain.c
kernel/exit.c
kernel/fork.c
kernel/futex.c
kernel/futex_compat.c
kernel/hrtimer.c
kernel/irq/manage.c
kernel/itimer.c
kernel/kexec.c
kernel/lockdep.c
kernel/marker.c [new file with mode: 0644]
kernel/module.c
kernel/notifier.c [new file with mode: 0644]
kernel/ns_cgroup.c [new file with mode: 0644]
kernel/nsproxy.c
kernel/panic.c
kernel/params.c
kernel/pid.c
kernel/posix-cpu-timers.c
kernel/posix-timers.c
kernel/power/Kconfig
kernel/power/disk.c
kernel/power/main.c
kernel/power/power.h
kernel/power/process.c
kernel/power/snapshot.c
kernel/power/swsusp.c
kernel/power/user.c
kernel/printk.c
kernel/ptrace.c
kernel/relay.c
kernel/rtmutex-debug.c
kernel/rtmutex.c
kernel/sched.c
kernel/sched_debug.c
kernel/sched_stats.h
kernel/signal.c
kernel/softlockup.c
kernel/sys.c
kernel/sysctl.c
kernel/sysctl_check.c [new file with mode: 0644]
kernel/taskstats.c
kernel/time.c
kernel/time/clocksource.c
kernel/time/tick-sched.c
kernel/timer.c
kernel/tsacct.c
kernel/workqueue.c
lib/Kconfig.debug
lib/Makefile
lib/argv_split.c
lib/crc32.c
lib/hweight.c
lib/kernel_lock.c
lib/kobject_uevent.c
lib/libcrc32c.c
lib/percpu_counter.c
lib/prio_heap.c [new file with mode: 0644]
lib/reed_solomon/decode_rs.c
lib/reed_solomon/reed_solomon.c
lib/spinlock_debug.c
lib/swiotlb.c
mm/Kconfig
mm/filemap.c
mm/hugetlb.c
mm/memory.c
mm/memory_hotplug.c
mm/mempolicy.c
mm/mempool.c
mm/migrate.c
mm/mmap.c
mm/mprotect.c
mm/mremap.c
mm/nommu.c
mm/oom_kill.c
mm/page-writeback.c
mm/page_alloc.c
mm/prio_tree.c
mm/shmem.c
mm/slab.c
mm/slub.c
mm/swap.c
mm/vmalloc.c
mm/vmscan.c
net/9p/Kconfig
net/9p/Makefile
net/9p/trans_virtio.c [new file with mode: 0644]
net/atm/br2684.c
net/ax25/ax25_ds_in.c
net/ax25/ax25_ds_subr.c
net/bluetooth/bnep/core.c
net/bluetooth/bnep/netdev.c
net/bluetooth/hci_conn.c
net/bluetooth/hci_core.c
net/bluetooth/hci_event.c
net/bluetooth/hci_sock.c
net/bluetooth/hci_sysfs.c
net/bluetooth/hidp/core.c
net/bluetooth/l2cap.c
net/bluetooth/rfcomm/core.c
net/bluetooth/rfcomm/tty.c
net/bluetooth/sco.c
net/bridge/netfilter/ebtables.c
net/core/dev.c
net/core/filter.c
net/core/gen_estimator.c
net/core/neighbour.c
net/core/netpoll.c
net/core/pktgen.c
net/core/rtnetlink.c
net/core/scm.c
net/core/skbuff.c
net/core/sock.c
net/dccp/diag.c
net/dccp/input.c
net/dccp/ipv4.c
net/dccp/ipv6.c
net/dccp/sysctl.c
net/ieee80211/ieee80211_crypt_tkip.c
net/ieee80211/ieee80211_crypt_wep.c
net/ieee80211/ieee80211_wx.c
net/ipv4/Kconfig
net/ipv4/fib_trie.c
net/ipv4/inet_connection_sock.c
net/ipv4/inet_diag.c
net/ipv4/inet_fragment.c
net/ipv4/inet_hashtables.c
net/ipv4/ip_fragment.c
net/ipv4/ipvs/ip_vs_sync.c
net/ipv4/netfilter/nf_conntrack_proto_icmp.c
net/ipv4/sysctl_net_ipv4.c
net/ipv4/tcp.c
net/ipv4/tcp_diag.c
net/ipv4/tcp_input.c
net/ipv4/udp.c
net/ipv4/xfrm4_input.c
net/ipv4/xfrm4_mode_beet.c
net/ipv4/xfrm4_mode_tunnel.c
net/ipv4/xfrm4_output.c
net/ipv4/xfrm4_policy.c
net/ipv4/xfrm4_state.c
net/ipv4/xfrm4_tunnel.c
net/ipv6/addrconf.c
net/ipv6/af_inet6.c
net/ipv6/ah6.c
net/ipv6/esp6.c
net/ipv6/inet6_hashtables.c
net/ipv6/ip6_flowlabel.c
net/ipv6/ipcomp6.c
net/ipv6/ndisc.c
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
net/ipv6/netfilter/nf_conntrack_reasm.c
net/ipv6/reassembly.c
net/ipv6/route.c
net/ipv6/xfrm6_input.c
net/ipv6/xfrm6_mode_beet.c
net/ipv6/xfrm6_mode_ro.c
net/ipv6/xfrm6_mode_tunnel.c
net/ipv6/xfrm6_output.c
net/ipv6/xfrm6_policy.c
net/ipv6/xfrm6_state.c
net/ipv6/xfrm6_tunnel.c
net/irda/discovery.c
net/irda/ircomm/ircomm_tty_attach.c
net/irda/iriap.c
net/irda/iriap_event.c
net/irda/irias_object.c
net/irda/irlan/irlan_client.c
net/irda/irlan/irlan_client_event.c
net/irda/irlan/irlan_common.c
net/irda/irlan/irlan_eth.c
net/irda/irlan/irlan_event.c
net/irda/irlan/irlan_filter.c
net/irda/irlan/irlan_provider.c
net/irda/irlan/irlan_provider_event.c
net/irda/irlap_event.c
net/irda/irlap_frame.c
net/irda/irlmp.c
net/irda/irlmp_event.c
net/irda/irlmp_frame.c
net/irda/irmod.c
net/irda/irqueue.c
net/irda/irsysctl.c
net/irda/irttp.c
net/irda/timer.c
net/irda/wrapper.c
net/iucv/iucv.c
net/llc/af_llc.c
net/mac80211/ieee80211_i.h
net/mac80211/ieee80211_ioctl.c
net/mac80211/ieee80211_sta.c
net/mac80211/wep.c
net/netfilter/nf_conntrack_proto_generic.c
net/netfilter/nf_conntrack_proto_sctp.c
net/netfilter/nf_conntrack_proto_tcp.c
net/netfilter/nf_conntrack_proto_udp.c
net/netfilter/xt_CONNMARK.c
net/netfilter/xt_connbytes.c
net/netfilter/xt_connmark.c
net/netfilter/xt_limit.c
net/netfilter/xt_sctp.c
net/packet/af_packet.c
net/rfkill/rfkill-input.c
net/sched/Kconfig
net/sched/em_meta.c
net/sched/sch_generic.c
net/sched/sch_teql.c
net/sctp/auth.c
net/sctp/sm_make_chunk.c
net/sunrpc/auth_gss/gss_krb5_crypto.c
net/sunrpc/sched.c
net/sunrpc/sysctl.c
net/sunrpc/xdr.c
net/unix/af_unix.c
net/xfrm/xfrm_algo.c
net/xfrm/xfrm_input.c
net/xfrm/xfrm_output.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_state.c
samples/Kconfig [new file with mode: 0644]
samples/Makefile [new file with mode: 0644]
samples/markers/Makefile [new file with mode: 0644]
samples/markers/marker-example.c [new file with mode: 0644]
samples/markers/probe-example.c [new file with mode: 0644]
scripts/Kbuild.include
scripts/basic/docproc.c
scripts/checkpatch.pl
scripts/checkstack.pl
scripts/kconfig/Makefile
scripts/kconfig/menu.c
scripts/kconfig/qconf.cc
scripts/mod/file2alias.c
scripts/mod/modpost.c
scripts/package/builddeb
security/commoncap.c
security/dummy.c
security/selinux/hooks.c
security/selinux/xfrm.c
sound/arm/aaci.c
sound/core/control.c
sound/core/seq/seq_midi_emul.c
sound/drivers/opl3/opl3_midi.c
sound/i2c/other/tea575x-tuner.c
sound/isa/es18xx.c
sound/mips/au1x00.c
sound/oss/Makefile
sound/oss/dmasound/Makefile
sound/oss/dmasound/awacs_defs.h [deleted file]
sound/oss/dmasound/dac3550a.c [deleted file]
sound/oss/dmasound/dmasound.h
sound/oss/dmasound/dmasound_awacs.c [deleted file]
sound/oss/dmasound/dmasound_core.c
sound/oss/dmasound/tas3001c.c [deleted file]
sound/oss/dmasound/tas3001c.h [deleted file]
sound/oss/dmasound/tas3001c_tables.c [deleted file]
sound/oss/dmasound/tas3004.c [deleted file]
sound/oss/dmasound/tas3004.h [deleted file]
sound/oss/dmasound/tas3004_tables.c [deleted file]
sound/oss/dmasound/tas_common.c [deleted file]
sound/oss/dmasound/tas_common.h [deleted file]
sound/oss/dmasound/tas_eq_prefs.h [deleted file]
sound/oss/dmasound/tas_ioctl.h [deleted file]
sound/oss/dmasound/trans_16.c [deleted file]
sound/oss/es1371.c [deleted file]
sound/pci/au88x0/au88x0.c
sound/pci/bt87x.c
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_local.h
sound/pci/hda/patch_analog.c
sound/pci/hda/patch_cmedia.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/pci/hda/patch_via.c
sound/ppc/beep.c
sound/sh/aica.c
sound/soc/soc-core.c
sound/soc/soc-dapm.c
sound/sparc/cs4231.c
sound/synth/emux/emux_synth.c
sound/usb/caiaq/caiaq-input.c
sound/usb/usbquirks.h

index 22fb8fa9bc3d283c829a7d7ce6da13a6db59262e..8d14531846b95bfa3564b58ccfb7913a034323b8 100644 (file)
@@ -12,6 +12,7 @@
 *.s
 *.ko
 *.so
+*.so.dbg
 *.mod.c
 *.i
 *.lst
diff --git a/CREDITS b/CREDITS
index 99566b1a6eebda3aea4c73f487d82e39072ffce8..ee909f2cc49e54f0799a4739d24c4cb9151ae453 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -959,7 +959,7 @@ S: 2037 Walnut #6
 S: Boulder, Colorado 80302
 S: USA
 
-N: Heiko Eissfeldt
+N: Heiko Eißfeldt
 E: heiko@colossus.escape.de heiko@unifix.de
 D: verify_area stuff, generic SCSI fixes
 D: SCSI Programming HOWTO
@@ -1988,8 +1988,8 @@ N: Volker Lendecke
 E: vl@kki.org
 D: Kernel smbfs (to mount WfW, NT and OS/2 network drives.)
 D: NCP filesystem support (to mount NetWare volumes)
-S: Von Ossietzky Str. 12
-S: 37085 Goettingen
+S: Von-Ossietzky-Str. 12
+S: 37085 Göttingen
 S: Germany
 
 N: Kevin Lentin
@@ -2431,11 +2431,11 @@ S: 12725 SW Millikan Way, Suite 400
 S: Beaverton, Oregon 97005
 S: USA
 
-N: Eberhard Moenkeberg
+N: Eberhard Mönkeberg
 E: emoenke@gwdg.de
 D: CDROM driver "sbpcd" (Matsushita/Panasonic/Soundblaster)
-S: Ruhstrathoehe 2 b.
-S: D-37085 Goettingen
+S: Ruhstrathöhe 2 b.
+S: D-37085 Göttingen
 S: Germany
 
 N: Thomas Molina
index 1a7f53068ec2a01f0881be61c22d707b40381a67..054a7ecf64c6257551db24c986671f06a7e3d772 100644 (file)
@@ -165,7 +165,7 @@ quiet_cmd_db2man = MAN     $@
        @touch $@
 
 ###
-# Rules to generate postscripts and PNG imgages from .fig format files
+# Rules to generate postscripts and PNG images from .fig format files
 quiet_cmd_fig2eps = FIG2EPS $@
       cmd_fig2eps = fig2dev -Leps $< $@
 
index d3290c46af51c0068148752d8b6ddab4d8bf88ca..aa38cc5692a005fe4a48f59bdabff3689865c6db 100644 (file)
@@ -46,7 +46,7 @@
 
      <sect1><title>Atomic and pointer manipulation</title>
 !Iinclude/asm-x86/atomic_32.h
-!Iinclude/asm-x86/unaligned_32.h
+!Iinclude/asm-x86/unaligned.h
      </sect1>
 
      <sect1><title>Delaying, scheduling, and timer routines</title>
index 6fbc41d98c1eb56a0779499ed6d9dd8ce45235f6..957cf5c26831a31df5b8adca8ecc3eb2feabad67 100644 (file)
@@ -282,7 +282,7 @@ int __init board_init (void)
                goto out;
        }
 
-       /* map physical adress */
+       /* map physical address */
        baseaddr = (unsigned long)ioremap(CHIP_PHYSICAL_ADDRESS, 1024);
        if(!baseaddr){
                printk("Ioremap to access NAND chip failed\n");
@@ -306,7 +306,7 @@ int __init board_init (void)
        this->dev_ready = board_dev_ready;
        this->eccmode = NAND_ECC_SOFT;
 
-       /* Scan to find existance of the device */
+       /* Scan to find existence of the device */
        if (nand_scan (board_mtd, 1)) {
                err = -ENXIO;
                goto out_ior;
@@ -340,7 +340,7 @@ static void __exit board_cleanup (void)
        /* Release resources, unregister device */
        nand_release (board_mtd);
 
-       /* unmap physical adress */
+       /* unmap physical address */
        iounmap((void *)baseaddr);
        
        /* Free the MTD device structure */
index 24dc3fcf15948e8a9ed93043cf46c0e81f929c36..bc38283379f01d107ec710d96c0863109b68622e 100644 (file)
@@ -441,17 +441,20 @@ ACPI, and if none of those then a KCS device at the spec-specified
 0xca2.  If you want to turn this off, set the "trydefaults" option to
 false.
 
-If you have high-res timers compiled into the kernel, the driver will
-use them to provide much better performance.  Note that if you do not
-have high-res timers enabled in the kernel and you don't have
-interrupts enabled, the driver will run VERY slowly.  Don't blame me,
+If your IPMI interface does not support interrupts and is a KCS or
+SMIC interface, the IPMI driver will start a kernel thread for the
+interface to help speed things up.  This is a low-priority kernel
+thread that constantly polls the IPMI driver while an IPMI operation
+is in progress.  The force_kipmid module parameter will all the user to
+force this thread on or off.  If you force it off and don't have
+interrupts, the driver will run VERY slowly.  Don't blame me,
 these interfaces suck.
 
 The driver supports a hot add and remove of interfaces.  This way,
 interfaces can be added or removed after the kernel is up and running.
-This is done using /sys/modules/ipmi_si/hotmod, which is a write-only
-parameter.  You write a string to this interface.  The string has the
-format:
+This is done using /sys/modules/ipmi_si/parameters/hotmod, which is a
+write-only parameter.  You write a string to this interface.  The string
+has the format:
    <op1>[:op2[:op3...]]
 The "op"s are:
    add|remove,kcs|bt|smic,mem|i/o,<address>[,<opt1>[,<opt2>[,...]]]
@@ -581,9 +584,11 @@ The watchdog will panic and start a 120 second reset timeout if it
 gets a pre-action.  During a panic or a reboot, the watchdog will
 start a 120 timer if it is running to make sure the reboot occurs.
 
-Note that if you use the NMI preaction for the watchdog, you MUST
-NOT use nmi watchdog mode 1.  If you use the NMI watchdog, you
-must use mode 2.
+Note that if you use the NMI preaction for the watchdog, you MUST NOT
+use the nmi watchdog.  There is no reasonable way to tell if an NMI
+comes from the IPMI controller, so it must assume that if it gets an
+otherwise unhandled NMI, it must be from IPMI and it will panic
+immediately.
 
 Once you open the watchdog timer, you must write a 'V' character to the
 device to close it, or the timer will not stop.  This is a new semantic
diff --git a/Documentation/Intel-IOMMU.txt b/Documentation/Intel-IOMMU.txt
new file mode 100644 (file)
index 0000000..c232190
--- /dev/null
@@ -0,0 +1,115 @@
+Linux IOMMU Support
+===================
+
+The architecture spec can be obtained from the below location.
+
+http://www.intel.com/technology/virtualization/
+
+This guide gives a quick cheat sheet for some basic understanding.
+
+Some Keywords
+
+DMAR - DMA remapping
+DRHD - DMA Engine Reporting Structure
+RMRR - Reserved memory Region Reporting Structure
+ZLR  - Zero length reads from PCI devices
+IOVA - IO Virtual address.
+
+Basic stuff
+-----------
+
+ACPI enumerates and lists the different DMA engines in the platform, and
+device scope relationships between PCI devices and which DMA engine  controls
+them.
+
+What is RMRR?
+-------------
+
+There are some devices the BIOS controls, for e.g USB devices to perform
+PS2 emulation. The regions of memory used for these devices are marked
+reserved in the e820 map. When we turn on DMA translation, DMA to those
+regions will fail. Hence BIOS uses RMRR to specify these regions along with
+devices that need to access these regions. OS is expected to setup
+unity mappings for these regions for these devices to access these regions.
+
+How is IOVA generated?
+---------------------
+
+Well behaved drivers call pci_map_*() calls before sending command to device
+that needs to perform DMA. Once DMA is completed and mapping is no longer
+required, device performs a pci_unmap_*() calls to unmap the region.
+
+The Intel IOMMU driver allocates a virtual address per domain. Each PCIE
+device has its own domain (hence protection). Devices under p2p bridges
+share the virtual address with all devices under the p2p bridge due to
+transaction id aliasing for p2p bridges.
+
+IOVA generation is pretty generic. We used the same technique as vmalloc()
+but these are not global address spaces, but separate for each domain.
+Different DMA engines may support different number of domains.
+
+We also allocate gaurd pages with each mapping, so we can attempt to catch
+any overflow that might happen.
+
+
+Graphics Problems?
+------------------
+If you encounter issues with graphics devices, you can try adding
+option intel_iommu=igfx_off to turn off the integrated graphics engine.
+
+If it happens to be a PCI device included in the INCLUDE_ALL Engine,
+then try enabling CONFIG_DMAR_GFX_WA to setup a 1-1 map. We hear
+graphics drivers may be in process of using DMA api's in the near
+future and at that time this option can be yanked out.
+
+Some exceptions to IOVA
+-----------------------
+Interrupt ranges are not address translated, (0xfee00000 - 0xfeefffff).
+The same is true for peer to peer transactions. Hence we reserve the
+address from PCI MMIO ranges so they are not allocated for IOVA addresses.
+
+
+Fault reporting
+---------------
+When errors are reported, the DMA engine signals via an interrupt. The fault
+reason and device that caused it with fault reason is printed on console.
+
+See below for sample.
+
+
+Boot Message Sample
+-------------------
+
+Something like this gets printed indicating presence of DMAR tables
+in ACPI.
+
+ACPI: DMAR (v001 A M I  OEMDMAR  0x00000001 MSFT 0x00000097) @ 0x000000007f5b5ef0
+
+When DMAR is being processed and initialized by ACPI, prints DMAR locations
+and any RMRR's processed.
+
+ACPI DMAR:Host address width 36
+ACPI DMAR:DRHD (flags: 0x00000000)base: 0x00000000fed90000
+ACPI DMAR:DRHD (flags: 0x00000000)base: 0x00000000fed91000
+ACPI DMAR:DRHD (flags: 0x00000001)base: 0x00000000fed93000
+ACPI DMAR:RMRR base: 0x00000000000ed000 end: 0x00000000000effff
+ACPI DMAR:RMRR base: 0x000000007f600000 end: 0x000000007fffffff
+
+When DMAR is enabled for use, you will notice..
+
+PCI-DMA: Using DMAR IOMMU
+
+Fault reporting
+---------------
+
+DMAR:[DMA Write] Request device [00:02.0] fault addr 6df084000
+DMAR:[fault reason 05] PTE Write access is not set
+DMAR:[DMA Write] Request device [00:02.0] fault addr 6df084000
+DMAR:[fault reason 05] PTE Write access is not set
+
+TBD
+----
+
+- For compatibility testing, could use unity map domain for all devices, just
+  provide a 1-1 for all useful memory under a single domain for all devices.
+- API for paravirt ops for abstracting functionlity for VMM folks.
index 19e7f65c269f21616347effd9035caeee4d2cb60..34e06d2f194fe58f082743a9407e670c442b9d85 100644 (file)
@@ -67,7 +67,7 @@ kernel patches.
 20: Check that it all passes `make headers_check'.
 
 21: Has been checked with injection of at least slab and page-allocation
-    fauilures.  See Documentation/fault-injection/.
+    failures.  See Documentation/fault-injection/.
 
     If the new code is substantial, addition of subsystem-specific fault
     injection might be appropriate.
index d7e26427e426929a35b339c35799c476c8f3573b..24f2eb40cae5e00491204e11fe8db8afd16b4aef 100644 (file)
@@ -36,8 +36,7 @@ Linux 2.4:
        If the code area has a general maintainer then please submit it to
        the maintainer listed in MAINTAINERS in the kernel file. If the
        maintainer does not respond or you cannot find the appropriate
-       maintainer then please contact Marcelo Tosatti
-       <marcelo.tosatti@cyclades.com>.
+       maintainer then please contact Willy Tarreau <w@1wt.eu>.
 
 Linux 2.6:
        The same rules apply as 2.4 except that you should follow linux-kernel
diff --git a/Documentation/accounting/cgroupstats.txt b/Documentation/accounting/cgroupstats.txt
new file mode 100644 (file)
index 0000000..eda40fd
--- /dev/null
@@ -0,0 +1,27 @@
+Control Groupstats is inspired by the discussion at
+http://lkml.org/lkml/2007/4/11/187 and implements per cgroup statistics as
+suggested by Andrew Morton in http://lkml.org/lkml/2007/4/11/263.
+
+Per cgroup statistics infrastructure re-uses code from the taskstats
+interface. A new set of cgroup operations are registered with commands
+and attributes specific to cgroups. It should be very easy to
+extend per cgroup statistics, by adding members to the cgroupstats
+structure.
+
+The current model for cgroupstats is a pull, a push model (to post
+statistics on interesting events), should be very easy to add. Currently
+user space requests for statistics by passing the cgroup path.
+Statistics about the state of all the tasks in the cgroup is returned to
+user space.
+
+NOTE: We currently rely on delay accounting for extracting information
+about tasks blocked on I/O. If CONFIG_TASK_DELAY_ACCT is disabled, this
+information will not be available.
+
+To extract cgroup statistics a utility very similar to getdelays.c
+has been developed, the sample output of the utility is shown below
+
+~/balbir/cgroupstats # ./getdelays  -C "/cgroup/a"
+sleeping 1, blocked 0, running 1, stopped 0, uninterruptible 0
+~/balbir/cgroupstats # ./getdelays  -C "/cgroup"
+sleeping 155, blocked 0, running 1, stopped 0, uninterruptible 2
index 37f4edcc5d871570dd363365d6ffcdc21d8cd750..3ed82383efea95c2293e7876c8e765cf1df42e13 100644 (file)
@@ -5,7 +5,7 @@ Introduction
 ------------
 
    The kernel provides an interface to manage DMA transfers
-   using the DMA channels in the cpu, so that the central
+   using the DMA channels in the CPU, so that the central
    duty of managing channel mappings, and programming the
    channel generators is in one place.
 
@@ -17,24 +17,24 @@ DMA Channel Ordering
    channels to all sources, which means that some devices
    have a restricted number of channels that can be used.
 
-   To allow flexibilty for each cpu type and board, the
-   dma code can be given an dma ordering structure which
+   To allow flexibility for each CPU type and board, the
+   DMA code can be given a DMA ordering structure which
    allows the order of channel search to be specified, as
    well as allowing the prohibition of certain claims.
 
    struct s3c24xx_dma_order has a list of channels, and
-   each channel within has a slot for a list of dma
-   channel numbers. The slots are searched in order, for
-   the presence of a dma channel number with DMA_CH_VALID
-   orred in.
+   each channel within has a slot for a list of DMA
+   channel numbers. The slots are searched in order for
+   the presence of a DMA channel number with DMA_CH_VALID
+   or-ed in.
 
    If the order has the flag DMA_CH_NEVER set, then after
    checking the channel list, the system will return no
    found channel, thus denying the request.
 
    A board support file can call s3c24xx_dma_order_set()
-   to register an complete ordering set. The routine will
-   copy the data, so the original can be discared with
+   to register a complete ordering set. The routine will
+   copy the data, so the original can be discarded with
    __initdata.
 
 
index d46306fea230cda4a21ee19da45337ab39898918..f20c10c2858fc7c60f3003a77c905bf108dfddd7 100644 (file)
@@ -418,6 +418,20 @@ brothers:
         */
         smp_mb__after_clear_bit();
 
+There are two special bitops with lock barrier semantics (acquire/release,
+same as spinlocks). These operate in the same way as their non-_lock/unlock
+postfixed variants, except that they are to provide acquire/release semantics,
+respectively. This means they can be used for bit_spin_trylock and
+bit_spin_unlock type operations without specifying any more barriers.
+
+       int test_and_set_bit_lock(unsigned long nr, unsigned long *addr);
+       void clear_bit_unlock(unsigned long nr, unsigned long *addr);
+       void __clear_bit_unlock(unsigned long nr, unsigned long *addr);
+
+The __clear_bit_unlock version is non-atomic, however it still implements
+unlock barrier semantics. This can be useful if the lock itself is protecting
+the other bits in the word.
+
 Finally, there are non-atomic versions of the bitmask operations
 provided.  They are used in contexts where some other higher-level SMP
 locking scheme is being used to protect the bitmask, and thus less
index 552cabac06082c460c55befab72b637724c86cd5..da42ab414c4864db4bb9d35b0cca9005b27670d2 100644 (file)
@@ -87,30 +87,7 @@ changes occur:
 
        This is used primarily during fault processing.
 
-5) void flush_tlb_pgtables(struct mm_struct *mm,
-                          unsigned long start, unsigned long end)
-
-   The software page tables for address space 'mm' for virtual
-   addresses in the range 'start' to 'end-1' are being torn down.
-
-   Some platforms cache the lowest level of the software page tables
-   in a linear virtually mapped array, to make TLB miss processing
-   more efficient.  On such platforms, since the TLB is caching the
-   software page table structure, it needs to be flushed when parts
-   of the software page table tree are unlinked/freed.
-
-   Sparc64 is one example of a platform which does this.
-
-   Usually, when munmap()'ing an area of user virtual address
-   space, the kernel leaves the page table parts around and just
-   marks the individual pte's as invalid.  However, if very large
-   portions of the address space are unmapped, the kernel frees up
-   those portions of the software page tables to prevent potential
-   excessive kernel memory usage caused by erratic mmap/mmunmap
-   sequences.  It is at these times that flush_tlb_pgtables will
-   be invoked.
-
-6) void update_mmu_cache(struct vm_area_struct *vma,
+5) void update_mmu_cache(struct vm_area_struct *vma,
                         unsigned long address, pte_t pte)
 
        At the end of every page fault, this routine is invoked to
@@ -123,7 +100,7 @@ changes occur:
        translations for software managed TLB configurations.
        The sparc64 port currently does this.
 
-7) void tlb_migrate_finish(struct mm_struct *mm)
+6) void tlb_migrate_finish(struct mm_struct *mm)
 
        This interface is called at the end of an explicit
        process migration. This interface provides a hook
index 92f94e59758229cb395a8acd28ebf8f3eb59b27f..c713aeb020c40f6bfba883031d87e83e9d783b09 100644 (file)
@@ -1009,7 +1009,7 @@ taken over the torch in maintaining \cdromc\ and integrating much
 \cdrom-related code in the 2.1-kernel.  Thanks to Scott Snyder and
 Gerd Knorr, who were the first to implement this interface for SCSI
 and IDE-CD drivers and added many ideas for extension of the data
-structures relative to kernel~2.0.  Further thanks to Heiko Eissfeldt,
+structures relative to kernel~2.0.  Further thanks to Heiko Ei{\sz}feldt,
 Thomas Quinot, Jon Tombs, Ken Pizzini, Eberhard M\"onkeberg and Andrew
 Kroll, the \linux\ \cdrom\ device driver developers who were kind
 enough to give suggestions and criticisms during the writing. Finally
diff --git a/Documentation/cgroups.txt b/Documentation/cgroups.txt
new file mode 100644 (file)
index 0000000..98a26f8
--- /dev/null
@@ -0,0 +1,545 @@
+                               CGROUPS
+                               -------
+
+Written by Paul Menage <menage@google.com> based on Documentation/cpusets.txt
+
+Original copyright statements from cpusets.txt:
+Portions Copyright (C) 2004 BULL SA.
+Portions Copyright (c) 2004-2006 Silicon Graphics, Inc.
+Modified by Paul Jackson <pj@sgi.com>
+Modified by Christoph Lameter <clameter@sgi.com>
+
+CONTENTS:
+=========
+
+1. Control Groups
+  1.1 What are cgroups ?
+  1.2 Why are cgroups needed ?
+  1.3 How are cgroups implemented ?
+  1.4 What does notify_on_release do ?
+  1.5 How do I use cgroups ?
+2. Usage Examples and Syntax
+  2.1 Basic Usage
+  2.2 Attaching processes
+3. Kernel API
+  3.1 Overview
+  3.2 Synchronization
+  3.3 Subsystem API
+4. Questions
+
+1. Control Groups
+==========
+
+1.1 What are cgroups ?
+----------------------
+
+Control Groups provide a mechanism for aggregating/partitioning sets of
+tasks, and all their future children, into hierarchical groups with
+specialized behaviour.
+
+Definitions:
+
+A *cgroup* associates a set of tasks with a set of parameters for one
+or more subsystems.
+
+A *subsystem* is a module that makes use of the task grouping
+facilities provided by cgroups to treat groups of tasks in
+particular ways. A subsystem is typically a "resource controller" that
+schedules a resource or applies per-cgroup limits, but it may be
+anything that wants to act on a group of processes, e.g. a
+virtualization subsystem.
+
+A *hierarchy* is a set of cgroups arranged in a tree, such that
+every task in the system is in exactly one of the cgroups in the
+hierarchy, and a set of subsystems; each subsystem has system-specific
+state attached to each cgroup in the hierarchy.  Each hierarchy has
+an instance of the cgroup virtual filesystem associated with it.
+
+At any one time there may be multiple active hierachies of task
+cgroups. Each hierarchy is a partition of all tasks in the system.
+
+User level code may create and destroy cgroups by name in an
+instance of the cgroup virtual file system, specify and query to
+which cgroup a task is assigned, and list the task pids assigned to
+a cgroup. Those creations and assignments only affect the hierarchy
+associated with that instance of the cgroup file system.
+
+On their own, the only use for cgroups is for simple job
+tracking. The intention is that other subsystems hook into the generic
+cgroup support to provide new attributes for cgroups, such as
+accounting/limiting the resources which processes in a cgroup can
+access. For example, cpusets (see Documentation/cpusets.txt) allows
+you to associate a set of CPUs and a set of memory nodes with the
+tasks in each cgroup.
+
+1.2 Why are cgroups needed ?
+----------------------------
+
+There are multiple efforts to provide process aggregations in the
+Linux kernel, mainly for resource tracking purposes. Such efforts
+include cpusets, CKRM/ResGroups, UserBeanCounters, and virtual server
+namespaces. These all require the basic notion of a
+grouping/partitioning of processes, with newly forked processes ending
+in the same group (cgroup) as their parent process.
+
+The kernel cgroup patch provides the minimum essential kernel
+mechanisms required to efficiently implement such groups. It has
+minimal impact on the system fast paths, and provides hooks for
+specific subsystems such as cpusets to provide additional behaviour as
+desired.
+
+Multiple hierarchy support is provided to allow for situations where
+the division of tasks into cgroups is distinctly different for
+different subsystems - having parallel hierarchies allows each
+hierarchy to be a natural division of tasks, without having to handle
+complex combinations of tasks that would be present if several
+unrelated subsystems needed to be forced into the same tree of
+cgroups.
+
+At one extreme, each resource controller or subsystem could be in a
+separate hierarchy; at the other extreme, all subsystems
+would be attached to the same hierarchy.
+
+As an example of a scenario (originally proposed by vatsa@in.ibm.com)
+that can benefit from multiple hierarchies, consider a large
+university server with various users - students, professors, system
+tasks etc. The resource planning for this server could be along the
+following lines:
+
+       CPU :           Top cpuset
+                       /       \
+               CPUSet1         CPUSet2
+                  |              |
+               (Profs)         (Students)
+
+               In addition (system tasks) are attached to topcpuset (so
+               that they can run anywhere) with a limit of 20%
+
+       Memory : Professors (50%), students (30%), system (20%)
+
+       Disk : Prof (50%), students (30%), system (20%)
+
+       Network : WWW browsing (20%), Network File System (60%), others (20%)
+                               / \
+                       Prof (15%) students (5%)
+
+Browsers like firefox/lynx go into the WWW network class, while (k)nfsd go
+into NFS network class.
+
+At the same time firefox/lynx will share an appropriate CPU/Memory class
+depending on who launched it (prof/student).
+
+With the ability to classify tasks differently for different resources
+(by putting those resource subsystems in different hierarchies) then
+the admin can easily set up a script which receives exec notifications
+and depending on who is launching the browser he can
+
+       # echo browser_pid > /mnt/<restype>/<userclass>/tasks
+
+With only a single hierarchy, he now would potentially have to create
+a separate cgroup for every browser launched and associate it with
+approp network and other resource class.  This may lead to
+proliferation of such cgroups.
+
+Also lets say that the administrator would like to give enhanced network
+access temporarily to a student's browser (since it is night and the user
+wants to do online gaming :)  OR give one of the students simulation
+apps enhanced CPU power,
+
+With ability to write pids directly to resource classes, its just a
+matter of :
+
+       # echo pid > /mnt/network/<new_class>/tasks
+       (after some time)
+       # echo pid > /mnt/network/<orig_class>/tasks
+
+Without this ability, he would have to split the cgroup into
+multiple separate ones and then associate the new cgroups with the
+new resource classes.
+
+
+
+1.3 How are cgroups implemented ?
+---------------------------------
+
+Control Groups extends the kernel as follows:
+
+ - Each task in the system has a reference-counted pointer to a
+   css_set.
+
+ - A css_set contains a set of reference-counted pointers to
+   cgroup_subsys_state objects, one for each cgroup subsystem
+   registered in the system. There is no direct link from a task to
+   the cgroup of which it's a member in each hierarchy, but this
+   can be determined by following pointers through the
+   cgroup_subsys_state objects. This is because accessing the
+   subsystem state is something that's expected to happen frequently
+   and in performance-critical code, whereas operations that require a
+   task's actual cgroup assignments (in particular, moving between
+   cgroups) are less common. A linked list runs through the cg_list
+   field of each task_struct using the css_set, anchored at
+   css_set->tasks.
+
+ - A cgroup hierarchy filesystem can be mounted  for browsing and
+   manipulation from user space.
+
+ - You can list all the tasks (by pid) attached to any cgroup.
+
+The implementation of cgroups requires a few, simple hooks
+into the rest of the kernel, none in performance critical paths:
+
+ - in init/main.c, to initialize the root cgroups and initial
+   css_set at system boot.
+
+ - in fork and exit, to attach and detach a task from its css_set.
+
+In addition a new file system, of type "cgroup" may be mounted, to
+enable browsing and modifying the cgroups presently known to the
+kernel.  When mounting a cgroup hierarchy, you may specify a
+comma-separated list of subsystems to mount as the filesystem mount
+options.  By default, mounting the cgroup filesystem attempts to
+mount a hierarchy containing all registered subsystems.
+
+If an active hierarchy with exactly the same set of subsystems already
+exists, it will be reused for the new mount. If no existing hierarchy
+matches, and any of the requested subsystems are in use in an existing
+hierarchy, the mount will fail with -EBUSY. Otherwise, a new hierarchy
+is activated, associated with the requested subsystems.
+
+It's not currently possible to bind a new subsystem to an active
+cgroup hierarchy, or to unbind a subsystem from an active cgroup
+hierarchy. This may be possible in future, but is fraught with nasty
+error-recovery issues.
+
+When a cgroup filesystem is unmounted, if there are any
+child cgroups created below the top-level cgroup, that hierarchy
+will remain active even though unmounted; if there are no
+child cgroups then the hierarchy will be deactivated.
+
+No new system calls are added for cgroups - all support for
+querying and modifying cgroups is via this cgroup file system.
+
+Each task under /proc has an added file named 'cgroup' displaying,
+for each active hierarchy, the subsystem names and the cgroup name
+as the path relative to the root of the cgroup file system.
+
+Each cgroup is represented by a directory in the cgroup file system
+containing the following files describing that cgroup:
+
+ - tasks: list of tasks (by pid) attached to that cgroup
+ - notify_on_release flag: run /sbin/cgroup_release_agent on exit?
+
+Other subsystems such as cpusets may add additional files in each
+cgroup dir
+
+New cgroups are created using the mkdir system call or shell
+command.  The properties of a cgroup, such as its flags, are
+modified by writing to the appropriate file in that cgroups
+directory, as listed above.
+
+The named hierarchical structure of nested cgroups allows partitioning
+a large system into nested, dynamically changeable, "soft-partitions".
+
+The attachment of each task, automatically inherited at fork by any
+children of that task, to a cgroup allows organizing the work load
+on a system into related sets of tasks.  A task may be re-attached to
+any other cgroup, if allowed by the permissions on the necessary
+cgroup file system directories.
+
+When a task is moved from one cgroup to another, it gets a new
+css_set pointer - if there's an already existing css_set with the
+desired collection of cgroups then that group is reused, else a new
+css_set is allocated. Note that the current implementation uses a
+linear search to locate an appropriate existing css_set, so isn't
+very efficient. A future version will use a hash table for better
+performance.
+
+To allow access from a cgroup to the css_sets (and hence tasks)
+that comprise it, a set of cg_cgroup_link objects form a lattice;
+each cg_cgroup_link is linked into a list of cg_cgroup_links for
+a single cgroup on its cont_link_list field, and a list of
+cg_cgroup_links for a single css_set on its cg_link_list.
+
+Thus the set of tasks in a cgroup can be listed by iterating over
+each css_set that references the cgroup, and sub-iterating over
+each css_set's task set.
+
+The use of a Linux virtual file system (vfs) to represent the
+cgroup hierarchy provides for a familiar permission and name space
+for cgroups, with a minimum of additional kernel code.
+
+1.4 What does notify_on_release do ?
+------------------------------------
+
+*** notify_on_release is disabled in the current patch set. It will be
+*** reactivated in a future patch in a less-intrusive manner
+
+If the notify_on_release flag is enabled (1) in a cgroup, then
+whenever the last task in the cgroup leaves (exits or attaches to
+some other cgroup) and the last child cgroup of that cgroup
+is removed, then the kernel runs the command specified by the contents
+of the "release_agent" file in that hierarchy's root directory,
+supplying the pathname (relative to the mount point of the cgroup
+file system) of the abandoned cgroup.  This enables automatic
+removal of abandoned cgroups.  The default value of
+notify_on_release in the root cgroup at system boot is disabled
+(0).  The default value of other cgroups at creation is the current
+value of their parents notify_on_release setting. The default value of
+a cgroup hierarchy's release_agent path is empty.
+
+1.5 How do I use cgroups ?
+--------------------------
+
+To start a new job that is to be contained within a cgroup, using
+the "cpuset" cgroup subsystem, the steps are something like:
+
+ 1) mkdir /dev/cgroup
+ 2) mount -t cgroup -ocpuset cpuset /dev/cgroup
+ 3) Create the new cgroup by doing mkdir's and write's (or echo's) in
+    the /dev/cgroup virtual file system.
+ 4) Start a task that will be the "founding father" of the new job.
+ 5) Attach that task to the new cgroup by writing its pid to the
+    /dev/cgroup tasks file for that cgroup.
+ 6) fork, exec or clone the job tasks from this founding father task.
+
+For example, the following sequence of commands will setup a cgroup
+named "Charlie", containing just CPUs 2 and 3, and Memory Node 1,
+and then start a subshell 'sh' in that cgroup:
+
+  mount -t cgroup cpuset -ocpuset /dev/cgroup
+  cd /dev/cgroup
+  mkdir Charlie
+  cd Charlie
+  /bin/echo 2-3 > cpus
+  /bin/echo 1 > mems
+  /bin/echo $$ > tasks
+  sh
+  # The subshell 'sh' is now running in cgroup Charlie
+  # The next line should display '/Charlie'
+  cat /proc/self/cgroup
+
+2. Usage Examples and Syntax
+============================
+
+2.1 Basic Usage
+---------------
+
+Creating, modifying, using the cgroups can be done through the cgroup
+virtual filesystem.
+
+To mount a cgroup hierarchy will all available subsystems, type:
+# mount -t cgroup xxx /dev/cgroup
+
+The "xxx" is not interpreted by the cgroup code, but will appear in
+/proc/mounts so may be any useful identifying string that you like.
+
+To mount a cgroup hierarchy with just the cpuset and numtasks
+subsystems, type:
+# mount -t cgroup -o cpuset,numtasks hier1 /dev/cgroup
+
+To change the set of subsystems bound to a mounted hierarchy, just
+remount with different options:
+
+# mount -o remount,cpuset,ns  /dev/cgroup
+
+Note that changing the set of subsystems is currently only supported
+when the hierarchy consists of a single (root) cgroup. Supporting
+the ability to arbitrarily bind/unbind subsystems from an existing
+cgroup hierarchy is intended to be implemented in the future.
+
+Then under /dev/cgroup you can find a tree that corresponds to the
+tree of the cgroups in the system. For instance, /dev/cgroup
+is the cgroup that holds the whole system.
+
+If you want to create a new cgroup under /dev/cgroup:
+# cd /dev/cgroup
+# mkdir my_cgroup
+
+Now you want to do something with this cgroup.
+# cd my_cgroup
+
+In this directory you can find several files:
+# ls
+notify_on_release release_agent tasks
+(plus whatever files are added by the attached subsystems)
+
+Now attach your shell to this cgroup:
+# /bin/echo $$ > tasks
+
+You can also create cgroups inside your cgroup by using mkdir in this
+directory.
+# mkdir my_sub_cs
+
+To remove a cgroup, just use rmdir:
+# rmdir my_sub_cs
+
+This will fail if the cgroup is in use (has cgroups inside, or
+has processes attached, or is held alive by other subsystem-specific
+reference).
+
+2.2 Attaching processes
+-----------------------
+
+# /bin/echo PID > tasks
+
+Note that it is PID, not PIDs. You can only attach ONE task at a time.
+If you have several tasks to attach, you have to do it one after another:
+
+# /bin/echo PID1 > tasks
+# /bin/echo PID2 > tasks
+       ...
+# /bin/echo PIDn > tasks
+
+3. Kernel API
+=============
+
+3.1 Overview
+------------
+
+Each kernel subsystem that wants to hook into the generic cgroup
+system needs to create a cgroup_subsys object. This contains
+various methods, which are callbacks from the cgroup system, along
+with a subsystem id which will be assigned by the cgroup system.
+
+Other fields in the cgroup_subsys object include:
+
+- subsys_id: a unique array index for the subsystem, indicating which
+  entry in cgroup->subsys[] this subsystem should be
+  managing. Initialized by cgroup_register_subsys(); prior to this
+  it should be initialized to -1
+
+- hierarchy: an index indicating which hierarchy, if any, this
+  subsystem is currently attached to. If this is -1, then the
+  subsystem is not attached to any hierarchy, and all tasks should be
+  considered to be members of the subsystem's top_cgroup. It should
+  be initialized to -1.
+
+- name: should be initialized to a unique subsystem name prior to
+  calling cgroup_register_subsystem. Should be no longer than
+  MAX_CGROUP_TYPE_NAMELEN
+
+Each cgroup object created by the system has an array of pointers,
+indexed by subsystem id; this pointer is entirely managed by the
+subsystem; the generic cgroup code will never touch this pointer.
+
+3.2 Synchronization
+-------------------
+
+There is a global mutex, cgroup_mutex, used by the cgroup
+system. This should be taken by anything that wants to modify a
+cgroup. It may also be taken to prevent cgroups from being
+modified, but more specific locks may be more appropriate in that
+situation.
+
+See kernel/cgroup.c for more details.
+
+Subsystems can take/release the cgroup_mutex via the functions
+cgroup_lock()/cgroup_unlock(), and can
+take/release the callback_mutex via the functions
+cgroup_lock()/cgroup_unlock().
+
+Accessing a task's cgroup pointer may be done in the following ways:
+- while holding cgroup_mutex
+- while holding the task's alloc_lock (via task_lock())
+- inside an rcu_read_lock() section via rcu_dereference()
+
+3.3 Subsystem API
+--------------------------
+
+Each subsystem should:
+
+- add an entry in linux/cgroup_subsys.h
+- define a cgroup_subsys object called <name>_subsys
+
+Each subsystem may export the following methods. The only mandatory
+methods are create/destroy. Any others that are null are presumed to
+be successful no-ops.
+
+struct cgroup_subsys_state *create(struct cgroup *cont)
+LL=cgroup_mutex
+
+Called to create a subsystem state object for a cgroup. The
+subsystem should allocate its subsystem state object for the passed
+cgroup, returning a pointer to the new object on success or a
+negative error code. On success, the subsystem pointer should point to
+a structure of type cgroup_subsys_state (typically embedded in a
+larger subsystem-specific object), which will be initialized by the
+cgroup system. Note that this will be called at initialization to
+create the root subsystem state for this subsystem; this case can be
+identified by the passed cgroup object having a NULL parent (since
+it's the root of the hierarchy) and may be an appropriate place for
+initialization code.
+
+void destroy(struct cgroup *cont)
+LL=cgroup_mutex
+
+The cgroup system is about to destroy the passed cgroup; the
+subsystem should do any necessary cleanup
+
+int can_attach(struct cgroup_subsys *ss, struct cgroup *cont,
+              struct task_struct *task)
+LL=cgroup_mutex
+
+Called prior to moving a task into a cgroup; if the subsystem
+returns an error, this will abort the attach operation.  If a NULL
+task is passed, then a successful result indicates that *any*
+unspecified task can be moved into the cgroup. Note that this isn't
+called on a fork. If this method returns 0 (success) then this should
+remain valid while the caller holds cgroup_mutex.
+
+void attach(struct cgroup_subsys *ss, struct cgroup *cont,
+           struct cgroup *old_cont, struct task_struct *task)
+LL=cgroup_mutex
+
+
+Called after the task has been attached to the cgroup, to allow any
+post-attachment activity that requires memory allocations or blocking.
+
+void fork(struct cgroup_subsy *ss, struct task_struct *task)
+LL=callback_mutex, maybe read_lock(tasklist_lock)
+
+Called when a task is forked into a cgroup. Also called during
+registration for all existing tasks.
+
+void exit(struct cgroup_subsys *ss, struct task_struct *task)
+LL=callback_mutex
+
+Called during task exit
+
+int populate(struct cgroup_subsys *ss, struct cgroup *cont)
+LL=none
+
+Called after creation of a cgroup to allow a subsystem to populate
+the cgroup directory with file entries.  The subsystem should make
+calls to cgroup_add_file() with objects of type cftype (see
+include/linux/cgroup.h for details).  Note that although this
+method can return an error code, the error code is currently not
+always handled well.
+
+void post_clone(struct cgroup_subsys *ss, struct cgroup *cont)
+
+Called at the end of cgroup_clone() to do any paramater
+initialization which might be required before a task could attach.  For
+example in cpusets, no task may attach before 'cpus' and 'mems' are set
+up.
+
+void bind(struct cgroup_subsys *ss, struct cgroup *root)
+LL=callback_mutex
+
+Called when a cgroup subsystem is rebound to a different hierarchy
+and root cgroup. Currently this will only involve movement between
+the default hierarchy (which never has sub-cgroups) and a hierarchy
+that is being created/destroyed (and hence has no sub-cgroups).
+
+4. Questions
+============
+
+Q: what's up with this '/bin/echo' ?
+A: bash's builtin 'echo' command does not check calls to write() against
+   errors. If you use it in the cgroup file system, you won't be
+   able to tell whether a command succeeded or failed.
+
+Q: When I attach processes, only the first of the line gets really attached !
+A: We can only return one error code per call to write(). So you should also
+   put only ONE pid.
+
index b6d24c22274b8dfb0ea28c3e841594779f5b20e7..a741f658a3c9d7393c9693bb4486d30473438222 100644 (file)
@@ -220,7 +220,9 @@ A: The following happen, listed in no particular order :-)
   CPU_DOWN_PREPARE or CPU_DOWN_PREPARE_FROZEN, depending on whether or not the
   CPU is being offlined while tasks are frozen due to a suspend operation in
   progress
-- All process is migrated away from this outgoing CPU to a new CPU
+- All processes are migrated away from this outgoing CPU to new CPUs.
+  The new CPU is chosen from each process' current cpuset, which may be
+  a subset of all online CPUs.
 - All interrupts targeted to this CPU is migrated to a new CPU
 - timers/bottom half/task lets are also migrated to a new CPU
 - Once all services are migrated, kernel calls an arch specific routine
index ec9de6917f01f34c088cd612121caaadc3edf08b..141bef1c859903bdb31cada3b8e3f7745827dc57 100644 (file)
@@ -7,6 +7,7 @@ Written by Simon.Derr@bull.net
 Portions Copyright (c) 2004-2006 Silicon Graphics, Inc.
 Modified by Paul Jackson <pj@sgi.com>
 Modified by Christoph Lameter <clameter@sgi.com>
+Modified by Paul Menage <menage@google.com>
 
 CONTENTS:
 =========
@@ -16,9 +17,9 @@ CONTENTS:
   1.2 Why are cpusets needed ?
   1.3 How are cpusets implemented ?
   1.4 What are exclusive cpusets ?
-  1.5 What does notify_on_release do ?
-  1.6 What is memory_pressure ?
-  1.7 What is memory spread ?
+  1.5 What is memory_pressure ?
+  1.6 What is memory spread ?
+  1.7 What is sched_load_balance ?
   1.8 How do I use cpusets ?
 2. Usage Examples and Syntax
   2.1 Basic Usage
@@ -44,18 +45,19 @@ hierarchy visible in a virtual file system.  These are the essential
 hooks, beyond what is already present, required to manage dynamic
 job placement on large systems.
 
-Each task has a pointer to a cpuset.  Multiple tasks may reference
-the same cpuset.  Requests by a task, using the sched_setaffinity(2)
-system call to include CPUs in its CPU affinity mask, and using the
-mbind(2) and set_mempolicy(2) system calls to include Memory Nodes
-in its memory policy, are both filtered through that tasks cpuset,
-filtering out any CPUs or Memory Nodes not in that cpuset.  The
-scheduler will not schedule a task on a CPU that is not allowed in
-its cpus_allowed vector, and the kernel page allocator will not
-allocate a page on a node that is not allowed in the requesting tasks
-mems_allowed vector.
-
-User level code may create and destroy cpusets by name in the cpuset
+Cpusets use the generic cgroup subsystem described in
+Documentation/cgroup.txt.
+
+Requests by a task, using the sched_setaffinity(2) system call to
+include CPUs in its CPU affinity mask, and using the mbind(2) and
+set_mempolicy(2) system calls to include Memory Nodes in its memory
+policy, are both filtered through that tasks cpuset, filtering out any
+CPUs or Memory Nodes not in that cpuset.  The scheduler will not
+schedule a task on a CPU that is not allowed in its cpus_allowed
+vector, and the kernel page allocator will not allocate a page on a
+node that is not allowed in the requesting tasks mems_allowed vector.
+
+User level code may create and destroy cpusets by name in the cgroup
 virtual file system, manage the attributes and permissions of these
 cpusets and which CPUs and Memory Nodes are assigned to each cpuset,
 specify and query to which cpuset a task is assigned, and list the
@@ -115,7 +117,7 @@ Cpusets extends these two mechanisms as follows:
  - Cpusets are sets of allowed CPUs and Memory Nodes, known to the
    kernel.
  - Each task in the system is attached to a cpuset, via a pointer
-   in the task structure to a reference counted cpuset structure.
+   in the task structure to a reference counted cgroup structure.
  - Calls to sched_setaffinity are filtered to just those CPUs
    allowed in that tasks cpuset.
  - Calls to mbind and set_mempolicy are filtered to just
@@ -145,15 +147,10 @@ into the rest of the kernel, none in performance critical paths:
  - in page_alloc.c, to restrict memory to allowed nodes.
  - in vmscan.c, to restrict page recovery to the current cpuset.
 
-In addition a new file system, of type "cpuset" may be mounted,
-typically at /dev/cpuset, to enable browsing and modifying the cpusets
-presently known to the kernel.  No new system calls are added for
-cpusets - all support for querying and modifying cpusets is via
-this cpuset file system.
-
-Each task under /proc has an added file named 'cpuset', displaying
-the cpuset name, as the path relative to the root of the cpuset file
-system.
+You should mount the "cgroup" filesystem type in order to enable
+browsing and modifying the cpusets presently known to the kernel.  No
+new system calls are added for cpusets - all support for querying and
+modifying cpusets is via this cpuset file system.
 
 The /proc/<pid>/status file for each task has two added lines,
 displaying the tasks cpus_allowed (on which CPUs it may be scheduled)
@@ -163,16 +160,15 @@ in the format seen in the following example:
   Cpus_allowed:   ffffffff,ffffffff,ffffffff,ffffffff
   Mems_allowed:   ffffffff,ffffffff
 
-Each cpuset is represented by a directory in the cpuset file system
-containing the following files describing that cpuset:
+Each cpuset is represented by a directory in the cgroup file system
+containing (on top of the standard cgroup files) the following
+files describing that cpuset:
 
  - cpus: list of CPUs in that cpuset
  - mems: list of Memory Nodes in that cpuset
  - memory_migrate flag: if set, move pages to cpusets nodes
  - cpu_exclusive flag: is cpu placement exclusive?
  - mem_exclusive flag: is memory placement exclusive?
- - tasks: list of tasks (by pid) attached to that cpuset
- - notify_on_release flag: run /sbin/cpuset_release_agent on exit?
  - memory_pressure: measure of how much paging pressure in cpuset
 
 In addition, the root cpuset only has the following file:
@@ -237,21 +233,7 @@ such as requests from interrupt handlers, is allowed to be taken
 outside even a mem_exclusive cpuset.
 
 
-1.5 What does notify_on_release do ?
-------------------------------------
-
-If the notify_on_release flag is enabled (1) in a cpuset, then whenever
-the last task in the cpuset leaves (exits or attaches to some other
-cpuset) and the last child cpuset of that cpuset is removed, then
-the kernel runs the command /sbin/cpuset_release_agent, supplying the
-pathname (relative to the mount point of the cpuset file system) of the
-abandoned cpuset.  This enables automatic removal of abandoned cpusets.
-The default value of notify_on_release in the root cpuset at system
-boot is disabled (0).  The default value of other cpusets at creation
-is the current value of their parents notify_on_release setting.
-
-
-1.6 What is memory_pressure ?
+1.5 What is memory_pressure ?
 -----------------------------
 The memory_pressure of a cpuset provides a simple per-cpuset metric
 of the rate that the tasks in a cpuset are attempting to free up in
@@ -308,7 +290,7 @@ the tasks in the cpuset, in units of reclaims attempted per second,
 times 1000.
 
 
-1.7 What is memory spread ?
+1.6 What is memory spread ?
 ---------------------------
 There are two boolean flag files per cpuset that control where the
 kernel allocates pages for the file system buffers and related in
@@ -378,6 +360,142 @@ policy, especially for jobs that might have one thread reading in the
 data set, the memory allocation across the nodes in the jobs cpuset
 can become very uneven.
 
+1.7 What is sched_load_balance ?
+--------------------------------
+
+The kernel scheduler (kernel/sched.c) automatically load balances
+tasks.  If one CPU is underutilized, kernel code running on that
+CPU will look for tasks on other more overloaded CPUs and move those
+tasks to itself, within the constraints of such placement mechanisms
+as cpusets and sched_setaffinity.
+
+The algorithmic cost of load balancing and its impact on key shared
+kernel data structures such as the task list increases more than
+linearly with the number of CPUs being balanced.  So the scheduler
+has support to  partition the systems CPUs into a number of sched
+domains such that it only load balances within each sched domain.
+Each sched domain covers some subset of the CPUs in the system;
+no two sched domains overlap; some CPUs might not be in any sched
+domain and hence won't be load balanced.
+
+Put simply, it costs less to balance between two smaller sched domains
+than one big one, but doing so means that overloads in one of the
+two domains won't be load balanced to the other one.
+
+By default, there is one sched domain covering all CPUs, except those
+marked isolated using the kernel boot time "isolcpus=" argument.
+
+This default load balancing across all CPUs is not well suited for
+the following two situations:
+ 1) On large systems, load balancing across many CPUs is expensive.
+    If the system is managed using cpusets to place independent jobs
+    on separate sets of CPUs, full load balancing is unnecessary.
+ 2) Systems supporting realtime on some CPUs need to minimize
+    system overhead on those CPUs, including avoiding task load
+    balancing if that is not needed.
+
+When the per-cpuset flag "sched_load_balance" is enabled (the default
+setting), it requests that all the CPUs in that cpusets allowed 'cpus'
+be contained in a single sched domain, ensuring that load balancing
+can move a task (not otherwised pinned, as by sched_setaffinity)
+from any CPU in that cpuset to any other.
+
+When the per-cpuset flag "sched_load_balance" is disabled, then the
+scheduler will avoid load balancing across the CPUs in that cpuset,
+--except-- in so far as is necessary because some overlapping cpuset
+has "sched_load_balance" enabled.
+
+So, for example, if the top cpuset has the flag "sched_load_balance"
+enabled, then the scheduler will have one sched domain covering all
+CPUs, and the setting of the "sched_load_balance" flag in any other
+cpusets won't matter, as we're already fully load balancing.
+
+Therefore in the above two situations, the top cpuset flag
+"sched_load_balance" should be disabled, and only some of the smaller,
+child cpusets have this flag enabled.
+
+When doing this, you don't usually want to leave any unpinned tasks in
+the top cpuset that might use non-trivial amounts of CPU, as such tasks
+may be artificially constrained to some subset of CPUs, depending on
+the particulars of this flag setting in descendent cpusets.  Even if
+such a task could use spare CPU cycles in some other CPUs, the kernel
+scheduler might not consider the possibility of load balancing that
+task to that underused CPU.
+
+Of course, tasks pinned to a particular CPU can be left in a cpuset
+that disables "sched_load_balance" as those tasks aren't going anywhere
+else anyway.
+
+There is an impedance mismatch here, between cpusets and sched domains.
+Cpusets are hierarchical and nest.  Sched domains are flat; they don't
+overlap and each CPU is in at most one sched domain.
+
+It is necessary for sched domains to be flat because load balancing
+across partially overlapping sets of CPUs would risk unstable dynamics
+that would be beyond our understanding.  So if each of two partially
+overlapping cpusets enables the flag 'sched_load_balance', then we
+form a single sched domain that is a superset of both.  We won't move
+a task to a CPU outside it cpuset, but the scheduler load balancing
+code might waste some compute cycles considering that possibility.
+
+This mismatch is why there is not a simple one-to-one relation
+between which cpusets have the flag "sched_load_balance" enabled,
+and the sched domain configuration.  If a cpuset enables the flag, it
+will get balancing across all its CPUs, but if it disables the flag,
+it will only be assured of no load balancing if no other overlapping
+cpuset enables the flag.
+
+If two cpusets have partially overlapping 'cpus' allowed, and only
+one of them has this flag enabled, then the other may find its
+tasks only partially load balanced, just on the overlapping CPUs.
+This is just the general case of the top_cpuset example given a few
+paragraphs above.  In the general case, as in the top cpuset case,
+don't leave tasks that might use non-trivial amounts of CPU in
+such partially load balanced cpusets, as they may be artificially
+constrained to some subset of the CPUs allowed to them, for lack of
+load balancing to the other CPUs.
+
+1.7.1 sched_load_balance implementation details.
+------------------------------------------------
+
+The per-cpuset flag 'sched_load_balance' defaults to enabled (contrary
+to most cpuset flags.)  When enabled for a cpuset, the kernel will
+ensure that it can load balance across all the CPUs in that cpuset
+(makes sure that all the CPUs in the cpus_allowed of that cpuset are
+in the same sched domain.)
+
+If two overlapping cpusets both have 'sched_load_balance' enabled,
+then they will be (must be) both in the same sched domain.
+
+If, as is the default, the top cpuset has 'sched_load_balance' enabled,
+then by the above that means there is a single sched domain covering
+the whole system, regardless of any other cpuset settings.
+
+The kernel commits to user space that it will avoid load balancing
+where it can.  It will pick as fine a granularity partition of sched
+domains as it can while still providing load balancing for any set
+of CPUs allowed to a cpuset having 'sched_load_balance' enabled.
+
+The internal kernel cpuset to scheduler interface passes from the
+cpuset code to the scheduler code a partition of the load balanced
+CPUs in the system. This partition is a set of subsets (represented
+as an array of cpumask_t) of CPUs, pairwise disjoint, that cover all
+the CPUs that must be load balanced.
+
+Whenever the 'sched_load_balance' flag changes, or CPUs come or go
+from a cpuset with this flag enabled, or a cpuset with this flag
+enabled is removed, the cpuset code builds a new such partition and
+passes it to the scheduler sched domain setup code, to have the sched
+domains rebuilt as necessary.
+
+This partition exactly defines what sched domains the scheduler should
+setup - one sched domain for each element (cpumask_t) in the partition.
+
+The scheduler remembers the currently active sched domain partitions.
+When the scheduler routine partition_sched_domains() is invoked from
+the cpuset code to update these sched domains, it compares the new
+partition requested with the current, and updates its sched domains,
+removing the old and adding the new, for each change.
 
 1.8 How do I use cpusets ?
 --------------------------
@@ -469,7 +587,7 @@ than stress the kernel.
 To start a new job that is to be contained within a cpuset, the steps are:
 
  1) mkdir /dev/cpuset
- 2) mount -t cpuset none /dev/cpuset
+ 2) mount -t cgroup -ocpuset cpuset /dev/cpuset
  3) Create the new cpuset by doing mkdir's and write's (or echo's) in
     the /dev/cpuset virtual file system.
  4) Start a task that will be the "founding father" of the new job.
@@ -481,7 +599,7 @@ For example, the following sequence of commands will setup a cpuset
 named "Charlie", containing just CPUs 2 and 3, and Memory Node 1,
 and then start a subshell 'sh' in that cpuset:
 
-  mount -t cpuset none /dev/cpuset
+  mount -t cgroup -ocpuset cpuset /dev/cpuset
   cd /dev/cpuset
   mkdir Charlie
   cd Charlie
@@ -513,7 +631,7 @@ Creating, modifying, using the cpusets can be done through the cpuset
 virtual filesystem.
 
 To mount it, type:
-# mount -t cpuset none /dev/cpuset
+# mount -t cgroup -o cpuset cpuset /dev/cpuset
 
 Then under /dev/cpuset you can find a tree that corresponds to the
 tree of the cpusets in the system. For instance, /dev/cpuset
@@ -556,6 +674,18 @@ To remove a cpuset, just use rmdir:
 This will fail if the cpuset is in use (has cpusets inside, or has
 processes attached).
 
+Note that for legacy reasons, the "cpuset" filesystem exists as a
+wrapper around the cgroup filesystem.
+
+The command
+
+mount -t cpuset X /dev/cpuset
+
+is equivalent to
+
+mount -t cgroup -ocpuset X /dev/cpuset
+echo "/sbin/cpuset_release_agent" > /dev/cpuset/release_agent
+
 2.2 Adding/removing cpus
 ------------------------
 
diff --git a/Documentation/device-mapper/dm-uevent.txt b/Documentation/device-mapper/dm-uevent.txt
new file mode 100644 (file)
index 0000000..07edbd8
--- /dev/null
@@ -0,0 +1,97 @@
+The device-mapper uevent code adds the capability to device-mapper to create
+and send kobject uevents (uevents).  Previously device-mapper events were only
+available through the ioctl interface.  The advantage of the uevents interface
+is the event contains environment attributes providing increased context for
+the event avoiding the need to query the state of the device-mapper device after
+the event is received.
+
+There are two functions currently for device-mapper events.  The first function
+listed creates the event and the second function sends the event(s).
+
+void dm_path_uevent(enum dm_uevent_type event_type, struct dm_target *ti,
+                    const char *path, unsigned nr_valid_paths)
+
+void dm_send_uevents(struct list_head *events, struct kobject *kobj)
+
+
+The variables added to the uevent environment are:
+
+Variable Name: DM_TARGET
+Uevent Action(s): KOBJ_CHANGE
+Type: string
+Description:
+Value: Name of device-mapper target that generated the event.
+
+Variable Name: DM_ACTION
+Uevent Action(s): KOBJ_CHANGE
+Type: string
+Description:
+Value: Device-mapper specific action that caused the uevent action.
+       PATH_FAILED - A path has failed.
+       PATH_REINSTATED - A path has been reinstated.
+
+Variable Name: DM_SEQNUM
+Uevent Action(s): KOBJ_CHANGE
+Type: unsigned integer
+Description: A sequence number for this specific device-mapper device.
+Value: Valid unsigned integer range.
+
+Variable Name: DM_PATH
+Uevent Action(s): KOBJ_CHANGE
+Type: string
+Description: Major and minor number of the path device pertaining to this
+event.
+Value: Path name in the form of "Major:Minor"
+
+Variable Name: DM_NR_VALID_PATHS
+Uevent Action(s): KOBJ_CHANGE
+Type: unsigned integer
+Description:
+Value: Valid unsigned integer range.
+
+Variable Name: DM_NAME
+Uevent Action(s): KOBJ_CHANGE
+Type: string
+Description: Name of the device-mapper device.
+Value: Name
+
+Variable Name: DM_UUID
+Uevent Action(s): KOBJ_CHANGE
+Type: string
+Description: UUID of the device-mapper device.
+Value: UUID. (Empty string if there isn't one.)
+
+An example of the uevents generated as captured by udevmonitor is shown
+below.
+
+1.) Path failure.
+UEVENT[1192521009.711215] change@/block/dm-3
+ACTION=change
+DEVPATH=/block/dm-3
+SUBSYSTEM=block
+DM_TARGET=multipath
+DM_ACTION=PATH_FAILED
+DM_SEQNUM=1
+DM_PATH=8:32
+DM_NR_VALID_PATHS=0
+DM_NAME=mpath2
+DM_UUID=mpath-35333333000002328
+MINOR=3
+MAJOR=253
+SEQNUM=1130
+
+2.) Path reinstate.
+UEVENT[1192521132.989927] change@/block/dm-3
+ACTION=change
+DEVPATH=/block/dm-3
+SUBSYSTEM=block
+DM_TARGET=multipath
+DM_ACTION=PATH_REINSTATED
+DM_SEQNUM=2
+DM_PATH=8:32
+DM_NR_VALID_PATHS=1
+DM_NAME=mpath2
+DM_UUID=mpath-35333333000002328
+MINOR=3
+MAJOR=253
+SEQNUM=1131
index 6c46730c631a6952fc34beb4302011463d754011..e6244cde26e9406527dfcaa9aae9edf9e17c6161 100644 (file)
@@ -2188,7 +2188,7 @@ Your cooperation is appreciated.
 
 136-143 char   Unix98 PTY slaves
                  0 = /dev/pts/0        First Unix98 pseudo-TTY
-                 1 = /dev/pts/1        Second Unix98 pesudo-TTY
+                 1 = /dev/pts/1        Second Unix98 pseudo-TTY
                    ...
 
                These device nodes are automatically generated with
index 8569072fa38725b942dea4d9c8a53e8d692f2397..387b8a720f4a6fdc3bb1cd01a4aff8b7ac6cd263 100644 (file)
@@ -32,7 +32,7 @@ braindamaged document, if it's finally working, well, it's working.
 
 For one reason or another, low level drivers don't receive as much
 attention or testing as core code, and bugs on driver detach or
-initilaization failure doesn't happen often enough to be noticeable.
+initialization failure don't happen often enough to be noticeable.
 Init failure path is worse because it's much less travelled while
 needs to handle multiple entry points.
 
@@ -160,7 +160,7 @@ resources on failure.  For example,
   devres_release_group(dev, NULL);
   return err_code;
 
-As resource acquision failure usually means probe failure, constructs
+As resource acquisition failure usually means probe failure, constructs
 like above are usually useful in midlayer driver (e.g. libata core
 layer) where interface function shouldn't have side effect on failure.
 For LLDs, just returning error code suffices in most cases.
index 73cf9fb7cf60aa61a895c2d030b127673b45e526..63883a892120e125be75db301e1c49322c1c7a71 100644 (file)
@@ -3,7 +3,7 @@ Deferred IO
 
 Deferred IO is a way to delay and repurpose IO. It uses host memory as a
 buffer and the MMU pagefault as a pretrigger for when to perform the device
-IO. The following example may be a useful explaination of how one such setup
+IO. The following example may be a useful explanation of how one such setup
 works:
 
 - userspace app like Xfbdev mmaps framebuffer
@@ -28,7 +28,7 @@ a relatively more expensive operation.
 
 For some types of nonvolatile high latency displays, the desired image is
 the final image rather than the intermediate stages which is why it's okay
-to not update for each write that is occuring.
+to not update for each write that is occurring.
 
 It may be the case that this is useful in other scenarios as well. Paul Mundt
 has mentioned a case where it is beneficial to use the page count to decide
index 280ec06573e659314a4ddcb4e0b17511e8208ea6..6bb9be54ab767817557b680407edca2f582e03e9 100644 (file)
@@ -14,18 +14,6 @@ Who: Jiri Slaby <jirislaby@gmail.com>
 
 ---------------------------
 
-What:  V4L2 VIDIOC_G_MPEGCOMP and VIDIOC_S_MPEGCOMP
-When:  October 2007
-Why:   Broken attempt to set MPEG compression parameters. These ioctls are
-       not able to implement the wide variety of parameters that can be set
-       by hardware MPEG encoders. A new MPEG control mechanism was created
-       in kernel 2.6.18 that replaces these ioctls. See the V4L2 specification
-       (section 1.9: Extended controls) for more information on this topic.
-Who:   Hans Verkuil <hverkuil@xs4all.nl> and
-       Mauro Carvalho Chehab <mchehab@infradead.org>
-
----------------------------
-
 What:  dev->power.power_state
 When:  July 2007
 Why:   Broken design for runtime control over driver power states, confusing
@@ -49,10 +37,10 @@ Who:        David Miller <davem@davemloft.net>
 ---------------------------
 
 What:  Video4Linux API 1 ioctls and video_decoder.h from Video devices.
-When:  December 2006
-Files: include/linux/video_decoder.h
-Check: include/linux/video_decoder.h
-Why:   V4L1 AP1 was replaced by V4L2 API. during migration from 2.4 to 2.6
+When:  December 2008
+Files: include/linux/video_decoder.h include/linux/videodev.h
+Check: include/linux/video_decoder.h include/linux/videodev.h
+Why:   V4L1 AP1 was replaced by V4L2 API during migration from 2.4 to 2.6
        series. The old API have lots of drawbacks and don't provide enough
        means to work with all video and audio standards. The newer API is
        already available on the main drivers and should be used instead.
@@ -61,7 +49,9 @@ Why:  V4L1 AP1 was replaced by V4L2 API. during migration from 2.4 to 2.6
        Decoder iocts are using internally to allow video drivers to
        communicate with video decoders. This should also be improved to allow
        V4L2 calls being translated into compatible internal ioctls.
-Who:   Mauro Carvalho Chehab <mchehab@brturbo.com.br>
+       Compatibility ioctls will be provided, for a while, via 
+       v4l1-compat module. 
+Who:   Mauro Carvalho Chehab <mchehab@infradead.org>
 
 ---------------------------
 
@@ -82,6 +72,41 @@ Who: Dominik Brodowski <linux@brodo.de>
 
 ---------------------------
 
+What:  sys_sysctl
+When:  September 2010
+Option: CONFIG_SYSCTL_SYSCALL
+Why:   The same information is available in a more convenient from
+       /proc/sys, and none of the sysctl variables appear to be
+       important performance wise.
+
+       Binary sysctls are a long standing source of subtle kernel
+       bugs and security issues.
+
+       When I looked several months ago all I could find after
+       searching several distributions were 5 user space programs and
+       glibc (which falls back to /proc/sys) using this syscall.
+
+       The man page for sysctl(2) documents it as unusable for user
+       space programs.
+
+       sysctl(2) is not generally ABI compatible to a 32bit user
+       space application on a 64bit and a 32bit kernel.
+
+       For the last several months the policy has been no new binary
+       sysctls and no one has put forward an argument to use them.
+
+       Binary sysctls issues seem to keep happening appearing so
+       properly deprecating them (with a warning to user space) and a
+       2 year grace warning period will mean eventually we can kill
+       them and end the pain.
+
+       In the mean time individual binary sysctls can be dealt with
+       in a piecewise fashion.
+
+Who:   Eric Biederman <ebiederm@xmission.com>
+
+---------------------------
+
 What:  a.out interpreter support for ELF executables
 When:  2.6.25
 Files: fs/binfmt_elf.c
@@ -184,13 +209,6 @@ Who:       Jean Delvare <khali@linux-fr.org>,
 
 ---------------------------
 
-What:  drivers depending on OBSOLETE_OSS
-When:  options in 2.6.22, code in 2.6.24
-Why:   OSS drivers with ALSA replacements
-Who:   Adrian Bunk <bunk@stusta.de>
-
----------------------------
-
 What:  ACPI procfs interface
 When:  July 2008
 Why:   ACPI sysfs conversion should be finished by January 2008.
index d6fd6c6e424411a37ed26af88b280cd7fac07c91..bf8080640eba405d01aac5a101623e825b542d90 100644 (file)
@@ -42,10 +42,12 @@ OPTIONS
 
   trans=name   select an alternative transport.  Valid options are
                currently:
-                       unix - specifying a named pipe mount point
-                       tcp  - specifying a normal TCP/IP connection
-                       fd   - used passed file descriptors for connection
+                       unix    - specifying a named pipe mount point
+                       tcp     - specifying a normal TCP/IP connection
+                       fd      - used passed file descriptors for connection
                                 (see rfdno and wfdno)
+                       virtio  - connect to the next virtio channel available
+                               (from lguest or KVM with trans_virtio module)
 
   uname=name   user name to attempt mount as on the remote server.  The
                server may override or ignore this value.  Certain user
@@ -54,7 +56,7 @@ OPTIONS
   aname=name   aname specifies the file tree to access when the server is
                offering several exported file systems.
 
-  cache=mode   specifies a cacheing policy.  By default, no caches are used.
+  cache=mode   specifies a caching policy.  By default, no caches are used.
                        loose = no attempts are made at consistency,
                                 intended for exclusive, read-only mounts
 
index 31047e0fe14bceb82ddda2c3692e38c846d20e40..87019d2b59815eca1accd2c39497c8de43ca8b49 100644 (file)
@@ -2,9 +2,12 @@
 Making Filesystems Exportable
 =============================
 
-Most filesystem operations require a dentry (or two) as a starting
+Overview
+--------
+
+All filesystem operations require a dentry (or two) as a starting
 point.  Local applications have a reference-counted hold on suitable
-dentrys via open file descriptors or cwd/root.  However remote
+dentries via open file descriptors or cwd/root.  However remote
 applications that access a filesystem via a remote filesystem protocol
 such as NFS may not be able to hold such a reference, and so need a
 different way to refer to a particular dentry.  As the alternative
@@ -13,14 +16,14 @@ server-reboot (among other things, though these tend to be the most
 problematic), there is no simple answer like 'filename'.
 
 The mechanism discussed here allows each filesystem implementation to
-specify how to generate an opaque (out side of the filesystem) byte
+specify how to generate an opaque (outside of the filesystem) byte
 string for any dentry, and how to find an appropriate dentry for any
 given opaque byte string.
 This byte string will be called a "filehandle fragment" as it
 corresponds to part of an NFS filehandle.
 
 A filesystem which supports the mapping between filehandle fragments
-and dentrys will be termed "exportable".
+and dentries will be termed "exportable".
 
 
 
@@ -89,11 +92,9 @@ For a filesystem to be exportable it must:
    1/ provide the filehandle fragment routines described below.
    2/ make sure that d_splice_alias is used rather than d_add
       when ->lookup finds an inode for a given parent and name.
-      Typically the ->lookup routine will end:
-               if (inode)
-                       return d_splice(inode, dentry);
-               d_add(dentry, inode);
-               return NULL;
+      Typically the ->lookup routine will end with a:
+
+               return d_splice_alias(inode, dentry);
        }
 
 
@@ -101,67 +102,39 @@ For a filesystem to be exportable it must:
   A file system implementation declares that instances of the filesystem
 are exportable by setting the s_export_op field in the struct
 super_block.  This field must point to a "struct export_operations"
-struct which could potentially be full of NULLs, though normally at
-least get_parent will be set.
-
- The primary operations are decode_fh and encode_fh.  
-decode_fh takes a filehandle fragment and tries to find or create a
-dentry for the object referred to by the filehandle.
-encode_fh takes a dentry and creates a filehandle fragment which can
-later be used to find/create a dentry for the same object.
-
-decode_fh will probably make use of "find_exported_dentry".
-This function lives in the "exportfs" module which a filesystem does
-not need unless it is being exported.  So rather that calling
-find_exported_dentry directly, each filesystem should call it through
-the find_exported_dentry pointer in it's export_operations table.
-This field is set correctly by the exporting agent (e.g. nfsd) when a
-filesystem is exported, and before any export operations are called.
-
-find_exported_dentry needs three support functions from the
-filesystem:
-  get_name.  When given a parent dentry and a child dentry, this
-    should find a name in the directory identified by the parent
-    dentry, which leads to the object identified by the child dentry.
-    If no get_name function is supplied, a default implementation is
-    provided which uses vfs_readdir to find potential names, and
-    matches inode numbers to find the correct match.
-
-  get_parent.  When given a dentry for a directory, this should return 
-    a dentry for the parent.  Quite possibly the parent dentry will
-    have been allocated by d_alloc_anon.  
-    The default get_parent function just returns an error so any
-    filehandle lookup that requires finding a parent will fail.
-    ->lookup("..") is *not* used as a default as it can leave ".."
-    entries in the dcache which are too messy to work with.
-
-  get_dentry.  When given an opaque datum, this should find the
-    implied object and create a dentry for it (possibly with
-    d_alloc_anon). 
-    The opaque datum is whatever is passed down by the decode_fh
-    function, and is often simply a fragment of the filehandle
-    fragment.
-    decode_fh passes two datums through find_exported_dentry.  One that 
-    should be used to identify the target object, and one that can be
-    used to identify the object's parent, should that be necessary.
-    The default get_dentry function assumes that the datum contains an
-    inode number and a generation number, and it attempts to get the
-    inode using "iget" and check it's validity by matching the
-    generation number.  A filesystem should only depend on the default
-    if iget can safely be used this way.
-
-If decode_fh and/or encode_fh are left as NULL, then default
-implementations are used.  These defaults are suitable for ext2 and 
-extremely similar filesystems (like ext3).
-
-The default encode_fh creates a filehandle fragment from the inode
-number and generation number of the target together with the inode
-number and generation number of the parent (if the parent is
-required).
-
-The default decode_fh extract the target and parent datums from the
-filehandle assuming the format used by the default encode_fh and
-passed them to find_exported_dentry.
+struct which has the following members:
+
+ encode_fh  (optional)
+    Takes a dentry and creates a filehandle fragment which can later be used
+    to find or create a dentry for the same object.  The default
+    implementation creates a filehandle fragment that encodes a 32bit inode
+    and generation number for the inode encoded, and if necessary the
+    same information for the parent.
+
+  fh_to_dentry (mandatory)
+    Given a filehandle fragment, this should find the implied object and
+    create a dentry for it (possibly with d_alloc_anon).
+
+  fh_to_parent (optional but strongly recommended)
+    Given a filehandle fragment, this should find the parent of the
+    implied object and create a dentry for it (possibly with d_alloc_anon).
+    May fail if the filehandle fragment is too small.
+
+  get_parent (optional but strongly recommended)
+    When given a dentry for a directory, this should return  a dentry for
+    the parent.  Quite possibly the parent dentry will have been allocated
+    by d_alloc_anon.  The default get_parent function just returns an error
+    so any filehandle lookup that requires finding a parent will fail.
+    ->lookup("..") is *not* used as a default as it can leave ".." entries
+    in the dcache which are too messy to work with.
+
+  get_name (optional)
+    When given a parent dentry and a child dentry, this should find a name
+    in the directory identified by the parent dentry, which leads to the
+    object identified by the child dentry.  If no get_name function is
+    supplied, a default implementation is provided which uses vfs_readdir
+    to find potential names, and matches inode numbers to find the correct
+    match.
 
 
 A filehandle fragment consists of an array of 1 or more 4byte words,
@@ -172,5 +145,3 @@ generated by encode_fh, in which case it will have been padded with
 nuls.  Rather, the encode_fh routine should choose a "type" which
 indicates the decode_fh how much of the filehandle is valid, and how
 it should be interpreted.
-
index fe26cc978523959b468cd8fa5398eed5ef1b8559..37c10cba717725f599ec999eb0a0a4ff6b1fc483 100644 (file)
@@ -224,7 +224,7 @@ against the page the filesystem should redirty the page with
 redirty_page_for_writepage(), then unlock the page and return zero.
 This may also be done to avoid internal deadlocks, but rarely.
 
-If the filesytem is called for sync then it must wait on any
+If the filesystem is called for sync then it must wait on any
 in-progress I/O and then start new I/O.
 
 The filesystem should unlock the page synchronously, before returning to the
index 4aecc9bdb273a3df8656a2db59899cf52e47de21..b45f3c1b8b431655f500b0a8842553ea21a5d6a0 100644 (file)
@@ -130,12 +130,12 @@ Device layer.
 
 Journaling Block Device layer
 -----------------------------
-The Journaling Block Device layer (JBD) isn't ext3 specific.  It was design to
-add journaling capabilities on a block device.  The ext3 filesystem code will
-inform the JBD of modifications it is performing (called a transaction).  The
-journal supports the transactions start and stop, and in case of crash, the
-journal can replayed the transactions to put the partition back in a
-consistent state fast.
+The Journaling Block Device layer (JBD) isn't ext3 specific.  It was designed
+to add journaling capabilities to a block device.  The ext3 filesystem code
+will inform the JBD of modifications it is performing (called a transaction).
+The journal supports the transactions start and stop, and in case of a crash,
+the journal can replay the transactions to quickly put the partition back into
+a consistent state.
 
 Handles represent a single atomic update to a filesystem.  JBD can handle an
 external journal on a block device.
@@ -164,7 +164,7 @@ written to the journal first, and then to its final location.
 In the event of a crash, the journal can be replayed, bringing both data and
 metadata into a consistent state.  This mode is the slowest except when data
 needs to be read from and written to disk at the same time where it
-outperforms all others modes.
+outperforms all other modes.
 
 Compatibility
 -------------
index 133e213ebb721912a79c2c6621ef30050941ce6e..bb0142f6108458f6ccd27b90e965a6bdf820e501 100644 (file)
@@ -76,13 +76,13 @@ the fdtable structure -
 5. Handling of the file structures is special. Since the look-up
    of the fd (fget()/fget_light()) are lock-free, it is possible
    that look-up may race with the last put() operation on the
-   file structure. This is avoided using the rcuref APIs
+   file structure. This is avoided using atomic_inc_not_zero()
    on ->f_count :
 
        rcu_read_lock();
        file = fcheck_files(files, fd);
        if (file) {
-               if (rcuref_inc_lf(&file->f_count))
+               if (atomic_inc_not_zero(&file->f_count))
                        *fput_needed = 1;
                else
                /* Didn't get the reference, someone's freed */
@@ -92,7 +92,7 @@ the fdtable structure -
        ....
        return file;
 
-   rcuref_inc_lf() detects if refcounts is already zero or
+   atomic_inc_not_zero() detects if refcounts is already zero or
    goes to zero during increment. If it does, we fail
    fget()/fget_light().
 
index e5c1df52a876fe9ab83173966772960ce0b25a77..dec99455321fdf86018ca5b2b62936103fd73031 100644 (file)
@@ -813,9 +813,9 @@ Various pieces   of  information about  kernel activity  are  available in the
 since the system first booted.  For a quick look, simply cat the file:
 
   > cat /proc/stat
-  cpu  2255 34 2290 22625563 6290 127 456
-  cpu0 1132 34 1441 11311718 3675 127 438
-  cpu1 1123 0 849 11313845 2614 0 18
+  cpu  2255 34 2290 22625563 6290 127 456 0
+  cpu0 1132 34 1441 11311718 3675 127 438 0
+  cpu1 1123 0 849 11313845 2614 0 18 0
   intr 114930548 113199788 3 0 5 263 0 4 [... lots more numbers ...]
   ctxt 1990473
   btime 1062191376
@@ -835,6 +835,7 @@ second).  The meanings of the columns are as follows, from left to right:
 - iowait: waiting for I/O to complete
 - irq: servicing interrupts
 - softirq: servicing softirqs
+- steal: involuntary wait
 
 The "intr" line gives counts of interrupts  serviced since boot time, for each
 of the  possible system interrupts.   The first  column  is the  total of  all
index 4b5ca26e50485cef96afb94f1d6be4238bbe90af..4598ef7b622bb88711cb22595a9b2f85a5050d9c 100644 (file)
@@ -51,7 +51,7 @@ for the attributes, providing a means to read and write kernel
 attributes.
 
 Attributes should be ASCII text files, preferably with only one value
-per file. It is noted that it may not be efficient to contain only
+per file. It is noted that it may not be efficient to contain only one
 value per file, so it is socially acceptable to express an array of
 values of the same type. 
 
index 6f8e16e3d6c0c65c97f5d1dfe650977aa711e6d5..9d019d35728f28bcb9ecfeaf5bd3a4227f026586 100644 (file)
@@ -706,7 +706,7 @@ struct address_space_operations {
         wants to make it a free page.  If ->releasepage succeeds, the
         page will be removed from the address_space and become free.
 
-       The second case if when a request has been made to invalidate
+       The second case is when a request has been made to invalidate
         some or all pages in an address_space.  This can happen
         through the fadvice(POSIX_FADV_DONTNEED) system call or by the
         filesystem explicitly requesting it as nfs and 9fs do (when
index 579b92d5f3a38c4796d6bcf4c1de559277090974..10518dd588146f6d57c1e3c9c912bb525bc86425 100644 (file)
@@ -68,7 +68,7 @@ We have found some I2C devices that needs the following modifications:
 
   Flags I2C_M_IGNORE_NAK
     Normally message is interrupted immediately if there is [NA] from the
-    client. Setting this flag treats any [NA] as [A], and all of
+    client. Setting this flag treats any [NA] as [A], and all of
     message is sent.
     These messages may still fail to SCL lo->hi timeout.
 
index 35985b34d5a6cc194e48ce9281bac676a959dcba..2f75e750e4f5c650a89df593ead1a1ff320eee62 100644 (file)
@@ -168,6 +168,8 @@ Offset      Proto   Name            Meaning
 0234/1 2.05+   relocatable_kernel Whether kernel is relocatable or not
 0235/3 N/A     pad2            Unused
 0238/4 2.06+   cmdline_size    Maximum size of the kernel command line
+023C/4 2.07+   hardware_subarch Hardware subarchitecture
+0240/8 2.07+   hardware_subarch_data Subarchitecture-specific data
 
 (1) For backwards compatibility, if the setup_sects field contains 0, the
     real value is 4.
@@ -204,7 +206,7 @@ boot loaders can ignore those fields.
 
 The byte order of all fields is littleendian (this is x86, after all.)
 
-Field name:    setup_secs
+Field name:    setup_sects
 Type:          read
 Offset/size:   0x1f1/1
 Protocol:      ALL
@@ -356,6 +358,13 @@ Protocol:  2.00+
        - If 0, the protected-mode code is loaded at 0x10000.
        - If 1, the protected-mode code is loaded at 0x100000.
 
+  Bit 6 (write): KEEP_SEGMENTS
+       Protocol: 2.07+
+       - if 0, reload the segment registers in the 32bit entry point.
+       - if 1, do not reload the segment registers in the 32bit entry point.
+               Assume that %cs %ds %ss %es are all set to flat segments with
+               a base of 0 (or the equivalent for their environment).
+
   Bit 7 (write): CAN_USE_HEAP
        Set this bit to 1 to indicate that the value entered in the
        heap_end_ptr is valid.  If this field is clear, some setup code
@@ -480,6 +489,29 @@ Protocol:  2.06+
   cmdline_size characters. With protocol version 2.05 and earlier, the
   maximum size was 255.
 
+Field name:    hardware_subarch
+Type:          write
+Offset/size:   0x23c/4
+Protocol:      2.07+
+
+  In a paravirtualized environment the hardware low level architectural
+  pieces such as interrupt handling, page table handling, and
+  accessing process control registers needs to be done differently.
+
+  This field allows the bootloader to inform the kernel we are in one
+  one of those environments.
+
+  0x00000000   The default x86/PC environment
+  0x00000001   lguest
+  0x00000002   Xen
+
+Field name:    hardware_subarch_data
+Type:          write
+Offset/size:   0x240/8
+Protocol:      2.07+
+
+  A pointer to data that is specific to hardware subarch
+
 
 **** THE KERNEL COMMAND LINE
 
index 6449a7090dbbf6e18c31f54a458561cf50ccd80e..223e4f0582d018254e692b8e83d809fe77dbc400 100644 (file)
@@ -21,10 +21,10 @@ software test suits to do stressful testing on IPF.
 
 Below is a sample application as part of the whole tool. The sample
 can be used as a working test tool. Or it can be expanded to include
-more features. It also can be a integrated into a libary or other user
+more features. It also can be a integrated into a library or other user
 application to have more thorough test.
 
-The sample application takes err.conf as error configuation input. Gcc
+The sample application takes err.conf as error configuration input. GCC
 compiles the code. After you install err_inject driver, you can run
 this sample application to inject errors.
 
@@ -809,7 +809,7 @@ int err_inj()
        }
 
        /* Create semaphore: If one_lock, one semaphore for all processors.
-          Otherwise, one sempaphore for each processor. */
+          Otherwise, one semaphore for each processor. */
        if (one_lock) {
                if (create_sem(0)) {
                        printf("Can not create semaphore...exit\n");
index ab050621e20f7878f19c19392f1007718fd6dddc..f3a3ba8847ba7749c0d881220f50a56c217d8c31 100644 (file)
@@ -170,7 +170,7 @@ major controller faults (ROM checksum and RAM test) and such things as stuck
 keys. Any keys down at power-up are presumed to be stuck, and their BREAK
 (sic) code is returned (which without the preceding MAKE code is a flag for a
 keyboard error). If the controller self-test completes without error, the code
-0xF0 is returned. (This code will be used to indicate the version/rlease of
+0xF0 is returned. (This code will be used to indicate the version/release of
 the ikbd controller. The first release of the ikbd is version 0xF0, should
 there be a second release it will be 0xF1, and so on.)
 The ikbd defaults to a mouse position reporting with threshold of 1 unit in
@@ -413,7 +413,7 @@ INTERROGATION MODE.
             %nnnnmmmm   ; where m is JOYSTICK1 state
                         ; and n is JOYSTICK0 state
 
-Sets the ikbd to do nothing but monitor the serial command lne, maintain the
+Sets the ikbd to do nothing but monitor the serial command line, maintain the
 time-of-day clock, and monitor the joystick. The rate sets the interval
 between joystick samples.
 N.B. The user should not set the rate higher than the serial communications
@@ -446,10 +446,10 @@ The sample interval should be as constant as possible.
                         ; until vertical cursor key is generated before RY
                         ; has elapsed
     VX                  ; length (in tenths of seconds) of joystick closure
-                        ; until horizontal cursor keystokes are generated
+                        ; until horizontal cursor keystrokes are generated
                         ; after RX has elapsed
     VY                  ; length (in tenths of seconds) of joystick closure
-                        ; until vertical cursor keystokes are generated
+                        ; until vertical cursor keystrokes are generated
                         ; after RY has elapsed
 
 In this mode, joystick 0 is scanned in a way that simulates cursor keystrokes.
index 085eb15b45b7c5655d0c8363e19bdde2cf4e4699..ded4d5f53109d13e79aa47e277a7dde674f5c883 100644 (file)
@@ -1,5 +1,5 @@
 Force feedback for Linux.
-By Johann Deneux <deneux@ifrance.com> on 2001/04/22.
+By Johann Deneux <johann.deneux@gmail.com> on 2001/04/22.
 Updated by Anssi Hannula <anssi.hannula@gmail.com> on 2006/04/09.
 You may redistribute this file. Please remember to include shape.fig and
 interactive.fig as well.
index 8777d2d321e38437424896c9f45e26ddff81ebbc..3ac92413c8748f8e0f4ae0998d2a0f0dfff334e0 100644 (file)
@@ -4,10 +4,10 @@ specify force effects to I-Force 2.0 devices.  None of this information comes
 from Immerse. That's why you should not trust what is written in this
 document. This document is intended to help understanding the protocol.
 This is not a reference. Comments and corrections are welcome.  To contact me,
-send an email to: deneux@ifrance.com
+send an email to: johann.deneux@gmail.com
 
 ** WARNING **
-I may not be held responsible for any dammage or harm caused if you try to
+I shall not be held responsible for any damage or harm caused if you try to
 send data to your I-Force device based on what you read in this document.
 
 ** Preliminary Notes:
@@ -151,13 +151,13 @@ OP=  ff
 Query command. Length varies according to the query type.
 The general format of this packet is:
 ff 01 QUERY [INDEX] CHECKSUM
-reponses are of the same form:
+responses are of the same form:
 FF LEN QUERY VALUE_QUERIED CHECKSUM2
 where LEN = 1 + length(VALUE_QUERIED)
 
 **** Query ram size ****
 QUERY = 42 ('B'uffer size)
-The device should reply with the same packet plus two additionnal bytes
+The device should reply with the same packet plus two additional bytes
 containing the size of the memory:
 ff 03 42 03 e8 CS would mean that the device has 1000 bytes of ram available.
 
@@ -234,19 +234,23 @@ is the amount of memory apparently needed for every set of parameters:
 
 ** Appendix: How to study the protocol ? **
 
-1. Generate effects using the force editor provided with the DirectX SDK, or use Immersion Studio (freely available at their web site in the developer section: www.immersion.com)
-2. Start a soft spying RS232 or USB (depending on where you connected your joystick/wheel). I used ComPortSpy from fCoder (alpha version!)
+1. Generate effects using the force editor provided with the DirectX SDK, or 
+use Immersion Studio (freely available at their web site in the developer section: 
+www.immersion.com)
+2. Start a soft spying RS232 or USB (depending on where you connected your 
+joystick/wheel). I used ComPortSpy from fCoder (alpha version!)
 3. Play the effect, and watch what happens on the spy screen.
 
 A few words about ComPortSpy:
-At first glance, this soft seems, hum, well... buggy. In fact, data appear with a few seconds latency. Personnaly, I restart it every time I play an effect.
+At first glance, this software seems, hum, well... buggy. In fact, data appear with a
+few seconds latency. Personally, I restart it every time I play an effect.
 Remember it's free (as in free beer) and alpha!
 
 ** URLS **
 Check www.immerse.com for Immersion Studio, and www.fcoder.com for ComPortSpy.
 
 ** Author of this document **
-Johann Deneux <deneux@ifrance.com>
+Johann Deneux <johann.deneux@gmail.com>
 Home page at http://www.esil.univ-mrs.fr/~jdeneux/projects/ff/
 
 Additions by Vojtech Pavlik.
index d9d523099bb7d69d3dd3e4124167e5dd9bad1fc4..47fc86830cd7691a5ea256a971065393d422f9b8 100644 (file)
@@ -42,8 +42,8 @@ static int __init button_init(void)
                goto err_free_irq;
        }
 
-       button_dev->evbit[0] = BIT(EV_KEY);
-       button_dev->keybit[LONG(BTN_0)] = BIT(BTN_0);
+       button_dev->evbit[0] = BIT_MASK(EV_KEY);
+       button_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
 
        error = input_register_device(button_dev);
        if (error) {
@@ -79,7 +79,7 @@ In the _init function, which is called either upon module load or when
 booting the kernel, it grabs the required resources (it should also check
 for the presence of the device).
 
-Then it allocates a new input device structure with input_aloocate_device()
+Then it allocates a new input device structure with input_allocate_device()
 and sets up input bitfields. This way the device driver tells the other
 parts of the input systems what it is - what events can be generated or
 accepted by this input device. Our example device can only generate EV_KEY
@@ -217,14 +217,15 @@ If you don't need absfuzz and absflat, you can set them to zero, which mean
 that the thing is precise and always returns to exactly the center position
 (if it has any).
 
-1.4 NBITS(), LONG(), BIT()
+1.4 BITS_TO_LONGS(), BIT_WORD(), BIT_MASK()
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-These three macros from input.h help some bitfield computations:
+These three macros from bitops.h help some bitfield computations:
 
-       NBITS(x) - returns the length of a bitfield array in longs for x bits
-       LONG(x)  - returns the index in the array in longs for bit x
-       BIT(x)   - returns the index in a long for bit x
+       BITS_TO_LONGS(x) - returns the length of a bitfield array in longs for
+                          x bits
+       BIT_WORD(x)      - returns the index in the array in longs for bit x
+       BIT_MASK(x)      - returns the index in a long for bit x
 
 1.5 The id* and name fields
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
index 7c17c837064fbfe7cd5f688de32947f5c4182fe2..8cac6c2f23ee3dd1337efb71db394e51c3284492 100644 (file)
@@ -40,7 +40,7 @@ Andreas Kool (akool@Kool.f.EUnet.de)
 Pedro Roque Marques (roque@di.fc.ul.pt)
   For lot of new ideas and the pcbit driver.
 
-Eberhard Moenkeberg (emoenke@gwdg.de)
+Eberhard Mönkeberg (emoenke@gwdg.de)
   For testing and help to get into kernel.
 
 Thomas Neumann (tn@ruhr.de)
index 2f114babe4b6a22538274deff8f384eece7a801f..a76d74845a4c8bea3500d1475ad526a3924d8672 100644 (file)
@@ -111,7 +111,7 @@ struct concap_proto_ops{
        struct concap_proto *  (*proto_new) (void);
 
        /* delete encapsulation protocol instance and free all its resources.
-          cprot may no loger be referenced after calling this */
+          cprot may no longer be referenced after calling this */
        void (*proto_del)(struct concap_proto *cprot);
 
        /* initialize the protocol's data. To be called at interface startup
index 3cce3fbb664437a2fb1acf65fda6ff3360e36273..e6a72328154783fc6e983904658eb8eb8c0c4ee8 100644 (file)
@@ -37,7 +37,7 @@ other program after you have done the following:
    or the following, if you want to be more selective:
      ':Applet:M::<!--applet::/usr/bin/appletviewer:'
 
-   Of cause you have to fix the path names. Given path/file names in this
+   Of course you have to fix the path names. The path/file names given in this
    document match the Debian 2.1 system. (i.e. jdk installed in /usr,
    custom wrappers from this document in /usr/local)
 
index fe8b0c4892cf14e6f39e255ac368f150c41647c8..616043a6da99a0afd945e3cb5acb93b26bbb3f17 100644 (file)
@@ -77,7 +77,12 @@ applicable everywhere (see syntax).
   Optionally, dependencies only for this default value can be added with
   "if".
 
-- dependencies: "depends on"/"requires" <expr>
+- type definition + default value:
+       "def_bool"/"def_tristate" <expr> ["if" <expr>]
+  This is a shorthand notation for a type definition plus a value.
+  Optionally dependencies for this default value can be added with "if".
+
+- dependencies: "depends on" <expr>
   This defines a dependency for this menu entry. If multiple
   dependencies are defined, they are connected with '&&'. Dependencies
   are applied to all other options within this menu entry (which also
@@ -289,3 +294,10 @@ source:
        "source" <prompt>
 
 This reads the specified configuration file. This file is always parsed.
+
+mainmenu:
+
+       "mainmenu" <prompt>
+
+This sets the config program's title bar if the config program chooses
+to use it.
index f099b814d383c49d44667954fe9e625c90c9a6e4..7a7753321a263f62c2a00c9d0e348716e701ac2c 100644 (file)
@@ -518,6 +518,28 @@ more details, with real examples.
        In this example for a specific GCC version the build will error out explaining
        to the user why it stops.
 
+    cc-cross-prefix
+       cc-cross-prefix is used to check if there exists a $(CC) in path with
+       one of the listed prefixes. The first prefix where there exist a
+       prefix$(CC) in the PATH is returned - and if no prefix$(CC) is found
+       then nothing is returned.
+       Additional prefixes are separated by a single space in the
+       call of cc-cross-prefix.
+       This functionality is useful for architecture Makefiles that try
+       to set CROSS_COMPILE to well-known values but may have several
+       values to select between.
+       It is recommended only to try to set CROSS_COMPILE if it is a cross
+       build (host arch is different from target arch). And if CROSS_COMPILE
+       is already set then leave it with the old value.
+
+       Example:
+               #arch/m68k/Makefile
+               ifneq ($(SUBARCH),$(ARCH))
+                       ifeq ($(CROSS_COMPILE),)
+                              CROSS_COMPILE := $(call cc-cross-prefix, m68k-linux-gnu-)
+                       endif
+               endif
+
 === 4 Host Program support
 
 Kbuild supports building executables on the host for use during the
index 1b37b28cc2343b82a7150d8c74724f4d2ecb8e7f..d0ac72cc19ff8e29667e7a2c58e21d2d0cfafcb5 100644 (file)
@@ -231,6 +231,32 @@ Dump-capture kernel config options (Arch Dependent, ia64)
   any space below the alignment point will be wasted.
 
 
+Extended crashkernel syntax
+===========================
+
+While the "crashkernel=size[@offset]" syntax is sufficient for most
+configurations, sometimes it's handy to have the reserved memory dependent
+on the value of System RAM -- that's mostly for distributors that pre-setup
+the kernel command line to avoid a unbootable system after some memory has
+been removed from the machine.
+
+The syntax is:
+
+    crashkernel=<range1>:<size1>[,<range2>:<size2>,...][@offset]
+    range=start-[end]
+
+For example:
+
+    crashkernel=512M-2G:64M,2G-:128M
+
+This would mean:
+
+    1) if the RAM is smaller than 512M, then don't reserve anything
+       (this is the "rescue" case)
+    2) if the RAM size is between 512M and 2G, then reserve 64M
+    3) if the RAM size is larger than 2G, then reserve 128M
+
+
 Boot into System Kernel
 =======================
 
index d9e3b199929bd6fb158576a040e88ee01276561f..5a4ef48224aeac7ce4cfef6eea9dd3e545a7300e 100644 (file)
@@ -76,9 +76,9 @@
      * Title: "Conceptual Architecture of the Linux Kernel"
        Author: Ivan T. Bowman.
        URL: http://plg.uwaterloo.ca/~itbowman/papers/CS746G-a1.html
-       Keywords: conceptual software arquitecture, extracted design,
+       Keywords: conceptual software architecture, extracted design,
        reverse engineering, system structure.
-       Description: Conceptual software arquitecture of the Linux kernel,
+       Description: Conceptual software architecture of the Linux kernel,
        automatically extracted from the source code. Very detailed. Good
        figures. Gives good overall kernel understanding.
 
index 98cf90f2631d736021478528fab34281a79b5659..b2361667839fd8850c385d1ba0a1f5cea1878751 100644 (file)
@@ -222,9 +222,6 @@ and is between 256 and 4096 characters. It is defined in the file
                        Warning: Many of these options can produce a lot of
                        output and make your system unusable. Be very careful.
 
-
-       acpi_fake_ecdt  [HW,ACPI] Workaround failure due to BIOS lacking ECDT
-
        acpi_pm_good    [X86-32,X86-64]
                        Override the pmtimer bug detection: force the kernel
                        to assume that this machine's pmtimer latches its value
@@ -297,9 +294,6 @@ and is between 256 and 4096 characters. It is defined in the file
        apm=            [APM] Advanced Power Management
                        See header of arch/i386/kernel/apm.c.
 
-       applicom=       [HW]
-                       Format: <mem>,<irq>
-
        arcrimi=        [HW,NET] ARCnet - "RIM I" (entirely mem-mapped) cards
                        Format: <io>,<irq>,<nodeID>
 
@@ -345,12 +339,6 @@ and is between 256 and 4096 characters. It is defined in the file
                        Format: <io>,<irq>,<mode>
                        See header of drivers/net/hamradio/baycom_ser_hdx.c.
 
-       blkmtd_device=  [HW,MTD]
-       blkmtd_erasesz=
-       blkmtd_ro=
-       blkmtd_bs=
-       blkmtd_count=
-
        boot_delay=     Milliseconds to delay each printk during boot.
                        Values larger than 10 seconds (10000) are changed to
                        no delay (0).
@@ -431,8 +419,10 @@ and is between 256 and 4096 characters. It is defined in the file
                        over the 8254 in addition to over the IO-APIC. The
                        kernel tries to set a sensible default.
 
-       hpet=           [X86-32,HPET] option to disable HPET and use PIT.
-                       Format: disable
+       hpet=           [X86-32,HPET] option to control HPET usage
+                       Format: { enable (default) | disable | force }
+                       disable: disable HPET and use PIT instead
+                       force: allow force enabled of undocumented chips (ICH4, VIA)
 
        com20020=       [HW,NET] ARCnet - COM20020 chipset
                        Format:
@@ -479,6 +469,16 @@ and is between 256 and 4096 characters. It is defined in the file
                        UART at the specified I/O port or MMIO address.
                        The options are the same as for ttyS, above.
 
+       no_console_suspend
+                       [HW] Never suspend the console
+                       Disable suspending of consoles during suspend and
+                       hibernate operations.  Once disabled, debugging
+                       messages can reach various consoles while the rest
+                       of the system is being put to sleep (ie, while
+                       debugging driver suspend/resume hooks).  This may
+                       not work reliably with all consoles, but is known
+                       to work with serial and VGA consoles.
+
        cpcihp_generic= [HW,PCI] Generic port I/O CompactPCI driver
                        Format:
                        <first_slot>,<last_slot>,<port>,<enum_bit>[,<debug>]
@@ -487,6 +487,13 @@ and is between 256 and 4096 characters. It is defined in the file
                        [KNL] Reserve a chunk of physical memory to
                        hold a kernel to switch to with kexec on panic.
 
+       crashkernel=range1:size1[,range2:size2,...][@offset]
+                       [KNL] Same as above, but depends on the memory
+                       in the running system. The syntax of range is
+                       start-[end] where start and end are both
+                       a memory unit (amount[KMG]). See also
+                       Documentation/kdump/kdump.txt for a example.
+
        cs4232=         [HW,OSS]
                        Format: <io>,<irq>,<dma>,<dma2>,<mpuio>,<mpuirq>
 
@@ -496,8 +503,6 @@ and is between 256 and 4096 characters. It is defined in the file
        cs89x0_media=   [HW,NET]
                        Format: { rj45 | aui | bnc }
 
-       cyclades=       [HW,SERIAL] Cyclades multi-serial port adapter.
-
        dasd=           [HW,NET]
                        See header of drivers/s390/block/dasd_devmap.c.
 
@@ -555,10 +560,6 @@ and is between 256 and 4096 characters. It is defined in the file
                        See drivers/char/README.epca and
                        Documentation/digiepca.txt.
 
-       dmascc=         [HW,AX25,SERIAL] AX.25 Z80SCC driver with DMA
-                       support available.
-                       Format: <io_dev0>[,<io_dev1>[,..<io_dev32>]]
-
        dmasound=       [HW,OSS] Sound subsystem buffers
 
        dscc4.setup=    [NET]
@@ -589,17 +590,10 @@ and is between 256 and 4096 characters. It is defined in the file
                        0: polling mode
                        non-0: interrupt mode (default)
 
-       eda=            [HW,PS2]
-
-       edb=            [HW,PS2]
-
        edd=            [EDD]
                        Format: {"of[f]" | "sk[ipmbr]"}
                        See comment in arch/i386/boot/edd.S
 
-       eicon=          [HW,ISDN]
-                       Format: <id>,<membase>,<irq>
-
        eisa_irq_edge=  [PARISC,HW]
                        See header of drivers/parisc/eisa.c.
 
@@ -778,6 +772,23 @@ and is between 256 and 4096 characters. It is defined in the file
 
        inttest=        [IA64]
 
+       intel_iommu=    [DMAR] Intel IOMMU driver (DMAR) option
+               off
+                       Disable intel iommu driver.
+               igfx_off [Default Off]
+                       By default, gfx is mapped as normal device. If a gfx
+                       device has a dedicated DMAR unit, the DMAR unit is
+                       bypassed by not enabling DMAR with this option. In
+                       this case, gfx device will use physical address for
+                       DMA.
+               forcedac [x86_64]
+                       With this option iommu will not optimize to look
+                       for io virtual address below 32 bit forcing dual
+                       address cycle on pci bus for cards supporting greater
+                       than 32 bit addressing. The default is to look
+                       for translation below 32 bit and if not available
+                       then look in the higher range.
+
        io7=            [HW] IO7 for Marvel based alpha systems
                        See comment before marvel_specify_io7 in
                        arch/alpha/kernel/core_marvel.c.
@@ -875,9 +886,6 @@ and is between 256 and 4096 characters. It is defined in the file
        lapic_timer_c2_ok       [X86-32,x86-64,APIC] trust the local apic timer in
                        C2 power state.
 
-       lasi=           [HW,SCSI] PARISC LASI driver for the 53c700 chip
-                       Format: addr:<io>,irq:<irq>
-
        libata.noacpi   [LIBATA] Disables use of ACPI in libata suspend/resume
                        when set.
                        Format: <int>
@@ -1125,9 +1133,6 @@ and is between 256 and 4096 characters. It is defined in the file
        noapic          [SMP,APIC] Tells the kernel to not make use of any
                        IOAPICs that may be present in the system.
 
-       noasync         [HW,M68K] Disables async and sync negotiation for
-                       all devices.
-
        nobats          [PPC] Do not use BATs for mapping kernel lowmem
                        on "Classic" PPC cores.
 
@@ -1439,6 +1444,7 @@ and is between 256 and 4096 characters. It is defined in the file
                        Param: <number> - step/bucket size as a power of 2 for
                                statistical time based profiling.
                        Param: "sleep" - profile D-state sleeping (millisecs)
+                       Param: "kvm" - profile VM exits.
 
        processor.max_cstate=   [HW,ACPI]
                        Limit processor to maximum C-state
@@ -1565,9 +1571,6 @@ and is between 256 and 4096 characters. It is defined in the file
        sa1100ir        [NET]
                        See drivers/net/irda/sa1100_ir.c.
 
-       sb=             [HW,OSS]
-                       Format: <io>,<irq>,<dma>,<dma2>
-
        sbni=           [NET] Granch SBNI12 leased line adapter
 
        sc1200wdt=      [HW,WDT] SC1200 WDT (watchdog) driver
@@ -1611,8 +1614,6 @@ and is between 256 and 4096 characters. It is defined in the file
 
        serialnumber    [BUGS=X86-32]
 
-       sg_def_reserved_size=   [SCSI]
-
        shapers=        [NET]
                        Maximal number of shapers.
 
@@ -2003,10 +2004,6 @@ and is between 256 and 4096 characters. It is defined in the file
        norandmaps      Don't use address space randomization
                        Equivalent to echo 0 > /proc/sys/kernel/randomize_va_space
 
-       unwind_debug=N  N > 0 will enable dwarf2 unwinder debugging
-                       This is useful to get more information why
-                       you got a "dwarf2 unwinder stuck"
-
 ______________________________________________________________________
 
 TODO:
index c0b7a4556390e7c15e3f088ab1368c5db3cb9cca..bac037eb1cda771905bc9ed22926f8eb6a237481 100644 (file)
@@ -1,28 +1,8 @@
 # This creates the demonstration utility "lguest" which runs a Linux guest.
-
-# For those people that have a separate object dir, look there for .config
-KBUILD_OUTPUT := ../..
-ifdef O
-  ifeq ("$(origin O)", "command line")
-    KBUILD_OUTPUT := $(O)
-  endif
-endif
-# We rely on CONFIG_PAGE_OFFSET to know where to put lguest binary.
-include $(KBUILD_OUTPUT)/.config
-LGUEST_GUEST_TOP := ($(CONFIG_PAGE_OFFSET) - 0x08000000)
-
-CFLAGS:=-Wall -Wmissing-declarations -Wmissing-prototypes -O3 -Wl,-T,lguest.lds
+CFLAGS:=-Wall -Wmissing-declarations -Wmissing-prototypes -O3 -I../../include
 LDLIBS:=-lz
-# Removing this works for some versions of ld.so (eg. Ubuntu Feisty) and
-# not others (eg. FC7).
-LDFLAGS+=-static
-all: lguest.lds lguest
 
-# The linker script on x86 is so complex the only way of creating one
-# which will link our binary in the right place is to mangle the
-# default one.
-lguest.lds:
-       $(LD) --verbose | awk '/^==========/ { PRINT=1; next; } /SIZEOF_HEADERS/ { gsub(/0x[0-9A-F]*/, "$(LGUEST_GUEST_TOP)") } { if (PRINT) print $$0; }' > $@
+all: lguest
 
 clean:
-       rm -f lguest.lds lguest
+       rm -f lguest
index 103e346c8b6adc0f2f584fe491c55a3cefa82756..5bdc37f8184292a57e273f4256d698ef148b68a4 100644 (file)
@@ -1,10 +1,7 @@
 /*P:100 This is the Launcher code, a simple program which lays out the
  * "physical" memory for the new Guest by mapping the kernel image and the
  * virtual devices, then reads repeatedly from /dev/lguest to run the Guest.
- *
- * The only trick: the Makefile links it at a high address so it will be clear
- * of the guest memory region.  It means that each Guest cannot have more than
- * about 2.5G of memory on a normally configured Host. :*/
+:*/
 #define _LARGEFILE64_SOURCE
 #define _GNU_SOURCE
 #include <stdio.h>
@@ -15,6 +12,7 @@
 #include <stdlib.h>
 #include <elf.h>
 #include <sys/mman.h>
+#include <sys/param.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/wait.h>
@@ -34,7 +32,9 @@
 #include <termios.h>
 #include <getopt.h>
 #include <zlib.h>
-/*L:110 We can ignore the 28 include files we need for this program, but I do
+#include <assert.h>
+#include <sched.h>
+/*L:110 We can ignore the 30 include files we need for this program, but I do
  * want to draw attention to the use of kernel-style types.
  *
  * As Linus said, "C is a Spartan language, and so should your naming be."  I
@@ -45,8 +45,14 @@ typedef unsigned long long u64;
 typedef uint32_t u32;
 typedef uint16_t u16;
 typedef uint8_t u8;
-#include "../../include/linux/lguest_launcher.h"
-#include "../../include/asm-x86/e820_32.h"
+#include "linux/lguest_launcher.h"
+#include "linux/pci_ids.h"
+#include "linux/virtio_config.h"
+#include "linux/virtio_net.h"
+#include "linux/virtio_blk.h"
+#include "linux/virtio_console.h"
+#include "linux/virtio_ring.h"
+#include "asm-x86/bootparam.h"
 /*:*/
 
 #define PAGE_PRESENT 0x7       /* Present, RW, Execute */
@@ -55,6 +61,10 @@ typedef uint8_t u8;
 #ifndef SIOCBRADDIF
 #define SIOCBRADDIF    0x89a2          /* add interface to bridge      */
 #endif
+/* We can have up to 256 pages for devices. */
+#define DEVICE_PAGES 256
+/* This fits nicely in a single 4096-byte page. */
+#define VIRTQUEUE_NUM 127
 
 /*L:120 verbose is both a global flag and a macro.  The C preprocessor allows
  * this, and although I wouldn't recommend it, it works quite nicely here. */
@@ -65,8 +75,10 @@ static bool verbose;
 
 /* The pipe to send commands to the waker process */
 static int waker_fd;
-/* The top of guest physical memory. */
-static u32 top;
+/* The pointer to the start of guest memory. */
+static void *guest_base;
+/* The maximum guest physical address allowed, and maximum possible. */
+static unsigned long guest_limit, guest_max;
 
 /* This is our list of devices. */
 struct device_list
@@ -76,8 +88,17 @@ struct device_list
        fd_set infds;
        int max_infd;
 
+       /* Counter to assign interrupt numbers. */
+       unsigned int next_irq;
+
+       /* Counter to print out convenient device numbers. */
+       unsigned int device_num;
+
        /* The descriptor page for the devices. */
-       struct lguest_device_desc *descs;
+       u8 *descpage;
+
+       /* The tail of the last descriptor. */
+       unsigned int desc_used;
 
        /* A single linked list of devices. */
        struct device *dev;
@@ -85,31 +106,111 @@ struct device_list
        struct device **lastdev;
 };
 
+/* The list of Guest devices, based on command line arguments. */
+static struct device_list devices;
+
 /* The device structure describes a single device. */
 struct device
 {
        /* The linked-list pointer. */
        struct device *next;
-       /* The descriptor for this device, as mapped into the Guest. */
+
+       /* The this device's descriptor, as mapped into the Guest. */
        struct lguest_device_desc *desc;
-       /* The memory page(s) of this device, if any.  Also mapped in Guest. */
-       void *mem;
+
+       /* The name of this device, for --verbose. */
+       const char *name;
 
        /* If handle_input is set, it wants to be called when this file
         * descriptor is ready. */
        int fd;
        bool (*handle_input)(int fd, struct device *me);
 
-       /* If handle_output is set, it wants to be called when the Guest sends
-        * DMA to this key. */
-       unsigned long watch_key;
-       u32 (*handle_output)(int fd, const struct iovec *iov,
-                            unsigned int num, struct device *me);
+       /* Any queues attached to this device */
+       struct virtqueue *vq;
 
        /* Device-specific data. */
        void *priv;
 };
 
+/* The virtqueue structure describes a queue attached to a device. */
+struct virtqueue
+{
+       struct virtqueue *next;
+
+       /* Which device owns me. */
+       struct device *dev;
+
+       /* The configuration for this queue. */
+       struct lguest_vqconfig config;
+
+       /* The actual ring of buffers. */
+       struct vring vring;
+
+       /* Last available index we saw. */
+       u16 last_avail_idx;
+
+       /* The routine to call when the Guest pings us. */
+       void (*handle_output)(int fd, struct virtqueue *me);
+};
+
+/* Since guest is UP and we don't run at the same time, we don't need barriers.
+ * But I include them in the code in case others copy it. */
+#define wmb()
+
+/* Convert an iovec element to the given type.
+ *
+ * This is a fairly ugly trick: we need to know the size of the type and
+ * alignment requirement to check the pointer is kosher.  It's also nice to
+ * have the name of the type in case we report failure.
+ *
+ * Typing those three things all the time is cumbersome and error prone, so we
+ * have a macro which sets them all up and passes to the real function. */
+#define convert(iov, type) \
+       ((type *)_convert((iov), sizeof(type), __alignof__(type), #type))
+
+static void *_convert(struct iovec *iov, size_t size, size_t align,
+                     const char *name)
+{
+       if (iov->iov_len != size)
+               errx(1, "Bad iovec size %zu for %s", iov->iov_len, name);
+       if ((unsigned long)iov->iov_base % align != 0)
+               errx(1, "Bad alignment %p for %s", iov->iov_base, name);
+       return iov->iov_base;
+}
+
+/* The virtio configuration space is defined to be little-endian.  x86 is
+ * little-endian too, but it's nice to be explicit so we have these helpers. */
+#define cpu_to_le16(v16) (v16)
+#define cpu_to_le32(v32) (v32)
+#define cpu_to_le64(v64) (v64)
+#define le16_to_cpu(v16) (v16)
+#define le32_to_cpu(v32) (v32)
+#define le64_to_cpu(v32) (v64)
+
+/*L:100 The Launcher code itself takes us out into userspace, that scary place
+ * where pointers run wild and free!  Unfortunately, like most userspace
+ * programs, it's quite boring (which is why everyone likes to hack on the
+ * kernel!).  Perhaps if you make up an Lguest Drinking Game at this point, it
+ * will get you through this section.  Or, maybe not.
+ *
+ * The Launcher sets up a big chunk of memory to be the Guest's "physical"
+ * memory and stores it in "guest_base".  In other words, Guest physical ==
+ * Launcher virtual with an offset.
+ *
+ * This can be tough to get your head around, but usually it just means that we
+ * use these trivial conversion functions when the Guest gives us it's
+ * "physical" addresses: */
+static void *from_guest_phys(unsigned long addr)
+{
+       return guest_base + addr;
+}
+
+static unsigned long to_guest_phys(const void *addr)
+{
+       return (addr - guest_base);
+}
+
 /*L:130
  * Loading the Kernel.
  *
@@ -123,43 +224,55 @@ static int open_or_die(const char *name, int flags)
        return fd;
 }
 
-/* map_zeroed_pages() takes a (page-aligned) address and a number of pages. */
-static void *map_zeroed_pages(unsigned long addr, unsigned int num)
+/* map_zeroed_pages() takes a number of pages. */
+static void *map_zeroed_pages(unsigned int num)
 {
-       /* We cache the /dev/zero file-descriptor so we only open it once. */
-       static int fd = -1;
-
-       if (fd == -1)
-               fd = open_or_die("/dev/zero", O_RDONLY);
+       int fd = open_or_die("/dev/zero", O_RDONLY);
+       void *addr;
 
        /* We use a private mapping (ie. if we write to the page, it will be
-        * copied), and obviously we insist that it be mapped where we ask. */
-       if (mmap((void *)addr, getpagesize() * num,
-                PROT_READ|PROT_WRITE|PROT_EXEC, MAP_FIXED|MAP_PRIVATE, fd, 0)
-           != (void *)addr)
-               err(1, "Mmaping %u pages of /dev/zero @%p", num, (void *)addr);
-
-       /* Returning the address is just a courtesy: can simplify callers. */
-       return (void *)addr;
+        * copied). */
+       addr = mmap(NULL, getpagesize() * num,
+                   PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, fd, 0);
+       if (addr == MAP_FAILED)
+               err(1, "Mmaping %u pages of /dev/zero", num);
+
+       return addr;
 }
 
-/* To find out where to start we look for the magic Guest string, which marks
- * the code we see in lguest_asm.S.  This is a hack which we are currently
- * plotting to replace with the normal Linux entry point. */
-static unsigned long entry_point(void *start, void *end,
-                                unsigned long page_offset)
+/* Get some more pages for a device. */
+static void *get_pages(unsigned int num)
 {
-       void *p;
+       void *addr = from_guest_phys(guest_limit);
 
-       /* The scan gives us the physical starting address.  We want the
-        * virtual address in this case, and fortunately, we already figured
-        * out the physical-virtual difference and passed it here in
-        * "page_offset". */
-       for (p = start; p < end; p++)
-               if (memcmp(p, "GenuineLguest", strlen("GenuineLguest")) == 0)
-                       return (long)p + strlen("GenuineLguest") + page_offset;
+       guest_limit += num * getpagesize();
+       if (guest_limit > guest_max)
+               errx(1, "Not enough memory for devices");
+       return addr;
+}
 
-       err(1, "Is this image a genuine lguest?");
+/* This routine is used to load the kernel or initrd.  It tries mmap, but if
+ * that fails (Plan 9's kernel file isn't nicely aligned on page boundaries),
+ * it falls back to reading the memory in. */
+static void map_at(int fd, void *addr, unsigned long offset, unsigned long len)
+{
+       ssize_t r;
+
+       /* We map writable even though for some segments are marked read-only.
+        * The kernel really wants to be writable: it patches its own
+        * instructions.
+        *
+        * MAP_PRIVATE means that the page won't be copied until a write is
+        * done to it.  This allows us to share untouched memory between
+        * Guests. */
+       if (mmap(addr, len, PROT_READ|PROT_WRITE|PROT_EXEC,
+                MAP_FIXED|MAP_PRIVATE, fd, offset) != MAP_FAILED)
+               return;
+
+       /* pread does a seek and a read in one shot: saves a few lines. */
+       r = pread(fd, addr, len, offset);
+       if (r != len)
+               err(1, "Reading offset %lu len %lu gave %zi", offset, len, r);
 }
 
 /* This routine takes an open vmlinux image, which is in ELF, and maps it into
@@ -167,19 +280,14 @@ static unsigned long entry_point(void *start, void *end,
  * by all modern binaries on Linux including the kernel.
  *
  * The ELF headers give *two* addresses: a physical address, and a virtual
- * address.  The Guest kernel expects to be placed in memory at the physical
- * address, and the page tables set up so it will correspond to that virtual
- * address.  We return the difference between the virtual and physical
- * addresses in the "page_offset" pointer.
+ * address.  We use the physical address; the Guest will map itself to the
+ * virtual address.
  *
  * We return the starting address. */
-static unsigned long map_elf(int elf_fd, const Elf32_Ehdr *ehdr,
-                            unsigned long *page_offset)
+static unsigned long map_elf(int elf_fd, const Elf32_Ehdr *ehdr)
 {
-       void *addr;
        Elf32_Phdr phdr[ehdr->e_phnum];
        unsigned int i;
-       unsigned long start = -1UL, end = 0;
 
        /* Sanity checks on the main ELF header: an x86 executable with a
         * reasonable number of correctly-sized program headers. */
@@ -199,9 +307,6 @@ static unsigned long map_elf(int elf_fd, const Elf32_Ehdr *ehdr,
        if (read(elf_fd, phdr, sizeof(phdr)) != sizeof(phdr))
                err(1, "Reading program headers");
 
-       /* We don't know page_offset yet. */
-       *page_offset = 0;
-
        /* Try all the headers: there are usually only three.  A read-only one,
         * a read-write one, and a "note" section which isn't loadable. */
        for (i = 0; i < ehdr->e_phnum; i++) {
@@ -212,158 +317,53 @@ static unsigned long map_elf(int elf_fd, const Elf32_Ehdr *ehdr,
                verbose("Section %i: size %i addr %p\n",
                        i, phdr[i].p_memsz, (void *)phdr[i].p_paddr);
 
-               /* We expect a simple linear address space: every segment must
-                * have the same difference between virtual (p_vaddr) and
-                * physical (p_paddr) address. */
-               if (!*page_offset)
-                       *page_offset = phdr[i].p_vaddr - phdr[i].p_paddr;
-               else if (*page_offset != phdr[i].p_vaddr - phdr[i].p_paddr)
-                       errx(1, "Page offset of section %i different", i);
-
-               /* We track the first and last address we mapped, so we can
-                * tell entry_point() where to scan. */
-               if (phdr[i].p_paddr < start)
-                       start = phdr[i].p_paddr;
-               if (phdr[i].p_paddr + phdr[i].p_filesz > end)
-                       end = phdr[i].p_paddr + phdr[i].p_filesz;
-
-               /* We map this section of the file at its physical address.  We
-                * map it read & write even if the header says this segment is
-                * read-only.  The kernel really wants to be writable: it
-                * patches its own instructions which would normally be
-                * read-only.
-                *
-                * MAP_PRIVATE means that the page won't be copied until a
-                * write is done to it.  This allows us to share much of the
-                * kernel memory between Guests. */
-               addr = mmap((void *)phdr[i].p_paddr,
-                           phdr[i].p_filesz,
-                           PROT_READ|PROT_WRITE|PROT_EXEC,
-                           MAP_FIXED|MAP_PRIVATE,
-                           elf_fd, phdr[i].p_offset);
-               if (addr != (void *)phdr[i].p_paddr)
-                       err(1, "Mmaping vmlinux seg %i gave %p not %p",
-                           i, addr, (void *)phdr[i].p_paddr);
+               /* We map this section of the file at its physical address. */
+               map_at(elf_fd, from_guest_phys(phdr[i].p_paddr),
+                      phdr[i].p_offset, phdr[i].p_filesz);
        }
 
-       return entry_point((void *)start, (void *)end, *page_offset);
+       /* The entry point is given in the ELF header. */
+       return ehdr->e_entry;
 }
 
-/*L:170 Prepare to be SHOCKED and AMAZED.  And possibly a trifle nauseated.
- *
- * We know that CONFIG_PAGE_OFFSET sets what virtual address the kernel expects
- * to be.  We don't know what that option was, but we can figure it out
- * approximately by looking at the addresses in the code.  I chose the common
- * case of reading a memory location into the %eax register:
- *
- *  movl <some-address>, %eax
- *
- * This gets encoded as five bytes: "0xA1 <4-byte-address>".  For example,
- * "0xA1 0x18 0x60 0x47 0xC0" reads the address 0xC0476018 into %eax.
- *
- * In this example can guess that the kernel was compiled with
- * CONFIG_PAGE_OFFSET set to 0xC0000000 (it's always a round number).  If the
- * kernel were larger than 16MB, we might see 0xC1 addresses show up, but our
- * kernel isn't that bloated yet.
- *
- * Unfortunately, x86 has variable-length instructions, so finding this
- * particular instruction properly involves writing a disassembler.  Instead,
- * we rely on statistics.  We look for "0xA1" and tally the different bytes
- * which occur 4 bytes later (the "0xC0" in our example above).  When one of
- * those bytes appears three times, we can be reasonably confident that it
- * forms the start of CONFIG_PAGE_OFFSET.
+/*L:150 A bzImage, unlike an ELF file, is not meant to be loaded.  You're
+ * supposed to jump into it and it will unpack itself.  We used to have to
+ * perform some hairy magic because the unpacking code scared me.
  *
- * This is amazingly reliable. */
-static unsigned long intuit_page_offset(unsigned char *img, unsigned long len)
+ * Fortunately, Jeremy Fitzhardinge convinced me it wasn't that hard and wrote
+ * a small patch to jump over the tricky bits in the Guest, so now we just read
+ * the funky header so we know where in the file to load, and away we go! */
+static unsigned long load_bzimage(int fd)
 {
-       unsigned int i, possibilities[256] = { 0 };
+       struct boot_params boot;
+       int r;
+       /* Modern bzImages get loaded at 1M. */
+       void *p = from_guest_phys(0x100000);
 
-       for (i = 0; i + 4 < len; i++) {
-               /* mov 0xXXXXXXXX,%eax */
-               if (img[i] == 0xA1 && ++possibilities[img[i+4]] > 3)
-                       return (unsigned long)img[i+4] << 24;
-       }
-       errx(1, "could not determine page offset");
-}
+       /* Go back to the start of the file and read the header.  It should be
+        * a Linux boot header (see Documentation/i386/boot.txt) */
+       lseek(fd, 0, SEEK_SET);
+       read(fd, &boot, sizeof(boot));
 
-/*L:160 Unfortunately the entire ELF image isn't compressed: the segments
- * which need loading are extracted and compressed raw.  This denies us the
- * information we need to make a fully-general loader. */
-static unsigned long unpack_bzimage(int fd, unsigned long *page_offset)
-{
-       gzFile f;
-       int ret, len = 0;
-       /* A bzImage always gets loaded at physical address 1M.  This is
-        * actually configurable as CONFIG_PHYSICAL_START, but as the comment
-        * there says, "Don't change this unless you know what you are doing".
-        * Indeed. */
-       void *img = (void *)0x100000;
-
-       /* gzdopen takes our file descriptor (carefully placed at the start of
-        * the GZIP header we found) and returns a gzFile. */
-       f = gzdopen(fd, "rb");
-       /* We read it into memory in 64k chunks until we hit the end. */
-       while ((ret = gzread(f, img + len, 65536)) > 0)
-               len += ret;
-       if (ret < 0)
-               err(1, "reading image from bzImage");
-
-       verbose("Unpacked size %i addr %p\n", len, img);
-
-       /* Without the ELF header, we can't tell virtual-physical gap.  This is
-        * CONFIG_PAGE_OFFSET, and people do actually change it.  Fortunately,
-        * I have a clever way of figuring it out from the code itself.  */
-       *page_offset = intuit_page_offset(img, len);
-
-       return entry_point(img, img + len, *page_offset);
-}
+       /* Inside the setup_hdr, we expect the magic "HdrS" */
+       if (memcmp(&boot.hdr.header, "HdrS", 4) != 0)
+               errx(1, "This doesn't look like a bzImage to me");
 
-/*L:150 A bzImage, unlike an ELF file, is not meant to be loaded.  You're
- * supposed to jump into it and it will unpack itself.  We can't do that
- * because the Guest can't run the unpacking code, and adding features to
- * lguest kills puppies, so we don't want to.
- *
- * The bzImage is formed by putting the decompressing code in front of the
- * compressed kernel code.  So we can simple scan through it looking for the
- * first "gzip" header, and start decompressing from there. */
-static unsigned long load_bzimage(int fd, unsigned long *page_offset)
-{
-       unsigned char c;
-       int state = 0;
-
-       /* GZIP header is 0x1F 0x8B <method> <flags>... <compressed-by>. */
-       while (read(fd, &c, 1) == 1) {
-               switch (state) {
-               case 0:
-                       if (c == 0x1F)
-                               state++;
-                       break;
-               case 1:
-                       if (c == 0x8B)
-                               state++;
-                       else
-                               state = 0;
-                       break;
-               case 2 ... 8:
-                       state++;
-                       break;
-               case 9:
-                       /* Seek back to the start of the gzip header. */
-                       lseek(fd, -10, SEEK_CUR);
-                       /* One final check: "compressed under UNIX". */
-                       if (c != 0x03)
-                               state = -1;
-                       else
-                               return unpack_bzimage(fd, page_offset);
-               }
-       }
-       errx(1, "Could not find kernel in bzImage");
+       /* Skip over the extra sectors of the header. */
+       lseek(fd, (boot.hdr.setup_sects+1) * 512, SEEK_SET);
+
+       /* Now read everything into memory. in nice big chunks. */
+       while ((r = read(fd, p, 65536)) > 0)
+               p += r;
+
+       /* Finally, code32_start tells us where to enter the kernel. */
+       return boot.hdr.code32_start;
 }
 
 /*L:140 Loading the kernel is easy when it's a "vmlinux", but most kernels
  * come wrapped up in the self-decompressing "bzImage" format.  With some funky
  * coding, we can load those, too. */
-static unsigned long load_kernel(int fd, unsigned long *page_offset)
+static unsigned long load_kernel(int fd)
 {
        Elf32_Ehdr hdr;
 
@@ -373,10 +373,10 @@ static unsigned long load_kernel(int fd, unsigned long *page_offset)
 
        /* If it's an ELF file, it starts with "\177ELF" */
        if (memcmp(hdr.e_ident, ELFMAG, SELFMAG) == 0)
-               return map_elf(fd, &hdr, page_offset);
+               return map_elf(fd, &hdr);
 
        /* Otherwise we assume it's a bzImage, and try to unpack it */
-       return load_bzimage(fd, page_offset);
+       return load_bzimage(fd);
 }
 
 /* This is a trivial little helper to align pages.  Andi Kleen hated it because
@@ -402,59 +402,45 @@ static unsigned long load_initrd(const char *name, unsigned long mem)
        int ifd;
        struct stat st;
        unsigned long len;
-       void *iaddr;
 
        ifd = open_or_die(name, O_RDONLY);
        /* fstat() is needed to get the file size. */
        if (fstat(ifd, &st) < 0)
                err(1, "fstat() on initrd '%s'", name);
 
-       /* The length needs to be rounded up to a page size: mmap needs the
-        * address to be page aligned. */
+       /* We map the initrd at the top of memory, but mmap wants it to be
+        * page-aligned, so we round the size up for that. */
        len = page_align(st.st_size);
-       /* We map the initrd at the top of memory. */
-       iaddr = mmap((void *)mem - len, st.st_size,
-                    PROT_READ|PROT_EXEC|PROT_WRITE,
-                    MAP_FIXED|MAP_PRIVATE, ifd, 0);
-       if (iaddr != (void *)mem - len)
-               err(1, "Mmaping initrd '%s' returned %p not %p",
-                   name, iaddr, (void *)mem - len);
+       map_at(ifd, from_guest_phys(mem - len), 0, st.st_size);
        /* Once a file is mapped, you can close the file descriptor.  It's a
         * little odd, but quite useful. */
        close(ifd);
-       verbose("mapped initrd %s size=%lu @ %p\n", name, st.st_size, iaddr);
+       verbose("mapped initrd %s size=%lu @ %p\n", name, len, (void*)mem-len);
 
        /* We return the initrd size. */
        return len;
 }
 
-/* Once we know how much memory we have, and the address the Guest kernel
- * expects, we can construct simple linear page tables which will get the Guest
- * far enough into the boot to create its own.
+/* Once we know how much memory we have, we can construct simple linear page
+ * tables which set virtual == physical which will get the Guest far enough
+ * into the boot to create its own.
  *
  * We lay them out of the way, just below the initrd (which is why we need to
  * know its size). */
 static unsigned long setup_pagetables(unsigned long mem,
-                                     unsigned long initrd_size,
-                                     unsigned long page_offset)
+                                     unsigned long initrd_size)
 {
-       u32 *pgdir, *linear;
+       unsigned long *pgdir, *linear;
        unsigned int mapped_pages, i, linear_pages;
-       unsigned int ptes_per_page = getpagesize()/sizeof(u32);
+       unsigned int ptes_per_page = getpagesize()/sizeof(void *);
 
-       /* Ideally we map all physical memory starting at page_offset.
-        * However, if page_offset is 0xC0000000 we can only map 1G of physical
-        * (0xC0000000 + 1G overflows). */
-       if (mem <= -page_offset)
-               mapped_pages = mem/getpagesize();
-       else
-               mapped_pages = -page_offset/getpagesize();
+       mapped_pages = mem/getpagesize();
 
        /* Each PTE page can map ptes_per_page pages: how many do we need? */
        linear_pages = (mapped_pages + ptes_per_page-1)/ptes_per_page;
 
        /* We put the toplevel page directory page at the top of memory. */
-       pgdir = (void *)mem - initrd_size - getpagesize();
+       pgdir = from_guest_phys(mem) - initrd_size - getpagesize();
 
        /* Now we use the next linear_pages pages as pte pages */
        linear = (void *)pgdir - linear_pages*getpagesize();
@@ -465,20 +451,19 @@ static unsigned long setup_pagetables(unsigned long mem,
        for (i = 0; i < mapped_pages; i++)
                linear[i] = ((i * getpagesize()) | PAGE_PRESENT);
 
-       /* The top level points to the linear page table pages above.  The
-        * entry representing page_offset points to the first one, and they
-        * continue from there. */
+       /* The top level points to the linear page table pages above. */
        for (i = 0; i < mapped_pages; i += ptes_per_page) {
-               pgdir[(i + page_offset/getpagesize())/ptes_per_page]
-                       = (((u32)linear + i*sizeof(u32)) | PAGE_PRESENT);
+               pgdir[i/ptes_per_page]
+                       = ((to_guest_phys(linear) + i*sizeof(void *))
+                          | PAGE_PRESENT);
        }
 
-       verbose("Linear mapping of %u pages in %u pte pages at %p\n",
-               mapped_pages, linear_pages, linear);
+       verbose("Linear mapping of %u pages in %u pte pages at %#lx\n",
+               mapped_pages, linear_pages, to_guest_phys(linear));
 
        /* We return the top level (guest-physical) address: the kernel needs
         * to know where it is. */
-       return (unsigned long)pgdir;
+       return to_guest_phys(pgdir);
 }
 
 /* Simple routine to roll all the commandline arguments together with spaces
@@ -498,14 +483,17 @@ static void concat(char *dst, char *args[])
 
 /* This is where we actually tell the kernel to initialize the Guest.  We saw
  * the arguments it expects when we looked at initialize() in lguest_user.c:
- * the top physical page to allow, the top level pagetable, the entry point and
- * the page_offset constant for the Guest. */
-static int tell_kernel(u32 pgdir, u32 start, u32 page_offset)
+ * the base of guest "physical" memory, the top physical page to allow, the
+ * top level pagetable and the entry point for the Guest. */
+static int tell_kernel(unsigned long pgdir, unsigned long start)
 {
-       u32 args[] = { LHREQ_INITIALIZE,
-                      top/getpagesize(), pgdir, start, page_offset };
+       unsigned long args[] = { LHREQ_INITIALIZE,
+                                (unsigned long)guest_base,
+                                guest_limit / getpagesize(), pgdir, start };
        int fd;
 
+       verbose("Guest: %p - %p (%#lx)\n",
+               guest_base, guest_base + guest_limit, guest_limit);
        fd = open_or_die("/dev/lguest", O_RDWR);
        if (write(fd, args, sizeof(args)) < 0)
                err(1, "Writing to /dev/lguest");
@@ -515,11 +503,11 @@ static int tell_kernel(u32 pgdir, u32 start, u32 page_offset)
 }
 /*:*/
 
-static void set_fd(int fd, struct device_list *devices)
+static void add_device_fd(int fd)
 {
-       FD_SET(fd, &devices->infds);
-       if (fd > devices->max_infd)
-               devices->max_infd = fd;
+       FD_SET(fd, &devices.infds);
+       if (fd > devices.max_infd)
+               devices.max_infd = fd;
 }
 
 /*L:200
@@ -537,36 +525,38 @@ static void set_fd(int fd, struct device_list *devices)
  *
  * This, of course, is merely a different *kind* of icky.
  */
-static void wake_parent(int pipefd, int lguest_fd, struct device_list *devices)
+static void wake_parent(int pipefd, int lguest_fd)
 {
        /* Add the pipe from the Launcher to the fdset in the device_list, so
         * we watch it, too. */
-       set_fd(pipefd, devices);
+       add_device_fd(pipefd);
 
        for (;;) {
-               fd_set rfds = devices->infds;
-               u32 args[] = { LHREQ_BREAK, 1 };
+               fd_set rfds = devices.infds;
+               unsigned long args[] = { LHREQ_BREAK, 1 };
 
                /* Wait until input is ready from one of the devices. */
-               select(devices->max_infd+1, &rfds, NULL, NULL, NULL);
+               select(devices.max_infd+1, &rfds, NULL, NULL, NULL);
                /* Is it a message from the Launcher? */
                if (FD_ISSET(pipefd, &rfds)) {
-                       int ignorefd;
+                       int fd;
                        /* If read() returns 0, it means the Launcher has
                         * exited.  We silently follow. */
-                       if (read(pipefd, &ignorefd, sizeof(ignorefd)) == 0)
+                       if (read(pipefd, &fd, sizeof(fd)) == 0)
                                exit(0);
-                       /* Otherwise it's telling us there's a problem with one
-                        * of the devices, and we should ignore that file
-                        * descriptor from now on. */
-                       FD_CLR(ignorefd, &devices->infds);
+                       /* Otherwise it's telling us to change what file
+                        * descriptors we're to listen to. */
+                       if (fd >= 0)
+                               FD_SET(fd, &devices.infds);
+                       else
+                               FD_CLR(-fd - 1, &devices.infds);
                } else /* Send LHREQ_BREAK command. */
                        write(lguest_fd, args, sizeof(args));
        }
 }
 
 /* This routine just sets up a pipe to the Waker process. */
-static int setup_waker(int lguest_fd, struct device_list *device_list)
+static int setup_waker(int lguest_fd)
 {
        int pipefd[2], child;
 
@@ -580,7 +570,7 @@ static int setup_waker(int lguest_fd, struct device_list *device_list)
        if (child == 0) {
                /* Close the "writing" end of our copy of the pipe */
                close(pipefd[1]);
-               wake_parent(pipefd[0], lguest_fd, device_list);
+               wake_parent(pipefd[0], lguest_fd);
        }
        /* Close the reading end of our copy of the pipe. */
        close(pipefd[0]);
@@ -602,83 +592,128 @@ static void *_check_pointer(unsigned long addr, unsigned int size,
 {
        /* We have to separately check addr and addr+size, because size could
         * be huge and addr + size might wrap around. */
-       if (addr >= top || addr + size >= top)
-               errx(1, "%s:%i: Invalid address %li", __FILE__, line, addr);
+       if (addr >= guest_limit || addr + size >= guest_limit)
+               errx(1, "%s:%i: Invalid address %#lx", __FILE__, line, addr);
        /* We return a pointer for the caller's convenience, now we know it's
         * safe to use. */
-       return (void *)addr;
+       return from_guest_phys(addr);
 }
 /* A macro which transparently hands the line number to the real function. */
 #define check_pointer(addr,size) _check_pointer(addr, size, __LINE__)
 
-/* The Guest has given us the address of a "struct lguest_dma".  We check it's
- * OK and convert it to an iovec (which is a simple array of ptr/size
- * pairs). */
-static u32 *dma2iov(unsigned long dma, struct iovec iov[], unsigned *num)
+/* This function returns the next descriptor in the chain, or vq->vring.num. */
+static unsigned next_desc(struct virtqueue *vq, unsigned int i)
 {
-       unsigned int i;
-       struct lguest_dma *udma;
-
-       /* First we make sure that the array memory itself is valid. */
-       udma = check_pointer(dma, sizeof(*udma));
-       /* Now we check each element */
-       for (i = 0; i < LGUEST_MAX_DMA_SECTIONS; i++) {
-               /* A zero length ends the array. */
-               if (!udma->len[i])
-                       break;
+       unsigned int next;
 
-               iov[i].iov_base = check_pointer(udma->addr[i], udma->len[i]);
-               iov[i].iov_len = udma->len[i];
-       }
-       *num = i;
+       /* If this descriptor says it doesn't chain, we're done. */
+       if (!(vq->vring.desc[i].flags & VRING_DESC_F_NEXT))
+               return vq->vring.num;
+
+       /* Check they're not leading us off end of descriptors. */
+       next = vq->vring.desc[i].next;
+       /* Make sure compiler knows to grab that: we don't want it changing! */
+       wmb();
 
-       /* We return the pointer to where the caller should write the amount of
-        * the buffer used. */
-       return &udma->used_len;
+       if (next >= vq->vring.num)
+               errx(1, "Desc next is %u", next);
+
+       return next;
+}
+
+/* This looks in the virtqueue and for the first available buffer, and converts
+ * it to an iovec for convenient access.  Since descriptors consist of some
+ * number of output then some number of input descriptors, it's actually two
+ * iovecs, but we pack them into one and note how many of each there were.
+ *
+ * This function returns the descriptor number found, or vq->vring.num (which
+ * is never a valid descriptor number) if none was found. */
+static unsigned get_vq_desc(struct virtqueue *vq,
+                           struct iovec iov[],
+                           unsigned int *out_num, unsigned int *in_num)
+{
+       unsigned int i, head;
+
+       /* Check it isn't doing very strange things with descriptor numbers. */
+       if ((u16)(vq->vring.avail->idx - vq->last_avail_idx) > vq->vring.num)
+               errx(1, "Guest moved used index from %u to %u",
+                    vq->last_avail_idx, vq->vring.avail->idx);
+
+       /* If there's nothing new since last we looked, return invalid. */
+       if (vq->vring.avail->idx == vq->last_avail_idx)
+               return vq->vring.num;
+
+       /* Grab the next descriptor number they're advertising, and increment
+        * the index we've seen. */
+       head = vq->vring.avail->ring[vq->last_avail_idx++ % vq->vring.num];
+
+       /* If their number is silly, that's a fatal mistake. */
+       if (head >= vq->vring.num)
+               errx(1, "Guest says index %u is available", head);
+
+       /* When we start there are none of either input nor output. */
+       *out_num = *in_num = 0;
+
+       i = head;
+       do {
+               /* Grab the first descriptor, and check it's OK. */
+               iov[*out_num + *in_num].iov_len = vq->vring.desc[i].len;
+               iov[*out_num + *in_num].iov_base
+                       = check_pointer(vq->vring.desc[i].addr,
+                                       vq->vring.desc[i].len);
+               /* If this is an input descriptor, increment that count. */
+               if (vq->vring.desc[i].flags & VRING_DESC_F_WRITE)
+                       (*in_num)++;
+               else {
+                       /* If it's an output descriptor, they're all supposed
+                        * to come before any input descriptors. */
+                       if (*in_num)
+                               errx(1, "Descriptor has out after in");
+                       (*out_num)++;
+               }
+
+               /* If we've got too many, that implies a descriptor loop. */
+               if (*out_num + *in_num > vq->vring.num)
+                       errx(1, "Looped descriptor");
+       } while ((i = next_desc(vq, i)) != vq->vring.num);
+
+       return head;
 }
 
-/* This routine gets a DMA buffer from the Guest for a given key, and converts
- * it to an iovec array.  It returns the interrupt the Guest wants when we're
- * finished, and a pointer to the "used_len" field to fill in. */
-static u32 *get_dma_buffer(int fd, void *key,
-                          struct iovec iov[], unsigned int *num, u32 *irq)
+/* Once we've used one of their buffers, we tell them about it.  We'll then
+ * want to send them an interrupt, using trigger_irq(). */
+static void add_used(struct virtqueue *vq, unsigned int head, int len)
 {
-       u32 buf[] = { LHREQ_GETDMA, (u32)key };
-       unsigned long udma;
-       u32 *res;
-
-       /* Ask the kernel for a DMA buffer corresponding to this key. */
-       udma = write(fd, buf, sizeof(buf));
-       /* They haven't registered any, or they're all used? */
-       if (udma == (unsigned long)-1)
-               return NULL;
-
-       /* Convert it into our iovec array */
-       res = dma2iov(udma, iov, num);
-       /* The kernel stashes irq in ->used_len to get it out to us. */
-       *irq = *res;
-       /* Return a pointer to ((struct lguest_dma *)udma)->used_len. */
-       return res;
+       struct vring_used_elem *used;
+
+       /* Get a pointer to the next entry in the used ring. */
+       used = &vq->vring.used->ring[vq->vring.used->idx % vq->vring.num];
+       used->id = head;
+       used->len = len;
+       /* Make sure buffer is written before we update index. */
+       wmb();
+       vq->vring.used->idx++;
 }
 
-/* This is a convenient routine to send the Guest an interrupt. */
-static void trigger_irq(int fd, u32 irq)
+/* This actually sends the interrupt for this virtqueue */
+static void trigger_irq(int fd, struct virtqueue *vq)
 {
-       u32 buf[] = { LHREQ_IRQ, irq };
+       unsigned long buf[] = { LHREQ_IRQ, vq->config.irq };
+
+       if (vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT)
+               return;
+
+       /* Send the Guest an interrupt tell them we used something up. */
        if (write(fd, buf, sizeof(buf)) != 0)
-               err(1, "Triggering irq %i", irq);
+               err(1, "Triggering irq %i", vq->config.irq);
 }
 
-/* This simply sets up an iovec array where we can put data to be discarded.
- * This happens when the Guest doesn't want or can't handle the input: we have
- * to get rid of it somewhere, and if we bury it in the ceiling space it will
- * start to smell after a week. */
-static void discard_iovec(struct iovec *iov, unsigned int *num)
+/* And here's the combo meal deal.  Supersize me! */
+static void add_used_and_trigger(int fd, struct virtqueue *vq,
+                                unsigned int head, int len)
 {
-       static char discard_buf[1024];
-       *num = 1;
-       iov->iov_base = discard_buf;
-       iov->iov_len = sizeof(discard_buf);
+       add_used(vq, head, len);
+       trigger_irq(fd, vq);
 }
 
 /* Here is the input terminal setting we save, and the routine to restore them
@@ -701,38 +736,39 @@ struct console_abort
 /* This is the routine which handles console input (ie. stdin). */
 static bool handle_console_input(int fd, struct device *dev)
 {
-       u32 irq = 0, *lenp;
        int len;
-       unsigned int num;
-       struct iovec iov[LGUEST_MAX_DMA_SECTIONS];
+       unsigned int head, in_num, out_num;
+       struct iovec iov[dev->vq->vring.num];
        struct console_abort *abort = dev->priv;
 
-       /* First we get the console buffer from the Guest.  The key is dev->mem
-        * which was set to 0 in setup_console(). */
-       lenp = get_dma_buffer(fd, dev->mem, iov, &num, &irq);
-       if (!lenp) {
-               /* If it's not ready for input, warn and set up to discard. */
-               warn("console: no dma buffer!");
-               discard_iovec(iov, &num);
-       }
+       /* First we need a console buffer from the Guests's input virtqueue. */
+       head = get_vq_desc(dev->vq, iov, &out_num, &in_num);
+
+       /* If they're not ready for input, stop listening to this file
+        * descriptor.  We'll start again once they add an input buffer. */
+       if (head == dev->vq->vring.num)
+               return false;
+
+       if (out_num)
+               errx(1, "Output buffers in console in queue?");
 
        /* This is why we convert to iovecs: the readv() call uses them, and so
         * it reads straight into the Guest's buffer. */
-       len = readv(dev->fd, iov, num);
+       len = readv(dev->fd, iov, in_num);
        if (len <= 0) {
                /* This implies that the console is closed, is /dev/null, or
-                * something went terribly wrong.  We still go through the rest
-                * of the logic, though, especially the exit handling below. */
+                * something went terribly wrong. */
                warnx("Failed to get console input, ignoring console.");
-               len = 0;
+               /* Put the input terminal back. */
+               restore_term();
+               /* Remove callback from input vq, so it doesn't restart us. */
+               dev->vq->handle_output = NULL;
+               /* Stop listening to this fd: don't call us again. */
+               return false;
        }
 
-       /* If we read the data into the Guest, fill in the length and send the
-        * interrupt. */
-       if (lenp) {
-               *lenp = len;
-               trigger_irq(fd, irq);
-       }
+       /* Tell the Guest about the new input. */
+       add_used_and_trigger(fd, dev->vq, head, len);
 
        /* Three ^C within one second?  Exit.
         *
@@ -746,7 +782,7 @@ static bool handle_console_input(int fd, struct device *dev)
                        struct timeval now;
                        gettimeofday(&now, NULL);
                        if (now.tv_sec <= abort->start.tv_sec+1) {
-                               u32 args[] = { LHREQ_BREAK, 0 };
+                               unsigned long args[] = { LHREQ_BREAK, 0 };
                                /* Close the fd so Waker will know it has to
                                 * exit. */
                                close(waker_fd);
@@ -761,214 +797,163 @@ static bool handle_console_input(int fd, struct device *dev)
                /* Any other key resets the abort counter. */
                abort->count = 0;
 
-       /* Now, if we didn't read anything, put the input terminal back and
-        * return failure (meaning, don't call us again). */
-       if (!len) {
-               restore_term();
-               return false;
-       }
        /* Everything went OK! */
        return true;
 }
 
-/* Handling console output is much simpler than input. */
-static u32 handle_console_output(int fd, const struct iovec *iov,
-                                unsigned num, struct device*dev)
+/* Handling output for console is simple: we just get all the output buffers
+ * and write them to stdout. */
+static void handle_console_output(int fd, struct virtqueue *vq)
 {
-       /* Whatever the Guest sends, write it to standard output.  Return the
-        * number of bytes written. */
-       return writev(STDOUT_FILENO, iov, num);
-}
-
-/* Guest->Host network output is also pretty easy. */
-static u32 handle_tun_output(int fd, const struct iovec *iov,
-                            unsigned num, struct device *dev)
-{
-       /* We put a flag in the "priv" pointer of the network device, and set
-        * it as soon as we see output.  We'll see why in handle_tun_input() */
-       *(bool *)dev->priv = true;
-       /* Whatever packet the Guest sent us, write it out to the tun
-        * device. */
-       return writev(dev->fd, iov, num);
+       unsigned int head, out, in;
+       int len;
+       struct iovec iov[vq->vring.num];
+
+       /* Keep getting output buffers from the Guest until we run out. */
+       while ((head = get_vq_desc(vq, iov, &out, &in)) != vq->vring.num) {
+               if (in)
+                       errx(1, "Input buffers in output queue?");
+               len = writev(STDOUT_FILENO, iov, out);
+               add_used_and_trigger(fd, vq, head, len);
+       }
 }
 
-/* This matches the peer_key() in lguest_net.c.  The key for any given slot
- * is the address of the network device's page plus 4 * the slot number. */
-static unsigned long peer_offset(unsigned int peernum)
+/* Handling output for network is also simple: we get all the output buffers
+ * and write them (ignoring the first element) to this device's file descriptor
+ * (stdout). */
+static void handle_net_output(int fd, struct virtqueue *vq)
 {
-       return 4 * peernum;
+       unsigned int head, out, in;
+       int len;
+       struct iovec iov[vq->vring.num];
+
+       /* Keep getting output buffers from the Guest until we run out. */
+       while ((head = get_vq_desc(vq, iov, &out, &in)) != vq->vring.num) {
+               if (in)
+                       errx(1, "Input buffers in output queue?");
+               /* Check header, but otherwise ignore it (we said we supported
+                * no features). */
+               (void)convert(&iov[0], struct virtio_net_hdr);
+               len = writev(vq->dev->fd, iov+1, out-1);
+               add_used_and_trigger(fd, vq, head, len);
+       }
 }
 
-/* This is where we handle a packet coming in from the tun device */
+/* This is where we handle a packet coming in from the tun device to our
+ * Guest. */
 static bool handle_tun_input(int fd, struct device *dev)
 {
-       u32 irq = 0, *lenp;
+       unsigned int head, in_num, out_num;
        int len;
-       unsigned num;
-       struct iovec iov[LGUEST_MAX_DMA_SECTIONS];
+       struct iovec iov[dev->vq->vring.num];
+       struct virtio_net_hdr *hdr;
 
-       /* First we get a buffer the Guest has bound to its key. */
-       lenp = get_dma_buffer(fd, dev->mem+peer_offset(NET_PEERNUM), iov, &num,
-                             &irq);
-       if (!lenp) {
+       /* First we need a network buffer from the Guests's recv virtqueue. */
+       head = get_vq_desc(dev->vq, iov, &out_num, &in_num);
+       if (head == dev->vq->vring.num) {
                /* Now, it's expected that if we try to send a packet too
-                * early, the Guest won't be ready yet.  This is why we set a
-                * flag when the Guest sends its first packet.  If it's sent a
-                * packet we assume it should be ready to receive them.
-                *
-                * Actually, this is what the status bits in the descriptor are
-                * for: we should *use* them.  FIXME! */
-               if (*(bool *)dev->priv)
+                * early, the Guest won't be ready yet.  Wait until the device
+                * status says it's ready. */
+               /* FIXME: Actually want DRIVER_ACTIVE here. */
+               if (dev->desc->status & VIRTIO_CONFIG_S_DRIVER_OK)
                        warn("network: no dma buffer!");
-               discard_iovec(iov, &num);
-       }
+               /* We'll turn this back on if input buffers are registered. */
+               return false;
+       } else if (out_num)
+               errx(1, "Output buffers in network recv queue?");
+
+       /* First element is the header: we set it to 0 (no features). */
+       hdr = convert(&iov[0], struct virtio_net_hdr);
+       hdr->flags = 0;
+       hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE;
 
        /* Read the packet from the device directly into the Guest's buffer. */
-       len = readv(dev->fd, iov, num);
+       len = readv(dev->fd, iov+1, in_num-1);
        if (len <= 0)
                err(1, "reading network");
 
-       /* Write the used_len, and trigger the interrupt for the Guest */
-       if (lenp) {
-               *lenp = len;
-               trigger_irq(fd, irq);
-       }
+       /* Tell the Guest about the new packet. */
+       add_used_and_trigger(fd, dev->vq, head, sizeof(*hdr) + len);
+
        verbose("tun input packet len %i [%02x %02x] (%s)\n", len,
-               ((u8 *)iov[0].iov_base)[0], ((u8 *)iov[0].iov_base)[1],
-               lenp ? "sent" : "discarded");
+               ((u8 *)iov[1].iov_base)[0], ((u8 *)iov[1].iov_base)[1],
+               head != dev->vq->vring.num ? "sent" : "discarded");
+
        /* All good. */
        return true;
 }
 
-/* The last device handling routine is block output: the Guest has sent a DMA
- * to the block device.  It will have placed the command it wants in the
- * "struct lguest_block_page". */
-static u32 handle_block_output(int fd, const struct iovec *iov,
-                              unsigned num, struct device *dev)
+/* This callback ensures we try again, in case we stopped console or net
+ * delivery because Guest didn't have any buffers. */
+static void enable_fd(int fd, struct virtqueue *vq)
 {
-       struct lguest_block_page *p = dev->mem;
-       u32 irq, *lenp;
-       unsigned int len, reply_num;
-       struct iovec reply[LGUEST_MAX_DMA_SECTIONS];
-       off64_t device_len, off = (off64_t)p->sector * 512;
-
-       /* First we extract the device length from the dev->priv pointer. */
-       device_len = *(off64_t *)dev->priv;
-
-       /* We first check that the read or write is within the length of the
-        * block file. */
-       if (off >= device_len)
-               err(1, "Bad offset %llu vs %llu", off, device_len);
-       /* Move to the right location in the block file.  This shouldn't fail,
-        * but best to check. */
-       if (lseek64(dev->fd, off, SEEK_SET) != off)
-               err(1, "Bad seek to sector %i", p->sector);
-
-       verbose("Block: %s at offset %llu\n", p->type ? "WRITE" : "READ", off);
-
-       /* They were supposed to bind a reply buffer at key equal to the start
-        * of the block device memory.  We need this to tell them when the
-        * request is finished. */
-       lenp = get_dma_buffer(fd, dev->mem, reply, &reply_num, &irq);
-       if (!lenp)
-               err(1, "Block request didn't give us a dma buffer");
-
-       if (p->type) {
-               /* A write request.  The DMA they sent contained the data, so
-                * write it out. */
-               len = writev(dev->fd, iov, num);
-               /* Grr... Now we know how long the "struct lguest_dma" they
-                * sent was, we make sure they didn't try to write over the end
-                * of the block file (possibly extending it). */
-               if (off + len > device_len) {
-                       /* Trim it back to the correct length */
-                       ftruncate64(dev->fd, device_len);
-                       /* Die, bad Guest, die. */
-                       errx(1, "Write past end %llu+%u", off, len);
-               }
-               /* The reply length is 0: we just send back an empty DMA to
-                * interrupt them and tell them the write is finished. */
-               *lenp = 0;
-       } else {
-               /* A read request.  They sent an empty DMA to start the
-                * request, and we put the read contents into the reply
-                * buffer. */
-               len = readv(dev->fd, reply, reply_num);
-               *lenp = len;
-       }
-
-       /* The result is 1 (done), 2 if there was an error (short read or
-        * write). */
-       p->result = 1 + (p->bytes != len);
-       /* Now tell them we've used their reply buffer. */
-       trigger_irq(fd, irq);
-
-       /* We're supposed to return the number of bytes of the output buffer we
-        * used.  But the block device uses the "result" field instead, so we
-        * don't bother. */
-       return 0;
+       add_device_fd(vq->dev->fd);
+       /* Tell waker to listen to it again */
+       write(waker_fd, &vq->dev->fd, sizeof(vq->dev->fd));
 }
 
-/* This is the generic routine we call when the Guest sends some DMA out. */
-static void handle_output(int fd, unsigned long dma, unsigned long key,
-                         struct device_list *devices)
+/* This is the generic routine we call when the Guest uses LHCALL_NOTIFY. */
+static void handle_output(int fd, unsigned long addr)
 {
        struct device *i;
-       u32 *lenp;
-       struct iovec iov[LGUEST_MAX_DMA_SECTIONS];
-       unsigned num = 0;
-
-       /* Convert the "struct lguest_dma" they're sending to a "struct
-        * iovec". */
-       lenp = dma2iov(dma, iov, &num);
-
-       /* Check each device: if they expect output to this key, tell them to
-        * handle it. */
-       for (i = devices->dev; i; i = i->next) {
-               if (i->handle_output && key == i->watch_key) {
-                       /* We write the result straight into the used_len field
-                        * for them. */
-                       *lenp = i->handle_output(fd, iov, num, i);
-                       return;
+       struct virtqueue *vq;
+
+       /* Check each virtqueue. */
+       for (i = devices.dev; i; i = i->next) {
+               for (vq = i->vq; vq; vq = vq->next) {
+                       if (vq->config.pfn == addr/getpagesize()
+                           && vq->handle_output) {
+                               verbose("Output to %s\n", vq->dev->name);
+                               vq->handle_output(fd, vq);
+                               return;
+                       }
                }
        }
 
-       /* This can happen: the kernel sends any SEND_DMA which doesn't match
-        * another Guest to us.  It could be that another Guest just left a
-        * network, for example.  But it's unusual. */
-       warnx("Pending dma %p, key %p", (void *)dma, (void *)key);
+       /* Early console write is done using notify on a nul-terminated string
+        * in Guest memory. */
+       if (addr >= guest_limit)
+               errx(1, "Bad NOTIFY %#lx", addr);
+
+       write(STDOUT_FILENO, from_guest_phys(addr),
+             strnlen(from_guest_phys(addr), guest_limit - addr));
 }
 
 /* This is called when the waker wakes us up: check for incoming file
  * descriptors. */
-static void handle_input(int fd, struct device_list *devices)
+static void handle_input(int fd)
 {
        /* select() wants a zeroed timeval to mean "don't wait". */
        struct timeval poll = { .tv_sec = 0, .tv_usec = 0 };
 
        for (;;) {
                struct device *i;
-               fd_set fds = devices->infds;
+               fd_set fds = devices.infds;
 
                /* If nothing is ready, we're done. */
-               if (select(devices->max_infd+1, &fds, NULL, NULL, &poll) == 0)
+               if (select(devices.max_infd+1, &fds, NULL, NULL, &poll) == 0)
                        break;
 
                /* Otherwise, call the device(s) which have readable
                 * file descriptors and a method of handling them.  */
-               for (i = devices->dev; i; i = i->next) {
+               for (i = devices.dev; i; i = i->next) {
                        if (i->handle_input && FD_ISSET(i->fd, &fds)) {
+                               int dev_fd;
+                               if (i->handle_input(fd, i))
+                                       continue;
+
                                /* If handle_input() returns false, it means we
-                                * should no longer service it.
-                                * handle_console_input() does this. */
-                               if (!i->handle_input(fd, i)) {
-                                       /* Clear it from the set of input file
-                                        * descriptors kept at the head of the
-                                        * device list. */
-                                       FD_CLR(i->fd, &devices->infds);
-                                       /* Tell waker to ignore it too... */
-                                       write(waker_fd, &i->fd, sizeof(i->fd));
-                               }
+                                * should no longer service it.  Networking and
+                                * console do this when there's no input
+                                * buffers to deliver into.  Console also uses
+                                * it when it discovers that stdin is
+                                * closed. */
+                               FD_CLR(i->fd, &devices.infds);
+                               /* Tell waker to ignore it too, by sending a
+                                * negative fd number (-1, since 0 is a valid
+                                * FD number). */
+                               dev_fd = -i->fd - 1;
+                               write(waker_fd, &dev_fd, sizeof(dev_fd));
                        }
                }
        }
@@ -982,43 +967,93 @@ static void handle_input(int fd, struct device_list *devices)
  * routines to allocate them.
  *
  * This routine allocates a new "struct lguest_device_desc" from descriptor
- * table in the devices array just above the Guest's normal memory. */
-static struct lguest_device_desc *
-new_dev_desc(struct lguest_device_desc *descs,
-            u16 type, u16 features, u16 num_pages)
+ * table just above the Guest's normal memory.  It returns a pointer to that
+ * descriptor. */
+static struct lguest_device_desc *new_dev_desc(u16 type)
 {
-       unsigned int i;
+       struct lguest_device_desc *d;
 
-       for (i = 0; i < LGUEST_MAX_DEVICES; i++) {
-               if (!descs[i].type) {
-                       descs[i].type = type;
-                       descs[i].features = features;
-                       descs[i].num_pages = num_pages;
-                       /* If they said the device needs memory, we allocate
-                        * that now, bumping up the top of Guest memory. */
-                       if (num_pages) {
-                               map_zeroed_pages(top, num_pages);
-                               descs[i].pfn = top/getpagesize();
-                               top += num_pages*getpagesize();
-                       }
-                       return &descs[i];
-               }
-       }
-       errx(1, "too many devices");
+       /* We only have one page for all the descriptors. */
+       if (devices.desc_used + sizeof(*d) > getpagesize())
+               errx(1, "Too many devices");
+
+       /* We don't need to set config_len or status: page is 0 already. */
+       d = (void *)devices.descpage + devices.desc_used;
+       d->type = type;
+       devices.desc_used += sizeof(*d);
+
+       return d;
 }
 
-/* This monster routine does all the creation and setup of a new device,
- * including caling new_dev_desc() to allocate the descriptor and device
- * memory. */
-static struct device *new_device(struct device_list *devices,
-                                u16 type, u16 num_pages, u16 features,
-                                int fd,
-                                bool (*handle_input)(int, struct device *),
-                                unsigned long watch_off,
-                                u32 (*handle_output)(int,
-                                                     const struct iovec *,
-                                                     unsigned,
-                                                     struct device *))
+/* Each device descriptor is followed by some configuration information.
+ * The first byte is a "status" byte for the Guest to report what's happening.
+ * After that are fields: u8 type, u8 len, [... len bytes...].
+ *
+ * This routine adds a new field to an existing device's descriptor.  It only
+ * works for the last device, but that's OK because that's how we use it. */
+static void add_desc_field(struct device *dev, u8 type, u8 len, const void *c)
+{
+       /* This is the last descriptor, right? */
+       assert(devices.descpage + devices.desc_used
+              == (u8 *)(dev->desc + 1) + dev->desc->config_len);
+
+       /* We only have one page of device descriptions. */
+       if (devices.desc_used + 2 + len > getpagesize())
+               errx(1, "Too many devices");
+
+       /* Copy in the new config header: type then length. */
+       devices.descpage[devices.desc_used++] = type;
+       devices.descpage[devices.desc_used++] = len;
+       memcpy(devices.descpage + devices.desc_used, c, len);
+       devices.desc_used += len;
+
+       /* Update the device descriptor length: two byte head then data. */
+       dev->desc->config_len += 2 + len;
+}
+
+/* This routine adds a virtqueue to a device.  We specify how many descriptors
+ * the virtqueue is to have. */
+static void add_virtqueue(struct device *dev, unsigned int num_descs,
+                         void (*handle_output)(int fd, struct virtqueue *me))
+{
+       unsigned int pages;
+       struct virtqueue **i, *vq = malloc(sizeof(*vq));
+       void *p;
+
+       /* First we need some pages for this virtqueue. */
+       pages = (vring_size(num_descs) + getpagesize() - 1) / getpagesize();
+       p = get_pages(pages);
+
+       /* Initialize the configuration. */
+       vq->config.num = num_descs;
+       vq->config.irq = devices.next_irq++;
+       vq->config.pfn = to_guest_phys(p) / getpagesize();
+
+       /* Initialize the vring. */
+       vring_init(&vq->vring, num_descs, p);
+
+       /* Add the configuration information to this device's descriptor. */
+       add_desc_field(dev, VIRTIO_CONFIG_F_VIRTQUEUE,
+                      sizeof(vq->config), &vq->config);
+
+       /* Add to tail of list, so dev->vq is first vq, dev->vq->next is
+        * second.  */
+       for (i = &dev->vq; *i; i = &(*i)->next);
+       *i = vq;
+
+       /* Link virtqueue back to device. */
+       vq->dev = dev;
+
+       /* Set up handler. */
+       vq->handle_output = handle_output;
+       if (!handle_output)
+               vq->vring.used->flags = VRING_USED_F_NO_NOTIFY;
+}
+
+/* This routine does all the creation and setup of a new device, including
+ * caling new_dev_desc() to allocate the descriptor and device memory. */
+static struct device *new_device(const char *name, u16 type, int fd,
+                                bool (*handle_input)(int, struct device *))
 {
        struct device *dev = malloc(sizeof(*dev));
 
@@ -1026,27 +1061,25 @@ static struct device *new_device(struct device_list *devices,
         * easier, but the user expects the devices to be arranged on the bus
         * in command-line order.  The first network device on the command line
         * is eth0, the first block device /dev/lgba, etc. */
-       *devices->lastdev = dev;
+       *devices.lastdev = dev;
        dev->next = NULL;
-       devices->lastdev = &dev->next;
+       devices.lastdev = &dev->next;
 
        /* Now we populate the fields one at a time. */
        dev->fd = fd;
        /* If we have an input handler for this file descriptor, then we add it
         * to the device_list's fdset and maxfd. */
        if (handle_input)
-               set_fd(dev->fd, devices);
-       dev->desc = new_dev_desc(devices->descs, type, features, num_pages);
-       dev->mem = (void *)(dev->desc->pfn * getpagesize());
+               add_device_fd(dev->fd);
+       dev->desc = new_dev_desc(type);
        dev->handle_input = handle_input;
-       dev->watch_key = (unsigned long)dev->mem + watch_off;
-       dev->handle_output = handle_output;
+       dev->name = name;
        return dev;
 }
 
 /* Our first setup routine is the console.  It's a fairly simple device, but
  * UNIX tty handling makes it uglier than it could be. */
-static void setup_console(struct device_list *devices)
+static void setup_console(void)
 {
        struct device *dev;
 
@@ -1062,127 +1095,38 @@ static void setup_console(struct device_list *devices)
                atexit(restore_term);
        }
 
-       /* We don't currently require any memory for the console, so we ask for
-        * 0 pages. */
-       dev = new_device(devices, LGUEST_DEVICE_T_CONSOLE, 0, 0,
-                        STDIN_FILENO, handle_console_input,
-                        LGUEST_CONSOLE_DMA_KEY, handle_console_output);
+       dev = new_device("console", VIRTIO_ID_CONSOLE,
+                        STDIN_FILENO, handle_console_input);
        /* We store the console state in dev->priv, and initialize it. */
        dev->priv = malloc(sizeof(struct console_abort));
        ((struct console_abort *)dev->priv)->count = 0;
-       verbose("device %p: console\n",
-               (void *)(dev->desc->pfn * getpagesize()));
-}
 
-/* Setting up a block file is also fairly straightforward. */
-static void setup_block_file(const char *filename, struct device_list *devices)
-{
-       int fd;
-       struct device *dev;
-       off64_t *device_len;
-       struct lguest_block_page *p;
-
-       /* We open with O_LARGEFILE because otherwise we get stuck at 2G.  We
-        * open with O_DIRECT because otherwise our benchmarks go much too
-        * fast. */
-       fd = open_or_die(filename, O_RDWR|O_LARGEFILE|O_DIRECT);
-
-       /* We want one page, and have no input handler (the block file never
-        * has anything interesting to say to us).  Our timing will be quite
-        * random, so it should be a reasonable randomness source. */
-       dev = new_device(devices, LGUEST_DEVICE_T_BLOCK, 1,
-                        LGUEST_DEVICE_F_RANDOMNESS,
-                        fd, NULL, 0, handle_block_output);
-
-       /* We store the device size in the private area */
-       device_len = dev->priv = malloc(sizeof(*device_len));
-       /* This is the safe way of establishing the size of our device: it
-        * might be a normal file or an actual block device like /dev/hdb. */
-       *device_len = lseek64(fd, 0, SEEK_END);
-
-       /* The device memory is a "struct lguest_block_page".  It's zeroed
-        * already, we just need to put in the device size.  Block devices
-        * think in sectors (ie. 512 byte chunks), so we translate here. */
-       p = dev->mem;
-       p->num_sectors = *device_len/512;
-       verbose("device %p: block %i sectors\n",
-               (void *)(dev->desc->pfn * getpagesize()), p->num_sectors);
+       /* The console needs two virtqueues: the input then the output.  When
+        * they put something the input queue, we make sure we're listening to
+        * stdin.  When they put something in the output queue, we write it to
+        * stdout.  */
+       add_virtqueue(dev, VIRTQUEUE_NUM, enable_fd);
+       add_virtqueue(dev, VIRTQUEUE_NUM, handle_console_output);
+
+       verbose("device %u: console\n", devices.device_num++);
 }
+/*:*/
 
-/*
- * Network Devices.
+/*M:010 Inter-guest networking is an interesting area.  Simplest is to have a
+ * --sharenet=<name> option which opens or creates a named pipe.  This can be
+ * used to send packets to another guest in a 1:1 manner.
  *
- * Setting up network devices is quite a pain, because we have three types.
- * First, we have the inter-Guest network.  This is a file which is mapped into
- * the address space of the Guests who are on the network.  Because it is a
- * shared mapping, the same page underlies all the devices, and they can send
- * DMA to each other.
+ * More sopisticated is to use one of the tools developed for project like UML
+ * to do networking.
  *
- * Remember from our network driver, the Guest is told what slot in the page it
- * is to use.  We use exclusive fnctl locks to reserve a slot.  If another
- * Guest is using a slot, the lock will fail and we try another.  Because fnctl
- * locks are cleaned up automatically when we die, this cleverly means that our
- * reservation on the slot will vanish if we crash. */
-static unsigned int find_slot(int netfd, const char *filename)
-{
-       struct flock fl;
-
-       fl.l_type = F_WRLCK;
-       fl.l_whence = SEEK_SET;
-       fl.l_len = 1;
-       /* Try a 1 byte lock in each possible position number */
-       for (fl.l_start = 0;
-            fl.l_start < getpagesize()/sizeof(struct lguest_net);
-            fl.l_start++) {
-               /* If we succeed, return the slot number. */
-               if (fcntl(netfd, F_SETLK, &fl) == 0)
-                       return fl.l_start;
-       }
-       errx(1, "No free slots in network file %s", filename);
-}
-
-/* This function sets up the network file */
-static void setup_net_file(const char *filename,
-                          struct device_list *devices)
-{
-       int netfd;
-       struct device *dev;
-
-       /* We don't use open_or_die() here: for friendliness we create the file
-        * if it doesn't already exist. */
-       netfd = open(filename, O_RDWR, 0);
-       if (netfd < 0) {
-               if (errno == ENOENT) {
-                       netfd = open(filename, O_RDWR|O_CREAT, 0600);
-                       if (netfd >= 0) {
-                               /* If we succeeded, initialize the file with a
-                                * blank page. */
-                               char page[getpagesize()];
-                               memset(page, 0, sizeof(page));
-                               write(netfd, page, sizeof(page));
-                       }
-               }
-               if (netfd < 0)
-                       err(1, "cannot open net file '%s'", filename);
-       }
-
-       /* We need 1 page, and the features indicate the slot to use and that
-        * no checksum is needed.  We never touch this device again; it's
-        * between the Guests on the network, so we don't register input or
-        * output handlers. */
-       dev = new_device(devices, LGUEST_DEVICE_T_NET, 1,
-                        find_slot(netfd, filename)|LGUEST_NET_F_NOCSUM,
-                        -1, NULL, 0, NULL);
-
-       /* Map the shared file. */
-       if (mmap(dev->mem, getpagesize(), PROT_READ|PROT_WRITE,
-                        MAP_FIXED|MAP_SHARED, netfd, 0) != dev->mem)
-                       err(1, "could not mmap '%s'", filename);
-       verbose("device %p: shared net %s, peer %i\n",
-               (void *)(dev->desc->pfn * getpagesize()), filename,
-               dev->desc->features & ~LGUEST_NET_F_NOCSUM);
-}
-/*:*/
+ * Faster is to do virtio bonding in kernel.  Doing this 1:1 would be
+ * completely generic ("here's my vring, attach to your vring") and would work
+ * for any traffic.  Of course, namespace and permissions issues need to be
+ * dealt with.  A more sophisticated "multi-channel" virtio_net.c could hide
+ * multiple inter-guest channels behind one interface, although it would
+ * require some manner of hotplugging new virtio channels.
+ *
+ * Finally, we could implement a virtio network switch in the kernel. :*/
 
 static u32 str2ip(const char *ipaddr)
 {
@@ -1217,7 +1161,7 @@ static void add_to_bridge(int fd, const char *if_name, const char *br_name)
 
 /* This sets up the Host end of the network device with an IP address, brings
  * it up so packets will flow, the copies the MAC address into the hwaddr
- * pointer (in practice, the Host's slot in the network device's memory). */
+ * pointer. */
 static void configure_device(int fd, const char *devname, u32 ipaddr,
                             unsigned char hwaddr[6])
 {
@@ -1243,18 +1187,18 @@ static void configure_device(int fd, const char *devname, u32 ipaddr,
        memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, 6);
 }
 
-/*L:195 The other kind of network is a Host<->Guest network.  This can either
- * use briding or routing, but the principle is the same: it uses the "tun"
- * device to inject packets into the Host as if they came in from a normal
- * network card.  We just shunt packets between the Guest and the tun
- * device. */
-static void setup_tun_net(const char *arg, struct device_list *devices)
+/*L:195 Our network is a Host<->Guest network.  This can either use bridging or
+ * routing, but the principle is the same: it uses the "tun" device to inject
+ * packets into the Host as if they came in from a normal network card.  We
+ * just shunt packets between the Guest and the tun device. */
+static void setup_tun_net(const char *arg)
 {
        struct device *dev;
        struct ifreq ifr;
        int netfd, ipfd;
        u32 ip;
        const char *br_name = NULL;
+       u8 hwaddr[6];
 
        /* We open the /dev/net/tun device and tell it we want a tap device.  A
         * tap device is like a tun device, only somehow different.  To tell
@@ -1270,21 +1214,13 @@ static void setup_tun_net(const char *arg, struct device_list *devices)
         * device: trust us! */
        ioctl(netfd, TUNSETNOCSUM, 1);
 
-       /* We create the net device with 1 page, using the features field of
-        * the descriptor to tell the Guest it is in slot 1 (NET_PEERNUM), and
-        * that the device has fairly random timing.  We do *not* specify
-        * LGUEST_NET_F_NOCSUM: these packets can reach the real world.
-        *
-        * We will put our MAC address is slot 0 for the Guest to see, so
-        * it will send packets to us using the key "peer_offset(0)": */
-       dev = new_device(devices, LGUEST_DEVICE_T_NET, 1,
-                        NET_PEERNUM|LGUEST_DEVICE_F_RANDOMNESS, netfd,
-                        handle_tun_input, peer_offset(0), handle_tun_output);
+       /* First we create a new network device. */
+       dev = new_device("net", VIRTIO_ID_NET, netfd, handle_tun_input);
 
-       /* We keep a flag which says whether we've seen packets come out from
-        * this network device. */
-       dev->priv = malloc(sizeof(bool));
-       *(bool *)dev->priv = false;
+       /* Network devices need a receive and a send queue, just like
+        * console. */
+       add_virtqueue(dev, VIRTQUEUE_NUM, enable_fd);
+       add_virtqueue(dev, VIRTQUEUE_NUM, handle_net_output);
 
        /* We need a socket to perform the magic network ioctls to bring up the
         * tap interface, connect to the bridge etc.  Any socket will do! */
@@ -1300,44 +1236,251 @@ static void setup_tun_net(const char *arg, struct device_list *devices)
        } else /* It is an IP address to set up the device with */
                ip = str2ip(arg);
 
-       /* We are peer 0, ie. first slot, so we hand dev->mem to this routine
-        * to write the MAC address at the start of the device memory.  */
-       configure_device(ipfd, ifr.ifr_name, ip, dev->mem);
+       /* Set up the tun device, and get the mac address for the interface. */
+       configure_device(ipfd, ifr.ifr_name, ip, hwaddr);
 
-       /* Set "promisc" bit: we want every single packet if we're going to
-        * bridge to other machines (and otherwise it doesn't matter). */
-       *((u8 *)dev->mem) |= 0x1;
+       /* Tell Guest what MAC address to use. */
+       add_desc_field(dev, VIRTIO_CONFIG_NET_MAC_F, sizeof(hwaddr), hwaddr);
 
+       /* We don't seed the socket any more; setup is done. */
        close(ipfd);
 
-       verbose("device %p: tun net %u.%u.%u.%u\n",
-               (void *)(dev->desc->pfn * getpagesize()),
-               (u8)(ip>>24), (u8)(ip>>16), (u8)(ip>>8), (u8)ip);
+       verbose("device %u: tun net %u.%u.%u.%u\n",
+               devices.device_num++,
+               (u8)(ip>>24),(u8)(ip>>16),(u8)(ip>>8),(u8)ip);
        if (br_name)
                verbose("attached to bridge: %s\n", br_name);
 }
+
+
+/*
+ * Block device.
+ *
+ * Serving a block device is really easy: the Guest asks for a block number and
+ * we read or write that position in the file.
+ *
+ * Unfortunately, this is amazingly slow: the Guest waits until the read is
+ * finished before running anything else, even if it could be doing useful
+ * work.  We could use async I/O, except it's reputed to suck so hard that
+ * characters actually go missing from your code when you try to use it.
+ *
+ * So we farm the I/O out to thread, and communicate with it via a pipe. */
+
+/* This hangs off device->priv, with the data. */
+struct vblk_info
+{
+       /* The size of the file. */
+       off64_t len;
+
+       /* The file descriptor for the file. */
+       int fd;
+
+       /* IO thread listens on this file descriptor [0]. */
+       int workpipe[2];
+
+       /* IO thread writes to this file descriptor to mark it done, then
+        * Launcher triggers interrupt to Guest. */
+       int done_fd;
+};
+
+/* This is the core of the I/O thread.  It returns true if it did something. */
+static bool service_io(struct device *dev)
+{
+       struct vblk_info *vblk = dev->priv;
+       unsigned int head, out_num, in_num, wlen;
+       int ret;
+       struct virtio_blk_inhdr *in;
+       struct virtio_blk_outhdr *out;
+       struct iovec iov[dev->vq->vring.num];
+       off64_t off;
+
+       head = get_vq_desc(dev->vq, iov, &out_num, &in_num);
+       if (head == dev->vq->vring.num)
+               return false;
+
+       if (out_num == 0 || in_num == 0)
+               errx(1, "Bad virtblk cmd %u out=%u in=%u",
+                    head, out_num, in_num);
+
+       out = convert(&iov[0], struct virtio_blk_outhdr);
+       in = convert(&iov[out_num+in_num-1], struct virtio_blk_inhdr);
+       off = out->sector * 512;
+
+       /* This is how we implement barriers.  Pretty poor, no? */
+       if (out->type & VIRTIO_BLK_T_BARRIER)
+               fdatasync(vblk->fd);
+
+       if (out->type & VIRTIO_BLK_T_SCSI_CMD) {
+               fprintf(stderr, "Scsi commands unsupported\n");
+               in->status = VIRTIO_BLK_S_UNSUPP;
+               wlen = sizeof(in);
+       } else if (out->type & VIRTIO_BLK_T_OUT) {
+               /* Write */
+
+               /* Move to the right location in the block file.  This can fail
+                * if they try to write past end. */
+               if (lseek64(vblk->fd, off, SEEK_SET) != off)
+                       err(1, "Bad seek to sector %llu", out->sector);
+
+               ret = writev(vblk->fd, iov+1, out_num-1);
+               verbose("WRITE to sector %llu: %i\n", out->sector, ret);
+
+               /* Grr... Now we know how long the descriptor they sent was, we
+                * make sure they didn't try to write over the end of the block
+                * file (possibly extending it). */
+               if (ret > 0 && off + ret > vblk->len) {
+                       /* Trim it back to the correct length */
+                       ftruncate64(vblk->fd, vblk->len);
+                       /* Die, bad Guest, die. */
+                       errx(1, "Write past end %llu+%u", off, ret);
+               }
+               wlen = sizeof(in);
+               in->status = (ret >= 0 ? VIRTIO_BLK_S_OK : VIRTIO_BLK_S_IOERR);
+       } else {
+               /* Read */
+
+               /* Move to the right location in the block file.  This can fail
+                * if they try to read past end. */
+               if (lseek64(vblk->fd, off, SEEK_SET) != off)
+                       err(1, "Bad seek to sector %llu", out->sector);
+
+               ret = readv(vblk->fd, iov+1, in_num-1);
+               verbose("READ from sector %llu: %i\n", out->sector, ret);
+               if (ret >= 0) {
+                       wlen = sizeof(in) + ret;
+                       in->status = VIRTIO_BLK_S_OK;
+               } else {
+                       wlen = sizeof(in);
+                       in->status = VIRTIO_BLK_S_IOERR;
+               }
+       }
+
+       /* We can't trigger an IRQ, because we're not the Launcher.  It does
+        * that when we tell it we're done. */
+       add_used(dev->vq, head, wlen);
+       return true;
+}
+
+/* This is the thread which actually services the I/O. */
+static int io_thread(void *_dev)
+{
+       struct device *dev = _dev;
+       struct vblk_info *vblk = dev->priv;
+       char c;
+
+       /* Close other side of workpipe so we get 0 read when main dies. */
+       close(vblk->workpipe[1]);
+       /* Close the other side of the done_fd pipe. */
+       close(dev->fd);
+
+       /* When this read fails, it means Launcher died, so we follow. */
+       while (read(vblk->workpipe[0], &c, 1) == 1) {
+               /* We acknowledge each request immediately, to reduce latency,
+                * rather than waiting until we've done them all.  I haven't
+                * measured to see if it makes any difference. */
+               while (service_io(dev))
+                       write(vblk->done_fd, &c, 1);
+       }
+       return 0;
+}
+
+/* When the thread says some I/O is done, we interrupt the Guest. */
+static bool handle_io_finish(int fd, struct device *dev)
+{
+       char c;
+
+       /* If child died, presumably it printed message. */
+       if (read(dev->fd, &c, 1) != 1)
+               exit(1);
+
+       /* It did some work, so trigger the irq. */
+       trigger_irq(fd, dev->vq);
+       return true;
+}
+
+/* When the Guest submits some I/O, we wake the I/O thread. */
+static void handle_virtblk_output(int fd, struct virtqueue *vq)
+{
+       struct vblk_info *vblk = vq->dev->priv;
+       char c = 0;
+
+       /* Wake up I/O thread and tell it to go to work! */
+       if (write(vblk->workpipe[1], &c, 1) != 1)
+               /* Presumably it indicated why it died. */
+               exit(1);
+}
+
+/* This creates a virtual block device. */
+static void setup_block_file(const char *filename)
+{
+       int p[2];
+       struct device *dev;
+       struct vblk_info *vblk;
+       void *stack;
+       u64 cap;
+       unsigned int val;
+
+       /* This is the pipe the I/O thread will use to tell us I/O is done. */
+       pipe(p);
+
+       /* The device responds to return from I/O thread. */
+       dev = new_device("block", VIRTIO_ID_BLOCK, p[0], handle_io_finish);
+
+       /* The device has a virtqueue. */
+       add_virtqueue(dev, VIRTQUEUE_NUM, handle_virtblk_output);
+
+       /* Allocate the room for our own bookkeeping */
+       vblk = dev->priv = malloc(sizeof(*vblk));
+
+       /* First we open the file and store the length. */
+       vblk->fd = open_or_die(filename, O_RDWR|O_LARGEFILE);
+       vblk->len = lseek64(vblk->fd, 0, SEEK_END);
+
+       /* Tell Guest how many sectors this device has. */
+       cap = cpu_to_le64(vblk->len / 512);
+       add_desc_field(dev, VIRTIO_CONFIG_BLK_F_CAPACITY, sizeof(cap), &cap);
+
+       /* Tell Guest not to put in too many descriptors at once: two are used
+        * for the in and out elements. */
+       val = cpu_to_le32(VIRTQUEUE_NUM - 2);
+       add_desc_field(dev, VIRTIO_CONFIG_BLK_F_SEG_MAX, sizeof(val), &val);
+
+       /* The I/O thread writes to this end of the pipe when done. */
+       vblk->done_fd = p[1];
+
+       /* This is how we tell the I/O thread about more work. */
+       pipe(vblk->workpipe);
+
+       /* Create stack for thread and run it */
+       stack = malloc(32768);
+       if (clone(io_thread, stack + 32768, CLONE_VM, dev) == -1)
+               err(1, "Creating clone");
+
+       /* We don't need to keep the I/O thread's end of the pipes open. */
+       close(vblk->done_fd);
+       close(vblk->workpipe[0]);
+
+       verbose("device %u: virtblock %llu sectors\n",
+               devices.device_num, cap);
+}
 /* That's the end of device setup. */
 
 /*L:220 Finally we reach the core of the Launcher, which runs the Guest, serves
  * its input and output, and finally, lays it to rest. */
-static void __attribute__((noreturn))
-run_guest(int lguest_fd, struct device_list *device_list)
+static void __attribute__((noreturn)) run_guest(int lguest_fd)
 {
        for (;;) {
-               u32 args[] = { LHREQ_BREAK, 0 };
-               unsigned long arr[2];
+               unsigned long args[] = { LHREQ_BREAK, 0 };
+               unsigned long notify_addr;
                int readval;
 
                /* We read from the /dev/lguest device to run the Guest. */
-               readval = read(lguest_fd, arr, sizeof(arr));
-
-               /* The read can only really return sizeof(arr) (the Guest did a
-                * SEND_DMA to us), or an error. */
+               readval = read(lguest_fd, &notify_addr, sizeof(notify_addr));
 
-               /* For a successful read, arr[0] is the address of the "struct
-                * lguest_dma", and arr[1] is the key the Guest sent to. */
-               if (readval == sizeof(arr)) {
-                       handle_output(lguest_fd, arr[0], arr[1], device_list);
+               /* One unsigned long means the Guest did HCALL_NOTIFY */
+               if (readval == sizeof(notify_addr)) {
+                       verbose("Notify on address %#lx\n", notify_addr);
+                       handle_output(lguest_fd, notify_addr);
                        continue;
                /* ENOENT means the Guest died.  Reading tells us why. */
                } else if (errno == ENOENT) {
@@ -1351,7 +1494,7 @@ run_guest(int lguest_fd, struct device_list *device_list)
 
                /* Service input, then unset the BREAK which releases
                 * the Waker. */
-               handle_input(lguest_fd, device_list);
+               handle_input(lguest_fd);
                if (write(lguest_fd, args, sizeof(args)) < 0)
                        err(1, "Resetting break");
        }
@@ -1365,7 +1508,6 @@ run_guest(int lguest_fd, struct device_list *device_list)
 
 static struct option opts[] = {
        { "verbose", 0, NULL, 'v' },
-       { "sharenet", 1, NULL, 's' },
        { "tunnet", 1, NULL, 't' },
        { "block", 1, NULL, 'b' },
        { "initrd", 1, NULL, 'i' },
@@ -1374,37 +1516,21 @@ static struct option opts[] = {
 static void usage(void)
 {
        errx(1, "Usage: lguest [--verbose] "
-            "[--sharenet=<filename>|--tunnet=(<ipaddr>|bridge:<bridgename>)\n"
+            "[--tunnet=(<ipaddr>|bridge:<bridgename>)\n"
             "|--block=<filename>|--initrd=<filename>]...\n"
             "<mem-in-mb> vmlinux [args...]");
 }
 
-/*L:100 The Launcher code itself takes us out into userspace, that scary place
- * where pointers run wild and free!  Unfortunately, like most userspace
- * programs, it's quite boring (which is why everyone like to hack on the
- * kernel!).  Perhaps if you make up an Lguest Drinking Game at this point, it
- * will get you through this section.  Or, maybe not.
- *
- * The Launcher binary sits up high, usually starting at address 0xB8000000.
- * Everything below this is the "physical" memory for the Guest.  For example,
- * if the Guest were to write a "1" at physical address 0, we would see a "1"
- * in the Launcher at "(int *)0".  Guest physical == Launcher virtual.
- *
- * This can be tough to get your head around, but usually it just means that we
- * don't need to do any conversion when the Guest gives us it's "physical"
- * addresses.
- */
+/*L:105 The main routine is where the real work begins: */
 int main(int argc, char *argv[])
 {
-       /* Memory, top-level pagetable, code startpoint, PAGE_OFFSET and size
-        * of the (optional) initrd. */
-       unsigned long mem = 0, pgdir, start, page_offset, initrd_size = 0;
+       /* Memory, top-level pagetable, code startpoint and size of the
+        * (optional) initrd. */
+       unsigned long mem = 0, pgdir, start, initrd_size = 0;
        /* A temporary and the /dev/lguest file descriptor. */
        int i, c, lguest_fd;
-       /* The list of Guest devices, based on command line arguments. */
-       struct device_list device_list;
-       /* The boot information for the Guest: at guest-physical address 0. */
-       void *boot = (void *)0;
+       /* The boot information for the Guest. */
+       struct boot_params *boot;
        /* If they specify an initrd file to load. */
        const char *initrd_name = NULL;
 
@@ -1412,11 +1538,12 @@ int main(int argc, char *argv[])
         * device receive input from a file descriptor, we keep an fdset
         * (infds) and the maximum fd number (max_infd) with the head of the
         * list.  We also keep a pointer to the last device, for easy appending
-        * to the list. */
-       device_list.max_infd = -1;
-       device_list.dev = NULL;
-       device_list.lastdev = &device_list.dev;
-       FD_ZERO(&device_list.infds);
+        * to the list.  Finally, we keep the next interrupt number to hand out
+        * (1: remember that 0 is used by the timer). */
+       FD_ZERO(&devices.infds);
+       devices.max_infd = -1;
+       devices.lastdev = &devices.dev;
+       devices.next_irq = 1;
 
        /* We need to know how much memory so we can set up the device
         * descriptor and memory pages for the devices as we parse the command
@@ -1424,9 +1551,16 @@ int main(int argc, char *argv[])
         * of memory now. */
        for (i = 1; i < argc; i++) {
                if (argv[i][0] != '-') {
-                       mem = top = atoi(argv[i]) * 1024 * 1024;
-                       device_list.descs = map_zeroed_pages(top, 1);
-                       top += getpagesize();
+                       mem = atoi(argv[i]) * 1024 * 1024;
+                       /* We start by mapping anonymous pages over all of
+                        * guest-physical memory range.  This fills it with 0,
+                        * and ensures that the Guest won't be killed when it
+                        * tries to access it. */
+                       guest_base = map_zeroed_pages(mem / getpagesize()
+                                                     + DEVICE_PAGES);
+                       guest_limit = mem;
+                       guest_max = mem + DEVICE_PAGES*getpagesize();
+                       devices.descpage = get_pages(1);
                        break;
                }
        }
@@ -1437,14 +1571,11 @@ int main(int argc, char *argv[])
                case 'v':
                        verbose = true;
                        break;
-               case 's':
-                       setup_net_file(optarg, &device_list);
-                       break;
                case 't':
-                       setup_tun_net(optarg, &device_list);
+                       setup_tun_net(optarg);
                        break;
                case 'b':
-                       setup_block_file(optarg, &device_list);
+                       setup_block_file(optarg);
                        break;
                case 'i':
                        initrd_name = optarg;
@@ -1459,56 +1590,60 @@ int main(int argc, char *argv[])
        if (optind + 2 > argc)
                usage();
 
-       /* We always have a console device */
-       setup_console(&device_list);
+       verbose("Guest base is at %p\n", guest_base);
 
-       /* We start by mapping anonymous pages over all of guest-physical
-        * memory range.  This fills it with 0, and ensures that the Guest
-        * won't be killed when it tries to access it. */
-       map_zeroed_pages(0, mem / getpagesize());
+       /* We always have a console device */
+       setup_console();
 
        /* Now we load the kernel */
-       start = load_kernel(open_or_die(argv[optind+1], O_RDONLY),
-                           &page_offset);
+       start = load_kernel(open_or_die(argv[optind+1], O_RDONLY));
+
+       /* Boot information is stashed at physical address 0 */
+       boot = from_guest_phys(0);
 
        /* Map the initrd image if requested (at top of physical memory) */
        if (initrd_name) {
                initrd_size = load_initrd(initrd_name, mem);
                /* These are the location in the Linux boot header where the
                 * start and size of the initrd are expected to be found. */
-               *(unsigned long *)(boot+0x218) = mem - initrd_size;
-               *(unsigned long *)(boot+0x21c) = initrd_size;
+               boot->hdr.ramdisk_image = mem - initrd_size;
+               boot->hdr.ramdisk_size = initrd_size;
                /* The bootloader type 0xFF means "unknown"; that's OK. */
-               *(unsigned char *)(boot+0x210) = 0xFF;
+               boot->hdr.type_of_loader = 0xFF;
        }
 
        /* Set up the initial linear pagetables, starting below the initrd. */
-       pgdir = setup_pagetables(mem, initrd_size, page_offset);
+       pgdir = setup_pagetables(mem, initrd_size);
 
        /* The Linux boot header contains an "E820" memory map: ours is a
         * simple, single region. */
-       *(char*)(boot+E820NR) = 1;
-       *((struct e820entry *)(boot+E820MAP))
-               = ((struct e820entry) { 0, mem, E820_RAM });
+       boot->e820_entries = 1;
+       boot->e820_map[0] = ((struct e820entry) { 0, mem, E820_RAM });
        /* The boot header contains a command line pointer: we put the command
-        * line after the boot header (at address 4096) */
-       *(void **)(boot + 0x228) = boot + 4096;
-       concat(boot + 4096, argv+optind+2);
+        * line after the boot header. */
+       boot->hdr.cmd_line_ptr = to_guest_phys(boot + 1);
+       concat((char *)(boot + 1), argv+optind+2);
+
+       /* Boot protocol version: 2.07 supports the fields for lguest. */
+       boot->hdr.version = 0x207;
+
+       /* The hardware_subarch value of "1" tells the Guest it's an lguest. */
+       boot->hdr.hardware_subarch = 1;
 
-       /* The guest type value of "1" tells the Guest it's under lguest. */
-       *(int *)(boot + 0x23c) = 1;
+       /* Tell the entry path not to try to reload segment registers. */
+       boot->hdr.loadflags |= KEEP_SEGMENTS;
 
        /* We tell the kernel to initialize the Guest: this returns the open
         * /dev/lguest file descriptor. */
-       lguest_fd = tell_kernel(pgdir, start, page_offset);
+       lguest_fd = tell_kernel(pgdir, start);
 
        /* We fork off a child process, which wakes the Launcher whenever one
         * of the input file descriptors needs attention.  Otherwise we would
         * run the Guest until it tries to output something. */
-       waker_fd = setup_waker(lguest_fd, &device_list);
+       waker_fd = setup_waker(lguest_fd);
 
        /* Finally, run the Guest.  This doesn't return. */
-       run_guest(lguest_fd, &device_list);
+       run_guest(lguest_fd);
 }
 /*:*/
 
index 821617bd6c048351fcd84e7ad125fe95fbd539e4..7885ab2d5f53710d54676c1e8df6be8f224c36ca 100644 (file)
@@ -6,7 +6,7 @@ Lguest is designed to be a minimal hypervisor for the Linux kernel, for
 Linux developers and users to experiment with virtualization with the
 minimum of complexity.  Nonetheless, it should have sufficient
 features to make it useful for specific tasks, and, of course, you are
-encouraged to fork and enhance it.
+encouraged to fork and enhance it (see drivers/lguest/README).
 
 Features:
 
@@ -23,19 +23,30 @@ Developer features:
 
 Running Lguest:
 
-- Lguest runs the same kernel as guest and host.  You can configure
-  them differently, but usually it's easiest not to.
+- The easiest way to run lguest is to use same kernel as guest and host.
+  You can configure them differently, but usually it's easiest not to.
 
   You will need to configure your kernel with the following options:
 
-  CONFIG_HIGHMEM64G=n ("High Memory Support" "64GB")[1]
-  CONFIG_TUN=y/m ("Universal TUN/TAP device driver support")
-  CONFIG_EXPERIMENTAL=y ("Prompt for development and/or incomplete code/drivers")
-  CONFIG_PARAVIRT=y ("Paravirtualization support (EXPERIMENTAL)")
-  CONFIG_LGUEST=y/m ("Linux hypervisor example code")
-
-  and I recommend:
-  CONFIG_HZ=100 ("Timer frequency")[2]
+  "General setup":
+     "Prompt for development and/or incomplete code/drivers" = Y
+        (CONFIG_EXPERIMENTAL=y)
+
+  "Processor type and features":
+     "Paravirtualized guest support" = Y
+        "Lguest guest support" = Y
+     "High Memory Support" = off/4GB
+     "Alignment value to which kernel should be aligned" = 0x100000
+        (CONFIG_PARAVIRT=y, CONFIG_LGUEST_GUEST=y, CONFIG_HIGHMEM64G=n and
+         CONFIG_PHYSICAL_ALIGN=0x100000)
+
+  "Device Drivers":
+     "Network device support"
+        "Universal TUN/TAP device driver support" = M/Y
+           (CONFIG_TUN=m)
+     "Virtualization"
+        "Linux hypervisor example code" = M/Y
+           (CONFIG_LGUEST=m)
 
 - A tool called "lguest" is available in this directory: type "make"
   to build it.  If you didn't build your kernel in-tree, use "make
@@ -51,14 +62,17 @@ Running Lguest:
          dd if=/dev/zero of=rootfile bs=1M count=2048
          qemu -cdrom image.iso -hda rootfile -net user -net nic -boot d
 
+  Make sure that you install a getty on /dev/hvc0 if you want to log in on the
+  console!
+
 - "modprobe lg" if you built it as a module.
 
 - Run an lguest as root:
 
-      Documentation/lguest/lguest 64m vmlinux --tunnet=192.168.19.1 --block=rootfile root=/dev/lgba
+      Documentation/lguest/lguest 64 vmlinux --tunnet=192.168.19.1 --block=rootfile root=/dev/vda
 
    Explanation:
-    64m: the amount of memory to use.
+    64: the amount of memory to use, in MB.
 
     vmlinux: the kernel image found in the top of your build directory.  You
        can also use a standard bzImage.
@@ -66,10 +80,10 @@ Running Lguest:
     --tunnet=192.168.19.1: configures a "tap" device for networking with this
        IP address.
 
-    --block=rootfile: a file or block device which becomes /dev/lgba
+    --block=rootfile: a file or block device which becomes /dev/vda
        inside the guest.
 
-    root=/dev/lgba: this (and anything else on the command line) are
+    root=/dev/vda: this (and anything else on the command line) are
        kernel boot parameters.
 
 - Configuring networking.  I usually have the host masquerade, using
@@ -99,31 +113,7 @@ Running Lguest:
   "--sharenet=<filename>": any two guests using the same file are on
   the same network.  This file is created if it does not exist.
 
-Lguest I/O model:
-
-Lguest uses a simplified DMA model plus shared memory for I/O.  Guests
-can communicate with each other if they share underlying memory
-(usually by the lguest program mmaping the same file), but they can
-use any non-shared memory to communicate with the lguest process.
-
-Guests can register DMA buffers at any key (must be a valid physical
-address) using the LHCALL_BIND_DMA(key, dmabufs, num<<8|irq)
-hypercall.  "dmabufs" is the physical address of an array of "num"
-"struct lguest_dma": each contains a used_len, and an array of
-physical addresses and lengths.  When a transfer occurs, the
-"used_len" field of one of the buffers which has used_len 0 will be
-set to the length transferred and the irq will fire.
+There is a helpful mailing list at http://ozlabs.org/mailman/listinfo/lguest
 
-Using an irq value of 0 unbinds the dma buffers.
-
-To send DMA, the LHCALL_SEND_DMA(key, dma_physaddr) hypercall is used,
-and the bytes used is written to the used_len field.  This can be 0 if
-noone else has bound a DMA buffer to that key or some other error.
-DMA buffers bound by the same guest are ignored.
-
-Cheers!
+Good luck!
 Rusty Russell rusty@rustcorp.com.au.
-
-[1] These are on various places on the TODO list, waiting for you to
-    get annoyed enough at the limitation to fix it.
-[2] Lguest is not yet tickless when idle.  See [1].
index 8a523f6af48ab754ad1fc51dc9a65d726bde9c23..248589e8bcf5b8da6be48877bccb0c233eb00be5 100644 (file)
@@ -890,10 +890,7 @@ Syntax: nosync:0
 5.5.2) noasync
 --------------
 
-Syntax: noasync:0
-
-  Disables async and sync negotiation for all devices.  Any value
-  after the colon is acceptable (and has the same effect).
+[OBSOLETE, REMOVED]
 
 5.5.3) nodisconnect
 -------------------
diff --git a/Documentation/markers.txt b/Documentation/markers.txt
new file mode 100644 (file)
index 0000000..295a71b
--- /dev/null
@@ -0,0 +1,81 @@
+                    Using the Linux Kernel Markers
+
+                           Mathieu Desnoyers
+
+
+This document introduces Linux Kernel Markers and their use. It provides
+examples of how to insert markers in the kernel and connect probe functions to
+them and provides some examples of probe functions.
+
+
+* Purpose of markers
+
+A marker placed in code provides a hook to call a function (probe) that you can
+provide at runtime. A marker can be "on" (a probe is connected to it) or "off"
+(no probe is attached). When a marker 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
+marker is "on", the function you provide is called each time the marker is
+executed, in the execution context of the caller. When the function provided
+ends its execution, it returns to the caller (continuing from the marker site).
+
+You can put markers at important locations in the code. Markers are
+lightweight hooks that can pass an arbitrary number of parameters,
+described in a printk-like format string, to the attached probe function.
+
+They can be used for tracing and performance accounting.
+
+
+* Usage
+
+In order to use the macro trace_mark, you should include linux/marker.h.
+
+#include <linux/marker.h>
+
+And,
+
+trace_mark(subsystem_event, "%d %s", someint, somestring);
+Where :
+- subsystem_event is an identifier unique to your event
+    - subsystem is the name of your subsystem.
+    - event is the name of the event to mark.
+- "%d %s" is the formatted string for the serializer.
+- someint is an integer.
+- somestring is a char pointer.
+
+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.
+
+The marker mechanism supports inserting multiple instances of the same marker.
+Markers can be put in inline functions, inlined static functions, and
+unrolled loops as well as regular functions.
+
+The naming scheme "subsystem_event" is suggested here as a convention intended
+to limit collisions. Marker names are global to the kernel: they are considered
+as being the same whether they are in the core kernel image or in modules.
+Conflicting format strings for markers with the same name will cause the markers
+to be detected to have a different format string not to be armed and will output
+a printk warning which identifies the inconsistency:
+
+"Format mismatch for probe probe_name (format), marker (format)"
+
+
+* Probe / marker example
+
+See the example provided in samples/markers/src
+
+Compile them with your kernel.
+
+Run, as root :
+modprobe marker-example (insmod order is not important)
+modprobe probe-example
+cat /proc/marker-example (returns an expected error)
+rmmod marker-example probe-example
+dmesg
index 650657c5473340dcd8f5ffe5f097c6776a754441..4e17beba237902908b33d38b764c285fec433724 100644 (file)
@@ -1479,7 +1479,8 @@ kernel.
 
 Any atomic operation that modifies some state in memory and returns information
 about the state (old or new) implies an SMP-conditional general memory barrier
-(smp_mb()) on each side of the actual operation.  These include:
+(smp_mb()) on each side of the actual operation (with the exception of
+explicit lock operations, described later).  These include:
 
        xchg();
        cmpxchg();
@@ -1536,10 +1537,19 @@ If they're used for constructing a lock of some description, then they probably
 do need memory barriers as a lock primitive generally has to do things in a
 specific order.
 
-
 Basically, each usage case has to be carefully considered as to whether memory
 barriers are needed or not.
 
+The following operations are special locking primitives:
+
+       test_and_set_bit_lock();
+       clear_bit_unlock();
+       __clear_bit_unlock();
+
+These implement LOCK-class and UNLOCK-class operations. These should be used in
+preference to other operations when implementing locking primitives, because
+their implementations can be optimised on many architectures.
+
 [!] Note that special memory barrier primitives are available for these
 situations because on some CPUs the atomic instructions used imply full memory
 barriers, and so barrier instructions are superfluous in conjunction with them,
index 5fbcc22c98e944c1ec628bca656ec1eae73cec5e..168117bd6ee8b8d7eafbb72c626a2434556f4cc9 100644 (file)
@@ -2,7 +2,8 @@
 Memory Hotplug
 ==============
 
-Last Updated: Jul 28 2007
+Created:                                       Jul 28 2007
+Add description of notifier of memory hotplug  Oct 11 2007
 
 This document is about memory hotplug including how-to-use and current status.
 Because Memory Hotplug is still under development, contents of this text will
@@ -24,7 +25,8 @@ be changed often.
   6.1 Memory offline and ZONE_MOVABLE
   6.2. How to offline memory
 7. Physical memory remove
-8. Future Work List
+8. Memory hotplug event notifier
+9. Future Work List
 
 Note(1): x86_64's has special implementation for memory hotplug.
          This text does not describe it.
@@ -307,8 +309,58 @@ Need more implementation yet....
  - Notification completion of remove works by OS to firmware.
  - Guard from remove if not yet.
 
+--------------------------------
+8. Memory hotplug event notifier
+--------------------------------
+Memory hotplug has event notifer. There are 6 types of notification.
+
+MEMORY_GOING_ONLINE
+  Generated before new memory becomes available in order to be able to
+  prepare subsystems to handle memory. The page allocator is still unable
+  to allocate from the new memory.
+
+MEMORY_CANCEL_ONLINE
+  Generated if MEMORY_GOING_ONLINE fails.
+
+MEMORY_ONLINE
+  Generated when memory has succesfully brought online. The callback may
+  allocate pages from the new memory.
+
+MEMORY_GOING_OFFLINE
+  Generated to begin the process of offlining memory. Allocations are no
+  longer possible from the memory but some of the memory to be offlined
+  is still in use. The callback can be used to free memory known to a
+  subsystem from the indicated memory section.
+
+MEMORY_CANCEL_OFFLINE
+  Generated if MEMORY_GOING_OFFLINE fails. Memory is available again from
+  the section that we attempted to offline.
+
+MEMORY_OFFLINE
+  Generated after offlining memory is complete.
+
+A callback routine can be registered by
+  hotplug_memory_notifier(callback_func, priority)
+
+The second argument of callback function (action) is event types of above.
+The third argument is passed by pointer of struct memory_notify.
+
+struct memory_notify {
+       unsigned long start_pfn;
+       unsigned long nr_pages;
+       int status_cahnge_nid;
+}
+
+start_pfn is start_pfn of online/offline memory.
+nr_pages is # of pages of online/offline memory.
+status_change_nid is set node id when N_HIGH_MEMORY of nodemask is (will be)
+set/clear. It means a new(memoryless) node gets new memory by online and a
+node loses all memory. If this is -1, then nodemask status is not changed.
+If status_changed_nid >= 0, callback should create/discard structures for the
+node if necessary.
+
 --------------
-8. Future Work
+9. Future Work
 --------------
   - allowing memory hot-add to ZONE_MOVABLE. maybe we need some switch like
     sysctl or new control file.
index 9df8a2eac7b462ef2c682f3fcfba42483f1b8077..3f13bf8043d2a2f8a7626102c4b1375153a53ba5 100644 (file)
@@ -4,5 +4,3 @@ AU1xxx_IDE.README
        - README for MIPS AU1XXX IDE driver.
 GT64120.README
        - README for dir with info on MIPS boards using GT-64120 or GT-64120A.
-time.README
-       - README for MIPS time services.
index afb31c141d9d281a3a5b406cffb29220961d02cc..5c8334123f4f7b6f29d41c6129ecd511a7e03d10 100644 (file)
@@ -59,7 +59,7 @@ Four configs variables are introduced:
   CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA    - enable the PIO+DBDMA mode
   CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA  - enable the MWDMA mode
   CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON - set Burstable FIFO in DBDMA
-                                           controler
+                                           controller
   CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ - maximum transfer size
                                            per descriptor
 
diff --git a/Documentation/mips/time.README b/Documentation/mips/time.README
deleted file mode 100644 (file)
index a4ce603..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-README for MIPS time services
-
-Jun Sun
-jsun@mvista.com or jsun@junsun.net
-
-
-ABOUT
------
-This file describes the new arch/mips/kernel/time.c, related files and the 
-services they provide. 
-
-If you are short in patience and just want to know how to use time.c for a 
-new board or convert an existing board, go to the last section.
-
-
-FILES, COMPATABILITY AND CONFIGS
----------------------------------
-
-The old arch/mips/kernel/time.c is renamed to old-time.c.
-
-A new time.c is put there, together with include/asm-mips/time.h.
-
-Two configs variables are introduced, CONFIG_OLD_TIME_C and CONFIG_NEW_TIME_C.
-So we allow boards using 
-
-       1) old time.c (CONFIG_OLD_TIME_C)
-       2) new time.c (CONFIG_NEW_TIME_C)
-       3) neither (their own private time.c)
-
-However, it is expected every board will move to the new time.c in the near
-future.
-
-
-WHAT THE NEW CODE PROVIDES?
---------------------------- 
-
-The new time code provide the following services:
-
-  a) Implements functions required by Linux common code:
-       time_init
-
-  b) provides an abstraction of RTC and null RTC implementation as default.
-       extern unsigned long (*rtc_get_time)(void);
-       extern int (*rtc_set_time)(unsigned long);
-
-  c) high-level and low-level timer interrupt routines where the timer
-     interrupt source  may or may not be the CPU timer.  The high-level
-     routine is dispatched through do_IRQ() while the low-level is
-     dispatched in assemably code (usually int-handler.S)
-
-
-WHAT THE NEW CODE REQUIRES?
----------------------------
-
-For the new code to work properly, each board implementation needs to supply
-the following functions or values:
-
-  a) board_time_init - a function pointer.  Invoked at the beginnig of
-     time_init().  It is optional.
-       1. (optional) set up RTC routines
-       2. (optional) calibrate and set the mips_hpt_frequency
-
-  b) plat_timer_setup - a function pointer.  Invoked at the end of time_init()
-       1. (optional) over-ride any decisions made in time_init()
-       2. set up the irqaction for timer interrupt.
-       3. enable the timer interrupt
-
-  c) (optional) board-specific RTC routines.
-
-  d) (optional) mips_hpt_frequency - It must be definied if the board
-     is using CPU counter for timer interrupt.
-
-
-PORTING GUIDE
--------------
-
-Step 1: decide how you like to implement the time services.
-
-  a) does this board have a RTC?  If yes, implement the two RTC funcs.
-
-  b) does the CPU have counter/compare registers? 
-
-     If the answer is no, you need a timer to provide the timer interrupt
-     at 100 HZ speed.
-
-  c) The following sub steps assume your CPU has counter register.
-     Do you plan to use the CPU counter register as the timer interrupt
-     or use an exnternal timer?
-
-     In order to use CPU counter register as the timer interrupt source, you
-     must know the counter speed (mips_hpt_frequency).  It is usually the
-     same as the CPU speed or an integral divisor of it.
-
-  d) decide on whether you want to use high-level or low-level timer
-     interrupt routines.  The low-level one is presumably faster, but should
-     not make too mcuh difference.
-
-
-Step 2:  the machine setup() function
-
-  If you supply board_time_init(), set the function poointer.
-
-
-Step 3: implement rtc routines, board_time_init() and plat_timer_setup()
-  if needed.
-
-  board_time_init() -
-       a) (optional) set up RTC routines,
-        b) (optional) calibrate and set the mips_hpt_frequency
-           (only needed if you intended to use cpu counter as timer interrupt
-            source)
-
-  plat_timer_setup() -
-       a) (optional) over-write any choices made above by time_init().
-       b) machine specific code should setup the timer irqaction.
-       c) enable the timer interrupt
-
-
-  If the RTC chip is a common chip, I suggest the routines are put under
-  arch/mips/libs.  For example, for DS1386 chip, one would create
-  rtc-ds1386.c under arch/mips/lib directory.  Add the following line to
-  the arch/mips/lib/Makefile:
-
-       obj-$(CONFIG_DDB5476) += rtc-ds1386.o
-
-Step 4: if you are using low-level timer interrupt, change your interrupt
-  dispathcing code to check for timer interrupt and jump to 
-  ll_timer_interrupt() directly  if one is detected.
-
-Step 5: Modify arch/mips/config.in and add CONFIG_NEW_TIME_C to your machine.
-  Modify the appropriate defconfig if applicable.
-
-Final notes: 
-
-For some tricky cases, you may need to add your own wrapper functions 
-for some of the functions in time.c.  
-
-For example, you may define your own timer interrupt routine, which does
-some of its own processing and then calls timer_interrupt().
-
-You can also over-ride any of the built-in functions (RTC routines
-and/or timer interrupt routine).
-
-
-PORTING NOTES FOR SMP
-----------------------
-
-If you have a SMP box, things are slightly more complicated.
-
-The time service running every jiffy is logically divided into two parts:
-
-  1) the one for the whole system  (defined in timer_interrupt())
-  2) the one that should run for each CPU (defined in local_timer_interrupt())
-
-You need to decide on your timer interrupt sources.
-
-  case 1) - whole system has only one timer interrupt delivered to one CPU
-
-       In this case, you set up timer interrupt as in UP systems.  In addtion,
-       you need to set emulate_local_timer_interrupt to 1 so that other
-       CPUs get to call local_timer_interrupt().
-
-       THIS IS CURRENTLY NOT IMPLEMNETED.  However, it is rather easy to write
-       one should such a need arise.  You simply make a IPI call.
-
-  case 2) - each CPU has a separate timer interrupt
-
-       In this case, you need to set up IRQ such that each of them will
-       call local_timer_interrupt().  In addition, you need to arrange
-       one and only one of them to call timer_interrupt().
-
-       You can also do the low-level version of those interrupt routines,
-       following similar dispatching routes described above.
index 51f935191ae5d86fbf21fb801853eb20dff546a3..aa60d1f627e523929dff9e787498e96ef661cfe6 100644 (file)
@@ -133,4 +133,6 @@ the APIs of 'struct mutex' have been streamlined:
  int  mutex_trylock(struct mutex *lock);
  void mutex_unlock(struct mutex *lock);
  int  mutex_is_locked(struct mutex *lock);
-
+ void mutex_lock_nested(struct mutex *lock, unsigned int subclass);
+ int  mutex_lock_interruptible_nested(struct mutex *lock,
+                                      unsigned int subclass);
index a136721499bfbb1d7683ed2c47a1340a6482ab24..d602c8d6ff3e5d6ea9614286550d6bc15756c24b 100644 (file)
@@ -37,7 +37,7 @@ all, distributions.  There is, however, additional software that is
 required. The firmware used by the chip is the intellectual property
 of Broadcom and they have not given the bcm43xx team redistribution
 rights to this firmware.  Since we cannot legally redistribute
-the firwmare we cannot include it with the driver. Furthermore, it
+the firmware we cannot include it with the driver. Furthermore, it
 cannot be placed in the downloadable archives of any distributing
 organization; therefore, the user is responsible for obtaining the
 firmware and placing it in the appropriate location so that the driver
index 6ae2feff3087edfc13f58fb1ea9d9ddfc6f06a97..747a5d15d529c8bff449d88802b79b70a213a775 100644 (file)
@@ -293,7 +293,7 @@ tcp_no_metrics_save - BOOLEAN
        when the connection closes, so that connections established in the
        near future can use these to set initial conditions.  Usually, this
        increases overall performance, but may sometimes cause performance
-       degredation.  If set, TCP will not cache metrics on closing
+       degradation.  If set, TCP will not cache metrics on closing
        connections.
 
 tcp_orphan_retries - INTEGER
index c36b64b0020fc670063519c4c8e64ac4f44af3d1..c3669a3fb4af284997fac1b5cd5a58d023a6be90 100644 (file)
@@ -689,7 +689,7 @@ such as the AFS filesystem.  This permits such a utility to:
      buffers manipulated directly.
 
 To use the RxRPC facility, a kernel utility must still open an AF_RXRPC socket,
-bind an addess as appropriate and listen if it's to be a server socket, but
+bind an address as appropriate and listen if it's to be a server socket, but
 then it passes this to the kernel interface functions.
 
 The kernel interface functions are as follows:
index 6be09ba24a365f25e1c16881f7560d63a2cef3e3..b6409cab075ca53aa3a5f4a6276403e0a0463c89 100644 (file)
@@ -12,7 +12,7 @@
   For in-depth information, you can consult:
 
    o The UDP-Lite Homepage: http://www.erg.abdn.ac.uk/users/gerrit/udp-lite/
-       Fom here you can also download some example application source code.
+       From here you can also download some example application source code.
 
    o The UDP-Lite HOWTO on
        http://www.erg.abdn.ac.uk/users/gerrit/udp-lite/files/UDP-Lite-HOWTO.txt
   While it is important that such cases are dealt with correctly, they
   are (annoyingly) rare: UDP-Lite is designed for optimising multimedia
   performance over wireless (or generally noisy) links and thus smaller
-  coverage lenghts are likely to be expected.
+  coverage lengths are likely to be expected.
 
 
   V) UDP-LITE RUNTIME STATISTICS AND THEIR MEANING
   VI) IPTABLES
 
   There is packet match support for UDP-Lite as well as support for the LOG target.
-  If you copy and paste the following line into /etc/protcols,
+  If you copy and paste the following line into /etc/protocols,
 
   udplite 136     UDP-Lite        # UDP-Lite [RFC 3828]
 
index 8f2302415eff90b0df7aa655f132f9567ff9ccd7..265fcdcb8e5f3cdc4a0826697be57ae7ebda3c54 100644 (file)
@@ -25,7 +25,6 @@ Global functions:
   parport_open
   parport_close
   parport_device_id
-  parport_device_num
   parport_device_coords
   parport_find_class
   parport_find_device
@@ -735,7 +734,7 @@ NULL is returned.
 
 SEE ALSO
 
-parport_register_device, parport_device_num
+parport_register_device
 \f
 parport_close - unregister device for particular device number
 -------------
@@ -787,29 +786,7 @@ Many devices have ill-formed IEEE 1284 Device IDs.
 
 SEE ALSO
 
-parport_find_class, parport_find_device, parport_device_num
-\f
-parport_device_num - convert device coordinates to device number
-------------------
-
-SYNOPSIS
-
-#include <linux/parport.h>
-
-int parport_device_num (int parport, int mux, int daisy);
-
-DESCRIPTION
-
-Convert between device coordinates (port, multiplexor, daisy chain
-address) and device number (zero-based).
-
-RETURN VALUE
-
-Device number, or -1 if no device at given coordinates.
-
-SEE ALSO
-
-parport_device_coords, parport_open, parport_device_id
+parport_find_class, parport_find_device
 \f
 parport_device_coords - convert device number to device coordinates
 ------------------
@@ -833,7 +810,7 @@ Zero on success, in which case the coordinates are (*parport, *mux,
 
 SEE ALSO
 
-parport_device_num, parport_open, parport_device_id
+parport_open, parport_device_id
 \f
 parport_find_class - find a device by its class
 ------------------
index 1a85e2b964dca0e34f4411cfef0098f6606c46b5..57aef2f6e0de6ad30673d8ce34a5430dc59ec5ab 100644 (file)
@@ -78,8 +78,8 @@ c) Advanced debugging
 In case the STD does not work on your system even in the minimal configuration
 and compiling more drivers as modules is not practical or some modules cannot
 be unloaded, you can use one of the more advanced debugging techniques to find
-the problem.  First, if there is a serial port in your box, you can set the
-CONFIG_DISABLE_CONSOLE_SUSPEND kernel configuration option and try to log kernel
+the problem.  First, if there is a serial port in your box, you can boot the
+kernel with the 'no_console_suspend' parameter and try to log kernel
 messages using the serial console.  This may provide you with some information
 about the reasons of the suspend (resume) failure.  Alternatively, it may be
 possible to use a FireWire port for debugging with firescope
index 04dc1cf9d2155a3488d2fe557d7f82b76a06ecc8..38b57248fd61f5755528837145052c5c998c17b7 100644 (file)
@@ -19,12 +19,13 @@ we only consider hibernation, but the description also applies to suspend).
 Namely, as the first step of the hibernation procedure the function
 freeze_processes() (defined in kernel/power/process.c) is called.  It executes
 try_to_freeze_tasks() that sets TIF_FREEZE for all of the freezable tasks and
-sends a fake signal to each of them.  A task that receives such a signal and has
-TIF_FREEZE set, should react to it by calling the refrigerator() function
-(defined in kernel/power/process.c), which sets the task's PF_FROZEN flag,
-changes its state to TASK_UNINTERRUPTIBLE and makes it loop until PF_FROZEN is
-cleared for it.  Then, we say that the task is 'frozen' and therefore the set of
-functions handling this mechanism is called 'the freezer' (these functions are
+either wakes them up, if they are kernel threads, or sends fake signals to them,
+if they are user space processes.  A task that has TIF_FREEZE set, should react
+to it by calling the function called refrigerator() (defined in
+kernel/power/process.c), which sets the task's PF_FROZEN flag, changes its state
+to TASK_UNINTERRUPTIBLE and makes it loop until PF_FROZEN is cleared for it.
+Then, we say that the task is 'frozen' and therefore the set of functions
+handling this mechanism is referred to as 'the freezer' (these functions are
 defined in kernel/power/process.c and include/linux/freezer.h).  User space
 processes are generally frozen before kernel threads.
 
@@ -35,21 +36,27 @@ task enter refrigerator() if the flag is set.
 
 For user space processes try_to_freeze() is called automatically from the
 signal-handling code, but the freezable kernel threads need to call it
-explicitly in suitable places.  The code to do this may look like the following:
+explicitly in suitable places or use the wait_event_freezable() or
+wait_event_freezable_timeout() macros (defined in include/linux/freezer.h)
+that combine interruptible sleep with checking if TIF_FREEZE is set and calling
+try_to_freeze().  The main loop of a freezable kernel thread may look like the
+following one:
 
+       set_freezable();
        do {
                hub_events();
-               wait_event_interruptible(khubd_wait,
-                                       !list_empty(&hub_event_list));
-               try_to_freeze();
-       } while (!signal_pending(current));
+               wait_event_freezable(khubd_wait,
+                               !list_empty(&hub_event_list) ||
+                               kthread_should_stop());
+       } while (!kthread_should_stop() || !list_empty(&hub_event_list));
 
 (from drivers/usb/core/hub.c::hub_thread()).
 
 If a freezable kernel thread fails to call try_to_freeze() after the freezer has
 set TIF_FREEZE for it, the freezing of tasks will fail and the entire
 hibernation operation will be cancelled.  For this reason, freezable kernel
-threads must call try_to_freeze() somewhere.
+threads must call try_to_freeze() somewhere or use one of the
+wait_event_freezable() and wait_event_freezable_timeout() macros.
 
 After the system memory state has been restored from a hibernation image and
 devices have been reinitialized, the function thaw_processes() is called in
@@ -81,7 +88,16 @@ hibernation image has been created and before the system is finally powered off.
 The majority of these are user space processes, but if any of the kernel threads
 may cause something like this to happen, they have to be freezable.
 
-2. The second reason is to prevent user space processes and some kernel threads
+2. Next, to create the hibernation image we need to free a sufficient amount of
+memory (approximately 50% of available RAM) and we need to do that before
+devices are deactivated, because we generally need them for swapping out.  Then,
+after the memory for the image has been freed, we don't want tasks to allocate
+additional memory and we prevent them from doing that by freezing them earlier.
+[Of course, this also means that device drivers should not allocate substantial
+amounts of memory from their .suspend() callbacks before hibernation, but this
+is e separate issue.]
+
+3. The third reason is to prevent user space processes and some kernel threads
 from interfering with the suspending and resuming of devices.  A user space
 process running on a second CPU while we are suspending devices may, for
 example, be troublesome and without the freezing of tasks we would need some
@@ -111,7 +127,7 @@ frozen before the driver's .suspend() callback is executed and it will be
 thawed after the driver's .resume() callback has run, so it won't be accessing
 the device while it's suspended.
 
-3. Another reason for freezing tasks is to prevent user space processes from
+4. Another reason for freezing tasks is to prevent user space processes from
 realizing that hibernation (or suspend) operation takes place.  Ideally, user
 space processes should not notice that such a system-wide operation has occurred
 and should continue running without any problems after the restore (or resume
index fd5192a8fa8abebd12fe86aefd99404978d88f34..e67211fe0ee2f432044efe62e8909702f0b46fc9 100644 (file)
@@ -20,7 +20,7 @@ states.
 /sys/power/disk controls the operating mode of the suspend-to-disk
 mechanism. Suspend-to-disk can be handled in several ways. We have a
 few options for putting the system to sleep - using the platform driver
-(e.g. ACPI or other pm_ops), powering off the system or rebooting the
+(e.g. ACPI or other suspend_ops), powering off the system or rebooting the
 system (for testing).
 
 Additionally, /sys/power/disk can be used to turn on one of the two testing
index 06f911a5f885bfc022c3d4098e08be2dd17ff105..f281886de4902041bbda38942772384a622d0319 100644 (file)
@@ -39,7 +39,7 @@ resume=<swap_file_partition> resume_offset=<swap_file_offset>
 where <swap_file_partition> is the partition on which the swap file is located
 and <swap_file_offset> is the offset of the swap header determined by the
 application in 2) (of course, this step may be carried out automatically
-by the same application that determies the swap file's header offset using the
+by the same application that determines the swap file's header offset using the
 FIBMAP ioctl)
 
 OR
index 4530d1bf0286f68a5642f8ad6e99096447e14aa4..df7afe43d46286a1c0cb50bb95269e7d7c99e7d6 100644 (file)
@@ -36,8 +36,8 @@ Causes of EEH Errors
 EEH was originally designed to guard against hardware failure, such
 as PCI cards dying from heat, humidity, dust, vibration and bad
 electrical connections. The vast majority of EEH errors seen in
-"real life" are due to eithr poorly seated PCI cards, or,
-unfortunately quite commonly, due device driver bugs, device firmware
+"real life" are due to either poorly seated PCI cards, or,
+unfortunately quite commonly, due to device driver bugs, device firmware
 bugs, and sometimes PCI card hardware bugs.
 
 The most common software bug, is one that causes the device to
index e59fcbbe338cb437dabb6fd28d8d0f5d1e14345b..5e03610e186f986c5cc3a21a5e4f9bbac3ee4332 100644 (file)
@@ -17,12 +17,12 @@ passed by the boot loader to the kernel at boot time.  The device tree
 describes what devices are present on the board and how they are
 connected.  The device tree can either be passed as a binary blob (as
 described in Documentation/powerpc/booting-without-of.txt), or passed
-by Open Firmare (IEEE 1275) compatible firmware using an OF compatible
+by Open Firmware (IEEE 1275) compatible firmware using an OF compatible
 client interface API.
 
 This document specifies the requirements on the device-tree for mpc5200
 based boards.  These requirements are above and beyond the details
-specified in either the OpenFirmware spec or booting-without-of.txt
+specified in either the Open Firmware spec or booting-without-of.txt
 
 All new mpc5200-based boards are expected to match this document.  In
 cases where this document is not sufficient to support a new board port,
@@ -73,8 +73,8 @@ match on the compatible list; the 'most compatible' driver should be
 selected.
 
 The split between the MPC5200 and the MPC5200B leaves a bit of a
-connundrum.  How should the compatible property be set up to provide
-maximum compatability information; but still acurately describe the
+conundrum.  How should the compatible property be set up to provide
+maximum compatibility information; but still accurately describe the
 chip?  For the MPC5200; the answer is easy.  Most of the SoC devices
 originally appeared on the MPC5200.  Since they didn't exist anywhere
 else; the 5200 compatible properties will contain only one item;
@@ -84,7 +84,7 @@ The 5200B is almost the same as the 5200, but not quite.  It fixes
 silicon bugs and it adds a small number of enhancements.  Most of the
 devices either provide exactly the same interface as on the 5200.  A few
 devices have extra functions but still have a backwards compatible mode.
-To express this infomation as completely as possible, 5200B device trees
+To express this information as completely as possible, 5200B device trees
 should have two items in the compatible list;
 "mpc5200b-<device>\0mpc5200-<device>".  It is *strongly* recommended
 that 5200B device trees follow this convention (instead of only listing
@@ -185,7 +185,7 @@ bestcomm@<addr>     dma-controller          mpc5200-bestcomm 5200 pic also requires
 Recommended soc5200 child nodes; populate as needed for your board
 name           device_type     compatible        Description
 ----           -----------     ----------        -----------
-gpt@<addr>     gpt             mpc5200-gpt       General purpose timers
+gpt@<addr>     gpt             fsl,mpc5200-gpt   General purpose timers
 rtc@<addr>     rtc             mpc5200-rtc       Real time clock
 mscan@<addr>   mscan           mpc5200-mscan     CAN bus controller
 pci@<addr>     pci             mpc5200-pci       PCI bridge
@@ -199,7 +199,7 @@ ethernet@<addr>     network         mpc5200-fec       MPC5200 ethernet device
 ata@<addr>     ata             mpc5200-ata       IDE ATA interface
 i2c@<addr>     i2c             mpc5200-i2c       I2C controller
 usb@<addr>     usb-ohci-be     mpc5200-ohci,ohci-be    USB controller
-xlb@<addr>     xlb             mpc5200-xlb       XLB arbritrator
+xlb@<addr>     xlb             mpc5200-xlb       XLB arbitrator
 
 Important child node properties
 name           type            description
@@ -213,7 +213,7 @@ cell-index  int             When multiple devices are present, is the
 5) General Purpose Timer nodes (child of soc5200 node)
 On the mpc5200 and 5200b, GPT0 has a watchdog timer function.  If the board
 design supports the internal wdt, then the device node for GPT0 should
-include the empty property 'has-wdt'.
+include the empty property 'fsl,has-wdt'.
 
 6) PSC nodes (child of soc5200 node)
 PSC nodes can define the optional 'port-number' property to force assignment
index 6aa9a891f3d00ec20df21d49c4a531f1ba574a2e..683ccae00ad412aa498e979d574627e87ade2088 100644 (file)
@@ -120,7 +120,7 @@ The following information is available in this file:
           list size to avoid SCSI malloc pool fragmentation.
         - Cleanup channel display in our /proc output.
         - Workaround duplicate device entries in the mid-layer
-          devlice list during add-single-device.
+          device list during add-single-device.
 
    1.3.6 (March 28th, 2003)
         - Correct a double free in the Domain Validation code.
index 5f34d2ba69b47ce0e4571ac5288a3415c314c05d..b7e238cbb5a7c72a527f73ffa5a93cd8aa4a9fa7 100644 (file)
@@ -159,7 +159,7 @@ The following information is available in this file:
         - Add support for 2.5.X's scsi_report_device_reset().
 
    6.2.34 (May 5th, 2003)
-        - Fix locking regression instroduced in 6.2.29 that
+        - Fix locking regression introduced in 6.2.29 that
           could cause a lock order reversal between the io_request_lock
           and our per-softc lock.  This was only possible on RH9,
           SuSE, and kernel.org 2.4.X kernels.
@@ -264,7 +264,7 @@ The following information is available in this file:
               Option: tag_info:{{value[,value...]}[,{value[,value...]}...]}
           Definition: Set the per-target tagged queue depth on a
                       per controller basis.  Both controllers and targets
-                      may be ommitted indicating that they should retain
+                      may be omitted indicating that they should retain
                       the default tag depth.
             Examples: tag_info:{{16,32,32,64,8,8,,32,32,32,32,32,32,32,32,32}
                         On Controller 0
@@ -290,7 +290,7 @@ The following information is available in this file:
    -----------------------------------------------------------------
               Option: dv: {value[,value...]} 
           Definition: Set Domain Validation Policy on a per-controller basis.
-                      Controllers may be ommitted indicating that
+                      Controllers may be omitted indicating that
                       they should retain the default read streaming setting.
              Example: dv:{-1,0,,1,1,0}
                         On Controller 0 leave DV at its default setting.
index 5e0042340fd3e2c51eb4335868633d23fb0dd808..45d9482c151760b01b618a5faa66b5fcf7bf2b56 100644 (file)
@@ -3,7 +3,7 @@
 *******************************************************************************
 **     Usage of IOP331 adapter
 **     (All In/Out is in IOP331's view)
-**     1. Message 0 --> InitThread message and retrun code
+**     1. Message 0 --> InitThread message and return code
 **     2. Doorbell is used for RS-232 emulation
 **             inDoorBell :    bit0 -- data in ready
 **                     (DRIVER DATA WRITE OK)
index a08e225653d6fae25fdf0fe0be7a577a0639927c..a810421f1fb3dfab2e256bcb097db6b1fbc484d9 100644 (file)
@@ -21,7 +21,7 @@
    versions older than 4.0 do not work with kernels 2.4.0 or later! If you
    try to compile your kernel with the wrong driver source, the 
    compilation is aborted and you get a corresponding error message. This is
-   no bug in the driver. It prevents you from using the wrong sourcecode
+   no bug in the driver; it prevents you from using the wrong source code
    with the wrong kernel version.
 
    Authors of this Driver
@@ -58,7 +58,7 @@
    5 Users' Manual
      5.1 Commandline Parameters
      5.2 Troubleshooting
-     5.3 Bugreports
+     5.3 Bug reports
      5.4 Support WWW-page
    6 References
    7 Credits to
 
    1 Abstract
    ----------
-   This README-file describes the IBM SCSI-subsystem low level driver for 
-   Linux. The descriptions which were formerly kept in the source-code have 
-   been taken out to this file to easify the codes' readability. The driver 
+   This README-file describes the IBM SCSI-subsystem low level driver for
+   Linux. The descriptions which were formerly kept in the source code have
+   been taken out of this file to simplify the codes readability. The driver
    description has been updated, as most of the former description was already
-   quite outdated. The history of the driver development is also kept inside 
-   here. Multiple historical developments have been summarized to shorten the 
-   textsize a bit. At the end of this file you can find a small manual for 
+   quite outdated. The history of the driver development is also kept inside
+   here. Multiple historical developments have been summarized to shorten the
+   text size a bit. At the end of this file you can find a small manual for
    this driver and hints to get it running on your machine.
 
    2 Driver Description
    between 0 and 7). The IBM SCSI-2 F/W adapter offers this on up to two
    busses and provides support for 30 logical devices at the same time, where
    in wide-addressing mode you can have 16 puns with 32 luns on each device.
-   This section dexribes you the handling of devices on non-F/W adapters.
+   This section describes the handling of devices on non-F/W adapters.
    Just imagine, that you can have 16 * 32 = 512 devices on a F/W adapter
    which means a lot of possible devices for such a small machine.
 
    --------------------------------------------------------
    One consequence of information hiding is that the real (pun,lun)    
    numbers are also hidden. The two possibilities to get around this problem
-   is to offer fake pun/lun combinations to the operating system or to 
+   are to offer fake pun/lun combinations to the operating system or to 
    delete the whole mapping of the adapter and to reassign the ldns, using
    the immediate assign command of the SCSI-subsystem for probing through
-   all possible pun/lun combinations. a ldn is a "logical device number"
+   all possible pun/lun combinations.  An ldn is a "logical device number"
    which is used by IBM SCSI-subsystems to access some valid SCSI-device.
    At the beginning of the development of this driver, the following approach 
    was used:
    lun>0 or to non-existing devices, in order to satisfy the subsystem, if 
    there are less than 15 SCSI-devices connected. In the case of more than 15 
    devices, the dynamical mapping goes active. If the get_scsi[][] reports a 
-   device to be existant, but it has no ldn assigned, it gets a ldn out of 7 
-   to 14. The numbers are assigned in cyclic order. Therefore it takes 8 
-   dynamical reassignments on the SCSI-devices, until a certain device 
+   device to be existent, but it has no ldn assigned, it gets an ldn out of 7
+   to 14. The numbers are assigned in cyclic order, therefore it takes 8 
+   dynamical reassignments on the SCSI-devices until a certain device 
    loses its ldn again. This assures that dynamical remapping is avoided 
    during intense I/O between up to 15 SCSI-devices (means pun,lun 
    combinations). A further advantage of this method is that people who
       than devices are available, they are assigned to non existing pun,lun
       combinations to satisfy the adapter. With this, the dynamical mapping
       was possible to implement. (For further info see the text in the 
-      source-code and in the description below. Read the description
+      source code and in the description below. Read the description
       below BEFORE installing this driver on your system!)
    2) Changed the name IBMMCA_DRIVER_VERSION to IBMMCA_SCSI_DRIVER_VERSION.
    3) The LED-display shows on PS/2-95 no longer the ldn, but the SCSI-ID
    - Michael Lang
 
    Apr 23, 2000 (v3.2pre1)
-   1) During a very long time, I collected a huge amount of bugreports from
+   1) During a very long time, I collected a huge amount of bug reports from
       various people, trying really quite different things on their SCSI-
-      PS/2s. Today, all these bugreports are taken into account and should be
+      PS/2s. Today, all these bug reports are taken into account and should be
       mostly solved. The major topics were:
       - Driver crashes during boottime by no obvious reason.
       - Driver panics while the midlevel-SCSI-driver is trying to inquire
    - Michael Lang
    
    July 17, 2000 (v3.2pre8)
-   A long period of collecting bugreports from all corners of the world
+   A long period of collecting bug reports from all corners of the world
    now lead to the following corrections to the code:
    1) SCSI-2 F/W support crashed with a COMMAND ERROR. The reason for this 
       was that it is possible to disable Fast-SCSI for the external bus.
    July 26, 2000 (v3.2pre11)
    1) I passed a horrible weekend getting mad with NMIs on kernel 2.2.14 and
       a model 9595. Asking around in the community, nobody except of me has
-      seen such errors. Weired, but I am trying to recompile everything on
+      seen such errors. Weird, but I am trying to recompile everything on
       the model 9595. Maybe, as I use a specially modified gcc, that could
       cause problems. But, it was not the reason. The true background was,
       that the kernel was compiled for i386 and the 9595 has a 486DX-2. 
       alive rotator during boottime. This makes sense, when no monitor is 
       connected to the system. You can get rid of all display activity, if
       you do not use any parameter or just ibmmcascsi=activity, for the 
-      harddrive activity LED, existant on all PS/2, except models 8595-XXX.
+      harddrive activity LED, existent on all PS/2, except models 8595-XXX.
       If no monitor is available, please use ibmmcascsi=display, which works
       fine together with the linuxinfo utility for the LED-panel.
    - Michael Lang
         If this really happens, do also send e-mail to the maintainer, as
        forced detection should be never necessary. Forced detection is in
        principal some flaw of the driver adapter detection and goes into 
-       bugreports.
+       bug reports.
      Q: The driver screws up, if it starts to probe SCSI-devices, is there
         some way out of it?
      A: Yes, that was some recognition problem of the correct SCSI-adapter
        recommended version is 3.2 or later. Here, the F/W support is in
        a stable and reliable condition. Wide-addressing is in addition 
        supported.
-     Q: I get a Ooops message and something like "killing interrupt".
+     Q: I get an Oops message and something like "killing interrupt".
      A: The reason for this is that the IBM SCSI-subsystem only sends a 
         termination status back, if some error appeared. In former releases
        of the driver, it was not checked, if the termination status block
        problem. Not yet tried, but guessing that it could work. To get this,
        set unchecked_isa_dma argument of ibmmca.h from 0 to 1.
 
-   5.3 Bugreports
+   5.3 Bug reports
    --------------
-   If you really find bugs in the sourcecode or the driver will successfully
+   If you really find bugs in the source code or the driver will successfully
    refuse to work on your machine, you should send a bug report to me. The
    best for this is to follow the instructions on the WWW-page for this
    driver. Fill out the bug-report form, placed on the WWW-page and ship it,
    so the bugs can be taken into account with maximum efforts. But, please
    do not send bug reports about this driver to Linus Torvalds or Leonard
-   Zubkoff, as Linus is burried in E-Mail and Leonard is supervising all
+   Zubkoff, as Linus is buried in E-Mail and Leonard is supervising all
    SCSI-drivers and won't have the time left to look inside every single
    driver to fix a bug and especially DO NOT send modified code to Linus
    Torvalds or Alan J. Cox which has not been checked here!!! They are both
-   quite burried in E-mail (as me, sometimes, too) and one should first check
+   quite buried in E-mail (as me, sometimes, too) and one should first check
    for problems on my local teststand. Recently, I got a lot of 
-   bugreports for errors in the ibmmca.c code, which I could not imagine, but
+   bug reports for errors in the ibmmca.c code, which I could not imagine, but
    a look inside some Linux-distribution showed me quite often some modified
    code, which did no longer work on most other machines than the one of the
    modifier. Ok, so now that there is maintenance service available for this
    some e-mail directly, but at least with the same information as required by
    the formular.
    
-   If you have extensive bugreports, including Ooops messages and 
+   If you have extensive bug reports, including Oops messages and
    screen-shots, please feel free to send it directly to the address
    of the maintainer, too. The current address of the maintainer is:
    
                detailed bug reports and ideas for this driver (and his 
                patience ;-)).
    Alan J. Cox  
-                for his bugreports and his bold activities in cross-checking
+                for his bug reports and his bold activities in cross-checking
                the driver-code with his teststand.
                
    7.2 Sponsors & Supporters
index ccf1cebe744f8b4a6901ff7f61bd23029562344a..736540045dc7b7c9e448fb90bd72fc63346e082d 100644 (file)
@@ -153,6 +153,7 @@ replicas continue to be exactly same.
        #include <stdio.h>
        #include <stdlib.h>
        #include <unistd.h>
+       #include <string.h>
        #include <sys/mount.h>
        #include <sys/fsuid.h>
 
index 58cbfd01ea8f5cb658e759db4b0ea1e001bc7d2e..3feeb9ecdec49719443cba15fcac628a0c24b058 100644 (file)
@@ -20,12 +20,12 @@ I2S
 ===
 
  I2S is a common 4 wire DAI used in HiFi, STB and portable devices. The Tx and
-Rx lines are used for audio transmision, whilst the bit clock (BCLK) and
+Rx lines are used for audio transmission, whilst the bit clock (BCLK) and
 left/right clock (LRC) synchronise the link. I2S is flexible in that either the
 controller or CODEC can drive (master) the BCLK and LRC clock lines. Bit clock
 usually varies depending on the sample rate and the master system clock
 (SYSCLK). LRCLK is the same as the sample rate. A few devices support separate
-ADC and DAC LRCLK's, this allows for similtanious capture and playback at
+ADC and DAC LRCLK's, this allows for simultaneous capture and playback at
 different sample rates.
 
 I2S has several different operating modes:-
@@ -41,12 +41,12 @@ I2S has several different operating modes:-
 PCM
 ===
 
-PCM is another 4 wire interface, very similar to I2S, that can support a more
+PCM is another 4 wire interface, very similar to I2S, which can support a more
 flexible protocol. It has bit clock (BCLK) and sync (SYNC) lines that are used
 to synchronise the link whilst the Tx and Rx lines are used to transmit and
 receive the audio data. Bit clock usually varies depending on sample rate
 whilst sync runs at the sample rate. PCM also supports Time Division
-Multiplexing (TDM) in that several devices can use the bus similtaniuosly (This
+Multiplexing (TDM) in that several devices can use the bus simultaneously (this
 is sometimes referred to as network mode).
 
 Common PCM operating modes:-
index e93960d53a1ea8f58512e43219cda0261cd594c9..14930887c25f194c206a43dd6c56bd6188e07dd2 100644 (file)
@@ -2,20 +2,20 @@ Audio Clocking
 ==============
 
 This text describes the audio clocking terms in ASoC and digital audio in
-general. Note: Audio clocking can be complex !
+general. Note: Audio clocking can be complex!
 
 
 Master Clock
 ------------
 
-Every audio subsystem is driven by a master clock (sometimes refered to as MCLK
+Every audio subsystem is driven by a master clock (sometimes referred to as MCLK
 or SYSCLK). This audio master clock can be derived from a number of sources
 (e.g. crystal, PLL, CPU clock) and is responsible for producing the correct
 audio playback and capture sample rates.
 
-Some master clocks (e.g. PLL's and CPU based clocks) are configuarble in that
+Some master clocks (e.g. PLL's and CPU based clocks) are configurable in that
 their speed can be altered by software (depending on the system use and to save
-power). Other master clocks are fixed at at set frequency (i.e. crystals).
+power). Other master clocks are fixed at a set frequency (i.e. crystals).
 
 
 DAI Clocks
@@ -44,7 +44,7 @@ This relationship depends on the codec or SoC CPU in particular. In general
 it's best to configure BCLK to the lowest possible speed (depending on your
 rate, number of channels and wordsize) to save on power.
 
-It's also desireable to use the codec (if possible) to drive (or master) the
+It's also desirable to use the codec (if possible) to drive (or master) the
 audio clocks as it's usually gives more accurate sample rates than the CPU.
 
 
index 48983c75aad9cacd7052a484408425602ff6f98b..1e766ad0ebd1f4f28f4e20cb88899d4b8f5717da 100644 (file)
@@ -19,7 +19,7 @@ Optionally, codec drivers can also provide:-
  6) DAPM event handler.
  7) DAC Digital mute control.
 
-It's probably best to use this guide in conjuction with the existing codec
+It's probably best to use this guide in conjunction with the existing codec
 driver code in sound/soc/codecs/
 
 ASoC Codec driver breakdown
@@ -28,7 +28,7 @@ ASoC Codec driver breakdown
 1 - Codec DAI and PCM configuration
 -----------------------------------
 Each codec driver must have a struct snd_soc_codec_dai to define it's DAI and
-PCM's capablities and operations. This struct is exported so that it can be
+PCM's capabilities and operations. This struct is exported so that it can be
 registered with the core by your machine driver.
 
 e.g.
@@ -67,7 +67,7 @@ EXPORT_SYMBOL_GPL(wm8731_dai);
 
 2 - Codec control IO
 --------------------
-The codec can ususally be controlled via an I2C or SPI style interface (AC97
+The codec can usually be controlled via an I2C or SPI style interface (AC97
 combines control with data in the DAI). The codec drivers will have to provide
 functions to read and write the codec registers along with supplying a register
 cache:-
index c11877f5b4a1d93abbae1a31acd074d334a3e361..ab0766fd78690859e1594602fcd62155f48b0529 100644 (file)
@@ -11,7 +11,7 @@ other PM systems.
 
 DAPM is also completely transparent to all user space applications as all power
 switching is done within the ASoC core. No code changes or recompiling are
-required for user space applications. DAPM makes power switching descisions based
+required for user space applications. DAPM makes power switching decisions based
 upon any audio stream (capture/playback) activity and audio mixer settings
 within the device.
 
@@ -38,7 +38,7 @@ There are 4 power domains within DAPM
       Enabled and disabled when stream playback/capture is started and
       stopped respectively. e.g. aplay, arecord.
 
-All DAPM power switching descisons are made automatically by consulting an audio
+All DAPM power switching decisions are made automatically by consulting an audio
 routing map of the whole machine. This map is specific to each machine and
 consists of the interconnections between every audio component (including
 internal codec components). All audio components that effect power are called
index 753c5cc5984a8b059799fb7e0f779e820b1c071c..c47ce9530677961142f371784bc7550cdc58c460 100644 (file)
@@ -2,18 +2,19 @@ ALSA SoC Layer
 ==============
 
 The overall project goal of the ALSA System on Chip (ASoC) layer is to provide
-better ALSA support for embedded system on chip procesors (e.g. pxa2xx, au1x00,
+better ALSA support for embedded system-on-chip processors (e.g. pxa2xx, au1x00,
 iMX, etc) and portable audio codecs. Currently there is some support in the
 kernel for SoC audio, however it has some limitations:-
 
   * Currently, codec drivers are often tightly coupled to the underlying SoC
-    cpu. This is not ideal and leads to code duplication i.e. Linux now has 4
+    CPU. This is not ideal and leads to code duplication i.e. Linux now has 4
     different wm8731 drivers for 4 different SoC platforms.
 
-  * There is no standard method to signal user initiated audio events.
-    e.g. Headphone/Mic insertion, Headphone/Mic detection after an insertion
-    event. These are quite common events on portable devices and ofter require
-    machine specific code to re route audio, enable amps etc after such an event.
+  * There is no standard method to signal user initiated audio events (e.g.
+    Headphone/Mic insertion, Headphone/Mic detection after an insertion
+    event). These are quite common events on portable devices and often require
+    machine specific code to re-route audio, enable amps, etc., after such an
+    event.
 
   * Current drivers tend to power up the entire codec when playing
     (or recording) audio. This is fine for a PC, but tends to waste a lot of
@@ -44,7 +45,7 @@ features :-
     signals the codec when to change power states.
 
   * Machine specific controls: Allow machines to add controls to the sound card
-    e.g. volume control for speaker amp.
+    (e.g. volume control for speaker amp).
 
 To achieve all this, ASoC basically splits an embedded audio system into 3
 components :-
@@ -57,7 +58,7 @@ components :-
     interface drivers (e.g. I2S, AC97, PCM) for that platform.
 
   * Machine driver: The machine driver handles any machine specific controls and
-    audio events. i.e. turing on an amp at start of playback.
+    audio events (e.g. turning on an amp at start of playback).
 
 
 Documentation
index e95b16d5a53b155aace06da2f28111e46c419194..d4678b4dc6c6704869763c98b584bf015584fda2 100644 (file)
@@ -20,7 +20,7 @@ struct snd_soc_ops {
        int (*trigger)(struct snd_pcm_substream *, int);
 };
 
-The platform driver exports it's DMA functionailty via struct snd_soc_platform:-
+The platform driver exports its DMA functionality via struct snd_soc_platform:-
 
 struct snd_soc_platform {
        char *name;
index 2cf7ee5b3d7446d901c4d9b0b2530a79d84af683..3371bd9d7cfa52c46c7713b78b932326090f996c 100644 (file)
@@ -2,7 +2,7 @@ Audio Pops and Clicks
 =====================
 
 Pops and clicks are unwanted audio artifacts caused by the powering up and down
-of components within the audio subsystem. This is noticable on PC's when an
+of components within the audio subsystem. This is noticeable on PCs when an
 audio module is either loaded or unloaded (at module load time the sound card is
 powered up and causes a popping noise on the speakers).
 
@@ -16,7 +16,7 @@ Minimising Playback Pops and Clicks
 ===================================
 
 Playback pops in portable audio subsystems cannot be completely eliminated atm,
-however future audio codec hardware will have better pop and click supression.
+however future audio codec hardware will have better pop and click suppression.
 Pops can be reduced within playback by powering the audio components in a
 specific order. This order is different for startup and shutdown and follows
 some basic rules:-
@@ -33,7 +33,7 @@ Minimising Capture Pops and Clicks
 ==================================
 
 Capture artifacts are somewhat easier to get rid as we can delay activating the
-ADC until all the pops have occured. This follows similar power rules to
+ADC until all the pops have occurred. This follows similar power rules to
 playback in that components are powered in a sequence depending upon stream
 startup or shutdown.
 
diff --git a/Documentation/sound/oss/es1371 b/Documentation/sound/oss/es1371
deleted file mode 100644 (file)
index c315126..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/proc/sound, /dev/sndstat
--------------------------
-
-/proc/sound and /dev/sndstat is not supported by the
-driver. To find out whether the driver succeeded loading,
-check the kernel log (dmesg).
-
-
-ALaw/uLaw sample formats
-------------------------
-
-This driver does not support the ALaw/uLaw sample formats.
-ALaw is the default mode when opening a sound device
-using OSS/Free. The reason for the lack of support is
-that the hardware does not support these formats, and adding
-conversion routines to the kernel would lead to very ugly
-code in the presence of the mmap interface to the driver.
-And since xquake uses mmap, mmap is considered important :-)
-and no sane application uses ALaw/uLaw these days anyway.
-In short, playing a Sun .au file as follows:
-
-cat my_file.au > /dev/dsp
-
-does not work. Instead, you may use the play script from
-Chris Bagwell's sox-12.14 package (available from the URL
-below) to play many different audio file formats.
-The script automatically determines the audio format
-and does do audio conversions if necessary.
-http://home.sprynet.com/sprynet/cbagwell/projects.html
-
-
-Blocking vs. nonblocking IO
----------------------------
-
-Unlike OSS/Free this driver honours the O_NONBLOCK file flag
-not only during open, but also during read and write.
-This is an effort to make the sound driver interface more
-regular. Timidity has problems with this; a patch
-is available from http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html.
-(Timidity patched will also run on OSS/Free).
-
-
-MIDI UART
----------
-
-The driver supports a simple MIDI UART interface, with
-no ioctl's supported.
-
-
-MIDI synthesizer
-----------------
-
-This soundcard does not have any hardware MIDI synthesizer;
-MIDI synthesis has to be done in software. To allow this
-the driver/soundcard supports two PCM (/dev/dsp) interfaces.
-
-There is a freely available software package that allows
-MIDI file playback on this soundcard called Timidity.
-See http://www.cgs.fi/~tt/timidity/.
-
-
-
-Thomas Sailer
-t.sailer@alumni.ethz.ch
index 215e3b8e72666b78f92addd070e74be29389711a..f3853cc37bde387e4608c27833e4653aa3811d3b 100644 (file)
@@ -1,4 +1,4 @@
-PXA2xx SPI on SSP driver HOWTO
+PXA2xx SPI on SSP driver HOWTO
 ===================================================
 This a mini howto on the pxa2xx_spi driver.  The driver turns a PXA2xx
 synchronous serial port into a SPI master controller
index 60953d6c919d065b850d8cedd3874cc27778404d..ec499265decaa45b7c2495e51bdc660f1959dc6f 100644 (file)
@@ -105,10 +105,15 @@ The version of thinkpad-acpi's sysfs interface is exported by the driver
 as a driver attribute (see below).
 
 Sysfs driver attributes are on the driver's sysfs attribute space,
-for 2.6.20 this is /sys/bus/platform/drivers/thinkpad_acpi/.
+for 2.6.23 this is /sys/bus/platform/drivers/thinkpad_acpi/ and
+/sys/bus/platform/drivers/thinkpad_hwmon/
 
-Sysfs device attributes are on the driver's sysfs attribute space,
-for 2.6.20 this is /sys/devices/platform/thinkpad_acpi/.
+Sysfs device attributes are on the thinkpad_acpi device sysfs attribute
+space, for 2.6.23 this is /sys/devices/platform/thinkpad_acpi/.
+
+Sysfs device attributes for the sensors and fan are on the
+thinkpad_hwmon device's sysfs attribute space, but you should locate it
+looking for a hwmon device with the name attribute of "thinkpad".
 
 Driver version
 --------------
@@ -766,7 +771,7 @@ Temperature sensors
 -------------------
 
 procfs: /proc/acpi/ibm/thermal
-sysfs device attributes: (hwmon) temp*_input
+sysfs device attributes: (hwmon "thinkpad") temp*_input
 
 Most ThinkPads include six or more separate temperature sensors but only
 expose the CPU temperature through the standard ACPI methods.  This
@@ -989,7 +994,9 @@ Fan control and monitoring: fan speed, fan enable/disable
 ---------------------------------------------------------
 
 procfs: /proc/acpi/ibm/fan
-sysfs device attributes: (hwmon) fan_input, pwm1, pwm1_enable
+sysfs device attributes: (hwmon "thinkpad") fan1_input, pwm1,
+                         pwm1_enable
+sysfs hwmon driver attributes: fan_watchdog
 
 NOTE NOTE NOTE: fan control operations are disabled by default for
 safety reasons.  To enable them, the module parameter "fan_control=1"
@@ -1028,7 +1035,7 @@ enable it if necessary to avoid overheating.
 
 An enabled fan in level "auto" may stop spinning if the EC decides the
 ThinkPad is cool enough and doesn't need the extra airflow.  This is
-normal, and the EC will spin the fan up if the varios thermal readings
+normal, and the EC will spin the fan up if the various thermal readings
 rise too much.
 
 On the X40, this seems to depend on the CPU and HDD temperatures.
@@ -1131,7 +1138,7 @@ hwmon device attribute fan1_input:
        which can take up to two minutes.  May return rubbish on older
        ThinkPads.
 
-driver attribute fan_watchdog:
+hwmon driver attribute fan_watchdog:
        Fan safety watchdog timer interval, in seconds.  Minimum is
        1 second, maximum is 120 seconds.  0 disables the watchdog.
 
@@ -1196,7 +1203,7 @@ for example:
 Enabling debugging output
 -------------------------
 
-The module takes a debug paramater which can be used to selectively
+The module takes a debug parameter which can be used to selectively
 enable various classes of debugging output, for example:
 
         modprobe ibm_acpi debug=0xffff
@@ -1233,3 +1240,9 @@ Sysfs interface changelog:
                layer, the radio switch generates input event EV_RADIO,
                and the driver enables hot key handling by default in
                the firmware.
+
+0x020000:      ABI fix: added a separate hwmon platform device and
+               driver, which must be located by name (thinkpad)
+               and the hwmon class for libsensors4 (lm-sensors 3)
+               compatibility.  Moved all hwmon attributes to this
+               new platform device.
index 4e0b62b8566ff266d3242e55efea5977e9d8bbbb..8b077e43eee7168c0a6594e88911636301c72c56 100644 (file)
@@ -338,7 +338,7 @@ MCT USB Single Port Serial Adapter U232
   This driver is for the MCT USB-RS232 Converter (25 pin, Model No.
   U232-P25) from Magic Control Technology Corp. (there is also a 9 pin
   Model No. U232-P9). More information about this device can be found at
-  the manufacture's web-site: http://www.mct.com.tw.
+  the manufacturer's web-site: http://www.mct.com.tw.
 
   The driver is generally working, though it still needs some more testing.
   It is derived from the Belkin USB Serial Adapter F5U103 driver and its
index 10deabeb3929f674e462da6f6a5667fd08784e17..40245af2d0e3611df6b0f18365910ab1d7798d9e 100644 (file)
@@ -1963,11 +1963,6 @@ M:       adaplas@gmail.com
 L:     linux-fbdev-devel@lists.sourceforge.net (subscribers-only)
 S:     Maintained
 
-INTEL APIC/IOAPIC, LOWLEVEL X86 SMP SUPPORT
-P:     Ingo Molnar
-M:     mingo@redhat.com
-S:     Maintained
-
 INTEL I8XX RANDOM NUMBER GENERATOR SUPPORT
 P:     Jeff Garzik
 M:     jgarzik@pobox.com
@@ -2178,7 +2173,7 @@ S:        Maintained
 KCONFIG
 P:     Roman Zippel
 M:     zippel@linux-m68k.org
-L:     kbuild-devel@lists.sourceforge.net
+L:     linux-kbuild@vger.kernel.org
 S:     Maintained
 
 KDUMP
@@ -2207,6 +2202,7 @@ KERNEL BUILD (kbuild: Makefile, scripts/Makefile.*)
 P:     Sam Ravnborg
 M:     sam@ravnborg.org
 T:     git kernel.org:/pub/scm/linux/kernel/git/sam/kbuild.git
+L:     linux-kbuild@vger.kernel.org
 S:     Maintained
 
 KERNEL JANITORS
@@ -2234,7 +2230,7 @@ S:        Supported
 KEXEC
 P:     Eric Biederman
 M:     ebiederm@xmission.com
-W:     http://www.xmission.com/~ebiederm/files/kexec/
+W:     http://ftp.kernel.org/pub/linux/kernel/people/horms/kexec-tools/
 L:     linux-kernel@vger.kernel.org
 L:     kexec@lists.infradead.org
 S:     Maintained
@@ -2342,6 +2338,8 @@ L:        linuxppc-dev@ozlabs.org
 S:     Maintained
 
 LINUX FOR POWERPC EMBEDDED PPC8XX
+P:     Vitaly Bordug
+M:     vitb@kernel.crashing.org
 P:     Marcelo Tosatti
 M:     marcelo@kvack.org
 W:     http://www.penguinppc.org/
@@ -2940,13 +2938,6 @@ L:       linux-kernel@vger.kernel.org
 L:     linux-pci@atrey.karlin.mff.cuni.cz
 S:     Supported
 
-PCI SOUND DRIVERS (ES1370, ES1371 and SONICVIBES)
-P:     Thomas Sailer
-M:     sailer@ife.ee.ethz.ch
-L:     linux-sound@vger.kernel.org
-W:     http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html
-S:     Maintained
-
 PCI SUBSYSTEM
 P:     Greg Kroah-Hartman
 M:     gregkh@suse.de
@@ -4275,9 +4266,15 @@ M:       jacmet@sunsite.dk
 L:     linux-serial@vger.kernel.org
 S:     Maintained
 
-X86 3-LEVEL PAGING (PAE) SUPPORT
+X86 ARCHITECTURE (32-BIT AND 64-BIT)
+P:     Thomas Gleixner
+M:     tglx@linutronix.de
 P:     Ingo Molnar
 M:     mingo@redhat.com
+P:     H. Peter Anvin
+M:     hpa@zytor.com
+L:     linux-kernel@vger.kernel.org
+T:     git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git
 S:     Maintained
 
 YAM DRIVER FOR AX.25
index 529b9048d97e950d2ea58948d2c5b93e67c0a563..264f37b8b263b9968936a2d88942112165086753 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -773,6 +773,9 @@ endef
 vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) vmlinux.o FORCE
 ifdef CONFIG_HEADERS_CHECK
        $(Q)$(MAKE) -f $(srctree)/Makefile headers_check
+endif
+ifdef CONFIG_SAMPLES
+       $(Q)$(MAKE) $(build)=samples
 endif
        $(call vmlinux-modpost)
        $(call if_changed_rule,vmlinux__)
@@ -884,10 +887,7 @@ prepare2: prepare3 outputmakefile
 
 prepare1: prepare2 include/linux/version.h include/linux/utsrelease.h \
                    include/asm include/config/auto.conf
-ifneq ($(KBUILD_MODULES),)
-       $(Q)mkdir -p $(MODVERDIR)
-       $(Q)rm -f $(MODVERDIR)/*
-endif
+       $(cmd_crmodverdir)
 
 archprepare: prepare1 scripts_basic
 
@@ -903,14 +903,24 @@ prepare: prepare0
 
 export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH)
 
-# FIXME: The asm symlink changes when $(ARCH) changes. That's
-# hard to detect, but I suppose "make mrproper" is a good idea
-# before switching between archs anyway.
-
-include/asm:
-       @echo '  SYMLINK $@ -> include/asm-$(SRCARCH)'
-       $(Q)if [ ! -d include ]; then mkdir -p include; fi;
-       @ln -fsn asm-$(SRCARCH) $@
+# The asm symlink changes when $(ARCH) changes.
+# Detect this and ask user to run make mrproper
+
+include/asm: FORCE
+       $(Q)set -e; asmlink=`readlink include/asm | cut -d '-' -f 2`;   \
+       if [ -L include/asm ]; then                                     \
+               if [ "$$asmlink" != "$(SRCARCH)" ]; then                \
+                       echo "ERROR: the symlink $@ points to asm-$$asmlink but asm-$(SRCARCH) was expected"; \
+                       echo "       set ARCH or save .config and run 'make mrproper' to fix it";             \
+                       exit 1;                                         \
+               fi;                                                     \
+       else                                                            \
+               echo '  SYMLINK $@ -> include/asm-$(SRCARCH)';          \
+               if [ ! -d include ]; then                               \
+                       mkdir -p include;                               \
+               fi;                                                     \
+               ln -fsn asm-$(SRCARCH) $@;                              \
+       fi
 
 # Generate some files
 # ---------------------------------------------------------------------------
@@ -1020,19 +1030,12 @@ _modinst_:
        fi
        $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
 
-# If System.map exists, run depmod.  This deliberately does not have a
-# dependency on System.map since that would run the dependency tree on
-# vmlinux.  This depmod is only for convenience to give the initial
+# This depmod is only for convenience to give the initial
 # boot a modules.dep even before / is mounted read-write.  However the
 # boot script depmod is the master version.
-ifeq "$(strip $(INSTALL_MOD_PATH))" ""
-depmod_opts    :=
-else
-depmod_opts    := -b $(INSTALL_MOD_PATH) -r
-endif
 PHONY += _modinst_post
 _modinst_post: _modinst_
-       if [ -r System.map -a -x $(DEPMOD) ]; then $(DEPMOD) -ae -F System.map $(depmod_opts) $(KERNELRELEASE); fi
+       $(call cmd,depmod)
 
 else # CONFIG_MODULES
 
@@ -1220,8 +1223,7 @@ else # KBUILD_EXTMOD
 KBUILD_MODULES := 1
 PHONY += crmodverdir
 crmodverdir:
-       $(Q)mkdir -p $(MODVERDIR)
-       $(Q)rm -f $(MODVERDIR)/*
+       $(cmd_crmodverdir)
 
 PHONY += $(objtree)/Module.symvers
 $(objtree)/Module.symvers:
@@ -1249,15 +1251,6 @@ _emodinst_:
        $(Q)mkdir -p $(MODLIB)/$(install-dir)
        $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
 
-# Run depmod only is we have System.map and depmod is executable
-quiet_cmd_depmod = DEPMOD  $(KERNELRELEASE)
-      cmd_depmod = if [ -r System.map -a -x $(DEPMOD) ]; then \
-                      $(DEPMOD) -ae -F System.map             \
-                      $(if $(strip $(INSTALL_MOD_PATH)),      \
-                     -b $(INSTALL_MOD_PATH) -r)              \
-                     $(KERNELRELEASE);                       \
-                   fi
-
 PHONY += _emodinst_post
 _emodinst_post: _emodinst_
        $(call cmd,depmod)
@@ -1341,7 +1334,7 @@ define find-sources
          find $(__srctree)include/asm-generic $(RCS_FIND_IGNORE) \
               -name $1 -print; \
          find $(__srctree) $(RCS_FIND_IGNORE) \
-              \( -name include -o -name arch \) -prune -o \
+              \( -name include -o -name arch -o -name '.tmp_*' \) -prune -o \
               -name $1 -print; \
          )
 endef
@@ -1490,9 +1483,11 @@ endif
 
 # Modules
 / %/: prepare scripts FORCE
+       $(cmd_crmodverdir)
        $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
        $(build)=$(build-dir)
 %.ko: prepare scripts FORCE
+       $(cmd_crmodverdir)
        $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1)   \
        $(build)=$(build-dir) $(@:.ko=.o)
        $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
@@ -1506,6 +1501,20 @@ quiet_cmd_rmdirs = $(if $(wildcard $(rm-dirs)),CLEAN   $(wildcard $(rm-dirs)))
 quiet_cmd_rmfiles = $(if $(wildcard $(rm-files)),CLEAN   $(wildcard $(rm-files)))
       cmd_rmfiles = rm -f $(rm-files)
 
+# Run depmod only is we have System.map and depmod is executable
+# and we build for the host arch
+quiet_cmd_depmod = DEPMOD  $(KERNELRELEASE)
+      cmd_depmod = \
+       if [ -r System.map -a -x $(DEPMOD) ]; then                              \
+               $(DEPMOD) -ae -F System.map                                     \
+               $(if $(strip $(INSTALL_MOD_PATH)), -b $(INSTALL_MOD_PATH) -r)   \
+               $(KERNELRELEASE);                                               \
+       fi
+
+# Create temporary dir for module support files
+# clean it up only when building all modules
+cmd_crmodverdir = $(Q)mkdir -p $(MODVERDIR) \
+                  $(if $(KBUILD_MODULES),; rm -f $(MODVERDIR)/*)
 
 a_flags = -Wp,-MD,$(depfile) $(KBUILD_AFLAGS) $(AFLAGS_KERNEL) \
          $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \
index 2a85dc33907c2c66f09c3e3ce61e96ef19e23d3a..4c002ba37e5076fe726826e3a2a73deb29d25176 100644 (file)
@@ -654,7 +654,7 @@ source "drivers/Kconfig"
 
 source "fs/Kconfig"
 
-source "arch/alpha/oprofile/Kconfig"
+source "kernel/Kconfig.instrumentation"
 
 source "arch/alpha/Kconfig.debug"
 
index f2956ac8dccc775f60f866a24eadae130333e5fe..497877bf20127daad85ee837ea829eec85c982aa 100644 (file)
@@ -1082,7 +1082,7 @@ marvel_machine_check(u64 vector, u64 la_ptr)
        }       
 
        /*
-        * A system event or error has occured, handle it here.
+        * A system event or error has occurred, handle it here.
         *
         * Any errors in the logout frame have already been cleared by the
         * PALcode, so just parse it.
index 543d96d7fa2b6f32d1629812fc269e149e1677f4..6f3867877d9e451f9e8278094f385d50a0fed660 100644 (file)
@@ -591,7 +591,7 @@ privateer_process_680_frame(struct el_common *mchk_header, int print)
                (struct el_PRIVATEER_envdata_mcheck *)
                ((unsigned long)mchk_header + mchk_header->sys_offset);
 
-       /* TODO - catagorize errors, for now, no error */
+       /* TODO - categorize errors, for now, no error */
 
        if (!print)
                return status;
index ce857158c1eacc2a1b22ac0f6c278a5501d9d42b..6413c5f232264dbc9b165489396dbb6987d42351 100644 (file)
@@ -715,7 +715,7 @@ osf_setsysinfo(unsigned long op, void __user *buffer, unsigned long nbytes,
                /* 
                 * Alpha Architecture Handbook 4.7.7.3:
                 * To be fully IEEE compiant, we must track the current IEEE
-                * exception state in software, because spurrious bits can be
+                * exception state in software, because spurious bits can be
                 * set in the trap shadow of a software-complete insn.
                 */
 
index e1c470752ebc0db7e146c2d544da50496f3076af..2d00a08d3f0811d0f7b819475d6f858828d88496 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/bootmem.h>
+#include <linux/scatterlist.h>
 #include <linux/log2.h>
 
 #include <asm/io.h>
@@ -465,7 +466,7 @@ EXPORT_SYMBOL(pci_free_consistent);
    Write dma_length of each leader with the combined lengths of
    the mergable followers.  */
 
-#define SG_ENT_VIRT_ADDRESS(SG) (page_address((SG)->page) + (SG)->offset)
+#define SG_ENT_VIRT_ADDRESS(SG) (sg_virt((SG)))
 #define SG_ENT_PHYS_ADDRESS(SG) __pa(SG_ENT_VIRT_ADDRESS(SG))
 
 static void
index 8c8aaa205eae123f208163749efaabe4ad2df710..8d2982aa1b8db8f3fdf8fbbf29321cb3b4dea010 100644 (file)
@@ -69,7 +69,7 @@ __down_failed(struct semaphore *sem)
 
 #ifdef CONFIG_DEBUG_SEMAPHORE
        printk("%s(%d): down failed(%p)\n",
-              tsk->comm, tsk->pid, sem);
+              tsk->comm, task_pid_nr(tsk), sem);
 #endif
 
        tsk->state = TASK_UNINTERRUPTIBLE;
@@ -98,7 +98,7 @@ __down_failed(struct semaphore *sem)
 
 #ifdef CONFIG_DEBUG_SEMAPHORE
        printk("%s(%d): down acquired(%p)\n",
-              tsk->comm, tsk->pid, sem);
+              tsk->comm, task_pid_nr(tsk), sem);
 #endif
 }
 
@@ -111,7 +111,7 @@ __down_failed_interruptible(struct semaphore *sem)
 
 #ifdef CONFIG_DEBUG_SEMAPHORE
        printk("%s(%d): down failed(%p)\n",
-              tsk->comm, tsk->pid, sem);
+              tsk->comm, task_pid_nr(tsk), sem);
 #endif
 
        tsk->state = TASK_INTERRUPTIBLE;
@@ -139,7 +139,7 @@ __down_failed_interruptible(struct semaphore *sem)
 
 #ifdef CONFIG_DEBUG_SEMAPHORE
        printk("%s(%d): down %s(%p)\n",
-              current->comm, current->pid,
+              current->comm, task_pid_nr(current),
               (ret < 0 ? "interrupted" : "acquired"), sem);
 #endif
        return ret;
@@ -168,7 +168,7 @@ down(struct semaphore *sem)
 #endif
 #ifdef CONFIG_DEBUG_SEMAPHORE
        printk("%s(%d): down(%p) <count=%d> from %p\n",
-              current->comm, current->pid, sem,
+              current->comm, task_pid_nr(current), sem,
               atomic_read(&sem->count), __builtin_return_address(0));
 #endif
        __down(sem);
@@ -182,7 +182,7 @@ down_interruptible(struct semaphore *sem)
 #endif
 #ifdef CONFIG_DEBUG_SEMAPHORE
        printk("%s(%d): down(%p) <count=%d> from %p\n",
-              current->comm, current->pid, sem,
+              current->comm, task_pid_nr(current), sem,
               atomic_read(&sem->count), __builtin_return_address(0));
 #endif
        return __down_interruptible(sem);
@@ -201,7 +201,7 @@ down_trylock(struct semaphore *sem)
 
 #ifdef CONFIG_DEBUG_SEMAPHORE
        printk("%s(%d): down_trylock %s from %p\n",
-              current->comm, current->pid,
+              current->comm, task_pid_nr(current),
               ret ? "failed" : "acquired",
               __builtin_return_address(0));
 #endif
@@ -217,7 +217,7 @@ up(struct semaphore *sem)
 #endif
 #ifdef CONFIG_DEBUG_SEMAPHORE
        printk("%s(%d): up(%p) <count=%d> from %p\n",
-              current->comm, current->pid, sem,
+              current->comm, task_pid_nr(current), sem,
               atomic_read(&sem->count), __builtin_return_address(0));
 #endif
        __up(sem);
index ad176441be558bcf41d7dfd109913ef77a36fa7d..f4ab233201b296013c7c45511a953838d29226d8 100644 (file)
@@ -439,7 +439,6 @@ setup_smp(void)
                                ((char *)cpubase + i*hwrpb->processor_size);
                        if ((cpu->flags & 0x1cc) == 0x1cc) {
                                smp_num_probed++;
-                               /* Assume here that "whami" == index */
                                cpu_set(i, cpu_present_map);
                                cpu->pal_revision = boot_cpu_palrev;
                        }
index 49bedfbbd31bedc7986f31b6182356d8d2690959..d187d01d2a17b72dc603241c26c85b6cf426d1ad 100644 (file)
@@ -138,7 +138,7 @@ alcor_init_irq(void)
 
        for (i = 16; i < 48; ++i) {
                /* On Alcor, at least, lines 20..30 are not connected
-                  and can generate spurrious interrupts if we turn them
+                  and can generate spurious interrupts if we turn them
                   on while IRQ probing.  */
                if (i >= 16+20 && i <= 16+30)
                        continue;
index 14b5a753aba50ec40bb9a31e38e9824b9beee5a5..ee7b9009ebb4f45c19d50fbf93d0a762769e0154 100644 (file)
@@ -78,7 +78,7 @@ alphabook1_init_arch(void)
  * example, sound boards seem to like using IRQ 9.
  *
  * This is NOT how we should do it. PIRQ0-X should have
- * their own IRQ's, the way intel uses the IO-APIC irq's.
+ * their own IRQs, the way intel uses the IO-APIC IRQs.
  */
 
 static void __init
index ec0f05e0d8ffc169567c0f78cbde1e194b7105db..2dc7f9fed213704749e0e2b7d58e161b909fad7e 100644 (file)
@@ -182,7 +182,7 @@ die_if_kernel(char * str, struct pt_regs *regs, long err, unsigned long *r9_15)
 #ifdef CONFIG_SMP
        printk("CPU %d ", hard_smp_processor_id());
 #endif
-       printk("%s(%d): %s %ld\n", current->comm, current->pid, str, err);
+       printk("%s(%d): %s %ld\n", current->comm, task_pid_nr(current), str, err);
        dik_show_regs(regs, r9_15);
        add_taint(TAINT_DIE);
        dik_show_trace((unsigned long *)(regs+1));
@@ -646,7 +646,7 @@ got_exception:
        lock_kernel();
 
        printk("%s(%d): unhandled unaligned exception\n",
-              current->comm, current->pid);
+              current->comm, task_pid_nr(current));
 
        printk("pc = [<%016lx>]  ra = [<%016lx>]  ps = %04lx\n",
               pc, una_reg(26), regs->ps);
@@ -786,7 +786,7 @@ do_entUnaUser(void __user * va, unsigned long opcode,
                }
                if (++cnt < 5) {
                        printk("%s(%d): unaligned trap at %016lx: %p %lx %ld\n",
-                              current->comm, current->pid,
+                              current->comm, task_pid_nr(current),
                               regs->pc - 4, va, opcode, reg);
                }
                last_time = jiffies;
index 8698e0746f9fd594e4647aed11f6c772dd9885da..199f6efa83faa9d809faec8aab319672dc4eed4f 100644 (file)
@@ -5,7 +5,7 @@
  * in an architecture-specific manner due to speed..
  * Comments in other versions indicate that the algorithms are from RFC1071
  *
- * accellerated versions (and 21264 assembly versions ) contributed by
+ * accelerated versions (and 21264 assembly versions ) contributed by
  *     Rick Gorton     <rick.gorton@alpha-processor.com>
  */
  
index 4ca75c74ce908f99bc7aea0887c73a327e995b44..40736da9bea87aef7d5e43e4af8672d46a58ef9e 100644 (file)
@@ -2,7 +2,7 @@
  * csum_partial_copy - do IP checksumming and copy
  *
  * (C) Copyright 1996 Linus Torvalds
- * accellerated versions (and 21264 assembly versions ) contributed by
+ * accelerated versions (and 21264 assembly versions ) contributed by
  *     Rick Gorton     <rick.gorton@alpha-processor.com>
  *
  * Don't look at this too closely - you'll go mad. The things
index 7ad84ea0acf879e58aac56a5845c0ec8271566a4..32afaa3fa6860e65762a06bcf6b13c961739b12f 100644 (file)
@@ -3,7 +3,7 @@
  */
 
 #include <linux/module.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 
 /* This is fls(x)-1, except zero is held to zero.  This allows most
    efficent input into extbl, plus it allows easy handling of fls(0)=0.  */
index 25154df3055abf7a501db5b5b00255d0bcbb410e..4829f96585b15a1fd59f0409750df4ed59d99d35 100644 (file)
@@ -188,13 +188,13 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
        /* We ran out of memory, or some other thing happened to us that
           made us unable to handle the page fault gracefully.  */
  out_of_memory:
-       if (is_init(current)) {
+       if (is_global_init(current)) {
                yield();
                down_read(&mm->mmap_sem);
                goto survive;
        }
        printk(KERN_ALERT "VM: killing process %s(%d)\n",
-              current->comm, current->pid);
+              current->comm, task_pid_nr(current));
        if (!user_mode(regs))
                goto no_context;
        do_group_exit(SIGKILL);
index 5e6da47779a408afd3392689f434444f81ee2d9a..40c15e7301ded438baa46d83e67fcac06062efd6 100644 (file)
@@ -235,7 +235,7 @@ callback_init(void * kernel_end)
                        unsigned long pfn = crb->map[i].pa >> PAGE_SHIFT;
                        crb->map[i].va = vaddr;
                        for (j = 0; j < crb->map[i].count; ++j) {
-                               /* Newer console's (especially on larger
+                               /* Newer consoles (especially on larger
                                   systems) may require more pages of
                                   PTEs. Grab additional pages as needed. */
                                if (pmd != pmd_offset(pgd, vaddr)) {
diff --git a/arch/alpha/oprofile/Kconfig b/arch/alpha/oprofile/Kconfig
deleted file mode 100644 (file)
index 5ade198..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-
-menu "Profiling support"
-       depends on EXPERIMENTAL
-
-config PROFILING
-       bool "Profiling support (EXPERIMENTAL)"
-       help
-         Say Y here to enable the extended profiling support mechanisms used
-         by profilers such as OProfile.
-         
-
-config OPROFILE
-       tristate "OProfile system profiling (EXPERIMENTAL)"
-       depends on PROFILING
-       help
-         OProfile is a profiling system capable of profiling the
-         whole system, include the kernel, kernel modules, libraries,
-         and applications.
-
-         If unsure, say N.
-
-endmenu
-
index 6b97893c1a80c9547a89985298d874c2c4790f51..b2b87ae9a353a9c3370499592f0858133179d79a 100644 (file)
@@ -38,7 +38,7 @@ struct op_register_config {
        unsigned long need_reset;
 };
 
-/* Per-architecture configury and hooks.  */
+/* Per-architecture configuration and hooks.  */
 struct op_axp_model {
        void (*reg_setup) (struct op_register_config *,
                           struct op_counter_config *,
index 0a0c88d0039ca43a195d2b746fc7b6943aca882b..a0cdaafa115b65accca46e4fdf8a4307d4ee2408 100644 (file)
@@ -851,7 +851,7 @@ config KEXEC
        help
          kexec is a system call that implements the ability to shutdown your
          current kernel, and to start another kernel.  It is like a reboot
-         but it is indepedent of the system firmware.   And like a reboot
+         but it is independent of the system firmware.   And like a reboot
          you can start any kernel with it, not just Linux.
 
          It is an ongoing process to be certain the hardware in a machine
@@ -1068,7 +1068,7 @@ endmenu
 
 source "fs/Kconfig"
 
-source "arch/arm/oprofile/Kconfig"
+source "kernel/Kconfig.instrumentation"
 
 source "arch/arm/Kconfig.debug"
 
index 44ab0dad40357dc83a5bafd305b93589cd71aa67..52fc6a883281120f7c80e2d332247971658b1ffa 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/dmapool.h>
 #include <linux/list.h>
+#include <linux/scatterlist.h>
 
 #include <asm/cacheflush.h>
 
@@ -442,7 +443,7 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
        BUG_ON(dir == DMA_NONE);
 
        for (i = 0; i < nents; i++, sg++) {
-               struct page *page = sg->page;
+               struct page *page = sg_page(sg);
                unsigned int offset = sg->offset;
                unsigned int length = sg->length;
                void *ptr = page_address(page) + offset;
index 111a7fa5debee4ace5a39f1aa5c50b2ab3927683..5bba5255b119dc7ee18d72cc8efc2d8c1d2963c2 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/platform_device.h>
 #include <linux/leds.h>
 #include <linux/apm-emulation.h>
+#include <linux/suspend.h>
 
 #include <asm/hardware.h>
 #include <asm/mach-types.h>
@@ -765,9 +766,9 @@ static void sharpsl_apm_get_power_status(struct apm_power_info *info)
        info->battery_life = sharpsl_pm.battstat.mainbat_percent;
 }
 
-static struct pm_ops sharpsl_pm_ops = {
+static struct platform_suspend_ops sharpsl_pm_ops = {
        .enter          = corgi_pxa_pm_enter,
-       .valid          = pm_valid_only_mem,
+       .valid          = suspend_valid_only_mem,
 };
 
 static int __init sharpsl_pm_probe(struct platform_device *pdev)
@@ -799,7 +800,7 @@ static int __init sharpsl_pm_probe(struct platform_device *pdev)
 
        apm_get_power_status = sharpsl_apm_get_power_status;
 
-       pm_set_ops(&sharpsl_pm_ops);
+       suspend_set_ops(&sharpsl_pm_ops);
 
        mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250));
 
@@ -808,7 +809,7 @@ static int __init sharpsl_pm_probe(struct platform_device *pdev)
 
 static int sharpsl_pm_remove(struct platform_device *pdev)
 {
-       pm_set_ops(NULL);
+       suspend_set_ops(NULL);
 
        device_remove_file(&pdev->dev, &dev_attr_battery_percentage);
        device_remove_file(&pdev->dev, &dev_attr_battery_voltage);
index 93b7f8e22dcc1b3b69aa424c60d0a91bed19f772..4f1a03124a74ae4a543df710a8c3e6af3d0200ad 100644 (file)
@@ -265,7 +265,7 @@ void __show_regs(struct pt_regs *regs)
 void show_regs(struct pt_regs * regs)
 {
        printk("\n");
-       printk("Pid: %d, comm: %20s\n", current->pid, current->comm);
+       printk("Pid: %d, comm: %20s\n", task_pid_nr(current), current->comm);
        __show_regs(regs);
        __backtrace();
 }
index 5feee722ea9878e08a9f6415fe7de8e45d7595f9..4b05dc5c1023666ce6efaa1c684776de98587875 100644 (file)
@@ -382,16 +382,16 @@ static void clear_breakpoint(struct task_struct *task, struct debug_entry *bp)
 
                if (ret != 2 || old_insn.thumb != BREAKINST_THUMB)
                        printk(KERN_ERR "%s:%d: corrupted Thumb breakpoint at "
-                               "0x%08lx (0x%04x)\n", task->comm, task->pid,
-                               addr, old_insn.thumb);
+                               "0x%08lx (0x%04x)\n", task->comm,
+                               task_pid_nr(task), addr, old_insn.thumb);
        } else {
                ret = swap_insn(task, addr & ~3, &old_insn.arm,
                                &bp->insn.arm, 4);
 
                if (ret != 4 || old_insn.arm != BREAKINST_ARM)
                        printk(KERN_ERR "%s:%d: corrupted ARM breakpoint at "
-                               "0x%08lx (0x%08x)\n", task->comm, task->pid,
-                               addr, old_insn.arm);
+                               "0x%08lx (0x%08x)\n", task->comm,
+                               task_pid_nr(task), addr, old_insn.arm);
        }
 }
 
index 8ad47619c07906b31dcd60c97490426f6330e34c..4764bd9ccee801ced5838d9043a5923c9e931cb8 100644 (file)
@@ -223,7 +223,7 @@ static void __die(const char *str, int err, struct thread_info *thread, struct p
        print_modules();
        __show_regs(regs);
        printk("Process %s (pid: %d, stack limit = 0x%p)\n",
-               tsk->comm, tsk->pid, thread + 1);
+               tsk->comm, task_pid_nr(tsk), thread + 1);
 
        if (!user_mode(regs) || in_interrupt()) {
                dump_mem("Stack: ", regs->ARM_sp,
@@ -337,7 +337,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
 #ifdef CONFIG_DEBUG_USER
        if (user_debug & UDBG_UNDEFINED) {
                printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n",
-                       current->comm, current->pid, pc);
+                       current->comm, task_pid_nr(current), pc);
                dump_instr(regs);
        }
 #endif
@@ -388,7 +388,7 @@ static int bad_syscall(int n, struct pt_regs *regs)
 #ifdef CONFIG_DEBUG_USER
        if (user_debug & UDBG_SYSCALL) {
                printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n",
-                       current->pid, current->comm, n);
+                       task_pid_nr(current), current->comm, n);
                dump_instr(regs);
        }
 #endif
@@ -565,7 +565,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
         */
        if (user_debug & UDBG_SYSCALL) {
                printk("[%d] %s: arm syscall %d\n",
-                      current->pid, current->comm, no);
+                      task_pid_nr(current), current->comm, no);
                dump_instr(regs);
                if (user_mode(regs)) {
                        __show_regs(regs);
@@ -642,7 +642,7 @@ baddataabort(int code, unsigned long instr, struct pt_regs *regs)
 #ifdef CONFIG_DEBUG_USER
        if (user_debug & UDBG_BADABORT) {
                printk(KERN_ERR "[%d] %s: bad data abort: code %d instr 0x%08lx\n",
-                       current->pid, current->comm, code, instr);
+                       task_pid_nr(current), current->comm, code, instr);
                dump_instr(regs);
                show_pte(current->mm, addr);
        }
index ba4a1bb3ee4027c8dd51392abe670dd0e2ce3992..aa2d365c93fb65a7bbacd45263b77262b24b4b4a 100644 (file)
@@ -439,7 +439,7 @@ void __init at91_gpio_irq_setup(void)
                for (i = 0; i < 32; i++, pin++) {
                        /*
                         * Can use the "simple" and not "edge" handler since it's
-                        * shorter, and the AIC handles interupts sanely.
+                        * shorter, and the AIC handles interrupts sanely.
                         */
                        set_irq_chip(pin, &gpio_irqchip);
                        set_irq_handler(pin, handle_simple_irq);
index ddf9184d561d2c82d4efe9e5a23ea07c6e62af35..98cb61482917a921d5ddaec2bc13925999097a0b 100644 (file)
  * (at your option) any later version.
  */
 
-#include <linux/pm.h>
+#include <linux/suspend.h>
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
-#include <linux/pm.h>
 #include <linux/interrupt.h>
 #include <linux/sysfs.h>
 #include <linux/module.h>
@@ -199,7 +198,7 @@ error:
 }
 
 
-static struct pm_ops at91_pm_ops ={
+static struct platform_suspend_ops at91_pm_ops ={
        .valid          = at91_pm_valid_state,
        .set_target     = at91_pm_set_target,
        .enter          = at91_pm_enter,
@@ -220,7 +219,7 @@ static int __init at91_pm_init(void)
        /* Disable SDRAM low-power mode.  Cannot be used with self-refresh. */
        at91_sys_write(AT91_SDRAMC_LPR, 0);
 
-       pm_set_ops(&at91_pm_ops);
+       suspend_set_ops(&at91_pm_ops);
 
        return 0;
 }
index 0733078940faabf0703a086199cfd754c63a8a9e..1da9d59a0347049c5959fd48cdfdd36d1407023e 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Copyright (C) 2004 Nokia Corporation
  * Written by Tony Lindgren <tony@atomide.com>
- * Major cleanups by Juha Yrjölä <juha.yrjola@nokia.com>
+ * Major cleanups by Juha Yrjölä <juha.yrjola@nokia.com>
  *
  * Completely re-written to support various OMAP chips with bank specific
  * interrupt handlers.
index 089b8208de0e4b25cb1b1a34a2d2b3a816ad802d..3bf01e28df334ceaaf49dc55c8d4cd59e00c09d4 100644 (file)
  * 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <linux/pm.h>
+#include <linux/suspend.h>
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
-#include <linux/pm.h>
 #include <linux/interrupt.h>
 #include <linux/sysfs.h>
 #include <linux/module.h>
@@ -600,27 +599,15 @@ static void (*saved_idle)(void) = NULL;
 
 /*
  *     omap_pm_prepare - Do preliminary suspend work.
- *     @state:         suspend state we're entering.
  *
  */
-static int omap_pm_prepare(suspend_state_t state)
+static int omap_pm_prepare(void)
 {
-       int error = 0;
-
        /* We cannot sleep in idle until we have resumed */
        saved_idle = pm_idle;
        pm_idle = NULL;
 
-       switch (state)
-       {
-       case PM_SUSPEND_STANDBY:
-       case PM_SUSPEND_MEM:
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return error;
+       return 0;
 }
 
 
@@ -648,16 +635,14 @@ static int omap_pm_enter(suspend_state_t state)
 
 /**
  *     omap_pm_finish - Finish up suspend sequence.
- *     @state:         State we're coming out of.
  *
  *     This is called after we wake back up (or if entering the sleep state
  *     failed).
  */
 
-static int omap_pm_finish(suspend_state_t state)
+static void omap_pm_finish(void)
 {
        pm_idle = saved_idle;
-       return 0;
 }
 
 
@@ -674,11 +659,11 @@ static struct irqaction omap_wakeup_irq = {
 
 
 
-static struct pm_ops omap_pm_ops ={
+static struct platform_suspend_ops omap_pm_ops ={
        .prepare        = omap_pm_prepare,
        .enter          = omap_pm_enter,
        .finish         = omap_pm_finish,
-       .valid          = pm_valid_only_mem,
+       .valid          = suspend_valid_only_mem,
 };
 
 static int __init omap_pm_init(void)
@@ -735,7 +720,7 @@ static int __init omap_pm_init(void)
        else if (cpu_is_omap16xx())
                omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3);
 
-       pm_set_ops(&omap_pm_ops);
+       suspend_set_ops(&omap_pm_ops);
 
 #if defined(DEBUG) && defined(CONFIG_PROC_FS)
        omap_pm_init_proc();
index 6f4a5436d0ce858f33598f3f6fb77800614a6318..baf7d82b458b968b61b1127e646cb17150812c0c 100644 (file)
  * published by the Free Software Foundation.
  */
 
-#include <linux/pm.h>
+#include <linux/suspend.h>
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
-#include <linux/pm.h>
 #include <linux/interrupt.h>
 #include <linux/sysfs.h>
 #include <linux/module.h>
@@ -71,28 +70,12 @@ void omap2_pm_idle(void)
        local_irq_enable();
 }
 
-static int omap2_pm_prepare(suspend_state_t state)
+static int omap2_pm_prepare(void)
 {
-       int error = 0;
-
        /* We cannot sleep in idle until we have resumed */
        saved_idle = pm_idle;
        pm_idle = NULL;
-
-       switch (state)
-       {
-       case PM_SUSPEND_STANDBY:
-       case PM_SUSPEND_MEM:
-               break;
-
-       case PM_SUSPEND_DISK:
-               return -ENOTSUPP;
-
-       default:
-               return -EINVAL;
-       }
-
-       return error;
+       return 0;
 }
 
 #define INT0_WAKE_MASK (OMAP_IRQ_BIT(INT_24XX_GPIO_BANK1) |    \
@@ -353,9 +336,6 @@ static int omap2_pm_enter(suspend_state_t state)
        case PM_SUSPEND_MEM:
                ret = omap2_pm_suspend();
                break;
-       case PM_SUSPEND_DISK:
-               ret = -ENOTSUPP;
-               break;
        default:
                ret = -EINVAL;
        }
@@ -363,17 +343,16 @@ static int omap2_pm_enter(suspend_state_t state)
        return ret;
 }
 
-static int omap2_pm_finish(suspend_state_t state)
+static void omap2_pm_finish(void)
 {
        pm_idle = saved_idle;
-       return 0;
 }
 
-static struct pm_ops omap_pm_ops = {
+static struct platform_suspend_ops omap_pm_ops = {
        .prepare        = omap2_pm_prepare,
        .enter          = omap2_pm_enter,
        .finish         = omap2_pm_finish,
-       .valid          = pm_valid_only_mem,
+       .valid          = suspend_valid_only_mem,
 };
 
 int __init omap2_pm_init(void)
@@ -397,7 +376,7 @@ int __init omap2_pm_init(void)
        omap2_sram_suspend = omap_sram_push(omap24xx_cpu_suspend,
                                            omap24xx_cpu_suspend_sz);
 
-       pm_set_ops(&omap_pm_ops);
+       suspend_set_ops(&omap_pm_ops);
        pm_idle = omap2_pm_idle;
 
        pmdomain_init();
index 62e801ef9ad9ef59ee91e920089b84dbefa8ba56..8d322c20ccaedd0e65f8537d376e2bceae3f42c4 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Copyright (C) 2005 Nokia Corporation
  * Author: Paul Mundt <paul.mundt@nokia.com>
- *         Juha Yrjölä <juha.yrjola@nokia.com>
+ *         Juha Yrjölä <juha.yrjola@nokia.com>
  * OMAP Dual-mode timer framework support by Timo Teras
  *
  * Some parts based off of TI's 24xx code:
index 2a137f33f752698daac232049e4fcd3309d30581..40116d2543496c284af73a8fde5d94c789951cd5 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/rtc.h>
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
-#include <linux/pm.h>
+#include <linux/suspend.h>
 #include <linux/delay.h>
 #include <linux/clk.h>
 
@@ -117,7 +117,7 @@ static int pnx4008_pm_valid(suspend_state_t state)
               (state == PM_SUSPEND_MEM);
 }
 
-static struct pm_ops pnx4008_pm_ops = {
+static struct platform_suspend_ops pnx4008_pm_ops = {
        .enter = pnx4008_pm_enter,
        .valid = pnx4008_pm_valid,
 };
@@ -146,7 +146,7 @@ static int __init pnx4008_pm_init(void)
                return -ENOMEM;
        }
 
-       pm_set_ops(&pnx4008_pm_ops);
+       suspend_set_ops(&pnx4008_pm_ops);
        return 0;
 }
 
index b59a81a8e7d32d35d1ad9c3b1ce4cc833bf7eb7b..a941c71c7d06cb36be51c43dfb3f456da7c344b9 100644 (file)
@@ -86,7 +86,7 @@ static int pxa_pm_valid(suspend_state_t state)
        return -EINVAL;
 }
 
-static struct pm_ops pxa_pm_ops = {
+static struct platform_suspend_ops pxa_pm_ops = {
        .valid          = pxa_pm_valid,
        .enter          = pxa_pm_enter,
 };
@@ -104,7 +104,7 @@ static int __init pxa_pm_init(void)
                return -ENOMEM;
        }
 
-       pm_set_ops(&pxa_pm_ops);
+       suspend_set_ops(&pxa_pm_ops);
        return 0;
 }
 
index 0d6a72504caa2cf67e97a0365bffd870d94404c9..dcd81f8d0833f28da844c3e468bf89ea8becfa40 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/pm.h>
+#include <linux/suspend.h>
 
 #include <asm/hardware.h>
 #include <asm/arch/irqs.h>
@@ -215,7 +215,7 @@ static void pxa25x_cpu_pm_enter(suspend_state_t state)
 
 static struct pxa_cpu_pm_fns pxa25x_cpu_pm_fns = {
        .save_size      = SLEEP_SAVE_SIZE,
-       .valid          = pm_valid_only_mem,
+       .valid          = suspend_valid_only_mem,
        .save           = pxa25x_cpu_pm_save,
        .restore        = pxa25x_cpu_pm_restore,
        .enter          = pxa25x_cpu_pm_enter,
index 2d7fc39732e444a7aa981dd63f0a8de3a3aed5bd..d0f2b597db12541ae15514dcf86d8e8d479e8490 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/pm.h>
+#include <linux/suspend.h>
 #include <linux/platform_device.h>
 
 #include <asm/hardware.h>
index cab9d6265e9ee513d37cae781a89e068721df398..2bfaa61020254e3e1db8cc6ebee26a8450edec33 100644 (file)
@@ -238,7 +238,7 @@ int __init s3c2410_baseclk_add(void)
        }
 
        /* We must be careful disabling the clocks we are not intending to
-        * be using at boot time, as subsytems such as the LCD which do
+        * be using at boot time, as subsystems such as the LCD which do
         * their own DMA requests to the bus can cause the system to lockup
         * if they where in the middle of requesting bus access.
         *
index 8543dd6df391e17cbeb895beef52af22b0091fb9..458993601897044244a767bc357f21e0f1d183b1 100644 (file)
@@ -689,7 +689,7 @@ int __init s3c2412_baseclk_add(void)
        }
 
        /* We must be careful disabling the clocks we are not intending to
-        * be using at boot time, as subsytems such as the LCD which do
+        * be using at boot time, as subsystems such as the LCD which do
         * their own DMA requests to the bus can cause the system to lockup
         * if they where in the middle of requesting bus access.
         *
index 58402948c47cd6c9a7099ef1ec233577ed18f833..b42f956738d0fa3620051a5f36bf543c0723fffc 100644 (file)
@@ -1005,7 +1005,7 @@ void __init s3c2443_init_clocks(int xtal)
        }
 
        /* We must be careful disabling the clocks we are not intending to
-        * be using at boot time, as subsytems such as the LCD which do
+        * be using at boot time, as subsystems such as the LCD which do
         * their own DMA requests to the bus can cause the system to lockup
         * if they where in the middle of requesting bus access.
         *
index 01a37d3c0727de0c631dcbcd5e9c5378433c2946..246c573e7252dc0d833f1325222809bd1782e36d 100644 (file)
@@ -122,14 +122,14 @@ unsigned long sleep_phys_sp(void *sp)
        return virt_to_phys(sp);
 }
 
-static struct pm_ops sa11x0_pm_ops = {
+static struct platform_suspend_ops sa11x0_pm_ops = {
        .enter          = sa11x0_pm_enter,
-       .valid          = pm_valid_only_mem,
+       .valid          = suspend_valid_only_mem,
 };
 
 static int __init sa11x0_pm_init(void)
 {
-       pm_set_ops(&sa11x0_pm_ops);
+       suspend_set_ops(&sa11x0_pm_ops);
        return 0;
 }
 
index 074b7cb0774349d6a51e7c4d210e472a892c4e01..e162cca5917fb21c72e29ae127da355c36e7cd27 100644 (file)
@@ -757,7 +757,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
        if (ai_usermode & 1)
                printk("Alignment trap: %s (%d) PC=0x%08lx Instr=0x%0*lx "
                       "Address=0x%08lx FSR 0x%03x\n", current->comm,
-                       current->pid, instrptr,
+                       task_pid_nr(current), instrptr,
                        thumb_mode(regs) ? 4 : 8,
                        thumb_mode(regs) ? tinstr : instr,
                        addr, fsr);
index 59ed1d05b71bf6d858e515d928da4ad102276d91..a8a7dab757eb4977bfc88201da37dfe85713cdbc 100644 (file)
@@ -197,7 +197,7 @@ survive:
        return fault;
 
 out_of_memory:
-       if (!is_init(tsk))
+       if (!is_global_init(tsk))
                goto out;
 
        /*
index ec78e3517fc9fccb55a560e26b389b9c9b95f4a4..786e4c96156dcea95429d0ebca6fd9c0c2bfad23 100644 (file)
@@ -78,11 +78,11 @@ TABLE 1
 +-------------------------+---+---+---------+---------+
 |  Precision              | u | v | FPSR.EP | length  |
 +-------------------------+---+---+---------+---------+
-| Single                  | 0 ü 0 |    x    | 1 words |
-| Double                  | 1 ü 1 |    x    | 2 words |
-| Extended                | 1 ü 1 |    x    | 3 words |
-| Packed decimal          | 1 ü 1 |    0    | 3 words |
-| Expanded packed decimal | 1 ü 1 |    1    | 4 words |
+| Single                  | 0 | 0 |    x    | 1 words |
+| Double                  | 1 | 1 |    x    | 2 words |
+| Extended                | 1 | 1 |    x    | 3 words |
+| Packed decimal          | 1 | 1 |    0    | 3 words |
+| Expanded packed decimal | 1 | 1 |    1    | 4 words |
 +-------------------------+---+---+---------+---------+
 Note: x = don't care
 */
@@ -92,10 +92,10 @@ TABLE 2
 +---+---+---------------------------------+
 | w | x | Number of registers to transfer |
 +---+---+---------------------------------+
-| 0 ü 1 |  1                              |
-| 1 ü 0 |  2                              |
-| 1 ü 1 |  3                              |
-| 0 ü 0 |  4                              |
+| 0 | 1 |  1                              |
+| 1 | 0 |  2                              |
+| 1 | 1 |  3                              |
+| 0 | 0 |  4                              |
 +---+---+---------------------------------+
 */
 
@@ -156,10 +156,10 @@ TABLE 5
 +-------------------------+---+---+
 |  Rounding Precision     | e | f |
 +-------------------------+---+---+
-| IEEE Single precision   | 0 ü 0 |
-| IEEE Double precision   | 0 ü 1 |
-| IEEE Extended precision | 1 ü 0 |
-| undefined (trap)        | 1 ü 1 |
+| IEEE Single precision   | 0 | 0 |
+| IEEE Double precision   | 0 | 1 |
+| IEEE Extended precision | 1 | 0 |
+| undefined (trap)        | 1 | 1 |
 +-------------------------+---+---+
 */
 
@@ -168,10 +168,10 @@ TABLE 5
 +---------------------------------+---+---+
 |  Rounding Mode                  | g | h |
 +---------------------------------+---+---+
-| Round to nearest (default)      | 0 ü 0 |
-| Round toward plus infinity      | 0 ü 1 |
-| Round toward negative infinity  | 1 ü 0 |
-| Round toward zero               | 1 ü 1 |
+| Round to nearest (default)      | 0 | 0 |
+| Round toward plus infinity      | 0 | 1 |
+| Round toward negative infinity  | 1 | 0 |
+| Round toward zero               | 1 | 1 |
 +---------------------------------+---+---+
 */
 
@@ -369,20 +369,20 @@ TABLE 5
 #define getRoundingMode(opcode)                ((opcode & MASK_ROUNDING_MODE) >> 5)
 
 #ifdef CONFIG_FPE_NWFPE_XP
-static inline __attribute_pure__ floatx80 getExtendedConstant(const unsigned int nIndex)
+static inline floatx80 __pure getExtendedConstant(const unsigned int nIndex)
 {
        extern const floatx80 floatx80Constant[];
        return floatx80Constant[nIndex];
 }
 #endif
 
-static inline __attribute_pure__ float64 getDoubleConstant(const unsigned int nIndex)
+static inline float64 __pure getDoubleConstant(const unsigned int nIndex)
 {
        extern const float64 float64Constant[];
        return float64Constant[nIndex];
 }
 
-static inline __attribute_pure__ float32 getSingleConstant(const unsigned int nIndex)
+static inline float32 __pure getSingleConstant(const unsigned int nIndex)
 {
        extern const float32 float32Constant[];
        return float32Constant[nIndex];
diff --git a/arch/arm/oprofile/Kconfig b/arch/arm/oprofile/Kconfig
deleted file mode 100644 (file)
index afd93ad..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-
-menu "Profiling support"
-       depends on EXPERIMENTAL
-
-config PROFILING
-       bool "Profiling support (EXPERIMENTAL)"
-       help
-         Say Y here to enable the extended profiling support mechanisms used
-         by profilers such as OProfile.
-
-
-config OPROFILE
-       tristate "OProfile system profiling (EXPERIMENTAL)"
-       depends on PROFILING
-       help
-         OProfile is a profiling system capable of profiling the
-         whole system, include the kernel, kernel modules, libraries,
-         and applications.
-
-         If unsure, say N.
-
-if OPROFILE
-
-config OPROFILE_ARMV6
-       bool
-       depends on CPU_V6 && !SMP
-       default y
-       select OPROFILE_ARM11_CORE
-
-config OPROFILE_MPCORE
-       bool
-       depends on CPU_V6 && SMP
-       default y
-       select OPROFILE_ARM11_CORE
-
-config OPROFILE_ARM11_CORE
-       bool
-
-endif
-
-endmenu
-
index 05a38498cbe06c3527260a12186fda3d2732a7fc..dcbba07cf98aad648367b62b5d47bc2ba51b52e2 100644 (file)
@@ -2,7 +2,7 @@
  * linux/arch/arm/plat-omap/dma.c
  *
  * Copyright (C) 2003 Nokia Corporation
- * Author: Juha Yrjölä <juha.yrjola@nokia.com>
+ * Author: Juha Yrjölä <juha.yrjola@nokia.com>
  * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
  * Graphics DMA and LCD DMA graphics tranformations
  * by Imre Deak <imre.deak@nokia.com>
index 337455dfe64d493e64746d62caf38e7d169e71d2..6097753394adaef923105fe47a6b6237fc1a27f7 100644 (file)
@@ -4,7 +4,7 @@
  * Support functions for OMAP GPIO
  *
  * Copyright (C) 2003-2005 Nokia Corporation
- * Written by Juha Yrjölä <juha.yrjola@nokia.com>
+ * Written by Juha Yrjölä <juha.yrjola@nokia.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
index eab1850616d860ef5488cbc4f5c489d0f763da49..4fdb3117744fe1f543f1ee78aa3f7df9fb81b237 100644 (file)
@@ -612,9 +612,9 @@ static int s3c2410_pm_enter(suspend_state_t state)
        return 0;
 }
 
-static struct pm_ops s3c2410_pm_ops = {
+static struct platform_suspend_ops s3c2410_pm_ops = {
        .enter          = s3c2410_pm_enter,
-       .valid          = pm_valid_only_mem,
+       .valid          = suspend_valid_only_mem,
 };
 
 /* s3c2410_pm_init
@@ -628,6 +628,6 @@ int __init s3c2410_pm_init(void)
 {
        printk("S3C2410 Power Management, (c) 2004 Simtec Electronics\n");
 
-       pm_set_ops(&s3c2410_pm_ops);
+       suspend_set_ops(&s3c2410_pm_ops);
        return 0;
 }
index d12346aaa88bdb19a76c54f1bd876657571271fa..bbecbd8469b59a449b6d525c1bc0725f81b7da29 100644 (file)
@@ -189,7 +189,7 @@ config CMDLINE
 
 endmenu
 
-menu "Power managment options"
+menu "Power management options"
 
 menu "CPU Frequency scaling"
 
index 6b9e466104ad04d8c5be831774a937931eb298e3..5be0d13f4b03c53d8d843d9a698b885361d98bc0 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/spi/spi.h>
+#include <linux/spi/at73c213.h>
 
 #include <video/atmel_lcdc.h>
 
@@ -48,8 +49,27 @@ static struct eth_platform_data __initdata eth_data[2] = {
        },
 };
 
+#ifndef CONFIG_BOARD_ATSTK1002_SW1_CUSTOM
+#ifndef CONFIG_BOARD_ATSTK1002_SW3_CUSTOM
+static struct at73c213_board_info at73c213_data = {
+       .ssc_id         = 0,
+       .shortname      = "AVR32 STK1000 external DAC",
+};
+#endif
+#endif
+
 #ifndef CONFIG_BOARD_ATSTK1002_SW1_CUSTOM
 static struct spi_board_info spi0_board_info[] __initdata = {
+#ifndef CONFIG_BOARD_ATSTK1002_SW3_CUSTOM
+       {
+               /* AT73C213 */
+               .modalias       = "at73c213",
+               .max_speed_hz   = 200000,
+               .chip_select    = 0,
+               .mode           = SPI_MODE_1,
+               .platform_data  = &at73c213_data,
+       },
+#endif
        {
                /* QVGA display */
                .modalias       = "ltv350qv",
@@ -180,6 +200,38 @@ static void setup_j2_leds(void)
 }
 #endif
 
+#ifndef CONFIG_BOARD_ATSTK1002_SW1_CUSTOM
+#ifndef CONFIG_BOARD_ATSTK1002_SW3_CUSTOM
+static void __init at73c213_set_clk(struct at73c213_board_info *info)
+{
+       struct clk *gclk;
+       struct clk *pll;
+
+       gclk = clk_get(NULL, "gclk0");
+       if (IS_ERR(gclk))
+               goto err_gclk;
+       pll = clk_get(NULL, "pll0");
+       if (IS_ERR(pll))
+               goto err_pll;
+
+       if (clk_set_parent(gclk, pll)) {
+               pr_debug("STK1000: failed to set pll0 as parent for DAC clock\n");
+               goto err_set_clk;
+       }
+
+       at32_select_periph(GPIO_PIN_PA(30), GPIO_PERIPH_A, 0);
+       info->dac_clk = gclk;
+
+err_set_clk:
+       clk_put(pll);
+err_pll:
+       clk_put(gclk);
+err_gclk:
+       return;
+}
+#endif
+#endif
+
 void __init setup_board(void)
 {
 #ifdef CONFIG_BOARD_ATSTK1002_SW2_CUSTOM
@@ -248,6 +300,12 @@ static int __init atstk1002_init(void)
 
        setup_j2_leds();
 
+#ifndef CONFIG_BOARD_ATSTK1002_SW3_CUSTOM
+#ifndef CONFIG_BOARD_ATSTK1002_SW1_CUSTOM
+       at73c213_set_clk(&at73c213_data);
+#endif
+#endif
+
        return 0;
 }
 postcore_initcall(atstk1002_init);
index 9a73ce7eb50fb1da8e6c04ca41c327108b602b6f..8a7caf8e7b454da39a915426a1d7ea363faf361f 100644 (file)
@@ -89,7 +89,7 @@ void _exception(long signr, struct pt_regs *regs, int code,
         * generate the same exception over and over again and we get
         * nowhere.  Better to kill it and let the kernel panic.
         */
-       if (is_init(current)) {
+       if (is_global_init(current)) {
                __sighandler_t handler;
 
                spin_lock_irq(&current->sighand->siglock);
index f6d154ca4d24ebdd91c2fa1fef37d15a25184777..a9d9ec081e3d7b8c729dfff3100ca3f2bc5f2b45 100644 (file)
@@ -556,6 +556,17 @@ static struct clk pico_clk = {
        .users          = 1,
 };
 
+static struct resource dmaca0_resource[] = {
+       {
+               .start  = 0xff200000,
+               .end    = 0xff20ffff,
+               .flags  = IORESOURCE_MEM,
+       },
+       IRQ(2),
+};
+DEFINE_DEV(dmaca, 0);
+DEV_CLK(hclk, dmaca0, hsb, 10);
+
 /* --------------------------------------------------------------------
  * HMATRIX
  * -------------------------------------------------------------------- */
@@ -655,6 +666,7 @@ void __init at32_add_system_devices(void)
        platform_device_register(&at32_eic0_device);
        platform_device_register(&smc0_device);
        platform_device_register(&pdc_device);
+       platform_device_register(&dmaca0_device);
 
        platform_device_register(&at32_systc0_device);
 
@@ -959,6 +971,96 @@ at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n)
        return pdev;
 }
 
+/* --------------------------------------------------------------------
+ *  TWI
+ * -------------------------------------------------------------------- */
+static struct resource atmel_twi0_resource[] __initdata = {
+       PBMEM(0xffe00800),
+       IRQ(5),
+};
+static struct clk atmel_twi0_pclk = {
+       .name           = "twi_pclk",
+       .parent         = &pba_clk,
+       .mode           = pba_clk_mode,
+       .get_rate       = pba_clk_get_rate,
+       .index          = 2,
+};
+
+struct platform_device *__init at32_add_device_twi(unsigned int id)
+{
+       struct platform_device *pdev;
+
+       if (id != 0)
+               return NULL;
+
+       pdev = platform_device_alloc("atmel_twi", id);
+       if (!pdev)
+               return NULL;
+
+       if (platform_device_add_resources(pdev, atmel_twi0_resource,
+                               ARRAY_SIZE(atmel_twi0_resource)))
+               goto err_add_resources;
+
+       select_peripheral(PA(6),  PERIPH_A, 0); /* SDA  */
+       select_peripheral(PA(7),  PERIPH_A, 0); /* SDL  */
+
+       atmel_twi0_pclk.dev = &pdev->dev;
+
+       platform_device_add(pdev);
+       return pdev;
+
+err_add_resources:
+       platform_device_put(pdev);
+       return NULL;
+}
+
+/* --------------------------------------------------------------------
+ * MMC
+ * -------------------------------------------------------------------- */
+static struct resource atmel_mci0_resource[] __initdata = {
+       PBMEM(0xfff02400),
+       IRQ(28),
+};
+static struct clk atmel_mci0_pclk = {
+       .name           = "mci_clk",
+       .parent         = &pbb_clk,
+       .mode           = pbb_clk_mode,
+       .get_rate       = pbb_clk_get_rate,
+       .index          = 9,
+};
+
+struct platform_device *__init at32_add_device_mci(unsigned int id)
+{
+       struct platform_device *pdev;
+
+       if (id != 0)
+               return NULL;
+
+       pdev = platform_device_alloc("atmel_mci", id);
+       if (!pdev)
+               return NULL;
+
+       if (platform_device_add_resources(pdev, atmel_mci0_resource,
+                               ARRAY_SIZE(atmel_mci0_resource)))
+               goto err_add_resources;
+
+       select_peripheral(PA(10), PERIPH_A, 0); /* CLK   */
+       select_peripheral(PA(11), PERIPH_A, 0); /* CMD   */
+       select_peripheral(PA(12), PERIPH_A, 0); /* DATA0 */
+       select_peripheral(PA(13), PERIPH_A, 0); /* DATA1 */
+       select_peripheral(PA(14), PERIPH_A, 0); /* DATA2 */
+       select_peripheral(PA(15), PERIPH_A, 0); /* DATA3 */
+
+       atmel_mci0_pclk.dev = &pdev->dev;
+
+       platform_device_add(pdev);
+       return pdev;
+
+err_add_resources:
+       platform_device_put(pdev);
+       return NULL;
+}
+
 /* --------------------------------------------------------------------
  *  LCDC
  * -------------------------------------------------------------------- */
@@ -1227,6 +1329,241 @@ out_free_pdev:
        return NULL;
 }
 
+/* --------------------------------------------------------------------
+ * IDE / CompactFlash
+ * -------------------------------------------------------------------- */
+static struct resource at32_smc_cs4_resource[] __initdata = {
+       {
+               .start  = 0x04000000,
+               .end    = 0x07ffffff,
+               .flags  = IORESOURCE_MEM,
+       },
+       IRQ(~0UL), /* Magic IRQ will be overridden */
+};
+static struct resource at32_smc_cs5_resource[] __initdata = {
+       {
+               .start  = 0x20000000,
+               .end    = 0x23ffffff,
+               .flags  = IORESOURCE_MEM,
+       },
+       IRQ(~0UL), /* Magic IRQ will be overridden */
+};
+
+static int __init at32_init_ide_or_cf(struct platform_device *pdev,
+               unsigned int cs, unsigned int extint)
+{
+       static unsigned int extint_pin_map[4] __initdata = {
+               GPIO_PIN_PB(25),
+               GPIO_PIN_PB(26),
+               GPIO_PIN_PB(27),
+               GPIO_PIN_PB(28),
+       };
+       static bool common_pins_initialized __initdata = false;
+       unsigned int extint_pin;
+       int ret;
+
+       if (extint >= ARRAY_SIZE(extint_pin_map))
+               return -EINVAL;
+       extint_pin = extint_pin_map[extint];
+
+       switch (cs) {
+       case 4:
+               ret = platform_device_add_resources(pdev,
+                               at32_smc_cs4_resource,
+                               ARRAY_SIZE(at32_smc_cs4_resource));
+               if (ret)
+                       return ret;
+
+               select_peripheral(PE(21), PERIPH_A, 0); /* NCS4   -> OE_N  */
+               set_ebi_sfr_bits(HMATRIX_BIT(CS4A));
+               break;
+       case 5:
+               ret = platform_device_add_resources(pdev,
+                               at32_smc_cs5_resource,
+                               ARRAY_SIZE(at32_smc_cs5_resource));
+               if (ret)
+                       return ret;
+
+               select_peripheral(PE(22), PERIPH_A, 0); /* NCS5   -> OE_N  */
+               set_ebi_sfr_bits(HMATRIX_BIT(CS5A));
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       if (!common_pins_initialized) {
+               select_peripheral(PE(19), PERIPH_A, 0); /* CFCE1  -> CS0_N */
+               select_peripheral(PE(20), PERIPH_A, 0); /* CFCE2  -> CS1_N */
+               select_peripheral(PE(23), PERIPH_A, 0); /* CFRNW  -> DIR   */
+               select_peripheral(PE(24), PERIPH_A, 0); /* NWAIT  <- IORDY */
+               common_pins_initialized = true;
+       }
+
+       at32_select_periph(extint_pin, GPIO_PERIPH_A, AT32_GPIOF_DEGLITCH);
+
+       pdev->resource[1].start = EIM_IRQ_BASE + extint;
+       pdev->resource[1].end = pdev->resource[1].start;
+
+       return 0;
+}
+
+struct platform_device *__init
+at32_add_device_ide(unsigned int id, unsigned int extint,
+                   struct ide_platform_data *data)
+{
+       struct platform_device *pdev;
+
+       pdev = platform_device_alloc("at32_ide", id);
+       if (!pdev)
+               goto fail;
+
+       if (platform_device_add_data(pdev, data,
+                               sizeof(struct ide_platform_data)))
+               goto fail;
+
+       if (at32_init_ide_or_cf(pdev, data->cs, extint))
+               goto fail;
+
+       platform_device_add(pdev);
+       return pdev;
+
+fail:
+       platform_device_put(pdev);
+       return NULL;
+}
+
+struct platform_device *__init
+at32_add_device_cf(unsigned int id, unsigned int extint,
+                   struct cf_platform_data *data)
+{
+       struct platform_device *pdev;
+
+       pdev = platform_device_alloc("at32_cf", id);
+       if (!pdev)
+               goto fail;
+
+       if (platform_device_add_data(pdev, data,
+                               sizeof(struct cf_platform_data)))
+               goto fail;
+
+       if (at32_init_ide_or_cf(pdev, data->cs, extint))
+               goto fail;
+
+       if (data->detect_pin != GPIO_PIN_NONE)
+               at32_select_gpio(data->detect_pin, AT32_GPIOF_DEGLITCH);
+       if (data->reset_pin != GPIO_PIN_NONE)
+               at32_select_gpio(data->reset_pin, 0);
+       if (data->vcc_pin != GPIO_PIN_NONE)
+               at32_select_gpio(data->vcc_pin, 0);
+       /* READY is used as extint, so we can't select it as gpio */
+
+       platform_device_add(pdev);
+       return pdev;
+
+fail:
+       platform_device_put(pdev);
+       return NULL;
+}
+
+/* --------------------------------------------------------------------
+ * AC97C
+ * -------------------------------------------------------------------- */
+static struct resource atmel_ac97c0_resource[] __initdata = {
+       PBMEM(0xfff02800),
+       IRQ(29),
+};
+static struct clk atmel_ac97c0_pclk = {
+       .name           = "pclk",
+       .parent         = &pbb_clk,
+       .mode           = pbb_clk_mode,
+       .get_rate       = pbb_clk_get_rate,
+       .index          = 10,
+};
+
+struct platform_device *__init at32_add_device_ac97c(unsigned int id)
+{
+       struct platform_device *pdev;
+
+       if (id != 0)
+               return NULL;
+
+       pdev = platform_device_alloc("atmel_ac97c", id);
+       if (!pdev)
+               return NULL;
+
+       if (platform_device_add_resources(pdev, atmel_ac97c0_resource,
+                               ARRAY_SIZE(atmel_ac97c0_resource)))
+               goto err_add_resources;
+
+       select_peripheral(PB(20), PERIPH_B, 0); /* SYNC */
+       select_peripheral(PB(21), PERIPH_B, 0); /* SDO  */
+       select_peripheral(PB(22), PERIPH_B, 0); /* SDI  */
+       select_peripheral(PB(23), PERIPH_B, 0); /* SCLK */
+
+       atmel_ac97c0_pclk.dev = &pdev->dev;
+
+       platform_device_add(pdev);
+       return pdev;
+
+err_add_resources:
+       platform_device_put(pdev);
+       return NULL;
+}
+
+/* --------------------------------------------------------------------
+ * ABDAC
+ * -------------------------------------------------------------------- */
+static struct resource abdac0_resource[] __initdata = {
+       PBMEM(0xfff02000),
+       IRQ(27),
+};
+static struct clk abdac0_pclk = {
+       .name           = "pclk",
+       .parent         = &pbb_clk,
+       .mode           = pbb_clk_mode,
+       .get_rate       = pbb_clk_get_rate,
+       .index          = 8,
+};
+static struct clk abdac0_sample_clk = {
+       .name           = "sample_clk",
+       .mode           = genclk_mode,
+       .get_rate       = genclk_get_rate,
+       .set_rate       = genclk_set_rate,
+       .set_parent     = genclk_set_parent,
+       .index          = 6,
+};
+
+struct platform_device *__init at32_add_device_abdac(unsigned int id)
+{
+       struct platform_device *pdev;
+
+       if (id != 0)
+               return NULL;
+
+       pdev = platform_device_alloc("abdac", id);
+       if (!pdev)
+               return NULL;
+
+       if (platform_device_add_resources(pdev, abdac0_resource,
+                               ARRAY_SIZE(abdac0_resource)))
+               goto err_add_resources;
+
+       select_peripheral(PB(20), PERIPH_A, 0); /* DATA1        */
+       select_peripheral(PB(21), PERIPH_A, 0); /* DATA0        */
+       select_peripheral(PB(22), PERIPH_A, 0); /* DATAN1       */
+       select_peripheral(PB(23), PERIPH_A, 0); /* DATAN0       */
+
+       abdac0_pclk.dev = &pdev->dev;
+       abdac0_sample_clk.dev = &pdev->dev;
+
+       platform_device_add(pdev);
+       return pdev;
+
+err_add_resources:
+       platform_device_put(pdev);
+       return NULL;
+}
+
 /* --------------------------------------------------------------------
  *  GCLK
  * -------------------------------------------------------------------- */
@@ -1290,6 +1627,7 @@ struct clk *at32_clock_list[] = {
        &smc0_mck,
        &pdc_hclk,
        &pdc_pclk,
+       &dmaca0_hclk,
        &pico_clk,
        &pio0_mck,
        &pio1_mck,
@@ -1307,6 +1645,8 @@ struct clk *at32_clock_list[] = {
        &macb1_pclk,
        &atmel_spi0_spi_clk,
        &atmel_spi1_spi_clk,
+       &atmel_twi0_pclk,
+       &atmel_mci0_pclk,
        &atmel_lcdfb0_hck1,
        &atmel_lcdfb0_pixclk,
        &ssc0_pclk,
@@ -1314,6 +1654,9 @@ struct clk *at32_clock_list[] = {
        &ssc2_pclk,
        &usba0_hclk,
        &usba0_pclk,
+       &atmel_ac97c0_pclk,
+       &abdac0_pclk,
+       &abdac0_sample_clk,
        &gclk0,
        &gclk1,
        &gclk2,
@@ -1355,6 +1698,7 @@ void __init at32_clock_init(void)
        genclk_init_parent(&gclk3);
        genclk_init_parent(&gclk4);
        genclk_init_parent(&atmel_lcdfb0_pixclk);
+       genclk_init_parent(&abdac0_sample_clk);
 
        /*
         * Turn on all clocks that have at least one user already, and
index 8acd010900313af2194ea5652be7c5abde1b83bd..f5bfd4c81fe70b883fdd620fdd5796fdb41328e3 100644 (file)
@@ -142,7 +142,7 @@ static int eic_set_irq_type(unsigned int irq, unsigned int flow_type)
        return ret;
 }
 
-struct irq_chip eic_chip = {
+static struct irq_chip eic_chip = {
        .name           = "eic",
        .ack            = eic_ack_irq,
        .mask           = eic_mask_irq,
index 47efd0d1951f41d86c21ddaae1c4c318a75efa08..694d521edc2ffcb91e47eeb6a96037d2f0e2ce12 100644 (file)
 
 /* Register access macros */
 #define pm_readl(reg)                                                  \
-       __raw_readl((void __iomem *)AT32_PM_BASE + PM_##reg)
+       __raw_readl((void __iomem __force *)AT32_PM_BASE + PM_##reg)
 #define pm_writel(reg,value)                                           \
-       __raw_writel((value), (void __iomem *)AT32_PM_BASE + PM_##reg)
+       __raw_writel((value), (void __iomem __force *)AT32_PM_BASE + PM_##reg)
 
 #endif /* __ARCH_AVR32_MACH_AT32AP_PM_H__ */
index e3070bdd4bb960b03aabcc31e56403dfb981f3bf..10265863c9822b1ec37600d84548136976a73462 100644 (file)
@@ -79,7 +79,7 @@ static int avr32_timer_calc_div_and_set_jiffies(struct clk *pclk)
 {
        unsigned int cycles_max = (clocksource_avr32.mask + 1) / 2;
        unsigned int divs[] = { 4, 8, 16, 32 };
-       int divs_size = sizeof(divs) / sizeof(*divs);
+       int divs_size = ARRAY_SIZE(divs);
        int i = 0;
        unsigned long count_hz;
        unsigned long shift;
index 11472f8701bdf4a88202d81e723efef38208e743..6560cb18b4e3403e498cb9076ea7025b61cbb2d0 100644 (file)
@@ -160,7 +160,7 @@ bad_area:
                if (exception_trace && printk_ratelimit())
                        printk("%s%s[%d]: segfault at %08lx pc %08lx "
                               "sp %08lx ecr %lu\n",
-                              is_init(tsk) ? KERN_EMERG : KERN_INFO,
+                              is_global_init(tsk) ? KERN_EMERG : KERN_INFO,
                               tsk->comm, tsk->pid, address, regs->pc,
                               regs->sp, ecr);
                _exception(SIGSEGV, regs, code, address);
@@ -209,7 +209,7 @@ no_context:
         */
 out_of_memory:
        up_read(&mm->mmap_sem);
-       if (is_init(current)) {
+       if (is_global_init(current)) {
                yield();
                down_read(&mm->mmap_sem);
                goto survive;
@@ -231,7 +231,7 @@ do_sigbus:
        if (exception_trace)
                printk("%s%s[%d]: bus error at %08lx pc %08lx "
                       "sp %08lx ecr %lu\n",
-                      is_init(tsk) ? KERN_EMERG : KERN_INFO,
+                      is_global_init(tsk) ? KERN_EMERG : KERN_INFO,
                       tsk->comm, tsk->pid, address, regs->pc,
                       regs->sp, ecr);
 
index aa9db3073312c2d8c18ce1726e492a4f4eb61e3a..7888551ed93992163438f5e0b56173b09d282a0e 100644 (file)
@@ -71,7 +71,7 @@ config GENERIC_CALIBRATE_DELAY
 
 config IRQCHIP_DEMUX_GPIO
        bool
-       depends on (BF53x || BF561 || BF54x)
+       depends on (BF52x || BF53x || BF561 || BF54x)
        default y
 
 source "init/Kconfig"
@@ -85,6 +85,21 @@ choice
        prompt "CPU"
        default BF533
 
+config BF522
+       bool "BF522"
+       help
+         BF522 Processor Support.
+
+config BF525
+       bool "BF525"
+       help
+         BF525 Processor Support.
+
+config BF527
+       bool "BF527"
+       help
+         BF527 Processor Support.
+
 config BF531
        bool "BF531"
        help
@@ -144,13 +159,18 @@ endchoice
 
 choice
        prompt "Silicon Rev"
+       default BF_REV_0_1 if BF527
        default BF_REV_0_2 if BF537
        default BF_REV_0_3 if BF533
        default BF_REV_0_0 if BF549
 
 config BF_REV_0_0
        bool "0.0"
-       depends on (BF549)
+       depends on (BF549 || BF527)
+
+config BF_REV_0_1
+       bool "0.2"
+       depends on (BF549 || BF527)
 
 config BF_REV_0_2
        bool "0.2"
@@ -176,6 +196,11 @@ config BF_REV_NONE
 
 endchoice
 
+config BF52x
+       bool
+       depends on (BF522 || BF525 || BF527)
+       default y
+
 config BF53x
        bool
        depends on (BF531 || BF532 || BF533 || BF534 || BF536 || BF537)
@@ -204,6 +229,12 @@ choice
          configuration to ensure that all the other settings are
          correct.
 
+config BFIN527_EZKIT
+       bool "BF527-EZKIT"
+       depends on (BF522 || BF525 || BF527)
+       help
+         BF533-EZKIT-LITE board Support.
+
 config BFIN533_EZKIT
        bool "BF533-EZKIT"
        depends on (BF533 || BF532 || BF531)
@@ -299,11 +330,17 @@ config MEM_MT48LC8M32B2B5_7
        depends on (BFIN561_BLUETECHNIX_CM)
        default y
 
+config MEM_MT48LC32M16A2TG_75
+       bool
+       depends on (BFIN527_EZKIT)
+       default y
+
 config BFIN_SHARED_FLASH_ENET
        bool
        depends on (BFIN533_STAMP)
        default y
 
+source "arch/blackfin/mach-bf527/Kconfig"
 source "arch/blackfin/mach-bf533/Kconfig"
 source "arch/blackfin/mach-bf561/Kconfig"
 source "arch/blackfin/mach-bf537/Kconfig"
@@ -329,7 +366,7 @@ config CLKIN_HZ
        int "Crystal Frequency in Hz"
        default "11059200" if BFIN533_STAMP
        default "27000000" if BFIN533_EZKIT
-       default "25000000" if BFIN537_STAMP
+       default "25000000" if (BFIN537_STAMP || BFIN527_EZKIT)
        default "30000000" if BFIN561_EZKIT
        default "24576000" if PNAV10
        help
@@ -362,7 +399,7 @@ config VCO_MULT
        range 1 64
        default "22" if BFIN533_EZKIT
        default "45" if BFIN533_STAMP
-       default "20" if BFIN537_STAMP
+       default "20" if (BFIN537_STAMP || BFIN527_EZKIT)
        default "22" if BFIN533_BLUETECHNIX_CM
        default "20" if BFIN537_BLUETECHNIX_CM
        default "20" if BFIN561_BLUETECHNIX_CM
@@ -398,7 +435,7 @@ config SCLK_DIV
        range 1 15
        default 5 if BFIN533_EZKIT
        default 5 if BFIN533_STAMP
-       default 4 if BFIN537_STAMP
+       default 4 if (BFIN537_STAMP || BFIN527_EZKIT)
        default 5 if BFIN533_BLUETECHNIX_CM
        default 4 if BFIN537_BLUETECHNIX_CM
        default 4 if BFIN561_BLUETECHNIX_CM
@@ -450,6 +487,7 @@ comment "Memory Setup"
 config MEM_SIZE
        int "SDRAM Memory Size in MBytes"
        default  32 if BFIN533_EZKIT
+       default  64 if BFIN527_EZKIT
        default  64 if BFIN537_STAMP
        default  64 if BFIN561_EZKIT
        default 128 if BFIN533_STAMP
@@ -459,6 +497,7 @@ config MEM_ADD_WIDTH
        int "SDRAM Memory Address Width"
        default  9 if BFIN533_EZKIT
        default  9 if BFIN561_EZKIT
+       default 10 if BFIN527_EZKIT
        default 10 if BFIN537_STAMP
        default 11 if BFIN533_STAMP
        default 10 if PNAV10
@@ -613,85 +652,86 @@ config I_ENTRY_L1
        bool "Locate interrupt entry code in L1 Memory"
        default y
        help
-         If enabled interrupt entry code (STORE/RESTORE CONTEXT) is linked
-         into L1 instruction memory.(less latency)
+         If enabled, interrupt entry code (STORE/RESTORE CONTEXT) is linked
+         into L1 instruction memory. (less latency)
 
 config EXCPT_IRQ_SYSC_L1
-       bool "Locate entire ASM lowlevel excepetion / interrupt - Syscall and CPLB handler code in L1 Memory"
+       bool "Locate entire ASM lowlevel exception / interrupt - Syscall and CPLB handler code in L1 Memory"
        default y
        help
-         If enabled entire ASM lowlevel exception and interrupt entry code (STORE/RESTORE CONTEXT) is linked
-         into L1 instruction memory.(less latency)
+         If enabled, the entire ASM lowlevel exception and interrupt entry code
+         (STORE/RESTORE CONTEXT) is linked into L1 instruction memory. 
+         (less latency)
 
 config DO_IRQ_L1
        bool "Locate frequently called do_irq dispatcher function in L1 Memory"
        default y
        help
-         If enabled frequently called do_irq dispatcher function is linked
-         into L1 instruction memory.(less latency)
+         If enabled, the frequently called do_irq dispatcher function is linked
+         into L1 instruction memory. (less latency)
 
 config CORE_TIMER_IRQ_L1
        bool "Locate frequently called timer_interrupt() function in L1 Memory"
        default y
        help
-         If enabled frequently called timer_interrupt() function is linked
-         into L1 instruction memory.(less latency)
+         If enabled, the frequently called timer_interrupt() function is linked
+         into L1 instruction memory. (less latency)
 
 config IDLE_L1
        bool "Locate frequently idle function in L1 Memory"
        default y
        help
-         If enabled frequently called idle function is linked
-         into L1 instruction memory.(less latency)
+         If enabled, the frequently called idle function is linked
+         into L1 instruction memory. (less latency)
 
 config SCHEDULE_L1
        bool "Locate kernel schedule function in L1 Memory"
        default y
        help
-         If enabled frequently called kernel schedule is linked
-         into L1 instruction memory.(less latency)
+         If enabled, the frequently called kernel schedule is linked
+         into L1 instruction memory. (less latency)
 
 config ARITHMETIC_OPS_L1
        bool "Locate kernel owned arithmetic functions in L1 Memory"
        default y
        help
-         If enabled arithmetic functions are linked
-         into L1 instruction memory.(less latency)
+         If enabled, arithmetic functions are linked
+         into L1 instruction memory. (less latency)
 
 config ACCESS_OK_L1
        bool "Locate access_ok function in L1 Memory"
        default y
        help
-         If enabled access_ok function is linked
-         into L1 instruction memory.(less latency)
+         If enabled, the access_ok function is linked
+         into L1 instruction memory. (less latency)
 
 config MEMSET_L1
        bool "Locate memset function in L1 Memory"
        default y
        help
-         If enabled memset function is linked
-         into L1 instruction memory.(less latency)
+         If enabled, the memset function is linked
+         into L1 instruction memory. (less latency)
 
 config MEMCPY_L1
        bool "Locate memcpy function in L1 Memory"
        default y
        help
-         If enabled memcpy function is linked
-         into L1 instruction memory.(less latency)
+         If enabled, the memcpy function is linked
+         into L1 instruction memory. (less latency)
 
 config SYS_BFIN_SPINLOCK_L1
        bool "Locate sys_bfin_spinlock function in L1 Memory"
        default y
        help
-         If enabled sys_bfin_spinlock function is linked
-         into L1 instruction memory.(less latency)
+         If enabled, sys_bfin_spinlock function is linked
+         into L1 instruction memory. (less latency)
 
 config IP_CHECKSUM_L1
        bool "Locate IP Checksum function in L1 Memory"
        default n
        help
-         If enabled IP Checksum function is linked
-         into L1 instruction memory.(less latency)
+         If enabled, the IP Checksum function is linked
+         into L1 instruction memory. (less latency)
 
 config CACHELINE_ALIGNED_L1
        bool "Locate cacheline_aligned data to L1 Data Memory"
@@ -699,24 +739,24 @@ config CACHELINE_ALIGNED_L1
        default n if BF54x
        depends on !BF531
        help
-         If enabled cacheline_anligned data is linked
-         into L1 data memory.(less latency)
+         If enabled, cacheline_anligned data is linked
+         into L1 data memory. (less latency)
 
 config SYSCALL_TAB_L1
        bool "Locate Syscall Table L1 Data Memory"
        default n
        depends on !BF531
        help
-         If enabled the Syscall LUT is linked
-         into L1 data memory.(less latency)
+         If enabled, the Syscall LUT is linked
+         into L1 data memory. (less latency)
 
 config CPLB_SWITCH_TAB_L1
        bool "Locate CPLB Switch Tables L1 Data Memory"
        default n
        depends on !BF531
        help
-         If enabled the CPLB Switch Tables are linked
-         into L1 data memory.(less latency)
+         If enabled, the CPLB Switch Tables are linked
+         into L1 data memory. (less latency)
 
 endmenu
 
@@ -748,9 +788,19 @@ config LARGE_ALLOCS
          a lot of RAM, and you need to able to allocate very large
          contiguous chunks. If unsure, say N.
 
+config BFIN_GPTIMERS
+       tristate "Enable Blackfin General Purpose Timers API"
+       default n
+       help
+         Enable support for the General Purpose Timers API.  If you
+         are unsure, say N.
+
+         To compile this driver as a module, choose M here: the module
+         will be called gptimers.ko.
+
 config BFIN_DMA_5XX
        bool "Enable DMA Support"
-       depends on (BF533 || BF532 || BF531 || BF537 || BF536 || BF534 || BF561 || BF54x)
+       depends on (BF52x || BF53x || BF561 || BF54x)
        default y
        help
          DMA driver for BF5xx.
@@ -1012,7 +1062,7 @@ source "drivers/Kconfig"
 
 source "fs/Kconfig"
 
-source "arch/blackfin/oprofile/Kconfig"
+source "kernel/Kconfig.instrumentation"
 
 menu "Kernel hacking"
 
@@ -1029,13 +1079,13 @@ config DEBUG_HWERR
          from.
 
 config DEBUG_ICACHE_CHECK
-       bool "Check Instruction cache coherancy"
+       bool "Check Instruction cache coherency"
        depends on DEBUG_KERNEL
        depends on DEBUG_HWERR
        help
-         Say Y here if you are getting wierd unexplained errors. This will
-         ensure that icache is what SDRAM says it should be, by doing a
-         byte wise comparision between SDRAM and instruction cache. This
+         Say Y here if you are getting weird unexplained errors. This will
+         ensure that icache is what SDRAM says it should be by doing a
+         byte wise comparison between SDRAM and instruction cache. This
          also relocates the irq_panic() function to L1 memory, (which is
          un-cached).
 
index 368933760d28bba2e43f591d299c1befd4630dd0..f7cac7c51e7e5303848ea847370f6f93e5c7354a 100644 (file)
@@ -12,12 +12,17 @@ LDFLAGS_vmlinux  := -X
 OBJCOPYFLAGS     := -O binary -R .note -R .comment -S
 GZFLAGS          := -9
 
+KBUILD_CFLAGS           += $(call cc-option,-mno-fdpic)
+KBUILD_AFLAGS           += $(call cc-option,-mno-fdpic)
 CFLAGS_MODULE    += -mlong-calls
 KALLSYMS         += --symbol-prefix=_
 
 KBUILD_DEFCONFIG := BF537-STAMP_defconfig
 
 # setup the machine name and the machine dependent settings
+machine-$(CONFIG_BF522) := bf527
+machine-$(CONFIG_BF525) := bf527
+machine-$(CONFIG_BF527) := bf527
 machine-$(CONFIG_BF531) := bf533
 machine-$(CONFIG_BF532) := bf533
 machine-$(CONFIG_BF533) := bf533
@@ -32,6 +37,9 @@ machine-$(CONFIG_BF561) := bf561
 MACHINE := $(machine-y)
 export MACHINE
 
+cpu-$(CONFIG_BF522) := bf522
+cpu-$(CONFIG_BF525) := bf525
+cpu-$(CONFIG_BF527) := bf527
 cpu-$(CONFIG_BF531) := bf531
 cpu-$(CONFIG_BF532) := bf532
 cpu-$(CONFIG_BF533) := bf533
@@ -97,12 +105,23 @@ archclean:
        $(Q)$(MAKE) $(clean)=$(boot)
 
 
-all: vmImage
 boot := arch/$(ARCH)/boot
 BOOT_TARGETS = vmImage
-.PHONY: $(BOOT_TARGETS)
+PHONY += $(BOOT_TARGETS) install
+KBUILD_IMAGE := $(boot)/vmImage
+
+all: vmImage
+
 $(BOOT_TARGETS): vmlinux
        $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
+
+install:
+       $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install
+
 define archhelp
   echo  '* vmImage         - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage)'
+  echo  '  install         - Install kernel using'
+  echo  '                     (your) ~/bin/$(CROSS_COMPILE)installkernel or'
+  echo  '                     (distribution) PATH: $(CROSS_COMPILE)installkernel or'
+  echo  '                     install to $$(INSTALL_PATH)'
 endef
index 8cd33560e8179922b34f454ffddcdc8e911d24cb..522f3c12406041128bdfedc6639bcfbfa7893f05 100644 (file)
@@ -26,3 +26,6 @@ $(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE
 $(obj)/vmImage: $(obj)/vmlinux.gz
        $(call if_changed,uimage)
        @echo 'Kernel: $@ is ready'
+
+install:
+       sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)"
diff --git a/arch/blackfin/boot/install.sh b/arch/blackfin/boot/install.sh
new file mode 100644 (file)
index 0000000..9560a6b
--- /dev/null
@@ -0,0 +1,57 @@
+#!/bin/sh
+#
+# arch/blackfin/boot/install.sh
+#
+# 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) 1995 by Linus Torvalds
+#
+# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
+# Adapted from code in arch/i386/boot/install.sh by Mike Frysinger
+#
+# "make install" script for Blackfin architecture
+#
+# Arguments:
+#   $1 - kernel version
+#   $2 - kernel image file
+#   $3 - kernel map file
+#   $4 - default install path (blank if root directory)
+#
+
+verify () {
+       if [ ! -f "$1" ]; then
+               echo ""                                                   1>&2
+               echo " *** Missing file: $1"                              1>&2
+               echo ' *** You need to run "make" before "make install".' 1>&2
+               echo ""                                                   1>&2
+               exit 1
+       fi
+}
+
+# Make sure the files actually exist
+verify "$2"
+verify "$3"
+
+# User may have a custom install script
+
+if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi
+if which ${CROSS_COMPILE}installkernel >/dev/null 2>&1; then
+       exec ${CROSS_COMPILE}installkernel "$@"
+fi
+
+# Default install - same as make zlilo
+
+back_it_up() {
+       local file=$1
+       [ -f ${file} ] || return 0
+       local stamp=$(stat -c %Y ${file} 2>/dev/null)
+       mv ${file} ${file}.${stamp:-old}
+}
+
+back_it_up $4/uImage
+back_it_up $4/System.map
+
+cat $2 > $4/uImage
+cp $3 $4/System.map
diff --git a/arch/blackfin/configs/BF527-EZKIT_defconfig b/arch/blackfin/configs/BF527-EZKIT_defconfig
new file mode 100644 (file)
index 0000000..df974e7
--- /dev/null
@@ -0,0 +1,1241 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.22.9
+#
+# CONFIG_MMU is not set
+# CONFIG_FPU is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_BLACKFIN=y
+CONFIG_ZONE_DMA=y
+CONFIG_BFIN=y
+CONFIG_SEMAPHORE_SLEEPERS=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+# CONFIG_GENERIC_TIME is not set
+CONFIG_GENERIC_GPIO=y
+CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_IRQCHIP_DEMUX_GPIO=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=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=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY 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_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3
+# CONFIG_NP2 is not set
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_RT_MUTEXES=y
+CONFIG_TINY_SHMEM=y
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+
+#
+# Blackfin Processor Options
+#
+
+#
+# Processor and Board Settings
+#
+# CONFIG_BF522 is not set
+# CONFIG_BF525 is not set
+CONFIG_BF527=y
+# CONFIG_BF531 is not set
+# CONFIG_BF532 is not set
+# CONFIG_BF533 is not set
+# CONFIG_BF534 is not set
+# CONFIG_BF536 is not set
+# CONFIG_BF537 is not set
+# CONFIG_BF542 is not set
+# CONFIG_BF544 is not set
+# CONFIG_BF548 is not set
+# CONFIG_BF549 is not set
+# CONFIG_BF561 is not set
+CONFIG_BF_REV_0_0=y
+# CONFIG_BF_REV_0_1 is not set
+# CONFIG_BF_REV_0_2 is not set
+# CONFIG_BF_REV_0_3 is not set
+# CONFIG_BF_REV_0_4 is not set
+# CONFIG_BF_REV_0_5 is not set
+# CONFIG_BF_REV_ANY is not set
+# CONFIG_BF_REV_NONE is not set
+CONFIG_BF52x=y
+CONFIG_BFIN_SINGLE_CORE=y
+CONFIG_BFIN527_EZKIT=y
+# CONFIG_BFIN533_EZKIT is not set
+# CONFIG_BFIN533_STAMP is not set
+# CONFIG_BFIN537_STAMP is not set
+# CONFIG_BFIN533_BLUETECHNIX_CM is not set
+# CONFIG_BFIN537_BLUETECHNIX_CM is not set
+# CONFIG_BFIN548_EZKIT is not set
+# CONFIG_BFIN561_BLUETECHNIX_CM is not set
+# CONFIG_BFIN561_EZKIT is not set
+# CONFIG_BFIN561_TEPLA is not set
+# CONFIG_PNAV10 is not set
+# CONFIG_GENERIC_BOARD is not set
+CONFIG_MEM_MT48LC32M16A2TG_75=y
+
+#
+# BF527 Specific Configuration
+#
+
+#
+# Alternative Multiplexing Scheme
+#
+# CONFIG_BF527_SPORT0_PORTF is not set
+CONFIG_BF527_SPORT0_PORTG=y
+CONFIG_BF527_SPORT0_TSCLK_PG10=y
+# CONFIG_BF527_SPORT0_TSCLK_PG14 is not set
+# CONFIG_BF527_UART1_PORTF is not set
+CONFIG_BF527_UART1_PORTG=y
+# CONFIG_BF527_NAND_D_PORTF is not set
+CONFIG_BF527_NAND_D_PORTH=y
+
+#
+# Interrupt Priority Assignment
+#
+
+#
+# Priority
+#
+CONFIG_IRQ_PLL_WAKEUP=7
+CONFIG_IRQ_DMA0_ERROR=7
+CONFIG_IRQ_DMAR0_BLK=7
+CONFIG_IRQ_DMAR1_BLK=7
+CONFIG_IRQ_DMAR0_OVR=7
+CONFIG_IRQ_DMAR1_OVR=7
+CONFIG_IRQ_PPI_ERROR=7
+CONFIG_IRQ_MAC_ERROR=7
+CONFIG_IRQ_SPORT0_ERROR=7
+CONFIG_IRQ_SPORT1_ERROR=7
+CONFIG_IRQ_UART0_ERROR=7
+CONFIG_IRQ_UART1_ERROR=7
+CONFIG_IRQ_RTC=8
+CONFIG_IRQ_PPI=8
+CONFIG_IRQ_SPORT0_RX=9
+CONFIG_IRQ_SPORT0_TX=9
+CONFIG_IRQ_SPORT1_RX=9
+CONFIG_IRQ_SPORT1_TX=9
+CONFIG_IRQ_TWI=10
+CONFIG_IRQ_SPI=10
+CONFIG_IRQ_UART0_RX=10
+CONFIG_IRQ_UART0_TX=10
+CONFIG_IRQ_UART1_RX=10
+CONFIG_IRQ_UART1_TX=10
+CONFIG_IRQ_OPTSEC=11
+CONFIG_IRQ_CNT=11
+CONFIG_IRQ_MAC_RX=11
+CONFIG_IRQ_PORTH_INTA=11
+CONFIG_IRQ_MAC_TX=11
+CONFIG_IRQ_PORTH_INTB=11
+CONFIG_IRQ_TMR0=12
+CONFIG_IRQ_TMR1=12
+CONFIG_IRQ_TMR2=12
+CONFIG_IRQ_TMR3=12
+CONFIG_IRQ_TMR4=12
+CONFIG_IRQ_TMR5=12
+CONFIG_IRQ_TMR6=12
+CONFIG_IRQ_TMR7=12
+CONFIG_IRQ_PORTG_INTA=12
+CONFIG_IRQ_PORTG_INTB=12
+CONFIG_IRQ_MEM_DMA0=13
+CONFIG_IRQ_MEM_DMA1=13
+CONFIG_IRQ_WATCH=13
+CONFIG_IRQ_PORTF_INTA=13
+CONFIG_IRQ_PORTF_INTB=13
+CONFIG_IRQ_SPI_ERROR=7
+CONFIG_IRQ_NFC_ERROR=7
+CONFIG_IRQ_HDMA_ERROR=7
+CONFIG_IRQ_HDMA=7
+CONFIG_IRQ_USB_EINT=10
+CONFIG_IRQ_USB_INT0=11
+CONFIG_IRQ_USB_INT1=11
+CONFIG_IRQ_USB_INT2=11
+CONFIG_IRQ_USB_DMA=11
+
+#
+# Board customizations
+#
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Clock/PLL Setup
+#
+CONFIG_CLKIN_HZ=25000000
+# CONFIG_BFIN_KERNEL_CLOCK is not set
+CONFIG_MAX_VCO_HZ=600000000
+CONFIG_MIN_VCO_HZ=50000000
+CONFIG_MAX_SCLK_HZ=133000000
+CONFIG_MIN_SCLK_HZ=27000000
+
+#
+# Kernel Timer/Scheduler
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+
+#
+# Memory Setup
+#
+CONFIG_MEM_SIZE=64
+CONFIG_MEM_ADD_WIDTH=10
+CONFIG_BOOT_LOAD=0x1000
+CONFIG_BFIN_SCRATCH_REG_RETN=y
+# CONFIG_BFIN_SCRATCH_REG_RETE is not set
+# CONFIG_BFIN_SCRATCH_REG_CYCLES is not set
+
+#
+# Blackfin Kernel Optimizations
+#
+
+#
+# Memory Optimizations
+#
+CONFIG_I_ENTRY_L1=y
+CONFIG_EXCPT_IRQ_SYSC_L1=y
+CONFIG_DO_IRQ_L1=y
+CONFIG_CORE_TIMER_IRQ_L1=y
+CONFIG_IDLE_L1=y
+# CONFIG_SCHEDULE_L1 is not set
+CONFIG_ARITHMETIC_OPS_L1=y
+CONFIG_ACCESS_OK_L1=y
+# CONFIG_MEMSET_L1 is not set
+# CONFIG_MEMCPY_L1 is not set
+# CONFIG_SYS_BFIN_SPINLOCK_L1 is not set
+# CONFIG_IP_CHECKSUM_L1 is not set
+CONFIG_CACHELINE_ALIGNED_L1=y
+# CONFIG_SYSCALL_TAB_L1 is not set
+# CONFIG_CPLB_SWITCH_TAB_L1 is not set
+CONFIG_RAMKERNEL=y
+# CONFIG_ROMKERNEL is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_LARGE_ALLOCS=y
+CONFIG_BFIN_DMA_5XX=y
+# CONFIG_DMA_UNCACHED_2M is not set
+CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_NONE is not set
+
+#
+# Cache Support
+#
+CONFIG_BFIN_ICACHE=y
+CONFIG_BFIN_DCACHE=y
+# CONFIG_BFIN_DCACHE_BANKA is not set
+# CONFIG_BFIN_ICACHE_LOCK is not set
+# CONFIG_BFIN_WB is not set
+CONFIG_BFIN_WT=y
+CONFIG_L1_MAX_PIECE=16
+
+#
+# Asynchonous Memory Configuration
+#
+
+#
+# EBIU_AMBCTL Global Control
+#
+CONFIG_C_AMCKEN=y
+CONFIG_C_CDPRIO=y
+# CONFIG_C_AMBEN is not set
+# CONFIG_C_AMBEN_B0 is not set
+# CONFIG_C_AMBEN_B0_B1 is not set
+# CONFIG_C_AMBEN_B0_B1_B2 is not set
+CONFIG_C_AMBEN_ALL=y
+
+#
+# EBIU_AMBCTL Control
+#
+CONFIG_BANK_0=0x7BB0
+CONFIG_BANK_1=0x5554
+CONFIG_BANK_2=0x7BB0
+CONFIG_BANK_3=0xFFC0
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+# CONFIG_PCI is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF_FDPIC=y
+CONFIG_BINFMT_FLAT=y
+CONFIG_BINFMT_ZFLAT=y
+# CONFIG_BINFMT_SHARED_FLAT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_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_NETLABEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_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
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_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
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+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=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
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_MW320D=m
+CONFIG_MTD_RAM=y
+CONFIG_MTD_ROM=m
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_BF5xx=m
+CONFIG_BFIN_FLASH_SIZE=0x400000
+CONFIG_EBIU_FLASH_BASE=0x20000000
+# CONFIG_MTD_UCLINUX is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_BFIN=m
+CONFIG_BFIN_NAND_BASE=0x20212000
+CONFIG_BFIN_NAND_CLE=2
+CONFIG_BFIN_NAND_ALE=1
+CONFIG_BFIN_NAND_READY=3
+CONFIG_MTD_NAND_IDS=m
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI 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_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_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# Misc devices
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+
+#
+# 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_EQUALIZER is not set
+# CONFIG_TUN 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_FIXED_PHY is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_SMC91X is not set
+CONFIG_BFIN_MAC=y
+CONFIG_BFIN_MAC_USE_L1=y
+CONFIG_BFIN_TX_DESC_NUM=10
+CONFIG_BFIN_RX_DESC_NUM=20
+CONFIG_BFIN_MAC_RMII=y
+# CONFIG_SMSC911X is not set
+# CONFIG_DM9000 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_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
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_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_UINPUT is not set
+# CONFIG_BF53X_PFBUTTONS is not set
+# CONFIG_TWI_KEYPAD is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_AD9960 is not set
+# CONFIG_SPI_ADC_BF533 is not set
+# CONFIG_BF5xx_PFLAGS is not set
+# CONFIG_BF5xx_PPIFCD is not set
+# CONFIG_BF5xx_TIMERS is not set
+# CONFIG_BF5xx_PPI is not set
+# CONFIG_BFIN_SPORT is not set
+# CONFIG_BFIN_TIMER_LATENCY is not set
+# CONFIG_TWI_LCD is not set
+# CONFIG_AD5304 is not set
+# CONFIG_BF5xx_TEA5764 is not set
+# CONFIG_BF5xx_FBDMA is not set
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_BFIN=y
+CONFIG_SERIAL_BFIN_CONSOLE=y
+# CONFIG_SERIAL_BFIN_DMA is not set
+CONFIG_SERIAL_BFIN_PIO=y
+# CONFIG_SERIAL_BFIN_UART0 is not set
+CONFIG_SERIAL_BFIN_UART1=y
+# CONFIG_BFIN_UART1_CTSRTS is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_BFIN_SPORT is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# CAN, the car bus and industrial fieldbus
+#
+# CONFIG_CAN4LINUX is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_BFIN_WDT=y
+CONFIG_HW_RANDOM=y
+# CONFIG_GEN_RTC is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_BLACKFIN_GPIO is not set
+CONFIG_I2C_BLACKFIN_TWI=m
+CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_SIMTEC 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_SENSORS_AD5252 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCF8575 is not set
+# CONFIG_SENSORS_PCA9543 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 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_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BFIN=y
+# CONFIG_SPI_BITBANG is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU 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_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS 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_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 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_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP 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_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB is not set
+
+#
+# Enable Host or Gadget support to see Inventra options
+#
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+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_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
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+
+#
+# Platform 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_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_BFIN=y
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# PBX support
+#
+# CONFIG_PBX is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# 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_SYSCTL=y
+CONFIG_SYSFS=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# 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=m
+CONFIG_YAFFS_YAFFS1=y
+# CONFIG_YAFFS_DOES_ECC is not set
+CONFIG_YAFFS_YAFFS2=y
+CONFIG_YAFFS_AUTO_YAFFS2=y
+# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
+CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10
+# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
+# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
+CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# 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_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+# CONFIG_SUNRPC_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 is not set
+# 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=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+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_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_MMRS=y
+CONFIG_DEBUG_HUNT_FOR_ZERO=y
+CONFIG_DEBUG_BFIN_HWTRACE_ON=y
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE is not set
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_TWO is not set
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0
+# CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set
+# CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
+CONFIG_EARLY_PRINTK=y
+CONFIG_CPLB_INFO=y
+CONFIG_ACCESS_CHECK=y
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+CONFIG_SECURITY=y
+# CONFIG_SECURITY_NETWORK is not set
+CONFIG_SECURITY_CAPABILITIES=y
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
index e80f3d59c2837de2481d1407b322b148d736c494..d8569888a1c84a6abf82c5951eba18f096bc83fa 100644 (file)
@@ -809,7 +809,14 @@ CONFIG_UNIX98_PTYS=y
 # IPMI
 #
 # CONFIG_IPMI_HANDLER is not set
-# CONFIG_WATCHDOG is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_BFIN_WDT=y
 CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
index 8aeb6066b19b06ffb875d7b1ff75cdb0ece34d86..8a4cfb293b27fd2b8c1b9d08b3271abbc7305957 100644 (file)
@@ -9,6 +9,7 @@ obj-y := \
        sys_bfin.o time.o traps.o irqchip.o dma-mapping.o flat.o \
        fixed_code.o cplbinit.o cacheinit.o reboot.o bfin_gpio.o
 
+obj-$(CONFIG_BFIN_GPTIMERS)          += gptimers.o
 obj-$(CONFIG_MODULES)                += module.o
 obj-$(CONFIG_BFIN_DMA_5XX)           += bfin_dma_5xx.o
 obj-$(CONFIG_DUAL_CORE_TEST_MODULE)  += dualcore_test.o
index e19164fb4cd1dfe1de064e201643d72416ff6c53..503eef4c7fec26b831476be01e98a532a2a25e96 100644 (file)
@@ -420,6 +420,32 @@ unsigned short get_dma_curr_ycount(unsigned int channel)
 }
 EXPORT_SYMBOL(get_dma_curr_ycount);
 
+unsigned long get_dma_next_desc_ptr(unsigned int channel)
+{
+       BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+             && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+       return dma_ch[channel].regs->next_desc_ptr;
+}
+EXPORT_SYMBOL(get_dma_next_desc_ptr);
+
+unsigned long get_dma_curr_desc_ptr(unsigned int channel)
+{
+       BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+             && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+       return dma_ch[channel].regs->curr_desc_ptr;
+}
+
+unsigned long get_dma_curr_addr(unsigned int channel)
+{
+       BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+             && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+       return dma_ch[channel].regs->curr_addr_ptr;
+}
+EXPORT_SYMBOL(get_dma_curr_addr);
+
 static void *__dma_memcpy(void *dest, const void *src, size_t size)
 {
        int direction;  /* 1 - address decrease, 0 - address increase */
index 3fe0cd49e8db51736620acd924f1457c88b02e42..ce85d4bf34cae428555d40771328b296d0f0376c 100644 (file)
@@ -124,7 +124,7 @@ static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
 };
 #endif
 
-#ifdef BF537_FAMILY
+#if defined(BF527_FAMILY) || defined(BF537_FAMILY)
 static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
        (struct gpio_port_t *) PORTFIO,
        (struct gpio_port_t *) PORTGIO,
@@ -139,6 +139,21 @@ static unsigned short *port_fer[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
 
 #endif
 
+#ifdef BF527_FAMILY
+static unsigned short *port_mux[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
+       (unsigned short *) PORTF_MUX,
+       (unsigned short *) PORTG_MUX,
+       (unsigned short *) PORTH_MUX,
+};
+
+static const
+u8 pmux_offset[][16] =
+       {{ 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 4, 6, 8, 8, 10, 10 }, /* PORTF */
+        { 0, 0, 0, 0, 0, 2, 2, 4, 4, 6, 8, 10, 10, 10, 12, 12 }, /* PORTG */
+        { 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 4, 4, 4, 4 }, /* PORTH */
+       };
+#endif
+
 #ifdef BF561_FAMILY
 static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
        (struct gpio_port_t *) FIO0_FLAG_D,
@@ -186,6 +201,10 @@ static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG_INTB
 static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG_INTB, IRQ_PORTG_INTB, IRQ_MAC_TX};
 #endif
 
+#ifdef BF527_FAMILY
+static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PORTF_INTB, IRQ_PORTG_INTB, IRQ_PORTH_INTB};
+#endif
+
 #ifdef BF561_FAMILY
 static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB};
 #endif
@@ -238,7 +257,7 @@ static int cmp_label(unsigned short ident, const char *label)
                return -EINVAL;
 }
 
-#ifdef BF537_FAMILY
+#if defined(BF527_FAMILY) || defined(BF537_FAMILY)
 static void port_setup(unsigned short gpio, unsigned short usage)
 {
        if (!check_gpio(gpio)) {
@@ -354,6 +373,18 @@ inline u16 get_portmux(unsigned short portno)
 
        return (pmux >> (2 * gpio_sub_n(portno)) & 0x3);
 }
+#elif defined(BF527_FAMILY)
+inline void portmux_setup(unsigned short portno, unsigned short function)
+{
+       u16 pmux, ident = P_IDENT(portno);
+       u8 offset = pmux_offset[gpio_bank(ident)][gpio_sub_n(ident)];
+
+       pmux = *port_mux[gpio_bank(ident)];
+       pmux &= ~(3 << offset);
+       pmux |= (function & 3) << offset;
+       *port_mux[gpio_bank(ident)] = pmux;
+       SSYNC();
+}
 #else
 # define portmux_setup(...)  do { } while (0)
 #endif
index 94d7b119b71ec6637e8b49a23d4f10b98f723a02..a16cb03c52913e43ef57abe8c06a95d023b00ce1 100644 (file)
@@ -160,8 +160,7 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
        BUG_ON(direction == DMA_NONE);
 
        for (i = 0; i < nents; i++, sg++) {
-               sg->dma_address = (dma_addr_t)(page_address(sg->page) +
-                                       sg->offset);
+               sg->dma_address = (dma_addr_t) sg_virt(sg);
 
                invalidate_dcache_range(sg_dma_address(sg),
                                        sg_dma_address(sg) +
diff --git a/arch/blackfin/kernel/gptimers.c b/arch/blackfin/kernel/gptimers.c
new file mode 100644 (file)
index 0000000..cb7ba9b
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ * bfin_gptimers.c - derived from bf53x_timers.c
+ *  Driver for General Purpose Timer functions on the Blackfin processor
+ *
+ *  Copyright (C) 2005 John DeHority
+ *  Copyright (C) 2006 Hella Aglaia GmbH (awe@aglaia-gmbh.de)
+ *
+ * Licensed under the GPLv2.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/io.h>
+#include <asm/blackfin.h>
+#include <asm/gptimers.h>
+
+#ifdef DEBUG
+# define tassert(expr)
+#else
+# define tassert(expr) \
+       if (!(expr)) \
+               printk(KERN_DEBUG "%s:%s:%i: Assertion failed: " #expr "\n", \
+                       __FILE__, __func__, __LINE__);
+#endif
+
+#define BFIN_TIMER_NUM_GROUP  (BFIN_TIMER_OCTET(MAX_BLACKFIN_GPTIMERS - 1) + 1)
+
+typedef struct {
+       uint16_t config;
+       uint16_t __pad;
+       uint32_t counter;
+       uint32_t period;
+       uint32_t width;
+} GPTIMER_timer_regs;
+
+typedef struct {
+       uint16_t enable;
+       uint16_t __pad0;
+       uint16_t disable;
+       uint16_t __pad1;
+       uint32_t status;
+} GPTIMER_group_regs;
+
+static volatile GPTIMER_timer_regs *const timer_regs[MAX_BLACKFIN_GPTIMERS] =
+{
+       (GPTIMER_timer_regs *)TIMER0_CONFIG,
+       (GPTIMER_timer_regs *)TIMER1_CONFIG,
+       (GPTIMER_timer_regs *)TIMER2_CONFIG,
+#if (MAX_BLACKFIN_GPTIMERS > 3)
+       (GPTIMER_timer_regs *)TIMER3_CONFIG,
+       (GPTIMER_timer_regs *)TIMER4_CONFIG,
+       (GPTIMER_timer_regs *)TIMER5_CONFIG,
+       (GPTIMER_timer_regs *)TIMER6_CONFIG,
+       (GPTIMER_timer_regs *)TIMER7_CONFIG,
+#endif
+#if (MAX_BLACKFIN_GPTIMERS > 8)
+       (GPTIMER_timer_regs *)TIMER8_CONFIG,
+       (GPTIMER_timer_regs *)TIMER9_CONFIG,
+       (GPTIMER_timer_regs *)TIMER10_CONFIG,
+       (GPTIMER_timer_regs *)TIMER11_CONFIG,
+#endif
+};
+
+static volatile GPTIMER_group_regs *const group_regs[BFIN_TIMER_NUM_GROUP] =
+{
+       (GPTIMER_group_regs *)TIMER0_GROUP_REG,
+#if (MAX_BLACKFIN_GPTIMERS > 8)
+       (GPTIMER_group_regs *)TIMER8_GROUP_REG,
+#endif
+};
+
+static uint32_t const dis_mask[MAX_BLACKFIN_GPTIMERS] =
+{
+       TIMER_STATUS_TRUN0,
+       TIMER_STATUS_TRUN1,
+       TIMER_STATUS_TRUN2,
+#if (MAX_BLACKFIN_GPTIMERS > 3)
+       TIMER_STATUS_TRUN3,
+       TIMER_STATUS_TRUN4,
+       TIMER_STATUS_TRUN5,
+       TIMER_STATUS_TRUN6,
+       TIMER_STATUS_TRUN7,
+#endif
+#if (MAX_BLACKFIN_GPTIMERS > 8)
+       TIMER_STATUS_TRUN8,
+       TIMER_STATUS_TRUN9,
+       TIMER_STATUS_TRUN10,
+       TIMER_STATUS_TRUN11,
+#endif
+};
+
+static uint32_t const irq_mask[MAX_BLACKFIN_GPTIMERS] =
+{
+       TIMER_STATUS_TIMIL0,
+       TIMER_STATUS_TIMIL1,
+       TIMER_STATUS_TIMIL2,
+#if (MAX_BLACKFIN_GPTIMERS > 3)
+       TIMER_STATUS_TIMIL3,
+       TIMER_STATUS_TIMIL4,
+       TIMER_STATUS_TIMIL5,
+       TIMER_STATUS_TIMIL6,
+       TIMER_STATUS_TIMIL7,
+#endif
+#if (MAX_BLACKFIN_GPTIMERS > 8)
+       TIMER_STATUS_TIMIL8,
+       TIMER_STATUS_TIMIL9,
+       TIMER_STATUS_TIMIL10,
+       TIMER_STATUS_TIMIL11,
+#endif
+};
+
+void set_gptimer_pwidth(int timer_id, uint32_t value)
+{
+       tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+       timer_regs[timer_id]->width = value;
+       SSYNC();
+}
+EXPORT_SYMBOL(set_gptimer_pwidth);
+
+uint32_t get_gptimer_pwidth(int timer_id)
+{
+       tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+       return timer_regs[timer_id]->width;
+}
+EXPORT_SYMBOL(get_gptimer_pwidth);
+
+void set_gptimer_period(int timer_id, uint32_t period)
+{
+       tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+       timer_regs[timer_id]->period = period;
+       SSYNC();
+}
+EXPORT_SYMBOL(set_gptimer_period);
+
+uint32_t get_gptimer_period(int timer_id)
+{
+       tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+       return timer_regs[timer_id]->period;
+}
+EXPORT_SYMBOL(get_gptimer_period);
+
+uint32_t get_gptimer_count(int timer_id)
+{
+       tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+       return timer_regs[timer_id]->counter;
+}
+EXPORT_SYMBOL(get_gptimer_count);
+
+uint32_t get_gptimer_status(int group)
+{
+       tassert(group < BFIN_TIMER_NUM_GROUP);
+       return group_regs[group]->status;
+}
+EXPORT_SYMBOL(get_gptimer_status);
+
+void set_gptimer_status(int group, uint32_t value)
+{
+       tassert(group < BFIN_TIMER_NUM_GROUP);
+       group_regs[group]->status = value;
+       SSYNC();
+}
+EXPORT_SYMBOL(set_gptimer_status);
+
+uint16_t get_gptimer_intr(int timer_id)
+{
+       tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+       return (group_regs[BFIN_TIMER_OCTET(timer_id)]->status & irq_mask[timer_id]) ? 1 : 0;
+}
+EXPORT_SYMBOL(get_gptimer_intr);
+
+void clear_gptimer_intr(int timer_id)
+{
+       tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+       group_regs[BFIN_TIMER_OCTET(timer_id)]->status = irq_mask[timer_id];
+}
+EXPORT_SYMBOL(clear_gptimer_intr);
+
+void set_gptimer_config(int timer_id, uint16_t config)
+{
+       tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+       timer_regs[timer_id]->config = config;
+       SSYNC();
+}
+EXPORT_SYMBOL(set_gptimer_config);
+
+uint16_t get_gptimer_config(int timer_id)
+{
+       tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+       return timer_regs[timer_id]->config;
+}
+EXPORT_SYMBOL(get_gptimer_config);
+
+void enable_gptimers(uint16_t mask)
+{
+       int i;
+       tassert((mask & ~BLACKFIN_GPTIMER_IDMASK) == 0);
+       for (i = 0; i < BFIN_TIMER_NUM_GROUP; ++i) {
+               group_regs[i]->enable = mask & 0xFF;
+               mask >>= 8;
+       }
+       SSYNC();
+}
+EXPORT_SYMBOL(enable_gptimers);
+
+void disable_gptimers(uint16_t mask)
+{
+       int i;
+       uint16_t m = mask;
+       tassert((mask & ~BLACKFIN_GPTIMER_IDMASK) == 0);
+       for (i = 0; i < BFIN_TIMER_NUM_GROUP; ++i) {
+               group_regs[i]->disable = m & 0xFF;
+               m >>= 8;
+       }
+       for (i = 0; i < MAX_BLACKFIN_GPTIMERS; ++i)
+               if (mask & (1 << i))
+                       group_regs[BFIN_TIMER_OCTET(i)]->status |= dis_mask[i];
+       SSYNC();
+}
+EXPORT_SYMBOL(disable_gptimers);
+
+void set_gptimer_pulse_hi(int timer_id)
+{
+       tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+       timer_regs[timer_id]->config |= TIMER_PULSE_HI;
+       SSYNC();
+}
+EXPORT_SYMBOL(set_gptimer_pulse_hi);
+
+void clear_gptimer_pulse_hi(int timer_id)
+{
+       tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+       timer_regs[timer_id]->config &= ~TIMER_PULSE_HI;
+       SSYNC();
+}
+EXPORT_SYMBOL(clear_gptimer_pulse_hi);
+
+uint16_t get_enabled_gptimers(void)
+{
+       int i;
+       uint16_t result = 0;
+       for (i = 0; i < BFIN_TIMER_NUM_GROUP; ++i)
+               result |= (group_regs[i]->enable << (i << 3));
+       return result;
+}
+EXPORT_SYMBOL(get_enabled_gptimers);
+
+MODULE_AUTHOR("Axel Weiss (awe@aglaia-gmbh.de)");
+MODULE_DESCRIPTION("Blackfin General Purpose Timers API");
+MODULE_LICENSE("GPL");
index 356078ec462b17310a4fffc43200bbbd61a3825c..ae28aac6fec156c01bfd3095a8002de8b9dc9863 100644 (file)
@@ -11,7 +11,7 @@
 #include <asm/reboot.h>
 #include <asm/system.h>
 
-#if defined(BF537_FAMILY) || defined(BF533_FAMILY)
+#if defined(BF537_FAMILY) || defined(BF533_FAMILY) || defined(BF527_FAMILY)
 #define SYSCR_VAL      0x0
 #elif defined(BF561_FAMILY)
 #define SYSCR_VAL      0x20
index 8dcd76e87ed5171056796c08911642ba4026e988..f1b059e5a06cb171516804f441438011b26eaf11 100644 (file)
@@ -459,7 +459,7 @@ static u_long get_vco(void)
        return vco;
 }
 
-/*Get the Core clock*/
+/* Get the Core clock */
 u_long get_cclk(void)
 {
        u_long csel, ssel;
@@ -493,12 +493,24 @@ u_long get_sclk(void)
 }
 EXPORT_SYMBOL(get_sclk);
 
+unsigned long sclk_to_usecs(unsigned long sclk)
+{
+       return (USEC_PER_SEC * (u64)sclk) / get_sclk();
+}
+EXPORT_SYMBOL(sclk_to_usecs);
+
+unsigned long usecs_to_sclk(unsigned long usecs)
+{
+       return (get_sclk() * (u64)usecs) / USEC_PER_SEC;
+}
+EXPORT_SYMBOL(usecs_to_sclk);
+
 /*
  *     Get CPU information for use by the procfs.
  */
 static int show_cpuinfo(struct seq_file *m, void *v)
 {
-       char *cpu, *mmu, *fpu, *name;
+       char *cpu, *mmu, *fpu, *vendor, *cache;
        uint32_t revid;
 
        u_long cclk = 0, sclk = 0;
@@ -508,70 +520,83 @@ static int show_cpuinfo(struct seq_file *m, void *v)
        mmu = "none";
        fpu = "none";
        revid = bfin_revid();
-       name = bfin_board_name;
 
        cclk = get_cclk();
        sclk = get_sclk();
 
-       seq_printf(m, "CPU:\t\tADSP-%s Rev. 0.%d\n"
-                  "MMU:\t\t%s\n"
-                  "FPU:\t\t%s\n"
-                  "Core Clock:\t%9lu Hz\n"
-                  "System Clock:\t%9lu Hz\n"
-                  "BogoMips:\t%lu.%02lu\n"
-                  "Calibration:\t%lu loops\n",
-                  cpu, revid, mmu, fpu,
-                  cclk,
-                  sclk,
-                  (loops_per_jiffy * HZ) / 500000,
-                  ((loops_per_jiffy * HZ) / 5000) % 100,
-                  (loops_per_jiffy * HZ));
-       seq_printf(m, "Board Name:\t%s\n", name);
-       seq_printf(m, "Board Memory:\t%ld MB\n", physical_mem_end >> 20);
-       seq_printf(m, "Kernel Memory:\t%ld MB\n", (unsigned long)_ramend >> 20);
-       if (bfin_read_IMEM_CONTROL() & (ENICPLB | IMC))
-               seq_printf(m, "I-CACHE:\tON\n");
-       else
-               seq_printf(m, "I-CACHE:\tOFF\n");
-       if ((bfin_read_DMEM_CONTROL()) & (ENDCPLB | DMC_ENABLE))
-               seq_printf(m, "D-CACHE:\tON"
-#if defined CONFIG_BFIN_WB
-                          " (write-back)"
-#elif defined CONFIG_BFIN_WT
-                          " (write-through)"
-#endif
-                          "\n");
-       else
-               seq_printf(m, "D-CACHE:\tOFF\n");
-
+       switch (bfin_read_CHIPID() & CHIPID_MANUFACTURE) {
+       case 0xca:
+               vendor = "Analog Devices";
+               break;
+       default:
+               vendor = "unknown";
+               break;
+       }
 
+       seq_printf(m, "processor\t: %d\n"
+               "vendor_id\t: %s\n"
+               "cpu family\t: 0x%x\n"
+               "model name\t: ADSP-%s %lu(MHz CCLK) %lu(MHz SCLK)\n"
+               "stepping\t: %d\n",
+               0,
+               vendor,
+               (bfin_read_CHIPID() & CHIPID_FAMILY),
+               cpu, cclk/1000000, sclk/1000000,
+               revid);
+
+       seq_printf(m, "cpu MHz\t\t: %lu.%03lu/%lu.%03lu\n",
+               cclk/1000000, cclk%1000000,
+               sclk/1000000, sclk%1000000);
+       seq_printf(m, "bogomips\t: %lu.%02lu\n"
+               "Calibration\t: %lu loops\n",
+               (loops_per_jiffy * HZ) / 500000,
+               ((loops_per_jiffy * HZ) / 5000) % 100,
+               (loops_per_jiffy * HZ));
+
+       /* Check Cache configutation */
        switch (bfin_read_DMEM_CONTROL() & (1 << DMC0_P | 1 << DMC1_P)) {
        case ACACHE_BSRAM:
-               seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tSRAM\n");
+               cache = "dbank-A/B\t: cache/sram";
                dcache_size = 16;
                dsup_banks = 1;
                break;
        case ACACHE_BCACHE:
-               seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tCACHE\n");
+               cache = "dbank-A/B\t: cache/cache";
                dcache_size = 32;
                dsup_banks = 2;
                break;
        case ASRAM_BSRAM:
-               seq_printf(m, "DBANK-A:\tSRAM\n" "DBANK-B:\tSRAM\n");
+               cache = "dbank-A/B\t: sram/sram";
                dcache_size = 0;
                dsup_banks = 0;
                break;
        default:
+               cache = "unknown";
+               dcache_size = 0;
+               dsup_banks = 0;
                break;
        }
 
+       /* Is it turned on? */
+       if (!((bfin_read_DMEM_CONTROL()) & (ENDCPLB | DMC_ENABLE)))
+               dcache_size = 0;
 
-       seq_printf(m, "I-CACHE Size:\t%dKB\n", BFIN_ICACHESIZE / 1024);
-       seq_printf(m, "D-CACHE Size:\t%dKB\n", dcache_size);
-       seq_printf(m, "I-CACHE Setup:\t%d Sub-banks/%d Ways, %d Lines/Way\n",
+       seq_printf(m, "cache size\t: %d KB(L1 icache) "
+               "%d KB(L1 dcache-%s) %d KB(L2 cache)\n",
+               BFIN_ICACHESIZE / 1024, dcache_size,
+#if defined CONFIG_BFIN_WB
+               "wb"
+#elif defined CONFIG_BFIN_WT
+               "wt"
+#endif
+               "", 0);
+
+       seq_printf(m, "%s\n", cache);
+
+       seq_printf(m, "icache setup\t: %d Sub-banks/%d Ways, %d Lines/Way\n",
                   BFIN_ISUBBANKS, BFIN_IWAYS, BFIN_ILINES);
        seq_printf(m,
-                  "D-CACHE Setup:\t%d Super-banks/%d Sub-banks/%d Ways, %d Lines/Way\n",
+                  "dcache setup\t: %d Super-banks/%d Sub-banks/%d Ways, %d Lines/Way\n",
                   dsup_banks, BFIN_DSUBBANKS, BFIN_DWAYS,
                   BFIN_DLINES);
 #ifdef CONFIG_BFIN_ICACHE_LOCK
@@ -625,6 +650,15 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                seq_printf(m, "No Ways are locked\n");
        }
 #endif
+
+       seq_printf(m, "board name\t: %s\n", bfin_board_name);
+       seq_printf(m, "board memory\t: %ld kB (0x%p -> 0x%p)\n",
+                physical_mem_end >> 10, (void *)0, (void *)physical_mem_end);
+       seq_printf(m, "kernel memory\t: %d kB (0x%p -> 0x%p)\n",
+               ((int)memory_end - (int)_stext) >> 10,
+               _stext,
+               (void *)memory_end);
+
        return 0;
 }
 
index 8823e9ade5849b02968442e158990e3c02ade6c6..afd044e78af677ce483fe919408fd5cb98046bb3 100644 (file)
@@ -118,12 +118,14 @@ static int printk_address(unsigned long address)
                                        offset = (address - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT);
 
                                write_unlock_irq(&tasklist_lock);
+                               mmput(mm);
                                return printk("<0x%p> [ %s + 0x%lx ]",
                                              (void *)address, name, offset);
                        }
 
                        vml = vml->next;
                }
+               mmput(mm);
        }
        write_unlock_irq(&tasklist_lock);
 
index 635288fc5f5432c2d3d89d1226968c8bd7077c72..bfdad52c570b9864824738247381a5e1408c5f5f 100644 (file)
@@ -4,7 +4,7 @@
 
 lib-y := \
        ashldi3.o ashrdi3.o lshrdi3.o \
-       muldi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o \
+       muldi3.o divsi3.o udivsi3.o udivdi3.o modsi3.o umodsi3.o \
        checksum.o memcpy.o memset.o memcmp.o memchr.o memmove.o \
        strcmp.o strcpy.o strncmp.o strncpy.o \
        umulsi3_highpart.o smulsi3_highpart.o \
diff --git a/arch/blackfin/lib/udivdi3.S b/arch/blackfin/lib/udivdi3.S
new file mode 100644 (file)
index 0000000..ad1ebee
--- /dev/null
@@ -0,0 +1,375 @@
+/*
+ * udivdi3.S - unsigned long long division
+ *
+ * Copyright 2003-2007 Analog Devices Inc.
+ * Enter bugs at http://blackfin.uclinux.org/
+ *
+ * Licensed under the GPLv2 or later.
+ */
+
+#include <linux/linkage.h>
+
+#define CARRY AC0
+
+#ifdef CONFIG_ARITHMETIC_OPS_L1
+.section .l1.text
+#else
+.text
+#endif
+
+
+ENTRY(___udivdi3)
+   R3 = [SP + 12];
+   [--SP] = (R7:4, P5:3);
+
+   /* Attempt to use divide primitive first; these will handle
+   **  most cases, and they're quick - avoids stalls incurred by
+   ** testing for identities.
+   */
+
+   R4 = R2 | R3;
+   CC = R4 == 0;
+   IF CC JUMP .LDIV_BY_ZERO;
+
+   R4.H = 0x8000;
+   R4 >>>= 16;                  // R4 now 0xFFFF8000
+   R5 = R0 | R2;                // If either dividend or
+   R4 = R5 & R4;                // divisor have bits in
+   CC = R4;                     // top half or low half's sign
+   IF CC JUMP .LIDENTS;          // bit, skip builtins.
+   R4 = R1 | R3;                // Also check top halves
+   CC = R4;
+   IF CC JUMP .LIDENTS;
+
+   /* Can use the builtins. */
+
+   AQ = CC;                     // Clear AQ (CC==0)
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   R0 = R0.L (Z);
+   R1 = 0;
+   (R7:4, P5:3) = [SP++];
+   RTS;
+
+.LIDENTS:
+   /* Test for common identities. Value to be returned is
+   ** placed in R6,R7.
+   */
+                                // Check for 0/y, return 0
+   R4 = R0 | R1;
+   CC = R4 == 0;
+   IF CC JUMP .LRETURN_R0;
+
+                                // Check for x/x, return 1
+   R6 = R0 - R2;                // If x == y, then both R6 and R7 will be zero
+   R7 = R1 - R3;
+   R4 = R6 | R7;                // making R4 zero.
+   R6 += 1;                     // which would now make R6:R7==1.
+   CC = R4 == 0;
+   IF CC JUMP .LRETURN_IDENT;
+
+                                // Check for x/1, return x
+   R6 = R0;
+   R7 = R1;
+   CC = R3 == 0;
+   IF !CC JUMP .Lnexttest;
+   CC = R2 == 1;
+   IF CC JUMP .LRETURN_IDENT;
+
+.Lnexttest:
+   R4.L = ONES R2;              // check for div by power of two which
+   R5.L = ONES R3;              // can be done using a shift
+   R6 = PACK (R5.L, R4.L);
+   CC = R6 == 1;
+   IF CC JUMP .Lpower_of_two_upper_zero;
+   R6 = PACK (R4.L, R5.L);
+   CC = R6 == 1;
+   IF CC JUMP .Lpower_of_two_lower_zero;
+
+                                // Check for x < y, return 0
+   R6 = 0;
+   R7 = R6;
+   CC = R1 < R3 (IU);
+   IF CC JUMP .LRETURN_IDENT;
+   CC = R1 == R3;
+   IF !CC JUMP .Lno_idents;
+   CC = R0 < R2 (IU);
+   IF CC JUMP .LRETURN_IDENT;
+
+.Lno_idents:                    // Idents don't match. Go for the full operation
+
+
+   // If X, or X and Y have high bit set, it'll affect the
+   // results, so shift right one to stop this. Note: we've already
+   // checked that X >= Y, so Y's msb won't be set unless X's
+   // is.
+
+   R4 = 0;
+   CC = R1 < 0;
+   IF !CC JUMP .Lx_msb_clear;
+   CC = !CC;                   // 1 -> 0;
+   R1 = ROT R1 BY -1;          // Shift X >> 1
+   R0 = ROT R0 BY -1;          // lsb -> CC
+   BITSET(R4,31);              // to record only x msb was set
+   CC = R3 < 0;
+   IF !CC JUMP .Ly_msb_clear;
+   CC = !CC;
+   R3 = ROT R3 BY -1;          // Shift Y >> 1
+   R2 = ROT R2 BY -1;
+   BITCLR(R4,31);              // clear bit to record only x msb was set
+
+.Ly_msb_clear:
+.Lx_msb_clear:
+   // Bit 31 in R4 indicates X msb set, but Y msb wasn't, and no bits
+   // were lost, so we should shift result left by one.
+
+   [--SP] = R4;                // save for later
+
+   // In the loop that follows, each iteration we add
+   // either Y' or -Y' to the Remainder. We compute the
+   // negated Y', and store, for convenience. Y' goes
+   // into P0:P1, while -Y' goes into P2:P3.
+
+   P0 = R2;
+   P1 = R3;
+   R2 = -R2;
+   CC = CARRY;
+   CC = !CC;
+   R4 = CC;
+   R3 = -R3;
+   R3 = R3 - R4;
+
+   R6 = 0;                     // remainder = 0
+   R7 = R6;
+
+   [--SP] = R2; P2 = SP;
+   [--SP] = R3; P3 = SP;
+   [--SP] = R6; P5 = SP;       // AQ = 0
+   [--SP] = P1;
+
+   /* In the loop that follows, we use the following
+   ** register assignments:
+   ** R0,R1 X, workspace
+   ** R2,R3 Y, workspace
+   ** R4,R5 partial Div
+   ** R6,R7 partial remainder
+   ** P5 AQ
+   ** The remainder and div form a 128-bit number, with
+   ** the remainder in the high 64-bits.
+   */
+   R4 = R0;                    // Div = X'
+   R5 = R1;
+   R3 = 0;
+
+   P4 = 64;                    // Iterate once per bit
+   LSETUP(.LULST,.LULEND) LC0 = P4;
+.LULST:
+        /* Shift Div and remainder up by one. The bit shifted
+        ** out of the top of the quotient is shifted into the bottom
+        ** of the remainder.
+        */
+        CC = R3;
+        R4 = ROT R4 BY 1;
+        R5 = ROT R5 BY 1 ||        // low q to high q
+             R2 = [P5];            // load saved AQ
+        R6 = ROT R6 BY 1 ||        // high q to low r
+             R0 = [P2];            // load -Y'
+        R7 = ROT R7 BY 1 ||        // low r to high r
+             R1 = [P3];
+
+                                   // Assume add -Y'
+        CC = R2 < 0;               // But if AQ is set...
+        IF CC R0 = P0;             // then add Y' instead
+        IF CC R1 = P1;
+
+        R6 = R6 + R0;              // Rem += (Y' or -Y')
+        CC = CARRY;
+        R0 = CC;
+        R7 = R7 + R1;
+        R7 = R7 + R0 (NS) ||
+             R1 = [SP];
+                                   // Set the next AQ bit
+        R1 = R7 ^ R1;              // from Remainder and Y'
+        R1 = R1 >> 31 ||           // Negate AQ's value, and
+             [P5] = R1;            // save next AQ
+        BITTGL(R1, 0);             // add neg AQ  to the Div
+.LULEND: R4 = R4 + R1;
+
+   R6 = [SP + 16];
+
+   R0 = R4;
+   R1 = R5;
+   CC = BITTST(R6,30);         // Just set CC=0
+   R4 = ROT R0 BY 1;           // but if we had to shift X,
+   R5 = ROT R1 BY 1;           // and didn't shift any bits out,
+   CC = BITTST(R6,31);         // then the result will be half as
+   IF CC R0 = R4;              // much as required, so shift left
+   IF CC R1 = R5;              // one space.
+
+   SP += 20;
+   (R7:4, P5:3) = [SP++];
+   RTS;
+
+.Lpower_of_two:
+   /* Y has a single bit set, which means it's a power of two.
+   ** That means we can perform the division just by shifting
+   ** X to the right the appropriate number of bits
+   */
+
+   /* signbits returns the number of sign bits, minus one.
+   ** 1=>30, 2=>29, ..., 0x40000000=>0. Which means we need
+   ** to shift right n-signbits spaces. It also means 0x80000000
+   ** is a special case, because that *also* gives a signbits of 0
+   */
+.Lpower_of_two_lower_zero:
+   R7 = 0;
+   R6 = R1 >> 31;
+   CC = R3 < 0;
+   IF CC JUMP .LRETURN_IDENT;
+
+   R2.L = SIGNBITS R3;
+   R2 = R2.L (Z);
+   R2 += -62;
+   (R7:4, P5:3) = [SP++];
+   JUMP ___lshftli;
+
+.Lpower_of_two_upper_zero:
+   CC = R2 < 0;
+   IF CC JUMP .Lmaxint_shift;
+
+   R2.L = SIGNBITS R2;
+   R2 = R2.L (Z);
+   R2 += -30;
+   (R7:4, P5:3) = [SP++];
+   JUMP ___lshftli;
+
+.Lmaxint_shift:
+   R2 = -31;
+   (R7:4, P5:3) = [SP++];
+   JUMP ___lshftli;
+
+.LRETURN_IDENT:
+   R0 = R6;
+   R1 = R7;
+.LRETURN_R0:
+   (R7:4, P5:3) = [SP++];
+   RTS;
+.LDIV_BY_ZERO:
+   R0 = ~R2;
+   R1 = R0;
+   (R7:4, P5:3) = [SP++];
+   RTS;
+
+ENDPROC(___udivdi3)
+
+
+ENTRY(___lshftli)
+       CC = R2 == 0;
+       IF CC JUMP .Lfinished;  // nothing to do
+       CC = R2 < 0;
+       IF CC JUMP .Lrshift;
+       R3 = 64;
+       CC = R2 < R3;
+       IF !CC JUMP .Lretzero;
+
+       // We're shifting left, and it's less than 64 bits, so
+       // a valid result will be returned.
+
+       R3 >>= 1;       // R3 now 32
+       CC = R2 < R3;
+
+       IF !CC JUMP .Lzerohalf;
+
+       // We're shifting left, between 1 and 31 bits, which means
+       // some of the low half will be shifted into the high half.
+       // Work out how much.
+
+       R3 = R3 - R2;
+
+       // Save that much data from the bottom half.
+
+       P1 = R7;
+       R7 = R0;
+       R7 >>= R3;
+
+       // Adjust both parts of the parameter.
+
+       R0 <<= R2;
+       R1 <<= R2;
+
+       // And include the bits moved across.
+
+       R1 = R1 | R7;
+       R7 = P1;
+       RTS;
+
+.Lzerohalf:
+       // We're shifting left, between 32 and 63 bits, so the
+       // bottom half will become zero, and the top half will
+       // lose some bits. How many?
+
+       R2 = R2 - R3;   // N - 32
+       R1 = LSHIFT R0 BY R2.L;
+       R0 = R0 - R0;
+       RTS;
+
+.Lretzero:
+       R0 = R0 - R0;
+       R1 = R0;
+.Lfinished:
+       RTS;
+
+.Lrshift:
+       // We're shifting right, but by how much?
+       R2 = -R2;
+       R3 = 64;
+       CC = R2 < R3;
+       IF !CC JUMP .Lretzero;
+
+       // Shifting right less than 64 bits, so some result bits will
+       // be retained.
+
+       R3 >>= 1;       // R3 now 32
+       CC = R2 < R3;
+       IF !CC JUMP .Lsignhalf;
+
+       // Shifting right between 1 and 31 bits, so need to copy
+       // data across words.
+
+       P1 = R7;
+       R3 = R3 - R2;
+       R7 = R1;
+       R7 <<= R3;
+       R1 >>= R2;
+       R0 >>= R2;
+       R0 = R7 | R0;
+       R7 = P1;
+       RTS;
+
+.Lsignhalf:
+       // Shifting right between 32 and 63 bits, so the top half
+       // will become all zero-bits, and the bottom half is some
+       // of the top half. But how much?
+
+       R2 = R2 - R3;
+       R0 = R1;
+       R0 >>= R2;
+       R1 = 0;
+       RTS;
+
+ENDPROC(___lshftli)
diff --git a/arch/blackfin/mach-bf527/Kconfig b/arch/blackfin/mach-bf527/Kconfig
new file mode 100644 (file)
index 0000000..50321f7
--- /dev/null
@@ -0,0 +1,251 @@
+if (BF52x)
+
+menu "BF527 Specific Configuration"
+
+comment "Alternative Multiplexing Scheme"
+
+choice
+       prompt "SPORT0"
+       default BF527_SPORT0_PORTG
+       help
+         Select PORT used for SPORT0. See Hardware Reference Manual
+
+config BF527_SPORT0_PORTF
+       bool "PORT F"
+       help
+         PORT F
+
+config BF527_SPORT0_PORTG
+       bool "PORT G"
+       help
+         PORT G
+endchoice
+
+choice
+       prompt "SPORT0 TSCLK Location"
+       depends on BF527_SPORT0_PORTG
+       default BF527_SPORT0_TSCLK_PG10
+       help
+         Select PIN used for SPORT0_TSCLK. See Hardware Reference Manual
+
+config BF527_SPORT0_TSCLK_PG10
+       bool "PORT PG10"
+       help
+         PORT PG10
+
+config BF527_SPORT0_TSCLK_PG14
+       bool "PORT PG14"
+       help
+         PORT PG14
+endchoice
+
+choice
+       prompt "UART1"
+       default BF527_UART1_PORTG
+       help
+         Select PORT used for UART1. See Hardware Reference Manual
+
+config BF527_UART1_PORTF
+       bool "PORT F"
+       help
+         PORT F
+
+config BF527_UART1_PORTG
+       bool "PORT G"
+       help
+         PORT G
+endchoice
+
+choice
+       prompt "NAND (NFC) Data"
+       default BF527_NAND_D_PORTH
+       help
+         Select PORT used for NAND Data Bus. See Hardware Reference Manual
+
+config BF527_NAND_D_PORTF
+       bool "PORT F"
+       help
+         PORT F
+
+config BF527_NAND_D_PORTH
+       bool "PORT H"
+       help
+         PORT H
+endchoice
+
+comment "Interrupt Priority Assignment"
+menu "Priority"
+
+config IRQ_PLL_WAKEUP
+       int "IRQ_PLL_WAKEUP"
+       default 7
+config IRQ_DMA0_ERROR
+       int "IRQ_DMA0_ERROR"
+       default 7
+config IRQ_DMAR0_BLK
+       int "IRQ_DMAR0_BLK"
+       default 7
+config IRQ_DMAR1_BLK
+       int "IRQ_DMAR1_BLK"
+       default 7
+config IRQ_DMAR0_OVR
+       int "IRQ_DMAR0_OVR"
+       default 7
+config IRQ_DMAR1_OVR
+       int "IRQ_DMAR1_OVR"
+       default 7
+config IRQ_PPI_ERROR
+       int "IRQ_PPI_ERROR"
+       default 7
+config IRQ_MAC_ERROR
+       int "IRQ_MAC_ERROR"
+       default 7
+config IRQ_SPORT0_ERROR
+       int "IRQ_SPORT0_ERROR"
+       default 7
+config IRQ_SPORT1_ERROR
+       int "IRQ_SPORT1_ERROR"
+       default 7
+config IRQ_UART0_ERROR
+       int "IRQ_UART0_ERROR"
+       default 7
+config IRQ_UART1_ERROR
+       int "IRQ_UART1_ERROR"
+       default 7
+config IRQ_RTC
+       int "IRQ_RTC"
+       default 8
+config IRQ_PPI
+       int "IRQ_PPI"
+       default 8
+config IRQ_SPORT0_RX
+       int "IRQ_SPORT0_RX"
+       default 9
+config IRQ_SPORT0_TX
+       int "IRQ_SPORT0_TX"
+       default 9
+config IRQ_SPORT1_RX
+       int "IRQ_SPORT1_RX"
+       default 9
+config IRQ_SPORT1_TX
+       int "IRQ_SPORT1_TX"
+       default 9
+config IRQ_TWI
+       int "IRQ_TWI"
+       default 10
+config IRQ_SPI
+       int "IRQ_SPI"
+       default 10
+config IRQ_UART0_RX
+       int "IRQ_UART0_RX"
+       default 10
+config IRQ_UART0_TX
+       int "IRQ_UART0_TX"
+       default 10
+config IRQ_UART1_RX
+       int "IRQ_UART1_RX"
+       default 10
+config IRQ_UART1_TX
+       int "IRQ_UART1_TX"
+       default 10
+config IRQ_OPTSEC
+       int "IRQ_OPTSEC"
+       default 11
+config IRQ_CNT
+       int "IRQ_CNT"
+       default 11
+config IRQ_MAC_RX
+       int "IRQ_MAC_RX"
+       default 11
+config IRQ_PORTH_INTA
+       int "IRQ_PORTH_INTA"
+       default 11
+config IRQ_MAC_TX
+       int "IRQ_MAC_TX/NFC"
+       default 11
+config IRQ_PORTH_INTB
+       int "IRQ_PORTH_INTB"
+       default 11
+config IRQ_TMR0
+       int "IRQ_TMR0"
+       default 12
+config IRQ_TMR1
+       int "IRQ_TMR1"
+       default 12
+config IRQ_TMR2
+       int "IRQ_TMR2"
+       default 12
+config IRQ_TMR3
+       int "IRQ_TMR3"
+       default 12
+config IRQ_TMR4
+       int "IRQ_TMR4"
+       default 12
+config IRQ_TMR5
+       int "IRQ_TMR5"
+       default 12
+config IRQ_TMR6
+       int "IRQ_TMR6"
+       default 12
+config IRQ_TMR7
+       int "IRQ_TMR7"
+       default 12
+config IRQ_PORTG_INTA
+       int "IRQ_PORTG_INTA"
+       default 12
+config IRQ_PORTG_INTB
+       int "IRQ_PORTG_INTB"
+       default 12
+config IRQ_MEM_DMA0
+       int "IRQ_MEM_DMA0"
+       default 13
+config IRQ_MEM_DMA1
+       int "IRQ_MEM_DMA1"
+       default 13
+config IRQ_WATCH
+       int "IRQ_WATCH"
+       default 13
+config IRQ_PORTF_INTA
+       int "IRQ_PORTF_INTA"
+       default 13
+config IRQ_PORTF_INTB
+       int "IRQ_PORTF_INTB"
+       default 13
+config IRQ_SPI_ERROR
+       int "IRQ_SPI_ERROR"
+       default 7
+config IRQ_NFC_ERROR
+       int "IRQ_NFC_ERROR"
+       default 7
+config IRQ_HDMA_ERROR
+       int "IRQ_HDMA_ERROR"
+       default 7
+config IRQ_HDMA
+       int "IRQ_HDMA"
+       default 7
+config IRQ_USB_EINT
+       int "IRQ_USB_EINT"
+       default 10
+config IRQ_USB_INT0
+       int "IRQ_USB_INT0"
+       default 10
+config IRQ_USB_INT1
+       int "IRQ_USB_INT1"
+       default 10
+config IRQ_USB_INT2
+       int "IRQ_USB_INT2"
+       default 10
+config IRQ_USB_DMA
+       int "IRQ_USB_DMA"
+       default 10
+
+       help
+         Enter the priority numbers between 7-13 ONLY.  Others are Reserved.
+         This applies to all the above.  It is not recommended to assign the
+         highest priority number 7 to UART or any other device.
+
+endmenu
+
+endmenu
+
+endif
diff --git a/arch/blackfin/mach-bf527/Makefile b/arch/blackfin/mach-bf527/Makefile
new file mode 100644 (file)
index 0000000..9f99f5d
--- /dev/null
@@ -0,0 +1,9 @@
+#
+# arch/blackfin/mach-bf527/Makefile
+#
+
+extra-y := head.o
+
+obj-y := ints-priority.o dma.o
+
+obj-$(CONFIG_CPU_FREQ)   += cpu.o
diff --git a/arch/blackfin/mach-bf527/boards/Makefile b/arch/blackfin/mach-bf527/boards/Makefile
new file mode 100644 (file)
index 0000000..912ac8e
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# arch/blackfin/mach-bf532/boards/Makefile
+#
+
+obj-y                                  += eth_mac.o
+obj-$(CONFIG_BFIN527_EZKIT)            += ezkit.o
+
diff --git a/arch/blackfin/mach-bf527/boards/eth_mac.c b/arch/blackfin/mach-bf527/boards/eth_mac.c
new file mode 100644 (file)
index 0000000..a725cc8
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ *  arch/blackfin/mach-bf537/board/eth_mac.c
+ *
+ *  Copyright (C) 2007 Analog Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <asm/blackfin.h>
+
+#if    defined(CONFIG_GENERIC_BOARD) || defined(CONFIG_BFIN537_STAMP)
+
+/*
+ * Currently the MAC address is saved in Flash by U-Boot
+ */
+#define FLASH_MAC      0x203f0000
+
+void get_bf537_ether_addr(char *addr)
+{
+       unsigned int flash_mac = (unsigned int) FLASH_MAC;
+       *(u32 *)(&(addr[0])) = bfin_read32(flash_mac);
+       flash_mac += 4;
+       *(u16 *)(&(addr[4])) = bfin_read16(flash_mac);
+}
+
+#else
+
+/*
+ * Provide MAC address function for other specific board setting
+ */
+void get_bf537_ether_addr(char *addr)
+{
+       printk(KERN_WARNING "%s: No valid Ethernet MAC address found\n", __FILE__);
+}
+
+#endif
+
+EXPORT_SYMBOL(get_bf537_ether_addr);
diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c
new file mode 100644 (file)
index 0000000..3e884f3
--- /dev/null
@@ -0,0 +1,737 @@
+/*
+ * File:         arch/blackfin/mach-bf527/boards/ezkit.c
+ * Based on:     arch/blackfin/mach-bf537/boards/stamp.c
+ * Author:       Aidan Williams <aidan@nicta.com.au>
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ *               Copyright 2005 National ICT Australia (NICTA)
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+#include <linux/usb_isp1362.h>
+#endif
+#include <linux/pata_platform.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/usb_sl811.h>
+#include <asm/dma.h>
+#include <asm/bfin5xx_spi.h>
+#include <asm/reboot.h>
+#include <linux/spi/ad7877.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+const char bfin_board_name[] = "ADDS-BF527-EZKIT";
+
+/*
+ *  Driver needs to know address, irq and flag pin.
+ */
+
+#define ISP1761_BASE       0x203C0000
+#define ISP1761_IRQ        IRQ_PF7
+
+#if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE)
+static struct resource bfin_isp1761_resources[] = {
+       [0] = {
+               .name   = "isp1761-regs",
+               .start  = ISP1761_BASE + 0x00000000,
+               .end    = ISP1761_BASE + 0x000fffff,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = ISP1761_IRQ,
+               .end    = ISP1761_IRQ,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bfin_isp1761_device = {
+       .name           = "isp1761",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(bfin_isp1761_resources),
+       .resource       = bfin_isp1761_resources,
+};
+
+static struct platform_device *bfin_isp1761_devices[] = {
+       &bfin_isp1761_device,
+};
+
+int __init bfin_isp1761_init(void)
+{
+       unsigned int num_devices = ARRAY_SIZE(bfin_isp1761_devices);
+
+       printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+       set_irq_type(ISP1761_IRQ, IRQF_TRIGGER_FALLING);
+
+       return platform_add_devices(bfin_isp1761_devices, num_devices);
+}
+
+void __exit bfin_isp1761_exit(void)
+{
+       platform_device_unregister(&bfin_isp1761_device);
+}
+
+arch_initcall(bfin_isp1761_init);
+#endif
+
+#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
+static struct resource bfin_pcmcia_cf_resources[] = {
+       {
+               .start = 0x20310000, /* IO PORT */
+               .end = 0x20312000,
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = 0x20311000, /* Attribute Memory */
+               .end = 0x20311FFF,
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = IRQ_PF4,
+               .end = IRQ_PF4,
+               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+       }, {
+               .start = 6, /* Card Detect PF6 */
+               .end = 6,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bfin_pcmcia_cf_device = {
+       .name = "bfin_cf_pcmcia",
+       .id = -1,
+       .num_resources = ARRAY_SIZE(bfin_pcmcia_cf_resources),
+       .resource = bfin_pcmcia_cf_resources,
+};
+#endif
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+static struct platform_device rtc_device = {
+       .name = "rtc-bfin",
+       .id   = -1,
+};
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+static struct resource smc91x_resources[] = {
+       {
+               .name = "smc91x-regs",
+               .start = 0x20300300,
+               .end = 0x20300300 + 16,
+               .flags = IORESOURCE_MEM,
+       }, {
+
+               .start = IRQ_PF7,
+               .end = IRQ_PF7,
+               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+       },
+};
+static struct platform_device smc91x_device = {
+       .name = "smc91x",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(smc91x_resources),
+       .resource = smc91x_resources,
+};
+#endif
+
+#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
+static struct resource dm9000_resources[] = {
+       [0] = {
+               .start  = 0x203FB800,
+               .end    = 0x203FB800 + 8,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_PF9,
+               .end    = IRQ_PF9,
+               .flags  = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE),
+       },
+};
+
+static struct platform_device dm9000_device = {
+       .name           = "dm9000",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(dm9000_resources),
+       .resource       = dm9000_resources,
+};
+#endif
+
+#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
+static struct resource sl811_hcd_resources[] = {
+       {
+               .start = 0x20340000,
+               .end = 0x20340000,
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = 0x20340004,
+               .end = 0x20340004,
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = CONFIG_USB_SL811_BFIN_IRQ,
+               .end = CONFIG_USB_SL811_BFIN_IRQ,
+               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+       },
+};
+
+#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
+void sl811_port_power(struct device *dev, int is_on)
+{
+       gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS");
+       gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS);
+
+       if (is_on)
+               gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 1);
+       else
+               gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 0);
+}
+#endif
+
+static struct sl811_platform_data sl811_priv = {
+       .potpg = 10,
+       .power = 250,       /* == 500mA */
+#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
+       .port_power = &sl811_port_power,
+#endif
+};
+
+static struct platform_device sl811_hcd_device = {
+       .name = "sl811-hcd",
+       .id = 0,
+       .dev = {
+               .platform_data = &sl811_priv,
+       },
+       .num_resources = ARRAY_SIZE(sl811_hcd_resources),
+       .resource = sl811_hcd_resources,
+};
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+static struct resource isp1362_hcd_resources[] = {
+       {
+               .start = 0x20360000,
+               .end = 0x20360000,
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = 0x20360004,
+               .end = 0x20360004,
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
+               .end = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
+               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+       },
+};
+
+static struct isp1362_platform_data isp1362_priv = {
+       .sel15Kres = 1,
+       .clknotstop = 0,
+       .oc_enable = 0,
+       .int_act_high = 0,
+       .int_edge_triggered = 0,
+       .remote_wakeup_connected = 0,
+       .no_power_switching = 1,
+       .power_switching_mode = 0,
+};
+
+static struct platform_device isp1362_hcd_device = {
+       .name = "isp1362-hcd",
+       .id = 0,
+       .dev = {
+               .platform_data = &isp1362_priv,
+       },
+       .num_resources = ARRAY_SIZE(isp1362_hcd_resources),
+       .resource = isp1362_hcd_resources,
+};
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static struct platform_device bfin_mac_device = {
+       .name = "bfin_mac",
+};
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+static struct resource net2272_bfin_resources[] = {
+       {
+               .start = 0x20300000,
+               .end = 0x20300000 + 0x100,
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = IRQ_PF7,
+               .end = IRQ_PF7,
+               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+       },
+};
+
+static struct platform_device net2272_bfin_device = {
+       .name = "net2272",
+       .id = -1,
+       .num_resources = ARRAY_SIZE(net2272_bfin_resources),
+       .resource = net2272_bfin_resources,
+};
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+/* all SPI peripherals info goes here */
+
+#if defined(CONFIG_MTD_M25P80) \
+       || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition bfin_spi_flash_partitions[] = {
+       {
+               .name = "bootloader",
+               .size = 0x00020000,
+               .offset = 0,
+               .mask_flags = MTD_CAP_ROM
+       }, {
+               .name = "kernel",
+               .size = 0xe0000,
+               .offset = 0x20000
+       }, {
+               .name = "file system",
+               .size = 0x700000,
+               .offset = 0x00100000,
+       }
+};
+
+static struct flash_platform_data bfin_spi_flash_data = {
+       .name = "m25p80",
+       .parts = bfin_spi_flash_partitions,
+       .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
+       .type = "m25p64",
+};
+
+/* SPI flash chip (m25p64) */
+static struct bfin5xx_spi_chip spi_flash_chip_info = {
+       .enable_dma = 0,         /* use dma transfer with this chip*/
+       .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) \
+       || defined(CONFIG_SPI_ADC_BF533_MODULE)
+/* SPI ADC chip */
+static struct bfin5xx_spi_chip spi_adc_chip_info = {
+       .enable_dma = 1,         /* use dma transfer with this chip*/
+       .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) \
+       || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
+       .enable_dma = 0,
+       .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
+static struct bfin5xx_spi_chip ad9960_spi_chip_info = {
+       .enable_dma = 0,
+       .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
+static struct bfin5xx_spi_chip spi_mmc_chip_info = {
+       .enable_dma = 1,
+       .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_PBX)
+static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
+       .ctl_reg        = 0x4, /* send zero */
+       .enable_dma     = 0,
+       .bits_per_word  = 8,
+       .cs_change_per_word = 1,
+};
+#endif
+
+#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
+static struct bfin5xx_spi_chip ad5304_chip_info = {
+       .enable_dma = 0,
+       .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
+static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
+       .enable_dma = 0,
+       .bits_per_word = 16,
+};
+
+static const struct ad7877_platform_data bfin_ad7877_ts_info = {
+       .model                  = 7877,
+       .vref_delay_usecs       = 50,   /* internal, no capacitor */
+       .x_plate_ohms           = 419,
+       .y_plate_ohms           = 486,
+       .pressure_max           = 1000,
+       .pressure_min           = 0,
+       .stopacq_polarity       = 1,
+       .first_conversion_delay = 3,
+       .acquisition_time       = 1,
+       .averaging              = 1,
+       .pen_down_acc_interval  = 1,
+};
+#endif
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80) \
+       || defined(CONFIG_MTD_M25P80_MODULE)
+       {
+               /* the modalias must be the same as spi device driver name */
+               .modalias = "m25p80", /* Name of spi_driver for this device */
+               .max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0, /* Framework bus number */
+               .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/
+               .platform_data = &bfin_spi_flash_data,
+               .controller_data = &spi_flash_chip_info,
+               .mode = SPI_MODE_3,
+       },
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) \
+       || defined(CONFIG_SPI_ADC_BF533_MODULE)
+       {
+               .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
+               .max_speed_hz = 6250000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0, /* Framework bus number */
+               .chip_select = 1, /* Framework chip select. */
+               .platform_data = NULL, /* No spi_driver specific config */
+               .controller_data = &spi_adc_chip_info,
+       },
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) \
+       || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+       {
+               .modalias = "ad1836-spi",
+               .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0,
+               .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+               .controller_data = &ad1836_spi_chip_info,
+       },
+#endif
+#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
+       {
+               .modalias = "ad9960-spi",
+               .max_speed_hz = 10000000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0,
+               .chip_select = 1,
+               .controller_data = &ad9960_spi_chip_info,
+       },
+#endif
+#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
+       {
+               .modalias = "spi_mmc_dummy",
+               .max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0,
+               .chip_select = 0,
+               .platform_data = NULL,
+               .controller_data = &spi_mmc_chip_info,
+               .mode = SPI_MODE_3,
+       },
+       {
+               .modalias = "spi_mmc",
+               .max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0,
+               .chip_select = CONFIG_SPI_MMC_CS_CHAN,
+               .platform_data = NULL,
+               .controller_data = &spi_mmc_chip_info,
+               .mode = SPI_MODE_3,
+       },
+#endif
+#if defined(CONFIG_PBX)
+       {
+               .modalias = "fxs-spi",
+               .max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0,
+               .chip_select = 8 - CONFIG_J11_JUMPER,
+               .controller_data = &spi_si3xxx_chip_info,
+               .mode = SPI_MODE_3,
+       },
+       {
+               .modalias = "fxo-spi",
+               .max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0,
+               .chip_select = 8 - CONFIG_J19_JUMPER,
+               .controller_data = &spi_si3xxx_chip_info,
+               .mode = SPI_MODE_3,
+       },
+#endif
+#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
+       {
+               .modalias = "ad5304_spi",
+               .max_speed_hz = 1250000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0,
+               .chip_select = 2,
+               .platform_data = NULL,
+               .controller_data = &ad5304_chip_info,
+               .mode = SPI_MODE_2,
+       },
+#endif
+#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
+       {
+               .modalias               = "ad7877",
+               .platform_data          = &bfin_ad7877_ts_info,
+               .irq                    = IRQ_PF6,
+               .max_speed_hz   = 12500000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num        = 1,
+               .chip_select  = 1,
+               .controller_data = &spi_ad7877_chip_info,
+       },
+#endif
+};
+
+/* SPI controller data */
+static struct bfin5xx_spi_master bfin_spi0_info = {
+       .num_chipselect = 8,
+       .enable_dma = 1,  /* master has the ability to do dma transfer */
+};
+
+/* SPI (0) */
+static struct resource bfin_spi0_resource[] = {
+       [0] = {
+               .start = SPI0_REGBASE,
+               .end   = SPI0_REGBASE + 0xFF,
+               .flags = IORESOURCE_MEM,
+               },
+       [1] = {
+               .start = CH_SPI,
+               .end   = CH_SPI,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bfin_spi0_device = {
+       .name = "bfin-spi",
+       .id = 0, /* Bus number */
+       .num_resources = ARRAY_SIZE(bfin_spi0_resource),
+       .resource = bfin_spi0_resource,
+       .dev = {
+               .platform_data = &bfin_spi0_info, /* Passed to driver */
+       },
+};
+#endif  /* spi master and devices */
+
+#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
+static struct platform_device bfin_fb_device = {
+       .name = "bf537-lq035",
+};
+#endif
+
+#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
+static struct platform_device bfin_fb_adv7393_device = {
+       .name = "bfin-adv7393",
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       {
+               .start = 0xFFC00400,
+               .end = 0xFFC004FF,
+               .flags = IORESOURCE_MEM,
+       },
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       {
+               .start = 0xFFC02000,
+               .end = 0xFFC020FF,
+               .flags = IORESOURCE_MEM,
+       },
+#endif
+};
+
+static struct platform_device bfin_uart_device = {
+       .name = "bfin-uart",
+       .id = 1,
+       .num_resources = ARRAY_SIZE(bfin_uart_resources),
+       .resource = bfin_uart_resources,
+};
+#endif
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+static struct resource bfin_twi0_resource[] = {
+       [0] = {
+               .start = TWI0_REGBASE,
+               .end   = TWI0_REGBASE,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_TWI,
+               .end   = IRQ_TWI,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device i2c_bfin_twi_device = {
+       .name = "i2c-bfin-twi",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_twi0_resource),
+       .resource = bfin_twi0_resource,
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+static struct platform_device bfin_sport0_uart_device = {
+       .name = "bfin-sport-uart",
+       .id = 0,
+};
+
+static struct platform_device bfin_sport1_uart_device = {
+       .name = "bfin-sport-uart",
+       .id = 1,
+};
+#endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+#define PATA_INT       55
+
+static struct pata_platform_info bfin_pata_platform_data = {
+       .ioport_shift = 1,
+       .irq_type = IRQF_TRIGGER_HIGH | IRQF_DISABLED,
+};
+
+static struct resource bfin_pata_resources[] = {
+       {
+               .start = 0x20314020,
+               .end = 0x2031403F,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = 0x2031401C,
+               .end = 0x2031401F,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = PATA_INT,
+               .end = PATA_INT,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bfin_pata_device = {
+       .name = "pata_platform",
+       .id = -1,
+       .num_resources = ARRAY_SIZE(bfin_pata_resources),
+       .resource = bfin_pata_resources,
+       .dev = {
+               .platform_data = &bfin_pata_platform_data,
+       }
+};
+#endif
+
+static struct platform_device *stamp_devices[] __initdata = {
+#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
+       &bfin_pcmcia_cf_device,
+#endif
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+       &rtc_device,
+#endif
+
+#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
+       &sl811_hcd_device,
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+       &isp1362_hcd_device,
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+       &smc91x_device,
+#endif
+
+#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
+       &dm9000_device,
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+       &bfin_mac_device,
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+       &net2272_bfin_device,
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+       &bfin_spi0_device,
+#endif
+
+#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
+       &bfin_fb_device,
+#endif
+
+#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
+       &bfin_fb_adv7393_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+       &bfin_uart_device,
+#endif
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+       &i2c_bfin_twi_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+       &bfin_sport0_uart_device,
+       &bfin_sport1_uart_device,
+#endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+       &bfin_pata_device,
+#endif
+};
+
+static int __init stamp_init(void)
+{
+       printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+       platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+       spi_register_board_info(bfin_spi_board_info,
+                               ARRAY_SIZE(bfin_spi_board_info));
+#endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+       irq_desc[PATA_INT].status |= IRQ_NOAUTOEN;
+#endif
+       return 0;
+}
+
+arch_initcall(stamp_init);
+
+void native_machine_restart(char *cmd)
+{
+       /* workaround reboot hang when booting from SPI */
+       if ((bfin_read_SYSCR() & 0x7) == 0x3)
+               bfin_gpio_reset_spi0_ssel1();
+}
diff --git a/arch/blackfin/mach-bf527/cpu.c b/arch/blackfin/mach-bf527/cpu.c
new file mode 100644 (file)
index 0000000..1975402
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * File:         arch/blackfin/mach-bf527/cpu.c
+ * Based on:   arch/blackfin/mach-bf537/cpu.c
+ * Author:       michael.kang@analog.com
+ *
+ * Created:
+ * Description:  clock scaling for the bf527
+ *
+ * Modified:
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <asm/dpmc.h>
+#include <linux/fs.h>
+#include <asm/bfin-global.h>
+
+/* CONFIG_CLKIN_HZ=11059200 */
+#define VCO5 (CONFIG_CLKIN_HZ*45)      /*497664000 */
+#define VCO4 (CONFIG_CLKIN_HZ*36)      /*398131200 */
+#define VCO3 (CONFIG_CLKIN_HZ*27)      /*298598400 */
+#define VCO2 (CONFIG_CLKIN_HZ*18)      /*199065600 */
+#define VCO1 (CONFIG_CLKIN_HZ*9)       /*99532800 */
+#define VCO(x) VCO##x
+
+#define MFREQ(x) {VCO(x), VCO(x)/4}, {VCO(x), VCO(x)/2}, {VCO(x), VCO(x)}
+/* frequency */
+static struct cpufreq_frequency_table bf527_freq_table[] = {
+       MFREQ(1),
+       MFREQ(3),
+       {VCO4, VCO4 / 2}, {VCO4, VCO4},
+       MFREQ(5),
+       {0, CPUFREQ_TABLE_END},
+};
+
+/*
+ * dpmc_fops->ioctl()
+ * static int dpmc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+ */
+static int bf527_getfreq(unsigned int cpu)
+{
+       unsigned long cclk_mhz;
+
+       /* The driver only support single cpu */
+       if (cpu == 0)
+               dpmc_fops.ioctl(NULL, NULL, IOCTL_GET_CORECLOCK, &cclk_mhz);
+       else
+               cclk_mhz = -1;
+
+       return cclk_mhz;
+}
+
+static int bf527_target(struct cpufreq_policy *policy,
+                       unsigned int target_freq, unsigned int relation)
+{
+       unsigned long cclk_mhz;
+       unsigned long vco_mhz;
+       unsigned long flags;
+       unsigned int index;
+       struct cpufreq_freqs freqs;
+
+       if (cpufreq_frequency_table_target
+           (policy, bf527_freq_table, target_freq, relation, &index))
+               return -EINVAL;
+
+       cclk_mhz = bf527_freq_table[index].frequency;
+       vco_mhz = bf527_freq_table[index].index;
+
+       dpmc_fops.ioctl(NULL, NULL, IOCTL_CHANGE_FREQUENCY, &vco_mhz);
+       freqs.old = bf527_getfreq(0);
+       freqs.new = cclk_mhz;
+       freqs.cpu = 0;
+
+       pr_debug
+           ("cclk begin change to cclk %d,vco=%d,index=%d,target=%d,oldfreq=%d\n",
+            cclk_mhz, vco_mhz, index, target_freq, freqs.old);
+
+       cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+       local_irq_save(flags);
+       dpmc_fops.ioctl(NULL, NULL, IOCTL_SET_CCLK, &cclk_mhz);
+       local_irq_restore(flags);
+       cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+       vco_mhz = get_vco();
+       cclk_mhz = get_cclk();
+       return 0;
+}
+
+/* make sure that only the "userspace" governor is run -- anything else wouldn't make sense on
+ * this platform, anyway.
+ */
+static int bf527_verify_speed(struct cpufreq_policy *policy)
+{
+       return cpufreq_frequency_table_verify(policy, &bf527_freq_table);
+}
+
+static int __init __bf527_cpu_init(struct cpufreq_policy *policy)
+{
+       if (policy->cpu != 0)
+               return -EINVAL;
+
+       policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+
+       policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+       /*Now ,only support one cpu */
+       policy->cur = bf527_getfreq(0);
+       cpufreq_frequency_table_get_attr(bf527_freq_table, policy->cpu);
+       return cpufreq_frequency_table_cpuinfo(policy, bf527_freq_table);
+}
+
+static struct freq_attr *bf527_freq_attr[] = {
+       &cpufreq_freq_attr_scaling_available_freqs,
+       NULL,
+};
+
+static struct cpufreq_driver bf527_driver = {
+       .verify = bf527_verify_speed,
+       .target = bf527_target,
+       .get = bf527_getfreq,
+       .init = __bf527_cpu_init,
+       .name = "bf527",
+       .owner = THIS_MODULE,
+       .attr = bf527_freq_attr,
+};
+
+static int __init bf527_cpu_init(void)
+{
+       return cpufreq_register_driver(&bf527_driver);
+}
+
+static void __exit bf527_cpu_exit(void)
+{
+       cpufreq_unregister_driver(&bf527_driver);
+}
+
+MODULE_AUTHOR("Mickael Kang");
+MODULE_DESCRIPTION("cpufreq driver for bf527 CPU");
+MODULE_LICENSE("GPL");
+
+module_init(bf527_cpu_init);
+module_exit(bf527_cpu_exit);
diff --git a/arch/blackfin/mach-bf527/dma.c b/arch/blackfin/mach-bf527/dma.c
new file mode 100644 (file)
index 0000000..522de24
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * File:         arch/blackfin/mach-bf527/dma.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:  This file contains the simple DMA Implementation for Blackfin
+ *
+ * Modified:
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <asm/blackfin.h>
+#include <asm/dma.h>
+
+struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL] = {
+       (struct dma_register *) DMA0_NEXT_DESC_PTR,
+       (struct dma_register *) DMA1_NEXT_DESC_PTR,
+       (struct dma_register *) DMA2_NEXT_DESC_PTR,
+       (struct dma_register *) DMA3_NEXT_DESC_PTR,
+       (struct dma_register *) DMA4_NEXT_DESC_PTR,
+       (struct dma_register *) DMA5_NEXT_DESC_PTR,
+       (struct dma_register *) DMA6_NEXT_DESC_PTR,
+       (struct dma_register *) DMA7_NEXT_DESC_PTR,
+       (struct dma_register *) DMA8_NEXT_DESC_PTR,
+       (struct dma_register *) DMA9_NEXT_DESC_PTR,
+       (struct dma_register *) DMA10_NEXT_DESC_PTR,
+       (struct dma_register *) DMA11_NEXT_DESC_PTR,
+       (struct dma_register *) MDMA_D0_NEXT_DESC_PTR,
+       (struct dma_register *) MDMA_S0_NEXT_DESC_PTR,
+       (struct dma_register *) MDMA_D1_NEXT_DESC_PTR,
+       (struct dma_register *) MDMA_S1_NEXT_DESC_PTR,
+};
+
+int channel2irq(unsigned int channel)
+{
+       int ret_irq = -1;
+
+       switch (channel) {
+       case CH_PPI:
+               ret_irq = IRQ_PPI;
+               break;
+
+       case CH_EMAC_RX:
+               ret_irq = IRQ_MAC_RX;
+               break;
+
+       case CH_EMAC_TX:
+               ret_irq = IRQ_MAC_TX;
+               break;
+
+       case CH_UART1_RX:
+               ret_irq = IRQ_UART1_RX;
+               break;
+
+       case CH_UART1_TX:
+               ret_irq = IRQ_UART1_TX;
+               break;
+
+       case CH_SPORT0_RX:
+               ret_irq = IRQ_SPORT0_RX;
+               break;
+
+       case CH_SPORT0_TX:
+               ret_irq = IRQ_SPORT0_TX;
+               break;
+
+       case CH_SPORT1_RX:
+               ret_irq = IRQ_SPORT1_RX;
+               break;
+
+       case CH_SPORT1_TX:
+               ret_irq = IRQ_SPORT1_TX;
+               break;
+
+       case CH_SPI:
+               ret_irq = IRQ_SPI;
+               break;
+
+       case CH_UART0_RX:
+               ret_irq = IRQ_UART0_RX;
+               break;
+
+       case CH_UART0_TX:
+               ret_irq = IRQ_UART0_TX;
+               break;
+
+       case CH_MEM_STREAM0_SRC:
+       case CH_MEM_STREAM0_DEST:
+               ret_irq = IRQ_MEM_DMA0;
+               break;
+
+       case CH_MEM_STREAM1_SRC:
+       case CH_MEM_STREAM1_DEST:
+               ret_irq = IRQ_MEM_DMA1;
+               break;
+       }
+       return ret_irq;
+}
diff --git a/arch/blackfin/mach-bf527/head.S b/arch/blackfin/mach-bf527/head.S
new file mode 100644 (file)
index 0000000..cdb00a0
--- /dev/null
@@ -0,0 +1,456 @@
+/*
+ * File:         arch/blackfin/mach-bf527/head.S
+ * Based on:     arch/blackfin/mach-bf533/head.S
+ * Author:       Jeff Dionne <jeff@uclinux.org> COPYRIGHT 1998 D. Jeff Dionne
+ *
+ * Created:      1998
+ * Description:  Startup code for Blackfin BF537
+ *
+ * Modified:
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/blackfin.h>
+#include <asm/trace.h>
+
+#if CONFIG_BFIN_KERNEL_CLOCK
+#include <asm/mach-common/clocks.h>
+#include <asm/mach/mem_init.h>
+#endif
+
+.global __rambase
+.global __ramstart
+.global __ramend
+.extern ___bss_stop
+.extern ___bss_start
+.extern _bf53x_relocate_l1_mem
+
+#define INITIAL_STACK  0xFFB01000
+
+__INIT
+
+ENTRY(__start)
+       /* R0: argument of command line string, passed from uboot, save it */
+       R7 = R0;
+       /* Enable Cycle Counter and Nesting Of Interrupts */
+#ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES
+       R0 = SYSCFG_SNEN;
+#else
+       R0 = SYSCFG_SNEN | SYSCFG_CCEN;
+#endif
+       SYSCFG = R0;
+       R0 = 0;
+
+       /* Clear Out All the data and pointer Registers */
+       R1 = R0;
+       R2 = R0;
+       R3 = R0;
+       R4 = R0;
+       R5 = R0;
+       R6 = R0;
+
+       P0 = R0;
+       P1 = R0;
+       P2 = R0;
+       P3 = R0;
+       P4 = R0;
+       P5 = R0;
+
+       LC0 = r0;
+       LC1 = r0;
+       L0 = r0;
+       L1 = r0;
+       L2 = r0;
+       L3 = r0;
+
+       /* Clear Out All the DAG Registers */
+       B0 = r0;
+       B1 = r0;
+       B2 = r0;
+       B3 = r0;
+
+       I0 = r0;
+       I1 = r0;
+       I2 = r0;
+       I3 = r0;
+
+       M0 = r0;
+       M1 = r0;
+       M2 = r0;
+       M3 = r0;
+
+       trace_buffer_init(p0,r0);
+       P0 = R1;
+       R0 = R1;
+
+       /* Turn off the icache */
+       p0.l = LO(IMEM_CONTROL);
+       p0.h = HI(IMEM_CONTROL);
+       R1 = [p0];
+       R0 = ~ENICPLB;
+       R0 = R0 & R1;
+
+       /* Anomaly 05000125 */
+#if ANOMALY_05000125
+       CLI R2;
+       SSYNC;
+#endif
+       [p0] = R0;
+       SSYNC;
+#if ANOMALY_05000125
+       STI R2;
+#endif
+
+       /* Turn off the dcache */
+       p0.l = LO(DMEM_CONTROL);
+       p0.h = HI(DMEM_CONTROL);
+       R1 = [p0];
+       R0 = ~ENDCPLB;
+       R0 = R0 & R1;
+
+       /* Anomaly 05000125 */
+#if ANOMALY_05000125
+       CLI R2;
+       SSYNC;
+#endif
+       [p0] = R0;
+       SSYNC;
+#if ANOMALY_05000125
+       STI R2;
+#endif
+
+
+#if defined(CONFIG_BF527)
+       p0.h = hi(EMAC_SYSTAT);
+       p0.l = lo(EMAC_SYSTAT);
+       R0.h = 0xFFFF; /* Clear EMAC Interrupt Status bits */
+       R0.l = 0xFFFF;
+       [P0] = R0;
+       SSYNC;
+#endif
+
+       /* Initialise UART - when booting from u-boot, the UART is not disabled
+        * so if we dont initalize here, our serial console gets hosed */
+       p0.h = hi(UART1_LCR);
+       p0.l = lo(UART1_LCR);
+       r0 = 0x0(Z);
+       w[p0] = r0.L;   /* To enable DLL writes */
+       ssync;
+
+       p0.h = hi(UART1_DLL);
+       p0.l = lo(UART1_DLL);
+       r0 = 0x0(Z);
+       w[p0] = r0.L;
+       ssync;
+
+       p0.h = hi(UART1_DLH);
+       p0.l = lo(UART1_DLH);
+       r0 = 0x00(Z);
+       w[p0] = r0.L;
+       ssync;
+
+       p0.h = hi(UART1_GCTL);
+       p0.l = lo(UART1_GCTL);
+       r0 = 0x0(Z);
+       w[p0] = r0.L;   /* To enable UART clock */
+       ssync;
+
+       /* Initialize stack pointer */
+       sp.l = lo(INITIAL_STACK);
+       sp.h = hi(INITIAL_STACK);
+       fp = sp;
+       usp = sp;
+
+#ifdef CONFIG_EARLY_PRINTK
+       SP += -12;
+       call _init_early_exception_vectors;
+       SP += 12;
+#endif
+
+       /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */
+       call _bf53x_relocate_l1_mem;
+#if CONFIG_BFIN_KERNEL_CLOCK
+       call _start_dma_code;
+#endif
+
+       /* Code for initializing Async memory banks */
+
+       p2.h = hi(EBIU_AMBCTL1);
+       p2.l = lo(EBIU_AMBCTL1);
+       r0.h = hi(AMBCTL1VAL);
+       r0.l = lo(AMBCTL1VAL);
+       [p2] = r0;
+       ssync;
+
+       p2.h = hi(EBIU_AMBCTL0);
+       p2.l = lo(EBIU_AMBCTL0);
+       r0.h = hi(AMBCTL0VAL);
+       r0.l = lo(AMBCTL0VAL);
+       [p2] = r0;
+       ssync;
+
+       p2.h = hi(EBIU_AMGCTL);
+       p2.l = lo(EBIU_AMGCTL);
+       r0 = AMGCTLVAL;
+       w[p2] = r0;
+       ssync;
+
+       /* This section keeps the processor in supervisor mode
+        * during kernel boot.  Switches to user mode at end of boot.
+        * See page 3-9 of Hardware Reference manual for documentation.
+        */
+
+       /* EVT15 = _real_start */
+
+       p0.l = lo(EVT15);
+       p0.h = hi(EVT15);
+       p1.l = _real_start;
+       p1.h = _real_start;
+       [p0] = p1;
+       csync;
+
+       p0.l = lo(IMASK);
+       p0.h = hi(IMASK);
+       p1.l = IMASK_IVG15;
+       p1.h = 0x0;
+       [p0] = p1;
+       csync;
+
+       raise 15;
+       p0.l = .LWAIT_HERE;
+       p0.h = .LWAIT_HERE;
+       reti = p0;
+#if ANOMALY_05000281
+       nop; nop; nop;
+#endif
+       rti;
+
+.LWAIT_HERE:
+       jump .LWAIT_HERE;
+ENDPROC(__start)
+
+ENTRY(_real_start)
+       [ -- sp ] = reti;
+       p0.l = lo(WDOG_CTL);
+       p0.h = hi(WDOG_CTL);
+       r0 = 0xAD6(z);
+       w[p0] = r0;     /* watchdog off for now */
+       ssync;
+
+       /* Code update for BSS size == 0
+        * Zero out the bss region.
+        */
+
+       p1.l = ___bss_start;
+       p1.h = ___bss_start;
+       p2.l = ___bss_stop;
+       p2.h = ___bss_stop;
+       r0 = 0;
+       p2 -= p1;
+       lsetup (.L_clear_bss, .L_clear_bss) lc0 = p2;
+.L_clear_bss:
+       B[p1++] = r0;
+
+       /* In case there is a NULL pointer reference
+        * Zero out region before stext
+        */
+
+       p1.l = 0x0;
+       p1.h = 0x0;
+       r0.l = __stext;
+       r0.h = __stext;
+       r0 = r0 >> 1;
+       p2 = r0;
+       r0 = 0;
+       lsetup (.L_clear_zero, .L_clear_zero) lc0 = p2;
+.L_clear_zero:
+       W[p1++] = r0;
+
+       /* pass the uboot arguments to the global value command line */
+       R0 = R7;
+       call _cmdline_init;
+
+       p1.l = __rambase;
+       p1.h = __rambase;
+       r0.l = __sdata;
+       r0.h = __sdata;
+       [p1] = r0;
+
+       p1.l = __ramstart;
+       p1.h = __ramstart;
+       p3.l = ___bss_stop;
+       p3.h = ___bss_stop;
+
+       r1 = p3;
+       [p1] = r1;
+
+       /*
+        * load the current thread pointer and stack
+        */
+       r1.l = _init_thread_union;
+       r1.h = _init_thread_union;
+
+       r2.l = 0x2000;
+       r2.h = 0x0000;
+       r1 = r1 + r2;
+       sp = r1;
+       usp = sp;
+       fp = sp;
+       jump.l _start_kernel;
+ENDPROC(_real_start)
+
+__FINIT
+
+.section .l1.text
+#if CONFIG_BFIN_KERNEL_CLOCK
+ENTRY(_start_dma_code)
+
+       /* Enable PHY CLK buffer output */
+       p0.h = hi(VR_CTL);
+       p0.l = lo(VR_CTL);
+       r0.l = w[p0];
+       bitset(r0, 14);
+       w[p0] = r0.l;
+       ssync;
+
+       p0.h = hi(SIC_IWR0);
+       p0.l = lo(SIC_IWR0);
+       r0.l = 0x1;
+       r0.h = 0x0;
+       [p0] = r0;
+       SSYNC;
+
+       /*
+        *  Set PLL_CTL
+        *   - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors
+        *   - [8]     = BYPASS    : BYPASS the PLL, run CLKIN into CCLK/SCLK
+        *   - [7]     = output delay (add 200ps of delay to mem signals)
+        *   - [6]     = input delay (add 200ps of input delay to mem signals)
+        *   - [5]     = PDWN      : 1=All Clocks off
+        *   - [3]     = STOPCK    : 1=Core Clock off
+        *   - [1]     = PLL_OFF   : 1=Disable Power to PLL
+        *   - [0]     = DF        : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL
+        *   all other bits set to zero
+        */
+
+       p0.h = hi(PLL_LOCKCNT);
+       p0.l = lo(PLL_LOCKCNT);
+       r0 = 0x300(Z);
+       w[p0] = r0.l;
+       ssync;
+
+       P2.H = hi(EBIU_SDGCTL);
+       P2.L = lo(EBIU_SDGCTL);
+       R0 = [P2];
+       BITSET (R0, 24);
+       [P2] = R0;
+       SSYNC;
+
+       r0 = CONFIG_VCO_MULT & 63;       /* Load the VCO multiplier         */
+       r0 = r0 << 9;                    /* Shift it over,                  */
+       r1 = CLKIN_HALF;                 /* Do we need to divide CLKIN by 2?*/
+       r0 = r1 | r0;
+       r1 = PLL_BYPASS;                 /* Bypass the PLL?                 */
+       r1 = r1 << 8;                    /* Shift it over                   */
+       r0 = r1 | r0;                    /* add them all together           */
+
+       p0.h = hi(PLL_CTL);
+       p0.l = lo(PLL_CTL);              /* Load the address                */
+       cli r2;                          /* Disable interrupts              */
+       ssync;
+       w[p0] = r0.l;                    /* Set the value                   */
+       idle;                            /* Wait for the PLL to stablize    */
+       sti r2;                          /* Enable interrupts               */
+
+.Lcheck_again:
+       p0.h = hi(PLL_STAT);
+       p0.l = lo(PLL_STAT);
+       R0 = W[P0](Z);
+       CC = BITTST(R0,5);
+       if ! CC jump .Lcheck_again;
+
+       /* Configure SCLK & CCLK Dividers */
+       r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV);
+       p0.h = hi(PLL_DIV);
+       p0.l = lo(PLL_DIV);
+       w[p0] = r0.l;
+       ssync;
+
+       p0.l = lo(EBIU_SDRRC);
+       p0.h = hi(EBIU_SDRRC);
+       r0 = mem_SDRRC;
+       w[p0] = r0.l;
+       ssync;
+
+       p0.l = LO(EBIU_SDBCTL);
+       p0.h = HI(EBIU_SDBCTL);     /* SDRAM Memory Bank Control Register */
+       r0 = mem_SDBCTL;
+       w[p0] = r0.l;
+       ssync;
+
+       P2.H = hi(EBIU_SDGCTL);
+       P2.L = lo(EBIU_SDGCTL);
+       R0 = [P2];
+       BITCLR (R0, 24);
+       p0.h = hi(EBIU_SDSTAT);
+       p0.l = lo(EBIU_SDSTAT);
+       r2.l = w[p0];
+       cc = bittst(r2,3);
+       if !cc jump .Lskip;
+       NOP;
+       BITSET (R0, 23);
+.Lskip:
+       [P2] = R0;
+       SSYNC;
+
+       R0.L = lo(mem_SDGCTL);
+       R0.H = hi(mem_SDGCTL);
+       R1 = [p2];
+       R1 = R1 | R0;
+       [P2] = R1;
+       SSYNC;
+
+       p0.h = hi(SIC_IWR0);
+       p0.l = lo(SIC_IWR0);
+       r0.l = lo(IWR_ENABLE_ALL);
+       r0.h = hi(IWR_ENABLE_ALL);
+       [p0] = r0;
+       SSYNC;
+
+       RTS;
+ENDPROC(_start_dma_code)
+#endif /* CONFIG_BFIN_KERNEL_CLOCK */
+
+.data
+
+/*
+ * Set up the usable of RAM stuff. Size of RAM is determined then
+ * an initial stack set up at the end.
+ */
+
+.align 4
+__rambase:
+.long   0
+__ramstart:
+.long   0
+__ramend:
+.long   0
diff --git a/arch/blackfin/mach-bf527/ints-priority.c b/arch/blackfin/mach-bf527/ints-priority.c
new file mode 100644 (file)
index 0000000..1fa3897
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * File:         arch/blackfin/mach-bf537/ints-priority.c
+ * Based on:     arch/blackfin/mach-bf533/ints-priority.c
+ * Author:       Michael Hennerich (michael.hennerich@analog.com)
+ *
+ * Created:
+ * Description:  Set up the interrupt priorities
+ *
+ * Modified:
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/module.h>
+#include <linux/irq.h>
+#include <asm/blackfin.h>
+
+void program_IAR(void)
+{
+       /* Program the IAR0 Register with the configured priority */
+       bfin_write_SIC_IAR0(((CONFIG_IRQ_PLL_WAKEUP - 7) << IRQ_PLL_WAKEUP_POS) |
+                       ((CONFIG_IRQ_DMA0_ERROR - 7) << IRQ_DMA0_ERROR_POS) |
+                       ((CONFIG_IRQ_DMAR0_BLK - 7) << IRQ_DMAR0_BLK_POS) |
+                       ((CONFIG_IRQ_DMAR1_BLK - 7) << IRQ_DMAR1_BLK_POS) |
+                       ((CONFIG_IRQ_DMAR0_OVR - 7) << IRQ_DMAR0_OVR_POS) |
+                       ((CONFIG_IRQ_DMAR1_OVR - 7) << IRQ_DMAR1_OVR_POS) |
+                       ((CONFIG_IRQ_PPI_ERROR - 7) << IRQ_PPI_ERROR_POS) |
+                       ((CONFIG_IRQ_MAC_ERROR - 7) << IRQ_MAC_ERROR_POS));
+
+
+       bfin_write_SIC_IAR1(((CONFIG_IRQ_SPORT0_ERROR - 7) << IRQ_SPORT0_ERROR_POS) |
+                       ((CONFIG_IRQ_SPORT1_ERROR - 7) << IRQ_SPORT1_ERROR_POS) |
+                       ((CONFIG_IRQ_UART0_ERROR - 7) << IRQ_UART0_ERROR_POS) |
+                       ((CONFIG_IRQ_UART1_ERROR - 7) << IRQ_UART1_ERROR_POS) |
+                       ((CONFIG_IRQ_RTC - 7) << IRQ_RTC_POS) |
+                       ((CONFIG_IRQ_PPI - 7) << IRQ_PPI_POS));
+
+       bfin_write_SIC_IAR2(((CONFIG_IRQ_SPORT0_RX - 7) << IRQ_SPORT0_RX_POS) |
+                       ((CONFIG_IRQ_SPORT0_TX - 7) << IRQ_SPORT0_TX_POS) |
+                       ((CONFIG_IRQ_SPORT1_RX - 7) << IRQ_SPORT1_RX_POS) |
+                       ((CONFIG_IRQ_SPORT1_TX - 7) << IRQ_SPORT1_TX_POS) |
+                       ((CONFIG_IRQ_TWI - 7) << IRQ_TWI_POS) |
+                       ((CONFIG_IRQ_SPI - 7) << IRQ_SPI_POS) |
+                       ((CONFIG_IRQ_UART0_RX - 7) << IRQ_UART0_RX_POS) |
+                       ((CONFIG_IRQ_UART0_TX - 7) << IRQ_UART0_TX_POS));
+
+       bfin_write_SIC_IAR3(((CONFIG_IRQ_UART1_RX - 7) << IRQ_UART1_RX_POS) |
+                       ((CONFIG_IRQ_UART1_TX - 7) << IRQ_UART1_TX_POS) |
+                       ((CONFIG_IRQ_OPTSEC - 7) << IRQ_OPTSEC_POS) |
+                       ((CONFIG_IRQ_CNT - 7) << IRQ_CNT_POS) |
+                       ((CONFIG_IRQ_MAC_RX - 7) << IRQ_MAC_RX_POS) |
+                       ((CONFIG_IRQ_PORTH_INTA - 7) << IRQ_PORTH_INTA_POS) |
+                       ((CONFIG_IRQ_MAC_TX - 7) << IRQ_MAC_TX_POS) |
+                       ((CONFIG_IRQ_PORTH_INTB - 7) << IRQ_PORTH_INTB_POS));
+
+       bfin_write_SIC_IAR4(((CONFIG_IRQ_TMR0 - 7) << IRQ_TMR0_POS) |
+                       ((CONFIG_IRQ_TMR1 - 7) << IRQ_TMR1_POS) |
+                       ((CONFIG_IRQ_TMR2 - 7) << IRQ_TMR2_POS) |
+                       ((CONFIG_IRQ_TMR3 - 7) << IRQ_TMR3_POS) |
+                       ((CONFIG_IRQ_TMR4 - 7) << IRQ_TMR4_POS) |
+                       ((CONFIG_IRQ_TMR5 - 7) << IRQ_TMR5_POS) |
+                       ((CONFIG_IRQ_TMR6 - 7) << IRQ_TMR6_POS) |
+                       ((CONFIG_IRQ_TMR7 - 7) << IRQ_TMR7_POS));
+
+       bfin_write_SIC_IAR5(((CONFIG_IRQ_PORTG_INTA - 7) << IRQ_PORTG_INTA_POS) |
+                       ((CONFIG_IRQ_PORTG_INTB - 7) << IRQ_PORTG_INTB_POS) |
+                       ((CONFIG_IRQ_MEM_DMA0 - 7) << IRQ_MEM_DMA0_POS) |
+                       ((CONFIG_IRQ_MEM_DMA1 - 7) << IRQ_MEM_DMA1_POS) |
+                       ((CONFIG_IRQ_WATCH - 7) << IRQ_WATCH_POS) |
+                       ((CONFIG_IRQ_PORTF_INTA - 7) << IRQ_PORTF_INTA_POS) |
+                       ((CONFIG_IRQ_PORTF_INTB - 7) << IRQ_PORTF_INTB_POS) |
+                       ((CONFIG_IRQ_SPI_ERROR - 7) << IRQ_SPI_ERROR_POS));
+
+       bfin_write_SIC_IAR6(((CONFIG_IRQ_NFC_ERROR - 7) << IRQ_NFC_ERROR_POS) |
+                       ((CONFIG_IRQ_HDMA_ERROR - 7) << IRQ_HDMA_ERROR_POS) |
+                       ((CONFIG_IRQ_HDMA - 7) << IRQ_HDMA_POS) |
+                       ((CONFIG_IRQ_USB_EINT - 7) << IRQ_USB_EINT_POS) |
+                       ((CONFIG_IRQ_USB_INT0 - 7) << IRQ_USB_INT0_POS) |
+                       ((CONFIG_IRQ_USB_INT1 - 7) << IRQ_USB_INT1_POS) |
+                       ((CONFIG_IRQ_USB_INT2 - 7) << IRQ_USB_INT2_POS) |
+                       ((CONFIG_IRQ_USB_DMA - 7) << IRQ_USB_DMA_POS));
+
+       SSYNC();
+}
index a57b52d207cda6ac4a200dace6093e1f12e2515c..1c5a86adfab79158b19ea2dd5dbd78ba475f6f51 100644 (file)
@@ -42,7 +42,7 @@
 /*
  * Name the Board for the /proc/cpuinfo
  */
-char *bfin_board_name = "Bluetechnix CM BF533";
+const char bfin_board_name[] = "Bluetechnix CM BF533";
 
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
 /* all SPI peripherals info goes here */
index 5c1e35d3c012b62e26c567fcc3b77a7978cd7d4d..34b63920e272ef0321ad5bee525ec80e22f4d567 100644 (file)
@@ -43,7 +43,7 @@
 /*
  * Name the Board for the /proc/cpuinfo
  */
-char *bfin_board_name = "ADDS-BF533-EZKIT";
+const char bfin_board_name[] = "ADDS-BF533-EZKIT";
 
 #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
 static struct platform_device rtc_device = {
index 9bc1f0d0ab508692f12791840ea9d30efd68a77c..310b7772c458cf512e1dfbf341d9af5fb9666b34 100644 (file)
@@ -35,7 +35,7 @@
 /*
  * Name the Board for the /proc/cpuinfo
  */
-char *bfin_board_name = "UNKNOWN BOARD";
+const char bfin_board_name[] = "UNKNOWN BOARD";
 
 #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
 static struct platform_device rtc_device = {
index 8975e06ea1582397849bada89e4b5b862405359b..f84be4eabfd1985af425717cfeb353c48ecd60a6 100644 (file)
@@ -46,7 +46,7 @@
 /*
  * Name the Board for the /proc/cpuinfo
  */
-char *bfin_board_name = "ADDS-BF533-STAMP";
+const char bfin_board_name[] = "ADDS-BF533-STAMP";
 
 #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
 static struct platform_device rtc_device = {
index 44dea05e1d034a6f29871b761196cfbc8549c478..52e2320307de028e19e75fdafe4e643b3324e03b 100644 (file)
@@ -43,7 +43,7 @@
 /*
  * Name the Board for the /proc/cpuinfo
  */
-char *bfin_board_name = "Bluetechnix CM BF537";
+const char bfin_board_name[] = "Bluetechnix CM BF537";
 
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
 /* all SPI peripherals info goes here */
index 6668c8e4a3fc953fb95f7f1a899a5e1212945985..255da7a984817ce0c1f7180181c6f26b6f5834c5 100644 (file)
@@ -49,7 +49,7 @@
 /*
  * Name the Board for the /proc/cpuinfo
  */
-char *bfin_board_name = "GENERIC Board";
+const char bfin_board_name[] = "GENERIC Board";
 
 /*
  *  Driver needs to know address, irq and flag pin.
index f83a2544004d4260ca574d57d54cccabd55b3c37..87b808926789b46acfb7c5513155dc2f4a05d9b8 100644 (file)
@@ -47,7 +47,7 @@
 /*
  * Name the Board for the /proc/cpuinfo
  */
-char *bfin_board_name = "PNAV-1.0";
+const char bfin_board_name[] = "PNAV-1.0";
 
 /*
  *  Driver needs to know address, irq and flag pin.
index f42ba3aa86d786407f6cb0d67c0cd046304889a7..cc41f6c2ef4f515c65f5e4f99b3e027b41d96045 100644 (file)
@@ -49,7 +49,7 @@
 /*
  * Name the Board for the /proc/cpuinfo
  */
-char *bfin_board_name = "ADDS-BF537-STAMP";
+const char bfin_board_name[] = "ADDS-BF537-STAMP";
 
 /*
  *  Driver needs to know address, irq and flag pin.
index 046e6d84bbfc7d36f4640e8ab01ce020cc8950c4..6b6490e66b30dd11086d901acdcf8e4cf6353c1c 100644 (file)
@@ -49,7 +49,7 @@
 /*
  * Name the Board for the /proc/cpuinfo
  */
-char *bfin_board_name = "ADSP-BF548-EZKIT";
+const char bfin_board_name[] = "ADSP-BF548-EZKIT";
 
 /*
  *  Driver needs to know address, irq and flag pin.
@@ -560,7 +560,7 @@ static struct platform_device *ezkit_devices[] __initdata = {
 
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
        &bf54x_spi_master0,
-/*     &bf54x_spi_master1,*/
+       &bf54x_spi_master1,
 #endif
 
 #if defined(CONFIG_KEYBOARD_BFIN) || defined(CONFIG_KEYBOARD_BFIN_MODULE)
index a8184113be482361b9ddfc039ac51293be7810d4..957bf1366eff249b0de48f5ae3cad877db96cad2 100644 (file)
@@ -64,6 +64,7 @@
        (struct dma_register *) MDMA_D3_NEXT_DESC_PTR,
        (struct dma_register *) MDMA_S3_NEXT_DESC_PTR,
 };
+EXPORT_SYMBOL(base_addr);
 
 int channel2irq(unsigned int channel)
 {
index cd827a1b6ba139e37604fa8e148836911dc8d7a2..97aeb43fd8b46e05eead1e481d0b3dca3507da34 100644 (file)
@@ -42,7 +42,7 @@
 /*
  * Name the Board for the /proc/cpuinfo
  */
-char *bfin_board_name = "Bluetechnix CM BF561";
+const char bfin_board_name[] = "Bluetechnix CM BF561";
 
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
 /* all SPI peripherals info goes here */
index 57e14edca8b1bb75f38c486e19ebeebb9b104344..059d516cec23e4bc9877d5271cf300bbf3a600c4 100644 (file)
@@ -39,7 +39,7 @@
 /*
  * Name the Board for the /proc/cpuinfo
  */
-char *bfin_board_name = "ADDS-BF561-EZKIT";
+const char bfin_board_name[] = "ADDS-BF561-EZKIT";
 
 #define ISP1761_BASE       0x2C0F0000
 #define ISP1761_IRQ        IRQ_PF10
index 4dfea5da674c9acf37968a2c4a1d250756ffffe5..46816be4b2bab8dac67a052f5bd00f4cddd68b38 100644 (file)
@@ -32,7 +32,7 @@
 #include <linux/platform_device.h>
 #include <linux/irq.h>
 
-char *bfin_board_name = "UNKNOWN BOARD";
+const char bfin_board_name[] = "UNKNOWN BOARD";
 
 /*
  *  Driver needs to know address, irq and flag pin.
index c442eb23db5ea26916156362d7f38392b5d6e946..4a17c6da2a594e10c1c8849a6880adf879669316 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/platform_device.h>
 #include <linux/irq.h>
 
-char *bfin_board_name = "Tepla-BF561";
+const char bfin_board_name[] = "Tepla-BF561";
 
 /*
  *  Driver needs to know address, irq and flag pin.
index 2db3546fc874f73804cd360c6d46c16c99262b5a..c2f05fabedc1c8f47e859d4821cecfe59e17c7b9 100644 (file)
  * -
  */
 
-unsigned long irq_flags = 0;
+/* Initialize this to an actual value to force it into the .data
+ * section so that we know it is properly initialized at entry into
+ * the kernel but before bss is initialized to zero (which is where
+ * it would live otherwise).  The 0x1f magic represents the IRQs we
+ * cannot actually mask out in hardware.
+ */
+unsigned long irq_flags = 0x1f;
 
 /* The number of spurious interrupts */
 atomic_t num_spurious;
index d3b7672b2b94ce91dd970c9ce30490cdf4362bae..2d2b63567b301d80c7223e8025e4acab279847ca 100644 (file)
  * -
  */
 
-unsigned long irq_flags = 0;
+/* Initialize this to an actual value to force it into the .data
+ * section so that we know it is properly initialized at entry into
+ * the kernel but before bss is initialized to zero (which is where
+ * it would live otherwise).  The 0x1f magic represents the IRQs we
+ * cannot actually mask out in hardware.
+ */
+unsigned long irq_flags = 0x1f;
 
 /* The number of spurious interrupts */
 atomic_t num_spurious;
@@ -92,10 +98,15 @@ static void __init search_IAR(void)
 
                for (irqn = 0; irqn < NR_PERI_INTS; irqn++) {
                        int iar_shift = (irqn & 7) * 4;
-                       if (ivg ==
+                               if (ivg ==
                            (0xf &
+#ifndef CONFIG_BF52x
                             bfin_read32((unsigned long *)SIC_IAR0 +
                                         (irqn >> 3)) >> iar_shift)) {
+#else
+                            bfin_read32((unsigned long *)SIC_IAR0 +
+                                        ((irqn%32) >> 3) + ((irqn / 32) * 16)) >> iar_shift)) {
+#endif
                                ivg_table[irq_pos].irqno = IVG7 + irqn;
                                ivg_table[irq_pos].isrflag = 1 << (irqn % 32);
                                ivg7_13[ivg].istop++;
@@ -140,7 +151,7 @@ static void bfin_core_unmask_irq(unsigned int irq)
 
 static void bfin_internal_mask_irq(unsigned int irq)
 {
-#ifndef CONFIG_BF54x
+#ifdef CONFIG_BF53x
        bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() &
                             ~(1 << (irq - (IRQ_CORETMR + 1))));
 #else
@@ -155,7 +166,7 @@ static void bfin_internal_mask_irq(unsigned int irq)
 
 static void bfin_internal_unmask_irq(unsigned int irq)
 {
-#ifndef CONFIG_BF54x
+#ifdef CONFIG_BF53x
        bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() |
                             (1 << (irq - (IRQ_CORETMR + 1))));
 #else
@@ -750,13 +761,15 @@ int __init init_arch_irq(void)
        int irq;
        unsigned long ilat = 0;
        /*  Disable all the peripheral intrs  - page 4-29 HW Ref manual */
-#ifdef CONFIG_BF54x
+#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x)
        bfin_write_SIC_IMASK0(SIC_UNMASK_ALL);
        bfin_write_SIC_IMASK1(SIC_UNMASK_ALL);
-       bfin_write_SIC_IMASK2(SIC_UNMASK_ALL);
        bfin_write_SIC_IWR0(IWR_ENABLE_ALL);
        bfin_write_SIC_IWR1(IWR_ENABLE_ALL);
+#ifdef CONFIG_BF54x
+       bfin_write_SIC_IMASK2(SIC_UNMASK_ALL);
        bfin_write_SIC_IWR2(IWR_ENABLE_ALL);
+#endif
 #else
        bfin_write_SIC_IMASK(SIC_UNMASK_ALL);
        bfin_write_SIC_IWR(IWR_ENABLE_ALL);
@@ -787,7 +800,7 @@ int __init init_arch_irq(void)
 
                        switch (irq) {
 #ifdef CONFIG_IRQCHIP_DEMUX_GPIO
-#ifndef CONFIG_BF54x
+#if defined(CONFIG_BF53x)
                        case IRQ_PROG_INTA:
                                set_irq_chained_handler(irq,
                                                        bfin_demux_gpio_irq);
@@ -798,7 +811,7 @@ int __init init_arch_irq(void)
                                                        bfin_demux_gpio_irq);
                                break;
 #endif
-#else
+#elif defined(CONFIG_BF54x)
                        case IRQ_PINT0:
                                set_irq_chained_handler(irq,
                                                        bfin_demux_gpio_irq);
@@ -815,7 +828,20 @@ int __init init_arch_irq(void)
                                set_irq_chained_handler(irq,
                                                        bfin_demux_gpio_irq);
                                break;
-#endif                         /*CONFIG_BF54x */
+#elif defined(CONFIG_BF52x)
+                       case IRQ_PORTF_INTA:
+                               set_irq_chained_handler(irq,
+                                                       bfin_demux_gpio_irq);
+                               break;
+                       case IRQ_PORTG_INTA:
+                               set_irq_chained_handler(irq,
+                                                       bfin_demux_gpio_irq);
+                               break;
+                       case IRQ_PORTH_INTA:
+                               set_irq_chained_handler(irq,
+                                                       bfin_demux_gpio_irq);
+                               break;
+#endif
 #endif
                        default:
                                set_irq_handler(irq, handle_simple_irq);
@@ -880,14 +906,15 @@ void do_irq(int vec, struct pt_regs *fp)
        } else {
                struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst;
                struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop;
-#ifdef CONFIG_BF54x
+#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x)
                unsigned long sic_status[3];
 
                SSYNC();
-               sic_status[0] = bfin_read_SIC_ISR(0) & bfin_read_SIC_IMASK(0);
-               sic_status[1] = bfin_read_SIC_ISR(1) & bfin_read_SIC_IMASK(1);
-               sic_status[2] = bfin_read_SIC_ISR(2) & bfin_read_SIC_IMASK(2);
-
+               sic_status[0] = bfin_read_SIC_ISR0() & bfin_read_SIC_IMASK0();
+               sic_status[1] = bfin_read_SIC_ISR1() & bfin_read_SIC_IMASK1();
+#ifdef CONFIG_BF54x
+               sic_status[2] = bfin_read_SIC_ISR2() & bfin_read_SIC_IMASK2();
+#endif
                for (;; ivg++) {
                        if (ivg >= ivg_stop) {
                                atomic_inc(&num_spurious);
index b103027222024d9218b1b983c5c7041d8a46e689..dac51fb06f22b5f2e8037f923c52c13ac693d383 100644 (file)
@@ -32,7 +32,7 @@
  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#include <linux/pm.h>
+#include <linux/suspend.h>
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
 #include <linux/io.h>
@@ -89,28 +89,15 @@ void bfin_pm_suspend_standby_enter(void)
 #endif                         /* CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR */
 }
 
-
 /*
- *     bfin_pm_prepare - Do preliminary suspend work.
- *     @state:         suspend state we're entering.
+ *     bfin_pm_valid - Tell the PM core that we only support the standby sleep
+ *                     state
+ *     @state:         suspend state we're checking.
  *
  */
-static int bfin_pm_prepare(suspend_state_t state)
+static int bfin_pm_valid(suspend_state_t state)
 {
-       int error = 0;
-
-       switch (state) {
-       case PM_SUSPEND_STANDBY:
-               break;
-
-       case PM_SUSPEND_MEM:
-               return -ENOTSUPP;
-
-       default:
-               return -EINVAL;
-       }
-
-       return error;
+       return (state == PM_SUSPEND_STANDBY);
 }
 
 /*
@@ -135,44 +122,14 @@ static int bfin_pm_enter(suspend_state_t state)
        return 0;
 }
 
-/*
- *     bfin_pm_finish - Finish up suspend sequence.
- *     @state:         State we're coming out of.
- *
- *     This is called after we wake back up (or if entering the sleep state
- *     failed).
- */
-static int bfin_pm_finish(suspend_state_t state)
-{
-       switch (state) {
-       case PM_SUSPEND_STANDBY:
-               break;
-
-       case PM_SUSPEND_MEM:
-               return -ENOTSUPP;
-
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int bfin_pm_valid(suspend_state_t state)
-{
-       return (state == PM_SUSPEND_STANDBY);
-}
-
-struct pm_ops bfin_pm_ops = {
-       .prepare = bfin_pm_prepare,
+struct platform_suspend_ops bfin_pm_ops = {
        .enter = bfin_pm_enter,
-       .finish = bfin_pm_finish,
        .valid  = bfin_pm_valid,
 };
 
 static int __init bfin_pm_init(void)
 {
-       pm_set_ops(&bfin_pm_ops);
+       suspend_set_ops(&bfin_pm_ops);
        return 0;
 }
 
diff --git a/arch/blackfin/oprofile/Kconfig b/arch/blackfin/oprofile/Kconfig
deleted file mode 100644 (file)
index 0a2fd99..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-menu "Profiling support"
-depends on EXPERIMENTAL
-
-config PROFILING
-       bool "Profiling support (EXPERIMENTAL)"
-       help
-         Say Y here to enable the extended profiling support mechanisms used
-         by profilers such as OProfile.
-
-config OPROFILE
-       tristate "OProfile system profiling (EXPERIMENTAL)"
-       depends on PROFILING
-       help
-         OProfile is a profiling system capable of profiling the
-         whole system, include the kernel, kernel modules, libraries,
-         and applications.
-
-         If unsure, say N.
-
-config HARDWARE_PM
-       tristate "Hardware Performance Monitor Profiling"
-       depends on PROFILING
-       help
-         take use of hardware performance monitor to profiling the kernel
-         and application.
-
-         If unsure, say N.
-
-endmenu
index 6b4d026a00a120e5728d8930bb6d4ad43a6b4006..21900a9378bbc04b4bb5fccd6161fb86a4d86ecd 100644 (file)
@@ -196,6 +196,8 @@ source "sound/Kconfig"
 
 source "drivers/usb/Kconfig"
 
+source "kernel/Kconfig.instrumentation"
+
 source "arch/cris/Kconfig.debug"
 
 source "security/Kconfig"
index c7ea9efd01049875e9e8a46f99b779480d008189..f1ce6f64401dd45c4e375a466146790f53aeb8eb 100644 (file)
@@ -182,7 +182,7 @@ config ETRAX_LED7G
          set this to same as CONFIG_ETRAX_LED1G (normally 2).
 
 config ETRAX_LED8Y
-       int "Eigth yellow LED bit"
+       int "Eighth yellow LED bit"
        depends on ETRAX_CSP0_LEDS
        default "2"
        help
index ffb8d21b2f83f16c8020aabc5c90177b8083fb6e..e205d2e7e0897202aed04742d0ff3cd67b399960 100644 (file)
@@ -8,7 +8,7 @@
  *
  * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
  * puts by Nick Holloway 1993, better puts by Martin Mares 1995
- * adoptation for Linux/CRIS Axis Communications AB, 1999
+ * adaptation for Linux/CRIS Axis Communications AB, 1999
  * 
  */
 
index 1de0026bb94ef7255d7f693bbb7fec57e3979b43..c263b8232dbcdfa6148d026db5253a4effc3c6a2 100644 (file)
@@ -4,7 +4,7 @@
  * From Phillips' datasheet:
  *
  * The PCF8563 is a CMOS real-time clock/calendar optimized for low power
- * consumption. A programmable clock output, interupt output and voltage
+ * consumption. A programmable clock output, interrupt output and voltage
  * low detector are also provided. All address and data are transferred
  * serially via two-line bidirectional I2C-bus. Maximum bus speed is
  * 400 kbits/s. The built-in word address register is incremented
index 2b536ca6f4446f6fb1ecc64df9305d8eaa303104..93679a48c791528625cd4e3949ef2e13ad4504e4 100644 (file)
@@ -83,7 +83,7 @@
  *
  * Revision 1.4  2002/11/19 14:35:24  starvik
  * Changes from linux 2.4
- * Changed struct initializer syntax to the currently prefered notation
+ * Changed struct initializer syntax to the currently preferred notation
  *
  * Revision 1.3  2002/11/06 09:47:03  starvik
  * Modified for new interrupt macros
index ae45d4522e6551982c9c57ffbc318dce71918fc3..c5844cb70f095bc96333bc46f9b114db2f725439 100644 (file)
@@ -97,7 +97,7 @@
  *
  *  Revision 1.36  2001/11/22 13:36:36  bjornw
  *  * In ret_from_intr, check regs->dccr for usermode reentrance instead of
- *    DCCR explicitely (because the latter might not reflect current reality)
+ *    DCCR explicitly (because the latter might not reflect current reality)
  *  * In mmu_bus_fault, set $r9 _after_ calling the C-code instead of before
  *    since $r9 is call-clobbered and is potentially needed afterwards
  *
index 8cbdf594b36955373629baa9bf6cd7b4fe6a6493..d3ea052e5ee148581a64d451e45d3033ad23ea67 100644 (file)
@@ -84,7 +84,7 @@
  * with time based on jiffies and *R_TIMER0_DATA, uses a table
  * for fast conversion of timer value to microseconds.
  * (Much faster the standard do_gettimeofday() and we don't really
- * wan't to use the true time - we wan't the "uptime" so timers don't screw up
+ * want to use the true time - we want the "uptime" so timers don't screw up
  * when we change the time.
  * TODO: Add efficient support for continuous timers as well.
  *
index 96094cbf12552ff0d5115f8a643d014550971ad2..845c95f6e87117318511e164ada754c321d97b6d 100644 (file)
@@ -169,7 +169,7 @@ init_IRQ(void)
         for (i = 0; i < 256; i++)
                etrax_irv->v[i] = weird_irq;
 
-       /* Initialize IRQ handler descriptiors. */
+       /* Initialize IRQ handler descriptors. */
        for(i = 2; i < NR_IRQS; i++) {
                irq_desc[i].chip = &crisv10_irq_type;
                set_int_vector(i, interrupt[i]);
index 07628a13c6c492c8c9574caeefd5c5fca6c3a894..77f4b142372590a4bce1b8dcfbaf59e6f4ee2712 100644 (file)
@@ -959,7 +959,7 @@ stub_is_stopped(int sigval)
 
        /* Send register contents. We probably only need to send the
         * PC, frame pointer and stack pointer here. Other registers will be
-        * explicitely asked for. But for now, send all. 
+        * explicitly asked for. But for now, send all.
         */
        
        for (regno = R0; regno <= USP; regno++) {
index b6831ceb6a62ee35bfa4108c8a88c654909824a6..1a3760c94f8578444787fc9f2424814ba45f8aa7 100644 (file)
@@ -64,7 +64,7 @@ void hard_reset_now (void)
 #if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
        cause_of_death = 0xbedead;
 #else
-       /* Since we dont plan to keep on reseting the watchdog,
+       /* Since we dont plan to keep on resetting the watchdog,
           the key can be arbitrary hence three */
        *R_WATCHDOG = IO_FIELD(R_WATCHDOG, key, 3) |
                IO_STATE(R_WATCHDOG, enable, start);
index 38fd44dfbc5b3e506f2a9c85c2d6a7e6bfb350e1..326178aef6ee45f1172133b76f4663efc297bac5 100644 (file)
@@ -20,7 +20,7 @@ unsigned long r_timer_ctrl_shadow;
  * These are only usable if there actually IS a latch connected
  * to the corresponding external chip-select pin.
  *
- * A common usage is that CSP0 controls LED's and CSP4 video chips.
+ * A common usage is that CSP0 controls LEDs and CSP4 video chips.
  */
 
 unsigned long port_cse1_shadow;
index 9cf83932cd5dd60d5b4352be0241307966f3b1a4..6a6bdfd6984d6725db83d667f12116e7a380391d 100644 (file)
@@ -40,7 +40,7 @@
  * Copy warning from head.S about r8 and r9
  *
  * Revision 1.7  2001/04/18 12:05:39  bjornw
- * Fixed comments, and explicitely include config.h to be sure its there
+ * Fixed comments, and explicitly include config.h to be sure its there
  *
  * Revision 1.6  2001/04/10 06:20:16  starvik
  * Delay should be 200us, not 200ns
@@ -66,7 +66,7 @@
  */
 
 /* Just to be certain the config file is included, we include it here
- * explicitely instead of depending on it being included in the file that
+ * explicitly instead of depending on it being included in the file that
  * uses this code.
  */
 
index 8ffde4901b5730c9738b047c608926f9ceaa1f84..15d6662b03b17212e2f57fb2588a93e0ae247859 100644 (file)
@@ -41,7 +41,7 @@ void *memcpy(void *pdst,
      Make sure the compiler is able to make something useful of this.
       As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
 
-     If gcc was allright, it really would need no temporaries, and no
+     If gcc was alright, it really would need no temporaries, and no
      stack space to save stuff on. */
 
   register void *return_dst __asm__ ("r10") = pdst;
index 43778d53c254c7ae60044ba72203a8c486c59c73..a12c708afc9a46ad12d83ca1bcafa5ee22af449b 100644 (file)
@@ -38,7 +38,7 @@ __copy_user (void __user *pdst, const void *psrc, unsigned long pn)
      As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
 
      FIXME: Comment for old gcc version.  Check.
-     If gcc was allright, it really would need no temporaries, and no
+     If gcc was alright, it really would need no temporaries, and no
      stack space to save stuff on. */
 
   register char *dst __asm__ ("r13") = pdst;
@@ -200,7 +200,7 @@ __copy_user_zeroing (void __user *pdst, const void *psrc, unsigned long pn)
      As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
 
      FIXME: Comment for old gcc version.  Check.
-     If gcc was allright, it really would need no temporaries, and no
+     If gcc was alright, it really would need no temporaries, and no
      stack space to save stuff on.  */
 
   register char *dst __asm__ ("r13") = pdst;
@@ -380,7 +380,7 @@ __do_clear_user (void __user *pto, unsigned long pn)
       As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
 
      FIXME: Comment for old gcc version.  Check.
-     If gcc was allright, it really would need no temporaries, and no
+     If gcc was alright, it really would need no temporaries, and no
      stack space to save stuff on. */
 
   register char *dst __asm__ ("r13") = pto;
index 11902697196d3f19027905d8cde5d4b25ab696bf..0169ba1ca9c90172e83dc6ed8ad6899669c29fd7 100644 (file)
@@ -8,7 +8,7 @@
  *
  * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
  * puts by Nick Holloway 1993, better puts by Martin Mares 1995
- * adoptation for Linux/CRIS Axis Communications AB, 1999
+ * adaptation for Linux/CRIS Axis Communications AB, 1999
  *
  */
 
@@ -151,7 +151,7 @@ serout(const char *s, reg_scope_instances regi_ser)
        do {
                rs = REG_RD(ser, regi_ser, rs_stat_din);
        }
-       while (!rs.tr_rdy);/* Wait for tranceiver. */
+       while (!rs.tr_rdy);/* Wait for transceiver. */
 
        REG_WR(ser, regi_ser, rw_dout, dout);
 }
@@ -264,7 +264,7 @@ serial_setup(reg_scope_instances regi_ser)
        tr_ctrl.stop_bits = 1;  /* 2 stop bits. */
 
        /*
-        * The baudrate setup is a bit fishy, but in the end the tranceiver is
+        * The baudrate setup is a bit fishy, but in the end the transceiver is
         * set to 4800 and the receiver to 115200. The magic value is
         * 29.493 MHz.
         */
index 5180d45412fc55db169dc132988e5f7b93cadedc..3ec12ea44e8ede39efda94ac85b3c6562243c4e7 100644 (file)
@@ -205,7 +205,7 @@ static struct mtd_info *probe_cs(struct map_info *map_cs)
 /*
  * Probe each chip select individually for flash chips. If there are chips on
  * both cse0 and cse1, the mtd_info structs will be concatenated to one struct
- * so that MTD partitions can cross chip boundries.
+ * so that MTD partitions can cross chip boundaries.
  *
  * The only known restriction to how you can mount your chips is that each
  * chip select must hold similar flash chips. But you need external hardware
index e12f6cc6f4a2f24e12306011924f2f53db088e2a..f1edd2e359b2dcf3dac6a1fed0e6dd35d4000671 100644 (file)
@@ -275,7 +275,7 @@ i2c_getack(void)
                ack = 0;
        i2c_delay(CLOCK_HIGH_TIME/2);
        if(!ack){
-               if(!i2c_getbit()) /* receiver pulld SDA low */
+               if(!i2c_getbit()) /* receiver pulled SDA low */
                        ack = 1;
                i2c_delay(CLOCK_HIGH_TIME/2);
        }
index 93ddea4d956490640a95da0ca2676ac1e2678958..5ce015c6bb0dec899179d281b813cf0c5edb9576 100644 (file)
@@ -138,7 +138,7 @@ struct mtd_info* __init crisv32_nand_flash_probe (void)
        /* Enable the following for a flash based bad block table */
        this->options = NAND_USE_FLASH_BBT;
 
-       /* Scan to find existance of the device */
+       /* Scan to find existence of the device */
        if (nand_scan (crisv32_mtd, 1)) {
                err = -ENXIO;
                goto out_ior;
index da479a14f8369dc9d9e13750c93ec1c380bdf6ea..6dbd700d3d667c3dc9d06f3390d01b509ce91433 100644 (file)
@@ -4,7 +4,7 @@
  * From Phillips' datasheet:
  *
  * The PCF8563 is a CMOS real-time clock/calendar optimized for low power
- * consumption. A programmable clock output, interupt output and voltage
+ * consumption. A programmable clock output, interrupt output and voltage
  * low detector are also provided. All address and data are transferred
  * serially via two-line bidirectional I2C-bus. Maximum bus speed is
  * 400 kbits/s. The built-in word address register is incremented
index 79e1e4c2ca1d6a11a6cf80d339def48faf9f4521..b40551f9f40dce0a4f771d63cc6e738126ad6477 100644 (file)
@@ -97,7 +97,7 @@
  * with time based on jiffies and *R_TIMER0_DATA, uses a table
  * for fast conversion of timer value to microseconds.
  * (Much faster the standard do_gettimeofday() and we don't really
- * wan't to use the true time - we wan't the "uptime" so timers don't screw up
+ * want to use the true time - we want the "uptime" so timers don't screw up
  * when we change the time.
  * TODO: Add efficient support for continuous timers as well.
  *
index cc361bf578aef8ae4907491b87ec265f9b5c3c30..a9acaa270243f9fb64b0aefc7eefdf895e39ca3c 100644 (file)
@@ -140,7 +140,7 @@ block_irq(int irq, int cpu)
         spin_lock_irqsave(&irq_lock, flags);
         intr_mask = REG_RD_INT(intr_vect, irq_regs[cpu], rw_mask);
 
-       /* Remember; 1 let thru, 0 block. */
+       /* Remember; 1 let through, 0 block. */
        intr_mask &= ~(1 << (irq - FIRST_IRQ));
 
        REG_WR_INT(intr_vect, irq_regs[cpu], rw_mask, intr_mask);
@@ -156,7 +156,7 @@ unblock_irq(int irq, int cpu)
         spin_lock_irqsave(&irq_lock, flags);
         intr_mask = REG_RD_INT(intr_vect, irq_regs[cpu], rw_mask);
 
-       /* Remember; 1 let thru, 0 block. */
+       /* Remember; 1 let through, 0 block. */
        intr_mask |= (1 << (irq - FIRST_IRQ));
 
        REG_WR_INT(intr_vect, irq_regs[cpu], rw_mask, intr_mask);
@@ -308,7 +308,7 @@ crisv32_do_multiple(struct pt_regs* regs)
         */
        irq_enter();
 
-       /* Get which IRQs that happend. */
+       /* Get which IRQs that happened. */
        masked = REG_RD_INT(intr_vect, irq_regs[cpu], r_masked_vect);
 
        /* Calculate new IRQ mask with these IRQs disabled. */
@@ -366,7 +366,7 @@ init_IRQ(void)
        for (i = 0; i < 256; i++)
                etrax_irv->v[i] = weird_irq;
 
-       /* Point all IRQ's to bad handlers. */
+       /* Point all IRQs to bad handlers. */
        for (i = FIRST_IRQ, j = 0; j < NR_IRQS; i++, j++) {
                irq_desc[j].chip = &crisv32_irq_type;
                set_exception_vector(i, interrupt[j]);
index 6326351af2528300ec01f287ed3bff40d4019ac8..b72a15580dc73a674ab832e5184939ebe42ec25f 100644 (file)
@@ -162,7 +162,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
        /* Put the switch stack right below the pt_regs. */
        swstack = ((struct switch_stack *) childregs) - 1;
 
-       /* Paramater to ret_from_sys_call. 0 is don't restart the syscall. */
+       /* Parameter to ret_from_sys_call. 0 is don't restart the syscall. */
        swstack->r9 = 0;
 
        /*
index 7cd6ac80340940300defd4f75ce48be1629461e9..024cc690197450a27f563915c5fc4bcfa98927cc 100644 (file)
@@ -347,7 +347,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
 /* Grab and setup a signal frame.
  *
  * Basically a lot of state-info is stacked, and arranged for the
- * user-mode program to return to the kernel using either a trampiline
+ * user-mode program to return to the kernel using either a trampoline
  * which performs the syscall sigreturn(), or a provided user-mode
  * trampoline.
   */
@@ -641,7 +641,7 @@ ugdb_trap_user(struct thread_info *ti, int sig)
                user_regs(ti)->spc = 0;
        }
        /* FIXME: Filter out false h/w breakpoint hits (i.e. EDA
-          not withing any configured h/w breakpoint range). Synchronize with
+          not within any configured h/w breakpoint range). Synchronize with
           what already exists for kernel debugging.  */
        if (((user_regs(ti)->exs & 0xff00) >> 8) == BREAK_8_INTR_VECT) {
                /* Break 8: subtract 2 from ERP unless in a delay slot. */
index 697494bc2de1ef360b47e811b740e48ae9fe7c55..171c96e0a5d35a770c01a3630a5a8bc2b14e436c 100644 (file)
@@ -142,7 +142,7 @@ smp_boot_one_cpu(int cpuid)
        return -1;
 }
 
-/* Secondary CPUs starts uing C here. Here we need to setup CPU
+/* Secondary CPUs starts using C here. Here we need to setup CPU
  * specific stuff such as the local timer and the MMU. */
 void __init smp_callin(void)
 {
index be0a01657d4fc88076e120b88264977acd25d2ed..2f7e8e200f2cdd033a387eb96a0baa9b5f91ddd6 100644 (file)
@@ -99,7 +99,7 @@ unsigned long do_slow_gettimeoffset(void)
 /* From timer MDS describing the hardware watchdog:
  * 4.3.1 Watchdog Operation
  * The watchdog timer is an 8-bit timer with a configurable start value.
- * Once started the whatchdog counts downwards with a frequency of 763 Hz
+ * Once started the watchdog counts downwards with a frequency of 763 Hz
  * (100/131072 MHz). When the watchdog counts down to 1, it generates an
  * NMI (Non Maskable Interrupt), and when it counts down to 0, it resets the
  * chip.
index 2462b1ef1fbba56fe13e559bf09caa03424f4821..17fd3dbd1c80ed3daa804f1f9b29bcc8a1abc4f5 100644 (file)
@@ -105,7 +105,7 @@ bad_value:
 
 /*
  * This gets called from entry.S when the watchdog has bitten. Show something
- * similiar to an Oops dump, and if the kernel if configured to be a nice doggy;
+ * similar to an Oops dump, and if the kernel is configured to be a nice doggy;
  * halt instead of reboot.
  */
 void
index 158b3dbb4d9d91a67b499afb057db5206d88585d..218fbe259ee50eab7e5efec576606a9895e3fd66 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 /* Just to be certain the config file is included, we include it here
- * explicitely instead of depending on it being included in the file that
+ * explicitly instead of depending on it being included in the file that
  * uses this code.
  */
 
index 98e282ac824af373cf75c85e252518ada91ded77..6740b2cebae5169d05a09d69ad5f99851394d8bc 100644 (file)
@@ -41,7 +41,7 @@ void *memcpy(void *pdst,
      Make sure the compiler is able to make something useful of this.
       As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
 
-     If gcc was allright, it really would need no temporaries, and no
+     If gcc was alright, it really would need no temporaries, and no
      stack space to save stuff on. */
 
   register void *return_dst __asm__ ("r10") = pdst;
index f0b08460c1be59e96466da1571ad5f0cd4bd8683..04d0cf35a2761b531c1350c58ecf36e081961fb7 100644 (file)
@@ -34,7 +34,7 @@ __copy_user (void __user *pdst, const void *psrc, unsigned long pn)
      As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
 
      FIXME: Comment for old gcc version.  Check.
-     If gcc was allright, it really would need no temporaries, and no
+     If gcc was alright, it really would need no temporaries, and no
      stack space to save stuff on. */
 
   register char *dst __asm__ ("r13") = pdst;
@@ -168,7 +168,7 @@ __copy_user_zeroing (void __user *pdst, const void *psrc, unsigned long pn)
      As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
 
      FIXME: Comment for old gcc version.  Check.
-     If gcc was allright, it really would need no temporaries, and no
+     If gcc was alright, it really would need no temporaries, and no
      stack space to save stuff on.  */
 
   register char *dst __asm__ ("r13") = pdst;
@@ -332,7 +332,7 @@ __do_clear_user (void __user *pto, unsigned long pn)
       As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
 
      FIXME: Comment for old gcc version.  Check.
-     If gcc was allright, it really would need no temporaries, and no
+     If gcc was alright, it really would need no temporaries, and no
      stack space to save stuff on. */
 
   register char *dst __asm__ ("r13") = pto;
index c2d12e9c40d79a2e5720837bdaca10bebd07693c..a076ef6e93893756436d32f6ef15927a33b642bd 100644 (file)
@@ -30,8 +30,8 @@ do {                                          \
  * The TLB can host up to 256 different mm contexts at the same time. The running
  * context is found in the PID register. Each TLB entry contains a page_id that
  * has to match the PID register to give a hit. page_id_map keeps track of which
- * mm's is assigned to which page_id's, making sure it's known when to
- * invalidate TLB entries.
+ * mm is assigned to which page_id, making sure it's known when to invalidate TLB
+ * entries.
  *
  * The last page_id is never running, it is used as an invalid page_id so that
  * it's possible to make TLB entries that will nerver match.
@@ -188,7 +188,7 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
        spin_unlock(&mmu_context_lock);
 
        /*
-        * Remember the pgd for the fault handlers. Keep a seperate copy of it
+        * Remember the pgd for the fault handlers. Keep a separate copy of it
         * because current and active_mm might be invalid at points where
         * there's still a need to derefer the pgd.
         */
index 903ea62c6e21b6ac5fa6ed899cba5c5c261b6015..5c27ff86121b9c40ccb39a60b9e3772d52c8a331 100644 (file)
@@ -7,7 +7,7 @@
  *      Authors: Bjorn Wesen (bjornw@axis.com)
  *
  * This file contains the code used by various IRQ handling routines:
- * asking for different IRQ's should be done through these routines
+ * asking for different IRQs should be done through these routines
  * instead of just grabbing them. Thus setups with different IRQ numbers
  * shouldn't result in any weird surprises, and installing new handlers
  * should be easier.
@@ -15,7 +15,7 @@
  */
 
 /*
- * IRQ's are in fact implemented a bit like signal handlers for the kernel.
+ * IRQs are in fact implemented a bit like signal handlers for the kernel.
  * Naturally it's not a 1:1 relation, but there are similarities.
  */
 
@@ -83,9 +83,9 @@ skip:
 
 
 /* called by the assembler IRQ entry functions defined in irq.h
- * to dispatch the interrupts to registred handlers
+ * to dispatch the interrupts to registered handlers
  * interrupts are disabled upon entry - depending on if the
- * interrupt was registred with IRQF_DISABLED or not, interrupts
+ * interrupt was registered with IRQF_DISABLED or not, interrupts
  * are re-enabled or not.
  */
 
index 8aab814306955a68a150a2453cfcb72f62c2441f..3034f3ff950c6014f807ad03a898b1619ac9669c 100644 (file)
@@ -13,7 +13,7 @@
  *  Fixed warning.
  *
  *  Revision 1.18  2005/01/12 08:10:14  starvik
- *  Readded the change of frametype when handling kernel page fault fixup
+ *  Re-added the change of frametype when handling kernel page fault fixup
  *  for v10. This is necessary to avoid that the CPU remakes the faulting
  *  access.
  *
@@ -49,7 +49,7 @@
  *
  *  Revision 1.8  2003/07/04 13:02:48  tobiasa
  *  Moved code snippet from arch/cris/mm/fault.c that searches for fixup code
- *  to seperate function in arch-specific files.
+ *  to separate function in arch-specific files.
  *
  *  Revision 1.7  2003/01/22 06:48:38  starvik
  *  Fixed warnings issued by GCC 3.2.1
index b7842ff213a6688f3e675e5c39b78bf311a34c12..0c833d176226516c6d664ef20c4aa36e4a387c18 100644 (file)
@@ -8,7 +8,7 @@
  *
  *  $Log: init.c,v $
  *  Revision 1.11  2004/05/28 09:28:56  starvik
- *  Calculation of loops_per_usec moved because initalization order has changed
+ *  Calculation of loops_per_usec moved because initialization order has changed
  *  in Linux 2.6.
  *
  *  Revision 1.10  2004/05/14 07:58:05  starvik
index c4a98e2e529e04dd46b85ff768bdabad3df8d1a4..b7f8de576777f83ab8f9c7f2e75c125b2d88822b 100644 (file)
@@ -16,7 +16,7 @@
 /* The TLB can host up to 64 different mm contexts at the same time.
  * The running context is R_MMU_CONTEXT, and each TLB entry contains a
  * page_id that has to match to give a hit. In page_id_map, we keep track
- * of which mm's we have assigned which page_id's, so that we know when
+ * of which mm we have assigned to which page_id, so that we know when
  * to invalidate TLB entries.
  *
  * The last page_id is never running - it is used as an invalid page_id
index 74eef7111f2bd429e60d93e1a5d021dd3ca5f50d..43153e767bb1ab548f1edc52bb755233b38830c3 100644 (file)
@@ -375,6 +375,8 @@ source "drivers/Kconfig"
 
 source "fs/Kconfig"
 
+source "kernel/Kconfig.instrumentation"
+
 source "arch/frv/Kconfig.debug"
 
 source "security/Kconfig"
index ad753c1e9b8fffa652e4e682f107f42ec400c5fc..9e38f99bbab89c7e0677e5da0f38f09d9d6590ea 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/irq.h>
+#include <linux/bitops.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
-#include <asm/bitops.h>
 #include <asm/delay.h>
 #include <asm/irq.h>
 #include <asm/irc-regs.h>
index e0983f6926ed77be5b8874a7624051c258b63bc4..3c2752ca97754eb881d5fef6ceeeb576ee679df1 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/irq.h>
+#include <linux/bitops.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
-#include <asm/bitops.h>
 #include <asm/delay.h>
 #include <asm/irq.h>
 #include <asm/irc-regs.h>
index c157eeff871d218348e12bcb48f2c3b951e1eaef..7754c7338e4b42cfaeb4c3a76158665f3b05d275 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/irq.h>
+#include <linux/bitops.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
-#include <asm/bitops.h>
 #include <asm/delay.h>
 #include <asm/irq.h>
 #include <asm/irc-regs.h>
index c7e59dcadee47d58c7c44dac6d1cbce7a2134730..73abae767fdc8a089c468372ba7ae499a21f65f2 100644 (file)
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/module.h>
+#include <linux/bitops.h>
 
 #include <asm/atomic.h>
 #include <asm/io.h>
 #include <asm/smp.h>
 #include <asm/system.h>
-#include <asm/bitops.h>
 #include <asm/uaccess.h>
 #include <asm/pgalloc.h>
 #include <asm/delay.h>
@@ -134,7 +134,7 @@ static struct irq_chip frv_cpu_pic = {
 };
 
 /*
- * handles all normal device IRQ's
+ * handles all normal device IRQs
  * - registers are referred to by the __frame variable (GR28)
  * - IRQ distribution is complicated in this arch because of the many PICs, the
  *   way they work and the way they cascade
index 8e182ced1a0f028d1020e5f44df4da8e5512722c..7ee3a147b47143cefb3b8c184727edaf933c1117 100644 (file)
@@ -139,7 +139,7 @@ void __up(struct semaphore *sem)
        waiter = list_entry(sem->wait_list.next, struct sem_waiter, list);
 
        /* We must be careful not to touch 'waiter' after we set ->task = NULL.
-        * It is an allocated on the waiter's stack and may become invalid at
+        * It is allocated on the waiter's stack and may become invalid at
         * any time after that point (due to a wakeup from another source).
         */
        list_del_init(&waiter->list);
index e83e0bccfab98d50af92d125e133ef8b275973fd..925fb0199a0f21cc8df27e2cbaf137b67a7a3d47 100644 (file)
@@ -66,7 +66,7 @@ static irqreturn_t timer_interrupt(int irq, void *dummy)
        /*
         * Here we are in the timer irq handler. We just have irqs locally
         * disabled but we don't know if the timer_bh is running on the other
-        * CPU. We need to avoid to SMP race with it. NOTE: we don' t need
+        * CPU. We need to avoid to SMP race with it. NOTE: we don't need
         * the irq version of write_lock because as just said we have irq
         * locally disabled. -arca
         */
@@ -126,7 +126,7 @@ void time_init(void)
 
        /* FIX by dqg : Set to zero for platforms that don't have tod */
        /* without this time is undefined and can overflow time_t, causing  */
-       /* very stange errors */
+       /* very strange errors */
        year = 1980;
        mon = day = 1;
        hour = min = sec = 0;
index e35f74e6e50566d489852d5156013e5e65de9c5d..e2e9f57abe2e33c012961f49734dea1837a69834 100644 (file)
@@ -223,6 +223,8 @@ endmenu
 
 source "fs/Kconfig"
 
+source "kernel/Kconfig.instrumentation"
+
 source "arch/h8300/Kconfig.debug"
 
 source "security/Kconfig"
index 996d97e953b07e2508ecc888717add2665a38cef..ee671c3f2c743eac455f2ac0b94fc798a2020c1c 100644 (file)
@@ -42,16 +42,16 @@ config SH_STANDARD_BIOS
          Require eCos/RedBoot
 
 config DEFAULT_CMDLINE
-       bool "Use buildin commandline"
+       bool "Use builtin commandline"
        default n
        help
-         buildin kernel commandline enabled.
+         builtin kernel commandline enabled.
 
 config KERNEL_COMMAND
        string "Buildin commmand string"
        depends on DEFAULT_CMDLINE
        help
-         buildin kernel commandline strings.
+         builtin kernel commandline strings.
 
 config BLKDEV_RESERVE
        bool "BLKDEV Reserved Memory"
index 43d21e93f41ff734eff4805399765232f9c723d6..8dec4dd57b4e06ff44f26da88a0f9d89d8b954da 100644 (file)
@@ -68,7 +68,7 @@ static void h8300_shutdown_irq(unsigned int irq)
 }
 
 /*
- * h8300 interrupt controler implementation
+ * h8300 interrupt controller implementation
  */
 struct irq_chip h8300irq_chip = {
        .name           = "H8300-INTC",
index 330638220a2e92792a692ba5d6b9ee95fac43bad..e37c835e67cf2bee6538e07a50913d08cb7a6eca 100644 (file)
@@ -53,7 +53,7 @@ void time_init(void)
 
        /* FIX by dqg : Set to zero for platforms that don't have tod */
        /* without this time is undefined and can overflow time_t, causing  */
-       /* very stange errors */
+       /* very strange errors */
        year = 1980;
        mon = day = 1;
        hour = min = sec = 0;
index f97183011c2cb501ccf6cb07de9d12a87e00d93a..f8f7d7ea97f17298522e599d22ce4e388cc5009a 100644 (file)
@@ -5,7 +5,7 @@
  * Cloned from Linux/m68k.
  *
  * No original Copyright holder listed,
- * Probabily original (C) Roman Zippel (assigned DJD, 1999)
+ * Probable original (C) Roman Zippel (assigned DJD, 1999)
  *
  * Copyright 1999-2000 D. Jeff Dionne, <jeff@rt-control.com>
  *
index a71d6e2a3919d1075785fa9bf4101d4d47b7cab5..551fd5f30d826ae0a25ab015100c18d9d0b3d4c4 100644 (file)
@@ -179,7 +179,7 @@ int request_irq(unsigned int irq,
        if (use_kmalloc)
                irq_handle = kmalloc(sizeof(irq_handler_t), GFP_ATOMIC);
        else {
-               /* use bootmem allocater */
+               /* use bootmem allocator */
                irq_handle = (irq_handler_t *)alloc_bootmem(sizeof(irq_handler_t));
                irq_handle = (irq_handler_t *)((unsigned long)irq_handle | 0x80000000);
        }
index 93395d2a8a0795808f54d3e4d90e9630079921b7..faa8a459d95268a869208df0b964136e137812c1 100644 (file)
@@ -63,7 +63,7 @@ static const struct irq_pins irq_assign_table1[16]={
        {H8300_GPIO_P2,H8300_GPIO_B6},{H8300_GPIO_P2,H8300_GPIO_B7},
 };
 
-/* IRQ to GPIO pinno transrate */
+/* IRQ to GPIO pin translation */
 #define IRQ_GPIO_MAP(irqbit,irq,port,bit)                        \
 do {                                                             \
        if (*(volatile unsigned short *)ITSR & irqbit) {          \
index b84d5050e92ee7189d7aba36d3fd6e398b20e920..5bed8be34ba5bf4573a7b1fb182c62660ffa14e1 100644 (file)
@@ -227,28 +227,40 @@ config SCHED_NO_NO_OMIT_FRAME_POINTER
          If in doubt, say "Y".
 
 config PARAVIRT
-       bool "Paravirtualization support (EXPERIMENTAL)"
-       depends on EXPERIMENTAL
+       bool
        depends on !(X86_VISWS || X86_VOYAGER)
        help
-         Paravirtualization is a way of running multiple instances of
-         Linux on the same machine, under a hypervisor.  This option
-         changes the kernel so it can modify itself when it is run
-         under a hypervisor, improving performance significantly.
-         However, when run without a hypervisor the kernel is
-         theoretically slower.  If in doubt, say N.
+         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.
+
+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
 
 source "arch/x86/xen/Kconfig"
 
 config VMI
-       bool "VMI Paravirt-ops support"
-       depends on PARAVIRT
+       bool "VMI Guest support"
+       select PARAVIRT
+       depends on !(X86_VISWS || X86_VOYAGER)
        help
          VMI provides a paravirtualized interface to the VMware ESX server
          (it could be used by other hypervisors in theory too, but is not
          at the moment), by linking the kernel to a GPL-ed ROM module
          provided by the hypervisor.
 
+source "arch/x86/lguest/Kconfig"
+
+endif
+
 config ACPI_SRAT
        bool
        default y
@@ -392,7 +404,7 @@ config X86_MCE_NONFATAL
          will look at the machine check registers to see if anything happened.
          Non-fatal problems automatically get corrected (but still logged).
          Disable this if you don't want to see these messages.
-         Seeing the messages this option prints out may be indicative of dying hardware,
+         Seeing the messages this option prints out may be indicative of dying
          or out-of-spec (ie, overclocked) hardware.
          This option only does something on certain CPUs.
          (AMD Athlon/Duron and Intel Pentium 4)
@@ -631,7 +643,7 @@ config NUMA
        default n if X86_PC
        default y if (X86_NUMAQ || X86_SUMMIT)
        help
-         NUMA support for i386. This is currently high experimental
+         NUMA support for i386. This is currently highly experimental
          and should be only used for kernel development. It might also
          cause boot failures.
 
@@ -1080,7 +1092,9 @@ config APM_REAL_MODE_POWER_OFF
 
 endif # APM
 
-source "arch/x86/kernel/cpu/cpufreq/Kconfig"
+source "arch/x86/kernel/cpu/cpufreq/Kconfig_32"
+
+source "drivers/cpuidle/Kconfig"
 
 endmenu
 
@@ -1256,31 +1270,6 @@ source "drivers/Kconfig"
 
 source "fs/Kconfig"
 
-menuconfig INSTRUMENTATION
-       bool "Instrumentation Support"
-       default y
-       ---help---
-         Say Y here to get to see options related to performance measurement,
-         debugging, and testing. This option alone does not add any kernel code.
-
-         If you say N, all options in this submenu will be skipped and disabled.
-
-if INSTRUMENTATION
-
-source "arch/x86/oprofile/Kconfig"
-
-config KPROBES
-       bool "Kprobes"
-       depends on KALLSYMS && MODULES
-       help
-         Kprobes allows you to trap at almost any kernel address and
-         execute a callback function.  register_kprobe() establishes
-         a probepoint and specifies the callback.  Kprobes is useful
-         for kernel debugging, non-intrusive instrumentation and testing.
-         If in doubt, say "N".
-
-endif # INSTRUMENTATION
-
 source "arch/i386/Kconfig.debug"
 
 source "security/Kconfig"
index f036d2dee3def4508411ebb9401e06e433039303..b81cb64d48e5f689ca229e443e7b996c7f7db393 100644 (file)
@@ -99,10 +99,13 @@ core-$(CONFIG_X86_ES7000)   := arch/x86/mach-es7000/
 # Xen paravirtualization support
 core-$(CONFIG_XEN)             += arch/x86/xen/
 
+# lguest paravirtualization support
+core-$(CONFIG_LGUEST_GUEST)    += arch/x86/lguest/
+
 # default subarch .h files
 mflags-y += -Iinclude/asm-x86/mach-default
 
-head-y := arch/x86/kernel/head_32.o arch/x86/kernel/init_task_32.o
+head-y := arch/x86/kernel/head_32.o arch/x86/kernel/init_task.o
 
 libs-y                                         += arch/x86/lib/
 core-y                                 += arch/x86/kernel/ \
@@ -131,9 +134,9 @@ all: bzImage
 zImage zlilo zdisk: KBUILD_IMAGE := arch/x86/boot/zImage
 
 zImage bzImage: vmlinux
-       $(Q)mkdir -p $(objtree)/arch/i386/boot
-       $(Q)ln -fsn $(objtree)/arch/x86/boot/bzImage $(objtree)/arch/i386/boot/bzImage
        $(Q)$(MAKE) $(build)=$(boot) $(KBUILD_IMAGE)
+       $(Q)mkdir -p $(objtree)/arch/i386/boot
+       $(Q)ln -fsn ../../x86/boot/bzImage $(objtree)/arch/i386/boot/bzImage
 
 compressed: zImage
 
index c60532d93c541714efd6111b871a530bedf3479a..bef47725d4ad461310e181d98fb3d04aa214b061 100644 (file)
@@ -452,9 +452,9 @@ config IA64_PALINFO
 config IA64_MC_ERR_INJECT
        tristate "MC error injection support"
        help
-         Selets whether support for MC error injection. By enabling the
-         support, kernel provide sysfs interface for user application to
-         call MC error injection PAL procedure to inject various errors.
+         Adds support for MC error injection. If enabled, the kernel 
+         will provide a sysfs interface for user applications to
+         call MC error injection PAL procedures to inject various errors.
          This is a useful tool for MCA testing.
 
          If you're unsure, do not select this option.
@@ -491,7 +491,7 @@ config KEXEC
          but it is independent of the system firmware.   And like a reboot
          you can start any kernel with it, not just Linux.
 
-         The name comes from the similiarity to the exec system call.
+         The name comes from the similarity to the exec system call.
 
          It is an ongoing process to be certain the hardware in a machine
          is properly shutdown, so do not be surprised if this code does not
@@ -592,20 +592,7 @@ config IRQ_PER_CPU
 
 source "arch/ia64/hp/sim/Kconfig"
 
-menu "Instrumentation Support"
-
-source "arch/ia64/oprofile/Kconfig"
-
-config KPROBES
-       bool "Kprobes"
-       depends on KALLSYMS && MODULES
-       help
-         Kprobes allows you to trap at almost any kernel address and
-         execute a callback function.  register_kprobe() establishes
-         a probepoint and specifies the callback.  Kprobes is useful
-         for kernel debugging, non-intrusive instrumentation and testing.
-         If in doubt, say "N".
-endmenu
+source "kernel/Kconfig.instrumentation"
 
 source "arch/ia64/Kconfig.debug"
 
index 449d3e75bfc29153752a4f732ce1d07ee6719891..75fd90dc76a3e73165a3f75964b7ea1823445392 100644 (file)
@@ -26,6 +26,7 @@ CONFIG_TASK_IO_ACCOUNTING=y
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=20
+CONFIG_CGROUPS=y
 CONFIG_CPUSETS=y
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
index 3c95f4184b996d26e98ba709acff2052d40313e8..bc859a311eaf07774379ad3daa40067cb252c304 100644 (file)
@@ -246,7 +246,7 @@ static int reserve_sba_gart = 1;
 static SBA_INLINE void sba_mark_invalid(struct ioc *, dma_addr_t, size_t);
 static SBA_INLINE void sba_free_range(struct ioc *, dma_addr_t, size_t);
 
-#define sba_sg_address(sg)     (page_address((sg)->page) + (sg)->offset)
+#define sba_sg_address(sg)     sg_virt((sg))
 
 #ifdef FULL_VALID_PDIR
 static u64 prefetch_spill_page;
index a3a558a0675779e602d9bb43625646cfe2cb02b6..6ef9b52199304af2f472f92becd0216cbbe2e492 100644 (file)
@@ -131,7 +131,7 @@ simscsi_sg_readwrite (struct scsi_cmnd *sc, int mode, unsigned long offset)
        stat.fd = desc[sc->device->id];
 
        scsi_for_each_sg(sc, sl, scsi_sg_count(sc), i) {
-               req.addr = __pa(page_address(sl->page) + sl->offset);
+               req.addr = __pa(sg_virt(sl));
                req.len  = sl->length;
                if (DBG)
                        printk("simscsi_sg_%s @ %lx (off %lx) use_sg=%d len=%d\n",
@@ -212,7 +212,7 @@ static void simscsi_fillresult(struct scsi_cmnd *sc, char *buf, unsigned len)
                if (!len)
                        break;
                thislen = min(len, slp->length);
-               memcpy(page_address(slp->page) + slp->offset, buf, thislen);
+               memcpy(sg_virt(slp), buf, thislen);
                len -= thislen;
        }
 }
index a3405b3c1eefba2a0ba94ac0e4ecd9b647992d84..d025a22eb225f6bf455ec5a76b47434dc09a0977 100644 (file)
@@ -773,7 +773,7 @@ emulate_mmap (struct file *file, unsigned long start, unsigned long len, int pro
                        if (flags & MAP_SHARED)
                                printk(KERN_INFO
                                       "%s(%d): emulate_mmap() can't share head (addr=0x%lx)\n",
-                                      current->comm, current->pid, start);
+                                      current->comm, task_pid_nr(current), start);
                        ret = mmap_subpage(file, start, min(PAGE_ALIGN(start), end), prot, flags,
                                           off);
                        if (IS_ERR((void *) ret))
@@ -786,7 +786,7 @@ emulate_mmap (struct file *file, unsigned long start, unsigned long len, int pro
                        if (flags & MAP_SHARED)
                                printk(KERN_INFO
                                       "%s(%d): emulate_mmap() can't share tail (end=0x%lx)\n",
-                                      current->comm, current->pid, end);
+                                      current->comm, task_pid_nr(current), end);
                        ret = mmap_subpage(file, max(start, PAGE_START(end)), end, prot, flags,
                                           (off + len) - offset_in_page(end));
                        if (IS_ERR((void *) ret))
@@ -816,7 +816,7 @@ emulate_mmap (struct file *file, unsigned long start, unsigned long len, int pro
 
        if ((flags & MAP_SHARED) && !is_congruent)
                printk(KERN_INFO "%s(%d): emulate_mmap() can't share contents of incongruent mmap "
-                      "(addr=0x%lx,off=0x%llx)\n", current->comm, current->pid, start, off);
+                      "(addr=0x%lx,off=0x%llx)\n", current->comm, task_pid_nr(current), start, off);
 
        DBG("mmap_body: mapping [0x%lx-0x%lx) %s with poff 0x%llx\n", pstart, pend,
            is_congruent ? "congruent" : "not congruent", poff);
index 73ca86d03810429fe29df09926741131017d600f..3f7ea13358e952366eeef347a208facb92d5e57f 100644 (file)
@@ -967,7 +967,7 @@ find_memmap_space (void)
  * to use.  We can allocate partial granules only if the unavailable
  * parts exist, and are WB.
  */
-void
+unsigned long
 efi_memmap_init(unsigned long *s, unsigned long *e)
 {
        struct kern_memdesc *k, *prev = NULL;
@@ -1084,11 +1084,14 @@ efi_memmap_init(unsigned long *s, unsigned long *e)
        /* reserve the memory we are using for kern_memmap */
        *s = (u64)kern_memmap;
        *e = (u64)++k;
+
+       return total_mem;
 }
 
 void
 efi_initialize_iomem_resources(struct resource *code_resource,
-                              struct resource *data_resource)
+                              struct resource *data_resource,
+                              struct resource *bss_resource)
 {
        struct resource *res;
        void *efi_map_start, *efi_map_end, *p;
@@ -1169,6 +1172,7 @@ efi_initialize_iomem_resources(struct resource *code_resource,
                         */
                        insert_resource(res, code_resource);
                        insert_resource(res, data_resource);
+                       insert_resource(res, bss_resource);
 #ifdef CONFIG_KEXEC
                         insert_resource(res, &efi_memmap_res);
                         insert_resource(res, &boot_param_res);
index f55fa07849c4c4383182d8b2acd6abfa62067d41..59169bf7145f69f955708f49c4a9debb5c2fa713 100644 (file)
  */
 #define PROTECT_CTX(c, f) \
        do {  \
-               DPRINT(("spinlock_irq_save ctx %p by [%d]\n", c, current->pid)); \
+               DPRINT(("spinlock_irq_save ctx %p by [%d]\n", c, task_pid_nr(current))); \
                spin_lock_irqsave(&(c)->ctx_lock, f); \
-               DPRINT(("spinlocked ctx %p  by [%d]\n", c, current->pid)); \
+               DPRINT(("spinlocked ctx %p  by [%d]\n", c, task_pid_nr(current))); \
        } while(0)
 
 #define UNPROTECT_CTX(c, f) \
        do { \
-               DPRINT(("spinlock_irq_restore ctx %p by [%d]\n", c, current->pid)); \
+               DPRINT(("spinlock_irq_restore ctx %p by [%d]\n", c, task_pid_nr(current))); \
                spin_unlock_irqrestore(&(c)->ctx_lock, f); \
        } while(0)
 
 #ifdef PFM_DEBUGGING
 #define DPRINT(a) \
        do { \
-               if (unlikely(pfm_sysctl.debug >0)) { printk("%s.%d: CPU%d [%d] ", __FUNCTION__, __LINE__, smp_processor_id(), current->pid); printk a; } \
+               if (unlikely(pfm_sysctl.debug >0)) { printk("%s.%d: CPU%d [%d] ", __FUNCTION__, __LINE__, smp_processor_id(), task_pid_nr(current)); printk a; } \
        } while (0)
 
 #define DPRINT_ovfl(a) \
        do { \
-               if (unlikely(pfm_sysctl.debug > 0 && pfm_sysctl.debug_ovfl >0)) { printk("%s.%d: CPU%d [%d] ", __FUNCTION__, __LINE__, smp_processor_id(), current->pid); printk a; } \
+               if (unlikely(pfm_sysctl.debug > 0 && pfm_sysctl.debug_ovfl >0)) { printk("%s.%d: CPU%d [%d] ", __FUNCTION__, __LINE__, smp_processor_id(), task_pid_nr(current)); printk a; } \
        } while (0)
 #endif
 
@@ -913,7 +913,7 @@ pfm_mask_monitoring(struct task_struct *task)
        unsigned long mask, val, ovfl_mask;
        int i;
 
-       DPRINT_ovfl(("masking monitoring for [%d]\n", task->pid));
+       DPRINT_ovfl(("masking monitoring for [%d]\n", task_pid_nr(task)));
 
        ovfl_mask = pmu_conf->ovfl_val;
        /*
@@ -992,12 +992,12 @@ pfm_restore_monitoring(struct task_struct *task)
        ovfl_mask = pmu_conf->ovfl_val;
 
        if (task != current) {
-               printk(KERN_ERR "perfmon.%d: invalid task[%d] current[%d]\n", __LINE__, task->pid, current->pid);
+               printk(KERN_ERR "perfmon.%d: invalid task[%d] current[%d]\n", __LINE__, task_pid_nr(task), task_pid_nr(current));
                return;
        }
        if (ctx->ctx_state != PFM_CTX_MASKED) {
                printk(KERN_ERR "perfmon.%d: task[%d] current[%d] invalid state=%d\n", __LINE__,
-                       task->pid, current->pid, ctx->ctx_state);
+                       task_pid_nr(task), task_pid_nr(current), ctx->ctx_state);
                return;
        }
        psr = pfm_get_psr();
@@ -1051,7 +1051,8 @@ pfm_restore_monitoring(struct task_struct *task)
                if ((mask & 0x1) == 0UL) continue;
                ctx->th_pmcs[i] = ctx->ctx_pmcs[i];
                ia64_set_pmc(i, ctx->th_pmcs[i]);
-               DPRINT(("[%d] pmc[%d]=0x%lx\n", task->pid, i, ctx->th_pmcs[i]));
+               DPRINT(("[%d] pmc[%d]=0x%lx\n",
+                                       task_pid_nr(task), i, ctx->th_pmcs[i]));
        }
        ia64_srlz_d();
 
@@ -1370,7 +1371,7 @@ pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu)
 
 error_conflict:
        DPRINT(("system wide not possible, conflicting session [%d] on CPU%d\n",
-               pfm_sessions.pfs_sys_session[cpu]->pid,
+               task_pid_nr(pfm_sessions.pfs_sys_session[cpu]),
                cpu));
 abort:
        UNLOCK_PFS(flags);
@@ -1442,7 +1443,7 @@ pfm_remove_smpl_mapping(struct task_struct *task, void *vaddr, unsigned long siz
 
        /* sanity checks */
        if (task->mm == NULL || size == 0UL || vaddr == NULL) {
-               printk(KERN_ERR "perfmon: pfm_remove_smpl_mapping [%d] invalid context mm=%p\n", task->pid, task->mm);
+               printk(KERN_ERR "perfmon: pfm_remove_smpl_mapping [%d] invalid context mm=%p\n", task_pid_nr(task), task->mm);
                return -EINVAL;
        }
 
@@ -1459,7 +1460,7 @@ pfm_remove_smpl_mapping(struct task_struct *task, void *vaddr, unsigned long siz
 
        up_write(&task->mm->mmap_sem);
        if (r !=0) {
-               printk(KERN_ERR "perfmon: [%d] unable to unmap sampling buffer @%p size=%lu\n", task->pid, vaddr, size);
+               printk(KERN_ERR "perfmon: [%d] unable to unmap sampling buffer @%p size=%lu\n", task_pid_nr(task), vaddr, size);
        }
 
        DPRINT(("do_unmap(%p, %lu)=%d\n", vaddr, size, r));
@@ -1501,7 +1502,7 @@ pfm_free_smpl_buffer(pfm_context_t *ctx)
        return 0;
 
 invalid_free:
-       printk(KERN_ERR "perfmon: pfm_free_smpl_buffer [%d] no buffer\n", current->pid);
+       printk(KERN_ERR "perfmon: pfm_free_smpl_buffer [%d] no buffer\n", task_pid_nr(current));
        return -EINVAL;
 }
 #endif
@@ -1547,13 +1548,13 @@ pfm_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
        unsigned long flags;
        DECLARE_WAITQUEUE(wait, current);
        if (PFM_IS_FILE(filp) == 0) {
-               printk(KERN_ERR "perfmon: pfm_poll: bad magic [%d]\n", current->pid);
+               printk(KERN_ERR "perfmon: pfm_poll: bad magic [%d]\n", task_pid_nr(current));
                return -EINVAL;
        }
 
        ctx = (pfm_context_t *)filp->private_data;
        if (ctx == NULL) {
-               printk(KERN_ERR "perfmon: pfm_read: NULL ctx [%d]\n", current->pid);
+               printk(KERN_ERR "perfmon: pfm_read: NULL ctx [%d]\n", task_pid_nr(current));
                return -EINVAL;
        }
 
@@ -1607,7 +1608,7 @@ pfm_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
 
                PROTECT_CTX(ctx, flags);
        }
-       DPRINT(("[%d] back to running ret=%ld\n", current->pid, ret));
+       DPRINT(("[%d] back to running ret=%ld\n", task_pid_nr(current), ret));
        set_current_state(TASK_RUNNING);
        remove_wait_queue(&ctx->ctx_msgq_wait, &wait);
 
@@ -1616,7 +1617,7 @@ pfm_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
        ret = -EINVAL;
        msg = pfm_get_next_msg(ctx);
        if (msg == NULL) {
-               printk(KERN_ERR "perfmon: pfm_read no msg for ctx=%p [%d]\n", ctx, current->pid);
+               printk(KERN_ERR "perfmon: pfm_read no msg for ctx=%p [%d]\n", ctx, task_pid_nr(current));
                goto abort_locked;
        }
 
@@ -1647,13 +1648,13 @@ pfm_poll(struct file *filp, poll_table * wait)
        unsigned int mask = 0;
 
        if (PFM_IS_FILE(filp) == 0) {
-               printk(KERN_ERR "perfmon: pfm_poll: bad magic [%d]\n", current->pid);
+               printk(KERN_ERR "perfmon: pfm_poll: bad magic [%d]\n", task_pid_nr(current));
                return 0;
        }
 
        ctx = (pfm_context_t *)filp->private_data;
        if (ctx == NULL) {
-               printk(KERN_ERR "perfmon: pfm_poll: NULL ctx [%d]\n", current->pid);
+               printk(KERN_ERR "perfmon: pfm_poll: NULL ctx [%d]\n", task_pid_nr(current));
                return 0;
        }
 
@@ -1692,7 +1693,7 @@ pfm_do_fasync(int fd, struct file *filp, pfm_context_t *ctx, int on)
        ret = fasync_helper (fd, filp, on, &ctx->ctx_async_queue);
 
        DPRINT(("pfm_fasync called by [%d] on ctx_fd=%d on=%d async_queue=%p ret=%d\n",
-               current->pid,
+               task_pid_nr(current),
                fd,
                on,
                ctx->ctx_async_queue, ret));
@@ -1707,13 +1708,13 @@ pfm_fasync(int fd, struct file *filp, int on)
        int ret;
 
        if (PFM_IS_FILE(filp) == 0) {
-               printk(KERN_ERR "perfmon: pfm_fasync bad magic [%d]\n", current->pid);
+               printk(KERN_ERR "perfmon: pfm_fasync bad magic [%d]\n", task_pid_nr(current));
                return -EBADF;
        }
 
        ctx = (pfm_context_t *)filp->private_data;
        if (ctx == NULL) {
-               printk(KERN_ERR "perfmon: pfm_fasync NULL ctx [%d]\n", current->pid);
+               printk(KERN_ERR "perfmon: pfm_fasync NULL ctx [%d]\n", task_pid_nr(current));
                return -EBADF;
        }
        /*
@@ -1759,7 +1760,7 @@ pfm_syswide_force_stop(void *info)
        if (owner != ctx->ctx_task) {
                printk(KERN_ERR "perfmon: pfm_syswide_force_stop CPU%d unexpected owner [%d] instead of [%d]\n",
                        smp_processor_id(),
-                       owner->pid, ctx->ctx_task->pid);
+                       task_pid_nr(owner), task_pid_nr(ctx->ctx_task));
                return;
        }
        if (GET_PMU_CTX() != ctx) {
@@ -1769,7 +1770,7 @@ pfm_syswide_force_stop(void *info)
                return;
        }
 
-       DPRINT(("on CPU%d forcing system wide stop for [%d]\n", smp_processor_id(), ctx->ctx_task->pid));       
+       DPRINT(("on CPU%d forcing system wide stop for [%d]\n", smp_processor_id(), task_pid_nr(ctx->ctx_task)));
        /*
         * the context is already protected in pfm_close(), we simply
         * need to mask interrupts to avoid a PMU interrupt race on
@@ -1821,7 +1822,7 @@ pfm_flush(struct file *filp, fl_owner_t id)
 
        ctx = (pfm_context_t *)filp->private_data;
        if (ctx == NULL) {
-               printk(KERN_ERR "perfmon: pfm_flush: NULL ctx [%d]\n", current->pid);
+               printk(KERN_ERR "perfmon: pfm_flush: NULL ctx [%d]\n", task_pid_nr(current));
                return -EBADF;
        }
 
@@ -1969,7 +1970,7 @@ pfm_close(struct inode *inode, struct file *filp)
        
        ctx = (pfm_context_t *)filp->private_data;
        if (ctx == NULL) {
-               printk(KERN_ERR "perfmon: pfm_close: NULL ctx [%d]\n", current->pid);
+               printk(KERN_ERR "perfmon: pfm_close: NULL ctx [%d]\n", task_pid_nr(current));
                return -EBADF;
        }
 
@@ -2066,7 +2067,7 @@ pfm_close(struct inode *inode, struct file *filp)
                 */
                ctx->ctx_state = PFM_CTX_ZOMBIE;
 
-               DPRINT(("zombie ctx for [%d]\n", task->pid));
+               DPRINT(("zombie ctx for [%d]\n", task_pid_nr(task)));
                /*
                 * cannot free the context on the spot. deferred until
                 * the task notices the ZOMBIE state
@@ -2472,7 +2473,7 @@ pfm_setup_buffer_fmt(struct task_struct *task, struct file *filp, pfm_context_t
        /* invoke and lock buffer format, if found */
        fmt = pfm_find_buffer_fmt(arg->ctx_smpl_buf_id);
        if (fmt == NULL) {
-               DPRINT(("[%d] cannot find buffer format\n", task->pid));
+               DPRINT(("[%d] cannot find buffer format\n", task_pid_nr(task)));
                return -EINVAL;
        }
 
@@ -2483,7 +2484,7 @@ pfm_setup_buffer_fmt(struct task_struct *task, struct file *filp, pfm_context_t
 
        ret = pfm_buf_fmt_validate(fmt, task, ctx_flags, cpu, fmt_arg);
 
-       DPRINT(("[%d] after validate(0x%x,%d,%p)=%d\n", task->pid, ctx_flags, cpu, fmt_arg, ret));
+       DPRINT(("[%d] after validate(0x%x,%d,%p)=%d\n", task_pid_nr(task), ctx_flags, cpu, fmt_arg, ret));
 
        if (ret) goto error;
 
@@ -2605,23 +2606,23 @@ pfm_task_incompatible(pfm_context_t *ctx, struct task_struct *task)
         * no kernel task or task not owner by caller
         */
        if (task->mm == NULL) {
-               DPRINT(("task [%d] has not memory context (kernel thread)\n", task->pid));
+               DPRINT(("task [%d] has not memory context (kernel thread)\n", task_pid_nr(task)));
                return -EPERM;
        }
        if (pfm_bad_permissions(task)) {
-               DPRINT(("no permission to attach to  [%d]\n", task->pid));
+               DPRINT(("no permission to attach to  [%d]\n", task_pid_nr(task)));
                return -EPERM;
        }
        /*
         * cannot block in self-monitoring mode
         */
        if (CTX_OVFL_NOBLOCK(ctx) == 0 && task == current) {
-               DPRINT(("cannot load a blocking context on self for [%d]\n", task->pid));
+               DPRINT(("cannot load a blocking context on self for [%d]\n", task_pid_nr(task)));
                return -EINVAL;
        }
 
        if (task->exit_state == EXIT_ZOMBIE) {
-               DPRINT(("cannot attach to  zombie task [%d]\n", task->pid));
+               DPRINT(("cannot attach to  zombie task [%d]\n", task_pid_nr(task)));
                return -EBUSY;
        }
 
@@ -2631,7 +2632,7 @@ pfm_task_incompatible(pfm_context_t *ctx, struct task_struct *task)
        if (task == current) return 0;
 
        if ((task->state != TASK_STOPPED) && (task->state != TASK_TRACED)) {
-               DPRINT(("cannot attach to non-stopped task [%d] state=%ld\n", task->pid, task->state));
+               DPRINT(("cannot attach to non-stopped task [%d] state=%ld\n", task_pid_nr(task), task->state));
                return -EBUSY;
        }
        /*
@@ -3512,7 +3513,7 @@ pfm_use_debug_registers(struct task_struct *task)
 
        if (pmu_conf->use_rr_dbregs == 0) return 0;
 
-       DPRINT(("called for [%d]\n", task->pid));
+       DPRINT(("called for [%d]\n", task_pid_nr(task)));
 
        /*
         * do it only once
@@ -3543,7 +3544,7 @@ pfm_use_debug_registers(struct task_struct *task)
        DPRINT(("ptrace_use_dbregs=%u  sys_use_dbregs=%u by [%d] ret = %d\n",
                  pfm_sessions.pfs_ptrace_use_dbregs,
                  pfm_sessions.pfs_sys_use_dbregs,
-                 task->pid, ret));
+                 task_pid_nr(task), ret));
 
        UNLOCK_PFS(flags);
 
@@ -3568,7 +3569,7 @@ pfm_release_debug_registers(struct task_struct *task)
 
        LOCK_PFS(flags);
        if (pfm_sessions.pfs_ptrace_use_dbregs == 0) {
-               printk(KERN_ERR "perfmon: invalid release for [%d] ptrace_use_dbregs=0\n", task->pid);
+               printk(KERN_ERR "perfmon: invalid release for [%d] ptrace_use_dbregs=0\n", task_pid_nr(task));
                ret = -1;
        }  else {
                pfm_sessions.pfs_ptrace_use_dbregs--;
@@ -3620,7 +3621,7 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
 
        /* sanity check */
        if (unlikely(task == NULL)) {
-               printk(KERN_ERR "perfmon: [%d] pfm_restart no task\n", current->pid);
+               printk(KERN_ERR "perfmon: [%d] pfm_restart no task\n", task_pid_nr(current));
                return -EINVAL;
        }
 
@@ -3629,7 +3630,7 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
                fmt = ctx->ctx_buf_fmt;
 
                DPRINT(("restarting self %d ovfl=0x%lx\n",
-                       task->pid,
+                       task_pid_nr(task),
                        ctx->ctx_ovfl_regs[0]));
 
                if (CTX_HAS_SMPL(ctx)) {
@@ -3653,11 +3654,11 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
                                pfm_reset_regs(ctx, ctx->ctx_ovfl_regs, PFM_PMD_LONG_RESET);
 
                        if (rst_ctrl.bits.mask_monitoring == 0) {
-                               DPRINT(("resuming monitoring for [%d]\n", task->pid));
+                               DPRINT(("resuming monitoring for [%d]\n", task_pid_nr(task)));
 
                                if (state == PFM_CTX_MASKED) pfm_restore_monitoring(task);
                        } else {
-                               DPRINT(("keeping monitoring stopped for [%d]\n", task->pid));
+                               DPRINT(("keeping monitoring stopped for [%d]\n", task_pid_nr(task)));
 
                                // cannot use pfm_stop_monitoring(task, regs);
                        }
@@ -3714,10 +3715,10 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
         * "self-monitoring".
         */
        if (CTX_OVFL_NOBLOCK(ctx) == 0 && state == PFM_CTX_MASKED) {
-               DPRINT(("unblocking [%d] \n", task->pid));
+               DPRINT(("unblocking [%d] \n", task_pid_nr(task)));
                complete(&ctx->ctx_restart_done);
        } else {
-               DPRINT(("[%d] armed exit trap\n", task->pid));
+               DPRINT(("[%d] armed exit trap\n", task_pid_nr(task)));
 
                ctx->ctx_fl_trap_reason = PFM_TRAP_REASON_RESET;
 
@@ -3805,7 +3806,7 @@ pfm_write_ibr_dbr(int mode, pfm_context_t *ctx, void *arg, int count, struct pt_
         * don't bother if we are loaded and task is being debugged
         */
        if (is_loaded && (thread->flags & IA64_THREAD_DBG_VALID) != 0) {
-               DPRINT(("debug registers already in use for [%d]\n", task->pid));
+               DPRINT(("debug registers already in use for [%d]\n", task_pid_nr(task)));
                return -EBUSY;
        }
 
@@ -3846,7 +3847,7 @@ pfm_write_ibr_dbr(int mode, pfm_context_t *ctx, void *arg, int count, struct pt_
         * is shared by all processes running on it
         */
        if (first_time && can_access_pmu) {
-               DPRINT(("[%d] clearing ibrs, dbrs\n", task->pid));
+               DPRINT(("[%d] clearing ibrs, dbrs\n", task_pid_nr(task)));
                for (i=0; i < pmu_conf->num_ibrs; i++) {
                        ia64_set_ibr(i, 0UL);
                        ia64_dv_serialize_instruction();
@@ -4035,7 +4036,7 @@ pfm_stop(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
                return -EBUSY;
        }
        DPRINT(("task [%d] ctx_state=%d is_system=%d\n",
-               PFM_CTX_TASK(ctx)->pid,
+               task_pid_nr(PFM_CTX_TASK(ctx)),
                state,
                is_system));
        /*
@@ -4093,7 +4094,7 @@ pfm_stop(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
                 * monitoring disabled in kernel at next reschedule
                 */
                ctx->ctx_saved_psr_up = 0;
-               DPRINT(("task=[%d]\n", task->pid));
+               DPRINT(("task=[%d]\n", task_pid_nr(task)));
        }
        return 0;
 }
@@ -4298,11 +4299,12 @@ pfm_context_load(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
 
                if (is_system) {
                        if (pfm_sessions.pfs_ptrace_use_dbregs) {
-                               DPRINT(("cannot load [%d] dbregs in use\n", task->pid));
+                               DPRINT(("cannot load [%d] dbregs in use\n",
+                                                       task_pid_nr(task)));
                                ret = -EBUSY;
                        } else {
                                pfm_sessions.pfs_sys_use_dbregs++;
-                               DPRINT(("load [%d] increased sys_use_dbreg=%u\n", task->pid, pfm_sessions.pfs_sys_use_dbregs));
+                               DPRINT(("load [%d] increased sys_use_dbreg=%u\n", task_pid_nr(task), pfm_sessions.pfs_sys_use_dbregs));
                                set_dbregs = 1;
                        }
                }
@@ -4394,7 +4396,7 @@ pfm_context_load(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
 
                        /* allow user level control */
                        ia64_psr(regs)->sp = 0;
-                       DPRINT(("clearing psr.sp for [%d]\n", task->pid));
+                       DPRINT(("clearing psr.sp for [%d]\n", task_pid_nr(task)));
 
                        SET_LAST_CPU(ctx, smp_processor_id());
                        INC_ACTIVATION();
@@ -4429,7 +4431,7 @@ pfm_context_load(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
                 */
                SET_PMU_OWNER(task, ctx);
 
-               DPRINT(("context loaded on PMU for [%d]\n", task->pid));
+               DPRINT(("context loaded on PMU for [%d]\n", task_pid_nr(task)));
        } else {
                /*
                 * when not current, task MUST be stopped, so this is safe
@@ -4493,7 +4495,7 @@ pfm_context_unload(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg
        int prev_state, is_system;
        int ret;
 
-       DPRINT(("ctx_state=%d task [%d]\n", ctx->ctx_state, task ? task->pid : -1));
+       DPRINT(("ctx_state=%d task [%d]\n", ctx->ctx_state, task ? task_pid_nr(task) : -1));
 
        prev_state = ctx->ctx_state;
        is_system  = ctx->ctx_fl_system;
@@ -4568,7 +4570,7 @@ pfm_context_unload(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg
                 */
                ia64_psr(regs)->sp = 1;
 
-               DPRINT(("setting psr.sp for [%d]\n", task->pid));
+               DPRINT(("setting psr.sp for [%d]\n", task_pid_nr(task)));
        }
        /*
         * save PMDs to context
@@ -4608,7 +4610,7 @@ pfm_context_unload(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg
        ctx->ctx_fl_can_restart  = 0;
        ctx->ctx_fl_going_zombie = 0;
 
-       DPRINT(("disconnected [%d] from context\n", task->pid));
+       DPRINT(("disconnected [%d] from context\n", task_pid_nr(task)));
 
        return 0;
 }
@@ -4631,7 +4633,7 @@ pfm_exit_thread(struct task_struct *task)
 
        PROTECT_CTX(ctx, flags);
 
-       DPRINT(("state=%d task [%d]\n", ctx->ctx_state, task->pid));
+       DPRINT(("state=%d task [%d]\n", ctx->ctx_state, task_pid_nr(task)));
 
        state = ctx->ctx_state;
        switch(state) {
@@ -4640,13 +4642,13 @@ pfm_exit_thread(struct task_struct *task)
                         * only comes to this function if pfm_context is not NULL, i.e., cannot
                         * be in unloaded state
                         */
-                       printk(KERN_ERR "perfmon: pfm_exit_thread [%d] ctx unloaded\n", task->pid);
+                       printk(KERN_ERR "perfmon: pfm_exit_thread [%d] ctx unloaded\n", task_pid_nr(task));
                        break;
                case PFM_CTX_LOADED:
                case PFM_CTX_MASKED:
                        ret = pfm_context_unload(ctx, NULL, 0, regs);
                        if (ret) {
-                               printk(KERN_ERR "perfmon: pfm_exit_thread [%d] state=%d unload failed %d\n", task->pid, state, ret);
+                               printk(KERN_ERR "perfmon: pfm_exit_thread [%d] state=%d unload failed %d\n", task_pid_nr(task), state, ret);
                        }
                        DPRINT(("ctx unloaded for current state was %d\n", state));
 
@@ -4655,12 +4657,12 @@ pfm_exit_thread(struct task_struct *task)
                case PFM_CTX_ZOMBIE:
                        ret = pfm_context_unload(ctx, NULL, 0, regs);
                        if (ret) {
-                               printk(KERN_ERR "perfmon: pfm_exit_thread [%d] state=%d unload failed %d\n", task->pid, state, ret);
+                               printk(KERN_ERR "perfmon: pfm_exit_thread [%d] state=%d unload failed %d\n", task_pid_nr(task), state, ret);
                        }
                        free_ok = 1;
                        break;
                default:
-                       printk(KERN_ERR "perfmon: pfm_exit_thread [%d] unexpected state=%d\n", task->pid, state);
+                       printk(KERN_ERR "perfmon: pfm_exit_thread [%d] unexpected state=%d\n", task_pid_nr(task), state);
                        break;
        }
        UNPROTECT_CTX(ctx, flags);
@@ -4744,7 +4746,7 @@ recheck:
        DPRINT(("context %d state=%d [%d] task_state=%ld must_stop=%d\n",
                ctx->ctx_fd,
                state,
-               task->pid,
+               task_pid_nr(task),
                task->state, PFM_CMD_STOPPED(cmd)));
 
        /*
@@ -4791,7 +4793,7 @@ recheck:
         */
        if (PFM_CMD_STOPPED(cmd)) {
                if ((task->state != TASK_STOPPED) && (task->state != TASK_TRACED)) {
-                       DPRINT(("[%d] task not in stopped state\n", task->pid));
+                       DPRINT(("[%d] task not in stopped state\n", task_pid_nr(task)));
                        return -EBUSY;
                }
                /*
@@ -4884,7 +4886,7 @@ restart_args:
         * limit abuse to min page size
         */
        if (unlikely(sz > PFM_MAX_ARGSIZE)) {
-               printk(KERN_ERR "perfmon: [%d] argument too big %lu\n", current->pid, sz);
+               printk(KERN_ERR "perfmon: [%d] argument too big %lu\n", task_pid_nr(current), sz);
                return -E2BIG;
        }
 
@@ -5031,11 +5033,11 @@ pfm_context_force_terminate(pfm_context_t *ctx, struct pt_regs *regs)
 {
        int ret;
 
-       DPRINT(("entering for [%d]\n", current->pid));
+       DPRINT(("entering for [%d]\n", task_pid_nr(current)));
 
        ret = pfm_context_unload(ctx, NULL, 0, regs);
        if (ret) {
-               printk(KERN_ERR "pfm_context_force_terminate: [%d] unloaded failed with %d\n", current->pid, ret);
+               printk(KERN_ERR "pfm_context_force_terminate: [%d] unloaded failed with %d\n", task_pid_nr(current), ret);
        }
 
        /*
@@ -5072,7 +5074,7 @@ pfm_handle_work(void)
 
        ctx = PFM_GET_CTX(current);
        if (ctx == NULL) {
-               printk(KERN_ERR "perfmon: [%d] has no PFM context\n", current->pid);
+               printk(KERN_ERR "perfmon: [%d] has no PFM context\n", task_pid_nr(current));
                return;
        }
 
@@ -5269,7 +5271,7 @@ pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, str
        DPRINT_ovfl(("pmc0=0x%lx pid=%d iip=0x%lx, %s "
                     "used_pmds=0x%lx\n",
                        pmc0,
-                       task ? task->pid: -1,
+                       task ? task_pid_nr(task): -1,
                        (regs ? regs->cr_iip : 0),
                        CTX_OVFL_NOBLOCK(ctx) ? "nonblocking" : "blocking",
                        ctx->ctx_used_pmds[0]));
@@ -5458,7 +5460,7 @@ pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, str
        }
 
        DPRINT_ovfl(("owner [%d] pending=%ld reason=%u ovfl_pmds=0x%lx ovfl_notify=0x%lx masked=%d\n",
-                       GET_PMU_OWNER() ? GET_PMU_OWNER()->pid : -1,
+                       GET_PMU_OWNER() ? task_pid_nr(GET_PMU_OWNER()) : -1,
                        PFM_GET_WORK_PENDING(task),
                        ctx->ctx_fl_trap_reason,
                        ovfl_pmds,
@@ -5483,7 +5485,7 @@ pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, str
 sanity_check:
        printk(KERN_ERR "perfmon: CPU%d overflow handler [%d] pmc0=0x%lx\n",
                        smp_processor_id(),
-                       task ? task->pid : -1,
+                       task ? task_pid_nr(task) : -1,
                        pmc0);
        return;
 
@@ -5516,7 +5518,7 @@ stop_monitoring:
         *
         * Overall pretty hairy stuff....
         */
-       DPRINT(("ctx is zombie for [%d], converted to spurious\n", task ? task->pid: -1));
+       DPRINT(("ctx is zombie for [%d], converted to spurious\n", task ? task_pid_nr(task): -1));
        pfm_clear_psr_up();
        ia64_psr(regs)->up = 0;
        ia64_psr(regs)->sp = 1;
@@ -5577,13 +5579,13 @@ pfm_do_interrupt_handler(int irq, void *arg, struct pt_regs *regs)
 
 report_spurious1:
        printk(KERN_INFO "perfmon: spurious overflow interrupt on CPU%d: process %d has no PFM context\n",
-               this_cpu, task->pid);
+               this_cpu, task_pid_nr(task));
        pfm_unfreeze_pmu();
        return -1;
 report_spurious2:
        printk(KERN_INFO "perfmon: spurious overflow interrupt on CPU%d: process %d, invalid flag\n", 
                this_cpu, 
-               task->pid);
+               task_pid_nr(task));
        pfm_unfreeze_pmu();
        return -1;
 }
@@ -5870,7 +5872,8 @@ pfm_force_cleanup(pfm_context_t *ctx, struct pt_regs *regs)
        ia64_psr(regs)->sp = 1;
 
        if (GET_PMU_OWNER() == task) {
-               DPRINT(("cleared ownership for [%d]\n", ctx->ctx_task->pid));
+               DPRINT(("cleared ownership for [%d]\n",
+                                       task_pid_nr(ctx->ctx_task)));
                SET_PMU_OWNER(NULL, NULL);
        }
 
@@ -5882,7 +5885,7 @@ pfm_force_cleanup(pfm_context_t *ctx, struct pt_regs *regs)
        task->thread.pfm_context  = NULL;
        task->thread.flags       &= ~IA64_THREAD_PM_VALID;
 
-       DPRINT(("force cleanup for [%d]\n",  task->pid));
+       DPRINT(("force cleanup for [%d]\n",  task_pid_nr(task)));
 }
 
 
@@ -6426,7 +6429,7 @@ pfm_flush_pmds(struct task_struct *task, pfm_context_t *ctx)
 
                if (PMD_IS_COUNTING(i)) {
                        DPRINT(("[%d] pmd[%d] ctx_pmd=0x%lx hw_pmd=0x%lx\n",
-                               task->pid,
+                               task_pid_nr(task),
                                i,
                                ctx->ctx_pmds[i].val,
                                val & ovfl_val));
@@ -6448,11 +6451,11 @@ pfm_flush_pmds(struct task_struct *task, pfm_context_t *ctx)
                         */
                        if (pmc0 & (1UL << i)) {
                                val += 1 + ovfl_val;
-                               DPRINT(("[%d] pmd[%d] overflowed\n", task->pid, i));
+                               DPRINT(("[%d] pmd[%d] overflowed\n", task_pid_nr(task), i));
                        }
                }
 
-               DPRINT(("[%d] ctx_pmd[%d]=0x%lx  pmd_val=0x%lx\n", task->pid, i, val, pmd_val));
+               DPRINT(("[%d] ctx_pmd[%d]=0x%lx  pmd_val=0x%lx\n", task_pid_nr(task), i, val, pmd_val));
 
                if (is_self) ctx->th_pmds[i] = pmd_val;
 
@@ -6793,14 +6796,14 @@ dump_pmu_state(const char *from)
        printk("CPU%d from %s() current [%d] iip=0x%lx %s\n", 
                this_cpu, 
                from, 
-               current->pid, 
+               task_pid_nr(current),
                regs->cr_iip,
                current->comm);
 
        task = GET_PMU_OWNER();
        ctx  = GET_PMU_CTX();
 
-       printk("->CPU%d owner [%d] ctx=%p\n", this_cpu, task ? task->pid : -1, ctx);
+       printk("->CPU%d owner [%d] ctx=%p\n", this_cpu, task ? task_pid_nr(task) : -1, ctx);
 
        psr = pfm_get_psr();
 
@@ -6848,7 +6851,7 @@ pfm_inherit(struct task_struct *task, struct pt_regs *regs)
 {
        struct thread_struct *thread;
 
-       DPRINT(("perfmon: pfm_inherit clearing state for [%d]\n", task->pid));
+       DPRINT(("perfmon: pfm_inherit clearing state for [%d]\n", task_pid_nr(task)));
 
        thread = &task->thread;
 
index ff80eab83b38668b5d3a573f064e97b1d13f5715..a7af1cb419f921490991a2d29c3a6e6bc69d6012 100644 (file)
@@ -44,11 +44,11 @@ default_validate(struct task_struct *task, unsigned int flags, int cpu, void *da
        int ret = 0;
 
        if (data == NULL) {
-               DPRINT(("[%d] no argument passed\n", task->pid));
+               DPRINT(("[%d] no argument passed\n", task_pid_nr(task)));
                return -EINVAL;
        }
 
-       DPRINT(("[%d] validate flags=0x%x CPU%d\n", task->pid, flags, cpu));
+       DPRINT(("[%d] validate flags=0x%x CPU%d\n", task_pid_nr(task), flags, cpu));
 
        /*
         * must hold at least the buffer header + one minimally sized entry
@@ -88,7 +88,7 @@ default_init(struct task_struct *task, void *buf, unsigned int flags, int cpu, v
        hdr->hdr_count        = 0UL;
 
        DPRINT(("[%d] buffer=%p buf_size=%lu hdr_size=%lu hdr_version=%u cur_offs=%lu\n",
-               task->pid,
+               task_pid_nr(task),
                buf,
                hdr->hdr_buf_size,
                sizeof(*hdr),
@@ -245,7 +245,7 @@ default_restart(struct task_struct *task, pfm_ovfl_ctrl_t *ctrl, void *buf, stru
 static int
 default_exit(struct task_struct *task, void *buf, struct pt_regs *regs)
 {
-       DPRINT(("[%d] exit(%p)\n", task->pid, buf));
+       DPRINT(("[%d] exit(%p)\n", task_pid_nr(task), buf));
        return 0;
 }
 
index c613fc0e91cc8bc5d1cdc6f204d4c3e76037b589..2418289ee5ca4a89e598f057c26f2f201497ea0e 100644 (file)
@@ -105,7 +105,8 @@ show_regs (struct pt_regs *regs)
        unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri;
 
        print_modules();
-       printk("\nPid: %d, CPU %d, comm: %20s\n", current->pid, smp_processor_id(), current->comm);
+       printk("\nPid: %d, CPU %d, comm: %20s\n", task_pid_nr(current),
+                       smp_processor_id(), current->comm);
        printk("psr : %016lx ifs : %016lx ip  : [<%016lx>]    %s\n",
               regs->cr_ipsr, regs->cr_ifs, ip, print_tainted());
        print_symbol("ip is at %s\n", ip);
index c5cfcfa4c87c1ae92db64feeda71039cd529e245..ae6c3c02e1170e63f1810bf37929cdf523d4d025 100644 (file)
@@ -90,7 +90,12 @@ static struct resource code_resource = {
        .name   = "Kernel code",
        .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
 };
-extern char _text[], _end[], _etext[];
+
+static struct resource bss_resource = {
+       .name   = "Kernel bss",
+       .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
+};
+extern char _text[], _end[], _etext[], _edata[], _bss[];
 
 unsigned long ia64_max_cacheline_size;
 
@@ -200,14 +205,59 @@ static int __init register_memory(void)
        code_resource.start = ia64_tpa(_text);
        code_resource.end   = ia64_tpa(_etext) - 1;
        data_resource.start = ia64_tpa(_etext);
-       data_resource.end   = ia64_tpa(_end) - 1;
-       efi_initialize_iomem_resources(&code_resource, &data_resource);
+       data_resource.end   = ia64_tpa(_edata) - 1;
+       bss_resource.start  = ia64_tpa(_bss);
+       bss_resource.end    = ia64_tpa(_end) - 1;
+       efi_initialize_iomem_resources(&code_resource, &data_resource,
+                       &bss_resource);
 
        return 0;
 }
 
 __initcall(register_memory);
 
+
+#ifdef CONFIG_KEXEC
+static void __init setup_crashkernel(unsigned long total, int *n)
+{
+       unsigned long long base = 0, size = 0;
+       int ret;
+
+       ret = parse_crashkernel(boot_command_line, total,
+                       &size, &base);
+       if (ret == 0 && size > 0) {
+               if (!base) {
+                       sort_regions(rsvd_region, *n);
+                       base = kdump_find_rsvd_region(size,
+                                       rsvd_region, *n);
+               }
+               if (base != ~0UL) {
+                       printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
+                                       "for crashkernel (System RAM: %ldMB)\n",
+                                       (unsigned long)(size >> 20),
+                                       (unsigned long)(base >> 20),
+                                       (unsigned long)(total >> 20));
+                       rsvd_region[*n].start =
+                               (unsigned long)__va(base);
+                       rsvd_region[*n].end =
+                               (unsigned long)__va(base + size);
+                       (*n)++;
+                       crashk_res.start = base;
+                       crashk_res.end = base + size - 1;
+               }
+       }
+       efi_memmap_res.start = ia64_boot_param->efi_memmap;
+       efi_memmap_res.end = efi_memmap_res.start +
+               ia64_boot_param->efi_memmap_size;
+       boot_param_res.start = __pa(ia64_boot_param);
+       boot_param_res.end = boot_param_res.start +
+               sizeof(*ia64_boot_param);
+}
+#else
+static inline void __init setup_crashkernel(unsigned long total, int *n)
+{}
+#endif
+
 /**
  * reserve_memory - setup reserved memory areas
  *
@@ -219,6 +269,7 @@ void __init
 reserve_memory (void)
 {
        int n = 0;
+       unsigned long total_memory;
 
        /*
         * none of the entries in this table overlap
@@ -254,50 +305,11 @@ reserve_memory (void)
                n++;
 #endif
 
-       efi_memmap_init(&rsvd_region[n].start, &rsvd_region[n].end);
+       total_memory = efi_memmap_init(&rsvd_region[n].start, &rsvd_region[n].end);
        n++;
 
-#ifdef CONFIG_KEXEC
-       /* crashkernel=size@offset specifies the size to reserve for a crash
-        * kernel. If offset is 0, then it is determined automatically.
-        * By reserving this memory we guarantee that linux never set's it
-        * up as a DMA target.Useful for holding code to do something
-        * appropriate after a kernel panic.
-        */
-       {
-               char *from = strstr(boot_command_line, "crashkernel=");
-               unsigned long base, size;
-               if (from) {
-                       size = memparse(from + 12, &from);
-                       if (*from == '@')
-                               base = memparse(from+1, &from);
-                       else
-                               base = 0;
-                       if (size) {
-                               if (!base) {
-                                       sort_regions(rsvd_region, n);
-                                       base = kdump_find_rsvd_region(size,
-                                                               rsvd_region, n);
-                                       }
-                               if (base != ~0UL) {
-                                       rsvd_region[n].start =
-                                               (unsigned long)__va(base);
-                                       rsvd_region[n].end =
-                                               (unsigned long)__va(base + size);
-                                       n++;
-                                       crashk_res.start = base;
-                                       crashk_res.end = base + size - 1;
-                               }
-                       }
-               }
-               efi_memmap_res.start = ia64_boot_param->efi_memmap;
-                efi_memmap_res.end = efi_memmap_res.start +
-                        ia64_boot_param->efi_memmap_size;
-                boot_param_res.start = __pa(ia64_boot_param);
-                boot_param_res.end = boot_param_res.start +
-                        sizeof(*ia64_boot_param);
-       }
-#endif
+       setup_crashkernel(total_memory, &n);
+
        /* end of memory marker */
        rsvd_region[n].start = ~0UL;
        rsvd_region[n].end   = ~0UL;
index aeec8184e862535e6676b2cafae699f502fa56f0..cdb64cc4d9c85d93ad21b26756047d358387700a 100644 (file)
@@ -227,7 +227,7 @@ ia64_rt_sigreturn (struct sigscratch *scr)
        si.si_signo = SIGSEGV;
        si.si_errno = 0;
        si.si_code = SI_KERNEL;
-       si.si_pid = current->pid;
+       si.si_pid = task_pid_vnr(current);
        si.si_uid = current->uid;
        si.si_addr = sc;
        force_sig_info(SIGSEGV, &si, current);
@@ -332,7 +332,7 @@ force_sigsegv_info (int sig, void __user *addr)
        si.si_signo = SIGSEGV;
        si.si_errno = 0;
        si.si_code = SI_KERNEL;
-       si.si_pid = current->pid;
+       si.si_pid = task_pid_vnr(current);
        si.si_uid = current->uid;
        si.si_addr = addr;
        force_sig_info(SIGSEGV, &si, current);
index 98cfc90cab1d4916e9664fa01cca00bb41801662..2bb84214e5f1384f2208b47f637a644aa94e747e 100644 (file)
@@ -371,6 +371,11 @@ ia64_setup_printk_clock(void)
                ia64_printk_clock = ia64_itc_printk_clock;
 }
 
+/* IA64 doesn't cache the timezone */
+void update_vsyscall_tz(void)
+{
+}
+
 void update_vsyscall(struct timespec *wall, struct clocksource *c)
 {
         unsigned long flags;
index 3aeaf15e468ba180381e79f7e19d94aad98e97e6..78d65cb947d29c4fb763c346efed30a307130bfc 100644 (file)
@@ -61,7 +61,7 @@ die (const char *str, struct pt_regs *regs, long err)
 
        if (++die.lock_owner_depth < 3) {
                printk("%s[%d]: %s %ld [%d]\n",
-                       current->comm, current->pid, str, err, ++die_counter);
+               current->comm, task_pid_nr(current), str, err, ++die_counter);
                (void) notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
                show_regs(regs);
        } else
@@ -315,7 +315,7 @@ handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr)
                                last.time = current_jiffies + 5 * HZ;
                                printk(KERN_WARNING
                                        "%s(%d): floating-point assist fault at ip %016lx, isr %016lx\n",
-                                       current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri, isr);
+                                       current->comm, task_pid_nr(current), regs->cr_iip + ia64_psr(regs)->ri, isr);
                        }
                }
        }
@@ -453,7 +453,7 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
                if (code == 8) {
 # ifdef CONFIG_IA64_PRINT_HAZARDS
                        printk("%s[%d]: possible hazard @ ip=%016lx (pr = %016lx)\n",
-                              current->comm, current->pid,
+                              current->comm, task_pid_nr(current),
                               regs.cr_iip + ia64_psr(&regs)->ri, regs.pr);
 # endif
                        return;
index fe6aa5a9f8fa94edc851c59b4d1cd9d28839cf32..2173de9fe9173773a960dbd9347367242968011f 100644 (file)
@@ -1340,7 +1340,8 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
                        size_t len;
 
                        len = sprintf(buf, "%s(%d): unaligned access to 0x%016lx, "
-                                     "ip=0x%016lx\n\r", current->comm, current->pid,
+                                     "ip=0x%016lx\n\r", current->comm,
+                                     task_pid_nr(current),
                                      ifa, regs->cr_iip + ipsr->ri);
                        /*
                         * Don't call tty_write_message() if we're in the kernel; we might
@@ -1363,7 +1364,7 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
                                       "administrator\n"
                                       "echo 0 > /proc/sys/kernel/ignore-"
                                       "unaligned-usertrap to re-enable\n",
-                                      current->comm, current->pid);
+                                      current->comm, task_pid_nr(current));
                        }
                }
        } else {
index 32f26253c4e8cea6b938e8babdffb96e826e6ac8..7571076a16a1991742af9f502b2113f7d9bd35a4 100644 (file)
@@ -274,7 +274,7 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
 
   out_of_memory:
        up_read(&mm->mmap_sem);
-       if (is_init(current)) {
+       if (is_global_init(current)) {
                yield();
                down_read(&mm->mmap_sem);
                goto survive;
index 3e10152abbf0f5873194e383cfcd8845f202b252..c6c19bf11becd573c38362462bf3c1ad0cce91bd 100644 (file)
@@ -127,8 +127,8 @@ ia64_init_addr_space (void)
                vma->vm_mm = current->mm;
                vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
                vma->vm_end = vma->vm_start + PAGE_SIZE;
-               vma->vm_page_prot = protection_map[VM_DATA_DEFAULT_FLAGS & 0x7];
                vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
+               vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
                down_write(&current->mm->mmap_sem);
                if (insert_vm_struct(current->mm, vma)) {
                        up_write(&current->mm->mmap_sem);
diff --git a/arch/ia64/oprofile/Kconfig b/arch/ia64/oprofile/Kconfig
deleted file mode 100644 (file)
index 97271ab..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-config PROFILING
-       bool "Profiling support (EXPERIMENTAL)"
-       help
-         Say Y here to enable the extended profiling support mechanisms used
-         by profilers such as OProfile.
-
-config OPROFILE
-       tristate "OProfile system profiling (EXPERIMENTAL)"
-       depends on PROFILING
-       help
-         OProfile is a profiling system capable of profiling the
-         whole system, include the kernel, kernel modules, libraries,
-         and applications.
-
-         Due to firmware bugs, you may need to use the "nohalt" boot
-         option if you're using OProfile with the hardware performance
-         counters.
-
-         If unsure, say N.
-
index e58fcadff2e976392c03e935e39ab0e5f97ca7cb..a5df672d83923a14479e1b94b9583354e2b14661 100644 (file)
@@ -269,8 +269,9 @@ xpnet_receive(partid_t partid, int channel, struct xpnet_message *msg)
        skb->protocol = eth_type_trans(skb, xpnet_device);
        skb->ip_summed = CHECKSUM_UNNECESSARY;
 
-       dev_dbg(xpnet, "passing skb to network layer; \n\tskb->head=0x%p "
-               "skb->data=0x%p skb->tail=0x%p skb->end=0x%p skb->len=%d\n",
+       dev_dbg(xpnet, "passing skb to network layer\n"
+               KERN_DEBUG "\tskb->head=0x%p skb->data=0x%p skb->tail=0x%p "
+               "skb->end=0x%p skb->len=%d\n",
                (void *)skb->head, (void *)skb->data, skb_tail_pointer(skb),
                skb_end_pointer(skb), skb->len);
 
@@ -576,10 +577,10 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
                msg->tailout_ignore = end_addr - (u64)skb_tail_pointer(skb);
                msg->buf_pa = __pa(start_addr);
 
-               dev_dbg(xpnet, "sending XPC message to %d:%d\nmsg->buf_pa="
-                       "0x%lx, msg->size=%u, msg->leadin_ignore=%u, "
-                       "msg->tailout_ignore=%u\n", dest_partid,
-                       XPC_NET_CHANNEL, msg->buf_pa, msg->size,
+               dev_dbg(xpnet, "sending XPC message to %d:%d\n"
+                       KERN_DEBUG "msg->buf_pa=0x%lx, msg->size=%u, "
+                       "msg->leadin_ignore=%u, msg->tailout_ignore=%u\n",
+                       dest_partid, XPC_NET_CHANNEL, msg->buf_pa, msg->size,
                        msg->leadin_ignore, msg->tailout_ignore);
 
 
index ecd8a52b9b9e23a2e9987d2703976983b30af4c0..511db2fd7bff9ad50dd92b7af192c486e73ad27b 100644 (file)
@@ -16,7 +16,7 @@
 #include <asm/sn/pcidev.h>
 #include <asm/sn/sn_sal.h>
 
-#define SG_ENT_VIRT_ADDRESS(sg)        (page_address((sg)->page) + (sg)->offset)
+#define SG_ENT_VIRT_ADDRESS(sg)        (sg_virt((sg)))
 #define SG_ENT_PHYS_ADDRESS(SG)        virt_to_phys(SG_ENT_VIRT_ADDRESS(SG))
 
 /**
index bd5fe76401f18dea117b6042362fc70a759a4a6f..ab9a264cb1947cb6a938c523e677f4c64873b72e 100644 (file)
@@ -426,7 +426,7 @@ source "drivers/Kconfig"
 
 source "fs/Kconfig"
 
-source "arch/m32r/oprofile/Kconfig"
+source "kernel/Kconfig.instrumentation"
 
 source "arch/m32r/Kconfig.debug"
 
index f8d8650383e0e6ecb09dd6d36a9ff42df69e3731..d0c5b0b7da2f0f571fa8e37c44b5f1a41ac5f363 100644 (file)
@@ -71,7 +71,7 @@ skip:
 }
 
 /*
- * do_IRQ handles all normal device IRQ's (the special
+ * do_IRQ handles all normal device IRQs (the special
  * SMP cross-CPU interrupts have their own specific
  * handlers).
  */
index 916faf6070af7d1a29b1c91f7a875166ccef88d1..a753d79c4e894f1fe2cd04429e28c6e4c103165f 100644 (file)
@@ -358,7 +358,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
 
        signr = get_signal_to_deliver(&info, &ka, regs, NULL);
        if (signr > 0) {
-               /* Reenable any watchpoints before delivering the
+               /* Re-enable any watchpoints before delivering the
                 * signal to user space. The processor register will
                 * have been cleared if the watchpoint triggered
                 * inside the kernel.
index 360129174b2bd17aaeed1fcc37c91e80a8100d05..c837bc13b015d01a72b9ec671c07b1144045d5b2 100644 (file)
@@ -202,7 +202,7 @@ void smp_flush_cache_all_interrupt(void)
 }
 
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
-/* TLB flush request Routin                                                */
+/* TLB flush request Routines                                                */
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
 
 /*==========================================================================*
@@ -378,7 +378,7 @@ void smp_flush_tlb_page(struct vm_area_struct *vma, unsigned long va)
  * Name:         flush_tlb_others
  *
  * Description:  This routine requests other CPU to execute flush TLB.
- *               1.Setup parmeters.
+ *               1.Setup parameters.
  *               2.Send 'INVALIDATE_TLB_IPI' to other CPU.
  *                 Request other CPU to execute 'smp_invalidate_interrupt()'.
  *               3.Wait for other CPUs operation finished.
@@ -502,7 +502,7 @@ void smp_invalidate_interrupt(void)
 }
 
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
-/* Stop CPU request Routins                                                 */
+/* Stop CPU request Routines                                                 */
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
 
 /*==========================================================================*
@@ -566,7 +566,7 @@ static void stop_this_cpu(void *dummy)
 }
 
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
-/* Call function Routin                                                    */
+/* Call function Routines                                                    */
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
 
 /*==========================================================================*
@@ -690,7 +690,7 @@ void smp_call_function_interrupt(void)
 }
 
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
-/* Timer Routin                                                            */
+/* Timer Routines                                                            */
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
 
 /*==========================================================================*
@@ -802,7 +802,7 @@ void smp_local_timer_interrupt(void)
 }
 
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
-/* Send IPI Routin                                                         */
+/* Send IPI Routines                                                         */
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
 
 /*==========================================================================*
@@ -814,7 +814,7 @@ void smp_local_timer_interrupt(void)
  *
  * Arguments:    ipi_num - Number of IPI
  *               try -  0 : Send IPI certainly.
- *                     !0 : The following IPI is not sended when Target CPU
+ *                     !0 : The following IPI is not sent when Target CPU
  *                          has not received the before IPI.
  *
  * Returns:      void (cannot fail)
@@ -844,7 +844,7 @@ void send_IPI_allbutself(int ipi_num, int try)
  * Arguments:    cpu_mask - Bitmap of target CPUs logical ID
  *               ipi_num - Number of IPI
  *               try -  0 : Send IPI certainly.
- *                     !0 : The following IPI is not sended when Target CPU
+ *                     !0 : The following IPI is not sent when Target CPU
  *                          has not received the before IPI.
  *
  * Returns:      void (cannot fail)
@@ -885,7 +885,7 @@ static void send_IPI_mask(cpumask_t cpumask, int ipi_num, int try)
  * Arguments:    cpu_mask - Bitmap of target CPUs physical ID
  *               ipi_num - Number of IPI
  *               try -  0 : Send IPI certainly.
- *                     !0 : The following IPI is not sended when Target CPU
+ *                     !0 : The following IPI is not sent when Target CPU
  *                          has not received the before IPI.
  *
  * Returns:      IPICRi regster value.
index 9dae410014d821c7d773ea65ba2441387538b1a3..0e383da158e95c3a84dfc7ffecb14f94b6325395 100644 (file)
@@ -133,7 +133,7 @@ static void map_cpu_to_physid(int, int);
 static void unmap_cpu_to_physid(int, int);
 
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
-/* Boot up APs Routins : BSP                                                 */
+/* Boot up APs Routines : BSP                                                */
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
 void __devinit smp_prepare_boot_cpu(void)
 {
@@ -404,7 +404,7 @@ void __init smp_cpus_done(unsigned int max_cpus)
 }
 
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
-/* Activate a secondary processor Routin                                   */
+/* Activate a secondary processor Routines                                   */
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
 
 /*==========================================================================*
@@ -509,7 +509,7 @@ static void __init smp_online(void)
 }
 
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
-/* Boot up CPUs common Routin                                              */
+/* Boot up CPUs common Routines                                              */
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
 static void __init show_mp_info(int nr_cpu)
 {
index 0fc2efec18f635f91f8191cebf001bd22dce7642..6d7a80fdad488676b8e69c43b0db180e68baf823 100644 (file)
@@ -214,7 +214,7 @@ asmlinkage int sys_uname(struct old_utsname __user * name)
 
 asmlinkage int sys_cacheflush(void *addr, int bytes, int cache)
 {
-       /* This should flush more selectivly ...  */
+       /* This should flush more selectively ...  */
        _flush_cache_all();
        return 0;
 }
index 97e0b1c0830e81cf218d4e61c4dbbc0a1de8e0ff..89ba4a0b5d5109d0be4569947e13591d115a2f91 100644 (file)
@@ -196,7 +196,7 @@ static void show_registers(struct pt_regs *regs)
                printk("SPI: %08lx\n", sp);
        }
        printk("Process %s (pid: %d, process nr: %d, stackpage=%08lx)",
-               current->comm, current->pid, 0xffff & i, 4096+(unsigned long)current);
+               current->comm, task_pid_nr(current), 0xffff & i, 4096+(unsigned long)current);
 
        /*
         * When in-kernel, we also print out the stack and code at the
index 70a766aad3e0bdbcdc22b6dfd11033d3183846aa..4a71df4c1b3022b1c8f324b50d78dd2b79f8e51a 100644 (file)
@@ -271,7 +271,7 @@ no_context:
  */
 out_of_memory:
        up_read(&mm->mmap_sem);
-       if (is_init(tsk)) {
+       if (is_global_init(tsk)) {
                yield();
                down_read(&mm->mmap_sem);
                goto survive;
diff --git a/arch/m32r/oprofile/Kconfig b/arch/m32r/oprofile/Kconfig
deleted file mode 100644 (file)
index 19d3773..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-
-menu "Profiling support"
-       depends on EXPERIMENTAL
-
-config PROFILING
-       bool "Profiling support (EXPERIMENTAL)"
-       help
-         Say Y here to enable the extended profiling support mechanisms used
-         by profilers such as OProfile.
-
-
-config OPROFILE
-       tristate "OProfile system profiling (EXPERIMENTAL)"
-       depends on PROFILING
-       help
-         OProfile is a profiling system capable of profiling the
-         whole system, include the kernel, kernel modules, libraries,
-         and applications.
-
-         If unsure, say N.
-
-endmenu
-
index 20a9c08e59c34ee34b21adb100b33014c99a39ff..01dee84f840ac72608dae4fe0ea4997b3e911f81 100644 (file)
@@ -683,6 +683,8 @@ endmenu
 
 source "fs/Kconfig"
 
+source "kernel/Kconfig.instrumentation"
+
 source "arch/m68k/Kconfig.debug"
 
 source "security/Kconfig"
index fc57c6e72acf10d2bd30997f25cc222488f07813..186662ca1a89dd0603d8df5e9865b9d62dddbb32 100644 (file)
@@ -33,7 +33,7 @@ void pcmcia_reset(void)
 
 
 /* copy a tuple, including tuple header. return nb bytes copied */
-/* be carefull as this may trigger a GAYLE_IRQ_WR interrupt ! */
+/* be careful as this may trigger a GAYLE_IRQ_WR interrupt ! */
 
 int pcmcia_copy_tuple(unsigned char tuple_id, void *tuple, int max_len)
 {
index c1e712dfc2e7abff08c0e8f8f19cf9845c9ba343..ba96596910fd99b0ede9e263b9d352ec68c07cd9 100644 (file)
@@ -4,7 +4,7 @@ M68000 Hi-Performance Microprocessor Division
 M68060 Software Package
 Production Release P1.00 -- October 10, 1994
 
-M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+M68060 Software Package Copyright Â© 1993, 1994 Motorola Inc.  All rights reserved.
 
 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 To the maximum extent permitted by applicable law,
index b7e644b94ae2338eb416fbdfce5873c1724d6512..1a63913daa16b5908863ce2d4f72beb44f130a65 100644 (file)
@@ -4,7 +4,7 @@ M68000 Hi-Performance Microprocessor Division
 M68060 Software Package
 Production Release P1.00 -- October 10, 1994
 
-M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+M68060 Software Package Copyright Â© 1993, 1994 Motorola Inc.  All rights reserved.
 
 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 To the maximum extent permitted by applicable law,
index e3bced429bd3a8f46c480f7772d93bbe604be324..f6f8f5c59419458a643aad58f3d2fe9b2e6ae0e8 100644 (file)
@@ -4,7 +4,7 @@ M68000 Hi-Performance Microprocessor Division
 M68060 Software Package
 Production Release P1.00 -- October 10, 1994
 
-M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+M68060 Software Package Copyright Â© 1993, 1994 Motorola Inc.  All rights reserved.
 
 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 To the maximum extent permitted by applicable law,
index 5e5900cb2dc4897fde603f8c98cf9a8955fc12c8..1ba3aef1500f72ff7148858e77353d3e54301c64 100644 (file)
@@ -4,7 +4,7 @@ M68000 Hi-Performance Microprocessor Division
 M68060 Software Package
 Production Release P1.00 -- October 10, 1994
 
-M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+M68060 Software Package Copyright Â© 1993, 1994 Motorola Inc.  All rights reserved.
 
 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 To the maximum extent permitted by applicable law,
index fb637c4367626592fd6287809c6349c8839f60ab..89730a934c5ef488d40f546f7ae62a32371661d8 100644 (file)
@@ -4,7 +4,7 @@ M68000 Hi-Performance Microprocessor Division
 M68060 Software Package
 Production Release P1.00 -- October 10, 1994
 
-M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+M68060 Software Package Copyright Â© 1993, 1994 Motorola Inc.  All rights reserved.
 
 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 To the maximum extent permitted by applicable law,
index 408315209e62c12b9166761096fda8924267f82e..23d513f72ed9a16648253c21e75ee00f5d6712ea 100644 (file)
@@ -4,7 +4,7 @@ M68000 Hi-Performance Microprocessor Division
 M68060 Software Package
 Production Release P1.00 -- October 10, 1994
 
-M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+M68060 Software Package Copyright Â© 1993, 1994 Motorola Inc.  All rights reserved.
 
 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 To the maximum extent permitted by applicable law,
index a45a4ff9d2af09b2c7e25de23f1406a06205728b..0a1ae4f44130f4a1a8ed502314431f68d51eb360 100644 (file)
@@ -4,7 +4,7 @@
 |M68060 Software Package
 |Production Release P1.00 -- October 10, 1994
 |
-|M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+|M68060 Software Package Copyright Â© 1993, 1994 Motorola Inc.  All rights reserved.
 |
 |THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 |To the maximum extent permitted by applicable law,
index f6fae6d900ae17f4987edc23dbfcfa2d0c5ccd92..4e6292f095aaa05689547d624ed77278608ea2d0 100644 (file)
@@ -4,7 +4,7 @@ M68000 Hi-Performance Microprocessor Division
 M68060 Software Package
 Production Release P1.00 -- October 10, 1994
 
-M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+M68060 Software Package Copyright Â© 1993, 1994 Motorola Inc.  All rights reserved.
 
 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 To the maximum extent permitted by applicable law,
index b2dbdf5ee3090ba7359eda1fcdca7971aa76ecae..91a9c65fee8a9568b1bd1be5256b767d31476d9f 100644 (file)
@@ -4,7 +4,7 @@
 |M68060 Software Package
 |Production Release P1.00 -- October 10, 1994
 |
-|M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+|M68060 Software Package Copyright Â© 1993, 1994 Motorola Inc.  All rights reserved.
 |
 |THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 |To the maximum extent permitted by applicable law,
index 5a90fded3f0b0e5e06334a996bb2030fd7a1d4cf..9dadd727fc50717c1c9850b33a1635e5527444fd 100644 (file)
@@ -4,7 +4,7 @@ M68000 Hi-Performance Microprocessor Division
 M68060 Software Package
 Production Release P1.00 -- October 10, 1994
 
-M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+M68060 Software Package Copyright Â© 1993, 1994 Motorola Inc.  All rights reserved.
 
 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 To the maximum extent permitted by applicable law,
index aa4df87a6c4271d6beb6fd0f04d0628f2b7646d8..7a0d6e42806656a59f7b5da80f019aed1d1626c6 100644 (file)
@@ -4,7 +4,7 @@
 |M68060 Software Package
 |Production Release P1.00 -- October 10, 1994
 |
-|M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+|M68060 Software Package Copyright Â© 1993, 1994 Motorola Inc.  All rights reserved.
 |
 |THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 |To the maximum extent permitted by applicable law,
index fdb79b927ef1671e63f1a1bf9b73487b524adc8e..3b7ea2dc9f1bbf098fe6cf03fdffeb1bb934e5ab 100644 (file)
@@ -4,7 +4,7 @@ M68000 Hi-Performance Microprocessor Division
 M68060 Software Package
 Production Release P1.00 -- October 10, 1994
 
-M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+M68060 Software Package Copyright Â© 1993, 1994 Motorola Inc.  All rights reserved.
 
 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 To the maximum extent permitted by applicable law,
index 3b597a9bbf438272f0c9f15bfc49ac3c89891efe..6c1a9a217887d01208562323ab4ec999dc5253ee 100644 (file)
@@ -4,7 +4,7 @@ M68000 Hi-Performance Microprocessor Division
 M68060 Software Package
 Production Release P1.00 -- October 10, 1994
 
-M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+M68060 Software Package Copyright Â© 1993, 1994 Motorola Inc.  All rights reserved.
 
 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 To the maximum extent permitted by applicable law,
index 2edcbae0fd53a18c893dc20a8ffa78771286bab9..1f947915d81e1d945a6aa36014e45c7b9e707376 100644 (file)
@@ -4,7 +4,7 @@ M68000 Hi-Performance Microprocessor Division
 M68060 Software Package
 Production Release P1.00 -- October 10, 1994
 
-M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+M68060 Software Package Copyright Â© 1993, 1994 Motorola Inc.  All rights reserved.
 
 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 To the maximum extent permitted by applicable law,
index afa7422cddb5b3de87ef6940b76d4634e5385769..970abaf3303e037184fb8bde424ee67624c0f125 100644 (file)
@@ -4,7 +4,7 @@ M68000 Hi-Performance Microprocessor Division
 M68060 Software Package
 Production Release P1.00 -- October 10, 1994
 
-M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+M68060 Software Package Copyright Â© 1993, 1994 Motorola Inc.  All rights reserved.
 
 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 To the maximum extent permitted by applicable law,
index b269091d9df65ddb9c99c8532a0ec60c6a21e4e8..6dccda766e22be661235d9af581cdae7f86b6772 100644 (file)
@@ -4,7 +4,7 @@ M68000 Hi-Performance Microprocessor Division
 M68060 Software Package
 Production Release P1.00 -- October 10, 1994
 
-M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+M68060 Software Package Copyright Â© 1993, 1994 Motorola Inc.  All rights reserved.
 
 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 To the maximum extent permitted by applicable law,
index ba4a30cbcbeaee303fa2c99f4f7b40fb0567ea90..beca47e7d514891ed31bee07c649d4a6e79d8eec 100644 (file)
@@ -4,7 +4,7 @@ M68000 Hi-Performance Microprocessor Division
 M68060 Software Package
 Production Release P1.00 -- October 10, 1994
 
-M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+M68060 Software Package Copyright Â© 1993, 1994 Motorola Inc.  All rights reserved.
 
 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 To the maximum extent permitted by applicable law,
index 0c997c436bebe0040352b6a1b7980438a37a1880..51b9f7d879dd714d677b9c04fd0ac0a3795316a7 100644 (file)
@@ -4,7 +4,7 @@ M68000 Hi-Performance Microprocessor Division
 M68060 Software Package
 Production Release P1.00 -- October 10, 1994
 
-M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+M68060 Software Package Copyright Â© 1993, 1994 Motorola Inc.  All rights reserved.
 
 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 To the maximum extent permitted by applicable law,
index 9d4e4b5b6bd889325d274334fd6b608989440831..ef490e1ce6002bae783774c77dc13b207191962f 100644 (file)
@@ -121,7 +121,7 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
        int i;
 
        for (i = 0; i < nents; sg++, i++) {
-               sg->dma_address = page_to_phys(sg->page) + sg->offset;
+               sg->dma_address = sg_phys(sg);
                dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir);
        }
        return nents;
index 4e2752a0e89b32b2dccd4e2576844378887bab16..97f556fa493290822dea1673986d1b269c23bcfe 100644 (file)
@@ -900,7 +900,7 @@ void show_registers(struct pt_regs *regs)
               regs->d4, regs->d5, regs->a0, regs->a1);
 
        printk("Process %s (pid: %d, task=%p)\n",
-               current->comm, current->pid, current);
+               current->comm, task_pid_nr(current), current);
        addr = (unsigned long)&fp->un;
        printk("Frame format=%X ", regs->format);
        switch (regs->format) {
@@ -1038,7 +1038,7 @@ void bad_super_trap (struct frame *fp)
                                fp->un.fmtb.daddr, space_names[ssw & DFC],
                                fp->ptregs.pc);
        }
-       printk ("Current process id is %d\n", current->pid);
+       printk ("Current process id is %d\n", task_pid_nr(current));
        die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0);
 }
 
index 8547dbc5e8d73335a9b78a2bb37a1e416ac37b8f..01b468b9392ec68cb1aade95d598adb06a51cdc5 100644 (file)
@@ -284,7 +284,7 @@ static struct mac_model mac_data_table[] = {
        },
 
        /*
-        *      Weirdified MacII hardware - all subtley different. Gee thanks
+        *      Weirdified MacII hardware - all subtly different. Gee thanks
         *      Apple. All these boxes seem to have VIA2 in a different place to
         *      the MacII (+1A000 rather than +4000)
         * CSA: see http://developer.apple.com/technotes/hw/hw_09.html
@@ -707,7 +707,7 @@ static struct mac_model mac_data_table[] = {
         * All of these probably have onboard SONIC in the Dock which
         * means we'll have to probe for it eventually.
         *
-        * Are these reallly MAC_VIA_IIci? The developer notes for the
+        * Are these really MAC_VIA_IIci? The developer notes for the
         * Duos show pretty much the same custom parts as in most of
         * the other PowerBooks which would imply MAC_VIA_QUADRA.
         */
index 0cea21f581926b07241e35ce621d1a6fc2b685fa..5b2799eb96a68f930d6d93e30873f6c796487c25 100644 (file)
  * finished; this function moves the message state to MSG_COMPLETE and signals
  * the IOP. This two-step process is provided to allow the handler to defer
  * message processing to a bottom-half handler if the processing will take
- * a signifigant amount of time (handlers are called at interrupt time so they
+ * a significant amount of time (handlers are called at interrupt time so they
  * should execute quickly.)
  */
 
 
 /*#define DEBUG_IOP*/
 
-/* Set to nonezero if the IOPs are present. Set by iop_init() */
+/* Set to non-zero if the IOPs are present. Set by iop_init() */
 
 int iop_scc_present,iop_ism_present;
 
index d7be16917efdf307292d90c68ec3ebc6900adc48..50603d3dce843798b488f249b95bc53d984cdb76 100644 (file)
@@ -8,7 +8,7 @@
  *
  * 990502 (jmt) - Major rewrite for new interrupt architecture as well as some
  *               recent insights into OSS operational details.
- * 990610 (jmt) - Now taking fulll advantage of the OSS. Interrupts are mapped
+ * 990610 (jmt) - Now taking full advantage of the OSS. Interrupts are mapped
  *               to mostly match the A/UX interrupt scheme supported on the
  *               VIA side. Also added support for enabling the ISM irq again
  *               since we now have a functional IOP manager.
index d5cac72eb3db1d25b41ef780372a69a36742c925..8df270e950fabead2b0f0a2f2cf247d6fb02c41b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     6522 Versatile Interface Adapter (VIA)
  *
- *     There are two of these on the Mac II. Some IRQ's are vectored
+ *     There are two of these on the Mac II. Some IRQs are vectored
  *     via them as are assorted bits and bobs - eg RTC, ADB.
  *
  * CSA: Motorola seems to have removed documentation on the 6522 from
index 87b4f0158560492d4ddfb243debbd8a6e4902a38..b1033ae0d6f084a357ddf318a8e67b10d789098a 100644 (file)
@@ -65,7 +65,7 @@ fp_fsqrt(struct fp_ext *dest, struct fp_ext *src)
        fp_copy_ext(&src2, dest);
 
        /*
-        * The taylor row arround a for sqrt(x) is:
+        * The taylor row around a for sqrt(x) is:
         *      sqrt(x) = sqrt(a) + 1/(2*sqrt(a))*(x-a) + R
         * With a=1 this gives:
         *      sqrt(x) = 1 + 1/2*(x-1)
index eaa618681159524ec1cf287b2ff1c91bf72d2da7..f493f03231d5ad3594d0813bd11a8855e9efcfbb 100644 (file)
@@ -180,7 +180,7 @@ good_area:
  */
 out_of_memory:
        up_read(&mm->mmap_sem);
-       if (is_init(current)) {
+       if (is_global_init(current)) {
                yield();
                down_read(&mm->mmap_sem);
                goto survive;
index ad3ed1fb88793e066aca96628a8ecb505f038d05..46161cef08b95520733b048b6cd40e53b7ad2716 100644 (file)
@@ -184,7 +184,7 @@ static struct IRQ_TABLE eirqs[] = {
 };
 
 /* complain only this many times about spurious ints : */
-static int ccleirq=60;    /* ISA dev IRQ's*/
+static int ccleirq=60;    /* ISA dev IRQs*/
 /*static int cclirq=60;*/     /* internal */
 
 /* FIXME: add shared ints,mask,unmask,probing.... */
@@ -234,7 +234,7 @@ static void q40_irq_handler(unsigned int irq, struct pt_regs *fp)
  * There is a little mess wrt which IRQ really caused this irq request. The
  * main problem is that IIRQ_REG and EIRQ_REG reflect the state when they
  * are read - which is long after the request came in. In theory IRQs should
- * not just go away but they occassionally do
+ * not just go away but they occasionally do
  */
                                if (irq > 4 && irq <= 15 && mext_disabled) {
                                        /*aliased_irq++;*/
index 7a0e3a22068708a47b1872c4dcc35507a3f515c5..fb0f6a20cc3c80dab2ca2f3f073bef4d006d63ae 100644 (file)
@@ -239,7 +239,7 @@ void clear_context(unsigned long context)
 /* gets an empty context.  if full, kills the next context listed to
    die first */
 /* This context invalidation scheme is, well, totally arbitrary, I'm
-   sure it could be much more intellegent...  but it gets the job done
+   sure it could be much more intelligent...  but it gets the job done
    for now without much overhead in making it's decision. */
 /* todo: come up with optimized scheme for flushing contexts */
 unsigned long get_free_context(struct mm_struct *mm)
index e892748e73865e633a3e2a6d4f3349647eb17424..7340f5b6cf6d55dbafe7b86fbf18ff58f4f6ada3 100644 (file)
@@ -3,7 +3,7 @@
  *                                        in Chip RAM with the kernel command
  *                                        line option `debug=mem'.
  *
- *  © Copyright 1996 by Geert Uytterhoeven <geert@linux-m68k.org>
+ *  Â© Copyright 1996 by Geert Uytterhoeven <geert@linux-m68k.org>
  *
  *
  *  Usage:
index 185906b54cb03ff00bd94721a652c19c76a4dc1f..f4b582cbb5678a541e9a972ef8f31d27399d69a9 100644 (file)
@@ -451,6 +451,12 @@ config MOD5272
        help
          Support for the Netburner MOD-5272 board.
 
+config SAVANTrosie1
+       bool "Savant Rosie1 board support"
+       depends on M523x
+       help
+         Support for the Savant Rosie1 board.
+
 config ROMFS_FROM_ROM
        bool "ROMFS image not RAM resident"
        depends on (NETtel || SNAPGEAR)
@@ -492,7 +498,12 @@ config SNEHA
         bool
        default y
        depends on CPU16B
-       
+
+config SAVANT
+       bool
+       default y
+       depends on SAVANTrosie1
+
 config AVNET
        bool
        default y
@@ -696,6 +707,8 @@ source "drivers/Kconfig"
 
 source "fs/Kconfig"
 
+source "kernel/Kconfig.instrumentation"
+
 source "arch/m68knommu/Kconfig.debug"
 
 source "security/Kconfig"
index 92227aaaa26e7e9f1bcb76cb02b1f74b2d2d2131..30aa2553693d116702684f904a262016b1472ca4 100644 (file)
@@ -48,6 +48,7 @@ board-$(CONFIG_SNEHA)                 := SNEHA
 board-$(CONFIG_M5208EVB)       := M5208EVB
 board-$(CONFIG_MOD5272)                := MOD5272
 board-$(CONFIG_AVNET)           := AVNET
+board-$(CONFIG_SAVANT)         := SAVANT
 BOARD := $(board-y)
 
 model-$(CONFIG_RAMKERNEL)      := ram
@@ -117,4 +118,4 @@ core-y      += arch/m68knommu/kernel/ \
 libs-y += arch/m68knommu/lib/
 
 archclean:
-       $(Q)$(MAKE) $(clean)=arch/m68knommu/boot
+
index 3891de09ac2372e1fcd51a11e8ea44a12cfe3262..5a0ecaaee3b08132b89c5e9a67b43510e959dae9 100644 (file)
@@ -1,41 +1,48 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.17
-# Tue Jun 27 12:57:06 2006
+# Linux kernel version: 2.6.23
+# Thu Oct 18 13:17:38 2007
 #
 CONFIG_M68K=y
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
+CONFIG_ZONE_DMA=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_TIME_LOW_RES=y
+CONFIG_NO_IOPORT=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_SYSVIPC is not set
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL 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_RELAY is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_UID16=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
+CONFIG_SYSCTL_SYSCALL=y
 # CONFIG_KALLSYMS is not set
 # CONFIG_HOTPLUG is not set
 CONFIG_PRINTK=y
@@ -44,20 +51,25 @@ CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
 CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
 CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-
-#
-# Block layer
-#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_KMOD 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
 
 #
 # IO Schedulers
@@ -99,6 +111,7 @@ CONFIG_CLOCK_DIV=1
 #
 # Platform
 #
+# CONFIG_UC5272 is not set
 CONFIG_M5272C3=y
 # CONFIG_COBRA5272 is not set
 # CONFIG_CANCam is not set
@@ -107,7 +120,6 @@ CONFIG_M5272C3=y
 # CONFIG_CPU16B is not set
 # CONFIG_MOD5272 is not set
 CONFIG_FREESCALE=y
-# CONFIG_LARGE_ALLOCS is not set
 CONFIG_4KSTACKS=y
 
 #
@@ -121,6 +133,11 @@ CONFIG_RAMAUTOBIT=y
 # CONFIG_RAM8BIT is not set
 # CONFIG_RAM16BIT is not set
 # CONFIG_RAM32BIT is not set
+
+#
+# ROM configuration
+#
+# CONFIG_ROM is not set
 CONFIG_RAMKERNEL=y
 # CONFIG_ROMKERNEL is not set
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -131,20 +148,19 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_VIRT_TO_BUS=y
 
 #
 # Bus options (PCI, PCMCIA, EISA, MCA, ISA)
 #
 # CONFIG_PCI is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
-# CONFIG_PCCARD is not set
-
-#
-# PCI Hotplug Support
-#
 
 #
 # Executable file formats
@@ -168,7 +184,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -187,27 +202,21 @@ CONFIG_IP_FIB_HASH=y
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_DIAG is not set
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -218,7 +227,6 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -234,7 +242,17 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_HAMRADIO 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
@@ -245,16 +263,8 @@ CONFIG_TCP_CONG_BIC=y
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
+# 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
@@ -266,11 +276,13 @@ CONFIG_MTD_PARTITIONS=y
 # User Modules And Translation Layers
 #
 CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
 CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -290,7 +302,6 @@ CONFIG_MTD_CFI_I2=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
@@ -313,42 +324,25 @@ CONFIG_MTD_UCLINUX=y
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
 # CONFIG_MTD_NAND is not set
-
-#
-# 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_INITRD is not set
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+# CONFIG_MISC_DEVICES is not set
 # CONFIG_IDE is not set
 
 #
@@ -356,67 +350,29 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK 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_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-
-#
-# PHY device support
-#
 # CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
 CONFIG_FEC=y
 # CONFIG_FEC2 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
 
 #
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
+# Wireless LAN
 #
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
 # CONFIG_WAN is not set
 CONFIG_PPP=y
 # CONFIG_PPP_MULTILINK is not set
@@ -427,20 +383,14 @@ CONFIG_PPP=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
 
 #
@@ -472,34 +422,13 @@ CONFIG_SERIAL_COLDFIRE=y
 # CONFIG_UNIX98_PTYS is not set
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
 # CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
 # 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
 
 #
@@ -507,101 +436,74 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # 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 is not set
-# CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
+# Multifunction device drivers
 #
+# CONFIG_MFD_SM501 is not set
 
 #
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
+# CONFIG_DVB_CORE is not set
+CONFIG_DAB=y
 
 #
-# Digital Video Broadcasting Devices
+# Graphics support
 #
-# CONFIG_DVB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
-# Graphics support
+# Display device support
 #
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=y
 # CONFIG_FB is not set
 
 #
 # Sound
 #
 # CONFIG_SOUND is not set
-
-#
-# USB support
-#
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-# CONFIG_USB_ARCH_HAS_EHCI is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
-#
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
+# CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
-
-#
-# LED devices
-#
 # CONFIG_NEW_LEDS is not set
+# CONFIG_RTC_CLASS is not set
 
 #
-# LED drivers
+# DMA Engine support
 #
+# CONFIG_DMA_ENGINE is not set
 
 #
-# LED Triggers
+# DMA Clients
 #
 
 #
-# InfiniBand support
+# DMA Devices
 #
 
 #
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+# Userspace I/O
 #
-
-#
-# Real Time Clock
-#
-# CONFIG_RTC_CLASS 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_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 CONFIG_ROMFS_FS=y
@@ -629,6 +531,7 @@ CONFIG_ROMFS_FS=y
 # Pseudo filesystems
 #
 CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
@@ -645,7 +548,6 @@ CONFIG_RAMFS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
@@ -664,7 +566,6 @@ 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
@@ -677,16 +578,22 @@ CONFIG_MSDOS_PARTITION=y
 #
 # CONFIG_NLS is not set
 
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
 #
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_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_UNWIND_INFO is not set
 # CONFIG_FULLDEBUG is not set
 # CONFIG_HIGHPROFILE is not set
 # CONFIG_BOOTPARAM is not set
@@ -699,20 +606,16 @@ CONFIG_LOG_BUF_SHIFT=14
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
 # CONFIG_CRYPTO is not set
 
-#
-# Hardware crypto devices
-#
-
 #
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
 # CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_DMA=y
index 3f86ade3a22af15a152d444579858197ddeaaab3..74bf94948ec2bf413be0ba51ad2f4900b48b152e 100644 (file)
@@ -151,27 +151,15 @@ void setup_arch(char **cmdline_p)
 #ifdef CONFIG_ELITE
        printk(KERN_INFO "Modified for M5206eLITE by Rob Scott, rscott@mtrob.fdns.net\n");
 #endif
-#ifdef CONFIG_TELOS
-       printk(KERN_INFO "Modified for Omnia ToolVox by James D. Schettine, james@telos-systems.com\n");
-#endif
 #endif
        printk(KERN_INFO "Flat model support (C) 1998,1999 Kenneth Albanowski, D. Jeff Dionne\n");
 
 #if defined( CONFIG_PILOT ) && defined( CONFIG_M68328 )
        printk(KERN_INFO "TRG SuperPilot FLASH card support <info@trgnet.com>\n");
 #endif
-
 #if defined( CONFIG_PILOT ) && defined( CONFIG_M68EZ328 )
        printk(KERN_INFO "PalmV support by Lineo Inc. <jeff@uclinux.com>\n");
 #endif
-
-#ifdef CONFIG_M68EZ328ADS
-       printk(KERN_INFO "M68EZ328ADS board support (C) 1999 Vladimir Gurevich <vgurevic@cisco.com>\n");
-#endif
-
-#ifdef CONFIG_ALMA_ANS
-       printk(KERN_INFO "Alma Electronics board support (C) 1999 Vladimir Gurevich <vgurevic@cisco.com>\n");
-#endif
 #if defined (CONFIG_M68360)
        printk(KERN_INFO "QUICC port done by SED Systems <hamilton@sedsystems.ca>,\n");
        printk(KERN_INFO "based on 2.0.38 port by Lineo Inc. <mleslie@lineo.com>.\n");
@@ -188,11 +176,9 @@ void setup_arch(char **cmdline_p)
                "BSS=0x%06x-0x%06x\n", (int) &_stext, (int) &_etext,
                (int) &_sdata, (int) &_edata,
                (int) &_sbss, (int) &_ebss);
-       printk(KERN_DEBUG "KERNEL -> ROMFS=0x%06x-0x%06x MEM=0x%06x-0x%06x "
-               "STACK=0x%06x-0x%06x\n",
+       printk(KERN_DEBUG "MEMORY -> ROMFS=0x%06x-0x%06x MEM=0x%06x-0x%06x\n ",
                (int) &_ebss, (int) memory_start,
-               (int) memory_start, (int) memory_end,
-               (int) memory_end, (int) _ramend);
+               (int) memory_start, (int) memory_end);
 #endif
 
        /* Keep a copy of command line */
@@ -287,12 +273,3 @@ struct seq_operations cpuinfo_op = {
        .show   = show_cpuinfo,
 };
 
-void arch_gettod(int *year, int *mon, int *day, int *hour,
-                int *min, int *sec)
-{
-       if (mach_gettod)
-               mach_gettod(year, mon, day, hour, min, sec);
-       else
-               *year = *mon = *day = *hour = *min = *sec = 0;
-}
-
index 437f8c6c14a0d872a45084b10caef28a541703c1..70371378db868de2ce8cabf544993e44d4ef8aa2 100644 (file)
@@ -781,15 +781,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
        /* Did we come from a system call? */
        if (regs->orig_d0 >= 0) {
                /* Restart the system call - no handlers present */
-               if (regs->d0 == -ERESTARTNOHAND
-                   || regs->d0 == -ERESTARTSYS
-                   || regs->d0 == -ERESTARTNOINTR) {
-                       regs->d0 = regs->orig_d0;
-                       regs->pc -= 2;
-               } else if (regs->d0 == -ERESTART_RESTARTBLOCK) {
-                       regs->d0 = __NR_restart_syscall;
-                       regs->pc -= 2;
-               }
+               handle_restart(regs, NULL, 0);
        }
        return 0;
 }
index 467053da2d08343d29f77c7cc31529c7caef8e54..77e5375a2dd505ecc90e0dee224ed953e043ab56 100644 (file)
@@ -27,7 +27,6 @@
 
 #define        TICK_SIZE (tick_nsec / 1000)
 
-
 static inline int set_rtc_mmss(unsigned long nowtime)
 {
        if (mach_set_clock_mmss)
@@ -39,15 +38,11 @@ static inline int set_rtc_mmss(unsigned long nowtime)
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
  */
-static irqreturn_t timer_interrupt(int irq, void *dummy)
+irqreturn_t arch_timer_interrupt(int irq, void *dummy)
 {
        /* last time the cmos clock got updated */
        static long last_rtc_update=0;
 
-       /* may need to kick the hardware timer */
-       if (mach_tick)
-         mach_tick();
-
        write_seqlock(&xtime_lock);
 
        do_timer(1);
@@ -103,10 +98,10 @@ void time_init(void)
 {
        unsigned int year, mon, day, hour, min, sec;
 
-       extern void arch_gettod(int *year, int *mon, int *day, int *hour,
-                               int *min, int *sec);
-
-       arch_gettod(&year, &mon, &day, &hour, &min, &sec);
+       if (mach_gettod)
+               mach_gettod(&year, &mon, &day, &hour, &min, &sec);
+       else
+               year = mon = day = hour = min = sec = 0;
 
        if ((year += 1900) < 1970)
                year += 100;
@@ -114,7 +109,7 @@ void time_init(void)
        xtime.tv_nsec = 0;
        wall_to_monotonic.tv_sec = -xtime.tv_sec;
 
-       mach_sched_init(timer_interrupt);
+       hw_timer_init();
 }
 
 /*
@@ -128,7 +123,7 @@ void do_gettimeofday(struct timeval *tv)
 
        do {
                seq = read_seqbegin_irqsave(&xtime_lock, flags);
-               usec = mach_gettimeoffset ? mach_gettimeoffset() : 0;
+               usec = hw_timer_offset();
                sec = xtime.tv_sec;
                usec += (xtime.tv_nsec / 1000);
        } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
@@ -160,8 +155,7 @@ int do_settimeofday(struct timespec *tv)
         * Discover what correction gettimeofday
         * would have done, and then undo it!
         */
-       if (mach_gettimeoffset)
-               nsec -= (mach_gettimeoffset() * 1000);
+       nsec -= (hw_timer_offset() * 1000);
 
        wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
        wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
index d0f2dc5cb5a17f833f1008c781159f37c18adb0a..b3c4dd4cc13546146be2726de69a53f747ba83f2 100644 (file)
 /***************************************************************************/
 
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <asm/irq.h>
 #include <asm/dma.h>
-#include <asm/traps.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 #include <asm/mcftimer.h>
@@ -25,9 +22,6 @@
 
 /***************************************************************************/
 
-void coldfire_tick(void);
-void coldfire_timer_init(irq_handler_t handler);
-unsigned long coldfire_timer_offset(void);
 void coldfire_reset(void);
 
 /***************************************************************************/
@@ -97,9 +91,6 @@ int mcf_timerirqpending(int timer)
 void config_BSP(char *commandp, int size)
 {
        mcf_setimr(MCFSIM_IMR_MASKALL);
-       mach_sched_init = coldfire_timer_init;
-       mach_tick = coldfire_tick;
-       mach_gettimeoffset = coldfire_timer_offset;
        mach_reset = coldfire_reset;
 }
 
index 425703fb6cee70c84e5a82ddd52ab2917a2baaa0..f84a4aea8cb68669f62e1119ced59f7b6be27130 100644 (file)
@@ -9,23 +9,16 @@
 /***************************************************************************/
 
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/param.h>
 #include <linux/interrupt.h>
-#include <asm/irq.h>
 #include <asm/dma.h>
-#include <asm/traps.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
-#include <asm/mcftimer.h>
 #include <asm/mcfsim.h>
 #include <asm/mcfdma.h>
 
 /***************************************************************************/
 
-void coldfire_tick(void);
-void coldfire_timer_init(irq_handler_t handler);
-unsigned long coldfire_timer_offset(void);
 void coldfire_reset(void);
 
 /***************************************************************************/
@@ -102,9 +95,6 @@ void config_BSP(char *commandp, int size)
        commandp[size-1] = 0;
 #endif /* CONFIG_NETtel */
 
-       mach_sched_init = coldfire_timer_init;
-       mach_tick = coldfire_tick;
-       mach_gettimeoffset = coldfire_timer_offset;
        mach_reset = coldfire_reset;
 }
 
index a2c95bebd004cf24b25f18d8fed75524b3de9059..6edbd41261cc0253fd48f19646614f632543d335 100644 (file)
@@ -27,9 +27,6 @@ unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
 
 /***************************************************************************/
 
-void coldfire_pit_tick(void);
-void coldfire_pit_init(irq_handler_t handler);
-unsigned long coldfire_pit_offset(void);
 void coldfire_reset(void);
 
 /***************************************************************************/
@@ -47,10 +44,7 @@ void mcf_autovector(unsigned int vec)
 
 void config_BSP(char *commandp, int size)
 {
-    mach_sched_init = coldfire_pit_init;
-    mach_tick = coldfire_pit_tick;
-    mach_gettimeoffset = coldfire_pit_offset;
-    mach_reset = coldfire_reset;
+       mach_reset = coldfire_reset;
 }
 
 /***************************************************************************/
index 0a3af05a434b415759621b0fc81e7e657b056f46..e7f80c8e8636f2234c8322555c6a7ce01e1e68a8 100644 (file)
 /***************************************************************************/
 
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <asm/dma.h>
-#include <asm/traps.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
@@ -26,9 +24,6 @@
 
 /***************************************************************************/
 
-void coldfire_pit_tick(void);
-void coldfire_pit_init(irq_handler_t handler);
-unsigned long coldfire_pit_offset(void);
 void coldfire_reset(void);
 
 /***************************************************************************/
@@ -62,9 +57,6 @@ void mcf_autovector(unsigned int vec)
 void config_BSP(char *commandp, int size)
 {
        mcf_disableall();
-       mach_sched_init = coldfire_pit_init;
-       mach_tick = coldfire_pit_tick;
-       mach_gettimeoffset = coldfire_pit_offset;
        mach_reset = coldfire_reset;
 }
 
index dc2c362590c229a29a3003b709d2ef75ee53a2e5..d4d39435cb15ce54bc33950027fd0f1072405aac 100644 (file)
@@ -9,24 +9,17 @@
 /***************************************************************************/
 
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <asm/irq.h>
 #include <asm/dma.h>
-#include <asm/traps.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
-#include <asm/mcftimer.h>
 #include <asm/mcfsim.h>
 #include <asm/mcfdma.h>
 
 /***************************************************************************/
 
-void coldfire_tick(void);
-void coldfire_timer_init(irq_handler_t handler);
-unsigned long coldfire_timer_offset(void);
 void coldfire_reset(void);
 
 /***************************************************************************/
@@ -95,9 +88,6 @@ int mcf_timerirqpending(int timer)
 void config_BSP(char *commandp, int size)
 {
        mcf_setimr(MCFSIM_IMR_MASKALL);
-       mach_sched_init = coldfire_timer_init;
-       mach_tick = coldfire_tick;
-       mach_gettimeoffset = coldfire_timer_offset;
        mach_reset = coldfire_reset;
 }
 
index 1365a8300d5defbe39be9cc32c89b2ad0689022e..634a6375e4a5f3a4f4f4f6e7428e16fe29ccf14d 100644 (file)
 /***************************************************************************/
 
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <asm/irq.h>
 #include <asm/dma.h>
-#include <asm/traps.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
-#include <asm/mcftimer.h>
 #include <asm/mcfsim.h>
 #include <asm/mcfdma.h>
 
 /***************************************************************************/
 
-void coldfire_tick(void);
-void coldfire_timer_init(irq_handler_t handler);
-unsigned long coldfire_timer_offset(void);
 void coldfire_reset(void);
 
 extern unsigned int mcf_timervector;
@@ -128,9 +121,6 @@ void config_BSP(char *commandp, int size)
 
        mcf_timervector = 69;
        mcf_profilevector = 70;
-       mach_sched_init = coldfire_timer_init;
-       mach_tick = coldfire_tick;
-       mach_gettimeoffset = coldfire_timer_offset;
        mach_reset = coldfire_reset;
 }
 
index 1b820441419aacea972433f166dfeff8b6a9c5a1..9cbfbc68ae4f3a083417236191b67c9c983f59c8 100644 (file)
 /***************************************************************************/
 
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <asm/dma.h>
-#include <asm/traps.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
@@ -26,9 +24,6 @@
 
 /***************************************************************************/
 
-void coldfire_pit_tick(void);
-void coldfire_pit_init(irq_handler_t handler);
-unsigned long coldfire_pit_offset(void);
 void coldfire_reset(void);
 
 /***************************************************************************/
@@ -62,9 +57,6 @@ void mcf_autovector(unsigned int vec)
 void config_BSP(char *commandp, int size)
 {
        mcf_disableall();
-       mach_sched_init = coldfire_pit_init;
-       mach_tick = coldfire_pit_tick;
-       mach_gettimeoffset = coldfire_pit_offset;
        mach_reset = coldfire_reset;
 }
 
index a089e9513699c1e82c0066576178564eb830ce73..acbd43486d97a457a3b0ce5c68123830274dc9d2 100644 (file)
 /***************************************************************************/
 
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <asm/dma.h>
-#include <asm/traps.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
@@ -26,9 +24,6 @@
 
 /***************************************************************************/
 
-void coldfire_pit_tick(void);
-void coldfire_pit_init(irq_handler_t handler);
-unsigned long coldfire_pit_offset(void);
 void coldfire_reset(void);
 
 /***************************************************************************/
@@ -62,9 +57,6 @@ void mcf_autovector(unsigned int vec)
 void config_BSP(char *commandp, int size)
 {
        mcf_disableall();
-       mach_sched_init = coldfire_pit_init;
-       mach_tick = coldfire_pit_tick;
-       mach_gettimeoffset = coldfire_pit_offset;
        mach_reset = coldfire_reset;
 }
 
index e3461619fd65cb5c23ada8aa109eaa5b1f880caf..6040821e637d40af16f2648438aac1ddd3ca632d 100644 (file)
 /***************************************************************************/
 
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <asm/irq.h>
 #include <asm/dma.h>
-#include <asm/traps.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
-#include <asm/mcftimer.h>
 #include <asm/mcfsim.h>
 #include <asm/mcfdma.h>
 #include <asm/mcfwdebug.h>
 
 /***************************************************************************/
 
-void coldfire_tick(void);
-void coldfire_timer_init(irq_handler_t handler);
-unsigned long coldfire_timer_offset(void);
 void coldfire_reset(void);
 
 extern unsigned int mcf_timervector;
@@ -122,9 +115,6 @@ void config_BSP(char *commandp, int size)
        mcf_timerlevel = 6;
 #endif
 
-       mach_sched_init = coldfire_timer_init;
-       mach_tick = coldfire_tick;
-       mach_gettimeoffset = coldfire_timer_offset;
        mach_reset = coldfire_reset;
 
 #ifdef MCF_BDM_DISABLE
index a8cd867805caeeffa12db832275ad8e51bbf2601..b333731b875a81de24c5ea29fee216a0c75bcfbb 100644 (file)
@@ -74,7 +74,8 @@ ENTRY(system_call)
        movel   %sp,%d2                 /* get thread_info pointer */
        andl    #-THREAD_SIZE,%d2       /* at start of kernel stack */
        movel   %d2,%a0
-       movel   %sp,%a0@(THREAD_ESP0)   /* save top of frame */
+       movel   %a0@,%a1                /* save top of frame */
+       movel   %sp,%a1@(TASK_THREAD+THREAD_ESP0)
        btst    #(TIF_SYSCALL_TRACE%8),%a0@(TI_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
        bnes    1f
 
@@ -83,6 +84,8 @@ ENTRY(system_call)
        movel   %d0,%sp@(PT_D0)         /* save the return value */
        jra     ret_from_exception
 1:
+       movel   #-ENOSYS,%d2            /* strace needs -ENOSYS in PT_D0 */
+       movel   %d2,PT_D0(%sp)          /* on syscall entry */
        subql   #4,%sp
        SAVE_SWITCH_STACK
        jbsr    syscall_trace
index e53c446d10e4d9cd2343293b82f0017756a23f58..173b754d1cdadea1fdf810c4a6cca030fc1916d4 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <asm/machdep.h>
 #include <asm/io.h>
 #include <asm/coldfire.h>
 #include <asm/mcfpit.h>
 
 /***************************************************************************/
 
-void coldfire_pit_tick(void)
+static irqreturn_t hw_tick(int irq, void *dummy)
 {
        unsigned short pcsr;
 
        /* Reset the ColdFire timer */
        pcsr = __raw_readw(TA(MCFPIT_PCSR));
        __raw_writew(pcsr | MCFPIT_PCSR_PIF, TA(MCFPIT_PCSR));
+
+       return arch_timer_interrupt(irq, dummy);
 }
 
 /***************************************************************************/
 
 static struct irqaction coldfire_pit_irq = {
-       .name    = "timer",
-       .flags   = IRQF_DISABLED | IRQF_TIMER,
+       .name    = "timer",
+       .flags   = IRQF_DISABLED | IRQF_TIMER,
+       .handler = hw_tick,
 };
 
-void coldfire_pit_init(irq_handler_t handler)
+void hw_timer_init(void)
 {
        volatile unsigned char *icrp;
        volatile unsigned long *imrp;
 
-       coldfire_pit_irq.handler = handler;
        setup_irq(MCFINT_VECBASE + MCFINT_PIT1, &coldfire_pit_irq);
 
        icrp = (volatile unsigned char *) (MCF_IPSBAR + MCFICM_INTC0 +
@@ -71,7 +74,7 @@ void coldfire_pit_init(irq_handler_t handler)
 
 /***************************************************************************/
 
-unsigned long coldfire_pit_offset(void)
+unsigned long hw_timer_offset(void)
 {
        volatile unsigned long *ipr;
        unsigned long pmr, pcntr, offset;
@@ -83,7 +86,7 @@ unsigned long coldfire_pit_offset(void)
 
        /*
         * If we are still in the first half of the upcount and a
-        * timer interupt is pending, then add on a ticks worth of time.
+        * timer interrupt is pending, then add on a ticks worth of time.
         */
        offset = ((pmr - pcntr) * (1000000 / HZ)) / pmr;
        if ((offset < (1000000 / HZ / 2)) && (*ipr & MCFPIT_IMR_IBIT))
index 64bd0ff9029e2922dc92b6bde566404c3e0eed79..489dec85c8594e8fa5d46eedf8478ec01cd249d3 100644 (file)
@@ -9,10 +9,9 @@
 /***************************************************************************/
 
 #include <linux/kernel.h>
+#include <linux/init.h>
 #include <linux/sched.h>
-#include <linux/param.h>
 #include <linux/interrupt.h>
-#include <linux/init.h>
 #include <linux/irq.h>
 #include <asm/io.h>
 #include <asm/traps.h>
@@ -54,24 +53,28 @@ extern int mcf_timerirqpending(int timer);
 
 /***************************************************************************/
 
-void coldfire_tick(void)
+static irqreturn_t hw_tick(int irq, void *dummy)
 {
        /* Reset the ColdFire timer */
        __raw_writeb(MCFTIMER_TER_CAP | MCFTIMER_TER_REF, TA(MCFTIMER_TER));
+
+       return arch_timer_interrupt(irq, dummy);
 }
 
 /***************************************************************************/
 
 static struct irqaction coldfire_timer_irq = {
-        .name    = "timer",
-        .flags   = IRQF_DISABLED | IRQF_TIMER,
+       .name    = "timer",
+       .flags   = IRQF_DISABLED | IRQF_TIMER,
+       .handler = hw_tick,
 };
 
+/***************************************************************************/
+
 static int ticks_per_intr;
 
-void coldfire_timer_init(irq_handler_t handler)
+void hw_timer_init(void)
 {
-       coldfire_timer_irq.handler = handler;
        setup_irq(mcf_timervector, &coldfire_timer_irq);
 
        __raw_writew(MCFTIMER_TMR_DISABLE, TA(MCFTIMER_TMR));
@@ -89,7 +92,7 @@ void coldfire_timer_init(irq_handler_t handler)
 
 /***************************************************************************/
 
-unsigned long coldfire_timer_offset(void)
+unsigned long hw_timer_offset(void)
 {
        unsigned long tcn, offset;
 
index b32c6425f8219ea0430de1a8ef3f23c506584648..f77328b7b6db0439dcf63d2877bfef40e737ac76 100644 (file)
 /***************************************************************************/
 
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <asm/irq.h>
 #include <asm/dma.h>
-#include <asm/traps.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
-#include <asm/mcftimer.h>
 #include <asm/mcfsim.h>
 #include <asm/mcfdma.h>
 #include <asm/mcfwdebug.h>
 
 /***************************************************************************/
 
-void coldfire_tick(void);
-void coldfire_timer_init(irq_handler_t handler);
-unsigned long coldfire_timer_offset(void);
 void coldfire_reset(void);
 
 extern unsigned int mcf_timervector;
@@ -104,9 +97,6 @@ void config_BSP(char *commandp, int size)
 
        mcf_timervector = 64+32;
        mcf_profilevector = 64+33;
-       mach_sched_init = coldfire_timer_init;
-       mach_tick = coldfire_tick;
-       mach_gettimeoffset = coldfire_timer_offset;
        mach_reset = coldfire_reset;
 
 #ifdef MCF_BDM_DISABLE
index e692536817d84fc22f9233360e3f33fd1785eea2..2d3b62eba7ca8c75040912d25ab33bec477f6bee 100644 (file)
 /***************************************************************************/
 
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <asm/irq.h>
 #include <asm/dma.h>
-#include <asm/traps.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
-#include <asm/mcftimer.h>
 #include <asm/mcfsim.h>
 #include <asm/mcfdma.h>
 
 /***************************************************************************/
 
-void coldfire_tick(void);
-void coldfire_timer_init(irq_handler_t handler);
-unsigned long coldfire_timer_offset(void);
 void coldfire_reset(void);
 
 extern unsigned int mcf_timervector;
@@ -108,9 +101,6 @@ void config_BSP(char *commandp, int size)
        mcf_timerlevel = 6;
 #endif
 
-       mach_sched_init = coldfire_timer_init;
-       mach_tick = coldfire_tick;
-       mach_gettimeoffset = coldfire_timer_offset;
        mach_reset = coldfire_reset;
 }
 
index 235d4514e0a9290ead0abe2e82ba711a700fb12c..61262c5f9c6299d440271ba5a596208c67444e11 100644 (file)
@@ -21,6 +21,7 @@ config MACH_ALCHEMY
 
 config BASLER_EXCITE
        bool "Basler eXcite smart camera"
+       select CEVT_R4K
        select DMA_COHERENT
        select HW_HAS_PCI
        select IRQ_CPU
@@ -47,6 +48,7 @@ config BASLER_EXCITE_PROTOTYPE
 
 config BCM47XX
        bool "BCM47XX based boards"
+       select CEVT_R4K
        select DMA_NONCOHERENT
        select HW_HAS_PCI
        select IRQ_CPU
@@ -63,6 +65,8 @@ config BCM47XX
 
 config MIPS_COBALT
        bool "Cobalt Server"
+       select CEVT_R4K
+       select CEVT_GT641XX
        select DMA_NONCOHERENT
        select HW_HAS_PCI
        select I8253
@@ -80,6 +84,7 @@ config MIPS_COBALT
 config MACH_DECSTATION
        bool "DECstations"
        select BOOT_ELF32
+       select CEVT_R4K
        select DMA_NONCOHERENT
        select NO_IOPORT
        select IRQ_CPU
@@ -111,6 +116,7 @@ config MACH_JAZZ
        select ARC
        select ARC32
        select ARCH_MAY_HAVE_PC_FDC
+       select CEVT_R4K
        select GENERIC_ISA_DMA
        select IRQ_CPU
        select I8253
@@ -130,6 +136,7 @@ config MACH_JAZZ
 
 config LASAT
        bool "LASAT Networks platforms"
+       select CEVT_R4K
        select DMA_NONCOHERENT
        select SYS_HAS_EARLY_PRINTK
        select HW_HAS_PCI
@@ -146,6 +153,7 @@ config LASAT
 config LEMOTE_FULONG
        bool "Lemote Fulong mini-PC"
        select ARCH_SPARSEMEM_ENABLE
+       select CEVT_R4K
        select SYS_HAS_CPU_LOONGSON2
        select DMA_NONCOHERENT
        select BOOT_ELF32
@@ -170,6 +178,7 @@ config LEMOTE_FULONG
 config MIPS_ATLAS
        bool "MIPS Atlas board"
        select BOOT_ELF32
+       select CEVT_R4K
        select DMA_NONCOHERENT
        select SYS_HAS_EARLY_PRINTK
        select IRQ_CPU
@@ -200,6 +209,7 @@ config MIPS_MALTA
        bool "MIPS Malta board"
        select ARCH_MAY_HAVE_PC_FDC
        select BOOT_ELF32
+       select CEVT_R4K
        select DMA_NONCOHERENT
        select GENERIC_ISA_DMA
        select IRQ_CPU
@@ -230,6 +240,7 @@ config MIPS_MALTA
 
 config MIPS_SEAD
        bool "MIPS SEAD board"
+       select CEVT_R4K
        select IRQ_CPU
        select DMA_NONCOHERENT
        select SYS_HAS_EARLY_PRINTK
@@ -248,6 +259,7 @@ config MIPS_SEAD
 
 config MIPS_SIM
        bool 'MIPS simulator (MIPSsim)'
+       select CEVT_R4K
        select DMA_NONCOHERENT
        select SYS_HAS_EARLY_PRINTK
        select IRQ_CPU
@@ -265,6 +277,7 @@ config MIPS_SIM
 
 config MARKEINS
        bool "NEC EMMA2RH Mark-eins"
+       select CEVT_R4K
        select DMA_NONCOHERENT
        select HW_HAS_PCI
        select IRQ_CPU
@@ -279,6 +292,7 @@ config MARKEINS
 
 config MACH_VR41XX
        bool "NEC VR4100 series based machines"
+       select CEVT_R4K
        select SYS_HAS_CPU_VR41XX
        select GENERIC_HARDIRQS_NO__DO_IRQ
 
@@ -315,6 +329,7 @@ config PMC_MSP
 
 config PMC_YOSEMITE
        bool "PMC-Sierra Yosemite eval board"
+       select CEVT_R4K
        select DMA_COHERENT
        select HW_HAS_PCI
        select IRQ_CPU
@@ -335,6 +350,7 @@ config PMC_YOSEMITE
 
 config QEMU
        bool "Qemu"
+       select CEVT_R4K
        select DMA_COHERENT
        select GENERIC_ISA_DMA
        select HAVE_STD_PC_SERIAL_PORT
@@ -365,6 +381,7 @@ config SGI_IP22
        select ARC
        select ARC32
        select BOOT_ELF32
+       select CEVT_R4K
        select DMA_NONCOHERENT
        select HW_HAS_EISA
        select I8253
@@ -409,6 +426,7 @@ config SGI_IP32
        select ARC
        select ARC32
        select BOOT_ELF32
+       select CEVT_R4K
        select DMA_NONCOHERENT
        select HW_HAS_PCI
        select IRQ_CPU
@@ -536,6 +554,7 @@ config SNI_RM
        select ARC32 if CPU_LITTLE_ENDIAN
        select ARCH_MAY_HAVE_PC_FDC
        select BOOT_ELF32
+       select CEVT_R4K
        select DMA_NONCOHERENT
        select GENERIC_ISA_DMA
        select HW_HAS_EISA
@@ -577,6 +596,7 @@ config TOSHIBA_JMR3927
 
 config TOSHIBA_RBTX4927
        bool "Toshiba RBTX49[23]7 board"
+       select CEVT_R4K
        select DMA_NONCOHERENT
        select HAS_TXX9_SERIAL
        select HW_HAS_PCI
@@ -597,6 +617,7 @@ config TOSHIBA_RBTX4927
 
 config TOSHIBA_RBTX4938
        bool "Toshiba RBTX4938 board"
+       select CEVT_R4K
        select DMA_NONCOHERENT
        select HAS_TXX9_SERIAL
        select HW_HAS_PCI
@@ -616,6 +637,7 @@ config TOSHIBA_RBTX4938
 
 config WR_PPMC
        bool "Wind River PPMC board"
+       select CEVT_R4K
        select IRQ_CPU
        select BOOT_ELF32
        select DMA_NONCOHERENT
@@ -708,6 +730,12 @@ config ARCH_MAY_HAVE_PC_FDC
 config BOOT_RAW
        bool
 
+config CEVT_GT641XX
+       bool
+
+config CEVT_R4K
+       bool
+
 config CFE
        bool
 
@@ -1788,7 +1816,7 @@ config KEXEC
          but it is independent of the system firmware.   And like a reboot
          you can start any kernel with it, not just Linux.
 
-         The name comes from the similiarity to the exec system call.
+         The name comes from the similarity to the exec system call.
 
          It is an ongoing process to be certain the hardware in a machine
          is properly shutdown, so do not be surprised if this code does not
@@ -1981,7 +2009,7 @@ source "drivers/Kconfig"
 
 source "fs/Kconfig"
 
-source "arch/mips/oprofile/Kconfig"
+source "kernel/Kconfig.instrumentation"
 
 source "arch/mips/Kconfig.debug"
 
index 3efe117721aad002edba89fa9be77e25c4230e4d..fd7124c1b75a01b74091cb51112c22501adc2f6a 100644 (file)
@@ -6,18 +6,6 @@ config TRACE_IRQFLAGS_SUPPORT
 
 source "lib/Kconfig.debug"
 
-config CROSSCOMPILE
-       bool "Are you using a crosscompiler"
-       help
-         Say Y here if you are compiling the kernel on a different
-         architecture than the one it is intended to run on.  This is just a
-         convenience option which will select the appropriate value for
-         the CROSS_COMPILE make variable which otherwise has to be passed on
-         the command line from mips-linux-, mipsel-linux-, mips64-linux- and
-         mips64el-linux- as appropriate for a particular kernel configuration.
-         You will have to pass the value for CROSS_COMPILE manually if the
-         name prefix for your tools is different.
-
 config CMDLINE
        string "Default kernel command string"
        default ""
index 14164c2b8791f00f13ae22b5c74e7b750ba7df11..23c17755eca07a0b6e46f416da5316e3e6638984 100644 (file)
@@ -18,15 +18,15 @@ cflags-y :=
 # Select the object file format to substitute into the linker script.
 #
 ifdef CONFIG_CPU_LITTLE_ENDIAN
-32bit-tool-prefix      = mipsel-linux-
-64bit-tool-prefix      = mips64el-linux-
+32bit-tool-archpref    = mipsel
+64bit-tool-archpref    = mips64el
 32bit-bfd              = elf32-tradlittlemips
 64bit-bfd              = elf64-tradlittlemips
 32bit-emul             = elf32ltsmip
 64bit-emul             = elf64ltsmip
 else
-32bit-tool-prefix      = mips-linux-
-64bit-tool-prefix      = mips64-linux-
+32bit-tool-archpref    = mips
+64bit-tool-archpref    = mips64
 32bit-bfd              = elf32-tradbigmips
 64bit-bfd              = elf64-tradbigmips
 32bit-emul             = elf32btsmip
@@ -34,16 +34,18 @@ else
 endif
 
 ifdef CONFIG_32BIT
-tool-prefix            = $(32bit-tool-prefix)
+tool-archpref          = $(32bit-tool-archpref)
 UTS_MACHINE            := mips
 endif
 ifdef CONFIG_64BIT
-tool-prefix            = $(64bit-tool-prefix)
+tool-archpref          = $(64bit-tool-archpref)
 UTS_MACHINE            := mips64
 endif
 
-ifdef CONFIG_CROSSCOMPILE
-CROSS_COMPILE          := $(tool-prefix)
+ifneq ($(SUBARCH),$(ARCH))
+  ifeq ($(CROSS_COMPILE),)
+    CROSS_COMPILE := $(call cc-cross-prefix, $(tool-archpref)-linux-  $(tool-archpref)-gnu-linux-  $(tool-archpref)-unknown-gnu-linux-)
+  endif
 endif
 
 ifdef CONFIG_32BIT
index a23d4154da01e161a39f8798795e4397d3a5ac40..b36cec58a9a848df2e7be884d85c23c9adb71da1 100644 (file)
@@ -137,6 +137,7 @@ config SOC_AU1200
 config SOC_AU1X00
        bool
        select 64BIT_PHYS_ADDR
+       select CEVT_R4K
        select IRQ_CPU
        select SYS_HAS_CPU_MIPS32_R1
        select SYS_SUPPORTS_32BIT_KERNEL
index 5f48b0603796bc077fb18fed96e33a1b1343ccbe..bdf00e2a35e47db2fd10c59cb4f29a30cefe7588 100644 (file)
@@ -36,8 +36,8 @@
 #include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/delay.h>
+#include <linux/bitops.h>
 
-#include <asm/bitops.h>
 #include <asm/bootinfo.h>
 #include <asm/io.h>
 #include <asm/mipsregs.h>
index 1ecab6350421cdeef9101185aac4ce0a3e26179f..4903e067916b4b5badaca3f2b44bfb2d8c3cbe8d 100644 (file)
@@ -29,7 +29,7 @@
 #include <linux/timex.h>
 #include <linux/slab.h>
 #include <linux/random.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 #include <asm/bootinfo.h>
 #include <asm/io.h>
 #include <asm/irq.h>
index 0ab4676c8bd3afedbfd1d95b709d51372a37ee4b..0c6f47b3fd9482d838d4ffec4c5e47150523a74b 100644 (file)
@@ -46,10 +46,3 @@ void __init plat_time_init(void)
        /* Set MIPS counter frequency for fixed_rate_gettimeoffset() */
        mips_hpt_frequency = hz;
 }
-
-void __init
-plat_timer_setup(struct irqaction *irq)
-{
-       /* Enable the timer interrupt */
-       setup_irq(7, irq);
-}
index 6b83f4ddc8fcbb5212fd416ceb77203fe9d9ce39..d73833b7c781212a3b4a54cc170f210a937dbde6 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for the Cobalt micro systems family specific parts of the kernel
 #
 
-obj-y := buttons.o irq.o led.o reset.o rtc.o serial.o setup.o
+obj-y := buttons.o irq.o led.o reset.o rtc.o serial.o setup.o time.o
 
 obj-$(CONFIG_PCI)              += pci.o
 obj-$(CONFIG_EARLY_PRINTK)     += console.o
index d11bb1bc7b6b2dd12644f32dc0558a71907a4238..dd23beb8604f43a4c0bbef4aefa667fd8dd55e69 100644 (file)
@@ -9,19 +9,17 @@
  * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv)
  *
  */
-#include <linux/interrupt.h>
 #include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
 #include <linux/pm.h>
 
 #include <asm/bootinfo.h>
-#include <asm/time.h>
-#include <asm/i8253.h>
-#include <asm/io.h>
 #include <asm/reboot.h>
 #include <asm/gt64120.h>
 
 #include <cobalt.h>
-#include <irq.h>
 
 extern void cobalt_machine_restart(char *command);
 extern void cobalt_machine_halt(void);
@@ -41,17 +39,6 @@ const char *get_system_type(void)
        return "MIPS Cobalt";
 }
 
-void __init plat_timer_setup(struct irqaction *irq)
-{
-       /* Load timer value for HZ (TCLK is 50MHz) */
-       GT_WRITE(GT_TC0_OFS, 50*1000*1000 / HZ);
-
-       /* Enable timer0 */
-       GT_WRITE(GT_TC_CONTROL_OFS, GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK);
-
-       setup_irq(GT641XX_TIMER0_IRQ, irq);
-}
-
 /*
  * Cobalt doesn't have PS/2 keyboard/mouse interfaces,
  * keyboard conntroller is never used.
@@ -84,11 +71,6 @@ static struct resource cobalt_reserved_resources[] = {
        },
 };
 
-void __init plat_time_init(void)
-{
-       setup_pit_timer();
-}
-
 void __init plat_mem_setup(void)
 {
        int i;
diff --git a/arch/mips/cobalt/time.c b/arch/mips/cobalt/time.c
new file mode 100644 (file)
index 0000000..fa819fc
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ *  Cobalt time initialization.
+ *
+ *  Copyright (C) 2007  Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/init.h>
+
+#include <asm/gt64120.h>
+#include <asm/i8253.h>
+#include <asm/time.h>
+
+#define GT641XX_BASE_CLOCK     50000000        /* 50MHz */
+
+void __init plat_time_init(void)
+{
+       setup_pit_timer();
+
+       gt641xx_set_base_clock(GT641XX_BASE_CLOCK);
+
+       mips_timer_state = gt641xx_timer0_state;
+}
index 49bcc58929ba3a0329a300e56ffe502b4e512a99..892d4c38fd0dd533a242fe45edc8eb632c50af1a 100644 (file)
@@ -175,6 +175,7 @@ CONFIG_POSIX_MQUEUE=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=15
+CONFIG_CGROUPS=y
 CONFIG_CPUSETS=y
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
index 86dcb74643539efc13445768d398a0b146422a8d..61b72f5a953e2cf93daed47c2d3600524b3fe538 100644 (file)
@@ -1,71 +1,68 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20
-# Tue Feb 20 21:47:35 2007
+# Linux kernel version: 2.6.23
+# Thu Oct 18 22:45:52 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
-CONFIG_ZONE_DMA=y
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_PB1200 is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_DB1200 is not set
-# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MACH_ALCHEMY is not set
 # CONFIG_BASLER_EXCITE is not set
+# CONFIG_BCM47XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_LEMOTE_FULONG is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
-# CONFIG_WR_PPMC is not set
 CONFIG_MIPS_SIM=y
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_MARKEINS is not set
+# CONFIG_MACH_VR41XX is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
-# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_MSP is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_QEMU is not set
-# CONFIG_MARKEINS is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SGI_IP27 is not set
 # CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_RHONE is not set
 # CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
 # CONFIG_SIBYTE_SENTOSA is not set
-# CONFIG_SIBYTE_RHONE is not set
-# CONFIG_SIBYTE_CARMEL is not set
 # CONFIG_SIBYTE_PTSWARM is not set
-# CONFIG_SIBYTE_LITTLESUR is not set
-# CONFIG_SIBYTE_CRHINE is not set
-# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_BIGSUR is not set
 # CONFIG_SNI_RM is not set
 # CONFIG_TOSHIBA_JMR3927 is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_WR_PPMC is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 # CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
+CONFIG_BOOT_RAW=y
+CONFIG_CEVT_R4K=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+# CONFIG_HOTPLUG_CPU is not set
+# CONFIG_NO_IOPORT is not set
 # CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
@@ -76,6 +73,11 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
 #
 # CPU selection
 #
+# 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_CPU_LOONGSON2 is not set
 CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_MIPS32_R2 is not set
 # CONFIG_CPU_MIPS64_R1 is not set
@@ -115,8 +117,8 @@ CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
+CONFIG_SYS_SUPPORTS_MULTITHREADING=y
 # CONFIG_MIPS_VPE_LOADER is not set
-# CONFIG_64BIT_PHYS_ADDR is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
@@ -130,50 +132,52 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=1
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
 # CONFIG_HZ_48 is not set
-# CONFIG_HZ_100 is not set
+CONFIG_HZ_100=y
 # CONFIG_HZ_128 is not set
 # CONFIG_HZ_250 is not set
 # CONFIG_HZ_256 is not set
-CONFIG_HZ_1000=y
+# CONFIG_HZ_1000 is not set
 # CONFIG_HZ_1024 is not set
 CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_HZ=1000
+CONFIG_HZ=100
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 # CONFIG_KEXEC is not set
+# CONFIG_SECCOMP is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=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_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 is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS 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_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
@@ -187,31 +191,29 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
-CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
 CONFIG_KMOD=y
-
-#
-# Block layer
-#
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
 
 #
 # IO Schedulers
@@ -229,17 +231,10 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 #
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_MMU=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
 # CONFIG_PCCARD is not set
 
-#
-# PCI Hotplug Support
-#
-
 #
 # Executable file formats
 #
@@ -250,9 +245,8 @@ CONFIG_TRAD_SIGNALS=y
 #
 # Power management options
 #
-CONFIG_PM=y
-# CONFIG_PM_LEGACY is not set
-# CONFIG_PM_DEBUG is not set
+# CONFIG_PM is not set
+CONFIG_SUSPEND_UP_POSSIBLE=y
 
 #
 # Networking
@@ -262,75 +256,50 @@ 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=y
-CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=y
+# CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 CONFIG_IP_ADVANCED_ROUTER=y
 CONFIG_ASK_IP_FIB_HASH=y
 # CONFIG_IP_FIB_TRIE is not set
 CONFIG_IP_FIB_HASH=y
-CONFIG_IP_MULTIPLE_TABLES=y
-CONFIG_IP_ROUTE_MULTIPATH=y
-# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
-CONFIG_IP_ROUTE_VERBOSE=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=y
 # 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=y
+# CONFIG_IP_MROUTE is not set
 # CONFIG_ARPD is not set
-CONFIG_SYN_COOKIES=y
+# 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=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-CONFIG_INET_XFRM_MODE_BEET=m
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
-CONFIG_TCP_MD5SIG=y
+# CONFIG_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=y
+# 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=m
-# CONFIG_SCTP_DBG_MSG is not set
-# CONFIG_SCTP_DBG_OBJCNT is not set
-# CONFIG_SCTP_HMAC_NONE is not set
-# CONFIG_SCTP_HMAC_SHA1 is not set
-CONFIG_SCTP_HMAC_MD5=y
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
+# CONFIG_IP_SCTP is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -347,44 +316,7 @@ CONFIG_SCTP_HMAC_MD5=y
 #
 # QoS and/or fair queueing
 #
-CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_FIFO=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
-#
-CONFIG_NET_SCH_CBQ=m
-CONFIG_NET_SCH_HTB=m
-CONFIG_NET_SCH_HFSC=m
-CONFIG_NET_SCH_PRIO=m
-CONFIG_NET_SCH_RED=m
-CONFIG_NET_SCH_SFQ=m
-CONFIG_NET_SCH_TEQL=m
-CONFIG_NET_SCH_TBF=m
-CONFIG_NET_SCH_GRED=m
-CONFIG_NET_SCH_DSMARK=m
-CONFIG_NET_SCH_NETEM=m
-CONFIG_NET_SCH_INGRESS=m
-
-#
-# Classification
-#
-CONFIG_NET_CLS=y
-CONFIG_NET_CLS_BASIC=m
-CONFIG_NET_CLS_TCINDEX=m
-CONFIG_NET_CLS_ROUTE4=m
-CONFIG_NET_CLS_ROUTE=y
-# CONFIG_NET_CLS_FW is not set
-# CONFIG_NET_CLS_U32 is not set
-# CONFIG_NET_CLS_RSVP is not set
-# CONFIG_NET_CLS_RSVP6 is not set
-# CONFIG_NET_EMATCH is not set
-# CONFIG_NET_CLS_ACT is not set
-# CONFIG_NET_CLS_POLICE is not set
-CONFIG_NET_ESTIMATOR=y
+# CONFIG_NET_SCHED is not set
 
 #
 # Network testing
@@ -393,8 +325,17 @@ CONFIG_NET_ESTIMATOR=y
 # CONFIG_HAMRADIO 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_FIB_RULES=y
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
 
 #
 # Device Drivers
@@ -403,52 +344,25 @@ CONFIG_FIB_RULES=y
 #
 # 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_DEBUG_DRIVER is not set
 # CONFIG_DEBUG_DEVRES 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
-#
-# CONFIG_PNPACPI is not set
-
-#
-# 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=y
 # CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
-
-#
-# Misc devices
-#
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+# CONFIG_MISC_DEVICES is not set
 # CONFIG_IDE is not set
 
 #
@@ -456,48 +370,29 @@ CONFIG_BLK_DEV_NBD=y
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
 # CONFIG_SCSI_NETLINK is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
 # CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
 # CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Network device support
-#
 CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# 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_MIPS_SIM_NET=y
 # CONFIG_DM9000 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
 
@@ -513,49 +408,18 @@ CONFIG_MIPS_SIM_NET=y
 # 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
 
 #
 # Input device support
 #
-CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
-
-#
-# Userland interfaces
-#
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
+# CONFIG_INPUT is not set
 
 #
 # Hardware I/O ports
 #
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_LIBPS2 is not set
-# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -581,31 +445,13 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
 # CONFIG_WATCHDOG is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
 # CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
 # CONFIG_I2C is not set
 
 #
@@ -613,118 +459,60 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # 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
 
 #
-# Dallas's 1-wire bus
+# Sonics Silicon Backplane
 #
-# CONFIG_W1 is not set
+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_SM501 is not set
 
 #
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
 
 #
 # Graphics support
 #
-# CONFIG_FIRMWARE_EDID 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_SOUND is not set
+# CONFIG_DISPLAY_SUPPORT is not set
 
 #
-# HID Devices
-#
-# CONFIG_HID is not set
-
-#
-# USB support
-#
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-# CONFIG_USB_ARCH_HAS_EHCI is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
-#
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
+# Sound
 #
+# CONFIG_SOUND is not set
+# CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
-
-#
-# LED devices
-#
 # CONFIG_NEW_LEDS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-
-#
-# InfiniBand support
-#
-
-#
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
-#
-
-#
-# Real Time Clock
-#
+CONFIG_RTC_LIB=y
 # CONFIG_RTC_CLASS is not set
 
 #
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
-#
-# Auxiliary Display support
-#
-
-#
-# Virtualization
+# Userspace I/O
 #
+# CONFIG_UIO is not set
 
 #
 # File systems
 #
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4DEV_FS is not set
 # CONFIG_REISERFS_FS is not set
@@ -732,6 +520,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 CONFIG_ROMFS_FS=y
 # CONFIG_INOTIFY is not set
@@ -760,10 +549,11 @@ CONFIG_ROMFS_FS=y
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
 CONFIG_PROC_SYSCTL=y
-# CONFIG_SYSFS is not set
-# CONFIG_TMPFS is not set
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -781,10 +571,7 @@ CONFIG_RAMFS=y
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
@@ -796,6 +583,7 @@ 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
@@ -803,22 +591,14 @@ 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
-#
+# CONFIG_DLM is not set
 
 #
 # Profiling support
@@ -833,20 +613,22 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
-CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_SCHED_DEBUG is not set
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS 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=y
+# CONFIG_DEBUG_MUTEXES is not set
 # CONFIG_DEBUG_LOCK_ALLOC is not set
 # CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -854,7 +636,9 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_LIST is not set
 CONFIG_FORCED_INLINING=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="nfsroot=192.168.192.169:/u1/mipsel,timeo=20 ip=dhcp"
 # CONFIG_DEBUG_STACK_USAGE is not set
@@ -865,60 +649,20 @@ CONFIG_CMDLINE="nfsroot=192.168.192.169:/u1/mipsel,timeo=20 ip=dhcp"
 # Security options
 #
 # CONFIG_KEYS is not set
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_BLKCIPHER=m
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_MANAGER=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_XCBC=m
-# CONFIG_CRYPTO_NULL is not set
-# CONFIG_CRYPTO_MD4 is not set
-CONFIG_CRYPTO_MD5=y
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_WP512 is not set
-# CONFIG_CRYPTO_TGR192 is not set
-CONFIG_CRYPTO_GF128MUL=m
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_LRW=m
-# CONFIG_CRYPTO_DES is not set
-CONFIG_CRYPTO_FCRYPT=m
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_AES is not set
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_ARC4 is not set
-# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_CRC32C is not set
-CONFIG_CRYPTO_CAMELLIA=m
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Hardware crypto devices
-#
+# CONFIG_SECURITY 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=y
-CONFIG_CRC32=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
index 3ed991ae0ebe180d5942f42bab47f5573594620b..49dfcef2518ce3bf9ea5f282d1adf421be923df4 100644 (file)
@@ -196,6 +196,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_CGROUPS=y
 CONFIG_CPUSETS=y
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
index 5e1da53b04a7fdbba100bafc4f124547433a12ea..82f9e9013e70c9ff38cab59fa9011c313b8af3ea 100644 (file)
@@ -104,12 +104,6 @@ void __init plat_time_init(void)
        mips_hpt_frequency = (bus_frequency * (4 + reg)) / 4 / 2;
 }
 
-void __init plat_timer_setup(struct irqaction *irq)
-{
-       /* we are using the cpu counter for timer interrupts */
-       setup_irq(CPU_IRQ_BASE + 7, irq);
-}
-
 static void markeins_board_init(void);
 extern void markeins_irq_setup(void);
 
index 835b056cea36c42c835cdadfdcfca47ae668611e..ae25b480723e8161366a692c0f36061852e8fbb8 100644 (file)
@@ -4,7 +4,7 @@
  * for more details.
  *
  * Copyright (C) 1992 Linus Torvalds
- * Copyright (C) 1994 - 2001, 2003 Ralf Baechle
+ * Copyright (C) 1994 - 2001, 2003, 07 Ralf Baechle
  */
 #include <linux/clockchips.h>
 #include <linux/init.h>
@@ -13,6 +13,7 @@
 #include <linux/spinlock.h>
 
 #include <asm/irq_cpu.h>
+#include <asm/i8253.h>
 #include <asm/i8259.h>
 #include <asm/io.h>
 #include <asm/jazz.h>
@@ -136,7 +137,7 @@ static struct irqaction r4030_timer_irqaction = {
        .name           = "timer",
 };
 
-void __init plat_timer_setup(struct irqaction *ignored)
+void __init plat_time_init(void)
 {
        struct irqaction *irq = &r4030_timer_irqaction;
 
@@ -152,4 +153,5 @@ void __init plat_timer_setup(struct irqaction *ignored)
        setup_irq(JAZZ_TIMER_IRQ, irq);
 
        clockevents_register_device(&r4030_clockevent);
+       setup_pit_timer();
 }
index cfc7dce78dab24b9060a432ad8465d22925ef4de..a7857973ca03fc7bd603742059858dcaf74d5bd4 100644 (file)
@@ -5,7 +5,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 1997, 1998, 2001 by Ralf Baechle
+ * Copyright (C) 1996, 1997, 1998, 2001, 07 by Ralf Baechle
  * Copyright (C) 2001 MIPS Technologies, Inc.
  * Copyright (C) 2007 by Thomas Bogendoerfer
  */
@@ -25,7 +25,6 @@
 #include <linux/serial_8250.h>
 
 #include <asm/bootinfo.h>
-#include <asm/i8253.h>
 #include <asm/irq.h>
 #include <asm/jazz.h>
 #include <asm/jazzdma.h>
@@ -64,11 +63,6 @@ static struct resource jazz_io_resources[] = {
        }
 };
 
-void __init plat_time_init(void)
-{
-       setup_pit_timer();
-}
-
 void __init plat_mem_setup(void)
 {
        int i;
index 0c7aee1682cd25852053683d7209ccf1f3fb5f16..edb9e59248ecea7860dde0f16c5623a54d00e16b 100644 (file)
@@ -1,15 +1,4 @@
-/***********************************************************************
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *              ahennessy@mvista.com
- *
- * Based on arch/mips/ddb5xxx/ddb5477/setup.c
- *
- *     Setup file for JMR3927.
- *
- * Copyright (C) 2000-2001 Toshiba 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
  *  with this program; if not, write  to the Free Software Foundation, Inc.,
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  *
- ***********************************************************************
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *              ahennessy@mvista.com
+ *
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
  */
 
+#include <linux/clockchips.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/kdev_t.h>
@@ -104,27 +99,60 @@ static cycle_t jmr3927_hpt_read(void)
        return jiffies * (JMR3927_TIMER_CLK / HZ) + jmr3927_tmrptr->trr;
 }
 
-static void jmr3927_timer_ack(void)
+static void jmr3927_set_mode(enum clock_event_mode mode,
+       struct clock_event_device *evt)
+{
+       /* Nothing to do here */
+}
+
+struct clock_event_device jmr3927_clock_event_device = {
+       .name           = "MIPS",
+       .features       = CLOCK_EVT_FEAT_PERIODIC,
+       .shift          = 32,
+       .rating         = 300,
+       .cpumask        = CPU_MASK_CPU0,
+       .irq            = JMR3927_IRQ_TICK,
+       .set_mode       = jmr3927_set_mode,
+};
+
+static irqreturn_t jmr3927_timer_interrupt(int irq, void *dev_id)
 {
+       struct clock_event_device *cd = &jmr3927_clock_event_device;
+
        jmr3927_tmrptr->tisr = 0;       /* ack interrupt */
+
+       cd->event_handler(cd);
+
+       return IRQ_HANDLED;
 }
 
+static struct irqaction jmr3927_timer_irqaction = {
+       .handler        = jmr3927_timer_interrupt,
+       .flags          = IRQF_DISABLED | IRQF_PERCPU,
+       .name           = "jmr3927-timer",
+};
+
 void __init plat_time_init(void)
 {
+       struct clock_event_device *cd;
+
        clocksource_mips.read = jmr3927_hpt_read;
-       mips_timer_ack = jmr3927_timer_ack;
        mips_hpt_frequency = JMR3927_TIMER_CLK;
-}
 
-void __init plat_timer_setup(struct irqaction *irq)
-{
        jmr3927_tmrptr->cpra = JMR3927_TIMER_CLK / HZ;
        jmr3927_tmrptr->itmr = TXx927_TMTITMR_TIIE | TXx927_TMTITMR_TZCE;
        jmr3927_tmrptr->ccdr = JMR3927_TIMER_CCD;
        jmr3927_tmrptr->tcr =
                TXx927_TMTCR_TCE | TXx927_TMTCR_CCDE | TXx927_TMTCR_TMODE_ITVL;
 
-       setup_irq(JMR3927_IRQ_TICK, irq);
+       cd = &jmr3927_clock_event_device;
+       /* Calculate the min / max delta */
+       cd->mult = div_sc((unsigned long) JMR3927_IMCLK, NSEC_PER_SEC, 32);
+       cd->max_delta_ns        = clockevent_delta2ns(0x7fffffff, cd);
+       cd->min_delta_ns        = clockevent_delta2ns(0x300, cd);
+       clockevents_register_device(cd);
+
+       setup_irq(JMR3927_IRQ_TICK, &jmr3927_timer_irqaction);
 }
 
 #define DO_WRITE_THROUGH
index 95a356ef39106d2e0b5693f805bdbf2ca193d5e4..d7745c8976f697a5e38351f240c2bf859c802b08 100644 (file)
@@ -8,6 +8,9 @@ obj-y           += cpu-probe.o branch.o entry.o genex.o irq.o process.o \
                   ptrace.o reset.o semaphore.o setup.o signal.o syscall.o \
                   time.o topology.o traps.o unaligned.o
 
+obj-$(CONFIG_CEVT_R4K)         += cevt-r4k.o
+obj-$(CONFIG_CEVT_GT641XX)     += cevt-gt641xx.o
+
 binfmt_irix-objs       := irixelf.o irixinv.o irixioctl.o irixsig.o    \
                           irix5sys.o sysirix.o
 
diff --git a/arch/mips/kernel/cevt-gt641xx.c b/arch/mips/kernel/cevt-gt641xx.c
new file mode 100644 (file)
index 0000000..4c651b2
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ *  GT641xx clockevent routines.
+ *
+ *  Copyright (C) 2007  Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/clockchips.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+
+#include <asm/gt64120.h>
+#include <asm/time.h>
+
+#include <irq.h>
+
+static DEFINE_SPINLOCK(gt641xx_timer_lock);
+static unsigned int gt641xx_base_clock;
+
+void gt641xx_set_base_clock(unsigned int clock)
+{
+       gt641xx_base_clock = clock;
+}
+
+int gt641xx_timer0_state(void)
+{
+       if (GT_READ(GT_TC0_OFS))
+               return 0;
+
+       GT_WRITE(GT_TC0_OFS, gt641xx_base_clock / HZ);
+       GT_WRITE(GT_TC_CONTROL_OFS, GT_TC_CONTROL_ENTC0_MSK);
+
+       return 1;
+}
+
+static int gt641xx_timer0_set_next_event(unsigned long delta,
+                                        struct clock_event_device *evt)
+{
+       unsigned long flags;
+       u32 ctrl;
+
+       spin_lock_irqsave(&gt641xx_timer_lock, flags);
+
+       ctrl = GT_READ(GT_TC_CONTROL_OFS);
+       ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK);
+       ctrl |= GT_TC_CONTROL_ENTC0_MSK;
+
+       GT_WRITE(GT_TC0_OFS, delta);
+       GT_WRITE(GT_TC_CONTROL_OFS, ctrl);
+
+       spin_unlock_irqrestore(&gt641xx_timer_lock, flags);
+
+       return 0;
+}
+
+static void gt641xx_timer0_set_mode(enum clock_event_mode mode,
+                                   struct clock_event_device *evt)
+{
+       unsigned long flags;
+       u32 ctrl;
+
+       spin_lock_irqsave(&gt641xx_timer_lock, flags);
+
+       ctrl = GT_READ(GT_TC_CONTROL_OFS);
+       ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK);
+
+       switch (mode) {
+       case CLOCK_EVT_MODE_PERIODIC:
+               ctrl |= GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK;
+               break;
+       case CLOCK_EVT_MODE_ONESHOT:
+               ctrl |= GT_TC_CONTROL_ENTC0_MSK;
+               break;
+       default:
+               break;
+       }
+
+       GT_WRITE(GT_TC_CONTROL_OFS, ctrl);
+
+       spin_unlock_irqrestore(&gt641xx_timer_lock, flags);
+}
+
+static void gt641xx_timer0_event_handler(struct clock_event_device *dev)
+{
+}
+
+static struct clock_event_device gt641xx_timer0_clockevent = {
+       .name           = "gt641xx-timer0",
+       .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+       .cpumask        = CPU_MASK_CPU0,
+       .irq            = GT641XX_TIMER0_IRQ,
+       .set_next_event = gt641xx_timer0_set_next_event,
+       .set_mode       = gt641xx_timer0_set_mode,
+       .event_handler  = gt641xx_timer0_event_handler,
+};
+
+static irqreturn_t gt641xx_timer0_interrupt(int irq, void *dev_id)
+{
+       struct clock_event_device *cd = &gt641xx_timer0_clockevent;
+
+       cd->event_handler(cd);
+
+       return IRQ_HANDLED;
+}
+
+static struct irqaction gt641xx_timer0_irqaction = {
+       .handler        = gt641xx_timer0_interrupt,
+       .flags          = IRQF_DISABLED | IRQF_PERCPU,
+       .name           = "gt641xx_timer0",
+};
+
+static int __init gt641xx_timer0_clockevent_init(void)
+{
+       struct clock_event_device *cd;
+
+       if (!gt641xx_base_clock)
+               return 0;
+
+       GT_WRITE(GT_TC0_OFS, gt641xx_base_clock / HZ);
+
+       cd = &gt641xx_timer0_clockevent;
+       cd->rating = 200 + gt641xx_base_clock / 10000000;
+       cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
+       cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
+       clockevent_set_clock(cd, gt641xx_base_clock);
+
+       clockevents_register_device(&gt641xx_timer0_clockevent);
+
+       return setup_irq(GT641XX_TIMER0_IRQ, &gt641xx_timer0_irqaction);
+}
+arch_initcall(gt641xx_timer0_clockevent_init);
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c
new file mode 100644 (file)
index 0000000..ae2984f
--- /dev/null
@@ -0,0 +1,273 @@
+/*
+ * 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) 2007 MIPS Technologies, Inc.
+ * Copyright (C) 2007 Ralf Baechle <ralf@linux-mips.org>
+ */
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/percpu.h>
+
+#include <asm/smtc_ipi.h>
+#include <asm/time.h>
+
+static int mips_next_event(unsigned long delta,
+                           struct clock_event_device *evt)
+{
+       unsigned int cnt;
+       int res;
+
+#ifdef CONFIG_MIPS_MT_SMTC
+       {
+       unsigned long flags, vpflags;
+       local_irq_save(flags);
+       vpflags = dvpe();
+#endif
+       cnt = read_c0_count();
+       cnt += delta;
+       write_c0_compare(cnt);
+       res = ((long)(read_c0_count() - cnt ) > 0) ? -ETIME : 0;
+#ifdef CONFIG_MIPS_MT_SMTC
+       evpe(vpflags);
+       local_irq_restore(flags);
+       }
+#endif
+       return res;
+}
+
+static void mips_set_mode(enum clock_event_mode mode,
+                          struct clock_event_device *evt)
+{
+       /* Nothing to do ...  */
+}
+
+static DEFINE_PER_CPU(struct clock_event_device, mips_clockevent_device);
+static int cp0_timer_irq_installed;
+
+/*
+ * Timer ack for an R4k-compatible timer of a known frequency.
+ */
+static void c0_timer_ack(void)
+{
+       write_c0_compare(read_c0_compare());
+}
+
+/*
+ * Possibly handle a performance counter interrupt.
+ * Return true if the timer interrupt should not be checked
+ */
+static inline int handle_perf_irq(int r2)
+{
+       /*
+        * The performance counter overflow interrupt may be shared with the
+        * timer interrupt (cp0_perfcount_irq < 0). If it is and a
+        * performance counter has overflowed (perf_irq() == IRQ_HANDLED)
+        * and we can't reliably determine if a counter interrupt has also
+        * happened (!r2) then don't check for a timer interrupt.
+        */
+       return (cp0_perfcount_irq < 0) &&
+               perf_irq() == IRQ_HANDLED &&
+               !r2;
+}
+
+static irqreturn_t c0_compare_interrupt(int irq, void *dev_id)
+{
+       const int r2 = cpu_has_mips_r2;
+       struct clock_event_device *cd;
+       int cpu = smp_processor_id();
+
+       /*
+        * Suckage alert:
+        * Before R2 of the architecture there was no way to see if a
+        * performance counter interrupt was pending, so we have to run
+        * the performance counter interrupt handler anyway.
+        */
+       if (handle_perf_irq(r2))
+               goto out;
+
+       /*
+        * The same applies to performance counter interrupts.  But with the
+        * above we now know that the reason we got here must be a timer
+        * interrupt.  Being the paranoiacs we are we check anyway.
+        */
+       if (!r2 || (read_c0_cause() & (1 << 30))) {
+               c0_timer_ack();
+#ifdef CONFIG_MIPS_MT_SMTC
+               if (cpu_data[cpu].vpe_id)
+                       goto out;
+               cpu = 0;
+#endif
+               cd = &per_cpu(mips_clockevent_device, cpu);
+               cd->event_handler(cd);
+       }
+
+out:
+       return IRQ_HANDLED;
+}
+
+static struct irqaction c0_compare_irqaction = {
+       .handler = c0_compare_interrupt,
+#ifdef CONFIG_MIPS_MT_SMTC
+       .flags = IRQF_DISABLED,
+#else
+       .flags = IRQF_DISABLED | IRQF_PERCPU,
+#endif
+       .name = "timer",
+};
+
+#ifdef CONFIG_MIPS_MT_SMTC
+DEFINE_PER_CPU(struct clock_event_device, smtc_dummy_clockevent_device);
+
+static void smtc_set_mode(enum clock_event_mode mode,
+                          struct clock_event_device *evt)
+{
+}
+
+static void mips_broadcast(cpumask_t mask)
+{
+       unsigned int cpu;
+
+       for_each_cpu_mask(cpu, mask)
+               smtc_send_ipi(cpu, SMTC_CLOCK_TICK, 0);
+}
+
+static void setup_smtc_dummy_clockevent_device(void)
+{
+       //uint64_t mips_freq = mips_hpt_^frequency;
+       unsigned int cpu = smp_processor_id();
+       struct clock_event_device *cd;
+
+       cd = &per_cpu(smtc_dummy_clockevent_device, cpu);
+
+       cd->name                = "SMTC";
+       cd->features            = CLOCK_EVT_FEAT_DUMMY;
+
+       /* Calculate the min / max delta */
+       cd->mult        = 0; //div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32);
+       cd->shift               = 0; //32;
+       cd->max_delta_ns        = 0; //clockevent_delta2ns(0x7fffffff, cd);
+       cd->min_delta_ns        = 0; //clockevent_delta2ns(0x30, cd);
+
+       cd->rating              = 200;
+       cd->irq                 = 17; //-1;
+//     if (cpu)
+//             cd->cpumask     = CPU_MASK_ALL; // cpumask_of_cpu(cpu);
+//     else
+               cd->cpumask     = cpumask_of_cpu(cpu);
+
+       cd->set_mode            = smtc_set_mode;
+
+       cd->broadcast           = mips_broadcast;
+
+       clockevents_register_device(cd);
+}
+#endif
+
+static void mips_event_handler(struct clock_event_device *dev)
+{
+}
+
+/*
+ * FIXME: This doesn't hold for the relocated E9000 compare interrupt.
+ */
+static int c0_compare_int_pending(void)
+{
+       return (read_c0_cause() >> cp0_compare_irq) & 0x100;
+}
+
+static int c0_compare_int_usable(void)
+{
+       const unsigned int delta = 0x300000;
+       unsigned int cnt;
+
+       /*
+        * IP7 already pending?  Try to clear it by acking the timer.
+        */
+       if (c0_compare_int_pending()) {
+               write_c0_compare(read_c0_count());
+               irq_disable_hazard();
+               if (c0_compare_int_pending())
+                       return 0;
+       }
+
+       cnt = read_c0_count();
+       cnt += delta;
+       write_c0_compare(cnt);
+
+       while ((long)(read_c0_count() - cnt) <= 0)
+               ;       /* Wait for expiry  */
+
+       if (!c0_compare_int_pending())
+               return 0;
+
+       write_c0_compare(read_c0_count());
+       irq_disable_hazard();
+       if (c0_compare_int_pending())
+               return 0;
+
+       /*
+        * Feels like a real count / compare timer.
+        */
+       return 1;
+}
+
+void __cpuinit mips_clockevent_init(void)
+{
+       uint64_t mips_freq = mips_hpt_frequency;
+       unsigned int cpu = smp_processor_id();
+       struct clock_event_device *cd;
+       unsigned int irq = MIPS_CPU_IRQ_BASE + 7;
+
+       if (!cpu_has_counter)
+               return;
+
+#ifdef CONFIG_MIPS_MT_SMTC
+       setup_smtc_dummy_clockevent_device();
+
+       /*
+        * On SMTC we only register VPE0's compare interrupt as clockevent
+        * device.
+        */
+       if (cpu)
+               return;
+#endif
+
+       if (!c0_compare_int_usable())
+               return;
+
+       cd = &per_cpu(mips_clockevent_device, cpu);
+
+       cd->name                = "MIPS";
+       cd->features            = CLOCK_EVT_FEAT_ONESHOT;
+
+       /* Calculate the min / max delta */
+       cd->mult        = div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32);
+       cd->shift               = 32;
+       cd->max_delta_ns        = clockevent_delta2ns(0x7fffffff, cd);
+       cd->min_delta_ns        = clockevent_delta2ns(0x300, cd);
+
+       cd->rating              = 300;
+       cd->irq                 = irq;
+#ifdef CONFIG_MIPS_MT_SMTC
+       cd->cpumask             = CPU_MASK_ALL;
+#else
+       cd->cpumask             = cpumask_of_cpu(cpu);
+#endif
+       cd->set_next_event      = mips_next_event;
+       cd->set_mode            = mips_set_mode;
+       cd->event_handler       = mips_event_handler;
+
+       clockevents_register_device(cd);
+
+       if (!cp0_timer_irq_installed) {
+#ifdef CONFIG_MIPS_MT_SMTC
+#define CPUCTR_IMASKBIT (0x100 << cp0_compare_irq)
+               setup_irq_smtc(irq, &c0_compare_irqaction, CPUCTR_IMASKBIT);
+#else
+               setup_irq(irq, &c0_compare_irqaction);
+#endif /* CONFIG_MIPS_MT_SMTC */
+               cp0_timer_irq_installed = 1;
+       }
+}
index bf164a562acbe185864a4ed1cc503e1d56546771..2367687310630c40a68b11423a21dab45cc6b2a9 100644 (file)
 
 #include <kernel-entry-init.h>
 
-       .macro  ARC64_TWIDDLE_PC
-#if defined(CONFIG_ARC64) || defined(CONFIG_MAPPED_KERNEL)
-       /* We get launched at a XKPHYS address but the kernel is linked to
-          run at a KSEG0 address, so jump there.  */
-       PTR_LA  t0, \@f
-       jr      t0
-\@:
-#endif
-       .endm
-
        /*
         * inputs are the text nasid in t1, data nasid in t2.
         */
@@ -157,7 +147,11 @@ NESTED(kernel_entry, 16, sp)                       # kernel entry point
 
        setup_c0_status_pri
 
-       ARC64_TWIDDLE_PC
+       /* We might not get launched at the address the kernel is linked to,
+          so we jump there.  */
+       PTR_LA  t0, 0f
+       jr      t0
+0:
 
 #ifdef CONFIG_MIPS_MT_SMTC
        /*
index b997af713eb393aa6d4322d8f1d3d326e5dd57e9..7852c7cdf29e7e5d575d049d5367a57ed4f21fe5 100644 (file)
@@ -1172,8 +1172,8 @@ static int irix_core_dump(long signr, struct pt_regs *regs, struct file *file, u
        prstatus.pr_sighold = current->blocked.sig[0];
        psinfo.pr_pid = prstatus.pr_pid = current->pid;
        psinfo.pr_ppid = prstatus.pr_ppid = current->parent->pid;
-       psinfo.pr_pgrp = prstatus.pr_pgrp = process_group(current);
-       psinfo.pr_sid = prstatus.pr_sid = process_session(current);
+       psinfo.pr_pgrp = prstatus.pr_pgrp = task_pgrp_nr(current);
+       psinfo.pr_sid = prstatus.pr_sid = task_session_nr(current);
        if (current->pid == current->tgid) {
                /*
                 * This is the record for the group leader.  Add in the
index 85c2e389edd6f1fea3f2c4465396ef73364604dd..a0a91056fda722472edd644e9fa73e379d697a3a 100644 (file)
@@ -609,7 +609,7 @@ repeat:
                p = list_entry(_p, struct task_struct, sibling);
                if ((type == IRIX_P_PID) && p->pid != pid)
                        continue;
-               if ((type == IRIX_P_PGID) && process_group(p) != pid)
+               if ((type == IRIX_P_PGID) && task_pgrp_nr(p) != pid)
                        continue;
                if ((p->exit_signal != SIGCHLD))
                        continue;
index cb0801437b666a7769fedbb2e0a7a82651c44ab6..e7ed0ac485375744bf8b78be07d2ef595357d644 100644 (file)
@@ -381,7 +381,7 @@ const struct exception_table_entry *search_module_dbetables(unsigned long addr)
        return e;
 }
 
-/* Put in dbe list if neccessary. */
+/* Put in dbe list if necessary. */
 int module_finalize(const Elf_Ehdr *hdr,
                    const Elf_Shdr *sechdrs,
                    struct module *me)
index ee7790d9debe2e249e0ebf3480aaebb885fa4fe8..4c477c7ff74a1388c21a85392ed19ac7033cbeec 100644 (file)
@@ -763,11 +763,11 @@ asmlinkage int irix_setpgrp(int flags)
        printk("[%s:%d] setpgrp(%d) ", current->comm, current->pid, flags);
 #endif
        if(!flags)
-               error = process_group(current);
+               error = task_pgrp_nr(current);
        else
                error = sys_setsid();
 #ifdef DEBUG_PROCGRPS
-       printk("returning %d\n", process_group(current));
+       printk("returning %d\n", task_pgrp_nr(current));
 #endif
 
        return error;
index e4b5e647b14211ec5a904091924c24570b99889e..6c6849a8f136988baed2d30a2f5e5eac5fd0bbc1 100644 (file)
 
 #include <irq.h>
 
-/*
- * The integer part of the number of usecs per jiffy is taken from tick,
- * but the fractional part is not recorded, so we calculate it using the
- * initial value of HZ.  This aids systems where tick isn't really an
- * integer (e.g. for HZ = 128).
- */
-#define USECS_PER_JIFFY                TICK_SIZE
-#define USECS_PER_JIFFY_FRAC   ((unsigned long)(u32)((1000000ULL << 32) / HZ))
-
-#define TICK_SIZE      (tick_nsec / 1000)
-
 /*
  * forward reference
  */
@@ -72,14 +61,6 @@ int update_persistent_clock(struct timespec now)
        return rtc_mips_set_mmss(now.tv_sec);
 }
 
-/* how many counter cycles in a jiffy */
-static unsigned long cycles_per_jiffy __read_mostly;
-
-/*
- * Null timer ack for systems not needing one (e.g. i8254).
- */
-static void null_timer_ack(void) { /* nothing */ }
-
 /*
  * Null high precision timer functions for systems lacking one.
  */
@@ -88,14 +69,6 @@ static cycle_t null_hpt_read(void)
        return 0;
 }
 
-/*
- * Timer ack for an R4k-compatible timer of a known frequency.
- */
-static void c0_timer_ack(void)
-{
-       write_c0_compare(read_c0_compare());
-}
-
 /*
  * High precision timer functions for a R4k-compatible timer.
  */
@@ -105,7 +78,6 @@ static cycle_t c0_hpt_read(void)
 }
 
 int (*mips_timer_state)(void);
-void (*mips_timer_ack)(void);
 
 /*
  * local_timer_interrupt() does profiling and process accounting
@@ -134,35 +106,6 @@ int (*perf_irq)(void) = null_perf_irq;
 
 EXPORT_SYMBOL(perf_irq);
 
-/*
- * Timer interrupt
- */
-int cp0_compare_irq;
-
-/*
- * Performance counter IRQ or -1 if shared with timer
- */
-int cp0_perfcount_irq;
-EXPORT_SYMBOL_GPL(cp0_perfcount_irq);
-
-/*
- * Possibly handle a performance counter interrupt.
- * Return true if the timer interrupt should not be checked
- */
-static inline int handle_perf_irq(int r2)
-{
-       /*
-        * The performance counter overflow interrupt may be shared with the
-        * timer interrupt (cp0_perfcount_irq < 0). If it is and a
-        * performance counter has overflowed (perf_irq() == IRQ_HANDLED)
-        * and we can't reliably determine if a counter interrupt has also
-        * happened (!r2) then don't check for a timer interrupt.
-        */
-       return (cp0_perfcount_irq < 0) &&
-               perf_irq() == IRQ_HANDLED &&
-               !r2;
-}
-
 /*
  * time_init() - it does the following things.
  *
@@ -228,270 +171,58 @@ struct clocksource clocksource_mips = {
        .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
-static int mips_next_event(unsigned long delta,
-                           struct clock_event_device *evt)
-{
-       unsigned int cnt;
-       int res;
-
-#ifdef CONFIG_MIPS_MT_SMTC
-       {
-       unsigned long flags, vpflags;
-       local_irq_save(flags);
-       vpflags = dvpe();
-#endif
-       cnt = read_c0_count();
-       cnt += delta;
-       write_c0_compare(cnt);
-       res = ((long)(read_c0_count() - cnt ) > 0) ? -ETIME : 0;
-#ifdef CONFIG_MIPS_MT_SMTC
-       evpe(vpflags);
-       local_irq_restore(flags);
-       }
-#endif
-       return res;
-}
-
-static void mips_set_mode(enum clock_event_mode mode,
-                          struct clock_event_device *evt)
-{
-       /* Nothing to do ...  */
-}
-
-static DEFINE_PER_CPU(struct clock_event_device, mips_clockevent_device);
-static int cp0_timer_irq_installed;
-
-static irqreturn_t timer_interrupt(int irq, void *dev_id)
-{
-       const int r2 = cpu_has_mips_r2;
-       struct clock_event_device *cd;
-       int cpu = smp_processor_id();
-
-       /*
-        * Suckage alert:
-        * Before R2 of the architecture there was no way to see if a
-        * performance counter interrupt was pending, so we have to run
-        * the performance counter interrupt handler anyway.
-        */
-       if (handle_perf_irq(r2))
-               goto out;
-
-       /*
-        * The same applies to performance counter interrupts.  But with the
-        * above we now know that the reason we got here must be a timer
-        * interrupt.  Being the paranoiacs we are we check anyway.
-        */
-       if (!r2 || (read_c0_cause() & (1 << 30))) {
-               c0_timer_ack();
-#ifdef CONFIG_MIPS_MT_SMTC
-               if (cpu_data[cpu].vpe_id)
-                       goto out;
-               cpu = 0;
-#endif
-               cd = &per_cpu(mips_clockevent_device, cpu);
-               cd->event_handler(cd);
-       }
-
-out:
-       return IRQ_HANDLED;
-}
-
-static struct irqaction timer_irqaction = {
-       .handler = timer_interrupt,
-#ifdef CONFIG_MIPS_MT_SMTC
-       .flags = IRQF_DISABLED,
-#else
-       .flags = IRQF_DISABLED | IRQF_PERCPU,
-#endif
-       .name = "timer",
-};
-
-static void __init init_mips_clocksource(void)
+void __init clocksource_set_clock(struct clocksource *cs, unsigned int clock)
 {
        u64 temp;
        u32 shift;
 
-       if (!mips_hpt_frequency || clocksource_mips.read == null_hpt_read)
-               return;
-
-       /* Calclate a somewhat reasonable rating value */
-       clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000;
        /* Find a shift value */
        for (shift = 32; shift > 0; shift--) {
                temp = (u64) NSEC_PER_SEC << shift;
-               do_div(temp, mips_hpt_frequency);
+               do_div(temp, clock);
                if ((temp >> 32) == 0)
                        break;
        }
-       clocksource_mips.shift = shift;
-       clocksource_mips.mult = (u32)temp;
-
-       clocksource_register(&clocksource_mips);
+       cs->shift = shift;
+       cs->mult = (u32) temp;
 }
 
-void __init __weak plat_time_init(void)
+void __cpuinit clockevent_set_clock(struct clock_event_device *cd,
+       unsigned int clock)
 {
-}
-
-void __init __weak plat_timer_setup(struct irqaction *irq)
-{
-}
-
-#ifdef CONFIG_MIPS_MT_SMTC
-DEFINE_PER_CPU(struct clock_event_device, smtc_dummy_clockevent_device);
-
-static void smtc_set_mode(enum clock_event_mode mode,
-                          struct clock_event_device *evt)
-{
-}
-
-int dummycnt[NR_CPUS];
-
-static void mips_broadcast(cpumask_t mask)
-{
-       unsigned int cpu;
+       u64 temp;
+       u32 shift;
 
-       for_each_cpu_mask(cpu, mask)
-               smtc_send_ipi(cpu, SMTC_CLOCK_TICK, 0);
+       /* Find a shift value */
+       for (shift = 32; shift > 0; shift--) {
+               temp = (u64) clock << shift;
+               do_div(temp, NSEC_PER_SEC);
+               if ((temp >> 32) == 0)
+                       break;
+       }
+       cd->shift = shift;
+       cd->mult = (u32) temp;
 }
 
-static void setup_smtc_dummy_clockevent_device(void)
+static void __init init_mips_clocksource(void)
 {
-       //uint64_t mips_freq = mips_hpt_^frequency;
-       unsigned int cpu = smp_processor_id();
-       struct clock_event_device *cd;
-
-       cd = &per_cpu(smtc_dummy_clockevent_device, cpu);
-
-       cd->name                = "SMTC";
-       cd->features            = CLOCK_EVT_FEAT_DUMMY;
-
-       /* Calculate the min / max delta */
-       cd->mult        = 0; //div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32);
-       cd->shift               = 0; //32;
-       cd->max_delta_ns        = 0; //clockevent_delta2ns(0x7fffffff, cd);
-       cd->min_delta_ns        = 0; //clockevent_delta2ns(0x30, cd);
-
-       cd->rating              = 200;
-       cd->irq                 = 17; //-1;
-//     if (cpu)
-//             cd->cpumask     = CPU_MASK_ALL; // cpumask_of_cpu(cpu);
-//     else
-               cd->cpumask     = cpumask_of_cpu(cpu);
-
-       cd->set_mode            = smtc_set_mode;
-
-       cd->broadcast           = mips_broadcast;
+       if (!mips_hpt_frequency || clocksource_mips.read == null_hpt_read)
+               return;
 
-       clockevents_register_device(cd);
-}
-#endif
+       /* Calclate a somewhat reasonable rating value */
+       clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000;
 
-static void mips_event_handler(struct clock_event_device *dev)
-{
-}
+       clocksource_set_clock(&clocksource_mips, mips_hpt_frequency);
 
-/*
- * FIXME: This doesn't hold for the relocated E9000 compare interrupt.
- */
-static int c0_compare_int_pending(void)
-{
-       return (read_c0_cause() >> cp0_compare_irq) & 0x100;
+       clocksource_register(&clocksource_mips);
 }
 
-static int c0_compare_int_usable(void)
+void __init __weak plat_time_init(void)
 {
-       const unsigned int delta = 0x300000;
-       unsigned int cnt;
-
-       /*
-        * IP7 already pending?  Try to clear it by acking the timer.
-        */
-       if (c0_compare_int_pending()) {
-               write_c0_compare(read_c0_compare());
-               irq_disable_hazard();
-               if (c0_compare_int_pending())
-                       return 0;
-       }
-
-       cnt = read_c0_count();
-       cnt += delta;
-       write_c0_compare(cnt);
-
-       while ((long)(read_c0_count() - cnt) <= 0)
-               ;       /* Wait for expiry  */
-
-       if (!c0_compare_int_pending())
-               return 0;
-
-       write_c0_compare(read_c0_compare());
-       irq_disable_hazard();
-       if (c0_compare_int_pending())
-               return 0;
-
-       /*
-        * Feels like a real count / compare timer.
-        */
-       return 1;
 }
 
-void __cpuinit mips_clockevent_init(void)
+void __init __weak plat_timer_setup(struct irqaction *irq)
 {
-       uint64_t mips_freq = mips_hpt_frequency;
-       unsigned int cpu = smp_processor_id();
-       struct clock_event_device *cd;
-       unsigned int irq = MIPS_CPU_IRQ_BASE + 7;
-
-       if (!cpu_has_counter)
-               return;
-
-#ifdef CONFIG_MIPS_MT_SMTC
-       setup_smtc_dummy_clockevent_device();
-
-       /*
-        * On SMTC we only register VPE0's compare interrupt as clockevent
-        * device.
-        */
-       if (cpu)
-               return;
-#endif
-
-       if (!c0_compare_int_usable())
-               return;
-
-       cd = &per_cpu(mips_clockevent_device, cpu);
-
-       cd->name                = "MIPS";
-       cd->features            = CLOCK_EVT_FEAT_ONESHOT;
-
-       /* Calculate the min / max delta */
-       cd->mult        = div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32);
-       cd->shift               = 32;
-       cd->max_delta_ns        = clockevent_delta2ns(0x7fffffff, cd);
-       cd->min_delta_ns        = clockevent_delta2ns(0x300, cd);
-
-       cd->rating              = 300;
-       cd->irq                 = irq;
-#ifdef CONFIG_MIPS_MT_SMTC
-       cd->cpumask             = CPU_MASK_ALL;
-#else
-       cd->cpumask             = cpumask_of_cpu(cpu);
-#endif
-       cd->set_next_event      = mips_next_event;
-       cd->set_mode            = mips_set_mode;
-       cd->event_handler       = mips_event_handler;
-
-       clockevents_register_device(cd);
-
-       if (!cp0_timer_irq_installed) {
-#ifdef CONFIG_MIPS_MT_SMTC
-#define CPUCTR_IMASKBIT (0x100 << cp0_compare_irq)
-               setup_irq_smtc(irq, &timer_irqaction, CPUCTR_IMASKBIT);
-#else
-               setup_irq(irq, &timer_irqaction);
-#endif /* CONFIG_MIPS_MT_SMTC */
-               cp0_timer_irq_installed = 1;
-       }
 }
 
 void __init time_init(void)
@@ -512,14 +243,6 @@ void __init time_init(void)
                if (!clocksource_mips.read) {
                        /* No external high precision timer -- use R4k.  */
                        clocksource_mips.read = c0_hpt_read;
-
-                       if (!mips_timer_state) {
-                               /* No external timer interrupt -- use R4k.  */
-                               mips_timer_ack = c0_timer_ack;
-                               /* Calculate cache parameters.  */
-                               cycles_per_jiffy =
-                                       (mips_hpt_frequency + HZ / 2) / HZ;
-                       }
                }
                if (!mips_hpt_frequency)
                        mips_hpt_frequency = calibrate_hpt();
@@ -528,29 +251,8 @@ void __init time_init(void)
                printk("Using %u.%03u MHz high precision timer.\n",
                       ((mips_hpt_frequency + 500) / 1000) / 1000,
                       ((mips_hpt_frequency + 500) / 1000) % 1000);
-
-#ifdef CONFIG_IRQ_CPU
-               setup_irq(MIPS_CPU_IRQ_BASE + 7, &timer_irqaction);
-#endif
        }
 
-       if (!mips_timer_ack)
-               /* No timer interrupt ack (e.g. i8254).  */
-               mips_timer_ack = null_timer_ack;
-
-       /*
-        * Call board specific timer interrupt setup.
-        *
-        * this pointer must be setup in machine setup routine.
-        *
-        * Even if a machine chooses to use a low-level timer interrupt,
-        * it still needs to setup the timer_irqaction.
-        * In that case, it might be better to set timer_irqaction.handler
-        * to be NULL function so that we are sure the high-level code
-        * is not invoked accidentally.
-        */
-       plat_timer_setup(&timer_irqaction);
-
        init_mips_clocksource();
        mips_clockevent_init();
 }
index bbf01b81a4ffbd8272b35966d92a8cce8a5ba8f1..fa500787152d2cfbc40ffc38075f7ee7545ea103 100644 (file)
@@ -314,7 +314,7 @@ void show_registers(const struct pt_regs *regs)
        __show_regs(regs);
        print_modules();
        printk("Process %s (pid: %d, threadinfo=%p, task=%p)\n",
-               current->comm, current->pid, current_thread_info(), current);
+               current->comm, task_pid_nr(current), current_thread_info(), current);
        show_stacktrace(current, regs);
        show_code((unsigned int __user *) regs->cp0_epc);
        printk("\n");
@@ -1336,6 +1336,17 @@ extern void cpu_cache_init(void);
 extern void tlb_init(void);
 extern void flush_tlb_handlers(void);
 
+/*
+ * Timer interrupt
+ */
+int cp0_compare_irq;
+
+/*
+ * Performance counter IRQ or -1 if shared with timer
+ */
+int cp0_perfcount_irq;
+EXPORT_SYMBOL_GPL(cp0_perfcount_irq);
+
 void __init per_cpu_trap_init(void)
 {
        unsigned int cpu = smp_processor_id();
index 09314a20f9fbfba6b2a594085cbc3ab81b020346..2cc6745991abbb6269e731bb46e9b4e358dd1160 100644 (file)
@@ -53,11 +53,6 @@ unsigned long bus_clock;
 unsigned int memsize;
 unsigned int highmemsize = 0;
 
-void __init plat_timer_setup(struct irqaction *irq)
-{
-       setup_irq(MIPS_CPU_IRQ_BASE + 7, irq);
-}
-
 void __init plat_time_init(void)
 {
        /* setup mips r4k timer */
index 1d00b778ff1e9c0038956aace71ef972c284d5b8..9d6243a8c15a25e430141833eadc4614005733f7 100644 (file)
@@ -147,21 +147,8 @@ void __init plat_time_init(void)
 #endif
 }
 
-//static irqreturn_t mips_perf_interrupt(int irq, void *dev_id)
-//{
-//     return perf_irq();
-//}
-
-//static struct irqaction perf_irqaction = {
-//     .handler = mips_perf_interrupt,
-//     .flags = IRQF_DISABLED | IRQF_PERCPU,
-//     .name = "performance",
-//};
-
 void __init plat_perf_setup(void)
 {
-//     struct irqaction *irq = &perf_irqaction;
-
        cp0_perfcount_irq = -1;
 
 #ifdef MSC01E_INT_BASE
index 98b5e5bac02e8b25ad7429a28b5548629cbee407..b1b40527658b12185ba7b2a0e935ae0920affb33 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/string.h>
+#include <linux/scatterlist.h>
 
 #include <asm/cache.h>
 #include <asm/io.h>
@@ -165,12 +166,11 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
        for (i = 0; i < nents; i++, sg++) {
                unsigned long addr;
 
-               addr = (unsigned long) page_address(sg->page);
+               addr = (unsigned long) sg_virt(sg);
                if (!plat_device_is_coherent(dev) && addr)
-                       __dma_sync(addr + sg->offset, sg->length, direction);
+                       __dma_sync(addr, sg->length, direction);
                sg->dma_address = plat_map_dma_mem(dev,
-                                                  (void *)(addr + sg->offset),
-                                                  sg->length);
+                                                  (void *)addr, sg->length);
        }
 
        return nents;
@@ -223,10 +223,9 @@ void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
        for (i = 0; i < nhwentries; i++, sg++) {
                if (!plat_device_is_coherent(dev) &&
                    direction != DMA_TO_DEVICE) {
-                       addr = (unsigned long) page_address(sg->page);
+                       addr = (unsigned long) sg_virt(sg);
                        if (addr)
-                               __dma_sync(addr + sg->offset, sg->length,
-                                          direction);
+                               __dma_sync(addr, sg->length, direction);
                }
                plat_unmap_dma_mem(sg->dma_address);
        }
@@ -304,7 +303,7 @@ void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
        /* Make sure that gcc doesn't leave the empty loop body.  */
        for (i = 0; i < nelems; i++, sg++) {
                if (cpu_is_noncoherent_r10000(dev))
-                       __dma_sync((unsigned long)page_address(sg->page),
+                       __dma_sync((unsigned long)page_address(sg_page(sg)),
                                   sg->length, direction);
                plat_unmap_dma_mem(sg->dma_address);
        }
@@ -322,7 +321,7 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nele
        /* Make sure that gcc doesn't leave the empty loop body.  */
        for (i = 0; i < nelems; i++, sg++) {
                if (!plat_device_is_coherent(dev))
-                       __dma_sync((unsigned long)page_address(sg->page),
+                       __dma_sync((unsigned long)page_address(sg_page(sg)),
                                   sg->length, direction);
                plat_unmap_dma_mem(sg->dma_address);
        }
index 5699c7713e2f01c5b42f7803df82c61c4b48ec8c..fa636fc6b7b90403a2a8771ef3c5f023a1a82cd4 100644 (file)
@@ -173,7 +173,7 @@ no_context:
  */
 out_of_memory:
        up_read(&mm->mmap_sem);
-       if (is_init(tsk)) {
+       if (is_global_init(tsk)) {
                yield();
                down_read(&mm->mmap_sem);
                goto survive;
diff --git a/arch/mips/oprofile/Kconfig b/arch/mips/oprofile/Kconfig
deleted file mode 100644 (file)
index fb6f235..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-
-menu "Profiling support"
-       depends on EXPERIMENTAL
-
-config PROFILING
-       bool "Profiling support (EXPERIMENTAL)"
-       help
-         Say Y here to enable the extended profiling support mechanisms used
-         by profilers such as OProfile.
-
-
-config OPROFILE
-       tristate "OProfile system profiling (EXPERIMENTAL)"
-       depends on PROFILING && !MIPS_MT_SMTC && EXPERIMENTAL
-       help
-         OProfile is a profiling system capable of profiling the
-         whole system, include the kernel, kernel modules, libraries,
-         and applications.
-
-         If unsure, say N.
-
-endmenu
-
index 3c86c77cb74fa026ffa16303e64f09faa64bb26b..8a56876afcc678dcb7d52783e482fb0e8e2ff545 100644 (file)
@@ -131,7 +131,7 @@ static int __init basler_excite_pci_setup(void)
                ocd_writel(0x00000000, bar + 0x100);
        }
 
-       /* Finally, enable the PCI interupt */
+       /* Finally, enable the PCI interrupt */
 #if USB_IRQ > 7
        set_c0_intcontrol(1 << USB_IRQ);
 #else
index abbd0bbfabd7ba9e93452727eb5a4f397244d625..6b293ce0935f020552490de88a0165f9cbb253f1 100644 (file)
@@ -4,11 +4,13 @@ choice
 
 config PMC_MSP4200_EVAL
        bool "PMC-Sierra MSP4200 Eval Board"
+       select CEVT_R4K
        select IRQ_MSP_SLP
        select HW_HAS_PCI
 
 config PMC_MSP4200_GW
        bool "PMC-Sierra MSP4200 VoIP Gateway"
+       select CEVT_R4K
        select IRQ_MSP_SLP
        select HW_HAS_PCI
 
index f221d4763625f6edb522e14e2bbcb673dfb6a402..7cfeda5a651b9c307105007acd3a2cf20cc910c6 100644 (file)
@@ -86,8 +86,5 @@ void __init plat_timer_setup(struct irqaction *irq)
 #ifdef CONFIG_IRQ_MSP_CIC
        /* we are using the vpe0 counter for timer interrupts */
        setup_irq(MSP_INT_VPE0_TIMER, irq);
-#else
-       /* we are using the mips counter for timer interrupts */
-       setup_irq(MSP_INT_TIMER, irq);
 #endif
 }
index 015fcc363dc0f7861910db4f6ef8bf3d1b7971c0..855977ca51cd3d5e05fd09bec366a40ce687a89b 100644 (file)
@@ -137,11 +137,6 @@ int rtc_mips_set_time(unsigned long tim)
        return 0;
 }
 
-void __init plat_timer_setup(struct irqaction *irq)
-{
-       setup_irq(7, irq);
-}
-
 void __init plat_time_init(void)
 {
        mips_hpt_frequency = cpu_clock_freq / 2;
index 681b593071cbced9405d9b5cb691405f4b2f1ff6..3305fa9ae66d7bec7b5072e9672c1b9e787f0bf7 100644 (file)
@@ -110,7 +110,7 @@ static void __init per_hub_init(cnodeid_t cnode)
        }
 }
 
-void __init per_cpu_init(void)
+void __cpuinit per_cpu_init(void)
 {
        int cpu = smp_processor_id();
        int slice = LOCAL_HUB_L(PI_CPU_NUM);
index 856649cf9f1ec6ab2e8bf6602c8e6554cf79782a..1bb692a3b31948d2a9abb4a13e7f5049ae38886a 100644 (file)
@@ -374,14 +374,13 @@ int __devinit request_bridge_irq(struct bridge_controller *bc)
        return irq;
 }
 
-extern void ip27_rt_timer_interrupt(void);
-
 asmlinkage void plat_irq_dispatch(void)
 {
        unsigned long pending = read_c0_cause() & read_c0_status();
+       extern unsigned int rt_timer_irq;
 
        if (pending & CAUSEF_IP4)
-               ip27_rt_timer_interrupt();
+               do_IRQ(rt_timer_irq);
        else if (pending & CAUSEF_IP2)  /* PI_INT_PEND_0 or CC_PEND_{A|B} */
                ip27_do_irq_mask0();
        else if (pending & CAUSEF_IP3)  /* PI_INT_PEND_1 */
index b7b3479b6bce2deca63503654f473fe2d3b33924..f5dccf01da115adb516adfc451c770439262fe54 100644 (file)
@@ -3,6 +3,7 @@
  * Copytight (C) 1999, 2000 Silicon Graphics, Inc.
  */
 #include <linux/bcd.h>
+#include <linux/clockchips.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <asm/sn/sn0/ip27.h>
 #include <asm/sn/sn0/hub.h>
 
-/*
- * This is a hack; we really need to figure these values out dynamically
- *
- * Since 800 ns works very well with various HUB frequencies, such as
- * 360, 380, 390 and 400 MHZ, we use 800 ns rtc cycle time.
- *
- * Ralf: which clock rate is used to feed the counter?
- */
-#define NSEC_PER_CYCLE         800
-#define CYCLES_PER_SEC         (NSEC_PER_SEC/NSEC_PER_CYCLE)
-#define CYCLES_PER_JIFFY       (CYCLES_PER_SEC/HZ)
-
 #define TICK_SIZE (tick_nsec / 1000)
 
-static unsigned long ct_cur[NR_CPUS];  /* What counter should be at next timer irq */
-
 #if 0
 static int set_rtc_mmss(unsigned long nowtime)
 {
@@ -86,36 +73,6 @@ static int set_rtc_mmss(unsigned long nowtime)
 }
 #endif
 
-static unsigned int rt_timer_irq;
-
-void ip27_rt_timer_interrupt(void)
-{
-       int cpu = smp_processor_id();
-       int cpuA = cputoslice(cpu) == 0;
-       unsigned int irq = rt_timer_irq;
-
-       irq_enter();
-       write_seqlock(&xtime_lock);
-
-again:
-       LOCAL_HUB_S(cpuA ? PI_RT_PEND_A : PI_RT_PEND_B, 0);     /* Ack  */
-       ct_cur[cpu] += CYCLES_PER_JIFFY;
-       LOCAL_HUB_S(cpuA ? PI_RT_COMPARE_A : PI_RT_COMPARE_B, ct_cur[cpu]);
-
-       if (LOCAL_HUB_L(PI_RT_COUNT) >= ct_cur[cpu])
-               goto again;
-
-       kstat_this_cpu.irqs[irq]++;             /* kstat only for bootcpu? */
-
-       if (cpu == 0)
-               do_timer(1);
-
-       update_process_times(user_mode(get_irq_regs()));
-
-       write_sequnlock(&xtime_lock);
-       irq_exit();
-}
-
 /* Includes for ioc3_init().  */
 #include <asm/sn/types.h>
 #include <asm/sn/sn0/addrs.h>
@@ -171,33 +128,109 @@ static struct irq_chip rt_irq_type = {
        .eoi            = enable_rt_irq,
 };
 
-static struct irqaction rt_irqaction = {
-       .handler        = (irq_handler_t) ip27_rt_timer_interrupt,
-       .flags          = IRQF_DISABLED,
-       .mask           = CPU_MASK_NONE,
-       .name           = "timer"
-};
+static int rt_next_event(unsigned long delta, struct clock_event_device *evt)
+{
+       unsigned int cpu = smp_processor_id();
+       int slice = cputoslice(cpu) == 0;
+       unsigned long cnt;
+
+       cnt = LOCAL_HUB_L(PI_RT_COUNT);
+       cnt += delta;
+       LOCAL_HUB_S(slice ? PI_RT_COMPARE_A : PI_RT_COMPARE_B, cnt);
+
+       return LOCAL_HUB_L(PI_RT_COUNT) >= cnt ? -ETIME : 0;
+}
+
+static void rt_set_mode(enum clock_event_mode mode,
+               struct clock_event_device *evt)
+{
+       switch (mode) {
+       case CLOCK_EVT_MODE_ONESHOT:
+               /* The only mode supported */
+               break;
+
+       case CLOCK_EVT_MODE_PERIODIC:
+       case CLOCK_EVT_MODE_UNUSED:
+       case CLOCK_EVT_MODE_SHUTDOWN:
+       case CLOCK_EVT_MODE_RESUME:
+               /* Nothing to do  */
+               break;
+       }
+}
 
-void __init plat_timer_setup(struct irqaction *irq)
+unsigned int rt_timer_irq;
+
+static irqreturn_t hub_rt_counter_handler(int irq, void *dev_id)
 {
-       int irqno  = allocate_irqno();
+       struct clock_event_device *cd = dev_id;
+       unsigned int cpu = smp_processor_id();
+       int slice = cputoslice(cpu) == 0;
 
-       if (irqno < 0)
-               panic("Can't allocate interrupt number for timer interrupt");
+       LOCAL_HUB_S(slice ? PI_RT_PEND_A : PI_RT_PEND_B, 0);    /* Ack  */
+       cd->event_handler(cd);
 
-       set_irq_chip_and_handler(irqno, &rt_irq_type, handle_percpu_irq);
+       return IRQ_HANDLED;
+}
 
-       /* over-write the handler, we use our own way */
-       irq->handler = no_action;
+struct irqaction hub_rt_irqaction = {
+       .handler        = hub_rt_counter_handler,
+       .flags          = IRQF_DISABLED | IRQF_PERCPU,
+       .name           = "hub-rt",
+};
 
-       /* setup irqaction */
-       irq_desc[irqno].status |= IRQ_PER_CPU;
+/*
+ * This is a hack; we really need to figure these values out dynamically
+ *
+ * Since 800 ns works very well with various HUB frequencies, such as
+ * 360, 380, 390 and 400 MHZ, we use 800 ns rtc cycle time.
+ *
+ * Ralf: which clock rate is used to feed the counter?
+ */
+#define NSEC_PER_CYCLE         800
+#define CYCLES_PER_SEC         (NSEC_PER_SEC / NSEC_PER_CYCLE)
 
-       rt_timer_irq = irqno;
-       /*
-        * Only needed to get /proc/interrupt to display timer irq stats
-        */
-       setup_irq(irqno, &rt_irqaction);
+static DEFINE_PER_CPU(struct clock_event_device, hub_rt_clockevent);
+static DEFINE_PER_CPU(char [11], hub_rt_name);
+
+static void __cpuinit hub_rt_clock_event_init(void)
+{
+       unsigned int cpu = smp_processor_id();
+       struct clock_event_device *cd = &per_cpu(hub_rt_clockevent, cpu);
+       unsigned char *name = per_cpu(hub_rt_name, cpu);
+       int irq = rt_timer_irq;
+
+       sprintf(name, "hub-rt %d", cpu);
+       cd->name                = "HUB-RT",
+       cd->features            = CLOCK_EVT_FEAT_ONESHOT,
+       clockevent_set_clock(cd, CYCLES_PER_SEC);
+       cd->max_delta_ns        = clockevent_delta2ns(0xfffffffffffff, cd);
+       cd->min_delta_ns        = clockevent_delta2ns(0x300, cd);
+       cd->rating              = 200,
+       cd->irq                 = irq,
+       cd->cpumask             = cpumask_of_cpu(cpu),
+       cd->rating              = 300,
+       cd->set_next_event      = rt_next_event,
+       cd->set_mode            = rt_set_mode,
+       clockevents_register_device(cd);
+}
+
+static void __init hub_rt_clock_event_global_init(void)
+{
+       unsigned int irq;
+
+       do {
+               smp_wmb();
+               irq = rt_timer_irq;
+               if (irq)
+                       break;
+
+               irq = allocate_irqno();
+               if (irq < 0)
+                       panic("Allocation of irq number for timer failed");
+       } while (xchg(&rt_timer_irq, irq));
+
+       set_irq_chip_and_handler(irq, &rt_irq_type, handle_percpu_irq);
+       setup_irq(irq, &hub_rt_irqaction);
 }
 
 static cycle_t hub_rt_read(void)
@@ -205,21 +238,29 @@ static cycle_t hub_rt_read(void)
        return REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT);
 }
 
-struct clocksource ht_rt_clocksource = {
-       .name   = "HUB",
+struct clocksource hub_rt_clocksource = {
+       .name   = "HUB-RT",
        .rating = 200,
        .read   = hub_rt_read,
        .mask   = CLOCKSOURCE_MASK(52),
-       .shift  = 32,
        .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
+static void __init hub_rt_clocksource_init(void)
+{
+       struct clocksource *cs = &hub_rt_clocksource;
+
+       clocksource_set_clock(cs, CYCLES_PER_SEC);
+       clocksource_register(cs);
+}
+
 void __init plat_time_init(void)
 {
-       clocksource_register(&ht_rt_clocksource);
+       hub_rt_clocksource_init();
+       hub_rt_clock_event_global_init();
 }
 
-void __init cpu_time_init(void)
+void __cpuinit cpu_time_init(void)
 {
        lboard_t *board;
        klcpu_t *cpu;
@@ -237,6 +278,7 @@ void __init cpu_time_init(void)
 
        printk("CPU %d clock is %dMHz.\n", smp_processor_id(), cpu->cpu_speed);
 
+       hub_rt_clock_event_init();
        set_c0_status(SRB_TIMOCLK);
 }
 
@@ -248,17 +290,12 @@ void __init hub_rtc_init(cnodeid_t cnode)
         * node and timeouts will not happen there.
         */
        if (get_compact_nodeid() == cnode) {
-               int cpu = smp_processor_id();
                LOCAL_HUB_S(PI_RT_EN_A, 1);
                LOCAL_HUB_S(PI_RT_EN_B, 1);
                LOCAL_HUB_S(PI_PROF_EN_A, 0);
                LOCAL_HUB_S(PI_PROF_EN_B, 0);
-               ct_cur[cpu] = CYCLES_PER_JIFFY;
-               LOCAL_HUB_S(PI_RT_COMPARE_A, ct_cur[cpu]);
                LOCAL_HUB_S(PI_RT_COUNT, 0);
                LOCAL_HUB_S(PI_RT_PEND_A, 0);
-               LOCAL_HUB_S(PI_RT_COMPARE_B, ct_cur[cpu]);
-               LOCAL_HUB_S(PI_RT_COUNT, 0);
                LOCAL_HUB_S(PI_RT_PEND_B, 0);
        }
 }
index fc75bfcb0c0e64ea41656f03a53b80d59f74a714..1024bf40bd9e79f1c63dd79f7be8289371e89caf 100644 (file)
@@ -80,12 +80,6 @@ void __init plat_time_init(void)
        printk("%d MHz CPU detected\n", mips_hpt_frequency * 2 / 1000000);
 }
 
-void __init plat_timer_setup(struct irqaction *irq)
-{
-       irq->handler = no_action;
-       setup_irq(MIPS_CPU_IRQ_BASE + 7, irq);
-}
-
 void __init plat_mem_setup(void)
 {
        board_be_init = ip32_be_init;
index 7aa79bf63c4ad423042365d5442e80f4a9fd0743..10299bafeab761aeb682d423be6223fd0176461b 100644 (file)
@@ -452,6 +452,43 @@ static void bcm1480_kgdb_interrupt(void)
 
 extern void bcm1480_mailbox_interrupt(void);
 
+static inline void dispatch_ip4(void)
+{
+       int cpu = smp_processor_id();
+       int irq = K_BCM1480_INT_TIMER_0 + cpu;
+
+       /* Reset the timer */
+       __raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
+                   IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+
+       do_IRQ(irq);
+}
+
+static inline void dispatch_ip2(void)
+{
+       unsigned long long mask_h, mask_l;
+       unsigned int cpu = smp_processor_id();
+       unsigned long base;
+
+       /*
+        * Default...we've hit an IP[2] interrupt, which means we've got to
+        * check the 1480 interrupt registers to figure out what to do.  Need
+        * to detect which CPU we're on, now that smp_affinity is supported.
+        */
+       base = A_BCM1480_IMR_MAPPER(cpu);
+       mask_h = __raw_readq(
+               IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H));
+       mask_l = __raw_readq(
+               IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L));
+
+       if (mask_h) {
+               if (mask_h ^ 1)
+                       do_IRQ(fls64(mask_h) - 1);
+               else if (mask_l)
+                       do_IRQ(63 + fls64(mask_l));
+       }
+}
+
 asmlinkage void plat_irq_dispatch(void)
 {
        unsigned int pending;
@@ -469,17 +506,8 @@ asmlinkage void plat_irq_dispatch(void)
        else
 #endif
 
-       if (pending & CAUSEF_IP4) {
-               int cpu = smp_processor_id();
-               int irq = K_BCM1480_INT_TIMER_0 + cpu;
-
-               /* Reset the timer */
-               __raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
-                           IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
-
-               do_IRQ(irq);
-       }
-
+       if (pending & CAUSEF_IP4)
+               dispatch_ip4();
 #ifdef CONFIG_SMP
        else if (pending & CAUSEF_IP3)
                bcm1480_mailbox_interrupt();
@@ -490,27 +518,6 @@ asmlinkage void plat_irq_dispatch(void)
                bcm1480_kgdb_interrupt();               /* KGDB (uart 1) */
 #endif
 
-       else if (pending & CAUSEF_IP2) {
-               unsigned long long mask_h, mask_l;
-               unsigned long base;
-
-               /*
-                * Default...we've hit an IP[2] interrupt, which means we've
-                * got to check the 1480 interrupt registers to figure out what
-                * to do.  Need to detect which CPU we're on, now that
-                * smp_affinity is supported.
-                */
-               base = A_BCM1480_IMR_MAPPER(smp_processor_id());
-               mask_h = __raw_readq(
-                       IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H));
-               mask_l = __raw_readq(
-                       IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L));
-
-               if (mask_h) {
-                       if (mask_h ^ 1)
-                               do_IRQ(fls64(mask_h) - 1);
-                       else
-                               do_IRQ(63 + fls64(mask_l));
-               }
-       }
+       else if (pending & CAUSEF_IP2)
+               dispatch_ip2();
 }
index 6eac36d1b8c893fcb1c56d16d1ba0808ce19e90d..436ba78359aba9dc83f8b43f0801155a00ade951 100644 (file)
@@ -58,7 +58,7 @@ static void *mailbox_0_regs[] = {
 /*
  * SMP init and finish on secondary CPUs
  */
-void bcm1480_smp_init(void)
+void __cpuinit bcm1480_smp_init(void)
 {
        unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
                STATUSF_IP1 | STATUSF_IP0;
@@ -67,10 +67,11 @@ void bcm1480_smp_init(void)
        change_c0_status(ST0_IM, imask);
 }
 
-void bcm1480_smp_finish(void)
+void __cpuinit bcm1480_smp_finish(void)
 {
-       extern void bcm1480_time_init(void);
-       bcm1480_time_init();
+       extern void sb1480_clockevent_init(void);
+
+       sb1480_clockevent_init();
        local_irq_enable();
 }
 
index 5b4bfbbb5a24b053c9176cb1bec5860e894fdd8f..610f0253954dbb5151bb87215d3ab0d424e3ef0e 100644 (file)
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
-
-/*
- * These are routines to set up and handle interrupts from the
- * bcm1480 general purpose timer 0.  We're using the timer as a
- * system clock, so we set it up to run at 100 Hz.  On every
- * interrupt, we update our idea of what the time of day is,
- * then call do_timer() in the architecture-independent kernel
- * code to do general bookkeeping (e.g. update jiffies, run
- * bottom halves, etc.)
- */
 #include <linux/clockchips.h>
 #include <linux/interrupt.h>
-#include <linux/sched.h>
+#include <linux/irq.h>
+#include <linux/percpu.h>
 #include <linux/spinlock.h>
-#include <linux/kernel_stat.h>
 
-#include <asm/irq.h>
 #include <asm/addrspace.h>
 #include <asm/time.h>
 #include <asm/io.h>
 #define IMR_IP3_VAL    K_BCM1480_INT_MAP_I1
 #define IMR_IP4_VAL    K_BCM1480_INT_MAP_I2
 
-#ifdef CONFIG_SIMULATION
-#define BCM1480_HPT_VALUE      50000
-#else
-#define BCM1480_HPT_VALUE      1000000
-#endif
-
 extern int bcm1480_steal_irq(int irq);
 
-void __init plat_time_init(void)
-{
-       unsigned int cpu = smp_processor_id();
-       unsigned int irq = K_BCM1480_INT_TIMER_0 + cpu;
-
-       BUG_ON(cpu > 3);        /* Only have 4 general purpose timers */
-
-       bcm1480_mask_irq(cpu, irq);
-
-       /* Map the timer interrupt to ip[4] of this cpu */
-       __raw_writeq(IMR_IP4_VAL, IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_INTERRUPT_MAP_BASE_H)
-             + (irq<<3)));
-
-       bcm1480_unmask_irq(cpu, irq);
-       bcm1480_steal_irq(irq);
-}
-
 /*
- * The general purpose timer ticks at 1 Mhz independent if
+ * The general purpose timer ticks at 1MHz independent if
  * the rest of the system
  */
 static void sibyte_set_mode(enum clock_event_mode mode,
@@ -89,7 +55,7 @@ static void sibyte_set_mode(enum clock_event_mode mode,
        switch (mode) {
        case CLOCK_EVT_MODE_PERIODIC:
                __raw_writeq(0, timer_cfg);
-               __raw_writeq(BCM1480_HPT_VALUE / HZ - 1, timer_init);
+               __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, timer_init);
                __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
                             timer_cfg);
                break;
@@ -101,76 +67,117 @@ static void sibyte_set_mode(enum clock_event_mode mode,
                break;
 
        case CLOCK_EVT_MODE_UNUSED:     /* shuddup gcc */
+       case CLOCK_EVT_MODE_RESUME:
                ;
        }
 }
 
-struct clock_event_device sibyte_hpt_clockevent = {
-       .name           = "bcm1480-counter",
-       .features       = CLOCK_EVT_FEAT_PERIODIC,
-       .set_mode       = sibyte_set_mode,
-       .shift          = 32,
-       .irq            = 0,
-};
+static int sibyte_next_event(unsigned long delta, struct clock_event_device *cd)
+{
+       unsigned int cpu = smp_processor_id();
+       void __iomem *timer_init;
+       unsigned int cnt;
+       int res;
+
+       timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
+       cnt = __raw_readq(timer_init);
+       cnt += delta;
+       __raw_writeq(cnt, timer_init);
+       res = ((long)(__raw_readq(timer_init) - cnt ) > 0) ? -ETIME : 0;
+
+       return res;
+}
 
 static irqreturn_t sibyte_counter_handler(int irq, void *dev_id)
 {
-       struct clock_event_device *cd = &sibyte_hpt_clockevent;
        unsigned int cpu = smp_processor_id();
+       struct clock_event_device *cd = dev_id;
+       void __iomem *timer_cfg;
+
+       timer_cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
 
        /* Reset the timer */
-       __raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
-                    IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+       __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
+                    timer_cfg);
        cd->event_handler(cd);
 
        return IRQ_HANDLED;
 }
 
-static struct irqaction sibyte_counter_irqaction = {
-       .handler        = sibyte_counter_handler,
-       .flags          = IRQF_DISABLED | IRQF_PERCPU,
-       .name           = "timer",
-};
+static DEFINE_PER_CPU(struct clock_event_device, sibyte_hpt_clockevent);
+static DEFINE_PER_CPU(struct irqaction, sibyte_hpt_irqaction);
+static DEFINE_PER_CPU(char [18], sibyte_hpt_name);
 
-/*
- * This interrupt is "special" in that it doesn't use the request_irq
- * way to hook the irq line.  The timer interrupt is initialized early
- * enough to make this a major pain, and it's also firing enough to
- * warrant a bit of special case code.  bcm1480_timer_interrupt is
- * called directly from irq_handler.S when IP[4] is set during an
- * interrupt
- */
-static void __init sb1480_clockevent_init(void)
+void __cpuinit sb1480_clockevent_init(void)
 {
        unsigned int cpu = smp_processor_id();
        unsigned int irq = K_BCM1480_INT_TIMER_0 + cpu;
+       struct irqaction *action = &per_cpu(sibyte_hpt_irqaction, cpu);
+       struct clock_event_device *cd = &per_cpu(sibyte_hpt_clockevent, cpu);
+       unsigned char *name = per_cpu(sibyte_hpt_name, cpu);
 
-       setup_irq(irq, &sibyte_counter_irqaction);
-}
+       BUG_ON(cpu > 3);        /* Only have 4 general purpose timers */
 
-void bcm1480_timer_interrupt(void)
-{
-       int cpu = smp_processor_id();
-       int irq = K_BCM1480_INT_TIMER_0 + cpu;
+       sprintf(name, "bcm1480-counter %d", cpu);
+       cd->name                = name;
+       cd->features            = CLOCK_EVT_FEAT_PERIODIC |
+                                 CLOCK_EVT_MODE_ONESHOT;
+       clockevent_set_clock(cd, V_SCD_TIMER_FREQ);
+       cd->max_delta_ns        = clockevent_delta2ns(0x7fffff, cd);
+       cd->min_delta_ns        = clockevent_delta2ns(1, cd);
+       cd->rating              = 200;
+       cd->irq                 = irq;
+       cd->cpumask             = cpumask_of_cpu(cpu);
+       cd->set_next_event      = sibyte_next_event;
+       cd->set_mode            = sibyte_set_mode;
+       clockevents_register_device(cd);
 
-       /* Reset the timer */
-       __raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
-             IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+       bcm1480_mask_irq(cpu, irq);
+
+       /*
+        * Map timer interrupt to IP[4] of this cpu
+        */
+       __raw_writeq(IMR_IP4_VAL,
+                    IOADDR(A_BCM1480_IMR_REGISTER(cpu,
+                       R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) + (irq << 3)));
+
+       bcm1480_unmask_irq(cpu, irq);
+       bcm1480_steal_irq(irq);
 
-       ll_timer_interrupt(irq);
+       action->handler = sibyte_counter_handler;
+       action->flags   = IRQF_DISABLED | IRQF_PERCPU;
+       action->name    = name;
+       action->dev_id  = cd;
+       setup_irq(irq, action);
 }
 
 static cycle_t bcm1480_hpt_read(void)
 {
-       /* We assume this function is called xtime_lock held. */
-       unsigned long count =
-               __raw_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT)));
-       return (jiffies + 1) * (BCM1480_HPT_VALUE / HZ) - count;
+       return (cycle_t) __raw_readq(IOADDR(A_SCD_ZBBUS_CYCLE_COUNT));
 }
 
-void __init bcm1480_hpt_setup(void)
+struct clocksource bcm1480_clocksource = {
+       .name   = "zbbus-cycles",
+       .rating = 200,
+       .read   = bcm1480_hpt_read,
+       .mask   = CLOCKSOURCE_MASK(64),
+       .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+void __init sb1480_clocksource_init(void)
+{
+       struct clocksource *cs = &bcm1480_clocksource;
+       unsigned int plldiv;
+       unsigned long zbbus;
+
+       plldiv = G_BCM1480_SYS_PLL_DIV(__raw_readq(IOADDR(A_SCD_SYSTEM_CFG)));
+       zbbus = ((plldiv >> 1) * 50000000) + ((plldiv & 1) * 25000000);
+       clocksource_set_clock(cs, zbbus);
+       clocksource_register(cs);
+}
+
+void __init plat_time_init(void)
 {
-       clocksource_mips.read = bcm1480_hpt_read;
-       mips_hpt_frequency = BCM1480_HPT_VALUE;
+       sb1480_clocksource_init();
        sb1480_clockevent_init();
 }
index 7659174819c65720f0a3de051a416ac0dbcf533d..53780a179d1d94efe7804b017f2d820a27485b4f 100644 (file)
@@ -400,43 +400,27 @@ static void sb1250_kgdb_interrupt(void)
 
 #endif         /* CONFIG_KGDB */
 
-static inline void sb1250_timer_interrupt(void)
-{
-       int cpu = smp_processor_id();
-       int irq = K_INT_TIMER_0 + cpu;
-
-       irq_enter();
-       kstat_this_cpu.irqs[irq]++;
-
-       write_seqlock(&xtime_lock);
-
-       /* ACK interrupt */
-       ____raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
-                      IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
-
-       /*
-        * call the generic timer interrupt handling
-        */
-       do_timer(1);
+extern void sb1250_mailbox_interrupt(void);
 
-       write_sequnlock(&xtime_lock);
+static inline void dispatch_ip2(void)
+{
+       unsigned int cpu = smp_processor_id();
+       unsigned long long mask;
 
        /*
-        * In UP mode, we call local_timer_interrupt() to do profiling
-        * and process accouting.
-        *
-        * In SMP mode, local_timer_interrupt() is invoked by appropriate
-        * low-level local timer interrupt handler.
+        * Default...we've hit an IP[2] interrupt, which means we've got to
+        * check the 1250 interrupt registers to figure out what to do.  Need
+        * to detect which CPU we're on, now that smp_affinity is supported.
         */
-       local_timer_interrupt(irq);
-
-       irq_exit();
+       mask = __raw_readq(IOADDR(A_IMR_REGISTER(cpu,
+                                 R_IMR_INTERRUPT_STATUS_BASE)));
+       if (mask)
+               do_IRQ(fls64(mask) - 1);
 }
 
-extern void sb1250_mailbox_interrupt(void);
-
 asmlinkage void plat_irq_dispatch(void)
 {
+       unsigned int cpu = smp_processor_id();
        unsigned int pending;
 
        /*
@@ -454,7 +438,7 @@ asmlinkage void plat_irq_dispatch(void)
        if (pending & CAUSEF_IP7) /* CPU performance counter interrupt */
                do_IRQ(MIPS_CPU_IRQ_BASE + 7);
        else if (pending & CAUSEF_IP4)
-               sb1250_timer_interrupt();
+               do_IRQ(K_INT_TIMER_0 + cpu);    /* sb1250_timer_interrupt() */
 
 #ifdef CONFIG_SMP
        else if (pending & CAUSEF_IP3)
@@ -466,21 +450,8 @@ asmlinkage void plat_irq_dispatch(void)
                sb1250_kgdb_interrupt();
 #endif
 
-       else if (pending & CAUSEF_IP2) {
-               unsigned long long mask;
-
-               /*
-                * Default...we've hit an IP[2] interrupt, which means we've
-                * got to check the 1250 interrupt registers to figure out what
-                * to do.  Need to detect which CPU we're on, now that
-                * smp_affinity is supported.
-                */
-               mask = __raw_readq(IOADDR(A_IMR_REGISTER(smp_processor_id(),
-                                             R_IMR_INTERRUPT_STATUS_BASE)));
-               if (mask)
-                       do_IRQ(fls64(mask) - 1);
-               else
-                       spurious_interrupt();
-       } else
+       else if (pending & CAUSEF_IP2)
+               dispatch_ip2();
+       else
                spurious_interrupt();
 }
index c38e1f34460d44847473d17f297af2f4a3a14d6b..3f52c95a4eb8a2ae14ad5d3ebe580aaa9194601e 100644 (file)
@@ -46,7 +46,7 @@ static void *mailbox_regs[] = {
 /*
  * SMP init and finish on secondary CPUs
  */
-void sb1250_smp_init(void)
+void __cpuinit sb1250_smp_init(void)
 {
        unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
                STATUSF_IP1 | STATUSF_IP0;
@@ -55,10 +55,11 @@ void sb1250_smp_init(void)
        change_c0_status(ST0_IM, imask);
 }
 
-void sb1250_smp_finish(void)
+void __cpuinit sb1250_smp_finish(void)
 {
-       extern void sb1250_time_init(void);
-       sb1250_time_init();
+       extern void sb1250_clockevent_init(void);
+
+       sb1250_clockevent_init();
        local_irq_enable();
 }
 
index fe11fed8e0d73e25857678d0c68746d9abb21887..a41e908bc2182395cdc4f24f994da985d3374f71 100644 (file)
 
 extern int sb1250_steal_irq(int irq);
 
-static cycle_t sb1250_hpt_read(void);
-
-void __init sb1250_hpt_setup(void)
-{
-       int cpu = smp_processor_id();
-
-       if (!cpu) {
-               /* Setup hpt using timer #3 but do not enable irq for it */
-               __raw_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CFG)));
-               __raw_writeq(SB1250_HPT_VALUE,
-                            IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_INIT)));
-               __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
-                            IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CFG)));
-
-               mips_hpt_frequency = V_SCD_TIMER_FREQ;
-               clocksource_mips.read = sb1250_hpt_read;
-               clocksource_mips.mask = M_SCD_TIMER_INIT;
-       }
-}
-
 /*
  * The general purpose timer ticks at 1 Mhz independent if
  * the rest of the system
@@ -100,6 +80,7 @@ static void sibyte_set_mode(enum clock_event_mode mode,
                break;
 
        case CLOCK_EVT_MODE_UNUSED:     /* shuddup gcc */
+       case CLOCK_EVT_MODE_RESUME:
                ;
        }
 }
@@ -120,90 +101,14 @@ sibyte_next_event(unsigned long delta, struct clock_event_device *evt)
        return 0;
 }
 
-struct clock_event_device sibyte_hpt_clockevent = {
-       .name           = "sb1250-counter",
-       .features       = CLOCK_EVT_FEAT_PERIODIC,
-       .set_mode       = sibyte_set_mode,
-       .set_next_event = sibyte_next_event,
-       .shift          = 32,
-       .irq            = 0,
-};
-
 static irqreturn_t sibyte_counter_handler(int irq, void *dev_id)
-{
-       struct clock_event_device *cd = &sibyte_hpt_clockevent;
-
-       cd->event_handler(cd);
-
-       return IRQ_HANDLED;
-}
-
-static struct irqaction sibyte_irqaction = {
-       .handler        = sibyte_counter_handler,
-       .flags          = IRQF_DISABLED | IRQF_PERCPU,
-       .name           = "timer",
-};
-
-/*
- * The general purpose timer ticks at 1 Mhz independent if
- * the rest of the system
- */
-static void sibyte_set_mode(enum clock_event_mode mode,
-                           struct clock_event_device *evt)
 {
        unsigned int cpu = smp_processor_id();
-       void __iomem *timer_cfg, *timer_init;
+       struct clock_event_device *cd = dev_id;
 
-       timer_cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
-       timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
-
-       switch (mode) {
-       case CLOCK_EVT_MODE_PERIODIC:
-               __raw_writeq(0, timer_cfg);
-               __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, timer_init);
-               __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
-                            timer_cfg);
-               break;
-
-       case CLOCK_EVT_MODE_ONESHOT:
-               /* Stop the timer until we actually program a shot */
-       case CLOCK_EVT_MODE_SHUTDOWN:
-               __raw_writeq(0, timer_cfg);
-               break;
-
-       case CLOCK_EVT_MODE_UNUSED:     /* shuddup gcc */
-               ;
-       }
-}
-
-static int
-sibyte_next_event(unsigned long delta, struct clock_event_device *evt)
-{
-       unsigned int cpu = smp_processor_id();
-       void __iomem *timer_cfg, *timer_init;
-
-       timer_cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
-       timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
-
-       __raw_writeq(0, timer_cfg);
-       __raw_writeq(delta, timer_init);
-       __raw_writeq(M_SCD_TIMER_ENABLE, timer_cfg);
-
-       return 0;
-}
-
-struct clock_event_device sibyte_hpt_clockevent = {
-       .name           = "sb1250-counter",
-       .features       = CLOCK_EVT_FEAT_PERIODIC,
-       .set_mode       = sibyte_set_mode,
-       .set_next_event = sibyte_next_event,
-       .shift          = 32,
-       .irq            = 0,
-};
-
-static irqreturn_t sibyte_counter_handler(int irq, void *dev_id)
-{
-       struct clock_event_device *cd = &sibyte_hpt_clockevent;
+       /* ACK interrupt */
+       ____raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
+                      IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
 
        cd->event_handler(cd);
 
@@ -216,15 +121,35 @@ static struct irqaction sibyte_irqaction = {
        .name           = "timer",
 };
 
-static void __init sb1250_clockevent_init(void)
+static DEFINE_PER_CPU(struct clock_event_device, sibyte_hpt_clockevent);
+static DEFINE_PER_CPU(struct irqaction, sibyte_hpt_irqaction);
+static DEFINE_PER_CPU(char [18], sibyte_hpt_name);
+
+void __cpuinit sb1250_clockevent_init(void)
 {
-       struct clock_event_device *cd = &sibyte_hpt_clockevent;
        unsigned int cpu = smp_processor_id();
-       int irq = K_INT_TIMER_0 + cpu;
+       unsigned int irq = K_INT_TIMER_0 + cpu;
+       struct irqaction *action = &per_cpu(sibyte_hpt_irqaction, cpu);
+       struct clock_event_device *cd = &per_cpu(sibyte_hpt_clockevent, cpu);
+       unsigned char *name = per_cpu(sibyte_hpt_name, cpu);
 
        /* Only have 4 general purpose timers, and we use last one as hpt */
        BUG_ON(cpu > 2);
 
+       sprintf(name, "bcm1480-counter %d", cpu);
+       cd->name                = name;
+       cd->features            = CLOCK_EVT_FEAT_PERIODIC |
+                                 CLOCK_EVT_MODE_ONESHOT;
+       clockevent_set_clock(cd, V_SCD_TIMER_FREQ);
+       cd->max_delta_ns        = clockevent_delta2ns(0x7fffff, cd);
+       cd->min_delta_ns        = clockevent_delta2ns(1, cd);
+       cd->rating              = 200;
+       cd->irq                 = irq;
+       cd->cpumask             = cpumask_of_cpu(cpu);
+       cd->set_next_event      = sibyte_next_event;
+       cd->set_mode            = sibyte_set_mode;
+       clockevents_register_device(cd);
+
        sb1250_mask_irq(cpu, irq);
 
        /* Map the timer interrupt to ip[4] of this cpu */
@@ -236,23 +161,11 @@ static void __init sb1250_clockevent_init(void)
        sb1250_unmask_irq(cpu, irq);
        sb1250_steal_irq(irq);
 
-       /*
-        * This interrupt is "special" in that it doesn't use the request_irq
-        * way to hook the irq line.  The timer interrupt is initialized early
-        * enough to make this a major pain, and it's also firing enough to
-        * warrant a bit of special case code.  sb1250_timer_interrupt is
-        * called directly from irq_handler.S when IP[4] is set during an
-        * interrupt
-        */
+       action->handler = sibyte_counter_handler;
+       action->flags   = IRQF_DISABLED | IRQF_PERCPU;
+       action->name    = name;
+       action->dev_id  = cd;
        setup_irq(irq, &sibyte_irqaction);
-
-       clockevents_register_device(cd);
-}
-
-void __init plat_time_init(void)
-{
-       sb1250_clocksource_init();
-       sb1250_clockevent_init();
 }
 
 /*
@@ -267,3 +180,36 @@ static cycle_t sb1250_hpt_read(void)
 
        return SB1250_HPT_VALUE - count;
 }
+
+struct clocksource bcm1250_clocksource = {
+       .name   = "MIPS",
+       .rating = 200,
+       .read   = sb1250_hpt_read,
+       .mask   = CLOCKSOURCE_MASK(23),
+       .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+void __init sb1250_clocksource_init(void)
+{
+       struct clocksource *cs = &bcm1250_clocksource;
+
+       /* Setup hpt using timer #3 but do not enable irq for it */
+       __raw_writeq(0,
+                    IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
+                                                R_SCD_TIMER_CFG)));
+       __raw_writeq(SB1250_HPT_VALUE,
+                    IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
+                                                R_SCD_TIMER_INIT)));
+       __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
+                    IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
+                                                R_SCD_TIMER_CFG)));
+
+       clocksource_set_clock(cs, V_SCD_TIMER_FREQ);
+       clocksource_register(cs);
+}
+
+void __init plat_time_init(void)
+{
+       sb1250_clocksource_init();
+       sb1250_clockevent_init();
+}
index 8b3ef0e4cd555c735bf3cfe60c5a42110fc0ac9e..080c966263b701aa608bb536f8147803aa11fc41 100644 (file)
@@ -69,31 +69,6 @@ const char *get_system_type(void)
        return "SiByte " SIBYTE_BOARD_NAME;
 }
 
-void __init plat_time_init(void)
-{
-#if defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
-       /* Setup HPT */
-       sb1250_hpt_setup();
-#endif
-}
-
-void __init plat_timer_setup(struct irqaction *irq)
-{
-        /*
-         * we don't set up irqaction, because we will deliver timer
-         * interrupts through low-level (direct) meachanism.
-         */
-
-        /* We only need to setup the generic timer */
-#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
-       bcm1480_time_init();
-#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
-       sb1250_time_init();
-#else
-#error invalid SiByte board configuration
-#endif
-}
-
 int swarm_be_handler(struct pt_regs *regs, int is_fixup)
 {
        if (!is_fixup && (regs->cp0_cause & 4)) {
index 39bb15f1f2a65e3b46f24975d985caf982ea4d28..4df070f2ff5dd488736cd49af07674e6f3844f1d 100644 (file)
@@ -246,7 +246,7 @@ static void pcimt_hwint1(void)
                /*
                 * Note: ASIC PCI's builtin interrupt achknowledge feature is
                 * broken.  Using it may result in loss of some or all i8259
-                * interupts, so don't use PCIMT_INT_ACKNOWLEDGE ...
+                * interrupts, so don't use PCIMT_INT_ACKNOWLEDGE ...
                 */
                irq = i8259_irq();
                if (unlikely(irq < 0))
index b80877349d3897718d6ee52672d00e83701c93d7..0910b35cb71fb0861cfb3c2d98ebf58804b16fbd 100644 (file)
@@ -121,15 +121,6 @@ void __init plat_time_init(void)
        setup_pit_timer();
 }
 
-/*
- * R4k counter based timer interrupt. Works on RM200-225 and possibly
- * others but not on RM400
- */
-static void __init sni_cpu_timer_setup(struct irqaction *irq)
-{
-        setup_irq(SNI_MIPS_IRQ_CPU_TIMER, irq);
-}
-
 void __init plat_timer_setup(struct irqaction *irq)
 {
        switch (sni_brd_type) {
@@ -139,15 +130,6 @@ void __init plat_timer_setup(struct irqaction *irq)
        case SNI_BRD_MINITOWER:
                sni_a20r_timer_setup(irq);
                break;
-
-       case SNI_BRD_PCI_TOWER:
-       case SNI_BRD_RM200:
-       case SNI_BRD_PCI_MTOWER:
-       case SNI_BRD_PCI_DESKTOP:
-       case SNI_BRD_PCI_TOWER_CPLUS:
-       case SNI_BRD_PCI_MTOWER_CPLUS:
-               sni_cpu_timer_setup(irq);
-               break;
        }
 }
 
index 8ce0989671d806e57214bf2b070459906e8932a9..36c5f200eb3dfadf76d2a10747f800480b8ea335 100644 (file)
@@ -72,22 +72,6 @@ void __init plat_time_init(void)
 #endif
 }
 
-void __init plat_timer_setup(struct irqaction *irq)
-{
-       setup_irq(TX4927_IRQ_CPU_TIMER, irq);
-
-#ifdef CONFIG_TOSHIBA_RBTX4927
-       {
-               extern void toshiba_rbtx4927_timer_setup(struct irqaction
-                                                        *irq);
-               toshiba_rbtx4927_timer_setup(irq);
-       }
-#endif
-
-       return;
-}
-
-
 #ifdef DEBUG
 void print_cp0(char *key, int num, char *name, u32 val)
 {
index b97102a1c635f2c1626ef714bcfac6f03f82a7ad..c7470fba6180d4ff9a57dc00fdc15517a6a3dfb7 100644 (file)
@@ -94,7 +94,6 @@
 #define TOSHIBA_RBTX4927_SETUP_EFWFU       ( 1 <<  3 )
 #define TOSHIBA_RBTX4927_SETUP_SETUP       ( 1 <<  4 )
 #define TOSHIBA_RBTX4927_SETUP_TIME_INIT   ( 1 <<  5 )
-#define TOSHIBA_RBTX4927_SETUP_TIMER_SETUP ( 1 <<  6 )
 #define TOSHIBA_RBTX4927_SETUP_PCIBIOS     ( 1 <<  7 )
 #define TOSHIBA_RBTX4927_SETUP_PCI1        ( 1 <<  8 )
 #define TOSHIBA_RBTX4927_SETUP_PCI2        ( 1 <<  9 )
@@ -108,7 +107,6 @@ static const u32 toshiba_rbtx4927_setup_debug_flag =
     (TOSHIBA_RBTX4927_SETUP_NONE | TOSHIBA_RBTX4927_SETUP_INFO |
      TOSHIBA_RBTX4927_SETUP_WARN | TOSHIBA_RBTX4927_SETUP_EROR |
      TOSHIBA_RBTX4927_SETUP_EFWFU | TOSHIBA_RBTX4927_SETUP_SETUP |
-     TOSHIBA_RBTX4927_SETUP_TIME_INIT | TOSHIBA_RBTX4927_SETUP_TIMER_SETUP
      | TOSHIBA_RBTX4927_SETUP_PCIBIOS | TOSHIBA_RBTX4927_SETUP_PCI1 |
      TOSHIBA_RBTX4927_SETUP_PCI2 | TOSHIBA_RBTX4927_SETUP_PCI66);
 #endif
@@ -947,14 +945,6 @@ toshiba_rbtx4927_time_init(void)
 
 }
 
-void __init toshiba_rbtx4927_timer_setup(struct irqaction *irq)
-{
-       TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIMER_SETUP,
-                                      "-\n");
-       TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIMER_SETUP,
-                                      "+\n");
-}
-
 static int __init toshiba_rbtx4927_rtc_init(void)
 {
        static struct resource __initdata res = {
index ab4082267553374cfaad83398bd2a37f25819e98..3ba4101d141eda4360f6a438cf2fafbcb5572553 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/irq.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 #include <asm/bootinfo.h>
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -43,8 +43,3 @@ plat_mem_setup(void)
 {
        toshiba_rbtx4938_setup();
 }
-
-void __init plat_timer_setup(struct irqaction *irq)
-{
-       setup_irq(TX4938_IRQ_CPU_TIMER, irq);
-}
index 8f4d3e74c2307017dfa1e44dcd90a4b595aafe4a..eeb089f20c0db183902a47faa22c217aee4765ee 100644 (file)
@@ -5,6 +5,7 @@ choice
 
 config CASIO_E55
        bool "CASIO CASSIOPEIA E-10/15/55/65"
+       select CEVT_R4K
        select DMA_NONCOHERENT
        select IRQ_CPU
        select ISA
@@ -13,6 +14,7 @@ config CASIO_E55
 
 config IBM_WORKPAD
        bool "IBM WorkPad z50"
+       select CEVT_R4K
        select DMA_NONCOHERENT
        select IRQ_CPU
        select ISA
@@ -21,6 +23,7 @@ config IBM_WORKPAD
 
 config NEC_CMBVR4133
        bool "NEC CMB-VR4133"
+       select CEVT_R4K
        select DMA_NONCOHERENT
        select IRQ_CPU
        select HW_HAS_PCI
@@ -29,6 +32,7 @@ config NEC_CMBVR4133
 
 config TANBAC_TB022X
        bool "TANBAC VR4131 multichip module and TANBAC VR4131DIMM"
+       select CEVT_R4K
        select DMA_NONCOHERENT
        select IRQ_CPU
        select HW_HAS_PCI
@@ -43,6 +47,7 @@ config TANBAC_TB022X
 
 config VICTOR_MPC30X
        bool "Victor MP-C303/304"
+       select CEVT_R4K
        select DMA_NONCOHERENT
        select IRQ_CPU
        select HW_HAS_PCI
@@ -52,6 +57,7 @@ config VICTOR_MPC30X
 
 config ZAO_CAPCELLA
        bool "ZAO Networks Capcella"
+       select CEVT_R4K
        select DMA_NONCOHERENT
        select IRQ_CPU
        select HW_HAS_PCI
index 407cec203b291276f4751e38f4ebd7ef6ac111ce..8d760df686c45b42bd2410cfa2d384ebb9f11793 100644 (file)
@@ -48,11 +48,6 @@ void __init plat_time_init(void)
                mips_hpt_frequency = tclock / 4;
 }
 
-void __init plat_timer_setup(struct irqaction *irq)
-{
-       setup_irq(TIMER_IRQ, irq);
-}
-
 void __init plat_mem_setup(void)
 {
        vr41xx_calculate_clock_frequency();
index 3d73545e8c484d158b96788be65a9a7fcab60f48..b8ef1787a191ce81337590391067b9dda811b89d 100644 (file)
@@ -267,7 +267,7 @@ source "drivers/Kconfig"
 
 source "fs/Kconfig"
 
-source "arch/parisc/oprofile/Kconfig"
+source "kernel/Kconfig.instrumentation"
 
 source "arch/parisc/Kconfig.debug"
 
index f3d0d7c7097782bb43bf2e93d5e0eead251274bc..ae4a9b3d4fd6bbde15bd3cea8916e154f1c7794d 100644 (file)
 NM             = sh $(srctree)/arch/parisc/nm
 CHECKFLAGS     += -D__hppa__=1
 
+MACHINE                := $(shell uname -m)
+ifeq ($(MACHINE),parisc*)
+NATIVE         := 1
+endif
+
 ifdef CONFIG_64BIT
-CROSS_COMPILE  := $(shell if [ -x /usr/bin/hppa64-linux-gnu-gcc ]; then \
-                       echo hppa64-linux-gnu-; else echo hppa64-linux-; fi)
 UTS_MACHINE    := parisc64
 CHECKFLAGS     += -D__LP64__=1 -m64
-else
-MACHINE := $(subst 64,,$(shell uname -m))
-ifneq ($(MACHINE),parisc)
-CROSS_COMPILE  := hppa-linux-
-endif
+WIDTH          := 64
+CROSS_COMPILE  := hppa64-linux-gnu-
+else # 32-bit
+WIDTH          :=
 endif
 
-FINAL_LD=$(CROSS_COMPILE)ld --warn-common --warn-section-align 
+# attempt to help out folks who are cross-compiling
+ifeq ($(NATIVE),1)
+CROSS_COMPILE  := hppa$(WIDTH)-linux-
+endif
 
 OBJCOPY_FLAGS =-O binary -R .note -R .comment -S
 
-ifneq ($(call cc-ifversion, -lt, 0303, "bad"),)
-$(error Sorry, GCC v3.3 or above is required.)
-endif
-
 cflags-y       := -pipe
 
 # These flags should be implied by an hppa-linux configuration, but they
@@ -69,7 +70,7 @@ kernel-y                      := mm/ kernel/ math-emu/ kernel/init_task.o
 kernel-$(CONFIG_HPUX)          += hpux/
 
 core-y += $(addprefix arch/parisc/, $(kernel-y))
-libs-y += arch/parisc/lib/ `$(CC) -print-libgcc-file-name`
+libs-y += arch/parisc/lib/
 
 drivers-$(CONFIG_OPROFILE)             += arch/parisc/oprofile/
 
@@ -77,27 +78,27 @@ PALO := $(shell if which palo; then : ; \
        elif [ -x /sbin/palo ]; then echo /sbin/palo; \
        fi)
 
+PALOCONF := $(shell if [ -f $(src)/palo.conf ]; then echo $(src)/palo.conf; \
+       else echo $(obj)/palo.conf; \
+       fi)
+
 palo: vmlinux
-       @if [ -x $PALO ]; then \
+       @if test ! -x "$(PALO)"; then \
                echo 'ERROR: Please install palo first (apt-get install palo)';\
                echo 'or build it from source and install it somewhere in your $$PATH';\
                false; \
        fi
-       @if [ ! -f ./palo.conf ]; then \
-               cp arch/parisc/defpalo.conf palo.conf; \
-               echo 'A generic palo config file (./palo.conf) has been created for you.'; \
+       @if test ! -f "$(PALOCONF)"; then \
+               cp $(src)/arch/parisc/defpalo.conf $(obj)/palo.conf; \
+               echo 'A generic palo config file ($(obj)/palo.conf) has been created for you.'; \
                echo 'You should check it and re-run "make palo".'; \
                echo 'WARNING: the "lifimage" file is now placed in this directory by default!'; \
                false; \
        fi
-       $(PALO) -f ./palo.conf
-
-oldpalo: vmlinux
-       export TOPDIR=`pwd`; \
-       unset STRIP LDFLAGS CPP CPPFLAGS AFLAGS CFLAGS CC LD; cd ../palo && make lifimage
+       $(PALO) -f $(PALOCONF)
 
-# Shorthands for known targets not supported by parisc, use palo as default
-Image zImage bzImage: palo
+# Shorthands for known targets not supported by parisc, use vmlinux as default
+Image zImage bzImage: vmlinux
 
 kernel_install: vmlinux
        sh $(src)/arch/parisc/install.sh \
@@ -116,3 +117,12 @@ define archhelp
        @echo  '                  (distribution) /sbin/installkernel or'
        @echo  '                  copy to $$(INSTALL_PATH)'
 endef
+
+# we require gcc 3.3 or above to compile the kernel
+archprepare: checkbin
+checkbin:
+       @if test "$(call cc-version)" -lt "0303"; then \
+               echo -n "Sorry, GCC v3.3 or above is required to build " ; \
+               echo "the kernel." ; \
+               false ; \
+       fi
index 41fd0696bbe7c5c161a1061776b5702c5199eb6c..9fc96e7271654cace9e0e2b24a50ec3e7b8e967a 100644 (file)
@@ -1,39 +1,51 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-pa6
-# Sun Mar 26 19:59:51 2006
+# Linux kernel version: 2.6.23
+# Fri Oct 12 21:00:07 2007
 #
 CONFIG_PARISC=y
 CONFIG_MMU=y
 CONFIG_STACK_GROWSUP=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_IRQ_PER_CPU=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_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -43,31 +55,29 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_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_VM_EVENT_COUNTERS=y
 CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=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
 
 #
 # IO Schedulers
@@ -91,6 +101,9 @@ CONFIG_PA7100LC=y
 # CONFIG_PA7300LC is not set
 # CONFIG_PA8X00 is not set
 CONFIG_PA11=y
+CONFIG_PARISC_PAGE_SIZE_4KB=y
+# CONFIG_PARISC_PAGE_SIZE_16KB is not set
+# CONFIG_PARISC_PAGE_SIZE_64KB is not set
 # CONFIG_SMP is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
 # CONFIG_PREEMPT_NONE is not set
@@ -98,6 +111,7 @@ CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
 # 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_SELECT_MEMORY_MODEL=y
@@ -108,6 +122,9 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
 # CONFIG_HPUX is not set
 
 #
@@ -120,21 +137,19 @@ CONFIG_GSC_LASI=y
 # CONFIG_GSC_WAX is not set
 # CONFIG_EISA is not set
 # CONFIG_PCI is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
 # CONFIG_PCCARD is not set
 
-#
-# PCI Hotplug Support
-#
-
 #
 # PA-RISC specific drivers
 #
 CONFIG_CHASSIS_LCD_LED=y
 # CONFIG_PDC_CHASSIS is not set
+CONFIG_PDC_CHASSIS_WARN=y
 CONFIG_PDC_STABLE=y
 
 #
@@ -151,13 +166,15 @@ 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=m
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
 CONFIG_NET_KEY=m
+# CONFIG_NET_KEY_MIGRATE is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -174,17 +191,23 @@ CONFIG_IP_PNP_BOOTP=y
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
 # CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=m
 CONFIG_INET_TCP_DIAG=m
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
-
-#
-# IP: Virtual Server Configuration
-#
+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
 
@@ -192,37 +215,18 @@ CONFIG_NETFILTER=y
 # Core Netfilter Configuration
 #
 # CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NF_CONNTRACK_ENABLED is not set
+# CONFIG_NF_CONNTRACK is not set
 # CONFIG_NETFILTER_XTABLES is not set
 
 #
 # IP: Netfilter Configuration
 #
-CONFIG_IP_NF_CONNTRACK=m
-# CONFIG_IP_NF_CT_ACCT is not set
-CONFIG_IP_NF_CONNTRACK_MARK=y
-# 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_IP_NF_QUEUE=m
-
-#
-# 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
@@ -234,7 +238,6 @@ CONFIG_LLC2=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
 
@@ -250,7 +253,17 @@ CONFIG_NET_PKTGEN=m
 # CONFIG_HAMRADIO 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
@@ -259,39 +272,24 @@ CONFIG_NET_PKTGEN=m
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_STANDALONE is not set
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 CONFIG_FW_LOADER=y
 # 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 is not set
-
-#
-# Parallel port support
-#
 CONFIG_PARPORT=y
 CONFIG_PARPORT_PC=m
 # CONFIG_PARPORT_PC_FIFO is not set
 # CONFIG_PARPORT_PC_SUPERIO is not set
-CONFIG_PARPORT_NOT_PC=y
 CONFIG_PARPORT_GSC=y
+# CONFIG_PARPORT_AX88796 is not set
 # CONFIG_PARPORT_1284 is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
+CONFIG_PARPORT_NOT_PC=y
+CONFIG_BLK_DEV=y
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
@@ -300,13 +298,11 @@ CONFIG_BLK_DEV_CRYPTOLOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=6144
-CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_CDROM_PKTCDVD is not set
 CONFIG_ATA_OVER_ETH=m
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_IDE is not set
 
 #
@@ -314,6 +310,9 @@ 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
 
 #
@@ -333,104 +332,61 @@ CONFIG_CHR_DEV_SG=y
 # 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 Transport Attributes
+# SCSI Transports
 #
 CONFIG_SCSI_SPI_ATTRS=y
 # CONFIG_SCSI_FC_ATTRS is not set
 CONFIG_SCSI_ISCSI_ATTRS=m
-# CONFIG_SCSI_SAS_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
+# CONFIG_SCSI_SAS_LIBSAS is not set
+CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
-# CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_PPA is not set
 # CONFIG_SCSI_IMM is not set
 CONFIG_SCSI_LASI700=y
 CONFIG_53C700_LE_ON_BE=y
 # CONFIG_SCSI_ZALON is not set
 CONFIG_SCSI_DEBUG=m
-
-#
-# Multi-device support (RAID and LVM)
-#
+# CONFIG_ATA is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
 CONFIG_MD_RAID0=m
 CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_RAID6 is not set
+# CONFIG_MD_RAID456 is not set
 # CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 # CONFIG_BLK_DEV_DM is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Network device support
-#
 CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 CONFIG_BONDING=m
+# CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 CONFIG_TUN=m
-
-#
-# 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_LASI_82596=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_B44 is not set
 # CONFIG_NET_POCKET 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_ATMEL is not set
-# CONFIG_HOSTAP is not set
-
-#
-# Wan interfaces
+# Wireless LAN
 #
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
 # CONFIG_WAN is not set
 # CONFIG_PLIP is not set
 CONFIG_PPP=m
@@ -442,26 +398,22 @@ 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_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
 
 #
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
 
 #
 # Userland interfaces
@@ -486,14 +438,22 @@ CONFIG_KEYBOARD_ATKBD_HP_KEYCODES=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_HIL_OLD is not set
 CONFIG_KEYBOARD_HIL=y
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
 CONFIG_MOUSE_SERIAL=m
 # CONFIG_MOUSE_VSXXXAA is not set
 CONFIG_MOUSE_HIL=m
 # CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
@@ -516,6 +476,7 @@ CONFIG_SERIO_LIBPS2=y
 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
 
 #
@@ -523,6 +484,7 @@ CONFIG_HW_CONSOLE=y
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_GSC=y
 CONFIG_SERIAL_8250_NR_UARTS=17
 CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 CONFIG_SERIAL_8250_EXTENDED=y
@@ -545,36 +507,15 @@ CONFIG_PRINTER=m
 # CONFIG_LP_CONSOLE is not set
 CONFIG_PPDEV=m
 # CONFIG_TIPAR is not set
-
-#
-# IPMI
-#
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
 # CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
 CONFIG_GEN_RTC=y
 CONFIG_GEN_RTC_X=y
-# CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 CONFIG_RAW_DRIVER=y
 CONFIG_MAX_RAW_DEVS=256
-
-#
-# TPM devices
-#
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
-
-#
-# I2C support
-#
 # CONFIG_I2C is not set
 
 #
@@ -582,46 +523,59 @@ CONFIG_MAX_RAW_DEVS=256
 #
 # 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 is not set
-# CONFIG_HWMON_VID 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_SM501 is not set
 
 #
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
 
 #
-# Digital Video Broadcasting Devices
+# Graphics support
 #
-# CONFIG_DVB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
-# Graphics support
+# Display device support
 #
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
 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_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=y
 CONFIG_FB_TILEBLITTING=y
+
+#
+# Frame buffer hardware drivers
+#
 CONFIG_FB_STI=y
 # CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
@@ -633,6 +587,7 @@ CONFIG_DUMMY_CONSOLE=y
 CONFIG_DUMMY_CONSOLE_COLUMNS=128
 CONFIG_DUMMY_CONSOLE_ROWS=48
 CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
 # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
 CONFIG_STI_CONSOLE=y
 CONFIG_FONTS=y
@@ -646,16 +601,11 @@ 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=y
 # CONFIG_LOGO_LINUX_MONO is not set
 # CONFIG_LOGO_LINUX_VGA16 is not set
 # CONFIG_LOGO_LINUX_CLUT224 is not set
 CONFIG_LOGO_PARISC_CLUT224=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -673,9 +623,11 @@ CONFIG_SND_SEQUENCER=y
 CONFIG_SND_OSSEMUL=y
 CONFIG_SND_MIXER_OSS=y
 CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
 CONFIG_SND_SEQUENCER_OSS=y
 # CONFIG_SND_DYNAMIC_MINORS is not set
 CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
 
@@ -685,8 +637,10 @@ CONFIG_SND_SUPPORT_OLD_API=y
 # CONFIG_SND_DUMMY is not set
 # CONFIG_SND_VIRMIDI is not set
 # CONFIG_SND_MTPAV is not set
+# CONFIG_SND_MTS64 is not set
 # CONFIG_SND_SERIAL_U16550 is not set
 # CONFIG_SND_MPU401 is not set
+# CONFIG_SND_PORTMAN2X4 is not set
 
 #
 # GSC devices
@@ -694,15 +648,25 @@ CONFIG_SND_SUPPORT_OLD_API=y
 CONFIG_SND_HARMONY=y
 
 #
-# Open Sound System
+# System on Chip audio support
 #
-# CONFIG_SOUND_PRIME is not set
+# CONFIG_SND_SOC is not set
 
 #
-# USB support
+# SoC Audio support for SuperH
 #
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HID_DEBUG=y
+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'
@@ -712,19 +676,28 @@ CONFIG_SND_HARMONY=y
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_RTC_CLASS is not set
 
 #
-# MMC/SD Card support
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
 #
-# CONFIG_MMC is not set
 
 #
-# InfiniBand support
+# DMA Devices
 #
+# CONFIG_AUXDISPLAY is not set
 
 #
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+# Userspace I/O
 #
+# CONFIG_UIO is not set
 
 #
 # File systems
@@ -734,6 +707,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 # CONFIG_REISERFS_FS is not set
@@ -744,15 +718,16 @@ CONFIG_JFS_FS=m
 # CONFIG_JFS_STATISTICS is not set
 CONFIG_FS_POSIX_ACL=y
 CONFIG_XFS_FS=m
-CONFIG_XFS_EXPORT=y
 # 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_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
@@ -783,11 +758,12 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -795,6 +771,7 @@ CONFIG_RAMFS=y
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
@@ -806,6 +783,8 @@ CONFIG_RAMFS=y
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_SYSV_FS is not set
 CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
 
 #
 # Network File Systems
@@ -827,6 +806,7 @@ CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
+# CONFIG_SUNRPC_BIND34 is not set
 CONFIG_RPCSEC_GSS_KRB5=y
 CONFIG_RPCSEC_GSS_SPKM3=m
 CONFIG_SMB_FS=m
@@ -834,12 +814,13 @@ CONFIG_SMB_NLS_DEFAULT=y
 CONFIG_SMB_NLS_REMOTE="cp437"
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
 # CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_CIFS_EXPERIMENTAL is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
 
 #
 # Partition Types
@@ -891,6 +872,11 @@ CONFIG_NLS_KOI8_R=m
 CONFIG_NLS_KOI8_U=m
 CONFIG_NLS_UTF8=m
 
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
 #
 # Profiling support
 #
@@ -901,21 +887,32 @@ CONFIG_OPROFILE=m
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+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_LOG_BUF_SHIFT=16
+# CONFIG_DEBUG_SHIRQ is not set
 CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
 # CONFIG_DEBUG_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_LIST is not set
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
 CONFIG_DEBUG_RODATA=y
 
 #
@@ -924,12 +921,13 @@ CONFIG_DEBUG_RODATA=y
 CONFIG_KEYS=y
 CONFIG_KEYS_DEBUG_PROC_KEYS=y
 # CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=y
@@ -938,9 +936,18 @@ CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+# 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_CRYPTD is not set
 CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
@@ -949,21 +956,28 @@ CONFIG_CRYPTO_TEA=m
 CONFIG_CRYPTO_ARC4=m
 CONFIG_CRYPTO_KHAZAD=m
 CONFIG_CRYPTO_ANUBIS=m
+# CONFIG_CRYPTO_SEED is not set
 CONFIG_CRYPTO_DEFLATE=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_CAMELLIA is not set
 CONFIG_CRYPTO_TEST=m
-
-#
-# Hardware crypto devices
-#
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_HW is not set
 
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=m
 CONFIG_ZLIB_DEFLATE=m
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
index f3b812f04592bc3746cfba8f2f41a8edcd02436e..ea071218a3ed2cf68b4e1e98e7fa91ac2355101b 100644 (file)
@@ -1,73 +1,98 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14-rc5-pa1
-# Fri Oct 21 23:04:54 2005
+# Linux kernel version: 2.6.23
+# Fri Oct 12 21:12:44 2007
 #
 CONFIG_PARISC=y
 CONFIG_MMU=y
 CONFIG_STACK_GROWSUP=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
+CONFIG_TIME_LOW_RES=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
-# Code maturity level options
+# General setup
 #
 CONFIG_EXPERIMENTAL=y
-# CONFIG_CLEAN_COMPILE is not set
-CONFIG_BROKEN=y
-CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
 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_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
 # CONFIG_CPUSETS is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY 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 is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=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_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_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
 CONFIG_MODULES=y
 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
 CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_BLOCK_COMPAT=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
 
 #
 # Processor type and features
@@ -80,11 +105,23 @@ CONFIG_PA8X00=y
 CONFIG_PA20=y
 CONFIG_PREFETCH=y
 CONFIG_64BIT=y
+CONFIG_PARISC_PAGE_SIZE_4KB=y
+# CONFIG_PARISC_PAGE_SIZE_16KB is not set
+# CONFIG_PARISC_PAGE_SIZE_64KB is not set
 CONFIG_SMP=y
 CONFIG_HOTPLUG_CPU=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y
+CONFIG_NODES_SHIFT=3
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=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_SELECT_MEMORY_MODEL=y
@@ -95,7 +132,10 @@ CONFIG_DISCONTIGMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_NEED_MULTIPLE_NODES=y
 # CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_PREEMPT is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_RESOURCES_64BIT=y
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
 CONFIG_COMPAT=y
 CONFIG_NR_CPUS=8
 
@@ -104,7 +144,7 @@ CONFIG_NR_CPUS=8
 #
 # CONFIG_GSC is not set
 CONFIG_PCI=y
-CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 # CONFIG_PCI_DEBUG is not set
 CONFIG_PCI_LBA=y
 CONFIG_IOSAPIC=y
@@ -124,13 +164,14 @@ CONFIG_CARDBUS=y
 # PC-card bridges
 #
 CONFIG_YENTA=m
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
 CONFIG_PD6729=m
 CONFIG_I82092=m
 CONFIG_PCCARD_NONSTATIC=m
-
-#
-# PCI Hotplug Support
-#
 # CONFIG_HOTPLUG_PCI is not set
 
 #
@@ -139,6 +180,7 @@ CONFIG_PCCARD_NONSTATIC=m
 # CONFIG_SUPERIO is not set
 # CONFIG_CHASSIS_LCD_LED is not set
 CONFIG_PDC_CHASSIS=y
+CONFIG_PDC_CHASSIS_WARN=y
 CONFIG_PDC_STABLE=y
 
 #
@@ -160,7 +202,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_NET_KEY=m
+# CONFIG_NET_KEY_MIGRATE is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -177,97 +222,97 @@ CONFIG_IP_PNP_BOOTP=y
 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=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_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
 # CONFIG_IP_VS 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_TUNNEL=m
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_NETWORK_SECMARK is not set
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
+
+#
+# Core Netfilter Configuration
+#
 # CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NF_CONNTRACK_ENABLED 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_NFQUEUE is not set
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS 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_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_POLICY is not set
+# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
+# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
+# CONFIG_NETFILTER_XT_MATCH_REALM 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_NETFILTER_XT_MATCH_HASHLIMIT is not set
 
 #
 # IP: Netfilter Configuration
 #
-CONFIG_IP_NF_CONNTRACK=m
-# CONFIG_IP_NF_CT_ACCT is not set
-CONFIG_IP_NF_CONNTRACK_MARK=y
-# 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_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_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_AH is not set
 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 is not set
-# CONFIG_IP_NF_MATCH_REALM is not set
-CONFIG_IP_NF_MATCH_SCTP=m
-# CONFIG_IP_NF_MATCH_DCCP is not set
-CONFIG_IP_NF_MATCH_COMMENT=m
-CONFIG_IP_NF_MATCH_CONNMARK=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=m
 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=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_AMANDA=m
 CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_TOS=m
 CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_DSCP=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_CLASSIFY=m
 # CONFIG_IP_NF_TARGET_TTL is not set
-CONFIG_IP_NF_TARGET_CONNMARK=m
-CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_TARGET_NOTRACK=m
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
@@ -277,48 +322,38 @@ CONFIG_IP_NF_ARP_MANGLE=m
 #
 # CONFIG_IP6_NF_QUEUE is not set
 CONFIG_IP6_NF_IPTABLES=m
-# CONFIG_IP6_NF_MATCH_LIMIT is not set
-CONFIG_IP6_NF_MATCH_MAC=m
 CONFIG_IP6_NF_MATCH_RT=m
 CONFIG_IP6_NF_MATCH_OPTS=m
 CONFIG_IP6_NF_MATCH_FRAG=m
 CONFIG_IP6_NF_MATCH_HL=m
-# CONFIG_IP6_NF_MATCH_MULTIPORT is not set
 # CONFIG_IP6_NF_MATCH_OWNER is not set
-# CONFIG_IP6_NF_MATCH_MARK is not set
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-# CONFIG_IP6_NF_MATCH_AHESP is not set
-# CONFIG_IP6_NF_MATCH_LENGTH is not set
+# CONFIG_IP6_NF_MATCH_AH is not set
+# CONFIG_IP6_NF_MATCH_MH is not set
 # CONFIG_IP6_NF_MATCH_EUI64 is not set
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_LOG=m
 CONFIG_IP6_NF_TARGET_REJECT=m
-# 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=m
 CONFIG_INET_DCCP_DIAG=m
+CONFIG_IP_DCCP_ACKVEC=y
 
 #
 # DCCP CCIDs Configuration (EXPERIMENTAL)
 #
+CONFIG_IP_DCCP_CCID2=m
+# CONFIG_IP_DCCP_CCID2_DEBUG is not set
 # CONFIG_IP_DCCP_CCID3 is not set
 
 #
 # DCCP Kernel Hacking
 #
 # CONFIG_IP_DCCP_DEBUG 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_VLAN_8021Q is not set
@@ -329,11 +364,13 @@ CONFIG_LLC2=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 is not set
 
 #
 # Network testing
@@ -342,7 +379,17 @@ CONFIG_NET_PKTGEN=m
 # CONFIG_HAMRADIO 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
@@ -351,34 +398,17 @@ CONFIG_NET_PKTGEN=m
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_STANDALONE is not set
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 CONFIG_FW_LOADER=y
 # 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 is not set
-
-#
-# Parallel port support
-#
 # CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
+CONFIG_BLK_DEV=y
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
@@ -391,21 +421,14 @@ CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=6144
-CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+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_IDE is not set
 
 #
@@ -413,6 +436,9 @@ CONFIG_IOSCHED_CFQ=y
 #
 CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+CONFIG_SCSI_NETLINK=y
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -432,18 +458,18 @@ CONFIG_CHR_DEV_SG=y
 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=y
 CONFIG_SCSI_FC_ATTRS=m
 CONFIG_SCSI_ISCSI_ATTRS=m
-CONFIG_SCSI_SAS_ATTRS=m
-
-#
-# SCSI low-level drivers
-#
+# CONFIG_SCSI_SAS_LIBSAS 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
 # CONFIG_SCSI_ACARD is not set
@@ -451,59 +477,40 @@ CONFIG_SCSI_SAS_ATTRS=m
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_CPQFCTS is not set
+# CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
 CONFIG_SCSI_SYM53C8XX_2=y
 CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
-# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-CONFIG_SCSI_QLOGIC_FC=m
-# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
+CONFIG_SCSI_SYM53C8XX_MMIO=y
 CONFIG_SCSI_QLOGIC_1280=m
-# CONFIG_SCSI_QLOGIC_1280_1040 is not set
-CONFIG_SCSI_QLA2XXX=y
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-CONFIG_SCSI_QLA2300=m
-CONFIG_SCSI_QLA2322=m
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA24XX 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_DEBUG=m
-
-#
-# PCMCIA SCSI adapter support
-#
-CONFIG_PCMCIA_FDOMAIN=m
-CONFIG_PCMCIA_QLOGIC=m
-CONFIG_PCMCIA_SYM53C500=m
-
-#
-# Multi-device support (RAID and LVM)
-#
+# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
+# CONFIG_ATA is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=y
 CONFIG_MD_LINEAR=y
 CONFIG_MD_RAID0=y
 CONFIG_MD_RAID1=y
 # CONFIG_MD_RAID10 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_RAID6 is not set
+# CONFIG_MD_RAID456 is not set
 # CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 # CONFIG_BLK_DEV_DM is not set
@@ -517,39 +524,25 @@ CONFIG_FUSION_FC=m
 # CONFIG_FUSION_SAS is not set
 CONFIG_FUSION_MAX_SGE=128
 CONFIG_FUSION_CTL=m
+# CONFIG_FUSION_LOGGING is not set
 
 #
 # IEEE 1394 (FireWire) support
 #
+# CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
 # CONFIG_I2O is not set
-
-#
-# Network device support
-#
 CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 CONFIG_BONDING=m
+# CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 CONFIG_TUN=m
-
-#
-# ARCnet devices
-#
+# CONFIG_VETH is not set
+# CONFIG_IP1000 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=m
 # CONFIG_HAPPYMEAL is not set
@@ -558,10 +551,6 @@ CONFIG_MII=m
 CONFIG_NET_VENDOR_3COM=y
 CONFIG_VORTEX=m
 CONFIG_TYPHOON=m
-
-#
-# Tulip family network device support
-#
 CONFIG_NET_TULIP=y
 CONFIG_DE2104X=m
 CONFIG_TULIP=y
@@ -573,15 +562,18 @@ CONFIG_TULIP_MMIO=y
 # CONFIG_DM9102 is not set
 # CONFIG_ULI526X is not set
 CONFIG_PCMCIA_XIRCOM=m
-# CONFIG_PCMCIA_XIRTULIP is not set
 CONFIG_HP100=m
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
 CONFIG_NET_PCI=y
 CONFIG_PCNET32=m
+# CONFIG_PCNET32_NAPI 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=m
 # CONFIG_FEALNX is not set
@@ -593,84 +585,46 @@ CONFIG_E100=m
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
 # CONFIG_VIA_RHINE is not set
-
-#
-# Ethernet (1000 Mbit)
-#
+# CONFIG_SC92031 is not set
+CONFIG_NETDEV_1000=y
 CONFIG_ACENIC=m
 CONFIG_ACENIC_OMIT_TIGON_I=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=m
 CONFIG_E1000_NAPI=y
 # CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+# CONFIG_E1000E is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=m
 # CONFIG_BNX2 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
+# 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
-
-#
-# Token Ring devices
-#
+# 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_TR 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=m
-
-#
-# Wireless 802.11 Frequency Hopping cards support
-#
-CONFIG_PCMCIA_RAYCS=m
-
-#
-# Wireless 802.11b ISA/PCI cards support
-#
-CONFIG_HERMES=m
-CONFIG_PLX_HERMES=m
-CONFIG_TMD_HERMES=m
-# CONFIG_NORTEL_HERMES is not set
-CONFIG_PCI_HERMES=m
-# CONFIG_ATMEL is not set
-
-#
-# Wireless 802.11b Pcmcia/Cardbus cards support
-#
-CONFIG_PCMCIA_HERMES=m
-# CONFIG_PCMCIA_SPECTRUM is not set
-CONFIG_AIRO_CS=m
-CONFIG_PCMCIA_WL3501=m
-
-#
-# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
-#
-# CONFIG_PRISM54 is not set
-# CONFIG_HOSTAP is not set
-CONFIG_NET_WIRELESS=y
-
-#
-# PCMCIA network device support
+# Wireless LAN
 #
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
 CONFIG_NET_PCMCIA=y
 CONFIG_PCMCIA_3C589=m
 CONFIG_PCMCIA_3C574=m
@@ -680,10 +634,6 @@ CONFIG_PCMCIA_3C574=m
 CONFIG_PCMCIA_SMC91C92=m
 CONFIG_PCMCIA_XIRC2PS=m
 # CONFIG_PCMCIA_AXNET is not set
-
-#
-# Wan interfaces
-#
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -694,28 +644,25 @@ CONFIG_PPP_ASYNC=m
 CONFIG_PPP_SYNC_TTY=m
 CONFIG_PPP_DEFLATE=m
 CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPP_MPPE is not set
 # CONFIG_PPPOE is not set
+# CONFIG_PPPOL2TP is not set
 # CONFIG_SLIP is not set
+CONFIG_SLHC=m
 # 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
 
 #
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
 
 #
 # Userland interfaces
@@ -732,6 +679,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
 
@@ -747,6 +695,7 @@ CONFIG_INPUT=y
 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
 
 #
@@ -754,8 +703,10 @@ CONFIG_HW_CONSOLE=y
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
 CONFIG_SERIAL_8250_CS=m
 CONFIG_SERIAL_8250_NR_UARTS=17
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
@@ -765,83 +716,73 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
 #
 # Non-8250 serial port support
 #
-# CONFIG_SERIAL_MUX is not set
 CONFIG_PDC_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
-
-#
-# IPMI
-#
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
 # CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
 CONFIG_GEN_RTC=y
 CONFIG_GEN_RTC_X=y
-# CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
+CONFIG_AGP=y
+CONFIG_AGP_PARISC=y
 # CONFIG_DRM is not set
 
 #
 # PCMCIA character devices
 #
 # CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
 CONFIG_RAW_DRIVER=y
 CONFIG_MAX_RAW_DEVS=256
-
-#
-# TPM devices
-#
 # CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
+CONFIG_DEVPORT=y
 # CONFIG_I2C is not set
 
 #
-# Dallas's 1-wire bus
+# SPI support
 #
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
 # CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
+# CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
-# CONFIG_HWMON_VID 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_SM501 is not set
 
 #
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
 
 #
-# Digital Video Broadcasting Devices
+# Graphics support
 #
-# CONFIG_DVB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
-# Graphics support
+# Display device support
 #
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
 # CONFIG_FB is not set
 
 #
@@ -856,33 +797,46 @@ CONFIG_DUMMY_CONSOLE_ROWS=64
 # Sound
 #
 # CONFIG_SOUND is not set
-
-#
-# USB support
-#
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_USB is not set
 
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
 #
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_RTC_CLASS is not set
 
 #
-# MMC/SD Card support
+# DMA Engine support
 #
-# CONFIG_MMC is not set
+# CONFIG_DMA_ENGINE is not set
 
 #
-# InfiniBand support
+# DMA Clients
 #
-# CONFIG_INFINIBAND is not set
 
 #
-# SN Devices
+# DMA Devices
 #
 
+#
+# Userspace I/O
+#
+# CONFIG_UIO is not set
+
 #
 # File systems
 #
@@ -891,6 +845,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 # CONFIG_REISERFS_FS is not set
@@ -901,14 +856,16 @@ CONFIG_JFS_FS=m
 # CONFIG_JFS_STATISTICS is not set
 CONFIG_FS_POSIX_ACL=y
 CONFIG_XFS_FS=m
-CONFIG_XFS_EXPORT=y
 # 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_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
@@ -939,18 +896,20 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
-# CONFIG_HUGETLBFS is not set
+# 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
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
@@ -963,6 +922,7 @@ CONFIG_RAMFS=y
 # CONFIG_SYSV_FS is not set
 CONFIG_UFS_FS=m
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
 
 #
 # Network File Systems
@@ -983,6 +943,7 @@ CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
 CONFIG_SUNRPC_GSS=m
+# CONFIG_SUNRPC_BIND34 is not set
 CONFIG_RPCSEC_GSS_KRB5=m
 CONFIG_RPCSEC_GSS_SPKM3=m
 CONFIG_SMB_FS=m
@@ -990,12 +951,13 @@ CONFIG_SMB_NLS_DEFAULT=y
 CONFIG_SMB_NLS_REMOTE="cp437"
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
 # CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_CIFS_EXPERIMENTAL is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
 
 #
 # Partition Types
@@ -1047,6 +1009,11 @@ CONFIG_NLS_ISO8859_15=m
 # CONFIG_NLS_KOI8_U is not set
 CONFIG_NLS_UTF8=m
 
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
 #
 # Profiling support
 #
@@ -1057,19 +1024,34 @@ CONFIG_OPROFILE=m
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
-CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+CONFIG_HEADERS_CHECK=y
+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_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_IOREMAP is not set
-# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
 # CONFIG_DEBUG_RWLOCK is not set
+# CONFIG_DEBUG_RODATA is not set
 
 #
 # Security options
@@ -1077,12 +1059,13 @@ CONFIG_DETECT_SOFTLOCKUP=y
 CONFIG_KEYS=y
 CONFIG_KEYS_DEBUG_PROC_KEYS=y
 # CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
 CONFIG_CRYPTO_NULL=m
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
@@ -1091,32 +1074,47 @@ CONFIG_CRYPTO_SHA1=m
 # 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=m
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_DES=m
+# CONFIG_CRYPTO_FCRYPT is not set
 CONFIG_CRYPTO_BLOWFISH=m
 # 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_CAST5=m
 # CONFIG_CRYPTO_CAST6 is not set
 # CONFIG_CRYPTO_TEA is not set
 # CONFIG_CRYPTO_ARC4 is not set
 # CONFIG_CRYPTO_KHAZAD is not set
 # CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
 CONFIG_CRYPTO_DEFLATE=m
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_CAMELLIA is not set
 CONFIG_CRYPTO_TEST=m
-
-#
-# Hardware crypto devices
-#
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_HW is not set
 
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=m
 CONFIG_ZLIB_DEFLATE=m
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
index 35093612ad2c1e6808b0c180b0598db84d76b127..1bf22c9a461403f018a283e73b80d160b5358fbd 100644 (file)
@@ -1,38 +1,47 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc1-pa0
-# Tue Jan 17 08:21:01 2006
+# Linux kernel version: 2.6.23
+# Fri Oct 12 21:16:46 2007
 #
 CONFIG_PARISC=y
 CONFIG_MMU=y
 CONFIG_STACK_GROWSUP=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
-# Code maturity level options
+# General setup
 #
 # CONFIG_EXPERIMENTAL is not set
-CONFIG_CLEAN_COMPILE=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_SYSVIPC_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
-CONFIG_INITRAMFS_SOURCE=""
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -42,30 +51,27 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_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_VM_EVENT_COUNTERS=y
 CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
 CONFIG_MODULES=y
 # CONFIG_MODULE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
 CONFIG_MODVERSIONS=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 # CONFIG_KMOD is not set
-
-#
-# Block layer
-#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
 
 #
 # IO Schedulers
@@ -89,16 +95,26 @@ CONFIG_PA7100LC=y
 # CONFIG_PA7300LC is not set
 # CONFIG_PA8X00 is not set
 CONFIG_PA11=y
+CONFIG_PARISC_PAGE_SIZE_4KB=y
+# CONFIG_PARISC_PAGE_SIZE_16KB is not set
+# CONFIG_PARISC_PAGE_SIZE_64KB is not set
 # CONFIG_SMP is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
 # 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_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4096
-# CONFIG_PREEMPT is not set
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
 # CONFIG_HPUX is not set
 
 #
@@ -113,7 +129,7 @@ CONFIG_EISA=y
 CONFIG_EISA_NAMES=y
 CONFIG_ISA=y
 CONFIG_PCI=y
-CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 # CONFIG_PCI_DEBUG is not set
 CONFIG_GSC_DINO=y
 # CONFIG_PCI_LBA is not set
@@ -123,15 +139,12 @@ CONFIG_GSC_DINO=y
 #
 # CONFIG_PCCARD is not set
 
-#
-# PCI Hotplug Support
-#
-
 #
 # PA-RISC specific drivers
 #
 CONFIG_CHASSIS_LCD_LED=y
 # CONFIG_PDC_CHASSIS is not set
+CONFIG_PDC_CHASSIS_WARN=y
 CONFIG_PDC_STABLE=y
 
 #
@@ -151,6 +164,8 @@ CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -167,18 +182,32 @@ CONFIG_IP_PNP_BOOTP=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=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_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
 CONFIG_IPV6=y
 # CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
 # CONFIG_INET6_AH is not set
 # CONFIG_INET6_ESP is not set
 # CONFIG_INET6_IPCOMP is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
+CONFIG_IPV6_SIT=y
 # CONFIG_IPV6_TUNNEL is not set
+# CONFIG_NETLABEL is not set
+# CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_VLAN_8021Q is not set
@@ -199,7 +228,14 @@ CONFIG_IPV6=y
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
 # CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
 
 #
 # Device Drivers
@@ -208,39 +244,24 @@ CONFIG_IPV6=y
 #
 # 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
-
-#
-# 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 is not set
-
-#
-# Parallel port support
-#
 CONFIG_PARPORT=y
 CONFIG_PARPORT_PC=y
 # CONFIG_PARPORT_SERIAL is not set
-CONFIG_PARPORT_NOT_PC=y
 CONFIG_PARPORT_GSC=y
+# CONFIG_PARPORT_AX88796 is not set
 # CONFIG_PARPORT_1284 is not set
-
-#
-# Plug and Play support
-#
+CONFIG_PARPORT_NOT_PC=y
 # CONFIG_PNP is not set
-
-#
-# Block devices
-#
+CONFIG_BLK_DEV=y
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
@@ -251,15 +272,13 @@ CONFIG_BLK_DEV_CRYPTOLOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_RAM is not set
-CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_CDROM_PKTCDVD=m
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
 CONFIG_ATA_OVER_ETH=y
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_SGI_IOC4 is not set
 # CONFIG_IDE is not set
 
 #
@@ -267,6 +286,8 @@ CONFIG_ATA_OVER_ETH=y
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -286,18 +307,17 @@ CONFIG_CHR_DEV_SG=y
 # 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 Transport Attributes
+# SCSI Transports
 #
 CONFIG_SCSI_SPI_ATTRS=y
 # 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_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
@@ -308,12 +328,14 @@ CONFIG_SCSI_SPI_ATTRS=y
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_DTC3280 is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
@@ -327,23 +349,22 @@ CONFIG_SCSI_SPI_ATTRS=y
 # CONFIG_SCSI_NCR53C406A is not set
 CONFIG_SCSI_LASI700=y
 CONFIG_53C700_LE_ON_BE=y
+# CONFIG_SCSI_STEX is not set
 CONFIG_SCSI_SYM53C8XX_2=y
 CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
 CONFIG_SCSI_SYM53C8XX_MMIO=y
-# CONFIG_SCSI_IPR is not set
 CONFIG_SCSI_ZALON=y
 CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
 CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
 CONFIG_SCSI_NCR53C8XX_SYNC=40
-# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
 # CONFIG_SCSI_PAS16 is not set
 # CONFIG_SCSI_PSI240I is not set
 # CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_QLOGIC_FC 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_SIM710 is not set
 # CONFIG_SCSI_SYM53C416 is not set
@@ -351,22 +372,14 @@ CONFIG_SCSI_NCR53C8XX_SYNC=40
 # CONFIG_SCSI_T128 is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
-
-#
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
+# CONFIG_SCSI_SRP is not set
+# CONFIG_ATA is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=y
 CONFIG_MD_LINEAR=y
 CONFIG_MD_RAID0=y
 CONFIG_MD_RAID1=y
-CONFIG_MD_RAID5=y
-CONFIG_MD_RAID6=y
+# CONFIG_MD_RAID456 is not set
 # CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 # CONFIG_BLK_DEV_DM is not set
@@ -382,35 +395,21 @@ CONFIG_MD_RAID6=y
 #
 # IEEE 1394 (FireWire) support
 #
-# CONFIG_IEEE1394 is not set
 
 #
-# I2O device support
+# An alternative FireWire stack is available with EXPERIMENTAL=y
 #
+# CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
-
-#
-# Network device support
-#
 CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-
-#
-# ARCnet devices
-#
+# CONFIG_VETH is not set
 # CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
 # CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
 CONFIG_LASI_82596=y
@@ -420,10 +419,6 @@ CONFIG_LASI_82596=y
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_NET_VENDOR_RACAL is not set
-
-#
-# Tulip family network device support
-#
 CONFIG_NET_TULIP=y
 CONFIG_TULIP=y
 # CONFIG_TULIP_MMIO is not set
@@ -435,62 +430,47 @@ CONFIG_TULIP=y
 # CONFIG_DEPCA is not set
 # CONFIG_HP100 is not set
 # CONFIG_NET_ISA is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
 # CONFIG_NET_PCI is not set
+# CONFIG_B44 is not set
 # CONFIG_NET_POCKET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
+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_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
+# CONFIG_QLA3XXX 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
-
-#
-# Token Ring devices
-#
+# 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_TR is not set
 
 #
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-
-#
-# Obsolete Wireless cards support (pre-802.11)
-#
-# CONFIG_STRIP is not set
-# CONFIG_ARLAN is not set
-# CONFIG_WAVELAN is not set
-
-#
-# Wireless 802.11b ISA/PCI cards support
-#
-# CONFIG_HERMES is not set
-# CONFIG_ATMEL is not set
-
-#
-# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
-#
-# CONFIG_HOSTAP is not set
-CONFIG_NET_WIRELESS=y
-
-#
-# Wan interfaces
+# Wireless LAN
 #
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_PLIP is not set
@@ -501,24 +481,19 @@ CONFIG_PPP=y
 # CONFIG_PPP_DEFLATE is not set
 # CONFIG_PPP_BSDCOMP is not set
 # CONFIG_SLIP is not set
+CONFIG_SLHC=y
 # CONFIG_NET_FC is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
 # CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
 # CONFIG_PHONE is not set
 
 #
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
 
 #
 # Userland interfaces
@@ -543,19 +518,31 @@ CONFIG_KEYBOARD_ATKBD_HP_KEYCODES=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_HIL_OLD is not set
 CONFIG_KEYBOARD_HIL=y
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
 # CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
 # CONFIG_MOUSE_INPORT is not set
 # CONFIG_MOUSE_LOGIBM is not set
 # CONFIG_MOUSE_PC110PAD is not set
 # CONFIG_MOUSE_VSXXXAA is not set
 CONFIG_MOUSE_HIL=y
 # CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_POWERMATE is not set
 # CONFIG_INPUT_UINPUT is not set
 # CONFIG_HP_SDC_RTC is not set
 
@@ -579,6 +566,7 @@ CONFIG_SERIO_LIBPS2=y
 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
 
 #
@@ -586,17 +574,20 @@ CONFIG_HW_CONSOLE=y
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_GSC=y
+CONFIG_SERIAL_8250_PCI=y
 CONFIG_SERIAL_8250_NR_UARTS=13
 CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_RSA is not set
 # CONFIG_SERIAL_8250_FOURPORT is not set
 # CONFIG_SERIAL_8250_ACCENT is not set
 # CONFIG_SERIAL_8250_BOCA is not set
+# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set
 # CONFIG_SERIAL_8250_HUB6 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
@@ -605,6 +596,7 @@ CONFIG_SERIAL_MUX=y
 CONFIG_SERIAL_MUX_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -612,35 +604,18 @@ CONFIG_PRINTER=y
 # CONFIG_LP_CONSOLE is not set
 # CONFIG_PPDEV is not set
 # CONFIG_TIPAR is not set
-
-#
-# IPMI
-#
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
 # CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
 CONFIG_GEN_RTC=y
 # CONFIG_GEN_RTC_X 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_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
-
-#
-# I2C support
-#
+CONFIG_DEVPORT=y
 # CONFIG_I2C is not set
 
 #
@@ -648,46 +623,59 @@ CONFIG_GEN_RTC=y
 #
 # CONFIG_SPI is not set
 # CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
 # CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
+# CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
-# CONFIG_HWMON_VID 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_SM501 is not set
 
 #
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
 
 #
-# Digital Video Broadcasting Devices
+# Graphics support
 #
-# CONFIG_DVB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
-# Graphics support
+# Display device support
 #
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
 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_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_CIRRUS is not set
 # CONFIG_FB_PM2 is not set
 # CONFIG_FB_CYBER2000 is not set
@@ -698,16 +686,18 @@ CONFIG_FB_STI=y
 # CONFIG_FB_NVIDIA is not set
 # CONFIG_FB_RIVA is not set
 # CONFIG_FB_MATROX is not set
-# CONFIG_FB_RADEON_OLD is not set
 # CONFIG_FB_RADEON is not set
 # CONFIG_FB_ATY128 is not set
 # CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
 # CONFIG_FB_SIS is not set
 # CONFIG_FB_NEOMAGIC is not set
 # CONFIG_FB_KYRO is not set
 # CONFIG_FB_3DFX is not set
 # CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
 # CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -717,21 +707,17 @@ CONFIG_DUMMY_CONSOLE=y
 CONFIG_DUMMY_CONSOLE_COLUMNS=160
 CONFIG_DUMMY_CONSOLE_ROWS=64
 CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
 # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
 CONFIG_STI_CONSOLE=y
 # CONFIG_FONTS is not set
 CONFIG_FONT_8x8=y
 CONFIG_FONT_8x16=y
-
-#
-# Logo configuration
-#
 CONFIG_LOGO=y
 CONFIG_LOGO_LINUX_MONO=y
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
 CONFIG_LOGO_PARISC_CLUT224=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -749,8 +735,11 @@ CONFIG_SND_SEQUENCER=y
 CONFIG_SND_OSSEMUL=y
 CONFIG_SND_MIXER_OSS=y
 CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
 CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
 CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
 
@@ -760,13 +749,16 @@ CONFIG_SND_SUPPORT_OLD_API=y
 # CONFIG_SND_DUMMY is not set
 # CONFIG_SND_VIRMIDI is not set
 # CONFIG_SND_MTPAV is not set
+# CONFIG_SND_MTS64 is not set
 # CONFIG_SND_SERIAL_U16550 is not set
 # CONFIG_SND_MPU401 is not set
+# CONFIG_SND_PORTMAN2X4 is not set
 
 #
 # PCI devices
 #
 # CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALS300 is not set
 # CONFIG_SND_ALI5451 is not set
 # CONFIG_SND_ATIIXP is not set
 # CONFIG_SND_ATIIXP_MODEM is not set
@@ -778,6 +770,18 @@ CONFIG_SND_SUPPORT_OLD_API=y
 # CONFIG_SND_CMIPCI is not set
 # CONFIG_SND_CS4281 is not set
 # CONFIG_SND_CS46XX is not set
+# CONFIG_SND_DARLA20 is not set
+# CONFIG_SND_GINA20 is not set
+# CONFIG_SND_LAYLA20 is not set
+# CONFIG_SND_DARLA24 is not set
+# CONFIG_SND_GINA24 is not set
+# CONFIG_SND_LAYLA24 is not set
+# CONFIG_SND_MONA is not set
+# CONFIG_SND_MIA is not set
+# CONFIG_SND_ECHO3G is not set
+# CONFIG_SND_INDIGO is not set
+# CONFIG_SND_INDIGOIO is not set
+# CONFIG_SND_INDIGODJ is not set
 # CONFIG_SND_EMU10K1 is not set
 # CONFIG_SND_EMU10K1X is not set
 # CONFIG_SND_ENS1370 is not set
@@ -791,11 +795,13 @@ CONFIG_SND_SUPPORT_OLD_API=y
 # CONFIG_SND_ICE1712 is not set
 # CONFIG_SND_ICE1724 is not set
 # CONFIG_SND_INTEL8X0 is not set
+# CONFIG_SND_INTEL8X0M is not set
 # CONFIG_SND_KORG1212 is not set
 # CONFIG_SND_MAESTRO3 is not set
 # CONFIG_SND_MIXART is not set
 # CONFIG_SND_NM256 is not set
 # CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RIPTIDE is not set
 # CONFIG_SND_RME32 is not set
 # CONFIG_SND_RME96 is not set
 # CONFIG_SND_RME9652 is not set
@@ -812,15 +818,25 @@ CONFIG_SND_SUPPORT_OLD_API=y
 CONFIG_SND_HARMONY=y
 
 #
-# Open Sound System
+# System on Chip audio support
 #
-# CONFIG_SOUND_PRIME is not set
+# CONFIG_SND_SOC is not set
 
 #
-# USB support
+# SoC Audio support for SuperH
+#
+
+#
+# Open Sound System
 #
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HID_DEBUG=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
 
 #
@@ -831,20 +847,29 @@ CONFIG_USB_ARCH_HAS_OHCI=y
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_RTC_CLASS is not set
 
 #
-# MMC/SD Card support
+# DMA Engine support
 #
-# CONFIG_MMC is not set
+# CONFIG_DMA_ENGINE is not set
 
 #
-# InfiniBand support
+# DMA Clients
 #
-# CONFIG_INFINIBAND is not set
 
 #
-# SN Devices
+# DMA Devices
 #
+# CONFIG_AUXDISPLAY is not set
+
+#
+# Userspace I/O
+#
+# CONFIG_UIO is not set
 
 #
 # File systems
@@ -860,9 +885,11 @@ CONFIG_JBD=y
 # 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_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
@@ -889,11 +916,12 @@ CONFIG_JOLIET=y
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -912,6 +940,7 @@ CONFIG_RAMFS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_DIRECTIO is not set
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V3_ACL is not set
@@ -982,22 +1011,32 @@ CONFIG_NLS_UTF8=m
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+CONFIG_HEADERS_CHECK=y
 CONFIG_DEBUG_KERNEL=y
-CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_DEBUG_SHIRQ is not set
 CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_IOREMAP is not set
-# CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
 # CONFIG_DEBUG_RODATA is not set
 
 #
@@ -1007,13 +1046,10 @@ CONFIG_FORCED_INLINING=y
 CONFIG_SECURITY=y
 # CONFIG_SECURITY_NETWORK is not set
 CONFIG_SECURITY_CAPABILITIES=y
-# CONFIG_SECURITY_SECLVL is not set
-# CONFIG_SECURITY_SELINUX is not set
-
-#
-# Cryptographic options
-#
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
@@ -1023,7 +1059,12 @@ CONFIG_CRYPTO=y
 # 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=y
+# CONFIG_CRYPTO_PCBC 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
@@ -1034,19 +1075,26 @@ CONFIG_CRYPTO=y
 # CONFIG_CRYPTO_ARC4 is not set
 # CONFIG_CRYPTO_KHAZAD is not set
 # CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
 # CONFIG_CRYPTO_TEST is not set
-
-#
-# Hardware crypto devices
-#
+# CONFIG_CRYPTO_AUTHENC is not set
+CONFIG_CRYPTO_HW=y
 
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
index eb2f9a3d515c4ec6925b30eb034888a67688541b..c6def3c1d2093725de6cf8e428cf5b43cf78864c 100644 (file)
@@ -1,39 +1,50 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-pa6
-# Sun Mar 26 20:03:29 2006
+# Linux kernel version: 2.6.23
+# Fri Oct 12 21:24:00 2007
 #
 CONFIG_PARISC=y
 CONFIG_MMU=y
 CONFIG_STACK_GROWSUP=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_IRQ_PER_CPU=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_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
-CONFIG_INITRAMFS_SOURCE=""
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -43,31 +54,29 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_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_VM_EVENT_COUNTERS=y
 CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=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
 
 #
 # IO Schedulers
@@ -93,6 +102,9 @@ CONFIG_PA8X00=y
 CONFIG_PA20=y
 CONFIG_PREFETCH=y
 # CONFIG_64BIT is not set
+CONFIG_PARISC_PAGE_SIZE_4KB=y
+# CONFIG_PARISC_PAGE_SIZE_16KB is not set
+# CONFIG_PARISC_PAGE_SIZE_64KB is not set
 # CONFIG_SMP is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
 # CONFIG_PREEMPT_NONE is not set
@@ -100,6 +112,7 @@ CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
 # 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_SELECT_MEMORY_MODEL=y
@@ -110,6 +123,9 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC 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_HPUX is not set
 
 #
@@ -117,7 +133,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 #
 # CONFIG_GSC is not set
 CONFIG_PCI=y
-CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 # CONFIG_PCI_DEBUG is not set
 CONFIG_PCI_LBA=y
 CONFIG_IOSAPIC=y
@@ -127,10 +143,6 @@ CONFIG_IOMMU_SBA=y
 # PCCARD (PCMCIA/CardBus) support
 #
 # CONFIG_PCCARD is not set
-
-#
-# PCI Hotplug Support
-#
 # CONFIG_HOTPLUG_PCI is not set
 
 #
@@ -139,6 +151,7 @@ CONFIG_IOMMU_SBA=y
 CONFIG_SUPERIO=y
 CONFIG_CHASSIS_LCD_LED=y
 # CONFIG_PDC_CHASSIS is not set
+CONFIG_PDC_CHASSIS_WARN=y
 CONFIG_PDC_STABLE=y
 
 #
@@ -155,13 +168,15 @@ 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=m
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
 CONFIG_NET_KEY=m
+# CONFIG_NET_KEY_MIGRATE is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -178,22 +193,36 @@ CONFIG_IP_PNP_BOOTP=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 is not set
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
-
-#
-# IP: Virtual Server Configuration
-#
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
 # CONFIG_IP_VS 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 is not set
 # CONFIG_INET6_ESP is not set
 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_TUNNEL=m
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_NETWORK_SECMARK is not set
 CONFIG_NETFILTER=y
 CONFIG_NETFILTER_DEBUG=y
 
@@ -201,42 +230,24 @@ CONFIG_NETFILTER_DEBUG=y
 # Core Netfilter Configuration
 #
 # CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NF_CONNTRACK_ENABLED is not set
+# CONFIG_NF_CONNTRACK is not set
 # CONFIG_NETFILTER_XTABLES 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 is not set
-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_IP_NF_QUEUE=m
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
 
 #
 # IPv6: Netfilter Configuration (EXPERIMENTAL)
 #
 # CONFIG_IP6_NF_QUEUE is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
+# CONFIG_IP6_NF_IPTABLES 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
@@ -247,7 +258,6 @@ CONFIG_IP_NF_QUEUE=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
 
@@ -263,7 +273,17 @@ CONFIG_NET_PKTGEN=m
 # CONFIG_HAMRADIO 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
@@ -272,33 +292,17 @@ CONFIG_NET_PKTGEN=m
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_STANDALONE is not set
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 CONFIG_FW_LOADER=y
 # 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 is not set
-
-#
-# Parallel port support
-#
 # CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
+CONFIG_BLK_DEV=y
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
@@ -310,14 +314,15 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m
 # CONFIG_BLK_DEV_SX8 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_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
 CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
 CONFIG_BLK_DEV_IDE=y
 
 #
@@ -331,19 +336,26 @@ CONFIG_BLK_DEV_IDECD=y
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 CONFIG_BLK_DEV_IDESCSI=y
 # CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_PROC_FS=y
 
 #
 # IDE chipset support/bugfixes
 #
 CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_PLATFORM is not set
+
+#
+# PCI IDE chipsets support
+#
 CONFIG_BLK_DEV_IDEPCI=y
 CONFIG_IDEPCI_SHARE_IRQ=y
+CONFIG_IDEPCI_PCIBUS_ORDER=y
 # CONFIG_BLK_DEV_OFFBOARD is not set
 # CONFIG_BLK_DEV_GENERIC is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
 CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-# CONFIG_IDEDMA_PCI_AUTO is not set
+CONFIG_IDEDMA_ONLYDISK=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
 # CONFIG_BLK_DEV_AMD74XX is not set
@@ -354,8 +366,10 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_CS5530 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT8213 is not set
 # CONFIG_BLK_DEV_IT821X is not set
 CONFIG_BLK_DEV_NS87415=y
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
@@ -365,10 +379,10 @@ CONFIG_BLK_DEV_SIIMAGE=m
 # 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_IDE_ARM is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_IVB is not set
-# CONFIG_IDEDMA_AUTO is not set
 # CONFIG_BLK_DEV_HD is not set
 
 #
@@ -376,6 +390,9 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 # 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
 
 #
@@ -395,18 +412,17 @@ CONFIG_CHR_DEV_SG=y
 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=y
 # CONFIG_SCSI_FC_ATTRS is not set
 CONFIG_SCSI_ISCSI_ATTRS=m
-# CONFIG_SCSI_SAS_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
+# CONFIG_SCSI_SAS_LIBSAS 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
@@ -415,66 +431,53 @@ CONFIG_SCSI_ISCSI_ATTRS=m
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-CONFIG_SCSI_SATA=y
-# CONFIG_SCSI_SATA_AHCI is not set
-# CONFIG_SCSI_SATA_SVW is not set
-CONFIG_SCSI_ATA_PIIX=m
-# CONFIG_SCSI_SATA_MV is not set
-# CONFIG_SCSI_SATA_NV is not set
-# CONFIG_SCSI_PDC_ADMA is not set
-# CONFIG_SCSI_SATA_QSTOR is not set
-CONFIG_SCSI_SATA_PROMISE=m
-# CONFIG_SCSI_SATA_SX4 is not set
-CONFIG_SCSI_SATA_SIL=m
-# CONFIG_SCSI_SATA_SIL24 is not set
-# CONFIG_SCSI_SATA_SIS is not set
-# CONFIG_SCSI_SATA_ULI is not set
-CONFIG_SCSI_SATA_VIA=m
-# CONFIG_SCSI_SATA_VITESSE is not set
+# CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
 CONFIG_SCSI_SYM53C8XX_2=y
 CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
 CONFIG_SCSI_SYM53C8XX_MMIO=y
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_FC 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=m
-
-#
-# Multi-device support (RAID and LVM)
-#
+# CONFIG_SCSI_SRP is not set
+# CONFIG_ATA is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=y
 CONFIG_MD_LINEAR=y
 CONFIG_MD_RAID0=y
 CONFIG_MD_RAID1=y
 # CONFIG_MD_RAID10 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_RAID6 is not set
+# CONFIG_MD_RAID456 is not set
 # CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
+# CONFIG_DM_DEBUG is not set
 CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
 # CONFIG_DM_MULTIPATH_EMC is not set
+# CONFIG_DM_MULTIPATH_RDAC is not set
+# CONFIG_DM_DELAY is not set
 
 #
 # Fusion MPT device support
@@ -485,49 +488,31 @@ CONFIG_FUSION_SPI=m
 # CONFIG_FUSION_SAS is not set
 CONFIG_FUSION_MAX_SGE=128
 CONFIG_FUSION_CTL=m
+# CONFIG_FUSION_LOGGING is not set
 
 #
 # IEEE 1394 (FireWire) support
 #
+# CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
 # CONFIG_I2O is not set
-
-#
-# Network device support
-#
 CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 CONFIG_BONDING=m
+# CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 CONFIG_TUN=m
-
-#
-# ARCnet devices
-#
+# CONFIG_VETH is not set
+# CONFIG_IP1000 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=m
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
-
-#
-# Tulip family network device support
-#
 CONFIG_NET_TULIP=y
 CONFIG_DE2104X=m
 CONFIG_TULIP=y
@@ -539,13 +524,16 @@ CONFIG_TULIP_MMIO=y
 # CONFIG_DM9102 is not set
 # CONFIG_ULI526X is not set
 # CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
 CONFIG_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=m
 # CONFIG_FEALNX is not set
@@ -558,16 +546,15 @@ CONFIG_E100=m
 # 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_NETDEV_1000=y
 CONFIG_ACENIC=m
 # CONFIG_ACENIC_OMIT_TIGON_I is not set
 # CONFIG_DL2K is not set
 CONFIG_E1000=m
 # CONFIG_E1000_NAPI is not set
 # CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+# CONFIG_E1000E is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -579,27 +566,36 @@ CONFIG_E1000=m
 # CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=m
 # CONFIG_BNX2 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
+# 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
-
-#
-# Token Ring devices
-#
+# 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_TR is not set
 
 #
-# Wireless LAN (non-hamradio)
+# Wireless LAN
 #
-# CONFIG_NET_RADIO is not set
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
 
 #
-# Wan interfaces
+# USB Network Adapters
 #
+# CONFIG_USB_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_MII is not set
+# CONFIG_USB_USBNET is not set
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -612,27 +608,23 @@ CONFIG_PPP_DEFLATE=m
 CONFIG_PPP_BSDCOMP=m
 # CONFIG_PPP_MPPE is not set
 CONFIG_PPPOE=m
+# CONFIG_PPPOL2TP is not set
 # CONFIG_SLIP is not set
+CONFIG_SLHC=m
 # CONFIG_NET_FC is not set
 # CONFIG_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
 
 #
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
 
 #
 # Userland interfaces
@@ -655,11 +647,14 @@ 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_INPUT_MOUSE=y
 # CONFIG_MOUSE_PS2 is not set
 # CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
 # CONFIG_MOUSE_VSXXXAA is not set
 # CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
@@ -679,6 +674,7 @@ CONFIG_SERIO_LIBPS2=m
 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
 
 #
@@ -686,6 +682,7 @@ CONFIG_HW_CONSOLE=y
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
 CONFIG_SERIAL_8250_NR_UARTS=13
 CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 CONFIG_SERIAL_8250_EXTENDED=y
@@ -704,38 +701,19 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
 # CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
 CONFIG_GEN_RTC=y
 CONFIG_GEN_RTC_X=y
-# CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
+# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 CONFIG_RAW_DRIVER=y
 CONFIG_MAX_RAW_DEVS=256
-
-#
-# TPM devices
-#
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
-
-#
-# I2C support
-#
+CONFIG_DEVPORT=y
 # CONFIG_I2C is not set
 
 #
@@ -743,46 +721,59 @@ CONFIG_MAX_RAW_DEVS=256
 #
 # 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 is not set
-# CONFIG_HWMON_VID 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_SM501 is not set
 
 #
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
 
 #
-# Digital Video Broadcasting Devices
+# Graphics support
 #
-# CONFIG_DVB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
-# Graphics support
+# Display device support
 #
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
 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_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_CIRRUS is not set
 # CONFIG_FB_PM2 is not set
 # CONFIG_FB_CYBER2000 is not set
@@ -793,17 +784,20 @@ CONFIG_FB_STI=y
 # CONFIG_FB_NVIDIA is not set
 # CONFIG_FB_RIVA is not set
 # CONFIG_FB_MATROX is not set
-# CONFIG_FB_RADEON_OLD is not set
 # CONFIG_FB_RADEON is not set
 # CONFIG_FB_ATY128 is not set
 # CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
 # CONFIG_FB_SAVAGE is not set
 # CONFIG_FB_SIS is not set
 # CONFIG_FB_NEOMAGIC is not set
 # CONFIG_FB_KYRO is not set
 # CONFIG_FB_3DFX is not set
 # CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
 # CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -813,21 +807,17 @@ CONFIG_DUMMY_CONSOLE=y
 CONFIG_DUMMY_CONSOLE_COLUMNS=160
 CONFIG_DUMMY_CONSOLE_ROWS=64
 CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
 # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
 CONFIG_STI_CONSOLE=y
 # CONFIG_FONTS is not set
 CONFIG_FONT_8x8=y
 CONFIG_FONT_8x16=y
-
-#
-# Logo configuration
-#
 CONFIG_LOGO=y
 # CONFIG_LOGO_LINUX_MONO is not set
 # CONFIG_LOGO_LINUX_VGA16 is not set
 # CONFIG_LOGO_LINUX_CLUT224 is not set
 CONFIG_LOGO_PARISC_CLUT224=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -845,9 +835,11 @@ CONFIG_SND_SEQUENCER=y
 CONFIG_SND_OSSEMUL=y
 CONFIG_SND_MIXER_OSS=y
 CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
 CONFIG_SND_SEQUENCER_OSS=y
 # CONFIG_SND_DYNAMIC_MINORS is not set
 CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
 
@@ -855,7 +847,6 @@ CONFIG_SND_SUPPORT_OLD_API=y
 # Generic devices
 #
 CONFIG_SND_AC97_CODEC=y
-CONFIG_SND_AC97_BUS=y
 # CONFIG_SND_DUMMY is not set
 # CONFIG_SND_VIRMIDI is not set
 # CONFIG_SND_MTPAV is not set
@@ -866,7 +857,7 @@ CONFIG_SND_AC97_BUS=y
 # PCI devices
 #
 CONFIG_SND_AD1889=y
-# CONFIG_SND_AD1889_OPL3 is not set
+# CONFIG_SND_ALS300 is not set
 # CONFIG_SND_ALI5451 is not set
 # CONFIG_SND_ATIIXP is not set
 # CONFIG_SND_ATIIXP_MODEM is not set
@@ -879,6 +870,18 @@ CONFIG_SND_AD1889=y
 # CONFIG_SND_CMIPCI is not set
 # CONFIG_SND_CS4281 is not set
 # CONFIG_SND_CS46XX is not set
+# CONFIG_SND_DARLA20 is not set
+# CONFIG_SND_GINA20 is not set
+# CONFIG_SND_LAYLA20 is not set
+# CONFIG_SND_DARLA24 is not set
+# CONFIG_SND_GINA24 is not set
+# CONFIG_SND_LAYLA24 is not set
+# CONFIG_SND_MONA is not set
+# CONFIG_SND_MIA is not set
+# CONFIG_SND_ECHO3G is not set
+# CONFIG_SND_INDIGO is not set
+# CONFIG_SND_INDIGOIO is not set
+# CONFIG_SND_INDIGODJ is not set
 # CONFIG_SND_EMU10K1 is not set
 # CONFIG_SND_EMU10K1X is not set
 # CONFIG_SND_ENS1370 is not set
@@ -898,6 +901,7 @@ CONFIG_SND_AD1889=y
 # CONFIG_SND_MIXART is not set
 # CONFIG_SND_NM256 is not set
 # CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RIPTIDE is not set
 # CONFIG_SND_RME32 is not set
 # CONFIG_SND_RME96 is not set
 # CONFIG_SND_RME9652 is not set
@@ -907,22 +911,43 @@ CONFIG_SND_AD1889=y
 # CONFIG_SND_VIA82XX_MODEM is not set
 # CONFIG_SND_VX222 is not set
 # CONFIG_SND_YMFPCI is not set
+# CONFIG_SND_AC97_POWER_SAVE is not set
 
 #
 # USB devices
 #
 # CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
+
+#
+# System on Chip audio support
+#
+# CONFIG_SND_SOC is not set
+
+#
+# SoC Audio support for SuperH
+#
 
 #
 # Open Sound System
 #
 # CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=y
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
 
 #
-# USB support
+# USB Input Devices
 #
+CONFIG_USB_HID=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+CONFIG_USB_HIDDEV=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=y
 
@@ -930,7 +955,7 @@ CONFIG_USB_DEBUG=y
 # 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
 
@@ -940,15 +965,16 @@ CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_EHCI_HCD is not set
 # CONFIG_USB_ISP116X_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_OBSOLETE_OSS_USB_DRIVER is not set
 # CONFIG_USB_ACM is not set
 CONFIG_USB_PRINTER=m
 
@@ -970,54 +996,14 @@ CONFIG_USB_STORAGE_SDDR09=y
 CONFIG_USB_STORAGE_SDDR55=y
 CONFIG_USB_STORAGE_JUMPSHOT=y
 # CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
 # CONFIG_USB_LIBUSUAL is not set
 
-#
-# USB Input Devices
-#
-CONFIG_USB_HID=y
-CONFIG_USB_HIDINPUT=y
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-# CONFIG_HID_FF is not set
-CONFIG_USB_HIDDEV=y
-# 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_MTOUCH is not set
-# CONFIG_USB_ITMTOUCH is not set
-# CONFIG_USB_EGALAX 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=m
 CONFIG_USB_MICROTEK=m
-
-#
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
-#
-# 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_USB_MON is not set
 
 #
@@ -1034,16 +1020,22 @@ CONFIG_USB_MICROTEK=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_RIO500 is not set
 CONFIG_USB_LEGOTOWER=m
 # 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_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO 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_TEST is not set
 
 #
@@ -1054,21 +1046,29 @@ CONFIG_USB_LEGOTOWER=m
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_RTC_CLASS is not set
 
 #
-# MMC/SD Card support
+# DMA Engine support
 #
-# CONFIG_MMC is not set
+# CONFIG_DMA_ENGINE is not set
 
 #
-# InfiniBand support
+# DMA Clients
 #
-# CONFIG_INFINIBAND is not set
 
 #
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+# DMA Devices
 #
 
+#
+# Userspace I/O
+#
+# CONFIG_UIO is not set
+
 #
 # File systems
 #
@@ -1077,21 +1077,23 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 CONFIG_XFS_FS=m
-CONFIG_XFS_EXPORT=y
 # 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_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
@@ -1121,11 +1123,12 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -1164,6 +1167,7 @@ CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=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
@@ -1171,7 +1175,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
@@ -1223,6 +1226,11 @@ CONFIG_NLS_ISO8859_15=m
 # CONFIG_NLS_KOI8_U is not set
 CONFIG_NLS_UTF8=m
 
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
 #
 # Profiling support
 #
@@ -1233,21 +1241,32 @@ CONFIG_OPROFILE=m
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+CONFIG_HEADERS_CHECK=y
 CONFIG_DEBUG_KERNEL=y
-CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_DEBUG_SHIRQ is not set
 CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
 # CONFIG_DEBUG_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_LIST is not set
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
 CONFIG_DEBUG_RODATA=y
 
 #
@@ -1255,12 +1274,12 @@ CONFIG_DEBUG_RODATA=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_MANAGER=m
 # CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
 CONFIG_CRYPTO_NULL=m
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=m
@@ -1269,7 +1288,15 @@ CONFIG_CRYPTO_MD5=m
 # 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=m
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_DES=m
+# CONFIG_CRYPTO_FCRYPT is not set
 CONFIG_CRYPTO_BLOWFISH=m
 # CONFIG_CRYPTO_TWOFISH is not set
 # CONFIG_CRYPTO_SERPENT is not set
@@ -1280,21 +1307,28 @@ CONFIG_CRYPTO_BLOWFISH=m
 # CONFIG_CRYPTO_ARC4 is not set
 # CONFIG_CRYPTO_KHAZAD is not set
 # CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
 CONFIG_CRYPTO_DEFLATE=m
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_CAMELLIA is not set
 CONFIG_CRYPTO_TEST=m
-
-#
-# Hardware crypto devices
-#
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_HW is not set
 
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=m
 CONFIG_ZLIB_DEFLATE=m
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
index b38b58eb9dc2062d71e2cf659cfcaf76046b548f..448a757b06c68d7b9eaa41d6020f4c4c3a15f5e6 100644 (file)
@@ -1,39 +1,51 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-pa10
-# Sun Apr  2 15:26:38 2006
+# Linux kernel version: 2.6.23
+# Fri Oct 12 20:54:57 2007
 #
 CONFIG_PARISC=y
 CONFIG_MMU=y
 CONFIG_STACK_GROWSUP=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_IRQ_PER_CPU=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_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -43,31 +55,29 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_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_VM_EVENT_COUNTERS=y
 CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=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
 
 #
 # IO Schedulers
@@ -101,6 +111,7 @@ CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
 # 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_SELECT_MEMORY_MODEL=y
@@ -111,6 +122,9 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
 # CONFIG_HPUX is not set
 
 #
@@ -125,7 +139,7 @@ CONFIG_EISA=y
 CONFIG_EISA_NAMES=y
 # CONFIG_ISA is not set
 CONFIG_PCI=y
-CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 # CONFIG_PCI_DEBUG is not set
 CONFIG_GSC_DINO=y
 CONFIG_PCI_LBA=y
@@ -154,10 +168,6 @@ CONFIG_YENTA_TOSHIBA=y
 CONFIG_PD6729=y
 CONFIG_I82092=y
 CONFIG_PCCARD_NONSTATIC=y
-
-#
-# PCI Hotplug Support
-#
 # CONFIG_HOTPLUG_PCI is not set
 
 #
@@ -166,6 +176,7 @@ CONFIG_PCCARD_NONSTATIC=y
 CONFIG_SUPERIO=y
 CONFIG_CHASSIS_LCD_LED=y
 CONFIG_PDC_CHASSIS=y
+CONFIG_PDC_CHASSIS_WARN=y
 CONFIG_PDC_STABLE=y
 
 #
@@ -182,13 +193,15 @@ 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=m
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
 CONFIG_NET_KEY=m
+# CONFIG_NET_KEY_MIGRATE is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -205,33 +218,39 @@ CONFIG_IP_PNP_BOOTP=y
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
 # CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
+# CONFIG_INET_XFRM_TUNNEL is not set
+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_BIC=y
+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_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES 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
@@ -243,7 +262,6 @@ CONFIG_LLC2=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
 
@@ -259,7 +277,17 @@ CONFIG_LLC2=m
 # CONFIG_HAMRADIO 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
@@ -268,41 +296,26 @@ CONFIG_LLC2=m
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_STANDALONE is not set
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 CONFIG_FW_LOADER=y
 # 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 is not set
-
-#
-# Parallel port support
-#
 CONFIG_PARPORT=y
 CONFIG_PARPORT_PC=m
 # CONFIG_PARPORT_SERIAL is not set
 # CONFIG_PARPORT_PC_FIFO is not set
 # CONFIG_PARPORT_PC_SUPERIO is not set
 CONFIG_PARPORT_PC_PCMCIA=m
-CONFIG_PARPORT_NOT_PC=y
 CONFIG_PARPORT_GSC=y
+# CONFIG_PARPORT_AX88796 is not set
 CONFIG_PARPORT_1284=y
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
+CONFIG_PARPORT_NOT_PC=y
+CONFIG_BLK_DEV=y
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
@@ -317,13 +330,14 @@ CONFIG_BLK_DEV_CRYPTOLOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=6144
-CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+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_IDE=y
 CONFIG_BLK_DEV_IDE=y
 
@@ -334,24 +348,32 @@ CONFIG_BLK_DEV_IDE=y
 CONFIG_BLK_DEV_IDEDISK=y
 CONFIG_IDEDISK_MULTI_MODE=y
 CONFIG_BLK_DEV_IDECS=y
+# CONFIG_BLK_DEV_DELKIN is not set
 CONFIG_BLK_DEV_IDECD=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
 
 #
 # IDE chipset support/bugfixes
 #
 CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_PLATFORM is not set
+
+#
+# PCI IDE chipsets support
+#
 CONFIG_BLK_DEV_IDEPCI=y
 CONFIG_IDEPCI_SHARE_IRQ=y
+CONFIG_IDEPCI_PCIBUS_ORDER=y
 # CONFIG_BLK_DEV_OFFBOARD is not set
 CONFIG_BLK_DEV_GENERIC=y
 # CONFIG_BLK_DEV_OPTI621 is not set
 CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-# CONFIG_IDEDMA_PCI_AUTO is not set
+CONFIG_IDEDMA_ONLYDISK=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
 # CONFIG_BLK_DEV_AMD74XX is not set
@@ -362,8 +384,10 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_CS5530 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT8213 is not set
 # CONFIG_BLK_DEV_IT821X is not set
 CONFIG_BLK_DEV_NS87415=y
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
@@ -373,10 +397,10 @@ CONFIG_BLK_DEV_NS87415=y
 # 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_IDE_ARM is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_IVB is not set
-# CONFIG_IDEDMA_AUTO is not set
 # CONFIG_BLK_DEV_HD is not set
 
 #
@@ -384,6 +408,9 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 # 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
 
 #
@@ -403,18 +430,17 @@ CONFIG_CHR_DEV_SG=y
 # 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 Transport Attributes
+# SCSI Transports
 #
 CONFIG_SCSI_SPI_ATTRS=y
 # 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_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
@@ -424,11 +450,13 @@ CONFIG_SCSI_SPI_ATTRS=y
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
@@ -438,55 +466,45 @@ CONFIG_SCSI_SPI_ATTRS=y
 # CONFIG_SCSI_IMM is not set
 CONFIG_SCSI_LASI700=y
 CONFIG_53C700_LE_ON_BE=y
+# CONFIG_SCSI_STEX is not set
 CONFIG_SCSI_SYM53C8XX_2=y
 CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
 CONFIG_SCSI_SYM53C8XX_MMIO=y
-# CONFIG_SCSI_IPR is not set
 CONFIG_SCSI_ZALON=y
 CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
 CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
 CONFIG_SCSI_NCR53C8XX_SYNC=20
-# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
-# CONFIG_SCSI_QLOGIC_FC 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_SIM710 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
-
-#
-# 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_SRP is not set
+# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
+# CONFIG_ATA is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=y
 CONFIG_MD_LINEAR=y
 CONFIG_MD_RAID0=y
 CONFIG_MD_RAID1=y
 CONFIG_MD_RAID10=y
-CONFIG_MD_RAID5=y
-CONFIG_MD_RAID6=y
+# CONFIG_MD_RAID456 is not set
 # CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=y
+# CONFIG_DM_DEBUG is not set
 # CONFIG_DM_CRYPT is not set
 # CONFIG_DM_SNAPSHOT is not set
 # CONFIG_DM_MIRROR is not set
 # CONFIG_DM_ZERO is not set
 # CONFIG_DM_MULTIPATH is not set
+# CONFIG_DM_DELAY is not set
 
 #
 # Fusion MPT device support
@@ -499,35 +517,20 @@ CONFIG_BLK_DEV_DM=y
 #
 # IEEE 1394 (FireWire) support
 #
+# CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
 # CONFIG_I2O is not set
-
-#
-# Network device support
-#
 CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 CONFIG_BONDING=m
+# CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 CONFIG_TUN=m
-
-#
-# ARCnet devices
-#
+# CONFIG_VETH is not set
+# CONFIG_IP1000 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=m
 CONFIG_LASI_82596=y
@@ -536,10 +539,6 @@ CONFIG_LASI_82596=y
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_NET_VENDOR_SMC is not set
-
-#
-# Tulip family network device support
-#
 CONFIG_NET_TULIP=y
 # CONFIG_DE2104X is not set
 CONFIG_TULIP=y
@@ -554,6 +553,10 @@ CONFIG_TULIP=y
 # CONFIG_PCMCIA_XIRTULIP is not set
 # CONFIG_DEPCA is not set
 # CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
 CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
@@ -561,7 +564,6 @@ CONFIG_NET_PCI=y
 # CONFIG_AC3200 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_LNE390 is not set
@@ -577,15 +579,14 @@ CONFIG_NET_PCI=y
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
+# CONFIG_SC92031 is not set
 # CONFIG_NET_POCKET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
+CONFIG_NETDEV_1000=y
 CONFIG_ACENIC=y
 # CONFIG_ACENIC_OMIT_TIGON_I is not set
 # CONFIG_DL2K is not set
 # CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -597,64 +598,36 @@ CONFIG_ACENIC=y
 # CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=y
 # CONFIG_BNX2 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
+# 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
-
-#
-# Token Ring devices
-#
+# 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_TR 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=y
-# CONFIG_PLX_HERMES is not set
-# CONFIG_TMD_HERMES is not set
-# CONFIG_NORTEL_HERMES is not set
-# CONFIG_PCI_HERMES is not set
-# CONFIG_ATMEL is not set
-
-#
-# Wireless 802.11b Pcmcia/Cardbus cards support
+# Wireless LAN
 #
-CONFIG_PCMCIA_HERMES=y
-CONFIG_PCMCIA_SPECTRUM=y
-# CONFIG_AIRO_CS is not set
-# CONFIG_PCMCIA_WL3501 is not set
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
 
 #
-# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
-#
-# CONFIG_PRISM54 is not set
-# CONFIG_HOSTAP is not set
-CONFIG_NET_WIRELESS=y
-
-#
-# PCMCIA network device support
+# 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_MII is not set
+# CONFIG_USB_USBNET is not set
 CONFIG_NET_PCMCIA=y
 # CONFIG_PCMCIA_3C589 is not set
 # CONFIG_PCMCIA_3C574 is not set
@@ -664,10 +637,6 @@ CONFIG_NET_PCMCIA=y
 # 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_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -681,27 +650,23 @@ CONFIG_PPP_DEFLATE=m
 CONFIG_PPP_BSDCOMP=m
 # CONFIG_PPP_MPPE is not set
 CONFIG_PPPOE=m
+# CONFIG_PPPOL2TP is not set
 # CONFIG_SLIP is not set
+CONFIG_SLHC=m
 # CONFIG_NET_FC is not set
 # CONFIG_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
 
 #
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
 
 #
 # Userland interfaces
@@ -726,14 +691,23 @@ CONFIG_KEYBOARD_ATKBD_HP_KEYCODES=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_HIL_OLD is not set
 CONFIG_KEYBOARD_HIL=y
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
 CONFIG_MOUSE_SERIAL=y
+# CONFIG_MOUSE_APPLETOUCH is not set
 # CONFIG_MOUSE_VSXXXAA is not set
 CONFIG_MOUSE_HIL=y
 # CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
@@ -757,6 +731,7 @@ CONFIG_SERIO_LIBPS2=y
 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
 
 #
@@ -764,6 +739,8 @@ CONFIG_HW_CONSOLE=y
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_GSC=y
+CONFIG_SERIAL_8250_PCI=y
 CONFIG_SERIAL_8250_CS=y
 CONFIG_SERIAL_8250_NR_UARTS=17
 CONFIG_SERIAL_8250_RUNTIME_UARTS=4
@@ -788,25 +765,14 @@ CONFIG_PRINTER=m
 # CONFIG_LP_CONSOLE is not set
 CONFIG_PPDEV=m
 # CONFIG_TIPAR is not set
-
-#
-# IPMI
-#
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
 # CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
 CONFIG_GEN_RTC=y
 CONFIG_GEN_RTC_X=y
-# CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
+# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 
 #
@@ -816,16 +782,8 @@ CONFIG_GEN_RTC_X=y
 # CONFIG_CARDMAN_4000 is not set
 # CONFIG_CARDMAN_4040 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_DEVPORT=y
 # CONFIG_I2C is not set
 
 #
@@ -833,46 +791,59 @@ CONFIG_GEN_RTC_X=y
 #
 # CONFIG_SPI is not set
 # CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
 # CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
+# CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
-# CONFIG_HWMON_VID 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_SM501 is not set
 
 #
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
 
 #
-# Digital Video Broadcasting Devices
+# Graphics support
 #
-# CONFIG_DVB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
-# Graphics support
+# Display device support
 #
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
 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_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=y
 CONFIG_FB_TILEBLITTING=y
+
+#
+# Frame buffer hardware drivers
+#
 # CONFIG_FB_CIRRUS is not set
 # CONFIG_FB_PM2 is not set
 # CONFIG_FB_CYBER2000 is not set
@@ -883,17 +854,20 @@ CONFIG_FB_STI=y
 # CONFIG_FB_NVIDIA is not set
 # CONFIG_FB_RIVA is not set
 # CONFIG_FB_MATROX is not set
-# CONFIG_FB_RADEON_OLD is not set
 # CONFIG_FB_RADEON is not set
 # CONFIG_FB_ATY128 is not set
 # CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
 # CONFIG_FB_SAVAGE is not set
 # CONFIG_FB_SIS is not set
 # CONFIG_FB_NEOMAGIC is not set
 # CONFIG_FB_KYRO is not set
 # CONFIG_FB_3DFX is not set
 # CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
 # CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -903,6 +877,7 @@ CONFIG_DUMMY_CONSOLE=y
 CONFIG_DUMMY_CONSOLE_COLUMNS=128
 CONFIG_DUMMY_CONSOLE_ROWS=48
 CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
 # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
 CONFIG_STI_CONSOLE=y
 CONFIG_FONTS=y
@@ -916,16 +891,11 @@ 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=y
 # CONFIG_LOGO_LINUX_MONO is not set
 # CONFIG_LOGO_LINUX_VGA16 is not set
 # CONFIG_LOGO_LINUX_CLUT224 is not set
 CONFIG_LOGO_PARISC_CLUT224=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -938,35 +908,36 @@ CONFIG_SOUND=y
 CONFIG_SND=y
 CONFIG_SND_TIMER=y
 CONFIG_SND_PCM=y
-CONFIG_SND_HWDEP=y
 CONFIG_SND_SEQUENCER=y
 # CONFIG_SND_SEQ_DUMMY is not set
 CONFIG_SND_OSSEMUL=y
 CONFIG_SND_MIXER_OSS=y
 CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
 CONFIG_SND_SEQUENCER_OSS=y
 CONFIG_SND_DYNAMIC_MINORS=y
 CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
 
 #
 # Generic devices
 #
-CONFIG_SND_OPL3_LIB=y
 CONFIG_SND_AC97_CODEC=y
-CONFIG_SND_AC97_BUS=y
 # CONFIG_SND_DUMMY is not set
 # CONFIG_SND_VIRMIDI is not set
 # CONFIG_SND_MTPAV is not set
+# CONFIG_SND_MTS64 is not set
 # CONFIG_SND_SERIAL_U16550 is not set
 # CONFIG_SND_MPU401 is not set
+# CONFIG_SND_PORTMAN2X4 is not set
 
 #
 # PCI devices
 #
 CONFIG_SND_AD1889=y
-CONFIG_SND_AD1889_OPL3=y
+# CONFIG_SND_ALS300 is not set
 # CONFIG_SND_ALI5451 is not set
 # CONFIG_SND_ATIIXP is not set
 # CONFIG_SND_ATIIXP_MODEM is not set
@@ -979,6 +950,18 @@ CONFIG_SND_AD1889_OPL3=y
 # CONFIG_SND_CMIPCI is not set
 # CONFIG_SND_CS4281 is not set
 # CONFIG_SND_CS46XX is not set
+# CONFIG_SND_DARLA20 is not set
+# CONFIG_SND_GINA20 is not set
+# CONFIG_SND_LAYLA20 is not set
+# CONFIG_SND_DARLA24 is not set
+# CONFIG_SND_GINA24 is not set
+# CONFIG_SND_LAYLA24 is not set
+# CONFIG_SND_MONA is not set
+# CONFIG_SND_MIA is not set
+# CONFIG_SND_ECHO3G is not set
+# CONFIG_SND_INDIGO is not set
+# CONFIG_SND_INDIGOIO is not set
+# CONFIG_SND_INDIGODJ is not set
 # CONFIG_SND_EMU10K1 is not set
 # CONFIG_SND_EMU10K1X is not set
 # CONFIG_SND_ENS1370 is not set
@@ -998,6 +981,7 @@ CONFIG_SND_AD1889_OPL3=y
 # CONFIG_SND_MIXART is not set
 # CONFIG_SND_NM256 is not set
 # CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RIPTIDE is not set
 # CONFIG_SND_RME32 is not set
 # CONFIG_SND_RME96 is not set
 # CONFIG_SND_RME9652 is not set
@@ -1007,31 +991,54 @@ CONFIG_SND_AD1889_OPL3=y
 # CONFIG_SND_VIA82XX_MODEM is not set
 # CONFIG_SND_VX222 is not set
 # CONFIG_SND_YMFPCI is not set
+# CONFIG_SND_AC97_POWER_SAVE is not set
 
 #
 # USB devices
 #
 # CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
 
 #
 # PCMCIA devices
 #
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
 
 #
 # GSC devices
 #
 CONFIG_SND_HARMONY=y
 
+#
+# System on Chip audio support
+#
+# CONFIG_SND_SOC is not set
+
+#
+# SoC Audio support for SuperH
+#
+
 #
 # Open Sound System
 #
 # CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=y
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HID_DEBUG=y
 
 #
-# USB support
+# USB Input Devices
 #
+CONFIG_USB_HID=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+# CONFIG_USB_HIDDEV is not set
+CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 
@@ -1039,7 +1046,7 @@ CONFIG_USB=y
 # 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
 
@@ -1049,15 +1056,16 @@ CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_EHCI_HCD is not set
 # CONFIG_USB_ISP116X_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=y
 # CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
 
 #
 # USB Device Class drivers
 #
-# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
 
@@ -1071,53 +1079,11 @@ CONFIG_USB_UHCI_HCD=y
 # CONFIG_USB_STORAGE is not set
 # CONFIG_USB_LIBUSUAL is not set
 
-#
-# USB Input Devices
-#
-CONFIG_USB_HID=y
-CONFIG_USB_HIDINPUT=y
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-# CONFIG_HID_FF is not set
-# CONFIG_USB_HIDDEV is not set
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_ACECAD is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_MTOUCH is not set
-# CONFIG_USB_ITMTOUCH is not set
-# CONFIG_USB_EGALAX 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 Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
-#
-# 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_USB_ZD1201 is not set
 CONFIG_USB_MON=y
 
 #
@@ -1135,16 +1101,22 @@ 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_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_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO 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_TEST is not set
 
 #
@@ -1155,20 +1127,29 @@ CONFIG_USB_MON=y
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_RTC_CLASS is not set
 
 #
-# MMC/SD Card support
+# DMA Engine support
 #
-# CONFIG_MMC is not set
+# CONFIG_DMA_ENGINE is not set
 
 #
-# InfiniBand support
+# DMA Clients
 #
-# CONFIG_INFINIBAND is not set
 
 #
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+# DMA Devices
+#
+# CONFIG_AUXDISPLAY is not set
+
+#
+# Userspace I/O
 #
+# CONFIG_UIO is not set
 
 #
 # File systems
@@ -1178,16 +1159,19 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 CONFIG_AUTOFS_FS=y
@@ -1217,11 +1201,12 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -1229,6 +1214,7 @@ CONFIG_RAMFS=y
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
@@ -1261,6 +1247,7 @@ CONFIG_EXPORTFS=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
+# CONFIG_SUNRPC_BIND34 is not set
 CONFIG_RPCSEC_GSS_KRB5=y
 CONFIG_RPCSEC_GSS_SPKM3=m
 CONFIG_SMB_FS=m
@@ -1268,12 +1255,13 @@ CONFIG_SMB_NLS_DEFAULT=y
 CONFIG_SMB_NLS_REMOTE="cp437"
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
 # CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_CIFS_EXPERIMENTAL is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
 
 #
 # Partition Types
@@ -1325,6 +1313,11 @@ CONFIG_NLS_KOI8_R=m
 CONFIG_NLS_KOI8_U=m
 CONFIG_NLS_UTF8=y
 
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
 #
 # Profiling support
 #
@@ -1335,21 +1328,32 @@ CONFIG_OPROFILE=m
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+CONFIG_HEADERS_CHECK=y
 CONFIG_DEBUG_KERNEL=y
-CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_DEBUG_SHIRQ is not set
 CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
 # CONFIG_DEBUG_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_LIST is not set
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
 # CONFIG_DEBUG_RODATA is not set
 
 #
@@ -1358,12 +1362,13 @@ CONFIG_FORCED_INLINING=y
 CONFIG_KEYS=y
 CONFIG_KEYS_DEBUG_PROC_KEYS=y
 # CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=y
@@ -1372,9 +1377,18 @@ CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+# 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_CRYPTD is not set
 CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
@@ -1383,21 +1397,28 @@ CONFIG_CRYPTO_TEA=m
 CONFIG_CRYPTO_ARC4=m
 CONFIG_CRYPTO_KHAZAD=m
 CONFIG_CRYPTO_ANUBIS=m
+# CONFIG_CRYPTO_SEED is not set
 CONFIG_CRYPTO_DEFLATE=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_CAMELLIA is not set
 CONFIG_CRYPTO_TEST=m
-
-#
-# Hardware crypto devices
-#
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_HW is not set
 
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 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 0b9d5b1e4b37e0ccec15e8e3c819071f47adf422..38a1c1b8d4e8e11093b3a35db9d95ca98749ed1a 100644 (file)
@@ -20,7 +20,7 @@
        .import hpux_call_table
        .import hpux_syscall_exit,code
 
-       .align 4096
+       .align  PAGE_SIZE
 ENTRY(hpux_gateway_page)
        nop
 #ifdef CONFIG_64BIT
@@ -103,5 +103,5 @@ syscall_nosys:
        ldo     -ENOSYS(%r0),%r28
 ENDPROC(hpux_gateway_page)
 
-       .align 4096
+       .align  PAGE_SIZE
 ENTRY(end_hpux_gateway_page)
index d3b7917a87cb559e68893ad40327d0ea5346a7e9..eaa79bc14d9463fcce66b5acc96014d15f9433f4 100644 (file)
@@ -290,9 +290,6 @@ int main(void)
        DEFINE(ASM_PTE_ENTRY_SIZE, PTE_ENTRY_SIZE);
        DEFINE(ASM_PFN_PTE_SHIFT, PFN_PTE_SHIFT);
        DEFINE(ASM_PT_INITIAL, PT_INITIAL);
-       DEFINE(ASM_PAGE_SIZE, PAGE_SIZE);
-       DEFINE(ASM_PAGE_SIZE_DIV64, PAGE_SIZE/64);
-       DEFINE(ASM_PAGE_SIZE_DIV128, PAGE_SIZE/128);
        BLANK();
        DEFINE(EXCDATA_IP, offsetof(struct exception_data, fault_ip));
        DEFINE(EXCDATA_SPACE, offsetof(struct exception_data, fault_space));
index 42598abf45763ccd4c9d2c4b1f2970eb6be8b50f..111d47284eacc8c492a2ce55d8f7f006005daa8b 100644 (file)
@@ -98,7 +98,6 @@
         * The "get_stack" macros are responsible for determining the
         * kernel stack value.
         *
-        * For Faults:
         *      If sr7 == 0
         *          Already using a kernel stack, so call the
         *          get_stack_use_r30 macro to push a pt_regs structure
         *          task pointer pointed to by cr30. Set the stack
         *          pointer to point to the end of the task structure.
         *
-        * For Interrupts:
-        *      If sr7 == 0
-        *          Already using a kernel stack, check to see if r30
-        *          is already pointing to the per processor interrupt
-        *          stack. If it is, call the get_stack_use_r30 macro
-        *          to push a pt_regs structure on the stack, and store
-        *          registers there. Otherwise, call get_stack_use_cr31
-        *          to get a pointer to the base of the interrupt stack
-        *          and push a pt_regs structure on that stack.
-        *      else
-        *          Need to set up a kernel stack, so call the
-        *          get_stack_use_cr30 macro to set up a pointer
-        *          to the pt_regs structure contained within the
-        *          task pointer pointed to by cr30. Set the stack
-        *          pointer to point to the end of the task structure.
-        *          N.B: We don't use the interrupt stack for the
-        *          first interrupt from userland, because signals/
-        *          resched's are processed when returning to userland,
-        *          and we can sleep in those cases.
-        *
         * Note that we use shadowed registers for temps until
         * we can save %r26 and %r29. %r26 is used to preserve
         * %r8 (a shadowed register) which temporarily contained
 
        .text
 
-       .align 4096
+       .align  PAGE_SIZE
 
 ENTRY(fault_vector_20)
        /* First vector is invalid (0) */
@@ -904,7 +883,7 @@ ENDPROC(_switch_to)
         *
         */
 
-       .align 4096
+       .align  PAGE_SIZE
 
 ENTRY(syscall_exit_rfi)
        mfctl   %cr30,%r16
@@ -1086,23 +1065,13 @@ intr_do_preempt:
 
 intr_extint:
        CMPIB=,n 0,%r16,1f
+
        get_stack_use_cr30
-       b,n 3f
+       b,n 2f
 
 1:
-#if 0  /* Interrupt Stack support not working yet! */
-       mfctl   %cr31,%r1
-       copy    %r30,%r17
-       /* FIXME! depi below has hardcoded idea of interrupt stack size (32k)*/
-       DEPI    0,31,15,%r17
-       CMPB=,n %r1,%r17,2f
-       get_stack_use_cr31
-       b,n 3f
-#endif
-2:
        get_stack_use_r30
-
-3:
+2:
        save_specials   %r29
        virt_map
        save_general    %r29
index 9676c486bb63825c59a5b4fd8f6f2420b467c03b..a7b8859488bb9ca7014746151a8d1f2a766a71be 100644 (file)
@@ -95,7 +95,7 @@ $bss_loop:
 
 1:
        stw             %r3,0(%r4)
-       ldo             (ASM_PAGE_SIZE >> PxD_VALUE_SHIFT)(%r3),%r3
+       ldo             (PAGE_SIZE >> PxD_VALUE_SHIFT)(%r3),%r3
        addib,>         -1,%r1,1b
 #if PT_NLEVELS == 3
        ldo             ASM_PMD_ENTRY_SIZE(%r4),%r4
@@ -128,10 +128,6 @@ $pgt_fill_loop:
        /* And the stack pointer too */
        ldo             THREAD_SZ_ALGN(%r6),%sp
 
-       /* And the interrupt stack */
-       load32          interrupt_stack,%r6
-       mtctl           %r6,%cr31
-
 #ifdef CONFIG_SMP
        /* Set the smp rendevous address into page zero.
        ** It would be safer to do this in init_smp_config() but
index 43b41df0b54106b0c38862ed52762fa4ddc405fd..2cbf13b3ef11d0a1ff62f7eb5cec9b1c96333371 100644 (file)
         * IODC requires 7K byte stack.  That leaves 1K byte for os_hpmc.
         */
 
-       .align 4096
+       .align  PAGE_SIZE
 hpmc_stack:
        .block 16384
 
 #define HPMC_IODC_BUF_SIZE 0x8000
 
-       .align 4096
+       .align  PAGE_SIZE
 hpmc_iodc_buf:
        .block HPMC_IODC_BUF_SIZE
 
index 446f98d3fd7bd025018bac31b36034b9e0753a96..26198a074d672fa724c9b21299e7a63bb53a953f 100644 (file)
@@ -49,7 +49,6 @@ EXPORT_SYMBOL(init_mm);
  * way process stacks are handled. This is done by having a special
  * "init_task" linker map entry..
  */
-unsigned char interrupt_stack[ISTACK_SIZE] __attribute__ ((section("init_istack"), aligned(4096)));
 union thread_union init_thread_union
        __attribute__((aligned(128))) __attribute__((__section__(".data.init_task"))) =
                { INIT_THREAD_INFO(init_task) };
index 90b240878520b9c41f28ccbcbfc9a663f7c3e571..5901092e0196b855e64845f0c483fedb774a62d4 100644 (file)
@@ -289,7 +289,7 @@ ENTRY(copy_user_page_asm)
         */
 
        ldd             0(%r25), %r19
-       ldi             ASM_PAGE_SIZE_DIV128, %r1
+       ldi             (PAGE_SIZE / 128), %r1
 
        ldw             64(%r25), %r0           /* prefetch 1 cacheline ahead */
        ldw             128(%r25), %r0          /* prefetch 2 */
@@ -355,7 +355,7 @@ ENTRY(copy_user_page_asm)
         * use ldd/std on a 32 bit kernel.
         */
        ldw             0(%r25), %r19
-       ldi             ASM_PAGE_SIZE_DIV64, %r1
+       ldi             (PAGE_SIZE / 64), %r1
 
 1:
        ldw             4(%r25), %r20
@@ -553,7 +553,7 @@ ENTRY(__clear_user_page_asm)
        pdtlb           0(%r28)
 
 #ifdef CONFIG_64BIT
-       ldi             ASM_PAGE_SIZE_DIV128, %r1
+       ldi             (PAGE_SIZE / 128), %r1
 
        /* PREFETCH (Write) has not (yet) been proven to help here */
        /* #define      PREFETCHW_OP    ldd             256(%0), %r0 */
@@ -578,7 +578,7 @@ ENTRY(__clear_user_page_asm)
        ldo             128(%r28), %r28
 
 #else  /* ! CONFIG_64BIT */
-       ldi             ASM_PAGE_SIZE_DIV64, %r1
+       ldi             (PAGE_SIZE / 64), %r1
 
 1:
        stw             %r0, 0(%r28)
index 7aca704e96f00bceecd841f621bc3b70cf5fc895..671ee5b9950c4826f4fa4c06626109db6a91a747 100644 (file)
@@ -122,31 +122,9 @@ EXPORT_SYMBOL($$divI_12);
 EXPORT_SYMBOL($$divI_14);
 EXPORT_SYMBOL($$divI_15);
 
-extern void __ashrdi3(void);
-extern void __ashldi3(void);
-extern void __lshrdi3(void);
-extern void __muldi3(void);
-
-EXPORT_SYMBOL(__ashrdi3);
-EXPORT_SYMBOL(__ashldi3);
-EXPORT_SYMBOL(__lshrdi3);
-EXPORT_SYMBOL(__muldi3);
-
 asmlinkage void * __canonicalize_funcptr_for_compare(void *);
 EXPORT_SYMBOL(__canonicalize_funcptr_for_compare);
 
-#ifdef CONFIG_64BIT
-extern void __divdi3(void);
-extern void __udivdi3(void);
-extern void __umoddi3(void);
-extern void __moddi3(void);
-
-EXPORT_SYMBOL(__divdi3);
-EXPORT_SYMBOL(__udivdi3);
-EXPORT_SYMBOL(__umoddi3);
-EXPORT_SYMBOL(__moddi3);
-#endif
-
 #ifndef CONFIG_64BIT
 extern void $$dyncall(void);
 EXPORT_SYMBOL($$dyncall);
index 23c1388df1f55c5e2a34459ace9e08f336dad2df..9448d4e91142a5e62f56afa639de5539d5d28173 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/types.h>
+#include <linux/scatterlist.h>
 
 #include <asm/cacheflush.h>
 #include <asm/dma.h>    /* for DMA_CHUNK_SIZE */
@@ -569,11 +570,10 @@ static void *fail_alloc_consistent(struct device *dev, size_t size,
 static void *pa11_dma_alloc_noncoherent(struct device *dev, size_t size,
                                          dma_addr_t *dma_handle, gfp_t flag)
 {
-       void *addr = NULL;
+       void *addr;
 
-       /* rely on kmalloc to be cacheline aligned */
-       addr = kmalloc(size, flag);
-       if(addr)
+       addr = (void *)__get_free_pages(flag, get_order(size));
+       if (addr)
                *dma_handle = (dma_addr_t)virt_to_phys(addr);
 
        return addr;
@@ -582,7 +582,7 @@ static void *pa11_dma_alloc_noncoherent(struct device *dev, size_t size,
 static void pa11_dma_free_noncoherent(struct device *dev, size_t size,
                                        void *vaddr, dma_addr_t iova)
 {
-       kfree(vaddr);
+       free_pages((unsigned long)vaddr, get_order(size));
        return;
 }
 
index 563df0072dee9cf5413778d068a55c4482ac2ce9..507d0ac99f665b928a7e5a7f43edaa92f6391623 100644 (file)
@@ -194,37 +194,13 @@ void __init pcibios_init_bus(struct pci_bus *bus)
        pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bridge_ctl);
 }
 
-
-/* KLUGE: Link the child and parent resources - generic PCI didn't */
-static void
-pcibios_link_hba_resources( struct resource *hba_res, struct resource *r)
-{
-       if (!r->parent) {
-               printk(KERN_EMERG "PCI: resource not parented! [%p-%p]\n",
-                               (void*) r->start, (void*) r->end);
-               r->parent = hba_res;
-
-               /* reverse link is harder *sigh*  */
-               if (r->parent->child) {
-                       if (r->parent->sibling) {
-                               struct resource *next = r->parent->sibling;
-                               while (next->sibling)
-                                        next = next->sibling;
-                               next->sibling = r;
-                       } else {
-                               r->parent->sibling = r;
-                       }
-               } else
-                       r->parent->child = r;
-       }
-}
-
 /* called by drivers/pci/setup-bus.c:pci_setup_bridge().  */
 void __devinit pcibios_resource_to_bus(struct pci_dev *dev,
                struct pci_bus_region *region, struct resource *res)
 {
-       struct pci_bus *bus = dev->bus;
-       struct pci_hba_data *hba = HBA_DATA(bus->bridge->platform_data);
+#ifdef CONFIG_64BIT
+       struct pci_hba_data *hba = HBA_DATA(dev->bus->bridge->platform_data);
+#endif
 
        if (res->flags & IORESOURCE_IO) {
                /*
@@ -243,23 +219,15 @@ void __devinit pcibios_resource_to_bus(struct pci_dev *dev,
        }
 
        DBG_RES("pcibios_resource_to_bus(%02x %s [%lx,%lx])\n",
-               bus->number, res->flags & IORESOURCE_IO ? "IO" : "MEM",
+               dev->bus->number, res->flags & IORESOURCE_IO ? "IO" : "MEM",
                region->start, region->end);
-
-       /* KLUGE ALERT
-       ** if this resource isn't linked to a "parent", then it seems
-       ** to be a child of the HBA - lets link it in.
-       */
-       pcibios_link_hba_resources(&hba->io_space, bus->resource[0]);
-       pcibios_link_hba_resources(&hba->lmmio_space, bus->resource[1]);
 }
 
 void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
                              struct pci_bus_region *region)
 {
 #ifdef CONFIG_64BIT
-       struct pci_bus *bus = dev->bus;
-       struct pci_hba_data *hba = HBA_DATA(bus->bridge->platform_data);
+       struct pci_hba_data *hba = HBA_DATA(dev->bus->bridge->platform_data);
 #endif
 
        if (res->flags & IORESOURCE_MEM) {
index 549f5484342c7d6e812edd457bf2c2475ec93fa1..370086fb8333a8a1b5b6f9fdb17418759dc9e064 100644 (file)
@@ -82,7 +82,12 @@ static int __cpuinit processor_probe(struct parisc_device *dev)
        unsigned long cpuid;
        struct cpuinfo_parisc *p;
 
-#ifndef CONFIG_SMP
+#ifdef CONFIG_SMP
+       if (num_online_cpus() >= NR_CPUS) {
+               printk(KERN_INFO "num_online_cpus() >= NR_CPUS\n");
+               return 1;
+       }
+#else
        if (boot_cpu_data.cpu_count > 0) {
                printk(KERN_INFO "CONFIG_SMP=n  ignoring additional CPUs\n");
                return 1;
index fb35ebc0c4da241a5d6da6e7e3b00de10a581b81..2ce3806f02e1989d5157ac9c9a3a037f40a384fc 100644 (file)
@@ -181,7 +181,7 @@ give_sigsegv:
        si.si_signo = SIGSEGV;
        si.si_errno = 0;
        si.si_code = SI_KERNEL;
-       si.si_pid = current->pid;
+       si.si_pid = task_pid_vnr(current);
        si.si_uid = current->uid;
        si.si_addr = &frame->uc;
        force_sig_info(SIGSEGV, &si, current);
index d7bc7bb42c94e11baf1da17597b9bf0017b50608..85fc7754ec255a36624b038031fb4103bcc76d3c 100644 (file)
@@ -432,22 +432,10 @@ smp_cpu_init(int cpunum)
 void __init smp_callin(void)
 {
        int slave_id = cpu_now_booting;
-#if 0
-       void *istack;
-#endif
 
        smp_cpu_init(slave_id);
        preempt_disable();
 
-#if 0  /* NOT WORKING YET - see entry.S */
-       istack = (void *)__get_free_pages(GFP_KERNEL,ISTACK_ORDER);
-       if (istack == NULL) {
-           printk(KERN_CRIT "Failed to allocate interrupt stack for cpu %d\n",slave_id);
-           BUG();
-       }
-       mtctl(istack,31);
-#endif
-
        flush_cache_all_local(); /* start with known state */
        flush_tlb_all_local(NULL);
 
index 2989c6682bf68702615585ceadc13505aab2d4c7..50bbf33ee00c3d6d40d692640a9c8669faba6d97 100644 (file)
@@ -473,3 +473,10 @@ long sys32_lookup_dcookie(u32 cookie_high, u32 cookie_low, char __user *buf,
        return sys_lookup_dcookie((u64)cookie_high << 32 | cookie_low,
                                  buf, len);
 }
+
+asmlinkage long compat_sys_fallocate(int fd, int mode, u32 offhi, u32 offlo,
+                               u32 lenhi, u32 lenlo)
+{
+        return sys_fallocate(fd, mode, ((loff_t)offhi << 32) | offlo,
+                             ((loff_t)lenhi << 32) | lenlo);
+}
index 56f6231cb863e97ca9c74781ccaea83e1fc063aa..69b6eebc466ea4860261d6ff9c503bae308a748c 100644 (file)
@@ -10,6 +10,7 @@
 #include <asm/asm-offsets.h>
 #include <asm/unistd.h>
 #include <asm/errno.h>
+#include <asm/page.h>
 #include <asm/psw.h>
 #include <asm/thread_info.h>
 #include <asm/assembly.h>
@@ -38,7 +39,7 @@
         * pointers.
         */
 
-       .align ASM_PAGE_SIZE
+       .align PAGE_SIZE
 ENTRY(linux_gateway_page)
 
         /* ADDRESS 0x00 to 0xb0 = 176 bytes / 4 bytes per insn = 44 insns */
@@ -597,7 +598,7 @@ cas_action:
 
 
        /* Make sure nothing else is placed on this page */
-       .align ASM_PAGE_SIZE
+       .align PAGE_SIZE
 END(linux_gateway_page)
 ENTRY(end_linux_gateway_page)
 
@@ -608,7 +609,7 @@ ENTRY(end_linux_gateway_page)
 
        .section .rodata,"a"
 
-       .align ASM_PAGE_SIZE
+       .align PAGE_SIZE
        /* Light-weight-syscall table */
        /* Start of lws table. */
 ENTRY(lws_table)
@@ -617,13 +618,13 @@ ENTRY(lws_table)
 END(lws_table)
        /* End of lws table */
 
-       .align ASM_PAGE_SIZE
+       .align PAGE_SIZE
 ENTRY(sys_call_table)
 #include "syscall_table.S"
 END(sys_call_table)
 
 #ifdef CONFIG_64BIT
-       .align ASM_PAGE_SIZE
+       .align PAGE_SIZE
 ENTRY(sys_call_table64)
 #define SYSCALL_TABLE_64BIT
 #include "syscall_table.S"
@@ -636,7 +637,7 @@ END(sys_call_table64)
                will use this set of locks 
        */
        .section .data
-       .align 4096
+       .align  PAGE_SIZE
 ENTRY(lws_lock_start)
        /* lws locks */
        .align 16
index 2540786a970f43c0a43da71c82e805a0fe0bd212..117438e9eb2a8329a932c17b5b184095982c39dc 100644 (file)
        ENTRY_COMP(signalfd)
        ENTRY_COMP(timerfd)
        ENTRY_SAME(eventfd)
+       ENTRY_COMP(fallocate)           /* 305 */
 
        /* Nothing yet */
 
index 8b3062a5c81235c4f938e6a3347f47fbfa76360d..24be86bba94d6bdf93618109bb490bf6fbe68205 100644 (file)
@@ -189,16 +189,14 @@ static struct clocksource clocksource_cr16 = {
 #ifdef CONFIG_SMP
 int update_cr16_clocksource(void)
 {
-       int change = 0;
-
        /* since the cr16 cycle counters are not synchronized across CPUs,
           we'll check if we should switch to a safe clocksource: */
        if (clocksource_cr16.rating != 0 && num_online_cpus() > 1) {
                clocksource_change_rating(&clocksource_cr16, 0);
-               change = 1;
+               return 1;
        }
 
-       return change;
+       return 0;
 }
 #else
 int update_cr16_clocksource(void)
index bbf029a184acce9be221def228b2e575160be633..99fd56939afa73909f4aabbe9fe88a490afa3748 100644 (file)
@@ -219,7 +219,7 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err)
                        return; /* STFU */
 
                printk(KERN_CRIT "%s (pid %d): %s (code %ld) at " RFMT "\n",
-                       current->comm, current->pid, str, err, regs->iaoq[0]);
+                       current->comm, task_pid_nr(current), str, err, regs->iaoq[0]);
 #ifdef PRINT_USER_FAULTS
                /* XXX for debugging only */
                show_regs(regs);
@@ -252,7 +252,7 @@ KERN_CRIT "                     ||     ||\n");
        
        if (err)
                printk(KERN_CRIT "%s (pid %d): %s (code %ld)\n",
-                       current->comm, current->pid, str, err);
+                       current->comm, task_pid_nr(current), str, err);
 
        /* Wot's wrong wif bein' racy? */
        if (current->thread.flags & PARISC_KERNEL_DEATH) {
@@ -317,7 +317,7 @@ static void handle_break(struct pt_regs *regs)
        if (unlikely(iir != GDB_BREAK_INSN)) {
                printk(KERN_DEBUG "break %d,%d: pid=%d command='%s'\n",
                        iir & 31, (iir>>13) & ((1<<13)-1),
-                       current->pid, current->comm);
+                       task_pid_nr(current), current->comm);
                show_regs(regs);
        }
 #endif
@@ -747,7 +747,7 @@ void handle_interruption(int code, struct pt_regs *regs)
                if (user_mode(regs)) {
 #ifdef PRINT_USER_FAULTS
                        printk(KERN_DEBUG "\nhandle_interruption() pid=%d command='%s'\n",
-                           current->pid, current->comm);
+                           task_pid_nr(current), current->comm);
                        show_regs(regs);
 #endif
                        /* SIGBUS, for lack of a better one. */
@@ -772,7 +772,7 @@ void handle_interruption(int code, struct pt_regs *regs)
                else
                        printk(KERN_DEBUG "User Fault (long pointer) (fault %d) ",
                               code);
-               printk("pid=%d command='%s'\n", current->pid, current->comm);
+               printk("pid=%d command='%s'\n", task_pid_nr(current), current->comm);
                show_regs(regs);
 #endif
                si.si_signo = SIGSEGV;
index 347bb922e6d077f717799dd2c642804dbe0f23dd..aebf3c1688719b0b6ce735f258c3eb068a68b845 100644 (file)
@@ -469,7 +469,7 @@ void handle_unaligned(struct pt_regs *regs)
                    && ++unaligned_count < 5) {
                        char buf[256];
                        sprintf(buf, "%s(%d): unaligned access to 0x" RFMT " at ip=0x" RFMT "\n",
-                               current->comm, current->pid, regs->ior, regs->iaoq[0]);
+                               current->comm, task_pid_nr(current), regs->ior, regs->iaoq[0]);
                        printk(KERN_WARNING "%s", buf);
 #ifdef DEBUG_UNALIGNED
                        show_regs(regs);
index cf780cb3b916fab25aa79c9adda3819b7d5bd7ba..701b2d2d88823f55fb2d18a2c03c1e91b2b3f2a9 100644 (file)
@@ -209,8 +209,8 @@ static int unwind_init(void)
 
 static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int frame_size)
 {
-       void handle_interruption(int, struct pt_regs *);
-       static unsigned long *hi = (unsigned long)&handle_interruption;
+       extern void handle_interruption(int, struct pt_regs *);
+       static unsigned long *hi = (unsigned long *)&handle_interruption;
 
        if (pc == get_func_addr(hi)) {
                struct pt_regs *regs = (struct pt_regs *)(info->sp - frame_size - PT_SZ_ALGN);
index ee7a16eb6fdd833bc58938eb9678a645a8760065..40d0ff9b81ab685acfd88dd5ca1a04158a25b1dd 100644 (file)
@@ -46,168 +46,211 @@ jiffies = jiffies_64;
 #endif
 SECTIONS
 {
+       . = KERNEL_BINARY_TEXT_START;
 
-  . = KERNEL_BINARY_TEXT_START;
-
-  _text = .;                   /* Text and read-only data */
-  .text ALIGN(16) : {
-       TEXT_TEXT
-       SCHED_TEXT
-       LOCK_TEXT
-       *(.text.do_softirq)
-       *(.text.sys_exit)
-       *(.text.do_sigaltstack)
-       *(.text.do_fork)
-       *(.text.*)
-       *(.fixup)
-       *(.lock.text)           /* out-of-line lock text */
-       *(.gnu.warning)
+       _text = .;              /* Text and read-only data */
+       .text ALIGN(16) : {
+               TEXT_TEXT
+               SCHED_TEXT
+               LOCK_TEXT
+               *(.text.do_softirq)
+               *(.text.sys_exit)
+               *(.text.do_sigaltstack)
+               *(.text.do_fork)
+               *(.text.*)
+               *(.fixup)
+               *(.lock.text)           /* out-of-line lock text */
+               *(.gnu.warning)
        } = 0
+       /* End of text section */
+       _etext = .;
 
-  _etext = .;                  /* End of text section */
+       RODATA
+       BUG_TABLE
 
-  RODATA
-
-  BUG_TABLE
-
-  /* writeable */
-  . = ALIGN(ASM_PAGE_SIZE);    /* Make sure this is page aligned so
-                                  that we can properly leave these
-                                  as writable */
-  data_start = .;
-
-  . = ALIGN(16);               /* Exception table */
-  __start___ex_table = .;
-  __ex_table : { *(__ex_table) }
-  __stop___ex_table = .;
+       /* writeable */
+       /* Make sure this is page aligned so
+        * that we can properly leave these
+        * as writable
+        */
+       . = ALIGN(PAGE_SIZE);
+       data_start = .;
+       . = ALIGN(16);
+       /* Exception table */
+       __ex_table : {
+               __start___ex_table = .;
+               *(__ex_table)
+               __stop___ex_table = .;
+       }
 
-  NOTES
+       NOTES
 
-  __start___unwind = .;         /* unwind info */
-  .PARISC.unwind : { *(.PARISC.unwind) }
-  __stop___unwind = .;
+       /* unwind info */
+       .PARISC.unwind : {
+               __start___unwind = .;
+               *(.PARISC.unwind)
+               __stop___unwind = .;
+       }
 
-  /* rarely changed data like cpu maps */
-  . = ALIGN(16);
-  .data.read_mostly : { *(.data.read_mostly) }
+       /* rarely changed data like cpu maps */
+       . = ALIGN(16);
+       .data.read_mostly : {
+               *(.data.read_mostly)
+       }
 
-  . = ALIGN(L1_CACHE_BYTES);
-  .data : {                    /* Data */
-       DATA_DATA
-       CONSTRUCTORS
+       . = ALIGN(L1_CACHE_BYTES);
+       /* Data */
+       .data : {
+               DATA_DATA
+               CONSTRUCTORS
        }
 
-  . = ALIGN(L1_CACHE_BYTES);
-  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+       . = ALIGN(L1_CACHE_BYTES);
+       .data.cacheline_aligned : {
+               *(.data.cacheline_aligned)
+       }
 
-  /* PA-RISC locks requires 16-byte alignment */
-  . = ALIGN(16);
-  .data.lock_aligned : { *(.data.lock_aligned) }
+       /* PA-RISC locks requires 16-byte alignment */
+       . = ALIGN(16);
+       .data.lock_aligned : {
+               *(.data.lock_aligned)
+       }
 
-  . = ALIGN(ASM_PAGE_SIZE);
-  /* nosave data is really only used for software suspend...it's here
-   * just in case we ever implement it */
-  __nosave_begin = .;
-  .data_nosave : { *(.data.nosave) }
-  . = ALIGN(ASM_PAGE_SIZE);
-  __nosave_end = .;
+       /* nosave data is really only used for software suspend...it's here
+        * just in case we ever implement it
+        */
+       . = ALIGN(PAGE_SIZE);
+       __nosave_begin = .;
+       .data_nosave : {
+               *(.data.nosave)
+       }
+       . = ALIGN(PAGE_SIZE);
+       __nosave_end = .;
 
-  _edata = .;                  /* End of data section */
+       /* End of data section */
+       _edata = .;
 
-  __bss_start = .;             /* BSS */
-  /* page table entries need to be PAGE_SIZE aligned */
-  . = ALIGN(ASM_PAGE_SIZE);
-  .data.vmpages : {
-       *(.data.vm0.pmd)
-       *(.data.vm0.pgd)
-       *(.data.vm0.pte)
+       /* BSS */
+       __bss_start = .;
+       /* page table entries need to be PAGE_SIZE aligned */
+       . = ALIGN(PAGE_SIZE);
+       .data.vmpages : {
+               *(.data.vm0.pmd)
+               *(.data.vm0.pgd)
+               *(.data.vm0.pte)
        }
-  .bss : { *(.bss) *(COMMON) }
-  __bss_stop = .;
-
+       .bss : {
+               *(.bss)
+               *(COMMON)
+       }
+       __bss_stop = .;
 
-  /* assembler code expects init_task to be 16k aligned */
-  . = ALIGN(16384);            /* init_task */
-  .data.init_task : { *(.data.init_task) }
 
-  /* The interrupt stack is currently partially coded, but not yet
-   * implemented */
-  . = ALIGN(16384);    
-  init_istack : { *(init_istack) }
+       /* assembler code expects init_task to be 16k aligned */
+       . = ALIGN(16384);
+       /* init_task */
+       .data.init_task : {
+               *(.data.init_task)
+       }
 
 #ifdef CONFIG_64BIT
-  . = ALIGN(16);               /* Linkage tables */
-  .opd : { *(.opd) } PROVIDE (__gp = .); 
-  .plt : { *(.plt) } 
-  .dlt : { *(.dlt) }
+       . = ALIGN(16);
+       /* Linkage tables */
+       .opd : {
+               *(.opd)
+       } PROVIDE (__gp = .); 
+       .plt : {
+               *(.plt)
+       } 
+       .dlt : {
+               *(.dlt)
+       }
 #endif
 
-  /* reserve space for interrupt stack by aligning __init* to 16k */
-  . = ALIGN(16384);
-  __init_begin = .;
-  .init.text : { 
-       _sinittext = .;
-       *(.init.text)
-       _einittext = .;
-  }
-  .init.data : { *(.init.data) }
-  . = ALIGN(16);
-  __setup_start = .;
-  .init.setup : { *(.init.setup) }
-  __setup_end = .;
-  __initcall_start = .;
-  .initcall.init : {
-       INITCALLS
-  }
-  __initcall_end = .;
-  __con_initcall_start = .;
-  .con_initcall.init : { *(.con_initcall.init) }
-  __con_initcall_end = .;
-  SECURITY_INIT
-  /* alternate instruction replacement.  This is a mechanism x86 uses
-   * to detect the CPU type and replace generic instruction sequences
-   * with CPU specific ones.  We don't currently do this in PA, but
-   * it seems like a good idea... */
-  . = ALIGN(4);
-  __alt_instructions = .;
-  .altinstructions : { *(.altinstructions) } 
-  __alt_instructions_end = .; 
- .altinstr_replacement : { *(.altinstr_replacement) } 
-  /* .exit.text is discard at runtime, not link time, to deal with references
-     from .altinstructions and .eh_frame */
-  .exit.text : { *(.exit.text) }
-  .exit.data : { *(.exit.data) }
+       /* reserve space for interrupt stack by aligning __init* to 16k */
+       . = ALIGN(16384);
+       __init_begin = .;
+       .init.text : { 
+               _sinittext = .;
+               *(.init.text)
+               _einittext = .;
+       }
+       .init.data : {
+               *(.init.data)
+       }
+       . = ALIGN(16);
+       .init.setup : {
+               __setup_start = .;
+               *(.init.setup)
+               __setup_end = .;
+       }
+       .initcall.init : {
+               __initcall_start = .;
+               INITCALLS
+               __initcall_end = .;
+       }
+       .con_initcall.init : {
+               __con_initcall_start = .;
+               *(.con_initcall.init)
+               __con_initcall_end = .;
+       }
+       SECURITY_INIT
+
+       /* alternate instruction replacement.  This is a mechanism x86 uses
+        * to detect the CPU type and replace generic instruction sequences
+        * with CPU specific ones.  We don't currently do this in PA, but
+        * it seems like a good idea...
+        */
+       . = ALIGN(4);
+       .altinstructions : {
+               __alt_instructions = .;
+               *(.altinstructions)
+               __alt_instructions_end = .; 
+       } 
+       .altinstr_replacement : {
+               *(.altinstr_replacement)
+       } 
+
+       /* .exit.text is discard at runtime, not link time, to deal with references
+        *  from .altinstructions and .eh_frame
+        */
+       .exit.text : {
+               *(.exit.text)
+       }
+       .exit.data : {
+               *(.exit.data)
+       }
 #ifdef CONFIG_BLK_DEV_INITRD
-  . = ALIGN(ASM_PAGE_SIZE);
-  __initramfs_start = .;
-  .init.ramfs : { *(.init.ramfs) }
-  __initramfs_end = .;
+       . = ALIGN(PAGE_SIZE);
+       .init.ramfs : {
+               __initramfs_start = .;
+               *(.init.ramfs)
+               __initramfs_end = .;
+       }
 #endif
 
-  PERCPU(ASM_PAGE_SIZE)
+       PERCPU(PAGE_SIZE)
+       . = ALIGN(PAGE_SIZE);
+       __init_end = .;
+       /* freed after init ends here */
+       _end = . ;
 
-  . = ALIGN(ASM_PAGE_SIZE);
-  __init_end = .;
-  /* freed after init ends here */
-       
-  _end = . ;
-
-  /* Sections to be discarded */
-  /DISCARD/ : {
-       *(.exitcall.exit)
+       /* Sections to be discarded */
+       /DISCARD/ : {
+               *(.exitcall.exit)
 #ifdef CONFIG_64BIT
-       /* temporary hack until binutils is fixed to not emit these
-        for static binaries */
-       *(.interp)
-       *(.dynsym)
-       *(.dynstr)
-       *(.dynamic)
-       *(.hash)
-       *(.gnu.hash)
+               /* temporary hack until binutils is fixed to not emit these
+                * for static binaries
+                */
+               *(.interp)
+               *(.dynsym)
+               *(.dynstr)
+               *(.dynamic)
+               *(.hash)
+               *(.gnu.hash)
 #endif
        }
 
-  STABS_DEBUG
-  .note 0 : { *(.note) }       
-
+       STABS_DEBUG
+       .note 0 : { *(.note) }  
 }
index 5f2e6904d14aecb897773538b1eadd001fde93f5..7ce406c7daf5d0f429460e1a67fdc6e2498875d9 100644 (file)
@@ -4,4 +4,4 @@
 
 lib-y  := lusercopy.o bitops.o checksum.o io.o memset.o fixup.o memcpy.o
 
-obj-y  := iomap.o
+obj-y  := libgcc/ milli/ iomap.o
diff --git a/arch/parisc/lib/libgcc/Makefile b/arch/parisc/lib/libgcc/Makefile
new file mode 100644 (file)
index 0000000..b67a85a
--- /dev/null
@@ -0,0 +1,4 @@
+obj-y  := __ashldi3.o __ashrdi3.o __clzsi2.o __divdi3.o __divsi3.o     \
+               __lshrdi3.o __moddi3.o __modsi3.o __udivdi3.o           \
+               __udivmoddi4.o __udivmodsi4.o __udivsi3.o               \
+               __umoddi3.o __umodsi3.o __muldi3.o __umulsidi3.o
diff --git a/arch/parisc/lib/libgcc/__ashldi3.c b/arch/parisc/lib/libgcc/__ashldi3.c
new file mode 100644 (file)
index 0000000..a14a257
--- /dev/null
@@ -0,0 +1,19 @@
+#include "libgcc.h"
+
+u64 __ashldi3(u64 v, int cnt)
+{
+       int c = cnt & 31;
+       u32 vl = (u32) v;
+       u32 vh = (u32) (v >> 32);
+
+       if (cnt & 32) {
+               vh = (vl << c);
+               vl = 0;
+       } else {
+               vh = (vh << c) + (vl >> (32 - c));
+               vl = (vl << c);
+       }
+
+       return ((u64) vh << 32) + vl;
+}
+EXPORT_SYMBOL(__ashldi3);
diff --git a/arch/parisc/lib/libgcc/__ashrdi3.c b/arch/parisc/lib/libgcc/__ashrdi3.c
new file mode 100644 (file)
index 0000000..8636a5a
--- /dev/null
@@ -0,0 +1,19 @@
+#include "libgcc.h"
+
+u64 __ashrdi3(u64 v, int cnt)
+{
+       int c = cnt & 31;
+       u32 vl = (u32) v;
+       u32 vh = (u32) (v >> 32);
+
+       if (cnt & 32) {
+               vl = ((s32) vh >> c);
+               vh = (s32) vh >> 31;
+       } else {
+               vl = (vl >> c) + (vh << (32 - c));
+               vh = ((s32) vh >> c);
+       }
+
+       return ((u64) vh << 32) + vl;
+}
+EXPORT_SYMBOL(__ashrdi3);
diff --git a/arch/parisc/lib/libgcc/__clzsi2.c b/arch/parisc/lib/libgcc/__clzsi2.c
new file mode 100644 (file)
index 0000000..a7aa2f5
--- /dev/null
@@ -0,0 +1,30 @@
+#include "libgcc.h"
+
+u32 __clzsi2(u32 v)
+{
+       int p = 31;
+
+       if (v & 0xffff0000) {
+               p -= 16;
+               v >>= 16;
+       }
+       if (v & 0xff00) {
+               p -= 8;
+               v >>= 8;
+       }
+       if (v & 0xf0) {
+               p -= 4;
+               v >>= 4;
+       }
+       if (v & 0xc) {
+               p -= 2;
+               v >>= 2;
+       }
+       if (v & 0x2) {
+               p -= 1;
+               v >>= 1;
+       }
+
+       return p;
+}
+EXPORT_SYMBOL(__clzsi2);
diff --git a/arch/parisc/lib/libgcc/__divdi3.c b/arch/parisc/lib/libgcc/__divdi3.c
new file mode 100644 (file)
index 0000000..f23c6fe
--- /dev/null
@@ -0,0 +1,23 @@
+#include "libgcc.h"
+
+s64 __divdi3(s64 num, s64 den)
+{
+       int minus = 0;
+       s64 v;
+
+       if (num < 0) {
+               num = -num;
+               minus = 1;
+       }
+       if (den < 0) {
+               den = -den;
+               minus ^= 1;
+       }
+
+       v = __udivmoddi4(num, den, NULL);
+       if (minus)
+               v = -v;
+
+       return v;
+}
+EXPORT_SYMBOL(__divdi3);
diff --git a/arch/parisc/lib/libgcc/__divsi3.c b/arch/parisc/lib/libgcc/__divsi3.c
new file mode 100644 (file)
index 0000000..730fb53
--- /dev/null
@@ -0,0 +1,23 @@
+#include "libgcc.h"
+
+s32 __divsi3(s32 num, s32 den)
+{
+       int minus = 0;
+       s32 v;
+
+       if (num < 0) {
+               num = -num;
+               minus = 1;
+       }
+       if (den < 0) {
+               den = -den;
+               minus ^= 1;
+       }
+
+       v = __udivmodsi4(num, den, NULL);
+       if (minus)
+               v = -v;
+
+       return v;
+}
+EXPORT_SYMBOL(__divsi3);
diff --git a/arch/parisc/lib/libgcc/__lshrdi3.c b/arch/parisc/lib/libgcc/__lshrdi3.c
new file mode 100644 (file)
index 0000000..4a82070
--- /dev/null
@@ -0,0 +1,19 @@
+#include "libgcc.h"
+
+u64 __lshrdi3(u64 v, int cnt)
+{
+       int c = cnt & 31;
+       u32 vl = (u32) v;
+       u32 vh = (u32) (v >> 32);
+
+       if (cnt & 32) {
+               vl = (vh >> c);
+               vh = 0;
+       } else {
+               vl = (vl >> c) + (vh << (32 - c));
+               vh = (vh >> c);
+       }
+
+       return ((u64) vh << 32) + vl;
+}
+EXPORT_SYMBOL(__lshrdi3);
diff --git a/arch/parisc/lib/libgcc/__moddi3.c b/arch/parisc/lib/libgcc/__moddi3.c
new file mode 100644 (file)
index 0000000..ed64bba
--- /dev/null
@@ -0,0 +1,23 @@
+#include "libgcc.h"
+
+s64 __moddi3(s64 num, s64 den)
+{
+       int minus = 0;
+       s64 v;
+
+       if (num < 0) {
+               num = -num;
+               minus = 1;
+       }
+       if (den < 0) {
+               den = -den;
+               minus ^= 1;
+       }
+
+       (void)__udivmoddi4(num, den, (u64 *) & v);
+       if (minus)
+               v = -v;
+
+       return v;
+}
+EXPORT_SYMBOL(__moddi3);
diff --git a/arch/parisc/lib/libgcc/__modsi3.c b/arch/parisc/lib/libgcc/__modsi3.c
new file mode 100644 (file)
index 0000000..62f773e
--- /dev/null
@@ -0,0 +1,23 @@
+#include "libgcc.h"
+
+s32 __modsi3(s32 num, s32 den)
+{
+       int minus = 0;
+       s32 v;
+
+       if (num < 0) {
+               num = -num;
+               minus = 1;
+       }
+       if (den < 0) {
+               den = -den;
+               minus ^= 1;
+       }
+
+       (void)__udivmodsi4(num, den, (u32 *) & v);
+       if (minus)
+               v = -v;
+
+       return v;
+}
+EXPORT_SYMBOL(__modsi3);
diff --git a/arch/parisc/lib/libgcc/__muldi3.c b/arch/parisc/lib/libgcc/__muldi3.c
new file mode 100644 (file)
index 0000000..3308abd
--- /dev/null
@@ -0,0 +1,22 @@
+#include "libgcc.h"
+
+union DWunion {
+       struct {
+               s32 high;
+               s32 low;
+       } s;
+       s64 ll;
+};
+
+s64 __muldi3(s64 u, s64 v)
+{
+       const union DWunion uu = { .ll = u };
+       const union DWunion vv = { .ll = v };
+       union DWunion w = { .ll = __umulsidi3(uu.s.low, vv.s.low) };
+
+       w.s.high += ((u32)uu.s.low * (u32)vv.s.high
+               + (u32)uu.s.high * (u32)vv.s.low);
+
+       return w.ll;
+}
+EXPORT_SYMBOL(__muldi3);
diff --git a/arch/parisc/lib/libgcc/__udivdi3.c b/arch/parisc/lib/libgcc/__udivdi3.c
new file mode 100644 (file)
index 0000000..740023d
--- /dev/null
@@ -0,0 +1,7 @@
+#include "libgcc.h"
+
+u64 __udivdi3(u64 num, u64 den)
+{
+       return __udivmoddi4(num, den, NULL);
+}
+EXPORT_SYMBOL(__udivdi3);
diff --git a/arch/parisc/lib/libgcc/__udivmoddi4.c b/arch/parisc/lib/libgcc/__udivmoddi4.c
new file mode 100644 (file)
index 0000000..2df0caa
--- /dev/null
@@ -0,0 +1,31 @@
+#include "libgcc.h"
+
+u64 __udivmoddi4(u64 num, u64 den, u64 * rem_p)
+{
+       u64 quot = 0, qbit = 1;
+
+       if (den == 0) {
+               BUG();
+       }
+
+       /* Left-justify denominator and count shift */
+       while ((s64) den >= 0) {
+               den <<= 1;
+               qbit <<= 1;
+       }
+
+       while (qbit) {
+               if (den <= num) {
+                       num -= den;
+                       quot += qbit;
+               }
+               den >>= 1;
+               qbit >>= 1;
+       }
+
+       if (rem_p)
+               *rem_p = num;
+
+       return quot;
+}
+EXPORT_SYMBOL(__udivmoddi4);
diff --git a/arch/parisc/lib/libgcc/__udivmodsi4.c b/arch/parisc/lib/libgcc/__udivmodsi4.c
new file mode 100644 (file)
index 0000000..2a2fc28
--- /dev/null
@@ -0,0 +1,31 @@
+#include "libgcc.h"
+
+u32 __udivmodsi4(u32 num, u32 den, u32 * rem_p)
+{
+       u32 quot = 0, qbit = 1;
+
+       if (den == 0) {
+               BUG();
+       }
+
+       /* Left-justify denominator and count shift */
+       while ((s32) den >= 0) {
+               den <<= 1;
+               qbit <<= 1;
+       }
+
+       while (qbit) {
+               if (den <= num) {
+                       num -= den;
+                       quot += qbit;
+               }
+               den >>= 1;
+               qbit >>= 1;
+       }
+
+       if (rem_p)
+               *rem_p = num;
+
+       return quot;
+}
+EXPORT_SYMBOL(__udivmodsi4);
diff --git a/arch/parisc/lib/libgcc/__udivsi3.c b/arch/parisc/lib/libgcc/__udivsi3.c
new file mode 100644 (file)
index 0000000..756a441
--- /dev/null
@@ -0,0 +1,7 @@
+#include "libgcc.h"
+
+u32 __udivsi3(u32 num, u32 den)
+{
+       return __udivmodsi4(num, den, NULL);
+}
+EXPORT_SYMBOL(__udivsi3);
diff --git a/arch/parisc/lib/libgcc/__umoddi3.c b/arch/parisc/lib/libgcc/__umoddi3.c
new file mode 100644 (file)
index 0000000..ac744e9
--- /dev/null
@@ -0,0 +1,10 @@
+#include "libgcc.h"
+
+u64 __umoddi3(u64 num, u64 den)
+{
+       u64 v;
+
+       (void)__udivmoddi4(num, den, &v);
+       return v;
+}
+EXPORT_SYMBOL(__umoddi3);
diff --git a/arch/parisc/lib/libgcc/__umodsi3.c b/arch/parisc/lib/libgcc/__umodsi3.c
new file mode 100644 (file)
index 0000000..51f55aa
--- /dev/null
@@ -0,0 +1,10 @@
+#include "libgcc.h"
+
+u32 __umodsi3(u32 num, u32 den)
+{
+       u32 v;
+
+       (void)__udivmodsi4(num, den, &v);
+       return v;
+}
+EXPORT_SYMBOL(__umodsi3);
diff --git a/arch/parisc/lib/libgcc/__umulsidi3.c b/arch/parisc/lib/libgcc/__umulsidi3.c
new file mode 100644 (file)
index 0000000..396f669
--- /dev/null
@@ -0,0 +1,46 @@
+#include "libgcc.h"
+
+#define __ll_B ((u32) 1 << (32 / 2))
+#define __ll_lowpart(t) ((u32) (t) & (__ll_B - 1))
+#define __ll_highpart(t) ((u32) (t) >> 16)
+
+#define umul_ppmm(w1, w0, u, v)                                                \
+  do {                                                                 \
+    u32 __x0, __x1, __x2, __x3;                                                \
+    u16 __ul, __vl, __uh, __vh;                                                \
+                                                                       \
+    __ul = __ll_lowpart (u);                                           \
+    __uh = __ll_highpart (u);                                          \
+    __vl = __ll_lowpart (v);                                           \
+    __vh = __ll_highpart (v);                                          \
+                                                                       \
+    __x0 = (u32) __ul * __vl;                                          \
+    __x1 = (u32) __ul * __vh;                                          \
+    __x2 = (u32) __uh * __vl;                                          \
+    __x3 = (u32) __uh * __vh;                                          \
+                                                                       \
+    __x1 += __ll_highpart (__x0);/* this can't give carry */           \
+    __x1 += __x2;               /* but this indeed can */              \
+    if (__x1 < __x2)            /* did we get it? */                   \
+      __x3 += __ll_B;           /* yes, add it in the proper pos.  */  \
+                                                                       \
+    (w1) = __x3 + __ll_highpart (__x1);                                        \
+    (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0);         \
+  } while (0)
+
+union DWunion {
+       struct {
+               s32 high;
+               s32 low;
+       } s;
+       s64 ll;
+};
+
+u64 __umulsidi3(u32 u, u32 v)
+{
+       union DWunion __w;
+
+       umul_ppmm(__w.s.high, __w.s.low, u, v);
+
+       return __w.ll;
+}
diff --git a/arch/parisc/lib/libgcc/libgcc.h b/arch/parisc/lib/libgcc/libgcc.h
new file mode 100644 (file)
index 0000000..5a6f7a5
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef _PA_LIBGCC_H_
+#define _PA_LIBGCC_H_
+
+#include <linux/types.h>
+#include <linux/module.h>
+
+/* Cribbed from klibc/libgcc/ */
+u64 __ashldi3(u64 v, int cnt);
+u64 __ashrdi3(u64 v, int cnt);
+
+u32 __clzsi2(u32 v);
+
+s64 __divdi3(s64 num, s64 den);
+s32 __divsi3(s32 num, s32 den);
+
+u64 __lshrdi3(u64 v, int cnt);
+
+s64 __moddi3(s64 num, s64 den);
+s32 __modsi3(s32 num, s32 den);
+
+u64 __udivdi3(u64 num, u64 den);
+u32 __udivsi3(u32 num, u32 den);
+
+u64 __udivmoddi4(u64 num, u64 den, u64 * rem_p);
+u32 __udivmodsi4(u32 num, u32 den, u32 * rem_p);
+
+u64 __umulsidi3(u32 u, u32 v);
+
+u64 __umoddi3(u64 num, u64 den);
+u32 __umodsi3(u32 num, u32 den);
+
+#endif /*_PA_LIBGCC_H_*/
index 2c43ebe99a9ce6492f53026f3530a07ebc657df1..d22042d33100b80c34d1c26b17b8fd25fcc350d1 100644 (file)
@@ -139,12 +139,12 @@ DECLARE_PER_CPU(struct exception_data, exception_data);
 #define stw(_s,_t,_o,_a,_e)    def_store_insn(stw,"r",_s,_t,_o,_a,_e)
 
 #ifdef  CONFIG_PREFETCH
-extern inline void prefetch_src(const void *addr)
+static inline void prefetch_src(const void *addr)
 {
        __asm__("ldw 0(" s_space ",%0), %%r0" : : "r" (addr));
 }
 
-extern inline void prefetch_dst(const void *addr)
+static inline void prefetch_dst(const void *addr)
 {
        __asm__("ldd 0(" d_space ",%0), %%r0" : : "r" (addr));
 }
diff --git a/arch/parisc/lib/milli/Makefile b/arch/parisc/lib/milli/Makefile
new file mode 100644 (file)
index 0000000..9b24e9b
--- /dev/null
@@ -0,0 +1 @@
+obj-y  := dyncall.o divI.o divU.o remI.o remU.o div_const.o mulI.o
diff --git a/arch/parisc/lib/milli/divI.S b/arch/parisc/lib/milli/divI.S
new file mode 100644 (file)
index 0000000..ac106b7
--- /dev/null
@@ -0,0 +1,254 @@
+/* 32 and 64-bit millicode, original author Hewlett-Packard
+   adapted for gcc by Paul Bame <bame@debian.org>
+   and Alan Modra <alan@linuxcare.com.au>.
+
+   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
+   This file is part of GCC and is released under the terms of
+   of the GNU General Public License as published by the Free Software
+   Foundation; either version 2, or (at your option) any later version.
+   See the file COPYING in the top-level GCC source directory for a copy
+   of the license.  */
+
+#include "milli.h"
+
+#ifdef L_divI
+/* ROUTINES:   $$divI, $$divoI
+
+   Single precision divide for signed binary integers.
+
+   The quotient is truncated towards zero.
+   The sign of the quotient is the XOR of the signs of the dividend and
+   divisor.
+   Divide by zero is trapped.
+   Divide of -2**31 by -1 is trapped for $$divoI but not for $$divI.
+
+   INPUT REGISTERS:
+   .   arg0 == dividend
+   .   arg1 == divisor
+   .   mrp  == return pc
+   .   sr0  == return space when called externally
+
+   OUTPUT REGISTERS:
+   .   arg0 =  undefined
+   .   arg1 =  undefined
+   .   ret1 =  quotient
+
+   OTHER REGISTERS AFFECTED:
+   .   r1   =  undefined
+
+   SIDE EFFECTS:
+   .   Causes a trap under the following conditions:
+   .           divisor is zero  (traps with ADDIT,=  0,25,0)
+   .           dividend==-2**31  and divisor==-1 and routine is $$divoI
+   .                            (traps with ADDO  26,25,0)
+   .   Changes memory at the following places:
+   .           NONE
+
+   PERMISSIBLE CONTEXT:
+   .   Unwindable.
+   .   Suitable for internal or external millicode.
+   .   Assumes the special millicode register conventions.
+
+   DISCUSSION:
+   .   Branchs to other millicode routines using BE
+   .           $$div_# for # being 2,3,4,5,6,7,8,9,10,12,14,15
+   .
+   .   For selected divisors, calls a divide by constant routine written by
+   .   Karl Pettis.  Eligible divisors are 1..15 excluding 11 and 13.
+   .
+   .   The only overflow case is -2**31 divided by -1.
+   .   Both routines return -2**31 but only $$divoI traps.  */
+
+RDEFINE(temp,r1)
+RDEFINE(retreg,ret1)   /*  r29 */
+RDEFINE(temp1,arg0)
+       SUBSPA_MILLI_DIV
+       ATTR_MILLI
+       .import $$divI_2,millicode
+       .import $$divI_3,millicode
+       .import $$divI_4,millicode
+       .import $$divI_5,millicode
+       .import $$divI_6,millicode
+       .import $$divI_7,millicode
+       .import $$divI_8,millicode
+       .import $$divI_9,millicode
+       .import $$divI_10,millicode
+       .import $$divI_12,millicode
+       .import $$divI_14,millicode
+       .import $$divI_15,millicode
+       .export $$divI,millicode
+       .export $$divoI,millicode
+       .proc
+       .callinfo       millicode
+       .entry
+GSYM($$divoI)
+       comib,=,n  -1,arg1,LREF(negative1)      /*  when divisor == -1 */
+GSYM($$divI)
+       ldo     -1(arg1),temp           /*  is there at most one bit set ? */
+       and,<>  arg1,temp,r0            /*  if not, don't use power of 2 divide */
+       addi,>  0,arg1,r0               /*  if divisor > 0, use power of 2 divide */
+       b,n     LREF(neg_denom)
+LSYM(pow2)
+       addi,>= 0,arg0,retreg           /*  if numerator is negative, add the */
+       add     arg0,temp,retreg        /*  (denominaotr -1) to correct for shifts */
+       extru,= arg1,15,16,temp         /*  test denominator with 0xffff0000 */
+       extrs   retreg,15,16,retreg     /*  retreg = retreg >> 16 */
+       or      arg1,temp,arg1          /*  arg1 = arg1 | (arg1 >> 16) */
+       ldi     0xcc,temp1              /*  setup 0xcc in temp1 */
+       extru,= arg1,23,8,temp          /*  test denominator with 0xff00 */
+       extrs   retreg,23,24,retreg     /*  retreg = retreg >> 8 */
+       or      arg1,temp,arg1          /*  arg1 = arg1 | (arg1 >> 8) */
+       ldi     0xaa,temp               /*  setup 0xaa in temp */
+       extru,= arg1,27,4,r0            /*  test denominator with 0xf0 */
+       extrs   retreg,27,28,retreg     /*  retreg = retreg >> 4 */
+       and,=   arg1,temp1,r0           /*  test denominator with 0xcc */
+       extrs   retreg,29,30,retreg     /*  retreg = retreg >> 2 */
+       and,=   arg1,temp,r0            /*  test denominator with 0xaa */
+       extrs   retreg,30,31,retreg     /*  retreg = retreg >> 1 */
+       MILLIRETN
+LSYM(neg_denom)
+       addi,<  0,arg1,r0               /*  if arg1 >= 0, it's not power of 2 */
+       b,n     LREF(regular_seq)
+       sub     r0,arg1,temp            /*  make denominator positive */
+       comb,=,n  arg1,temp,LREF(regular_seq)   /*  test against 0x80000000 and 0 */
+       ldo     -1(temp),retreg         /*  is there at most one bit set ? */
+       and,=   temp,retreg,r0          /*  if so, the denominator is power of 2 */
+       b,n     LREF(regular_seq)
+       sub     r0,arg0,retreg          /*  negate numerator */
+       comb,=,n arg0,retreg,LREF(regular_seq) /*  test against 0x80000000 */
+       copy    retreg,arg0             /*  set up arg0, arg1 and temp  */
+       copy    temp,arg1               /*  before branching to pow2 */
+       b       LREF(pow2)
+       ldo     -1(arg1),temp
+LSYM(regular_seq)
+       comib,>>=,n 15,arg1,LREF(small_divisor)
+       add,>=  0,arg0,retreg           /*  move dividend, if retreg < 0, */
+LSYM(normal)
+       subi    0,retreg,retreg         /*    make it positive */
+       sub     0,arg1,temp             /*  clear carry,  */
+                                       /*    negate the divisor */
+       ds      0,temp,0                /*  set V-bit to the comple- */
+                                       /*    ment of the divisor sign */
+       add     retreg,retreg,retreg    /*  shift msb bit into carry */
+       ds      r0,arg1,temp            /*  1st divide step, if no carry */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  2nd divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  3rd divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  4th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  5th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  6th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  7th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  8th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  9th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  10th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  11th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  12th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  13th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  14th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  15th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  16th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  17th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  18th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  19th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  20th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  21st divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  22nd divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  23rd divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  24th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  25th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  26th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  27th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  28th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  29th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  30th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  31st divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  32nd divide step, */
+       addc    retreg,retreg,retreg    /*  shift last retreg bit into retreg */
+       xor,>=  arg0,arg1,0             /*  get correct sign of quotient */
+         sub   0,retreg,retreg         /*    based on operand signs */
+       MILLIRETN
+       nop
+
+LSYM(small_divisor)
+
+#if defined(CONFIG_64BIT)
+/*  Clear the upper 32 bits of the arg1 register.  We are working with */
+/*  small divisors (and 32-bit integers)   We must not be mislead  */
+/*  by "1" bits left in the upper 32 bits.  */
+       depd %r0,31,32,%r25
+#endif
+       blr,n   arg1,r0
+       nop
+/*  table for divisor == 0,1, ... ,15 */
+       addit,= 0,arg1,r0       /*  trap if divisor == 0 */
+       nop
+       MILLIRET                /*  divisor == 1 */
+       copy    arg0,retreg
+       MILLI_BEN($$divI_2)     /*  divisor == 2 */
+       nop
+       MILLI_BEN($$divI_3)     /*  divisor == 3 */
+       nop
+       MILLI_BEN($$divI_4)     /*  divisor == 4 */
+       nop
+       MILLI_BEN($$divI_5)     /*  divisor == 5 */
+       nop
+       MILLI_BEN($$divI_6)     /*  divisor == 6 */
+       nop
+       MILLI_BEN($$divI_7)     /*  divisor == 7 */
+       nop
+       MILLI_BEN($$divI_8)     /*  divisor == 8 */
+       nop
+       MILLI_BEN($$divI_9)     /*  divisor == 9 */
+       nop
+       MILLI_BEN($$divI_10)    /*  divisor == 10 */
+       nop
+       b       LREF(normal)            /*  divisor == 11 */
+       add,>=  0,arg0,retreg
+       MILLI_BEN($$divI_12)    /*  divisor == 12 */
+       nop
+       b       LREF(normal)            /*  divisor == 13 */
+       add,>=  0,arg0,retreg
+       MILLI_BEN($$divI_14)    /*  divisor == 14 */
+       nop
+       MILLI_BEN($$divI_15)    /*  divisor == 15 */
+       nop
+
+LSYM(negative1)
+       sub     0,arg0,retreg   /*  result is negation of dividend */
+       MILLIRET
+       addo    arg0,arg1,r0    /*  trap iff dividend==0x80000000 && divisor==-1 */
+       .exit
+       .procend
+       .end
+#endif
diff --git a/arch/parisc/lib/milli/divU.S b/arch/parisc/lib/milli/divU.S
new file mode 100644 (file)
index 0000000..9287fe2
--- /dev/null
@@ -0,0 +1,235 @@
+/* 32 and 64-bit millicode, original author Hewlett-Packard
+   adapted for gcc by Paul Bame <bame@debian.org>
+   and Alan Modra <alan@linuxcare.com.au>.
+
+   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
+   This file is part of GCC and is released under the terms of
+   of the GNU General Public License as published by the Free Software
+   Foundation; either version 2, or (at your option) any later version.
+   See the file COPYING in the top-level GCC source directory for a copy
+   of the license.  */
+
+#include "milli.h"
+
+#ifdef L_divU
+/* ROUTINE:    $$divU
+   .
+   .   Single precision divide for unsigned integers.
+   .
+   .   Quotient is truncated towards zero.
+   .   Traps on divide by zero.
+
+   INPUT REGISTERS:
+   .   arg0 == dividend
+   .   arg1 == divisor
+   .   mrp  == return pc
+   .   sr0  == return space when called externally
+
+   OUTPUT REGISTERS:
+   .   arg0 =  undefined
+   .   arg1 =  undefined
+   .   ret1 =  quotient
+
+   OTHER REGISTERS AFFECTED:
+   .   r1   =  undefined
+
+   SIDE EFFECTS:
+   .   Causes a trap under the following conditions:
+   .           divisor is zero
+   .   Changes memory at the following places:
+   .           NONE
+
+   PERMISSIBLE CONTEXT:
+   .   Unwindable.
+   .   Does not create a stack frame.
+   .   Suitable for internal or external millicode.
+   .   Assumes the special millicode register conventions.
+
+   DISCUSSION:
+   .   Branchs to other millicode routines using BE:
+   .           $$divU_# for 3,5,6,7,9,10,12,14,15
+   .
+   .   For selected small divisors calls the special divide by constant
+   .   routines written by Karl Pettis.  These are: 3,5,6,7,9,10,12,14,15.  */
+
+RDEFINE(temp,r1)
+RDEFINE(retreg,ret1)   /* r29 */
+RDEFINE(temp1,arg0)
+       SUBSPA_MILLI_DIV
+       ATTR_MILLI
+       .export $$divU,millicode
+       .import $$divU_3,millicode
+       .import $$divU_5,millicode
+       .import $$divU_6,millicode
+       .import $$divU_7,millicode
+       .import $$divU_9,millicode
+       .import $$divU_10,millicode
+       .import $$divU_12,millicode
+       .import $$divU_14,millicode
+       .import $$divU_15,millicode
+       .proc
+       .callinfo       millicode
+       .entry
+GSYM($$divU)
+/* The subtract is not nullified since it does no harm and can be used
+   by the two cases that branch back to "normal".  */
+       ldo     -1(arg1),temp           /* is there at most one bit set ? */
+       and,=   arg1,temp,r0            /* if so, denominator is power of 2 */
+       b       LREF(regular_seq)
+       addit,= 0,arg1,0                /* trap for zero dvr */
+       copy    arg0,retreg
+       extru,= arg1,15,16,temp         /* test denominator with 0xffff0000 */
+       extru   retreg,15,16,retreg     /* retreg = retreg >> 16 */
+       or      arg1,temp,arg1          /* arg1 = arg1 | (arg1 >> 16) */
+       ldi     0xcc,temp1              /* setup 0xcc in temp1 */
+       extru,= arg1,23,8,temp          /* test denominator with 0xff00 */
+       extru   retreg,23,24,retreg     /* retreg = retreg >> 8 */
+       or      arg1,temp,arg1          /* arg1 = arg1 | (arg1 >> 8) */
+       ldi     0xaa,temp               /* setup 0xaa in temp */
+       extru,= arg1,27,4,r0            /* test denominator with 0xf0 */
+       extru   retreg,27,28,retreg     /* retreg = retreg >> 4 */
+       and,=   arg1,temp1,r0           /* test denominator with 0xcc */
+       extru   retreg,29,30,retreg     /* retreg = retreg >> 2 */
+       and,=   arg1,temp,r0            /* test denominator with 0xaa */
+       extru   retreg,30,31,retreg     /* retreg = retreg >> 1 */
+       MILLIRETN
+       nop     
+LSYM(regular_seq)
+       comib,>=  15,arg1,LREF(special_divisor)
+       subi    0,arg1,temp             /* clear carry, negate the divisor */
+       ds      r0,temp,r0              /* set V-bit to 1 */
+LSYM(normal)
+       add     arg0,arg0,retreg        /* shift msb bit into carry */
+       ds      r0,arg1,temp            /* 1st divide step, if no carry */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 2nd divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 3rd divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 4th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 5th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 6th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 7th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 8th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 9th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 10th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 11th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 12th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 13th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 14th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 15th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 16th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 17th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 18th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 19th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 20th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 21st divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 22nd divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 23rd divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 24th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 25th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 26th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 27th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 28th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 29th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 30th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 31st divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 32nd divide step, */
+       MILLIRET
+       addc    retreg,retreg,retreg    /* shift last retreg bit into retreg */
+
+/* Handle the cases where divisor is a small constant or has high bit on.  */
+LSYM(special_divisor)
+/*     blr     arg1,r0 */
+/*     comib,>,n  0,arg1,LREF(big_divisor) ; nullify previous instruction */
+
+/* Pratap 8/13/90. The 815 Stirling chip set has a bug that prevents us from
+   generating such a blr, comib sequence. A problem in nullification. So I
+   rewrote this code.  */
+
+#if defined(CONFIG_64BIT)
+/* Clear the upper 32 bits of the arg1 register.  We are working with
+   small divisors (and 32-bit unsigned integers)   We must not be mislead
+   by "1" bits left in the upper 32 bits.  */
+       depd %r0,31,32,%r25
+#endif
+       comib,> 0,arg1,LREF(big_divisor)
+       nop
+       blr     arg1,r0
+       nop
+
+LSYM(zero_divisor)     /* this label is here to provide external visibility */
+       addit,= 0,arg1,0                /* trap for zero dvr */
+       nop
+       MILLIRET                        /* divisor == 1 */
+       copy    arg0,retreg
+       MILLIRET                        /* divisor == 2 */
+       extru   arg0,30,31,retreg
+       MILLI_BEN($$divU_3)             /* divisor == 3 */
+       nop
+       MILLIRET                        /* divisor == 4 */
+       extru   arg0,29,30,retreg
+       MILLI_BEN($$divU_5)             /* divisor == 5 */
+       nop
+       MILLI_BEN($$divU_6)             /* divisor == 6 */
+       nop
+       MILLI_BEN($$divU_7)             /* divisor == 7 */
+       nop
+       MILLIRET                        /* divisor == 8 */
+       extru   arg0,28,29,retreg
+       MILLI_BEN($$divU_9)             /* divisor == 9 */
+       nop
+       MILLI_BEN($$divU_10)            /* divisor == 10 */
+       nop
+       b       LREF(normal)            /* divisor == 11 */
+       ds      r0,temp,r0              /* set V-bit to 1 */
+       MILLI_BEN($$divU_12)            /* divisor == 12 */
+       nop
+       b       LREF(normal)            /* divisor == 13 */
+       ds      r0,temp,r0              /* set V-bit to 1 */
+       MILLI_BEN($$divU_14)            /* divisor == 14 */
+       nop
+       MILLI_BEN($$divU_15)            /* divisor == 15 */
+       nop
+
+/* Handle the case where the high bit is on in the divisor.
+   Compute:    if( dividend>=divisor) quotient=1; else quotient=0;
+   Note:       dividend>==divisor iff dividend-divisor does not borrow
+   and         not borrow iff carry.  */
+LSYM(big_divisor)
+       sub     arg0,arg1,r0
+       MILLIRET
+       addc    r0,r0,retreg
+       .exit
+       .procend
+       .end
+#endif
diff --git a/arch/parisc/lib/milli/div_const.S b/arch/parisc/lib/milli/div_const.S
new file mode 100644 (file)
index 0000000..dd66007
--- /dev/null
@@ -0,0 +1,682 @@
+/* 32 and 64-bit millicode, original author Hewlett-Packard
+   adapted for gcc by Paul Bame <bame@debian.org>
+   and Alan Modra <alan@linuxcare.com.au>.
+
+   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
+   This file is part of GCC and is released under the terms of
+   of the GNU General Public License as published by the Free Software
+   Foundation; either version 2, or (at your option) any later version.
+   See the file COPYING in the top-level GCC source directory for a copy
+   of the license.  */
+
+#include "milli.h"
+
+#ifdef L_div_const
+/* ROUTINE:    $$divI_2
+   .           $$divI_3        $$divU_3
+   .           $$divI_4
+   .           $$divI_5        $$divU_5
+   .           $$divI_6        $$divU_6
+   .           $$divI_7        $$divU_7
+   .           $$divI_8
+   .           $$divI_9        $$divU_9
+   .           $$divI_10       $$divU_10
+   .
+   .           $$divI_12       $$divU_12
+   .
+   .           $$divI_14       $$divU_14
+   .           $$divI_15       $$divU_15
+   .           $$divI_16
+   .           $$divI_17       $$divU_17
+   .
+   .   Divide by selected constants for single precision binary integers.
+
+   INPUT REGISTERS:
+   .   arg0 == dividend
+   .   mrp  == return pc
+   .   sr0  == return space when called externally
+
+   OUTPUT REGISTERS:
+   .   arg0 =  undefined
+   .   arg1 =  undefined
+   .   ret1 =  quotient
+
+   OTHER REGISTERS AFFECTED:
+   .   r1   =  undefined
+
+   SIDE EFFECTS:
+   .   Causes a trap under the following conditions: NONE
+   .   Changes memory at the following places:  NONE
+
+   PERMISSIBLE CONTEXT:
+   .   Unwindable.
+   .   Does not create a stack frame.
+   .   Suitable for internal or external millicode.
+   .   Assumes the special millicode register conventions.
+
+   DISCUSSION:
+   .   Calls other millicode routines using mrp:  NONE
+   .   Calls other millicode routines:  NONE  */
+
+
+/* TRUNCATED DIVISION BY SMALL INTEGERS
+
+   We are interested in q(x) = floor(x/y), where x >= 0 and y > 0
+   (with y fixed).
+
+   Let a = floor(z/y), for some choice of z.  Note that z will be
+   chosen so that division by z is cheap.
+
+   Let r be the remainder(z/y).  In other words, r = z - ay.
+
+   Now, our method is to choose a value for b such that
+
+   q'(x) = floor((ax+b)/z)
+
+   is equal to q(x) over as large a range of x as possible.  If the
+   two are equal over a sufficiently large range, and if it is easy to
+   form the product (ax), and it is easy to divide by z, then we can
+   perform the division much faster than the general division algorithm.
+
+   So, we want the following to be true:
+
+   .   For x in the following range:
+   .
+   .       ky <= x < (k+1)y
+   .
+   .   implies that
+   .
+   .       k <= (ax+b)/z < (k+1)
+
+   We want to determine b such that this is true for all k in the
+   range {0..K} for some maximum K.
+
+   Since (ax+b) is an increasing function of x, we can take each
+   bound separately to determine the "best" value for b.
+
+   (ax+b)/z < (k+1)           implies
+
+   (a((k+1)y-1)+b < (k+1)z     implies
+
+   b < a + (k+1)(z-ay)        implies
+
+   b < a + (k+1)r
+
+   This needs to be true for all k in the range {0..K}.  In
+   particular, it is true for k = 0 and this leads to a maximum
+   acceptable value for b.
+
+   b < a+r   or   b <= a+r-1
+
+   Taking the other bound, we have
+
+   k <= (ax+b)/z              implies
+
+   k <= (aky+b)/z             implies
+
+   k(z-ay) <= b                       implies
+
+   kr <= b
+
+   Clearly, the largest range for k will be achieved by maximizing b,
+   when r is not zero. When r is zero, then the simplest choice for b
+   is 0.  When r is not 0, set
+
+   .   b = a+r-1
+
+   Now, by construction, q'(x) = floor((ax+b)/z) = q(x) = floor(x/y)
+   for all x in the range:
+
+   .   0 <= x < (K+1)y
+
+   We need to determine what K is.  Of our two bounds,
+
+   .   b < a+(k+1)r    is satisfied for all k >= 0, by construction.
+
+   The other bound is
+
+   .   kr <= b
+
+   This is always true if r = 0.  If r is not 0 (the usual case), then
+   K = floor((a+r-1)/r), is the maximum value for k.
+
+   Therefore, the formula q'(x) = floor((ax+b)/z) yields the correct
+   answer for q(x) = floor(x/y) when x is in the range
+
+   (0,(K+1)y-1)               K = floor((a+r-1)/r)
+
+   To be most useful, we want (K+1)y-1 = (max x) >= 2**32-1 so that
+   the formula for q'(x) yields the correct value of q(x) for all x
+   representable by a single word in HPPA.
+
+   We are also constrained in that computing the product (ax), adding
+   b, and dividing by z must all be done quickly, otherwise we will be
+   better off going through the general algorithm using the DS
+   instruction, which uses approximately 70 cycles.
+
+   For each y, there is a choice of z which satisfies the constraints
+   for (K+1)y >= 2**32.  We may not, however, be able to satisfy the
+   timing constraints for arbitrary y. It seems that z being equal to
+   a power of 2 or a power of 2 minus 1 is as good as we can do, since
+   it minimizes the time to do division by z.  We want the choice of z
+   to also result in a value for (a) that minimizes the computation of
+   the product (ax).  This is best achieved if (a) has a regular bit
+   pattern (so the multiplication can be done with shifts and adds).
+   The value of (a) also needs to be less than 2**32 so the product is
+   always guaranteed to fit in 2 words.
+
+   In actual practice, the following should be done:
+
+   1) For negative x, you should take the absolute value and remember
+   .  the fact so that the result can be negated.  This obviously does
+   .  not apply in the unsigned case.
+   2) For even y, you should factor out the power of 2 that divides y
+   .  and divide x by it.  You can then proceed by dividing by the
+   .  odd factor of y.
+
+   Here is a table of some odd values of y, and corresponding choices
+   for z which are "good".
+
+    y    z       r      a (hex)     max x (hex)
+
+    3  2**32     1     55555555      100000001
+    5  2**32     1     33333333      100000003
+    7  2**24-1   0       249249     (infinite)
+    9  2**24-1   0       1c71c7     (infinite)
+   11  2**20-1   0        1745d     (infinite)
+   13  2**24-1   0       13b13b     (infinite)
+   15  2**32     1     11111111      10000000d
+   17  2**32     1      f0f0f0f      10000000f
+
+   If r is 1, then b = a+r-1 = a.  This simplifies the computation
+   of (ax+b), since you can compute (x+1)(a) instead.  If r is 0,
+   then b = 0 is ok to use which simplifies (ax+b).
+
+   The bit patterns for 55555555, 33333333, and 11111111 are obviously
+   very regular.  The bit patterns for the other values of a above are:
+
+    y     (hex)          (binary)
+
+    7    249249  001001001001001001001001  << regular >>
+    9    1c71c7  000111000111000111000111  << regular >>
+   11     1745d  000000010111010001011101  << irregular >>
+   13    13b13b  000100111011000100111011  << irregular >>
+
+   The bit patterns for (a) corresponding to (y) of 11 and 13 may be
+   too irregular to warrant using this method.
+
+   When z is a power of 2 minus 1, then the division by z is slightly
+   more complicated, involving an iterative solution.
+
+   The code presented here solves division by 1 through 17, except for
+   11 and 13. There are algorithms for both signed and unsigned
+   quantities given.
+
+   TIMINGS (cycles)
+
+   divisor  positive  negative unsigned
+
+   .   1       2          2         2
+   .   2       4          4         2
+   .   3       19        21        19
+   .   4       4          4         2
+   .   5       18        22        19
+   .   6       19        22        19
+   .   8       4          4         2
+   .  10       18        19        17
+   .  12       18        20        18
+   .  15       16        18        16
+   .  16       4          4         2
+   .  17       16        18        16
+
+   Now, the algorithm for 7, 9, and 14 is an iterative one.  That is,
+   a loop body is executed until the tentative quotient is 0.  The
+   number of times the loop body is executed varies depending on the
+   dividend, but is never more than two times. If the dividend is
+   less than the divisor, then the loop body is not executed at all.
+   Each iteration adds 4 cycles to the timings.
+
+   divisor  positive  negative unsigned
+
+   .   7       19+4n    20+4n     20+4n    n = number of iterations
+   .   9       21+4n    22+4n     21+4n
+   .  14       21+4n    22+4n     20+4n
+
+   To give an idea of how the number of iterations varies, here is a
+   table of dividend versus number of iterations when dividing by 7.
+
+   smallest     largest       required
+   dividend    dividend      iterations
+
+   .   0            6              0
+   .   7        0x6ffffff          1
+   0x1000006   0xffffffff          2
+
+   There is some overlap in the range of numbers requiring 1 and 2
+   iterations. */
+
+RDEFINE(t2,r1)
+RDEFINE(x2,arg0)       /*  r26 */
+RDEFINE(t1,arg1)       /*  r25 */
+RDEFINE(x1,ret1)       /*  r29 */
+
+       SUBSPA_MILLI_DIV
+       ATTR_MILLI
+
+       .proc
+       .callinfo       millicode
+       .entry
+/* NONE of these routines require a stack frame
+   ALL of these routines are unwindable from millicode */
+
+GSYM($$divide_by_constant)
+       .export $$divide_by_constant,millicode
+/*  Provides a "nice" label for the code covered by the unwind descriptor
+    for things like gprof.  */
+
+/* DIVISION BY 2 (shift by 1) */
+GSYM($$divI_2)
+       .export         $$divI_2,millicode
+       comclr,>=       arg0,0,0
+       addi            1,arg0,arg0
+       MILLIRET
+       extrs           arg0,30,31,ret1
+
+
+/* DIVISION BY 4 (shift by 2) */
+GSYM($$divI_4)
+       .export         $$divI_4,millicode
+       comclr,>=       arg0,0,0
+       addi            3,arg0,arg0
+       MILLIRET
+       extrs           arg0,29,30,ret1
+
+
+/* DIVISION BY 8 (shift by 3) */
+GSYM($$divI_8)
+       .export         $$divI_8,millicode
+       comclr,>=       arg0,0,0
+       addi            7,arg0,arg0
+       MILLIRET
+       extrs           arg0,28,29,ret1
+
+/* DIVISION BY 16 (shift by 4) */
+GSYM($$divI_16)
+       .export         $$divI_16,millicode
+       comclr,>=       arg0,0,0
+       addi            15,arg0,arg0
+       MILLIRET
+       extrs           arg0,27,28,ret1
+
+/****************************************************************************
+*
+*      DIVISION BY DIVISORS OF FFFFFFFF, and powers of 2 times these
+*
+*      includes 3,5,15,17 and also 6,10,12
+*
+****************************************************************************/
+
+/* DIVISION BY 3 (use z = 2**32; a = 55555555) */
+
+GSYM($$divI_3)
+       .export         $$divI_3,millicode
+       comb,<,N        x2,0,LREF(neg3)
+
+       addi            1,x2,x2         /* this cannot overflow */
+       extru           x2,1,2,x1       /* multiply by 5 to get started */
+       sh2add          x2,x2,x2
+       b               LREF(pos)
+       addc            x1,0,x1
+
+LSYM(neg3)
+       subi            1,x2,x2         /* this cannot overflow */
+       extru           x2,1,2,x1       /* multiply by 5 to get started */
+       sh2add          x2,x2,x2
+       b               LREF(neg)
+       addc            x1,0,x1
+
+GSYM($$divU_3)
+       .export         $$divU_3,millicode
+       addi            1,x2,x2         /* this CAN overflow */
+       addc            0,0,x1
+       shd             x1,x2,30,t1     /* multiply by 5 to get started */
+       sh2add          x2,x2,x2
+       b               LREF(pos)
+       addc            x1,t1,x1
+
+/* DIVISION BY 5 (use z = 2**32; a = 33333333) */
+
+GSYM($$divI_5)
+       .export         $$divI_5,millicode
+       comb,<,N        x2,0,LREF(neg5)
+
+       addi            3,x2,t1         /* this cannot overflow */
+       sh1add          x2,t1,x2        /* multiply by 3 to get started */
+       b               LREF(pos)
+       addc            0,0,x1
+
+LSYM(neg5)
+       sub             0,x2,x2         /* negate x2                    */
+       addi            1,x2,x2         /* this cannot overflow */
+       shd             0,x2,31,x1      /* get top bit (can be 1)       */
+       sh1add          x2,x2,x2        /* multiply by 3 to get started */
+       b               LREF(neg)
+       addc            x1,0,x1
+
+GSYM($$divU_5)
+       .export         $$divU_5,millicode
+       addi            1,x2,x2         /* this CAN overflow */
+       addc            0,0,x1
+       shd             x1,x2,31,t1     /* multiply by 3 to get started */
+       sh1add          x2,x2,x2
+       b               LREF(pos)
+       addc            t1,x1,x1
+
+/* DIVISION BY 6 (shift to divide by 2 then divide by 3) */
+GSYM($$divI_6)
+       .export         $$divI_6,millicode
+       comb,<,N        x2,0,LREF(neg6)
+       extru           x2,30,31,x2     /* divide by 2                  */
+       addi            5,x2,t1         /* compute 5*(x2+1) = 5*x2+5    */
+       sh2add          x2,t1,x2        /* multiply by 5 to get started */
+       b               LREF(pos)
+       addc            0,0,x1
+
+LSYM(neg6)
+       subi            2,x2,x2         /* negate, divide by 2, and add 1 */
+                                       /* negation and adding 1 are done */
+                                       /* at the same time by the SUBI   */
+       extru           x2,30,31,x2
+       shd             0,x2,30,x1
+       sh2add          x2,x2,x2        /* multiply by 5 to get started */
+       b               LREF(neg)
+       addc            x1,0,x1
+
+GSYM($$divU_6)
+       .export         $$divU_6,millicode
+       extru           x2,30,31,x2     /* divide by 2 */
+       addi            1,x2,x2         /* cannot carry */
+       shd             0,x2,30,x1      /* multiply by 5 to get started */
+       sh2add          x2,x2,x2
+       b               LREF(pos)
+       addc            x1,0,x1
+
+/* DIVISION BY 10 (shift to divide by 2 then divide by 5) */
+GSYM($$divU_10)
+       .export         $$divU_10,millicode
+       extru           x2,30,31,x2     /* divide by 2 */
+       addi            3,x2,t1         /* compute 3*(x2+1) = (3*x2)+3  */
+       sh1add          x2,t1,x2        /* multiply by 3 to get started */
+       addc            0,0,x1
+LSYM(pos)
+       shd             x1,x2,28,t1     /* multiply by 0x11 */
+       shd             x2,0,28,t2
+       add             x2,t2,x2
+       addc            x1,t1,x1
+LSYM(pos_for_17)
+       shd             x1,x2,24,t1     /* multiply by 0x101 */
+       shd             x2,0,24,t2
+       add             x2,t2,x2
+       addc            x1,t1,x1
+
+       shd             x1,x2,16,t1     /* multiply by 0x10001 */
+       shd             x2,0,16,t2
+       add             x2,t2,x2
+       MILLIRET
+       addc            x1,t1,x1
+
+GSYM($$divI_10)
+       .export         $$divI_10,millicode
+       comb,<          x2,0,LREF(neg10)
+       copy            0,x1
+       extru           x2,30,31,x2     /* divide by 2 */
+       addib,TR        1,x2,LREF(pos)  /* add 1 (cannot overflow)     */
+       sh1add          x2,x2,x2        /* multiply by 3 to get started */
+
+LSYM(neg10)
+       subi            2,x2,x2         /* negate, divide by 2, and add 1 */
+                                       /* negation and adding 1 are done */
+                                       /* at the same time by the SUBI   */
+       extru           x2,30,31,x2
+       sh1add          x2,x2,x2        /* multiply by 3 to get started */
+LSYM(neg)
+       shd             x1,x2,28,t1     /* multiply by 0x11 */
+       shd             x2,0,28,t2
+       add             x2,t2,x2
+       addc            x1,t1,x1
+LSYM(neg_for_17)
+       shd             x1,x2,24,t1     /* multiply by 0x101 */
+       shd             x2,0,24,t2
+       add             x2,t2,x2
+       addc            x1,t1,x1
+
+       shd             x1,x2,16,t1     /* multiply by 0x10001 */
+       shd             x2,0,16,t2
+       add             x2,t2,x2
+       addc            x1,t1,x1
+       MILLIRET
+       sub             0,x1,x1
+
+/* DIVISION BY 12 (shift to divide by 4 then divide by 3) */
+GSYM($$divI_12)
+       .export         $$divI_12,millicode
+       comb,<          x2,0,LREF(neg12)
+       copy            0,x1
+       extru           x2,29,30,x2     /* divide by 4                  */
+       addib,tr        1,x2,LREF(pos)  /* compute 5*(x2+1) = 5*x2+5    */
+       sh2add          x2,x2,x2        /* multiply by 5 to get started */
+
+LSYM(neg12)
+       subi            4,x2,x2         /* negate, divide by 4, and add 1 */
+                                       /* negation and adding 1 are done */
+                                       /* at the same time by the SUBI   */
+       extru           x2,29,30,x2
+       b               LREF(neg)
+       sh2add          x2,x2,x2        /* multiply by 5 to get started */
+
+GSYM($$divU_12)
+       .export         $$divU_12,millicode
+       extru           x2,29,30,x2     /* divide by 4   */
+       addi            5,x2,t1         /* cannot carry */
+       sh2add          x2,t1,x2        /* multiply by 5 to get started */
+       b               LREF(pos)
+       addc            0,0,x1
+
+/* DIVISION BY 15 (use z = 2**32; a = 11111111) */
+GSYM($$divI_15)
+       .export         $$divI_15,millicode
+       comb,<          x2,0,LREF(neg15)
+       copy            0,x1
+       addib,tr        1,x2,LREF(pos)+4
+       shd             x1,x2,28,t1
+
+LSYM(neg15)
+       b               LREF(neg)
+       subi            1,x2,x2
+
+GSYM($$divU_15)
+       .export         $$divU_15,millicode
+       addi            1,x2,x2         /* this CAN overflow */
+       b               LREF(pos)
+       addc            0,0,x1
+
+/* DIVISION BY 17 (use z = 2**32; a =  f0f0f0f) */
+GSYM($$divI_17)
+       .export         $$divI_17,millicode
+       comb,<,n        x2,0,LREF(neg17)
+       addi            1,x2,x2         /* this cannot overflow */
+       shd             0,x2,28,t1      /* multiply by 0xf to get started */
+       shd             x2,0,28,t2
+       sub             t2,x2,x2
+       b               LREF(pos_for_17)
+       subb            t1,0,x1
+
+LSYM(neg17)
+       subi            1,x2,x2         /* this cannot overflow */
+       shd             0,x2,28,t1      /* multiply by 0xf to get started */
+       shd             x2,0,28,t2
+       sub             t2,x2,x2
+       b               LREF(neg_for_17)
+       subb            t1,0,x1
+
+GSYM($$divU_17)
+       .export         $$divU_17,millicode
+       addi            1,x2,x2         /* this CAN overflow */
+       addc            0,0,x1
+       shd             x1,x2,28,t1     /* multiply by 0xf to get started */
+LSYM(u17)
+       shd             x2,0,28,t2
+       sub             t2,x2,x2
+       b               LREF(pos_for_17)
+       subb            t1,x1,x1
+
+
+/* DIVISION BY DIVISORS OF FFFFFF, and powers of 2 times these
+   includes 7,9 and also 14
+
+
+   z = 2**24-1
+   r = z mod x = 0
+
+   so choose b = 0
+
+   Also, in order to divide by z = 2**24-1, we approximate by dividing
+   by (z+1) = 2**24 (which is easy), and then correcting.
+
+   (ax) = (z+1)q' + r
+   .   = zq' + (q'+r)
+
+   So to compute (ax)/z, compute q' = (ax)/(z+1) and r = (ax) mod (z+1)
+   Then the true remainder of (ax)/z is (q'+r).  Repeat the process
+   with this new remainder, adding the tentative quotients together,
+   until a tentative quotient is 0 (and then we are done).  There is
+   one last correction to be done.  It is possible that (q'+r) = z.
+   If so, then (q'+r)/(z+1) = 0 and it looks like we are done. But,
+   in fact, we need to add 1 more to the quotient.  Now, it turns
+   out that this happens if and only if the original value x is
+   an exact multiple of y.  So, to avoid a three instruction test at
+   the end, instead use 1 instruction to add 1 to x at the beginning.  */
+
+/* DIVISION BY 7 (use z = 2**24-1; a = 249249) */
+GSYM($$divI_7)
+       .export         $$divI_7,millicode
+       comb,<,n        x2,0,LREF(neg7)
+LSYM(7)
+       addi            1,x2,x2         /* cannot overflow */
+       shd             0,x2,29,x1
+       sh3add          x2,x2,x2
+       addc            x1,0,x1
+LSYM(pos7)
+       shd             x1,x2,26,t1
+       shd             x2,0,26,t2
+       add             x2,t2,x2
+       addc            x1,t1,x1
+
+       shd             x1,x2,20,t1
+       shd             x2,0,20,t2
+       add             x2,t2,x2
+       addc            x1,t1,t1
+
+       /* computed <t1,x2>.  Now divide it by (2**24 - 1)      */
+
+       copy            0,x1
+       shd,=           t1,x2,24,t1     /* tentative quotient  */
+LSYM(1)
+       addb,tr         t1,x1,LREF(2)   /* add to previous quotient   */
+       extru           x2,31,24,x2     /* new remainder (unadjusted) */
+
+       MILLIRETN
+
+LSYM(2)
+       addb,tr         t1,x2,LREF(1)   /* adjust remainder */
+       extru,=         x2,7,8,t1       /* new quotient     */
+
+LSYM(neg7)
+       subi            1,x2,x2         /* negate x2 and add 1 */
+LSYM(8)
+       shd             0,x2,29,x1
+       sh3add          x2,x2,x2
+       addc            x1,0,x1
+
+LSYM(neg7_shift)
+       shd             x1,x2,26,t1
+       shd             x2,0,26,t2
+       add             x2,t2,x2
+       addc            x1,t1,x1
+
+       shd             x1,x2,20,t1
+       shd             x2,0,20,t2
+       add             x2,t2,x2
+       addc            x1,t1,t1
+
+       /* computed <t1,x2>.  Now divide it by (2**24 - 1)      */
+
+       copy            0,x1
+       shd,=           t1,x2,24,t1     /* tentative quotient  */
+LSYM(3)
+       addb,tr         t1,x1,LREF(4)   /* add to previous quotient   */
+       extru           x2,31,24,x2     /* new remainder (unadjusted) */
+
+       MILLIRET
+       sub             0,x1,x1         /* negate result    */
+
+LSYM(4)
+       addb,tr         t1,x2,LREF(3)   /* adjust remainder */
+       extru,=         x2,7,8,t1       /* new quotient     */
+
+GSYM($$divU_7)
+       .export         $$divU_7,millicode
+       addi            1,x2,x2         /* can carry */
+       addc            0,0,x1
+       shd             x1,x2,29,t1
+       sh3add          x2,x2,x2
+       b               LREF(pos7)
+       addc            t1,x1,x1
+
+/* DIVISION BY 9 (use z = 2**24-1; a = 1c71c7) */
+GSYM($$divI_9)
+       .export         $$divI_9,millicode
+       comb,<,n        x2,0,LREF(neg9)
+       addi            1,x2,x2         /* cannot overflow */
+       shd             0,x2,29,t1
+       shd             x2,0,29,t2
+       sub             t2,x2,x2
+       b               LREF(pos7)
+       subb            t1,0,x1
+
+LSYM(neg9)
+       subi            1,x2,x2         /* negate and add 1 */
+       shd             0,x2,29,t1
+       shd             x2,0,29,t2
+       sub             t2,x2,x2
+       b               LREF(neg7_shift)
+       subb            t1,0,x1
+
+GSYM($$divU_9)
+       .export         $$divU_9,millicode
+       addi            1,x2,x2         /* can carry */
+       addc            0,0,x1
+       shd             x1,x2,29,t1
+       shd             x2,0,29,t2
+       sub             t2,x2,x2
+       b               LREF(pos7)
+       subb            t1,x1,x1
+
+/* DIVISION BY 14 (shift to divide by 2 then divide by 7) */
+GSYM($$divI_14)
+       .export         $$divI_14,millicode
+       comb,<,n        x2,0,LREF(neg14)
+GSYM($$divU_14)
+       .export         $$divU_14,millicode
+       b               LREF(7)         /* go to 7 case */
+       extru           x2,30,31,x2     /* divide by 2  */
+
+LSYM(neg14)
+       subi            2,x2,x2         /* negate (and add 2) */
+       b               LREF(8)
+       extru           x2,30,31,x2     /* divide by 2        */
+       .exit
+       .procend
+       .end
+#endif
diff --git a/arch/parisc/lib/milli/dyncall.S b/arch/parisc/lib/milli/dyncall.S
new file mode 100644 (file)
index 0000000..27f9ca5
--- /dev/null
@@ -0,0 +1,32 @@
+/* 32 and 64-bit millicode, original author Hewlett-Packard
+   adapted for gcc by Paul Bame <bame@debian.org>
+   and Alan Modra <alan@linuxcare.com.au>.
+
+   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
+   This file is part of GCC and is released under the terms of
+   of the GNU General Public License as published by the Free Software
+   Foundation; either version 2, or (at your option) any later version.
+   See the file COPYING in the top-level GCC source directory for a copy
+   of the license.  */
+
+#include "milli.h"
+
+#ifdef L_dyncall
+       SUBSPA_MILLI
+       ATTR_DATA
+GSYM($$dyncall)
+       .export $$dyncall,millicode
+       .proc
+       .callinfo       millicode
+       .entry
+       bb,>=,n %r22,30,LREF(1)         ; branch if not plabel address
+       depi    0,31,2,%r22             ; clear the two least significant bits
+       ldw     4(%r22),%r19            ; load new LTP value
+       ldw     0(%r22),%r22            ; load address of target
+LSYM(1)
+       bv      %r0(%r22)               ; branch to the real target
+       stw     %r2,-24(%r30)           ; save return address into frame marker
+       .exit
+       .procend
+#endif
diff --git a/arch/parisc/lib/milli/milli.S b/arch/parisc/lib/milli/milli.S
new file mode 100644 (file)
index 0000000..47c6cde
--- /dev/null
@@ -0,0 +1,2071 @@
+/* 32 and 64-bit millicode, original author Hewlett-Packard
+   adapted for gcc by Paul Bame <bame@debian.org>
+   and Alan Modra <alan@linuxcare.com.au>.
+
+   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
+   This file is part of GCC and is released under the terms of
+   of the GNU General Public License as published by the Free Software
+   Foundation; either version 2, or (at your option) any later version.
+   See the file COPYING in the top-level GCC source directory for a copy
+   of the license.  */
+
+#ifdef CONFIG_64BIT
+        .level  2.0w
+#endif
+
+/* Hardware General Registers.  */
+r0:    .reg    %r0
+r1:    .reg    %r1
+r2:    .reg    %r2
+r3:    .reg    %r3
+r4:    .reg    %r4
+r5:    .reg    %r5
+r6:    .reg    %r6
+r7:    .reg    %r7
+r8:    .reg    %r8
+r9:    .reg    %r9
+r10:   .reg    %r10
+r11:   .reg    %r11
+r12:   .reg    %r12
+r13:   .reg    %r13
+r14:   .reg    %r14
+r15:   .reg    %r15
+r16:   .reg    %r16
+r17:   .reg    %r17
+r18:   .reg    %r18
+r19:   .reg    %r19
+r20:   .reg    %r20
+r21:   .reg    %r21
+r22:   .reg    %r22
+r23:   .reg    %r23
+r24:   .reg    %r24
+r25:   .reg    %r25
+r26:   .reg    %r26
+r27:   .reg    %r27
+r28:   .reg    %r28
+r29:   .reg    %r29
+r30:   .reg    %r30
+r31:   .reg    %r31
+
+/* Hardware Space Registers.  */
+sr0:   .reg    %sr0
+sr1:   .reg    %sr1
+sr2:   .reg    %sr2
+sr3:   .reg    %sr3
+sr4:   .reg    %sr4
+sr5:   .reg    %sr5
+sr6:   .reg    %sr6
+sr7:   .reg    %sr7
+
+/* Hardware Floating Point Registers.  */
+fr0:   .reg    %fr0
+fr1:   .reg    %fr1
+fr2:   .reg    %fr2
+fr3:   .reg    %fr3
+fr4:   .reg    %fr4
+fr5:   .reg    %fr5
+fr6:   .reg    %fr6
+fr7:   .reg    %fr7
+fr8:   .reg    %fr8
+fr9:   .reg    %fr9
+fr10:  .reg    %fr10
+fr11:  .reg    %fr11
+fr12:  .reg    %fr12
+fr13:  .reg    %fr13
+fr14:  .reg    %fr14
+fr15:  .reg    %fr15
+
+/* Hardware Control Registers.  */
+cr11:  .reg    %cr11
+sar:   .reg    %cr11   /* Shift Amount Register */
+
+/* Software Architecture General Registers.  */
+rp:    .reg    r2      /* return pointer */
+#ifdef CONFIG_64BIT
+mrp:   .reg    r2      /* millicode return pointer */
+#else
+mrp:   .reg    r31     /* millicode return pointer */
+#endif
+ret0:  .reg    r28     /* return value */
+ret1:  .reg    r29     /* return value (high part of double) */
+sp:    .reg    r30     /* stack pointer */
+dp:    .reg    r27     /* data pointer */
+arg0:  .reg    r26     /* argument */
+arg1:  .reg    r25     /* argument or high part of double argument */
+arg2:  .reg    r24     /* argument */
+arg3:  .reg    r23     /* argument or high part of double argument */
+
+/* Software Architecture Space Registers.  */
+/*             sr0     ; return link from BLE */
+sret:  .reg    sr1     /* return value */
+sarg:  .reg    sr1     /* argument */
+/*             sr4     ; PC SPACE tracker */
+/*             sr5     ; process private data */
+
+/* Frame Offsets (millicode convention!)  Used when calling other
+   millicode routines.  Stack unwinding is dependent upon these
+   definitions.  */
+r31_slot:      .equ    -20     /* "current RP" slot */
+sr0_slot:      .equ    -16     /* "static link" slot */
+#if defined(CONFIG_64BIT)
+mrp_slot:       .equ    -16    /* "current RP" slot */
+psp_slot:       .equ    -8     /* "previous SP" slot */
+#else
+mrp_slot:      .equ    -20     /* "current RP" slot (replacing "r31_slot") */
+#endif
+
+
+#define DEFINE(name,value)name:        .EQU    value
+#define RDEFINE(name,value)name:       .REG    value
+#ifdef milliext
+#define MILLI_BE(lbl)   BE    lbl(sr7,r0)
+#define MILLI_BEN(lbl)  BE,n  lbl(sr7,r0)
+#define MILLI_BLE(lbl) BLE   lbl(sr7,r0)
+#define MILLI_BLEN(lbl)        BLE,n lbl(sr7,r0)
+#define MILLIRETN      BE,n  0(sr0,mrp)
+#define MILLIRET       BE    0(sr0,mrp)
+#define MILLI_RETN     BE,n  0(sr0,mrp)
+#define MILLI_RET      BE    0(sr0,mrp)
+#else
+#define MILLI_BE(lbl)  B     lbl
+#define MILLI_BEN(lbl)  B,n   lbl
+#define MILLI_BLE(lbl) BL    lbl,mrp
+#define MILLI_BLEN(lbl)        BL,n  lbl,mrp
+#define MILLIRETN      BV,n  0(mrp)
+#define MILLIRET       BV    0(mrp)
+#define MILLI_RETN     BV,n  0(mrp)
+#define MILLI_RET      BV    0(mrp)
+#endif
+
+#define CAT(a,b)       a##b
+
+#define SUBSPA_MILLI    .section .text
+#define SUBSPA_MILLI_DIV .section .text.div,"ax",@progbits! .align 16
+#define SUBSPA_MILLI_MUL .section .text.mul,"ax",@progbits! .align 16
+#define ATTR_MILLI
+#define SUBSPA_DATA     .section .data
+#define ATTR_DATA
+#define GLOBAL          $global$
+#define GSYM(sym)       !sym:
+#define LSYM(sym)       !CAT(.L,sym:)
+#define LREF(sym)       CAT(.L,sym)
+
+#ifdef L_dyncall
+       SUBSPA_MILLI
+       ATTR_DATA
+GSYM($$dyncall)
+       .export $$dyncall,millicode
+       .proc
+       .callinfo       millicode
+       .entry
+       bb,>=,n %r22,30,LREF(1)         ; branch if not plabel address
+       depi    0,31,2,%r22             ; clear the two least significant bits
+       ldw     4(%r22),%r19            ; load new LTP value
+       ldw     0(%r22),%r22            ; load address of target
+LSYM(1)
+       bv      %r0(%r22)               ; branch to the real target
+       stw     %r2,-24(%r30)           ; save return address into frame marker
+       .exit
+       .procend
+#endif
+
+#ifdef L_divI
+/* ROUTINES:   $$divI, $$divoI
+
+   Single precision divide for signed binary integers.
+
+   The quotient is truncated towards zero.
+   The sign of the quotient is the XOR of the signs of the dividend and
+   divisor.
+   Divide by zero is trapped.
+   Divide of -2**31 by -1 is trapped for $$divoI but not for $$divI.
+
+   INPUT REGISTERS:
+   .   arg0 == dividend
+   .   arg1 == divisor
+   .   mrp  == return pc
+   .   sr0  == return space when called externally
+
+   OUTPUT REGISTERS:
+   .   arg0 =  undefined
+   .   arg1 =  undefined
+   .   ret1 =  quotient
+
+   OTHER REGISTERS AFFECTED:
+   .   r1   =  undefined
+
+   SIDE EFFECTS:
+   .   Causes a trap under the following conditions:
+   .           divisor is zero  (traps with ADDIT,=  0,25,0)
+   .           dividend==-2**31  and divisor==-1 and routine is $$divoI
+   .                            (traps with ADDO  26,25,0)
+   .   Changes memory at the following places:
+   .           NONE
+
+   PERMISSIBLE CONTEXT:
+   .   Unwindable.
+   .   Suitable for internal or external millicode.
+   .   Assumes the special millicode register conventions.
+
+   DISCUSSION:
+   .   Branchs to other millicode routines using BE
+   .           $$div_# for # being 2,3,4,5,6,7,8,9,10,12,14,15
+   .
+   .   For selected divisors, calls a divide by constant routine written by
+   .   Karl Pettis.  Eligible divisors are 1..15 excluding 11 and 13.
+   .
+   .   The only overflow case is -2**31 divided by -1.
+   .   Both routines return -2**31 but only $$divoI traps.  */
+
+RDEFINE(temp,r1)
+RDEFINE(retreg,ret1)   /*  r29 */
+RDEFINE(temp1,arg0)
+       SUBSPA_MILLI_DIV
+       ATTR_MILLI
+       .import $$divI_2,millicode
+       .import $$divI_3,millicode
+       .import $$divI_4,millicode
+       .import $$divI_5,millicode
+       .import $$divI_6,millicode
+       .import $$divI_7,millicode
+       .import $$divI_8,millicode
+       .import $$divI_9,millicode
+       .import $$divI_10,millicode
+       .import $$divI_12,millicode
+       .import $$divI_14,millicode
+       .import $$divI_15,millicode
+       .export $$divI,millicode
+       .export $$divoI,millicode
+       .proc
+       .callinfo       millicode
+       .entry
+GSYM($$divoI)
+       comib,=,n  -1,arg1,LREF(negative1)      /*  when divisor == -1 */
+GSYM($$divI)
+       ldo     -1(arg1),temp           /*  is there at most one bit set ? */
+       and,<>  arg1,temp,r0            /*  if not, don't use power of 2 divide */
+       addi,>  0,arg1,r0               /*  if divisor > 0, use power of 2 divide */
+       b,n     LREF(neg_denom)
+LSYM(pow2)
+       addi,>= 0,arg0,retreg           /*  if numerator is negative, add the */
+       add     arg0,temp,retreg        /*  (denominaotr -1) to correct for shifts */
+       extru,= arg1,15,16,temp         /*  test denominator with 0xffff0000 */
+       extrs   retreg,15,16,retreg     /*  retreg = retreg >> 16 */
+       or      arg1,temp,arg1          /*  arg1 = arg1 | (arg1 >> 16) */
+       ldi     0xcc,temp1              /*  setup 0xcc in temp1 */
+       extru,= arg1,23,8,temp          /*  test denominator with 0xff00 */
+       extrs   retreg,23,24,retreg     /*  retreg = retreg >> 8 */
+       or      arg1,temp,arg1          /*  arg1 = arg1 | (arg1 >> 8) */
+       ldi     0xaa,temp               /*  setup 0xaa in temp */
+       extru,= arg1,27,4,r0            /*  test denominator with 0xf0 */
+       extrs   retreg,27,28,retreg     /*  retreg = retreg >> 4 */
+       and,=   arg1,temp1,r0           /*  test denominator with 0xcc */
+       extrs   retreg,29,30,retreg     /*  retreg = retreg >> 2 */
+       and,=   arg1,temp,r0            /*  test denominator with 0xaa */
+       extrs   retreg,30,31,retreg     /*  retreg = retreg >> 1 */
+       MILLIRETN
+LSYM(neg_denom)
+       addi,<  0,arg1,r0               /*  if arg1 >= 0, it's not power of 2 */
+       b,n     LREF(regular_seq)
+       sub     r0,arg1,temp            /*  make denominator positive */
+       comb,=,n  arg1,temp,LREF(regular_seq)   /*  test against 0x80000000 and 0 */
+       ldo     -1(temp),retreg         /*  is there at most one bit set ? */
+       and,=   temp,retreg,r0          /*  if so, the denominator is power of 2 */
+       b,n     LREF(regular_seq)
+       sub     r0,arg0,retreg          /*  negate numerator */
+       comb,=,n arg0,retreg,LREF(regular_seq) /*  test against 0x80000000 */
+       copy    retreg,arg0             /*  set up arg0, arg1 and temp  */
+       copy    temp,arg1               /*  before branching to pow2 */
+       b       LREF(pow2)
+       ldo     -1(arg1),temp
+LSYM(regular_seq)
+       comib,>>=,n 15,arg1,LREF(small_divisor)
+       add,>=  0,arg0,retreg           /*  move dividend, if retreg < 0, */
+LSYM(normal)
+       subi    0,retreg,retreg         /*    make it positive */
+       sub     0,arg1,temp             /*  clear carry,  */
+                                       /*    negate the divisor */
+       ds      0,temp,0                /*  set V-bit to the comple- */
+                                       /*    ment of the divisor sign */
+       add     retreg,retreg,retreg    /*  shift msb bit into carry */
+       ds      r0,arg1,temp            /*  1st divide step, if no carry */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  2nd divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  3rd divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  4th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  5th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  6th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  7th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  8th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  9th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  10th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  11th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  12th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  13th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  14th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  15th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  16th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  17th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  18th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  19th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  20th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  21st divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  22nd divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  23rd divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  24th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  25th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  26th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  27th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  28th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  29th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  30th divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  31st divide step */
+       addc    retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds      temp,arg1,temp          /*  32nd divide step, */
+       addc    retreg,retreg,retreg    /*  shift last retreg bit into retreg */
+       xor,>=  arg0,arg1,0             /*  get correct sign of quotient */
+         sub   0,retreg,retreg         /*    based on operand signs */
+       MILLIRETN
+       nop
+
+LSYM(small_divisor)
+
+#if defined(CONFIG_64BIT)
+/*  Clear the upper 32 bits of the arg1 register.  We are working with */
+/*  small divisors (and 32-bit integers)   We must not be mislead  */
+/*  by "1" bits left in the upper 32 bits.  */
+       depd %r0,31,32,%r25
+#endif
+       blr,n   arg1,r0
+       nop
+/*  table for divisor == 0,1, ... ,15 */
+       addit,= 0,arg1,r0       /*  trap if divisor == 0 */
+       nop
+       MILLIRET                /*  divisor == 1 */
+       copy    arg0,retreg
+       MILLI_BEN($$divI_2)     /*  divisor == 2 */
+       nop
+       MILLI_BEN($$divI_3)     /*  divisor == 3 */
+       nop
+       MILLI_BEN($$divI_4)     /*  divisor == 4 */
+       nop
+       MILLI_BEN($$divI_5)     /*  divisor == 5 */
+       nop
+       MILLI_BEN($$divI_6)     /*  divisor == 6 */
+       nop
+       MILLI_BEN($$divI_7)     /*  divisor == 7 */
+       nop
+       MILLI_BEN($$divI_8)     /*  divisor == 8 */
+       nop
+       MILLI_BEN($$divI_9)     /*  divisor == 9 */
+       nop
+       MILLI_BEN($$divI_10)    /*  divisor == 10 */
+       nop
+       b       LREF(normal)            /*  divisor == 11 */
+       add,>=  0,arg0,retreg
+       MILLI_BEN($$divI_12)    /*  divisor == 12 */
+       nop
+       b       LREF(normal)            /*  divisor == 13 */
+       add,>=  0,arg0,retreg
+       MILLI_BEN($$divI_14)    /*  divisor == 14 */
+       nop
+       MILLI_BEN($$divI_15)    /*  divisor == 15 */
+       nop
+
+LSYM(negative1)
+       sub     0,arg0,retreg   /*  result is negation of dividend */
+       MILLIRET
+       addo    arg0,arg1,r0    /*  trap iff dividend==0x80000000 && divisor==-1 */
+       .exit
+       .procend
+       .end
+#endif
+
+#ifdef L_divU
+/* ROUTINE:    $$divU
+   .
+   .   Single precision divide for unsigned integers.
+   .
+   .   Quotient is truncated towards zero.
+   .   Traps on divide by zero.
+
+   INPUT REGISTERS:
+   .   arg0 == dividend
+   .   arg1 == divisor
+   .   mrp  == return pc
+   .   sr0  == return space when called externally
+
+   OUTPUT REGISTERS:
+   .   arg0 =  undefined
+   .   arg1 =  undefined
+   .   ret1 =  quotient
+
+   OTHER REGISTERS AFFECTED:
+   .   r1   =  undefined
+
+   SIDE EFFECTS:
+   .   Causes a trap under the following conditions:
+   .           divisor is zero
+   .   Changes memory at the following places:
+   .           NONE
+
+   PERMISSIBLE CONTEXT:
+   .   Unwindable.
+   .   Does not create a stack frame.
+   .   Suitable for internal or external millicode.
+   .   Assumes the special millicode register conventions.
+
+   DISCUSSION:
+   .   Branchs to other millicode routines using BE:
+   .           $$divU_# for 3,5,6,7,9,10,12,14,15
+   .
+   .   For selected small divisors calls the special divide by constant
+   .   routines written by Karl Pettis.  These are: 3,5,6,7,9,10,12,14,15.  */
+
+RDEFINE(temp,r1)
+RDEFINE(retreg,ret1)   /* r29 */
+RDEFINE(temp1,arg0)
+       SUBSPA_MILLI_DIV
+       ATTR_MILLI
+       .export $$divU,millicode
+       .import $$divU_3,millicode
+       .import $$divU_5,millicode
+       .import $$divU_6,millicode
+       .import $$divU_7,millicode
+       .import $$divU_9,millicode
+       .import $$divU_10,millicode
+       .import $$divU_12,millicode
+       .import $$divU_14,millicode
+       .import $$divU_15,millicode
+       .proc
+       .callinfo       millicode
+       .entry
+GSYM($$divU)
+/* The subtract is not nullified since it does no harm and can be used
+   by the two cases that branch back to "normal".  */
+       ldo     -1(arg1),temp           /* is there at most one bit set ? */
+       and,=   arg1,temp,r0            /* if so, denominator is power of 2 */
+       b       LREF(regular_seq)
+       addit,= 0,arg1,0                /* trap for zero dvr */
+       copy    arg0,retreg
+       extru,= arg1,15,16,temp         /* test denominator with 0xffff0000 */
+       extru   retreg,15,16,retreg     /* retreg = retreg >> 16 */
+       or      arg1,temp,arg1          /* arg1 = arg1 | (arg1 >> 16) */
+       ldi     0xcc,temp1              /* setup 0xcc in temp1 */
+       extru,= arg1,23,8,temp          /* test denominator with 0xff00 */
+       extru   retreg,23,24,retreg     /* retreg = retreg >> 8 */
+       or      arg1,temp,arg1          /* arg1 = arg1 | (arg1 >> 8) */
+       ldi     0xaa,temp               /* setup 0xaa in temp */
+       extru,= arg1,27,4,r0            /* test denominator with 0xf0 */
+       extru   retreg,27,28,retreg     /* retreg = retreg >> 4 */
+       and,=   arg1,temp1,r0           /* test denominator with 0xcc */
+       extru   retreg,29,30,retreg     /* retreg = retreg >> 2 */
+       and,=   arg1,temp,r0            /* test denominator with 0xaa */
+       extru   retreg,30,31,retreg     /* retreg = retreg >> 1 */
+       MILLIRETN
+       nop     
+LSYM(regular_seq)
+       comib,>=  15,arg1,LREF(special_divisor)
+       subi    0,arg1,temp             /* clear carry, negate the divisor */
+       ds      r0,temp,r0              /* set V-bit to 1 */
+LSYM(normal)
+       add     arg0,arg0,retreg        /* shift msb bit into carry */
+       ds      r0,arg1,temp            /* 1st divide step, if no carry */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 2nd divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 3rd divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 4th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 5th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 6th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 7th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 8th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 9th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 10th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 11th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 12th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 13th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 14th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 15th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 16th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 17th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 18th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 19th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 20th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 21st divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 22nd divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 23rd divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 24th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 25th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 26th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 27th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 28th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 29th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 30th divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 31st divide step */
+       addc    retreg,retreg,retreg    /* shift retreg with/into carry */
+       ds      temp,arg1,temp          /* 32nd divide step, */
+       MILLIRET
+       addc    retreg,retreg,retreg    /* shift last retreg bit into retreg */
+
+/* Handle the cases where divisor is a small constant or has high bit on.  */
+LSYM(special_divisor)
+/*     blr     arg1,r0 */
+/*     comib,>,n  0,arg1,LREF(big_divisor) ; nullify previous instruction */
+
+/* Pratap 8/13/90. The 815 Stirling chip set has a bug that prevents us from
+   generating such a blr, comib sequence. A problem in nullification. So I
+   rewrote this code.  */
+
+#if defined(CONFIG_64BIT)
+/* Clear the upper 32 bits of the arg1 register.  We are working with
+   small divisors (and 32-bit unsigned integers)   We must not be mislead
+   by "1" bits left in the upper 32 bits.  */
+       depd %r0,31,32,%r25
+#endif
+       comib,> 0,arg1,LREF(big_divisor)
+       nop
+       blr     arg1,r0
+       nop
+
+LSYM(zero_divisor)     /* this label is here to provide external visibility */
+       addit,= 0,arg1,0                /* trap for zero dvr */
+       nop
+       MILLIRET                        /* divisor == 1 */
+       copy    arg0,retreg
+       MILLIRET                        /* divisor == 2 */
+       extru   arg0,30,31,retreg
+       MILLI_BEN($$divU_3)             /* divisor == 3 */
+       nop
+       MILLIRET                        /* divisor == 4 */
+       extru   arg0,29,30,retreg
+       MILLI_BEN($$divU_5)             /* divisor == 5 */
+       nop
+       MILLI_BEN($$divU_6)             /* divisor == 6 */
+       nop
+       MILLI_BEN($$divU_7)             /* divisor == 7 */
+       nop
+       MILLIRET                        /* divisor == 8 */
+       extru   arg0,28,29,retreg
+       MILLI_BEN($$divU_9)             /* divisor == 9 */
+       nop
+       MILLI_BEN($$divU_10)            /* divisor == 10 */
+       nop
+       b       LREF(normal)            /* divisor == 11 */
+       ds      r0,temp,r0              /* set V-bit to 1 */
+       MILLI_BEN($$divU_12)            /* divisor == 12 */
+       nop
+       b       LREF(normal)            /* divisor == 13 */
+       ds      r0,temp,r0              /* set V-bit to 1 */
+       MILLI_BEN($$divU_14)            /* divisor == 14 */
+       nop
+       MILLI_BEN($$divU_15)            /* divisor == 15 */
+       nop
+
+/* Handle the case where the high bit is on in the divisor.
+   Compute:    if( dividend>=divisor) quotient=1; else quotient=0;
+   Note:       dividend>==divisor iff dividend-divisor does not borrow
+   and         not borrow iff carry.  */
+LSYM(big_divisor)
+       sub     arg0,arg1,r0
+       MILLIRET
+       addc    r0,r0,retreg
+       .exit
+       .procend
+       .end
+#endif
+
+#ifdef L_remI
+/* ROUTINE:    $$remI
+
+   DESCRIPTION:
+   .   $$remI returns the remainder of the division of two signed 32-bit
+   .   integers.  The sign of the remainder is the same as the sign of
+   .   the dividend.
+
+
+   INPUT REGISTERS:
+   .   arg0 == dividend
+   .   arg1 == divisor
+   .   mrp  == return pc
+   .   sr0  == return space when called externally
+
+   OUTPUT REGISTERS:
+   .   arg0 = destroyed
+   .   arg1 = destroyed
+   .   ret1 = remainder
+
+   OTHER REGISTERS AFFECTED:
+   .   r1   = undefined
+
+   SIDE EFFECTS:
+   .   Causes a trap under the following conditions:  DIVIDE BY ZERO
+   .   Changes memory at the following places:  NONE
+
+   PERMISSIBLE CONTEXT:
+   .   Unwindable
+   .   Does not create a stack frame
+   .   Is usable for internal or external microcode
+
+   DISCUSSION:
+   .   Calls other millicode routines via mrp:  NONE
+   .   Calls other millicode routines:  NONE  */
+
+RDEFINE(tmp,r1)
+RDEFINE(retreg,ret1)
+
+       SUBSPA_MILLI
+       ATTR_MILLI
+       .proc
+       .callinfo millicode
+       .entry
+GSYM($$remI)
+GSYM($$remoI)
+       .export $$remI,MILLICODE
+       .export $$remoI,MILLICODE
+       ldo             -1(arg1),tmp            /*  is there at most one bit set ? */
+       and,<>          arg1,tmp,r0             /*  if not, don't use power of 2 */
+       addi,>          0,arg1,r0               /*  if denominator > 0, use power */
+                                               /*  of 2 */
+       b,n             LREF(neg_denom)
+LSYM(pow2)
+       comb,>,n        0,arg0,LREF(neg_num)    /*  is numerator < 0 ? */
+       and             arg0,tmp,retreg         /*  get the result */
+       MILLIRETN
+LSYM(neg_num)
+       subi            0,arg0,arg0             /*  negate numerator */
+       and             arg0,tmp,retreg         /*  get the result */
+       subi            0,retreg,retreg         /*  negate result */
+       MILLIRETN
+LSYM(neg_denom)
+       addi,<          0,arg1,r0               /*  if arg1 >= 0, it's not power */
+                                               /*  of 2 */
+       b,n             LREF(regular_seq)
+       sub             r0,arg1,tmp             /*  make denominator positive */
+       comb,=,n        arg1,tmp,LREF(regular_seq) /*  test against 0x80000000 and 0 */
+       ldo             -1(tmp),retreg          /*  is there at most one bit set ? */
+       and,=           tmp,retreg,r0           /*  if not, go to regular_seq */
+       b,n             LREF(regular_seq)
+       comb,>,n        0,arg0,LREF(neg_num_2)  /*  if arg0 < 0, negate it  */
+       and             arg0,retreg,retreg
+       MILLIRETN
+LSYM(neg_num_2)
+       subi            0,arg0,tmp              /*  test against 0x80000000 */
+       and             tmp,retreg,retreg
+       subi            0,retreg,retreg
+       MILLIRETN
+LSYM(regular_seq)
+       addit,=         0,arg1,0                /*  trap if div by zero */
+       add,>=          0,arg0,retreg           /*  move dividend, if retreg < 0, */
+       sub             0,retreg,retreg         /*    make it positive */
+       sub             0,arg1, tmp             /*  clear carry,  */
+                                               /*    negate the divisor */
+       ds              0, tmp,0                /*  set V-bit to the comple- */
+                                               /*    ment of the divisor sign */
+       or              0,0, tmp                /*  clear  tmp */
+       add             retreg,retreg,retreg    /*  shift msb bit into carry */
+       ds               tmp,arg1, tmp          /*  1st divide step, if no carry */
+                                               /*    out, msb of quotient = 0 */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+LSYM(t1)
+       ds               tmp,arg1, tmp          /*  2nd divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  3rd divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  4th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  5th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  6th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  7th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  8th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  9th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  10th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  11th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  12th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  13th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  14th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  15th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  16th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  17th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  18th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  19th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  20th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  21st divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  22nd divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  23rd divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  24th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  25th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  26th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  27th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  28th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  29th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  30th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  31st divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  32nd divide step, */
+       addc            retreg,retreg,retreg    /*  shift last bit into retreg */
+       movb,>=,n        tmp,retreg,LREF(finish) /*  branch if pos.  tmp */
+       add,<           arg1,0,0                /*  if arg1 > 0, add arg1 */
+       add,tr           tmp,arg1,retreg        /*    for correcting remainder tmp */
+       sub              tmp,arg1,retreg        /*  else add absolute value arg1 */
+LSYM(finish)
+       add,>=          arg0,0,0                /*  set sign of remainder */
+       sub             0,retreg,retreg         /*    to sign of dividend */
+       MILLIRET
+       nop
+       .exit
+       .procend
+#ifdef milliext
+       .origin 0x00000200
+#endif
+       .end
+#endif
+
+#ifdef L_remU
+/* ROUTINE:    $$remU
+   .   Single precision divide for remainder with unsigned binary integers.
+   .
+   .   The remainder must be dividend-(dividend/divisor)*divisor.
+   .   Divide by zero is trapped.
+
+   INPUT REGISTERS:
+   .   arg0 == dividend
+   .   arg1 == divisor
+   .   mrp  == return pc
+   .   sr0  == return space when called externally
+
+   OUTPUT REGISTERS:
+   .   arg0 =  undefined
+   .   arg1 =  undefined
+   .   ret1 =  remainder
+
+   OTHER REGISTERS AFFECTED:
+   .   r1   =  undefined
+
+   SIDE EFFECTS:
+   .   Causes a trap under the following conditions:  DIVIDE BY ZERO
+   .   Changes memory at the following places:  NONE
+
+   PERMISSIBLE CONTEXT:
+   .   Unwindable.
+   .   Does not create a stack frame.
+   .   Suitable for internal or external millicode.
+   .   Assumes the special millicode register conventions.
+
+   DISCUSSION:
+   .   Calls other millicode routines using mrp: NONE
+   .   Calls other millicode routines: NONE  */
+
+
+RDEFINE(temp,r1)
+RDEFINE(rmndr,ret1)    /*  r29 */
+       SUBSPA_MILLI
+       ATTR_MILLI
+       .export $$remU,millicode
+       .proc
+       .callinfo       millicode
+       .entry
+GSYM($$remU)
+       ldo     -1(arg1),temp           /*  is there at most one bit set ? */
+       and,=   arg1,temp,r0            /*  if not, don't use power of 2 */
+       b       LREF(regular_seq)
+       addit,= 0,arg1,r0               /*  trap on div by zero */
+       and     arg0,temp,rmndr         /*  get the result for power of 2 */
+       MILLIRETN
+LSYM(regular_seq)
+       comib,>=,n  0,arg1,LREF(special_case)
+       subi    0,arg1,rmndr            /*  clear carry, negate the divisor */
+       ds      r0,rmndr,r0             /*  set V-bit to 1 */
+       add     arg0,arg0,temp          /*  shift msb bit into carry */
+       ds      r0,arg1,rmndr           /*  1st divide step, if no carry */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  2nd divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  3rd divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  4th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  5th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  6th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  7th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  8th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  9th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  10th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  11th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  12th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  13th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  14th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  15th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  16th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  17th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  18th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  19th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  20th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  21st divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  22nd divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  23rd divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  24th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  25th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  26th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  27th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  28th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  29th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  30th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  31st divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  32nd divide step, */
+       comiclr,<= 0,rmndr,r0
+         add   rmndr,arg1,rmndr        /*  correction */
+       MILLIRETN
+       nop
+
+/* Putting >= on the last DS and deleting COMICLR does not work!  */
+LSYM(special_case)
+       sub,>>= arg0,arg1,rmndr
+         copy  arg0,rmndr
+       MILLIRETN
+       nop
+       .exit
+       .procend
+       .end
+#endif
+
+#ifdef L_div_const
+/* ROUTINE:    $$divI_2
+   .           $$divI_3        $$divU_3
+   .           $$divI_4
+   .           $$divI_5        $$divU_5
+   .           $$divI_6        $$divU_6
+   .           $$divI_7        $$divU_7
+   .           $$divI_8
+   .           $$divI_9        $$divU_9
+   .           $$divI_10       $$divU_10
+   .
+   .           $$divI_12       $$divU_12
+   .
+   .           $$divI_14       $$divU_14
+   .           $$divI_15       $$divU_15
+   .           $$divI_16
+   .           $$divI_17       $$divU_17
+   .
+   .   Divide by selected constants for single precision binary integers.
+
+   INPUT REGISTERS:
+   .   arg0 == dividend
+   .   mrp  == return pc
+   .   sr0  == return space when called externally
+
+   OUTPUT REGISTERS:
+   .   arg0 =  undefined
+   .   arg1 =  undefined
+   .   ret1 =  quotient
+
+   OTHER REGISTERS AFFECTED:
+   .   r1   =  undefined
+
+   SIDE EFFECTS:
+   .   Causes a trap under the following conditions: NONE
+   .   Changes memory at the following places:  NONE
+
+   PERMISSIBLE CONTEXT:
+   .   Unwindable.
+   .   Does not create a stack frame.
+   .   Suitable for internal or external millicode.
+   .   Assumes the special millicode register conventions.
+
+   DISCUSSION:
+   .   Calls other millicode routines using mrp:  NONE
+   .   Calls other millicode routines:  NONE  */
+
+
+/* TRUNCATED DIVISION BY SMALL INTEGERS
+
+   We are interested in q(x) = floor(x/y), where x >= 0 and y > 0
+   (with y fixed).
+
+   Let a = floor(z/y), for some choice of z.  Note that z will be
+   chosen so that division by z is cheap.
+
+   Let r be the remainder(z/y).  In other words, r = z - ay.
+
+   Now, our method is to choose a value for b such that
+
+   q'(x) = floor((ax+b)/z)
+
+   is equal to q(x) over as large a range of x as possible.  If the
+   two are equal over a sufficiently large range, and if it is easy to
+   form the product (ax), and it is easy to divide by z, then we can
+   perform the division much faster than the general division algorithm.
+
+   So, we want the following to be true:
+
+   .   For x in the following range:
+   .
+   .       ky <= x < (k+1)y
+   .
+   .   implies that
+   .
+   .       k <= (ax+b)/z < (k+1)
+
+   We want to determine b such that this is true for all k in the
+   range {0..K} for some maximum K.
+
+   Since (ax+b) is an increasing function of x, we can take each
+   bound separately to determine the "best" value for b.
+
+   (ax+b)/z < (k+1)           implies
+
+   (a((k+1)y-1)+b < (k+1)z     implies
+
+   b < a + (k+1)(z-ay)        implies
+
+   b < a + (k+1)r
+
+   This needs to be true for all k in the range {0..K}.  In
+   particular, it is true for k = 0 and this leads to a maximum
+   acceptable value for b.
+
+   b < a+r   or   b <= a+r-1
+
+   Taking the other bound, we have
+
+   k <= (ax+b)/z              implies
+
+   k <= (aky+b)/z             implies
+
+   k(z-ay) <= b                       implies
+
+   kr <= b
+
+   Clearly, the largest range for k will be achieved by maximizing b,
+   when r is not zero. When r is zero, then the simplest choice for b
+   is 0.  When r is not 0, set
+
+   .   b = a+r-1
+
+   Now, by construction, q'(x) = floor((ax+b)/z) = q(x) = floor(x/y)
+   for all x in the range:
+
+   .   0 <= x < (K+1)y
+
+   We need to determine what K is.  Of our two bounds,
+
+   .   b < a+(k+1)r    is satisfied for all k >= 0, by construction.
+
+   The other bound is
+
+   .   kr <= b
+
+   This is always true if r = 0.  If r is not 0 (the usual case), then
+   K = floor((a+r-1)/r), is the maximum value for k.
+
+   Therefore, the formula q'(x) = floor((ax+b)/z) yields the correct
+   answer for q(x) = floor(x/y) when x is in the range
+
+   (0,(K+1)y-1)               K = floor((a+r-1)/r)
+
+   To be most useful, we want (K+1)y-1 = (max x) >= 2**32-1 so that
+   the formula for q'(x) yields the correct value of q(x) for all x
+   representable by a single word in HPPA.
+
+   We are also constrained in that computing the product (ax), adding
+   b, and dividing by z must all be done quickly, otherwise we will be
+   better off going through the general algorithm using the DS
+   instruction, which uses approximately 70 cycles.
+
+   For each y, there is a choice of z which satisfies the constraints
+   for (K+1)y >= 2**32.  We may not, however, be able to satisfy the
+   timing constraints for arbitrary y. It seems that z being equal to
+   a power of 2 or a power of 2 minus 1 is as good as we can do, since
+   it minimizes the time to do division by z.  We want the choice of z
+   to also result in a value for (a) that minimizes the computation of
+   the product (ax).  This is best achieved if (a) has a regular bit
+   pattern (so the multiplication can be done with shifts and adds).
+   The value of (a) also needs to be less than 2**32 so the product is
+   always guaranteed to fit in 2 words.
+
+   In actual practice, the following should be done:
+
+   1) For negative x, you should take the absolute value and remember
+   .  the fact so that the result can be negated.  This obviously does
+   .  not apply in the unsigned case.
+   2) For even y, you should factor out the power of 2 that divides y
+   .  and divide x by it.  You can then proceed by dividing by the
+   .  odd factor of y.
+
+   Here is a table of some odd values of y, and corresponding choices
+   for z which are "good".
+
+    y    z       r      a (hex)     max x (hex)
+
+    3  2**32     1     55555555      100000001
+    5  2**32     1     33333333      100000003
+    7  2**24-1   0       249249     (infinite)
+    9  2**24-1   0       1c71c7     (infinite)
+   11  2**20-1   0        1745d     (infinite)
+   13  2**24-1   0       13b13b     (infinite)
+   15  2**32     1     11111111      10000000d
+   17  2**32     1      f0f0f0f      10000000f
+
+   If r is 1, then b = a+r-1 = a.  This simplifies the computation
+   of (ax+b), since you can compute (x+1)(a) instead.  If r is 0,
+   then b = 0 is ok to use which simplifies (ax+b).
+
+   The bit patterns for 55555555, 33333333, and 11111111 are obviously
+   very regular.  The bit patterns for the other values of a above are:
+
+    y     (hex)          (binary)
+
+    7    249249  001001001001001001001001  << regular >>
+    9    1c71c7  000111000111000111000111  << regular >>
+   11     1745d  000000010111010001011101  << irregular >>
+   13    13b13b  000100111011000100111011  << irregular >>
+
+   The bit patterns for (a) corresponding to (y) of 11 and 13 may be
+   too irregular to warrant using this method.
+
+   When z is a power of 2 minus 1, then the division by z is slightly
+   more complicated, involving an iterative solution.
+
+   The code presented here solves division by 1 through 17, except for
+   11 and 13. There are algorithms for both signed and unsigned
+   quantities given.
+
+   TIMINGS (cycles)
+
+   divisor  positive  negative unsigned
+
+   .   1       2          2         2
+   .   2       4          4         2
+   .   3       19        21        19
+   .   4       4          4         2
+   .   5       18        22        19
+   .   6       19        22        19
+   .   8       4          4         2
+   .  10       18        19        17
+   .  12       18        20        18
+   .  15       16        18        16
+   .  16       4          4         2
+   .  17       16        18        16
+
+   Now, the algorithm for 7, 9, and 14 is an iterative one.  That is,
+   a loop body is executed until the tentative quotient is 0.  The
+   number of times the loop body is executed varies depending on the
+   dividend, but is never more than two times. If the dividend is
+   less than the divisor, then the loop body is not executed at all.
+   Each iteration adds 4 cycles to the timings.
+
+   divisor  positive  negative unsigned
+
+   .   7       19+4n    20+4n     20+4n    n = number of iterations
+   .   9       21+4n    22+4n     21+4n
+   .  14       21+4n    22+4n     20+4n
+
+   To give an idea of how the number of iterations varies, here is a
+   table of dividend versus number of iterations when dividing by 7.
+
+   smallest     largest       required
+   dividend    dividend      iterations
+
+   .   0            6              0
+   .   7        0x6ffffff          1
+   0x1000006   0xffffffff          2
+
+   There is some overlap in the range of numbers requiring 1 and 2
+   iterations. */
+
+RDEFINE(t2,r1)
+RDEFINE(x2,arg0)       /*  r26 */
+RDEFINE(t1,arg1)       /*  r25 */
+RDEFINE(x1,ret1)       /*  r29 */
+
+       SUBSPA_MILLI_DIV
+       ATTR_MILLI
+
+       .proc
+       .callinfo       millicode
+       .entry
+/* NONE of these routines require a stack frame
+   ALL of these routines are unwindable from millicode */
+
+GSYM($$divide_by_constant)
+       .export $$divide_by_constant,millicode
+/*  Provides a "nice" label for the code covered by the unwind descriptor
+    for things like gprof.  */
+
+/* DIVISION BY 2 (shift by 1) */
+GSYM($$divI_2)
+       .export         $$divI_2,millicode
+       comclr,>=       arg0,0,0
+       addi            1,arg0,arg0
+       MILLIRET
+       extrs           arg0,30,31,ret1
+
+
+/* DIVISION BY 4 (shift by 2) */
+GSYM($$divI_4)
+       .export         $$divI_4,millicode
+       comclr,>=       arg0,0,0
+       addi            3,arg0,arg0
+       MILLIRET
+       extrs           arg0,29,30,ret1
+
+
+/* DIVISION BY 8 (shift by 3) */
+GSYM($$divI_8)
+       .export         $$divI_8,millicode
+       comclr,>=       arg0,0,0
+       addi            7,arg0,arg0
+       MILLIRET
+       extrs           arg0,28,29,ret1
+
+/* DIVISION BY 16 (shift by 4) */
+GSYM($$divI_16)
+       .export         $$divI_16,millicode
+       comclr,>=       arg0,0,0
+       addi            15,arg0,arg0
+       MILLIRET
+       extrs           arg0,27,28,ret1
+
+/****************************************************************************
+*
+*      DIVISION BY DIVISORS OF FFFFFFFF, and powers of 2 times these
+*
+*      includes 3,5,15,17 and also 6,10,12
+*
+****************************************************************************/
+
+/* DIVISION BY 3 (use z = 2**32; a = 55555555) */
+
+GSYM($$divI_3)
+       .export         $$divI_3,millicode
+       comb,<,N        x2,0,LREF(neg3)
+
+       addi            1,x2,x2         /* this cannot overflow */
+       extru           x2,1,2,x1       /* multiply by 5 to get started */
+       sh2add          x2,x2,x2
+       b               LREF(pos)
+       addc            x1,0,x1
+
+LSYM(neg3)
+       subi            1,x2,x2         /* this cannot overflow */
+       extru           x2,1,2,x1       /* multiply by 5 to get started */
+       sh2add          x2,x2,x2
+       b               LREF(neg)
+       addc            x1,0,x1
+
+GSYM($$divU_3)
+       .export         $$divU_3,millicode
+       addi            1,x2,x2         /* this CAN overflow */
+       addc            0,0,x1
+       shd             x1,x2,30,t1     /* multiply by 5 to get started */
+       sh2add          x2,x2,x2
+       b               LREF(pos)
+       addc            x1,t1,x1
+
+/* DIVISION BY 5 (use z = 2**32; a = 33333333) */
+
+GSYM($$divI_5)
+       .export         $$divI_5,millicode
+       comb,<,N        x2,0,LREF(neg5)
+
+       addi            3,x2,t1         /* this cannot overflow */
+       sh1add          x2,t1,x2        /* multiply by 3 to get started */
+       b               LREF(pos)
+       addc            0,0,x1
+
+LSYM(neg5)
+       sub             0,x2,x2         /* negate x2                    */
+       addi            1,x2,x2         /* this cannot overflow */
+       shd             0,x2,31,x1      /* get top bit (can be 1)       */
+       sh1add          x2,x2,x2        /* multiply by 3 to get started */
+       b               LREF(neg)
+       addc            x1,0,x1
+
+GSYM($$divU_5)
+       .export         $$divU_5,millicode
+       addi            1,x2,x2         /* this CAN overflow */
+       addc            0,0,x1
+       shd             x1,x2,31,t1     /* multiply by 3 to get started */
+       sh1add          x2,x2,x2
+       b               LREF(pos)
+       addc            t1,x1,x1
+
+/* DIVISION BY 6 (shift to divide by 2 then divide by 3) */
+GSYM($$divI_6)
+       .export         $$divI_6,millicode
+       comb,<,N        x2,0,LREF(neg6)
+       extru           x2,30,31,x2     /* divide by 2                  */
+       addi            5,x2,t1         /* compute 5*(x2+1) = 5*x2+5    */
+       sh2add          x2,t1,x2        /* multiply by 5 to get started */
+       b               LREF(pos)
+       addc            0,0,x1
+
+LSYM(neg6)
+       subi            2,x2,x2         /* negate, divide by 2, and add 1 */
+                                       /* negation and adding 1 are done */
+                                       /* at the same time by the SUBI   */
+       extru           x2,30,31,x2
+       shd             0,x2,30,x1
+       sh2add          x2,x2,x2        /* multiply by 5 to get started */
+       b               LREF(neg)
+       addc            x1,0,x1
+
+GSYM($$divU_6)
+       .export         $$divU_6,millicode
+       extru           x2,30,31,x2     /* divide by 2 */
+       addi            1,x2,x2         /* cannot carry */
+       shd             0,x2,30,x1      /* multiply by 5 to get started */
+       sh2add          x2,x2,x2
+       b               LREF(pos)
+       addc            x1,0,x1
+
+/* DIVISION BY 10 (shift to divide by 2 then divide by 5) */
+GSYM($$divU_10)
+       .export         $$divU_10,millicode
+       extru           x2,30,31,x2     /* divide by 2 */
+       addi            3,x2,t1         /* compute 3*(x2+1) = (3*x2)+3  */
+       sh1add          x2,t1,x2        /* multiply by 3 to get started */
+       addc            0,0,x1
+LSYM(pos)
+       shd             x1,x2,28,t1     /* multiply by 0x11 */
+       shd             x2,0,28,t2
+       add             x2,t2,x2
+       addc            x1,t1,x1
+LSYM(pos_for_17)
+       shd             x1,x2,24,t1     /* multiply by 0x101 */
+       shd             x2,0,24,t2
+       add             x2,t2,x2
+       addc            x1,t1,x1
+
+       shd             x1,x2,16,t1     /* multiply by 0x10001 */
+       shd             x2,0,16,t2
+       add             x2,t2,x2
+       MILLIRET
+       addc            x1,t1,x1
+
+GSYM($$divI_10)
+       .export         $$divI_10,millicode
+       comb,<          x2,0,LREF(neg10)
+       copy            0,x1
+       extru           x2,30,31,x2     /* divide by 2 */
+       addib,TR        1,x2,LREF(pos)  /* add 1 (cannot overflow)     */
+       sh1add          x2,x2,x2        /* multiply by 3 to get started */
+
+LSYM(neg10)
+       subi            2,x2,x2         /* negate, divide by 2, and add 1 */
+                                       /* negation and adding 1 are done */
+                                       /* at the same time by the SUBI   */
+       extru           x2,30,31,x2
+       sh1add          x2,x2,x2        /* multiply by 3 to get started */
+LSYM(neg)
+       shd             x1,x2,28,t1     /* multiply by 0x11 */
+       shd             x2,0,28,t2
+       add             x2,t2,x2
+       addc            x1,t1,x1
+LSYM(neg_for_17)
+       shd             x1,x2,24,t1     /* multiply by 0x101 */
+       shd             x2,0,24,t2
+       add             x2,t2,x2
+       addc            x1,t1,x1
+
+       shd             x1,x2,16,t1     /* multiply by 0x10001 */
+       shd             x2,0,16,t2
+       add             x2,t2,x2
+       addc            x1,t1,x1
+       MILLIRET
+       sub             0,x1,x1
+
+/* DIVISION BY 12 (shift to divide by 4 then divide by 3) */
+GSYM($$divI_12)
+       .export         $$divI_12,millicode
+       comb,<          x2,0,LREF(neg12)
+       copy            0,x1
+       extru           x2,29,30,x2     /* divide by 4                  */
+       addib,tr        1,x2,LREF(pos)  /* compute 5*(x2+1) = 5*x2+5    */
+       sh2add          x2,x2,x2        /* multiply by 5 to get started */
+
+LSYM(neg12)
+       subi            4,x2,x2         /* negate, divide by 4, and add 1 */
+                                       /* negation and adding 1 are done */
+                                       /* at the same time by the SUBI   */
+       extru           x2,29,30,x2
+       b               LREF(neg)
+       sh2add          x2,x2,x2        /* multiply by 5 to get started */
+
+GSYM($$divU_12)
+       .export         $$divU_12,millicode
+       extru           x2,29,30,x2     /* divide by 4   */
+       addi            5,x2,t1         /* cannot carry */
+       sh2add          x2,t1,x2        /* multiply by 5 to get started */
+       b               LREF(pos)
+       addc            0,0,x1
+
+/* DIVISION BY 15 (use z = 2**32; a = 11111111) */
+GSYM($$divI_15)
+       .export         $$divI_15,millicode
+       comb,<          x2,0,LREF(neg15)
+       copy            0,x1
+       addib,tr        1,x2,LREF(pos)+4
+       shd             x1,x2,28,t1
+
+LSYM(neg15)
+       b               LREF(neg)
+       subi            1,x2,x2
+
+GSYM($$divU_15)
+       .export         $$divU_15,millicode
+       addi            1,x2,x2         /* this CAN overflow */
+       b               LREF(pos)
+       addc            0,0,x1
+
+/* DIVISION BY 17 (use z = 2**32; a =  f0f0f0f) */
+GSYM($$divI_17)
+       .export         $$divI_17,millicode
+       comb,<,n        x2,0,LREF(neg17)
+       addi            1,x2,x2         /* this cannot overflow */
+       shd             0,x2,28,t1      /* multiply by 0xf to get started */
+       shd             x2,0,28,t2
+       sub             t2,x2,x2
+       b               LREF(pos_for_17)
+       subb            t1,0,x1
+
+LSYM(neg17)
+       subi            1,x2,x2         /* this cannot overflow */
+       shd             0,x2,28,t1      /* multiply by 0xf to get started */
+       shd             x2,0,28,t2
+       sub             t2,x2,x2
+       b               LREF(neg_for_17)
+       subb            t1,0,x1
+
+GSYM($$divU_17)
+       .export         $$divU_17,millicode
+       addi            1,x2,x2         /* this CAN overflow */
+       addc            0,0,x1
+       shd             x1,x2,28,t1     /* multiply by 0xf to get started */
+LSYM(u17)
+       shd             x2,0,28,t2
+       sub             t2,x2,x2
+       b               LREF(pos_for_17)
+       subb            t1,x1,x1
+
+
+/* DIVISION BY DIVISORS OF FFFFFF, and powers of 2 times these
+   includes 7,9 and also 14
+
+
+   z = 2**24-1
+   r = z mod x = 0
+
+   so choose b = 0
+
+   Also, in order to divide by z = 2**24-1, we approximate by dividing
+   by (z+1) = 2**24 (which is easy), and then correcting.
+
+   (ax) = (z+1)q' + r
+   .   = zq' + (q'+r)
+
+   So to compute (ax)/z, compute q' = (ax)/(z+1) and r = (ax) mod (z+1)
+   Then the true remainder of (ax)/z is (q'+r).  Repeat the process
+   with this new remainder, adding the tentative quotients together,
+   until a tentative quotient is 0 (and then we are done).  There is
+   one last correction to be done.  It is possible that (q'+r) = z.
+   If so, then (q'+r)/(z+1) = 0 and it looks like we are done. But,
+   in fact, we need to add 1 more to the quotient.  Now, it turns
+   out that this happens if and only if the original value x is
+   an exact multiple of y.  So, to avoid a three instruction test at
+   the end, instead use 1 instruction to add 1 to x at the beginning.  */
+
+/* DIVISION BY 7 (use z = 2**24-1; a = 249249) */
+GSYM($$divI_7)
+       .export         $$divI_7,millicode
+       comb,<,n        x2,0,LREF(neg7)
+LSYM(7)
+       addi            1,x2,x2         /* cannot overflow */
+       shd             0,x2,29,x1
+       sh3add          x2,x2,x2
+       addc            x1,0,x1
+LSYM(pos7)
+       shd             x1,x2,26,t1
+       shd             x2,0,26,t2
+       add             x2,t2,x2
+       addc            x1,t1,x1
+
+       shd             x1,x2,20,t1
+       shd             x2,0,20,t2
+       add             x2,t2,x2
+       addc            x1,t1,t1
+
+       /* computed <t1,x2>.  Now divide it by (2**24 - 1)      */
+
+       copy            0,x1
+       shd,=           t1,x2,24,t1     /* tentative quotient  */
+LSYM(1)
+       addb,tr         t1,x1,LREF(2)   /* add to previous quotient   */
+       extru           x2,31,24,x2     /* new remainder (unadjusted) */
+
+       MILLIRETN
+
+LSYM(2)
+       addb,tr         t1,x2,LREF(1)   /* adjust remainder */
+       extru,=         x2,7,8,t1       /* new quotient     */
+
+LSYM(neg7)
+       subi            1,x2,x2         /* negate x2 and add 1 */
+LSYM(8)
+       shd             0,x2,29,x1
+       sh3add          x2,x2,x2
+       addc            x1,0,x1
+
+LSYM(neg7_shift)
+       shd             x1,x2,26,t1
+       shd             x2,0,26,t2
+       add             x2,t2,x2
+       addc            x1,t1,x1
+
+       shd             x1,x2,20,t1
+       shd             x2,0,20,t2
+       add             x2,t2,x2
+       addc            x1,t1,t1
+
+       /* computed <t1,x2>.  Now divide it by (2**24 - 1)      */
+
+       copy            0,x1
+       shd,=           t1,x2,24,t1     /* tentative quotient  */
+LSYM(3)
+       addb,tr         t1,x1,LREF(4)   /* add to previous quotient   */
+       extru           x2,31,24,x2     /* new remainder (unadjusted) */
+
+       MILLIRET
+       sub             0,x1,x1         /* negate result    */
+
+LSYM(4)
+       addb,tr         t1,x2,LREF(3)   /* adjust remainder */
+       extru,=         x2,7,8,t1       /* new quotient     */
+
+GSYM($$divU_7)
+       .export         $$divU_7,millicode
+       addi            1,x2,x2         /* can carry */
+       addc            0,0,x1
+       shd             x1,x2,29,t1
+       sh3add          x2,x2,x2
+       b               LREF(pos7)
+       addc            t1,x1,x1
+
+/* DIVISION BY 9 (use z = 2**24-1; a = 1c71c7) */
+GSYM($$divI_9)
+       .export         $$divI_9,millicode
+       comb,<,n        x2,0,LREF(neg9)
+       addi            1,x2,x2         /* cannot overflow */
+       shd             0,x2,29,t1
+       shd             x2,0,29,t2
+       sub             t2,x2,x2
+       b               LREF(pos7)
+       subb            t1,0,x1
+
+LSYM(neg9)
+       subi            1,x2,x2         /* negate and add 1 */
+       shd             0,x2,29,t1
+       shd             x2,0,29,t2
+       sub             t2,x2,x2
+       b               LREF(neg7_shift)
+       subb            t1,0,x1
+
+GSYM($$divU_9)
+       .export         $$divU_9,millicode
+       addi            1,x2,x2         /* can carry */
+       addc            0,0,x1
+       shd             x1,x2,29,t1
+       shd             x2,0,29,t2
+       sub             t2,x2,x2
+       b               LREF(pos7)
+       subb            t1,x1,x1
+
+/* DIVISION BY 14 (shift to divide by 2 then divide by 7) */
+GSYM($$divI_14)
+       .export         $$divI_14,millicode
+       comb,<,n        x2,0,LREF(neg14)
+GSYM($$divU_14)
+       .export         $$divU_14,millicode
+       b               LREF(7)         /* go to 7 case */
+       extru           x2,30,31,x2     /* divide by 2  */
+
+LSYM(neg14)
+       subi            2,x2,x2         /* negate (and add 2) */
+       b               LREF(8)
+       extru           x2,30,31,x2     /* divide by 2        */
+       .exit
+       .procend
+       .end
+#endif
+
+#ifdef L_mulI
+/* VERSION "@(#)$$mulI $ Revision: 12.4 $ $ Date: 94/03/17 17:18:51 $" */
+/******************************************************************************
+This routine is used on PA2.0 processors when gcc -mno-fpregs is used
+
+ROUTINE:       $$mulI
+
+
+DESCRIPTION:   
+
+       $$mulI multiplies two single word integers, giving a single 
+       word result.  
+
+
+INPUT REGISTERS:
+
+       arg0 = Operand 1
+       arg1 = Operand 2
+       r31  == return pc
+       sr0  == return space when called externally 
+
+
+OUTPUT REGISTERS:
+
+       arg0 = undefined
+       arg1 = undefined
+       ret1 = result 
+
+OTHER REGISTERS AFFECTED:
+
+       r1   = undefined
+
+SIDE EFFECTS:
+
+       Causes a trap under the following conditions:  NONE
+       Changes memory at the following places:  NONE
+
+PERMISSIBLE CONTEXT:
+
+       Unwindable
+       Does not create a stack frame
+       Is usable for internal or external microcode
+
+DISCUSSION:
+
+       Calls other millicode routines via mrp:  NONE
+       Calls other millicode routines:  NONE
+
+***************************************************************************/
+
+
+#define        a0      %arg0
+#define        a1      %arg1
+#define        t0      %r1
+#define        r       %ret1
+
+#define        a0__128a0       zdep    a0,24,25,a0
+#define        a0__256a0       zdep    a0,23,24,a0
+#define        a1_ne_0_b_l0    comb,<> a1,0,LREF(l0)
+#define        a1_ne_0_b_l1    comb,<> a1,0,LREF(l1)
+#define        a1_ne_0_b_l2    comb,<> a1,0,LREF(l2)
+#define        b_n_ret_t0      b,n     LREF(ret_t0)
+#define        b_e_shift       b       LREF(e_shift)
+#define        b_e_t0ma0       b       LREF(e_t0ma0)
+#define        b_e_t0          b       LREF(e_t0)
+#define        b_e_t0a0        b       LREF(e_t0a0)
+#define        b_e_t02a0       b       LREF(e_t02a0)
+#define        b_e_t04a0       b       LREF(e_t04a0)
+#define        b_e_2t0         b       LREF(e_2t0)
+#define        b_e_2t0a0       b       LREF(e_2t0a0)
+#define        b_e_2t04a0      b       LREF(e2t04a0)
+#define        b_e_3t0         b       LREF(e_3t0)
+#define        b_e_4t0         b       LREF(e_4t0)
+#define        b_e_4t0a0       b       LREF(e_4t0a0)
+#define        b_e_4t08a0      b       LREF(e4t08a0)
+#define        b_e_5t0         b       LREF(e_5t0)
+#define        b_e_8t0         b       LREF(e_8t0)
+#define        b_e_8t0a0       b       LREF(e_8t0a0)
+#define        r__r_a0         add     r,a0,r
+#define        r__r_2a0        sh1add  a0,r,r
+#define        r__r_4a0        sh2add  a0,r,r
+#define        r__r_8a0        sh3add  a0,r,r
+#define        r__r_t0         add     r,t0,r
+#define        r__r_2t0        sh1add  t0,r,r
+#define        r__r_4t0        sh2add  t0,r,r
+#define        r__r_8t0        sh3add  t0,r,r
+#define        t0__3a0         sh1add  a0,a0,t0
+#define        t0__4a0         sh2add  a0,0,t0
+#define        t0__5a0         sh2add  a0,a0,t0
+#define        t0__8a0         sh3add  a0,0,t0
+#define        t0__9a0         sh3add  a0,a0,t0
+#define        t0__16a0        zdep    a0,27,28,t0
+#define        t0__32a0        zdep    a0,26,27,t0
+#define        t0__64a0        zdep    a0,25,26,t0
+#define        t0__128a0       zdep    a0,24,25,t0
+#define        t0__t0ma0       sub     t0,a0,t0
+#define        t0__t0_a0       add     t0,a0,t0
+#define        t0__t0_2a0      sh1add  a0,t0,t0
+#define        t0__t0_4a0      sh2add  a0,t0,t0
+#define        t0__t0_8a0      sh3add  a0,t0,t0
+#define        t0__2t0_a0      sh1add  t0,a0,t0
+#define        t0__3t0         sh1add  t0,t0,t0
+#define        t0__4t0         sh2add  t0,0,t0
+#define        t0__4t0_a0      sh2add  t0,a0,t0
+#define        t0__5t0         sh2add  t0,t0,t0
+#define        t0__8t0         sh3add  t0,0,t0
+#define        t0__8t0_a0      sh3add  t0,a0,t0
+#define        t0__9t0         sh3add  t0,t0,t0
+#define        t0__16t0        zdep    t0,27,28,t0
+#define        t0__32t0        zdep    t0,26,27,t0
+#define        t0__256a0       zdep    a0,23,24,t0
+
+
+       SUBSPA_MILLI
+       ATTR_MILLI
+       .align 16
+       .proc
+       .callinfo millicode
+       .export $$mulI,millicode
+GSYM($$mulI)   
+       combt,<<=       a1,a0,LREF(l4)  /* swap args if unsigned a1>a0 */
+       copy            0,r             /* zero out the result */
+       xor             a0,a1,a0        /* swap a0 & a1 using the */
+       xor             a0,a1,a1        /*  old xor trick */
+       xor             a0,a1,a0
+LSYM(l4)
+       combt,<=        0,a0,LREF(l3)           /* if a0>=0 then proceed like unsigned */
+       zdep            a1,30,8,t0      /* t0 = (a1&0xff)<<1 ********* */
+       sub,>           0,a1,t0         /* otherwise negate both and */
+       combt,<=,n      a0,t0,LREF(l2)  /*  swap back if |a0|<|a1| */
+       sub             0,a0,a1
+       movb,tr,n       t0,a0,LREF(l2)  /* 10th inst.  */
+
+LSYM(l0)       r__r_t0                         /* add in this partial product */
+LSYM(l1)       a0__256a0                       /* a0 <<= 8 ****************** */
+LSYM(l2)       zdep            a1,30,8,t0      /* t0 = (a1&0xff)<<1 ********* */
+LSYM(l3)       blr             t0,0            /* case on these 8 bits ****** */
+               extru           a1,23,24,a1     /* a1 >>= 8 ****************** */
+
+/*16 insts before this.  */
+/*                       a0 <<= 8 ************************** */
+LSYM(x0)       a1_ne_0_b_l2    ! a0__256a0     ! MILLIRETN     ! nop
+LSYM(x1)       a1_ne_0_b_l1    ! r__r_a0       ! MILLIRETN     ! nop
+LSYM(x2)       a1_ne_0_b_l1    ! r__r_2a0      ! MILLIRETN     ! nop
+LSYM(x3)       a1_ne_0_b_l0    ! t0__3a0       ! MILLIRET      ! r__r_t0
+LSYM(x4)       a1_ne_0_b_l1    ! r__r_4a0      ! MILLIRETN     ! nop
+LSYM(x5)       a1_ne_0_b_l0    ! t0__5a0       ! MILLIRET      ! r__r_t0
+LSYM(x6)       t0__3a0         ! a1_ne_0_b_l1  ! r__r_2t0      ! MILLIRETN
+LSYM(x7)       t0__3a0         ! a1_ne_0_b_l0  ! r__r_4a0      ! b_n_ret_t0
+LSYM(x8)       a1_ne_0_b_l1    ! r__r_8a0      ! MILLIRETN     ! nop
+LSYM(x9)       a1_ne_0_b_l0    ! t0__9a0       ! MILLIRET      ! r__r_t0
+LSYM(x10)      t0__5a0         ! a1_ne_0_b_l1  ! r__r_2t0      ! MILLIRETN
+LSYM(x11)      t0__3a0         ! a1_ne_0_b_l0  ! r__r_8a0      ! b_n_ret_t0
+LSYM(x12)      t0__3a0         ! a1_ne_0_b_l1  ! r__r_4t0      ! MILLIRETN
+LSYM(x13)      t0__5a0         ! a1_ne_0_b_l0  ! r__r_8a0      ! b_n_ret_t0
+LSYM(x14)      t0__3a0         ! t0__2t0_a0    ! b_e_shift     ! r__r_2t0
+LSYM(x15)      t0__5a0         ! a1_ne_0_b_l0  ! t0__3t0       ! b_n_ret_t0
+LSYM(x16)      t0__16a0        ! a1_ne_0_b_l1  ! r__r_t0       ! MILLIRETN
+LSYM(x17)      t0__9a0         ! a1_ne_0_b_l0  ! t0__t0_8a0    ! b_n_ret_t0
+LSYM(x18)      t0__9a0         ! a1_ne_0_b_l1  ! r__r_2t0      ! MILLIRETN
+LSYM(x19)      t0__9a0         ! a1_ne_0_b_l0  ! t0__2t0_a0    ! b_n_ret_t0
+LSYM(x20)      t0__5a0         ! a1_ne_0_b_l1  ! r__r_4t0      ! MILLIRETN
+LSYM(x21)      t0__5a0         ! a1_ne_0_b_l0  ! t0__4t0_a0    ! b_n_ret_t0
+LSYM(x22)      t0__5a0         ! t0__2t0_a0    ! b_e_shift     ! r__r_2t0
+LSYM(x23)      t0__5a0         ! t0__2t0_a0    ! b_e_t0        ! t0__2t0_a0
+LSYM(x24)      t0__3a0         ! a1_ne_0_b_l1  ! r__r_8t0      ! MILLIRETN
+LSYM(x25)      t0__5a0         ! a1_ne_0_b_l0  ! t0__5t0       ! b_n_ret_t0
+LSYM(x26)      t0__3a0         ! t0__4t0_a0    ! b_e_shift     ! r__r_2t0
+LSYM(x27)      t0__3a0         ! a1_ne_0_b_l0  ! t0__9t0       ! b_n_ret_t0
+LSYM(x28)      t0__3a0         ! t0__2t0_a0    ! b_e_shift     ! r__r_4t0
+LSYM(x29)      t0__3a0         ! t0__2t0_a0    ! b_e_t0        ! t0__4t0_a0
+LSYM(x30)      t0__5a0         ! t0__3t0       ! b_e_shift     ! r__r_2t0
+LSYM(x31)      t0__32a0        ! a1_ne_0_b_l0  ! t0__t0ma0     ! b_n_ret_t0
+LSYM(x32)      t0__32a0        ! a1_ne_0_b_l1  ! r__r_t0       ! MILLIRETN
+LSYM(x33)      t0__8a0         ! a1_ne_0_b_l0  ! t0__4t0_a0    ! b_n_ret_t0
+LSYM(x34)      t0__16a0        ! t0__t0_a0     ! b_e_shift     ! r__r_2t0
+LSYM(x35)      t0__9a0         ! t0__3t0       ! b_e_t0        ! t0__t0_8a0
+LSYM(x36)      t0__9a0         ! a1_ne_0_b_l1  ! r__r_4t0      ! MILLIRETN
+LSYM(x37)      t0__9a0         ! a1_ne_0_b_l0  ! t0__4t0_a0    ! b_n_ret_t0
+LSYM(x38)      t0__9a0         ! t0__2t0_a0    ! b_e_shift     ! r__r_2t0
+LSYM(x39)      t0__9a0         ! t0__2t0_a0    ! b_e_t0        ! t0__2t0_a0
+LSYM(x40)      t0__5a0         ! a1_ne_0_b_l1  ! r__r_8t0      ! MILLIRETN
+LSYM(x41)      t0__5a0         ! a1_ne_0_b_l0  ! t0__8t0_a0    ! b_n_ret_t0
+LSYM(x42)      t0__5a0         ! t0__4t0_a0    ! b_e_shift     ! r__r_2t0
+LSYM(x43)      t0__5a0         ! t0__4t0_a0    ! b_e_t0        ! t0__2t0_a0
+LSYM(x44)      t0__5a0         ! t0__2t0_a0    ! b_e_shift     ! r__r_4t0
+LSYM(x45)      t0__9a0         ! a1_ne_0_b_l0  ! t0__5t0       ! b_n_ret_t0
+LSYM(x46)      t0__9a0         ! t0__5t0       ! b_e_t0        ! t0__t0_a0
+LSYM(x47)      t0__9a0         ! t0__5t0       ! b_e_t0        ! t0__t0_2a0
+LSYM(x48)      t0__3a0         ! a1_ne_0_b_l0  ! t0__16t0      ! b_n_ret_t0
+LSYM(x49)      t0__9a0         ! t0__5t0       ! b_e_t0        ! t0__t0_4a0
+LSYM(x50)      t0__5a0         ! t0__5t0       ! b_e_shift     ! r__r_2t0
+LSYM(x51)      t0__9a0         ! t0__t0_8a0    ! b_e_t0        ! t0__3t0
+LSYM(x52)      t0__3a0         ! t0__4t0_a0    ! b_e_shift     ! r__r_4t0
+LSYM(x53)      t0__3a0         ! t0__4t0_a0    ! b_e_t0        ! t0__4t0_a0
+LSYM(x54)      t0__9a0         ! t0__3t0       ! b_e_shift     ! r__r_2t0
+LSYM(x55)      t0__9a0         ! t0__3t0       ! b_e_t0        ! t0__2t0_a0
+LSYM(x56)      t0__3a0         ! t0__2t0_a0    ! b_e_shift     ! r__r_8t0
+LSYM(x57)      t0__9a0         ! t0__2t0_a0    ! b_e_t0        ! t0__3t0
+LSYM(x58)      t0__3a0         ! t0__2t0_a0    ! b_e_2t0       ! t0__4t0_a0
+LSYM(x59)      t0__9a0         ! t0__2t0_a0    ! b_e_t02a0     ! t0__3t0
+LSYM(x60)      t0__5a0         ! t0__3t0       ! b_e_shift     ! r__r_4t0
+LSYM(x61)      t0__5a0         ! t0__3t0       ! b_e_t0        ! t0__4t0_a0
+LSYM(x62)      t0__32a0        ! t0__t0ma0     ! b_e_shift     ! r__r_2t0
+LSYM(x63)      t0__64a0        ! a1_ne_0_b_l0  ! t0__t0ma0     ! b_n_ret_t0
+LSYM(x64)      t0__64a0        ! a1_ne_0_b_l1  ! r__r_t0       ! MILLIRETN
+LSYM(x65)      t0__8a0         ! a1_ne_0_b_l0  ! t0__8t0_a0    ! b_n_ret_t0
+LSYM(x66)      t0__32a0        ! t0__t0_a0     ! b_e_shift     ! r__r_2t0
+LSYM(x67)      t0__8a0         ! t0__4t0_a0    ! b_e_t0        ! t0__2t0_a0
+LSYM(x68)      t0__8a0         ! t0__2t0_a0    ! b_e_shift     ! r__r_4t0
+LSYM(x69)      t0__8a0         ! t0__2t0_a0    ! b_e_t0        ! t0__4t0_a0
+LSYM(x70)      t0__64a0        ! t0__t0_4a0    ! b_e_t0        ! t0__t0_2a0
+LSYM(x71)      t0__9a0         ! t0__8t0       ! b_e_t0        ! t0__t0ma0
+LSYM(x72)      t0__9a0         ! a1_ne_0_b_l1  ! r__r_8t0      ! MILLIRETN
+LSYM(x73)      t0__9a0         ! t0__8t0_a0    ! b_e_shift     ! r__r_t0
+LSYM(x74)      t0__9a0         ! t0__4t0_a0    ! b_e_shift     ! r__r_2t0
+LSYM(x75)      t0__9a0         ! t0__4t0_a0    ! b_e_t0        ! t0__2t0_a0
+LSYM(x76)      t0__9a0         ! t0__2t0_a0    ! b_e_shift     ! r__r_4t0
+LSYM(x77)      t0__9a0         ! t0__2t0_a0    ! b_e_t0        ! t0__4t0_a0
+LSYM(x78)      t0__9a0         ! t0__2t0_a0    ! b_e_2t0       ! t0__2t0_a0
+LSYM(x79)      t0__16a0        ! t0__5t0       ! b_e_t0        ! t0__t0ma0
+LSYM(x80)      t0__16a0        ! t0__5t0       ! b_e_shift     ! r__r_t0
+LSYM(x81)      t0__9a0         ! t0__9t0       ! b_e_shift     ! r__r_t0
+LSYM(x82)      t0__5a0         ! t0__8t0_a0    ! b_e_shift     ! r__r_2t0
+LSYM(x83)      t0__5a0         ! t0__8t0_a0    ! b_e_t0        ! t0__2t0_a0
+LSYM(x84)      t0__5a0         ! t0__4t0_a0    ! b_e_shift     ! r__r_4t0
+LSYM(x85)      t0__8a0         ! t0__2t0_a0    ! b_e_t0        ! t0__5t0
+LSYM(x86)      t0__5a0         ! t0__4t0_a0    ! b_e_2t0       ! t0__2t0_a0
+LSYM(x87)      t0__9a0         ! t0__9t0       ! b_e_t02a0     ! t0__t0_4a0
+LSYM(x88)      t0__5a0         ! t0__2t0_a0    ! b_e_shift     ! r__r_8t0
+LSYM(x89)      t0__5a0         ! t0__2t0_a0    ! b_e_t0        ! t0__8t0_a0
+LSYM(x90)      t0__9a0         ! t0__5t0       ! b_e_shift     ! r__r_2t0
+LSYM(x91)      t0__9a0         ! t0__5t0       ! b_e_t0        ! t0__2t0_a0
+LSYM(x92)      t0__5a0         ! t0__2t0_a0    ! b_e_4t0       ! t0__2t0_a0
+LSYM(x93)      t0__32a0        ! t0__t0ma0     ! b_e_t0        ! t0__3t0
+LSYM(x94)      t0__9a0         ! t0__5t0       ! b_e_2t0       ! t0__t0_2a0
+LSYM(x95)      t0__9a0         ! t0__2t0_a0    ! b_e_t0        ! t0__5t0
+LSYM(x96)      t0__8a0         ! t0__3t0       ! b_e_shift     ! r__r_4t0
+LSYM(x97)      t0__8a0         ! t0__3t0       ! b_e_t0        ! t0__4t0_a0
+LSYM(x98)      t0__32a0        ! t0__3t0       ! b_e_t0        ! t0__t0_2a0
+LSYM(x99)      t0__8a0         ! t0__4t0_a0    ! b_e_t0        ! t0__3t0
+LSYM(x100)     t0__5a0         ! t0__5t0       ! b_e_shift     ! r__r_4t0
+LSYM(x101)     t0__5a0         ! t0__5t0       ! b_e_t0        ! t0__4t0_a0
+LSYM(x102)     t0__32a0        ! t0__t0_2a0    ! b_e_t0        ! t0__3t0
+LSYM(x103)     t0__5a0         ! t0__5t0       ! b_e_t02a0     ! t0__4t0_a0
+LSYM(x104)     t0__3a0         ! t0__4t0_a0    ! b_e_shift     ! r__r_8t0
+LSYM(x105)     t0__5a0         ! t0__4t0_a0    ! b_e_t0        ! t0__5t0
+LSYM(x106)     t0__3a0         ! t0__4t0_a0    ! b_e_2t0       ! t0__4t0_a0
+LSYM(x107)     t0__9a0         ! t0__t0_4a0    ! b_e_t02a0     ! t0__8t0_a0
+LSYM(x108)     t0__9a0         ! t0__3t0       ! b_e_shift     ! r__r_4t0
+LSYM(x109)     t0__9a0         ! t0__3t0       ! b_e_t0        ! t0__4t0_a0
+LSYM(x110)     t0__9a0         ! t0__3t0       ! b_e_2t0       ! t0__2t0_a0
+LSYM(x111)     t0__9a0         ! t0__4t0_a0    ! b_e_t0        ! t0__3t0
+LSYM(x112)     t0__3a0         ! t0__2t0_a0    ! b_e_t0        ! t0__16t0
+LSYM(x113)     t0__9a0         ! t0__4t0_a0    ! b_e_t02a0     ! t0__3t0
+LSYM(x114)     t0__9a0         ! t0__2t0_a0    ! b_e_2t0       ! t0__3t0
+LSYM(x115)     t0__9a0         ! t0__2t0_a0    ! b_e_2t0a0     ! t0__3t0
+LSYM(x116)     t0__3a0         ! t0__2t0_a0    ! b_e_4t0       ! t0__4t0_a0
+LSYM(x117)     t0__3a0         ! t0__4t0_a0    ! b_e_t0        ! t0__9t0
+LSYM(x118)     t0__3a0         ! t0__4t0_a0    ! b_e_t0a0      ! t0__9t0
+LSYM(x119)     t0__3a0         ! t0__4t0_a0    ! b_e_t02a0     ! t0__9t0
+LSYM(x120)     t0__5a0         ! t0__3t0       ! b_e_shift     ! r__r_8t0
+LSYM(x121)     t0__5a0         ! t0__3t0       ! b_e_t0        ! t0__8t0_a0
+LSYM(x122)     t0__5a0         ! t0__3t0       ! b_e_2t0       ! t0__4t0_a0
+LSYM(x123)     t0__5a0         ! t0__8t0_a0    ! b_e_t0        ! t0__3t0
+LSYM(x124)     t0__32a0        ! t0__t0ma0     ! b_e_shift     ! r__r_4t0
+LSYM(x125)     t0__5a0         ! t0__5t0       ! b_e_t0        ! t0__5t0
+LSYM(x126)     t0__64a0        ! t0__t0ma0     ! b_e_shift     ! r__r_2t0
+LSYM(x127)     t0__128a0       ! a1_ne_0_b_l0  ! t0__t0ma0     ! b_n_ret_t0
+LSYM(x128)     t0__128a0       ! a1_ne_0_b_l1  ! r__r_t0       ! MILLIRETN
+LSYM(x129)     t0__128a0       ! a1_ne_0_b_l0  ! t0__t0_a0     ! b_n_ret_t0
+LSYM(x130)     t0__64a0        ! t0__t0_a0     ! b_e_shift     ! r__r_2t0
+LSYM(x131)     t0__8a0         ! t0__8t0_a0    ! b_e_t0        ! t0__2t0_a0
+LSYM(x132)     t0__8a0         ! t0__4t0_a0    ! b_e_shift     ! r__r_4t0
+LSYM(x133)     t0__8a0         ! t0__4t0_a0    ! b_e_t0        ! t0__4t0_a0
+LSYM(x134)     t0__8a0         ! t0__4t0_a0    ! b_e_2t0       ! t0__2t0_a0
+LSYM(x135)     t0__9a0         ! t0__5t0       ! b_e_t0        ! t0__3t0
+LSYM(x136)     t0__8a0         ! t0__2t0_a0    ! b_e_shift     ! r__r_8t0
+LSYM(x137)     t0__8a0         ! t0__2t0_a0    ! b_e_t0        ! t0__8t0_a0
+LSYM(x138)     t0__8a0         ! t0__2t0_a0    ! b_e_2t0       ! t0__4t0_a0
+LSYM(x139)     t0__8a0         ! t0__2t0_a0    ! b_e_2t0a0     ! t0__4t0_a0
+LSYM(x140)     t0__3a0         ! t0__2t0_a0    ! b_e_4t0       ! t0__5t0
+LSYM(x141)     t0__8a0         ! t0__2t0_a0    ! b_e_4t0a0     ! t0__2t0_a0
+LSYM(x142)     t0__9a0         ! t0__8t0       ! b_e_2t0       ! t0__t0ma0
+LSYM(x143)     t0__16a0        ! t0__9t0       ! b_e_t0        ! t0__t0ma0
+LSYM(x144)     t0__9a0         ! t0__8t0       ! b_e_shift     ! r__r_2t0
+LSYM(x145)     t0__9a0         ! t0__8t0       ! b_e_t0        ! t0__2t0_a0
+LSYM(x146)     t0__9a0         ! t0__8t0_a0    ! b_e_shift     ! r__r_2t0
+LSYM(x147)     t0__9a0         ! t0__8t0_a0    ! b_e_t0        ! t0__2t0_a0
+LSYM(x148)     t0__9a0         ! t0__4t0_a0    ! b_e_shift     ! r__r_4t0
+LSYM(x149)     t0__9a0         ! t0__4t0_a0    ! b_e_t0        ! t0__4t0_a0
+LSYM(x150)     t0__9a0         ! t0__4t0_a0    ! b_e_2t0       ! t0__2t0_a0
+LSYM(x151)     t0__9a0         ! t0__4t0_a0    ! b_e_2t0a0     ! t0__2t0_a0
+LSYM(x152)     t0__9a0         ! t0__2t0_a0    ! b_e_shift     ! r__r_8t0
+LSYM(x153)     t0__9a0         ! t0__2t0_a0    ! b_e_t0        ! t0__8t0_a0
+LSYM(x154)     t0__9a0         ! t0__2t0_a0    ! b_e_2t0       ! t0__4t0_a0
+LSYM(x155)     t0__32a0        ! t0__t0ma0     ! b_e_t0        ! t0__5t0
+LSYM(x156)     t0__9a0         ! t0__2t0_a0    ! b_e_4t0       ! t0__2t0_a0
+LSYM(x157)     t0__32a0        ! t0__t0ma0     ! b_e_t02a0     ! t0__5t0
+LSYM(x158)     t0__16a0        ! t0__5t0       ! b_e_2t0       ! t0__t0ma0
+LSYM(x159)     t0__32a0        ! t0__5t0       ! b_e_t0        ! t0__t0ma0
+LSYM(x160)     t0__5a0         ! t0__4t0       ! b_e_shift     ! r__r_8t0
+LSYM(x161)     t0__8a0         ! t0__5t0       ! b_e_t0        ! t0__4t0_a0
+LSYM(x162)     t0__9a0         ! t0__9t0       ! b_e_shift     ! r__r_2t0
+LSYM(x163)     t0__9a0         ! t0__9t0       ! b_e_t0        ! t0__2t0_a0
+LSYM(x164)     t0__5a0         ! t0__8t0_a0    ! b_e_shift     ! r__r_4t0
+LSYM(x165)     t0__8a0         ! t0__4t0_a0    ! b_e_t0        ! t0__5t0
+LSYM(x166)     t0__5a0         ! t0__8t0_a0    ! b_e_2t0       ! t0__2t0_a0
+LSYM(x167)     t0__5a0         ! t0__8t0_a0    ! b_e_2t0a0     ! t0__2t0_a0
+LSYM(x168)     t0__5a0         ! t0__4t0_a0    ! b_e_shift     ! r__r_8t0
+LSYM(x169)     t0__5a0         ! t0__4t0_a0    ! b_e_t0        ! t0__8t0_a0
+LSYM(x170)     t0__32a0        ! t0__t0_2a0    ! b_e_t0        ! t0__5t0
+LSYM(x171)     t0__9a0         ! t0__2t0_a0    ! b_e_t0        ! t0__9t0
+LSYM(x172)     t0__5a0         ! t0__4t0_a0    ! b_e_4t0       ! t0__2t0_a0
+LSYM(x173)     t0__9a0         ! t0__2t0_a0    ! b_e_t02a0     ! t0__9t0
+LSYM(x174)     t0__32a0        ! t0__t0_2a0    ! b_e_t04a0     ! t0__5t0
+LSYM(x175)     t0__8a0         ! t0__2t0_a0    ! b_e_5t0       ! t0__2t0_a0
+LSYM(x176)     t0__5a0         ! t0__4t0_a0    ! b_e_8t0       ! t0__t0_a0
+LSYM(x177)     t0__5a0         ! t0__4t0_a0    ! b_e_8t0a0     ! t0__t0_a0
+LSYM(x178)     t0__5a0         ! t0__2t0_a0    ! b_e_2t0       ! t0__8t0_a0
+LSYM(x179)     t0__5a0         ! t0__2t0_a0    ! b_e_2t0a0     ! t0__8t0_a0
+LSYM(x180)     t0__9a0         ! t0__5t0       ! b_e_shift     ! r__r_4t0
+LSYM(x181)     t0__9a0         ! t0__5t0       ! b_e_t0        ! t0__4t0_a0
+LSYM(x182)     t0__9a0         ! t0__5t0       ! b_e_2t0       ! t0__2t0_a0
+LSYM(x183)     t0__9a0         ! t0__5t0       ! b_e_2t0a0     ! t0__2t0_a0
+LSYM(x184)     t0__5a0         ! t0__9t0       ! b_e_4t0       ! t0__t0_a0
+LSYM(x185)     t0__9a0         ! t0__4t0_a0    ! b_e_t0        ! t0__5t0
+LSYM(x186)     t0__32a0        ! t0__t0ma0     ! b_e_2t0       ! t0__3t0
+LSYM(x187)     t0__9a0         ! t0__4t0_a0    ! b_e_t02a0     ! t0__5t0
+LSYM(x188)     t0__9a0         ! t0__5t0       ! b_e_4t0       ! t0__t0_2a0
+LSYM(x189)     t0__5a0         ! t0__4t0_a0    ! b_e_t0        ! t0__9t0
+LSYM(x190)     t0__9a0         ! t0__2t0_a0    ! b_e_2t0       ! t0__5t0
+LSYM(x191)     t0__64a0        ! t0__3t0       ! b_e_t0        ! t0__t0ma0
+LSYM(x192)     t0__8a0         ! t0__3t0       ! b_e_shift     ! r__r_8t0
+LSYM(x193)     t0__8a0         ! t0__3t0       ! b_e_t0        ! t0__8t0_a0
+LSYM(x194)     t0__8a0         ! t0__3t0       ! b_e_2t0       ! t0__4t0_a0
+LSYM(x195)     t0__8a0         ! t0__8t0_a0    ! b_e_t0        ! t0__3t0
+LSYM(x196)     t0__8a0         ! t0__3t0       ! b_e_4t0       ! t0__2t0_a0
+LSYM(x197)     t0__8a0         ! t0__3t0       ! b_e_4t0a0     ! t0__2t0_a0
+LSYM(x198)     t0__64a0        ! t0__t0_2a0    ! b_e_t0        ! t0__3t0
+LSYM(x199)     t0__8a0         ! t0__4t0_a0    ! b_e_2t0a0     ! t0__3t0
+LSYM(x200)     t0__5a0         ! t0__5t0       ! b_e_shift     ! r__r_8t0
+LSYM(x201)     t0__5a0         ! t0__5t0       ! b_e_t0        ! t0__8t0_a0
+LSYM(x202)     t0__5a0         ! t0__5t0       ! b_e_2t0       ! t0__4t0_a0
+LSYM(x203)     t0__5a0         ! t0__5t0       ! b_e_2t0a0     ! t0__4t0_a0
+LSYM(x204)     t0__8a0         ! t0__2t0_a0    ! b_e_4t0       ! t0__3t0
+LSYM(x205)     t0__5a0         ! t0__8t0_a0    ! b_e_t0        ! t0__5t0
+LSYM(x206)     t0__64a0        ! t0__t0_4a0    ! b_e_t02a0     ! t0__3t0
+LSYM(x207)     t0__8a0         ! t0__2t0_a0    ! b_e_3t0       ! t0__4t0_a0
+LSYM(x208)     t0__5a0         ! t0__5t0       ! b_e_8t0       ! t0__t0_a0
+LSYM(x209)     t0__5a0         ! t0__5t0       ! b_e_8t0a0     ! t0__t0_a0
+LSYM(x210)     t0__5a0         ! t0__4t0_a0    ! b_e_2t0       ! t0__5t0
+LSYM(x211)     t0__5a0         ! t0__4t0_a0    ! b_e_2t0a0     ! t0__5t0
+LSYM(x212)     t0__3a0         ! t0__4t0_a0    ! b_e_4t0       ! t0__4t0_a0
+LSYM(x213)     t0__3a0         ! t0__4t0_a0    ! b_e_4t0a0     ! t0__4t0_a0
+LSYM(x214)     t0__9a0         ! t0__t0_4a0    ! b_e_2t04a0    ! t0__8t0_a0
+LSYM(x215)     t0__5a0         ! t0__4t0_a0    ! b_e_5t0       ! t0__2t0_a0
+LSYM(x216)     t0__9a0         ! t0__3t0       ! b_e_shift     ! r__r_8t0
+LSYM(x217)     t0__9a0         ! t0__3t0       ! b_e_t0        ! t0__8t0_a0
+LSYM(x218)     t0__9a0         ! t0__3t0       ! b_e_2t0       ! t0__4t0_a0
+LSYM(x219)     t0__9a0         ! t0__8t0_a0    ! b_e_t0        ! t0__3t0
+LSYM(x220)     t0__3a0         ! t0__9t0       ! b_e_4t0       ! t0__2t0_a0
+LSYM(x221)     t0__3a0         ! t0__9t0       ! b_e_4t0a0     ! t0__2t0_a0
+LSYM(x222)     t0__9a0         ! t0__4t0_a0    ! b_e_2t0       ! t0__3t0
+LSYM(x223)     t0__9a0         ! t0__4t0_a0    ! b_e_2t0a0     ! t0__3t0
+LSYM(x224)     t0__9a0         ! t0__3t0       ! b_e_8t0       ! t0__t0_a0
+LSYM(x225)     t0__9a0         ! t0__5t0       ! b_e_t0        ! t0__5t0
+LSYM(x226)     t0__3a0         ! t0__2t0_a0    ! b_e_t02a0     ! t0__32t0
+LSYM(x227)     t0__9a0         ! t0__5t0       ! b_e_t02a0     ! t0__5t0
+LSYM(x228)     t0__9a0         ! t0__2t0_a0    ! b_e_4t0       ! t0__3t0
+LSYM(x229)     t0__9a0         ! t0__2t0_a0    ! b_e_4t0a0     ! t0__3t0
+LSYM(x230)     t0__9a0         ! t0__5t0       ! b_e_5t0       ! t0__t0_a0
+LSYM(x231)     t0__9a0         ! t0__2t0_a0    ! b_e_3t0       ! t0__4t0_a0
+LSYM(x232)     t0__3a0         ! t0__2t0_a0    ! b_e_8t0       ! t0__4t0_a0
+LSYM(x233)     t0__3a0         ! t0__2t0_a0    ! b_e_8t0a0     ! t0__4t0_a0
+LSYM(x234)     t0__3a0         ! t0__4t0_a0    ! b_e_2t0       ! t0__9t0
+LSYM(x235)     t0__3a0         ! t0__4t0_a0    ! b_e_2t0a0     ! t0__9t0
+LSYM(x236)     t0__9a0         ! t0__2t0_a0    ! b_e_4t08a0    ! t0__3t0
+LSYM(x237)     t0__16a0        ! t0__5t0       ! b_e_3t0       ! t0__t0ma0
+LSYM(x238)     t0__3a0         ! t0__4t0_a0    ! b_e_2t04a0    ! t0__9t0
+LSYM(x239)     t0__16a0        ! t0__5t0       ! b_e_t0ma0     ! t0__3t0
+LSYM(x240)     t0__9a0         ! t0__t0_a0     ! b_e_8t0       ! t0__3t0
+LSYM(x241)     t0__9a0         ! t0__t0_a0     ! b_e_8t0a0     ! t0__3t0
+LSYM(x242)     t0__5a0         ! t0__3t0       ! b_e_2t0       ! t0__8t0_a0
+LSYM(x243)     t0__9a0         ! t0__9t0       ! b_e_t0        ! t0__3t0
+LSYM(x244)     t0__5a0         ! t0__3t0       ! b_e_4t0       ! t0__4t0_a0
+LSYM(x245)     t0__8a0         ! t0__3t0       ! b_e_5t0       ! t0__2t0_a0
+LSYM(x246)     t0__5a0         ! t0__8t0_a0    ! b_e_2t0       ! t0__3t0
+LSYM(x247)     t0__5a0         ! t0__8t0_a0    ! b_e_2t0a0     ! t0__3t0
+LSYM(x248)     t0__32a0        ! t0__t0ma0     ! b_e_shift     ! r__r_8t0
+LSYM(x249)     t0__32a0        ! t0__t0ma0     ! b_e_t0        ! t0__8t0_a0
+LSYM(x250)     t0__5a0         ! t0__5t0       ! b_e_2t0       ! t0__5t0
+LSYM(x251)     t0__5a0         ! t0__5t0       ! b_e_2t0a0     ! t0__5t0
+LSYM(x252)     t0__64a0        ! t0__t0ma0     ! b_e_shift     ! r__r_4t0
+LSYM(x253)     t0__64a0        ! t0__t0ma0     ! b_e_t0        ! t0__4t0_a0
+LSYM(x254)     t0__128a0       ! t0__t0ma0     ! b_e_shift     ! r__r_2t0
+LSYM(x255)     t0__256a0       ! a1_ne_0_b_l0  ! t0__t0ma0     ! b_n_ret_t0
+/*1040 insts before this.  */
+LSYM(ret_t0)   MILLIRET
+LSYM(e_t0)     r__r_t0
+LSYM(e_shift)  a1_ne_0_b_l2
+       a0__256a0       /* a0 <<= 8 *********** */
+       MILLIRETN
+LSYM(e_t0ma0)  a1_ne_0_b_l0
+       t0__t0ma0
+       MILLIRET
+       r__r_t0
+LSYM(e_t0a0)   a1_ne_0_b_l0
+       t0__t0_a0
+       MILLIRET
+       r__r_t0
+LSYM(e_t02a0)  a1_ne_0_b_l0
+       t0__t0_2a0
+       MILLIRET
+       r__r_t0
+LSYM(e_t04a0)  a1_ne_0_b_l0
+       t0__t0_4a0
+       MILLIRET
+       r__r_t0
+LSYM(e_2t0)    a1_ne_0_b_l1
+       r__r_2t0
+       MILLIRETN
+LSYM(e_2t0a0)  a1_ne_0_b_l0
+       t0__2t0_a0
+       MILLIRET
+       r__r_t0
+LSYM(e2t04a0)  t0__t0_2a0
+       a1_ne_0_b_l1
+       r__r_2t0
+       MILLIRETN
+LSYM(e_3t0)    a1_ne_0_b_l0
+       t0__3t0
+       MILLIRET
+       r__r_t0
+LSYM(e_4t0)    a1_ne_0_b_l1
+       r__r_4t0
+       MILLIRETN
+LSYM(e_4t0a0)  a1_ne_0_b_l0
+       t0__4t0_a0
+       MILLIRET
+       r__r_t0
+LSYM(e4t08a0)  t0__t0_2a0
+       a1_ne_0_b_l1
+       r__r_4t0
+       MILLIRETN
+LSYM(e_5t0)    a1_ne_0_b_l0
+       t0__5t0
+       MILLIRET
+       r__r_t0
+LSYM(e_8t0)    a1_ne_0_b_l1
+       r__r_8t0
+       MILLIRETN
+LSYM(e_8t0a0)  a1_ne_0_b_l0
+       t0__8t0_a0
+       MILLIRET
+       r__r_t0
+
+       .procend
+       .end
+#endif
diff --git a/arch/parisc/lib/milli/milli.h b/arch/parisc/lib/milli/milli.h
new file mode 100644 (file)
index 0000000..19ac79f
--- /dev/null
@@ -0,0 +1,165 @@
+/* 32 and 64-bit millicode, original author Hewlett-Packard
+   adapted for gcc by Paul Bame <bame@debian.org>
+   and Alan Modra <alan@linuxcare.com.au>.
+
+   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
+   This file is part of GCC and is released under the terms of
+   of the GNU General Public License as published by the Free Software
+   Foundation; either version 2, or (at your option) any later version.
+   See the file COPYING in the top-level GCC source directory for a copy
+   of the license.  */
+
+#ifndef _PA_MILLI_H_
+#define _PA_MILLI_H_
+
+#define L_dyncall
+#define L_divI
+#define L_divU
+#define L_remI
+#define L_remU
+#define L_div_const
+#define L_mulI
+
+#ifdef CONFIG_64BIT
+        .level  2.0w
+#endif
+
+/* Hardware General Registers.  */
+r0:    .reg    %r0
+r1:    .reg    %r1
+r2:    .reg    %r2
+r3:    .reg    %r3
+r4:    .reg    %r4
+r5:    .reg    %r5
+r6:    .reg    %r6
+r7:    .reg    %r7
+r8:    .reg    %r8
+r9:    .reg    %r9
+r10:   .reg    %r10
+r11:   .reg    %r11
+r12:   .reg    %r12
+r13:   .reg    %r13
+r14:   .reg    %r14
+r15:   .reg    %r15
+r16:   .reg    %r16
+r17:   .reg    %r17
+r18:   .reg    %r18
+r19:   .reg    %r19
+r20:   .reg    %r20
+r21:   .reg    %r21
+r22:   .reg    %r22
+r23:   .reg    %r23
+r24:   .reg    %r24
+r25:   .reg    %r25
+r26:   .reg    %r26
+r27:   .reg    %r27
+r28:   .reg    %r28
+r29:   .reg    %r29
+r30:   .reg    %r30
+r31:   .reg    %r31
+
+/* Hardware Space Registers.  */
+sr0:   .reg    %sr0
+sr1:   .reg    %sr1
+sr2:   .reg    %sr2
+sr3:   .reg    %sr3
+sr4:   .reg    %sr4
+sr5:   .reg    %sr5
+sr6:   .reg    %sr6
+sr7:   .reg    %sr7
+
+/* Hardware Floating Point Registers.  */
+fr0:   .reg    %fr0
+fr1:   .reg    %fr1
+fr2:   .reg    %fr2
+fr3:   .reg    %fr3
+fr4:   .reg    %fr4
+fr5:   .reg    %fr5
+fr6:   .reg    %fr6
+fr7:   .reg    %fr7
+fr8:   .reg    %fr8
+fr9:   .reg    %fr9
+fr10:  .reg    %fr10
+fr11:  .reg    %fr11
+fr12:  .reg    %fr12
+fr13:  .reg    %fr13
+fr14:  .reg    %fr14
+fr15:  .reg    %fr15
+
+/* Hardware Control Registers.  */
+cr11:  .reg    %cr11
+sar:   .reg    %cr11   /* Shift Amount Register */
+
+/* Software Architecture General Registers.  */
+rp:    .reg    r2      /* return pointer */
+#ifdef CONFIG_64BIT
+mrp:   .reg    r2      /* millicode return pointer */
+#else
+mrp:   .reg    r31     /* millicode return pointer */
+#endif
+ret0:  .reg    r28     /* return value */
+ret1:  .reg    r29     /* return value (high part of double) */
+sp:    .reg    r30     /* stack pointer */
+dp:    .reg    r27     /* data pointer */
+arg0:  .reg    r26     /* argument */
+arg1:  .reg    r25     /* argument or high part of double argument */
+arg2:  .reg    r24     /* argument */
+arg3:  .reg    r23     /* argument or high part of double argument */
+
+/* Software Architecture Space Registers.  */
+/*             sr0     ; return link from BLE */
+sret:  .reg    sr1     /* return value */
+sarg:  .reg    sr1     /* argument */
+/*             sr4     ; PC SPACE tracker */
+/*             sr5     ; process private data */
+
+/* Frame Offsets (millicode convention!)  Used when calling other
+   millicode routines.  Stack unwinding is dependent upon these
+   definitions.  */
+r31_slot:      .equ    -20     /* "current RP" slot */
+sr0_slot:      .equ    -16     /* "static link" slot */
+#if defined(CONFIG_64BIT)
+mrp_slot:       .equ    -16    /* "current RP" slot */
+psp_slot:       .equ    -8     /* "previous SP" slot */
+#else
+mrp_slot:      .equ    -20     /* "current RP" slot (replacing "r31_slot") */
+#endif
+
+
+#define DEFINE(name,value)name:        .EQU    value
+#define RDEFINE(name,value)name:       .REG    value
+#ifdef milliext
+#define MILLI_BE(lbl)   BE    lbl(sr7,r0)
+#define MILLI_BEN(lbl)  BE,n  lbl(sr7,r0)
+#define MILLI_BLE(lbl) BLE   lbl(sr7,r0)
+#define MILLI_BLEN(lbl)        BLE,n lbl(sr7,r0)
+#define MILLIRETN      BE,n  0(sr0,mrp)
+#define MILLIRET       BE    0(sr0,mrp)
+#define MILLI_RETN     BE,n  0(sr0,mrp)
+#define MILLI_RET      BE    0(sr0,mrp)
+#else
+#define MILLI_BE(lbl)  B     lbl
+#define MILLI_BEN(lbl)  B,n   lbl
+#define MILLI_BLE(lbl) BL    lbl,mrp
+#define MILLI_BLEN(lbl)        BL,n  lbl,mrp
+#define MILLIRETN      BV,n  0(mrp)
+#define MILLIRET       BV    0(mrp)
+#define MILLI_RETN     BV,n  0(mrp)
+#define MILLI_RET      BV    0(mrp)
+#endif
+
+#define CAT(a,b)       a##b
+
+#define SUBSPA_MILLI    .section .text
+#define SUBSPA_MILLI_DIV .section .text.div,"ax",@progbits! .align 16
+#define SUBSPA_MILLI_MUL .section .text.mul,"ax",@progbits! .align 16
+#define ATTR_MILLI
+#define SUBSPA_DATA     .section .data
+#define ATTR_DATA
+#define GLOBAL          $global$
+#define GSYM(sym)       !sym:
+#define LSYM(sym)       !CAT(.L,sym:)
+#define LREF(sym)       CAT(.L,sym)
+
+#endif /*_PA_MILLI_H_*/
diff --git a/arch/parisc/lib/milli/mulI.S b/arch/parisc/lib/milli/mulI.S
new file mode 100644 (file)
index 0000000..4c7e0c3
--- /dev/null
@@ -0,0 +1,474 @@
+/* 32 and 64-bit millicode, original author Hewlett-Packard
+   adapted for gcc by Paul Bame <bame@debian.org>
+   and Alan Modra <alan@linuxcare.com.au>.
+
+   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
+   This file is part of GCC and is released under the terms of
+   of the GNU General Public License as published by the Free Software
+   Foundation; either version 2, or (at your option) any later version.
+   See the file COPYING in the top-level GCC source directory for a copy
+   of the license.  */
+
+#include "milli.h"
+
+#ifdef L_mulI
+/* VERSION "@(#)$$mulI $ Revision: 12.4 $ $ Date: 94/03/17 17:18:51 $" */
+/******************************************************************************
+This routine is used on PA2.0 processors when gcc -mno-fpregs is used
+
+ROUTINE:       $$mulI
+
+
+DESCRIPTION:   
+
+       $$mulI multiplies two single word integers, giving a single 
+       word result.  
+
+
+INPUT REGISTERS:
+
+       arg0 = Operand 1
+       arg1 = Operand 2
+       r31  == return pc
+       sr0  == return space when called externally 
+
+
+OUTPUT REGISTERS:
+
+       arg0 = undefined
+       arg1 = undefined
+       ret1 = result 
+
+OTHER REGISTERS AFFECTED:
+
+       r1   = undefined
+
+SIDE EFFECTS:
+
+       Causes a trap under the following conditions:  NONE
+       Changes memory at the following places:  NONE
+
+PERMISSIBLE CONTEXT:
+
+       Unwindable
+       Does not create a stack frame
+       Is usable for internal or external microcode
+
+DISCUSSION:
+
+       Calls other millicode routines via mrp:  NONE
+       Calls other millicode routines:  NONE
+
+***************************************************************************/
+
+
+#define        a0      %arg0
+#define        a1      %arg1
+#define        t0      %r1
+#define        r       %ret1
+
+#define        a0__128a0       zdep    a0,24,25,a0
+#define        a0__256a0       zdep    a0,23,24,a0
+#define        a1_ne_0_b_l0    comb,<> a1,0,LREF(l0)
+#define        a1_ne_0_b_l1    comb,<> a1,0,LREF(l1)
+#define        a1_ne_0_b_l2    comb,<> a1,0,LREF(l2)
+#define        b_n_ret_t0      b,n     LREF(ret_t0)
+#define        b_e_shift       b       LREF(e_shift)
+#define        b_e_t0ma0       b       LREF(e_t0ma0)
+#define        b_e_t0          b       LREF(e_t0)
+#define        b_e_t0a0        b       LREF(e_t0a0)
+#define        b_e_t02a0       b       LREF(e_t02a0)
+#define        b_e_t04a0       b       LREF(e_t04a0)
+#define        b_e_2t0         b       LREF(e_2t0)
+#define        b_e_2t0a0       b       LREF(e_2t0a0)
+#define        b_e_2t04a0      b       LREF(e2t04a0)
+#define        b_e_3t0         b       LREF(e_3t0)
+#define        b_e_4t0         b       LREF(e_4t0)
+#define        b_e_4t0a0       b       LREF(e_4t0a0)
+#define        b_e_4t08a0      b       LREF(e4t08a0)
+#define        b_e_5t0         b       LREF(e_5t0)
+#define        b_e_8t0         b       LREF(e_8t0)
+#define        b_e_8t0a0       b       LREF(e_8t0a0)
+#define        r__r_a0         add     r,a0,r
+#define        r__r_2a0        sh1add  a0,r,r
+#define        r__r_4a0        sh2add  a0,r,r
+#define        r__r_8a0        sh3add  a0,r,r
+#define        r__r_t0         add     r,t0,r
+#define        r__r_2t0        sh1add  t0,r,r
+#define        r__r_4t0        sh2add  t0,r,r
+#define        r__r_8t0        sh3add  t0,r,r
+#define        t0__3a0         sh1add  a0,a0,t0
+#define        t0__4a0         sh2add  a0,0,t0
+#define        t0__5a0         sh2add  a0,a0,t0
+#define        t0__8a0         sh3add  a0,0,t0
+#define        t0__9a0         sh3add  a0,a0,t0
+#define        t0__16a0        zdep    a0,27,28,t0
+#define        t0__32a0        zdep    a0,26,27,t0
+#define        t0__64a0        zdep    a0,25,26,t0
+#define        t0__128a0       zdep    a0,24,25,t0
+#define        t0__t0ma0       sub     t0,a0,t0
+#define        t0__t0_a0       add     t0,a0,t0
+#define        t0__t0_2a0      sh1add  a0,t0,t0
+#define        t0__t0_4a0      sh2add  a0,t0,t0
+#define        t0__t0_8a0      sh3add  a0,t0,t0
+#define        t0__2t0_a0      sh1add  t0,a0,t0
+#define        t0__3t0         sh1add  t0,t0,t0
+#define        t0__4t0         sh2add  t0,0,t0
+#define        t0__4t0_a0      sh2add  t0,a0,t0
+#define        t0__5t0         sh2add  t0,t0,t0
+#define        t0__8t0         sh3add  t0,0,t0
+#define        t0__8t0_a0      sh3add  t0,a0,t0
+#define        t0__9t0         sh3add  t0,t0,t0
+#define        t0__16t0        zdep    t0,27,28,t0
+#define        t0__32t0        zdep    t0,26,27,t0
+#define        t0__256a0       zdep    a0,23,24,t0
+
+
+       SUBSPA_MILLI
+       ATTR_MILLI
+       .align 16
+       .proc
+       .callinfo millicode
+       .export $$mulI,millicode
+GSYM($$mulI)   
+       combt,<<=       a1,a0,LREF(l4)  /* swap args if unsigned a1>a0 */
+       copy            0,r             /* zero out the result */
+       xor             a0,a1,a0        /* swap a0 & a1 using the */
+       xor             a0,a1,a1        /*  old xor trick */
+       xor             a0,a1,a0
+LSYM(l4)
+       combt,<=        0,a0,LREF(l3)           /* if a0>=0 then proceed like unsigned */
+       zdep            a1,30,8,t0      /* t0 = (a1&0xff)<<1 ********* */
+       sub,>           0,a1,t0         /* otherwise negate both and */
+       combt,<=,n      a0,t0,LREF(l2)  /*  swap back if |a0|<|a1| */
+       sub             0,a0,a1
+       movb,tr,n       t0,a0,LREF(l2)  /* 10th inst.  */
+
+LSYM(l0)       r__r_t0                         /* add in this partial product */
+LSYM(l1)       a0__256a0                       /* a0 <<= 8 ****************** */
+LSYM(l2)       zdep            a1,30,8,t0      /* t0 = (a1&0xff)<<1 ********* */
+LSYM(l3)       blr             t0,0            /* case on these 8 bits ****** */
+               extru           a1,23,24,a1     /* a1 >>= 8 ****************** */
+
+/*16 insts before this.  */
+/*                       a0 <<= 8 ************************** */
+LSYM(x0)       a1_ne_0_b_l2    ! a0__256a0     ! MILLIRETN     ! nop
+LSYM(x1)       a1_ne_0_b_l1    ! r__r_a0       ! MILLIRETN     ! nop
+LSYM(x2)       a1_ne_0_b_l1    ! r__r_2a0      ! MILLIRETN     ! nop
+LSYM(x3)       a1_ne_0_b_l0    ! t0__3a0       ! MILLIRET      ! r__r_t0
+LSYM(x4)       a1_ne_0_b_l1    ! r__r_4a0      ! MILLIRETN     ! nop
+LSYM(x5)       a1_ne_0_b_l0    ! t0__5a0       ! MILLIRET      ! r__r_t0
+LSYM(x6)       t0__3a0         ! a1_ne_0_b_l1  ! r__r_2t0      ! MILLIRETN
+LSYM(x7)       t0__3a0         ! a1_ne_0_b_l0  ! r__r_4a0      ! b_n_ret_t0
+LSYM(x8)       a1_ne_0_b_l1    ! r__r_8a0      ! MILLIRETN     ! nop
+LSYM(x9)       a1_ne_0_b_l0    ! t0__9a0       ! MILLIRET      ! r__r_t0
+LSYM(x10)      t0__5a0         ! a1_ne_0_b_l1  ! r__r_2t0      ! MILLIRETN
+LSYM(x11)      t0__3a0         ! a1_ne_0_b_l0  ! r__r_8a0      ! b_n_ret_t0
+LSYM(x12)      t0__3a0         ! a1_ne_0_b_l1  ! r__r_4t0      ! MILLIRETN
+LSYM(x13)      t0__5a0         ! a1_ne_0_b_l0  ! r__r_8a0      ! b_n_ret_t0
+LSYM(x14)      t0__3a0         ! t0__2t0_a0    ! b_e_shift     ! r__r_2t0
+LSYM(x15)      t0__5a0         ! a1_ne_0_b_l0  ! t0__3t0       ! b_n_ret_t0
+LSYM(x16)      t0__16a0        ! a1_ne_0_b_l1  ! r__r_t0       ! MILLIRETN
+LSYM(x17)      t0__9a0         ! a1_ne_0_b_l0  ! t0__t0_8a0    ! b_n_ret_t0
+LSYM(x18)      t0__9a0         ! a1_ne_0_b_l1  ! r__r_2t0      ! MILLIRETN
+LSYM(x19)      t0__9a0         ! a1_ne_0_b_l0  ! t0__2t0_a0    ! b_n_ret_t0
+LSYM(x20)      t0__5a0         ! a1_ne_0_b_l1  ! r__r_4t0      ! MILLIRETN
+LSYM(x21)      t0__5a0         ! a1_ne_0_b_l0  ! t0__4t0_a0    ! b_n_ret_t0
+LSYM(x22)      t0__5a0         ! t0__2t0_a0    ! b_e_shift     ! r__r_2t0
+LSYM(x23)      t0__5a0         ! t0__2t0_a0    ! b_e_t0        ! t0__2t0_a0
+LSYM(x24)      t0__3a0         ! a1_ne_0_b_l1  ! r__r_8t0      ! MILLIRETN
+LSYM(x25)      t0__5a0         ! a1_ne_0_b_l0  ! t0__5t0       ! b_n_ret_t0
+LSYM(x26)      t0__3a0         ! t0__4t0_a0    ! b_e_shift     ! r__r_2t0
+LSYM(x27)      t0__3a0         ! a1_ne_0_b_l0  ! t0__9t0       ! b_n_ret_t0
+LSYM(x28)      t0__3a0         ! t0__2t0_a0    ! b_e_shift     ! r__r_4t0
+LSYM(x29)      t0__3a0         ! t0__2t0_a0    ! b_e_t0        ! t0__4t0_a0
+LSYM(x30)      t0__5a0         ! t0__3t0       ! b_e_shift     ! r__r_2t0
+LSYM(x31)      t0__32a0        ! a1_ne_0_b_l0  ! t0__t0ma0     ! b_n_ret_t0
+LSYM(x32)      t0__32a0        ! a1_ne_0_b_l1  ! r__r_t0       ! MILLIRETN
+LSYM(x33)      t0__8a0         ! a1_ne_0_b_l0  ! t0__4t0_a0    ! b_n_ret_t0
+LSYM(x34)      t0__16a0        ! t0__t0_a0     ! b_e_shift     ! r__r_2t0
+LSYM(x35)      t0__9a0         ! t0__3t0       ! b_e_t0        ! t0__t0_8a0
+LSYM(x36)      t0__9a0         ! a1_ne_0_b_l1  ! r__r_4t0      ! MILLIRETN
+LSYM(x37)      t0__9a0         ! a1_ne_0_b_l0  ! t0__4t0_a0    ! b_n_ret_t0
+LSYM(x38)      t0__9a0         ! t0__2t0_a0    ! b_e_shift     ! r__r_2t0
+LSYM(x39)      t0__9a0         ! t0__2t0_a0    ! b_e_t0        ! t0__2t0_a0
+LSYM(x40)      t0__5a0         ! a1_ne_0_b_l1  ! r__r_8t0      ! MILLIRETN
+LSYM(x41)      t0__5a0         ! a1_ne_0_b_l0  ! t0__8t0_a0    ! b_n_ret_t0
+LSYM(x42)      t0__5a0         ! t0__4t0_a0    ! b_e_shift     ! r__r_2t0
+LSYM(x43)      t0__5a0         ! t0__4t0_a0    ! b_e_t0        ! t0__2t0_a0
+LSYM(x44)      t0__5a0         ! t0__2t0_a0    ! b_e_shift     ! r__r_4t0
+LSYM(x45)      t0__9a0         ! a1_ne_0_b_l0  ! t0__5t0       ! b_n_ret_t0
+LSYM(x46)      t0__9a0         ! t0__5t0       ! b_e_t0        ! t0__t0_a0
+LSYM(x47)      t0__9a0         ! t0__5t0       ! b_e_t0        ! t0__t0_2a0
+LSYM(x48)      t0__3a0         ! a1_ne_0_b_l0  ! t0__16t0      ! b_n_ret_t0
+LSYM(x49)      t0__9a0         ! t0__5t0       ! b_e_t0        ! t0__t0_4a0
+LSYM(x50)      t0__5a0         ! t0__5t0       ! b_e_shift     ! r__r_2t0
+LSYM(x51)      t0__9a0         ! t0__t0_8a0    ! b_e_t0        ! t0__3t0
+LSYM(x52)      t0__3a0         ! t0__4t0_a0    ! b_e_shift     ! r__r_4t0
+LSYM(x53)      t0__3a0         ! t0__4t0_a0    ! b_e_t0        ! t0__4t0_a0
+LSYM(x54)      t0__9a0         ! t0__3t0       ! b_e_shift     ! r__r_2t0
+LSYM(x55)      t0__9a0         ! t0__3t0       ! b_e_t0        ! t0__2t0_a0
+LSYM(x56)      t0__3a0         ! t0__2t0_a0    ! b_e_shift     ! r__r_8t0
+LSYM(x57)      t0__9a0         ! t0__2t0_a0    ! b_e_t0        ! t0__3t0
+LSYM(x58)      t0__3a0         ! t0__2t0_a0    ! b_e_2t0       ! t0__4t0_a0
+LSYM(x59)      t0__9a0         ! t0__2t0_a0    ! b_e_t02a0     ! t0__3t0
+LSYM(x60)      t0__5a0         ! t0__3t0       ! b_e_shift     ! r__r_4t0
+LSYM(x61)      t0__5a0         ! t0__3t0       ! b_e_t0        ! t0__4t0_a0
+LSYM(x62)      t0__32a0        ! t0__t0ma0     ! b_e_shift     ! r__r_2t0
+LSYM(x63)      t0__64a0        ! a1_ne_0_b_l0  ! t0__t0ma0     ! b_n_ret_t0
+LSYM(x64)      t0__64a0        ! a1_ne_0_b_l1  ! r__r_t0       ! MILLIRETN
+LSYM(x65)      t0__8a0         ! a1_ne_0_b_l0  ! t0__8t0_a0    ! b_n_ret_t0
+LSYM(x66)      t0__32a0        ! t0__t0_a0     ! b_e_shift     ! r__r_2t0
+LSYM(x67)      t0__8a0         ! t0__4t0_a0    ! b_e_t0        ! t0__2t0_a0
+LSYM(x68)      t0__8a0         ! t0__2t0_a0    ! b_e_shift     ! r__r_4t0
+LSYM(x69)      t0__8a0         ! t0__2t0_a0    ! b_e_t0        ! t0__4t0_a0
+LSYM(x70)      t0__64a0        ! t0__t0_4a0    ! b_e_t0        ! t0__t0_2a0
+LSYM(x71)      t0__9a0         ! t0__8t0       ! b_e_t0        ! t0__t0ma0
+LSYM(x72)      t0__9a0         ! a1_ne_0_b_l1  ! r__r_8t0      ! MILLIRETN
+LSYM(x73)      t0__9a0         ! t0__8t0_a0    ! b_e_shift     ! r__r_t0
+LSYM(x74)      t0__9a0         ! t0__4t0_a0    ! b_e_shift     ! r__r_2t0
+LSYM(x75)      t0__9a0         ! t0__4t0_a0    ! b_e_t0        ! t0__2t0_a0
+LSYM(x76)      t0__9a0         ! t0__2t0_a0    ! b_e_shift     ! r__r_4t0
+LSYM(x77)      t0__9a0         ! t0__2t0_a0    ! b_e_t0        ! t0__4t0_a0
+LSYM(x78)      t0__9a0         ! t0__2t0_a0    ! b_e_2t0       ! t0__2t0_a0
+LSYM(x79)      t0__16a0        ! t0__5t0       ! b_e_t0        ! t0__t0ma0
+LSYM(x80)      t0__16a0        ! t0__5t0       ! b_e_shift     ! r__r_t0
+LSYM(x81)      t0__9a0         ! t0__9t0       ! b_e_shift     ! r__r_t0
+LSYM(x82)      t0__5a0         ! t0__8t0_a0    ! b_e_shift     ! r__r_2t0
+LSYM(x83)      t0__5a0         ! t0__8t0_a0    ! b_e_t0        ! t0__2t0_a0
+LSYM(x84)      t0__5a0         ! t0__4t0_a0    ! b_e_shift     ! r__r_4t0
+LSYM(x85)      t0__8a0         ! t0__2t0_a0    ! b_e_t0        ! t0__5t0
+LSYM(x86)      t0__5a0         ! t0__4t0_a0    ! b_e_2t0       ! t0__2t0_a0
+LSYM(x87)      t0__9a0         ! t0__9t0       ! b_e_t02a0     ! t0__t0_4a0
+LSYM(x88)      t0__5a0         ! t0__2t0_a0    ! b_e_shift     ! r__r_8t0
+LSYM(x89)      t0__5a0         ! t0__2t0_a0    ! b_e_t0        ! t0__8t0_a0
+LSYM(x90)      t0__9a0         ! t0__5t0       ! b_e_shift     ! r__r_2t0
+LSYM(x91)      t0__9a0         ! t0__5t0       ! b_e_t0        ! t0__2t0_a0
+LSYM(x92)      t0__5a0         ! t0__2t0_a0    ! b_e_4t0       ! t0__2t0_a0
+LSYM(x93)      t0__32a0        ! t0__t0ma0     ! b_e_t0        ! t0__3t0
+LSYM(x94)      t0__9a0         ! t0__5t0       ! b_e_2t0       ! t0__t0_2a0
+LSYM(x95)      t0__9a0         ! t0__2t0_a0    ! b_e_t0        ! t0__5t0
+LSYM(x96)      t0__8a0         ! t0__3t0       ! b_e_shift     ! r__r_4t0
+LSYM(x97)      t0__8a0         ! t0__3t0       ! b_e_t0        ! t0__4t0_a0
+LSYM(x98)      t0__32a0        ! t0__3t0       ! b_e_t0        ! t0__t0_2a0
+LSYM(x99)      t0__8a0         ! t0__4t0_a0    ! b_e_t0        ! t0__3t0
+LSYM(x100)     t0__5a0         ! t0__5t0       ! b_e_shift     ! r__r_4t0
+LSYM(x101)     t0__5a0         ! t0__5t0       ! b_e_t0        ! t0__4t0_a0
+LSYM(x102)     t0__32a0        ! t0__t0_2a0    ! b_e_t0        ! t0__3t0
+LSYM(x103)     t0__5a0         ! t0__5t0       ! b_e_t02a0     ! t0__4t0_a0
+LSYM(x104)     t0__3a0         ! t0__4t0_a0    ! b_e_shift     ! r__r_8t0
+LSYM(x105)     t0__5a0         ! t0__4t0_a0    ! b_e_t0        ! t0__5t0
+LSYM(x106)     t0__3a0         ! t0__4t0_a0    ! b_e_2t0       ! t0__4t0_a0
+LSYM(x107)     t0__9a0         ! t0__t0_4a0    ! b_e_t02a0     ! t0__8t0_a0
+LSYM(x108)     t0__9a0         ! t0__3t0       ! b_e_shift     ! r__r_4t0
+LSYM(x109)     t0__9a0         ! t0__3t0       ! b_e_t0        ! t0__4t0_a0
+LSYM(x110)     t0__9a0         ! t0__3t0       ! b_e_2t0       ! t0__2t0_a0
+LSYM(x111)     t0__9a0         ! t0__4t0_a0    ! b_e_t0        ! t0__3t0
+LSYM(x112)     t0__3a0         ! t0__2t0_a0    ! b_e_t0        ! t0__16t0
+LSYM(x113)     t0__9a0         ! t0__4t0_a0    ! b_e_t02a0     ! t0__3t0
+LSYM(x114)     t0__9a0         ! t0__2t0_a0    ! b_e_2t0       ! t0__3t0
+LSYM(x115)     t0__9a0         ! t0__2t0_a0    ! b_e_2t0a0     ! t0__3t0
+LSYM(x116)     t0__3a0         ! t0__2t0_a0    ! b_e_4t0       ! t0__4t0_a0
+LSYM(x117)     t0__3a0         ! t0__4t0_a0    ! b_e_t0        ! t0__9t0
+LSYM(x118)     t0__3a0         ! t0__4t0_a0    ! b_e_t0a0      ! t0__9t0
+LSYM(x119)     t0__3a0         ! t0__4t0_a0    ! b_e_t02a0     ! t0__9t0
+LSYM(x120)     t0__5a0         ! t0__3t0       ! b_e_shift     ! r__r_8t0
+LSYM(x121)     t0__5a0         ! t0__3t0       ! b_e_t0        ! t0__8t0_a0
+LSYM(x122)     t0__5a0         ! t0__3t0       ! b_e_2t0       ! t0__4t0_a0
+LSYM(x123)     t0__5a0         ! t0__8t0_a0    ! b_e_t0        ! t0__3t0
+LSYM(x124)     t0__32a0        ! t0__t0ma0     ! b_e_shift     ! r__r_4t0
+LSYM(x125)     t0__5a0         ! t0__5t0       ! b_e_t0        ! t0__5t0
+LSYM(x126)     t0__64a0        ! t0__t0ma0     ! b_e_shift     ! r__r_2t0
+LSYM(x127)     t0__128a0       ! a1_ne_0_b_l0  ! t0__t0ma0     ! b_n_ret_t0
+LSYM(x128)     t0__128a0       ! a1_ne_0_b_l1  ! r__r_t0       ! MILLIRETN
+LSYM(x129)     t0__128a0       ! a1_ne_0_b_l0  ! t0__t0_a0     ! b_n_ret_t0
+LSYM(x130)     t0__64a0        ! t0__t0_a0     ! b_e_shift     ! r__r_2t0
+LSYM(x131)     t0__8a0         ! t0__8t0_a0    ! b_e_t0        ! t0__2t0_a0
+LSYM(x132)     t0__8a0         ! t0__4t0_a0    ! b_e_shift     ! r__r_4t0
+LSYM(x133)     t0__8a0         ! t0__4t0_a0    ! b_e_t0        ! t0__4t0_a0
+LSYM(x134)     t0__8a0         ! t0__4t0_a0    ! b_e_2t0       ! t0__2t0_a0
+LSYM(x135)     t0__9a0         ! t0__5t0       ! b_e_t0        ! t0__3t0
+LSYM(x136)     t0__8a0         ! t0__2t0_a0    ! b_e_shift     ! r__r_8t0
+LSYM(x137)     t0__8a0         ! t0__2t0_a0    ! b_e_t0        ! t0__8t0_a0
+LSYM(x138)     t0__8a0         ! t0__2t0_a0    ! b_e_2t0       ! t0__4t0_a0
+LSYM(x139)     t0__8a0         ! t0__2t0_a0    ! b_e_2t0a0     ! t0__4t0_a0
+LSYM(x140)     t0__3a0         ! t0__2t0_a0    ! b_e_4t0       ! t0__5t0
+LSYM(x141)     t0__8a0         ! t0__2t0_a0    ! b_e_4t0a0     ! t0__2t0_a0
+LSYM(x142)     t0__9a0         ! t0__8t0       ! b_e_2t0       ! t0__t0ma0
+LSYM(x143)     t0__16a0        ! t0__9t0       ! b_e_t0        ! t0__t0ma0
+LSYM(x144)     t0__9a0         ! t0__8t0       ! b_e_shift     ! r__r_2t0
+LSYM(x145)     t0__9a0         ! t0__8t0       ! b_e_t0        ! t0__2t0_a0
+LSYM(x146)     t0__9a0         ! t0__8t0_a0    ! b_e_shift     ! r__r_2t0
+LSYM(x147)     t0__9a0         ! t0__8t0_a0    ! b_e_t0        ! t0__2t0_a0
+LSYM(x148)     t0__9a0         ! t0__4t0_a0    ! b_e_shift     ! r__r_4t0
+LSYM(x149)     t0__9a0         ! t0__4t0_a0    ! b_e_t0        ! t0__4t0_a0
+LSYM(x150)     t0__9a0         ! t0__4t0_a0    ! b_e_2t0       ! t0__2t0_a0
+LSYM(x151)     t0__9a0         ! t0__4t0_a0    ! b_e_2t0a0     ! t0__2t0_a0
+LSYM(x152)     t0__9a0         ! t0__2t0_a0    ! b_e_shift     ! r__r_8t0
+LSYM(x153)     t0__9a0         ! t0__2t0_a0    ! b_e_t0        ! t0__8t0_a0
+LSYM(x154)     t0__9a0         ! t0__2t0_a0    ! b_e_2t0       ! t0__4t0_a0
+LSYM(x155)     t0__32a0        ! t0__t0ma0     ! b_e_t0        ! t0__5t0
+LSYM(x156)     t0__9a0         ! t0__2t0_a0    ! b_e_4t0       ! t0__2t0_a0
+LSYM(x157)     t0__32a0        ! t0__t0ma0     ! b_e_t02a0     ! t0__5t0
+LSYM(x158)     t0__16a0        ! t0__5t0       ! b_e_2t0       ! t0__t0ma0
+LSYM(x159)     t0__32a0        ! t0__5t0       ! b_e_t0        ! t0__t0ma0
+LSYM(x160)     t0__5a0         ! t0__4t0       ! b_e_shift     ! r__r_8t0
+LSYM(x161)     t0__8a0         ! t0__5t0       ! b_e_t0        ! t0__4t0_a0
+LSYM(x162)     t0__9a0         ! t0__9t0       ! b_e_shift     ! r__r_2t0
+LSYM(x163)     t0__9a0         ! t0__9t0       ! b_e_t0        ! t0__2t0_a0
+LSYM(x164)     t0__5a0         ! t0__8t0_a0    ! b_e_shift     ! r__r_4t0
+LSYM(x165)     t0__8a0         ! t0__4t0_a0    ! b_e_t0        ! t0__5t0
+LSYM(x166)     t0__5a0         ! t0__8t0_a0    ! b_e_2t0       ! t0__2t0_a0
+LSYM(x167)     t0__5a0         ! t0__8t0_a0    ! b_e_2t0a0     ! t0__2t0_a0
+LSYM(x168)     t0__5a0         ! t0__4t0_a0    ! b_e_shift     ! r__r_8t0
+LSYM(x169)     t0__5a0         ! t0__4t0_a0    ! b_e_t0        ! t0__8t0_a0
+LSYM(x170)     t0__32a0        ! t0__t0_2a0    ! b_e_t0        ! t0__5t0
+LSYM(x171)     t0__9a0         ! t0__2t0_a0    ! b_e_t0        ! t0__9t0
+LSYM(x172)     t0__5a0         ! t0__4t0_a0    ! b_e_4t0       ! t0__2t0_a0
+LSYM(x173)     t0__9a0         ! t0__2t0_a0    ! b_e_t02a0     ! t0__9t0
+LSYM(x174)     t0__32a0        ! t0__t0_2a0    ! b_e_t04a0     ! t0__5t0
+LSYM(x175)     t0__8a0         ! t0__2t0_a0    ! b_e_5t0       ! t0__2t0_a0
+LSYM(x176)     t0__5a0         ! t0__4t0_a0    ! b_e_8t0       ! t0__t0_a0
+LSYM(x177)     t0__5a0         ! t0__4t0_a0    ! b_e_8t0a0     ! t0__t0_a0
+LSYM(x178)     t0__5a0         ! t0__2t0_a0    ! b_e_2t0       ! t0__8t0_a0
+LSYM(x179)     t0__5a0         ! t0__2t0_a0    ! b_e_2t0a0     ! t0__8t0_a0
+LSYM(x180)     t0__9a0         ! t0__5t0       ! b_e_shift     ! r__r_4t0
+LSYM(x181)     t0__9a0         ! t0__5t0       ! b_e_t0        ! t0__4t0_a0
+LSYM(x182)     t0__9a0         ! t0__5t0       ! b_e_2t0       ! t0__2t0_a0
+LSYM(x183)     t0__9a0         ! t0__5t0       ! b_e_2t0a0     ! t0__2t0_a0
+LSYM(x184)     t0__5a0         ! t0__9t0       ! b_e_4t0       ! t0__t0_a0
+LSYM(x185)     t0__9a0         ! t0__4t0_a0    ! b_e_t0        ! t0__5t0
+LSYM(x186)     t0__32a0        ! t0__t0ma0     ! b_e_2t0       ! t0__3t0
+LSYM(x187)     t0__9a0         ! t0__4t0_a0    ! b_e_t02a0     ! t0__5t0
+LSYM(x188)     t0__9a0         ! t0__5t0       ! b_e_4t0       ! t0__t0_2a0
+LSYM(x189)     t0__5a0         ! t0__4t0_a0    ! b_e_t0        ! t0__9t0
+LSYM(x190)     t0__9a0         ! t0__2t0_a0    ! b_e_2t0       ! t0__5t0
+LSYM(x191)     t0__64a0        ! t0__3t0       ! b_e_t0        ! t0__t0ma0
+LSYM(x192)     t0__8a0         ! t0__3t0       ! b_e_shift     ! r__r_8t0
+LSYM(x193)     t0__8a0         ! t0__3t0       ! b_e_t0        ! t0__8t0_a0
+LSYM(x194)     t0__8a0         ! t0__3t0       ! b_e_2t0       ! t0__4t0_a0
+LSYM(x195)     t0__8a0         ! t0__8t0_a0    ! b_e_t0        ! t0__3t0
+LSYM(x196)     t0__8a0         ! t0__3t0       ! b_e_4t0       ! t0__2t0_a0
+LSYM(x197)     t0__8a0         ! t0__3t0       ! b_e_4t0a0     ! t0__2t0_a0
+LSYM(x198)     t0__64a0        ! t0__t0_2a0    ! b_e_t0        ! t0__3t0
+LSYM(x199)     t0__8a0         ! t0__4t0_a0    ! b_e_2t0a0     ! t0__3t0
+LSYM(x200)     t0__5a0         ! t0__5t0       ! b_e_shift     ! r__r_8t0
+LSYM(x201)     t0__5a0         ! t0__5t0       ! b_e_t0        ! t0__8t0_a0
+LSYM(x202)     t0__5a0         ! t0__5t0       ! b_e_2t0       ! t0__4t0_a0
+LSYM(x203)     t0__5a0         ! t0__5t0       ! b_e_2t0a0     ! t0__4t0_a0
+LSYM(x204)     t0__8a0         ! t0__2t0_a0    ! b_e_4t0       ! t0__3t0
+LSYM(x205)     t0__5a0         ! t0__8t0_a0    ! b_e_t0        ! t0__5t0
+LSYM(x206)     t0__64a0        ! t0__t0_4a0    ! b_e_t02a0     ! t0__3t0
+LSYM(x207)     t0__8a0         ! t0__2t0_a0    ! b_e_3t0       ! t0__4t0_a0
+LSYM(x208)     t0__5a0         ! t0__5t0       ! b_e_8t0       ! t0__t0_a0
+LSYM(x209)     t0__5a0         ! t0__5t0       ! b_e_8t0a0     ! t0__t0_a0
+LSYM(x210)     t0__5a0         ! t0__4t0_a0    ! b_e_2t0       ! t0__5t0
+LSYM(x211)     t0__5a0         ! t0__4t0_a0    ! b_e_2t0a0     ! t0__5t0
+LSYM(x212)     t0__3a0         ! t0__4t0_a0    ! b_e_4t0       ! t0__4t0_a0
+LSYM(x213)     t0__3a0         ! t0__4t0_a0    ! b_e_4t0a0     ! t0__4t0_a0
+LSYM(x214)     t0__9a0         ! t0__t0_4a0    ! b_e_2t04a0    ! t0__8t0_a0
+LSYM(x215)     t0__5a0         ! t0__4t0_a0    ! b_e_5t0       ! t0__2t0_a0
+LSYM(x216)     t0__9a0         ! t0__3t0       ! b_e_shift     ! r__r_8t0
+LSYM(x217)     t0__9a0         ! t0__3t0       ! b_e_t0        ! t0__8t0_a0
+LSYM(x218)     t0__9a0         ! t0__3t0       ! b_e_2t0       ! t0__4t0_a0
+LSYM(x219)     t0__9a0         ! t0__8t0_a0    ! b_e_t0        ! t0__3t0
+LSYM(x220)     t0__3a0         ! t0__9t0       ! b_e_4t0       ! t0__2t0_a0
+LSYM(x221)     t0__3a0         ! t0__9t0       ! b_e_4t0a0     ! t0__2t0_a0
+LSYM(x222)     t0__9a0         ! t0__4t0_a0    ! b_e_2t0       ! t0__3t0
+LSYM(x223)     t0__9a0         ! t0__4t0_a0    ! b_e_2t0a0     ! t0__3t0
+LSYM(x224)     t0__9a0         ! t0__3t0       ! b_e_8t0       ! t0__t0_a0
+LSYM(x225)     t0__9a0         ! t0__5t0       ! b_e_t0        ! t0__5t0
+LSYM(x226)     t0__3a0         ! t0__2t0_a0    ! b_e_t02a0     ! t0__32t0
+LSYM(x227)     t0__9a0         ! t0__5t0       ! b_e_t02a0     ! t0__5t0
+LSYM(x228)     t0__9a0         ! t0__2t0_a0    ! b_e_4t0       ! t0__3t0
+LSYM(x229)     t0__9a0         ! t0__2t0_a0    ! b_e_4t0a0     ! t0__3t0
+LSYM(x230)     t0__9a0         ! t0__5t0       ! b_e_5t0       ! t0__t0_a0
+LSYM(x231)     t0__9a0         ! t0__2t0_a0    ! b_e_3t0       ! t0__4t0_a0
+LSYM(x232)     t0__3a0         ! t0__2t0_a0    ! b_e_8t0       ! t0__4t0_a0
+LSYM(x233)     t0__3a0         ! t0__2t0_a0    ! b_e_8t0a0     ! t0__4t0_a0
+LSYM(x234)     t0__3a0         ! t0__4t0_a0    ! b_e_2t0       ! t0__9t0
+LSYM(x235)     t0__3a0         ! t0__4t0_a0    ! b_e_2t0a0     ! t0__9t0
+LSYM(x236)     t0__9a0         ! t0__2t0_a0    ! b_e_4t08a0    ! t0__3t0
+LSYM(x237)     t0__16a0        ! t0__5t0       ! b_e_3t0       ! t0__t0ma0
+LSYM(x238)     t0__3a0         ! t0__4t0_a0    ! b_e_2t04a0    ! t0__9t0
+LSYM(x239)     t0__16a0        ! t0__5t0       ! b_e_t0ma0     ! t0__3t0
+LSYM(x240)     t0__9a0         ! t0__t0_a0     ! b_e_8t0       ! t0__3t0
+LSYM(x241)     t0__9a0         ! t0__t0_a0     ! b_e_8t0a0     ! t0__3t0
+LSYM(x242)     t0__5a0         ! t0__3t0       ! b_e_2t0       ! t0__8t0_a0
+LSYM(x243)     t0__9a0         ! t0__9t0       ! b_e_t0        ! t0__3t0
+LSYM(x244)     t0__5a0         ! t0__3t0       ! b_e_4t0       ! t0__4t0_a0
+LSYM(x245)     t0__8a0         ! t0__3t0       ! b_e_5t0       ! t0__2t0_a0
+LSYM(x246)     t0__5a0         ! t0__8t0_a0    ! b_e_2t0       ! t0__3t0
+LSYM(x247)     t0__5a0         ! t0__8t0_a0    ! b_e_2t0a0     ! t0__3t0
+LSYM(x248)     t0__32a0        ! t0__t0ma0     ! b_e_shift     ! r__r_8t0
+LSYM(x249)     t0__32a0        ! t0__t0ma0     ! b_e_t0        ! t0__8t0_a0
+LSYM(x250)     t0__5a0         ! t0__5t0       ! b_e_2t0       ! t0__5t0
+LSYM(x251)     t0__5a0         ! t0__5t0       ! b_e_2t0a0     ! t0__5t0
+LSYM(x252)     t0__64a0        ! t0__t0ma0     ! b_e_shift     ! r__r_4t0
+LSYM(x253)     t0__64a0        ! t0__t0ma0     ! b_e_t0        ! t0__4t0_a0
+LSYM(x254)     t0__128a0       ! t0__t0ma0     ! b_e_shift     ! r__r_2t0
+LSYM(x255)     t0__256a0       ! a1_ne_0_b_l0  ! t0__t0ma0     ! b_n_ret_t0
+/*1040 insts before this.  */
+LSYM(ret_t0)   MILLIRET
+LSYM(e_t0)     r__r_t0
+LSYM(e_shift)  a1_ne_0_b_l2
+       a0__256a0       /* a0 <<= 8 *********** */
+       MILLIRETN
+LSYM(e_t0ma0)  a1_ne_0_b_l0
+       t0__t0ma0
+       MILLIRET
+       r__r_t0
+LSYM(e_t0a0)   a1_ne_0_b_l0
+       t0__t0_a0
+       MILLIRET
+       r__r_t0
+LSYM(e_t02a0)  a1_ne_0_b_l0
+       t0__t0_2a0
+       MILLIRET
+       r__r_t0
+LSYM(e_t04a0)  a1_ne_0_b_l0
+       t0__t0_4a0
+       MILLIRET
+       r__r_t0
+LSYM(e_2t0)    a1_ne_0_b_l1
+       r__r_2t0
+       MILLIRETN
+LSYM(e_2t0a0)  a1_ne_0_b_l0
+       t0__2t0_a0
+       MILLIRET
+       r__r_t0
+LSYM(e2t04a0)  t0__t0_2a0
+       a1_ne_0_b_l1
+       r__r_2t0
+       MILLIRETN
+LSYM(e_3t0)    a1_ne_0_b_l0
+       t0__3t0
+       MILLIRET
+       r__r_t0
+LSYM(e_4t0)    a1_ne_0_b_l1
+       r__r_4t0
+       MILLIRETN
+LSYM(e_4t0a0)  a1_ne_0_b_l0
+       t0__4t0_a0
+       MILLIRET
+       r__r_t0
+LSYM(e4t08a0)  t0__t0_2a0
+       a1_ne_0_b_l1
+       r__r_4t0
+       MILLIRETN
+LSYM(e_5t0)    a1_ne_0_b_l0
+       t0__5t0
+       MILLIRET
+       r__r_t0
+LSYM(e_8t0)    a1_ne_0_b_l1
+       r__r_8t0
+       MILLIRETN
+LSYM(e_8t0a0)  a1_ne_0_b_l0
+       t0__8t0_a0
+       MILLIRET
+       r__r_t0
+
+       .procend
+       .end
+#endif
diff --git a/arch/parisc/lib/milli/remI.S b/arch/parisc/lib/milli/remI.S
new file mode 100644 (file)
index 0000000..63bc094
--- /dev/null
@@ -0,0 +1,185 @@
+/* 32 and 64-bit millicode, original author Hewlett-Packard
+   adapted for gcc by Paul Bame <bame@debian.org>
+   and Alan Modra <alan@linuxcare.com.au>.
+
+   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
+   This file is part of GCC and is released under the terms of
+   of the GNU General Public License as published by the Free Software
+   Foundation; either version 2, or (at your option) any later version.
+   See the file COPYING in the top-level GCC source directory for a copy
+   of the license.  */
+
+#include "milli.h"
+
+#ifdef L_remI
+/* ROUTINE:    $$remI
+
+   DESCRIPTION:
+   .   $$remI returns the remainder of the division of two signed 32-bit
+   .   integers.  The sign of the remainder is the same as the sign of
+   .   the dividend.
+
+
+   INPUT REGISTERS:
+   .   arg0 == dividend
+   .   arg1 == divisor
+   .   mrp  == return pc
+   .   sr0  == return space when called externally
+
+   OUTPUT REGISTERS:
+   .   arg0 = destroyed
+   .   arg1 = destroyed
+   .   ret1 = remainder
+
+   OTHER REGISTERS AFFECTED:
+   .   r1   = undefined
+
+   SIDE EFFECTS:
+   .   Causes a trap under the following conditions:  DIVIDE BY ZERO
+   .   Changes memory at the following places:  NONE
+
+   PERMISSIBLE CONTEXT:
+   .   Unwindable
+   .   Does not create a stack frame
+   .   Is usable for internal or external microcode
+
+   DISCUSSION:
+   .   Calls other millicode routines via mrp:  NONE
+   .   Calls other millicode routines:  NONE  */
+
+RDEFINE(tmp,r1)
+RDEFINE(retreg,ret1)
+
+       SUBSPA_MILLI
+       ATTR_MILLI
+       .proc
+       .callinfo millicode
+       .entry
+GSYM($$remI)
+GSYM($$remoI)
+       .export $$remI,MILLICODE
+       .export $$remoI,MILLICODE
+       ldo             -1(arg1),tmp            /*  is there at most one bit set ? */
+       and,<>          arg1,tmp,r0             /*  if not, don't use power of 2 */
+       addi,>          0,arg1,r0               /*  if denominator > 0, use power */
+                                               /*  of 2 */
+       b,n             LREF(neg_denom)
+LSYM(pow2)
+       comb,>,n        0,arg0,LREF(neg_num)    /*  is numerator < 0 ? */
+       and             arg0,tmp,retreg         /*  get the result */
+       MILLIRETN
+LSYM(neg_num)
+       subi            0,arg0,arg0             /*  negate numerator */
+       and             arg0,tmp,retreg         /*  get the result */
+       subi            0,retreg,retreg         /*  negate result */
+       MILLIRETN
+LSYM(neg_denom)
+       addi,<          0,arg1,r0               /*  if arg1 >= 0, it's not power */
+                                               /*  of 2 */
+       b,n             LREF(regular_seq)
+       sub             r0,arg1,tmp             /*  make denominator positive */
+       comb,=,n        arg1,tmp,LREF(regular_seq) /*  test against 0x80000000 and 0 */
+       ldo             -1(tmp),retreg          /*  is there at most one bit set ? */
+       and,=           tmp,retreg,r0           /*  if not, go to regular_seq */
+       b,n             LREF(regular_seq)
+       comb,>,n        0,arg0,LREF(neg_num_2)  /*  if arg0 < 0, negate it  */
+       and             arg0,retreg,retreg
+       MILLIRETN
+LSYM(neg_num_2)
+       subi            0,arg0,tmp              /*  test against 0x80000000 */
+       and             tmp,retreg,retreg
+       subi            0,retreg,retreg
+       MILLIRETN
+LSYM(regular_seq)
+       addit,=         0,arg1,0                /*  trap if div by zero */
+       add,>=          0,arg0,retreg           /*  move dividend, if retreg < 0, */
+       sub             0,retreg,retreg         /*    make it positive */
+       sub             0,arg1, tmp             /*  clear carry,  */
+                                               /*    negate the divisor */
+       ds              0, tmp,0                /*  set V-bit to the comple- */
+                                               /*    ment of the divisor sign */
+       or              0,0, tmp                /*  clear  tmp */
+       add             retreg,retreg,retreg    /*  shift msb bit into carry */
+       ds               tmp,arg1, tmp          /*  1st divide step, if no carry */
+                                               /*    out, msb of quotient = 0 */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+LSYM(t1)
+       ds               tmp,arg1, tmp          /*  2nd divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  3rd divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  4th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  5th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  6th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  7th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  8th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  9th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  10th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  11th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  12th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  13th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  14th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  15th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  16th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  17th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  18th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  19th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  20th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  21st divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  22nd divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  23rd divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  24th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  25th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  26th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  27th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  28th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  29th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  30th divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  31st divide step */
+       addc            retreg,retreg,retreg    /*  shift retreg with/into carry */
+       ds               tmp,arg1, tmp          /*  32nd divide step, */
+       addc            retreg,retreg,retreg    /*  shift last bit into retreg */
+       movb,>=,n        tmp,retreg,LREF(finish) /*  branch if pos.  tmp */
+       add,<           arg1,0,0                /*  if arg1 > 0, add arg1 */
+       add,tr           tmp,arg1,retreg        /*    for correcting remainder tmp */
+       sub              tmp,arg1,retreg        /*  else add absolute value arg1 */
+LSYM(finish)
+       add,>=          arg0,0,0                /*  set sign of remainder */
+       sub             0,retreg,retreg         /*    to sign of dividend */
+       MILLIRET
+       nop
+       .exit
+       .procend
+#ifdef milliext
+       .origin 0x00000200
+#endif
+       .end
+#endif
diff --git a/arch/parisc/lib/milli/remU.S b/arch/parisc/lib/milli/remU.S
new file mode 100644 (file)
index 0000000..c0a2d6e
--- /dev/null
@@ -0,0 +1,148 @@
+/* 32 and 64-bit millicode, original author Hewlett-Packard
+   adapted for gcc by Paul Bame <bame@debian.org>
+   and Alan Modra <alan@linuxcare.com.au>.
+
+   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
+   This file is part of GCC and is released under the terms of
+   of the GNU General Public License as published by the Free Software
+   Foundation; either version 2, or (at your option) any later version.
+   See the file COPYING in the top-level GCC source directory for a copy
+   of the license.  */
+
+#include "milli.h"
+
+#ifdef L_remU
+/* ROUTINE:    $$remU
+   .   Single precision divide for remainder with unsigned binary integers.
+   .
+   .   The remainder must be dividend-(dividend/divisor)*divisor.
+   .   Divide by zero is trapped.
+
+   INPUT REGISTERS:
+   .   arg0 == dividend
+   .   arg1 == divisor
+   .   mrp  == return pc
+   .   sr0  == return space when called externally
+
+   OUTPUT REGISTERS:
+   .   arg0 =  undefined
+   .   arg1 =  undefined
+   .   ret1 =  remainder
+
+   OTHER REGISTERS AFFECTED:
+   .   r1   =  undefined
+
+   SIDE EFFECTS:
+   .   Causes a trap under the following conditions:  DIVIDE BY ZERO
+   .   Changes memory at the following places:  NONE
+
+   PERMISSIBLE CONTEXT:
+   .   Unwindable.
+   .   Does not create a stack frame.
+   .   Suitable for internal or external millicode.
+   .   Assumes the special millicode register conventions.
+
+   DISCUSSION:
+   .   Calls other millicode routines using mrp: NONE
+   .   Calls other millicode routines: NONE  */
+
+
+RDEFINE(temp,r1)
+RDEFINE(rmndr,ret1)    /*  r29 */
+       SUBSPA_MILLI
+       ATTR_MILLI
+       .export $$remU,millicode
+       .proc
+       .callinfo       millicode
+       .entry
+GSYM($$remU)
+       ldo     -1(arg1),temp           /*  is there at most one bit set ? */
+       and,=   arg1,temp,r0            /*  if not, don't use power of 2 */
+       b       LREF(regular_seq)
+       addit,= 0,arg1,r0               /*  trap on div by zero */
+       and     arg0,temp,rmndr         /*  get the result for power of 2 */
+       MILLIRETN
+LSYM(regular_seq)
+       comib,>=,n  0,arg1,LREF(special_case)
+       subi    0,arg1,rmndr            /*  clear carry, negate the divisor */
+       ds      r0,rmndr,r0             /*  set V-bit to 1 */
+       add     arg0,arg0,temp          /*  shift msb bit into carry */
+       ds      r0,arg1,rmndr           /*  1st divide step, if no carry */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  2nd divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  3rd divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  4th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  5th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  6th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  7th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  8th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  9th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  10th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  11th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  12th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  13th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  14th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  15th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  16th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  17th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  18th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  19th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  20th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  21st divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  22nd divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  23rd divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  24th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  25th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  26th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  27th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  28th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  29th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  30th divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  31st divide step */
+       addc    temp,temp,temp          /*  shift temp with/into carry */
+       ds      rmndr,arg1,rmndr                /*  32nd divide step, */
+       comiclr,<= 0,rmndr,r0
+         add   rmndr,arg1,rmndr        /*  correction */
+       MILLIRETN
+       nop
+
+/* Putting >= on the last DS and deleting COMICLR does not work!  */
+LSYM(special_case)
+       sub,>>= arg0,arg1,rmndr
+         copy  arg0,rmndr
+       MILLIRETN
+       nop
+       .exit
+       .procend
+       .end
+#endif
index 1c091b415cd9b8375506c470527ae929b9900b9c..b2e3e9a8cecefce049d43ef1a5d36d61403cc9b9 100644 (file)
@@ -211,7 +211,7 @@ bad_area:
 #ifdef PRINT_USER_FAULTS
                printk(KERN_DEBUG "\n");
                printk(KERN_DEBUG "do_page_fault() pid=%d command='%s' type=%lu address=0x%08lx\n",
-                   tsk->pid, tsk->comm, code, address);
+                   task_pid_nr(tsk), tsk->comm, code, address);
                if (vma) {
                        printk(KERN_DEBUG "vm_start = 0x%08lx, vm_end = 0x%08lx\n",
                                        vma->vm_start, vma->vm_end);
index e724b362c49a526de3adb906cd4d079772f471f2..aa875fa43488b8a835e2b6d079871832bc0c308f 100644 (file)
@@ -607,7 +607,7 @@ void show_mem(void)
 
                                printk("Zone list for zone %d on node %d: ", j, i);
                                for (k = 0; zl->zones[k] != NULL; k++) 
-                                       printk("[%ld/%s] ", zone_to_nid(zl->zones[k]), zl->zones[k]->name);
+                                       printk("[%d/%s] ", zone_to_nid(zl->zones[k]), zl->zones[k]->name);
                                printk("\n");
                        }
                }
diff --git a/arch/parisc/oprofile/Kconfig b/arch/parisc/oprofile/Kconfig
deleted file mode 100644 (file)
index 5ade198..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-
-menu "Profiling support"
-       depends on EXPERIMENTAL
-
-config PROFILING
-       bool "Profiling support (EXPERIMENTAL)"
-       help
-         Say Y here to enable the extended profiling support mechanisms used
-         by profilers such as OProfile.
-         
-
-config OPROFILE
-       tristate "OProfile system profiling (EXPERIMENTAL)"
-       depends on PROFILING
-       help
-         OProfile is a profiling system capable of profiling the
-         whole system, include the kernel, kernel modules, libraries,
-         and applications.
-
-         If unsure, say N.
-
-endmenu
-
index 3763f681ce4cfa0cc2e09e9332e226414ec8a66a..18f397ca05efbc27966ee2bfebd50c68dffe0448 100644 (file)
@@ -669,20 +669,7 @@ source "arch/powerpc/sysdev/qe_lib/Kconfig"
 
 source "lib/Kconfig"
 
-menu "Instrumentation Support"
-
-source "arch/powerpc/oprofile/Kconfig"
-
-config KPROBES
-       bool "Kprobes"
-       depends on !BOOKE && !4xx && KALLSYMS && MODULES
-       help
-         Kprobes allows you to trap at almost any kernel address and
-         execute a callback function.  register_kprobe() establishes
-         a probepoint and specifies the callback.  Kprobes is useful
-         for kernel debugging, non-intrusive instrumentation and testing.
-         If in doubt, say "N".
-endmenu
+source "kernel/Kconfig.instrumentation"
 
 source "arch/powerpc/Kconfig.debug"
 
index c939fe86a9e007cee6474eeb9bdb8d01d9f18896..6a79fe43e229e9036a25b8792eb45246f44db30c 100644 (file)
@@ -216,7 +216,6 @@ config PPC_EARLY_DEBUG_BEAT
 config PPC_EARLY_DEBUG_44x
        bool "Early serial debugging for IBM/AMCC 44x CPUs"
        depends on 44x
-       select PPC_UDBG_16550
        help
          Select this to enable early debugging for IBM 44x chips via the
          inbuilt serial port.
index a88ae3d218a5a2a99b6c27b29ed36d318a2c3c10..cb2fb50a281c1ba704eceaceabe4198c2857b228 100644 (file)
                        interrupt-parent = <&MAL0>;
                        interrupts = <0 1 2 3 4>;
                        #interrupt-cells = <1>;
+                       #address-cells = <0>;
+                       #size-cells = <0>;
                        interrupt-map = </*TXEOB*/ 0 &UIC0 a 4
                                        /*RXEOB*/ 1 &UIC0 b 4
                                        /*SERR*/  2 &UIC1 0 4
                                        /*TXDE*/  3 &UIC1 1 4
-                                       /*RXDE*/  4 &UIC1 3 4>;
+                                       /*RXDE*/  4 &UIC1 2 4>;
                };
 
                POB0: opb {
                        };
 
                        EMAC0: ethernet@ef600e00 {
+                               linux,network-index = <0>;
                                device_type = "network";
                                compatible = "ibm,emac-440ep", "ibm,emac-440gp", "ibm,emac";
                                interrupt-parent = <&UIC1>;
                                rx-fifo-size = <1000>;
                                tx-fifo-size = <800>;
                                phy-mode = "rmii";
-                               phy-map = <00000001>;
+                               phy-map = <00000000>;
                                zmii-device = <&ZMII0>;
                                zmii-channel = <0>;
                        };
 
                        EMAC1: ethernet@ef600f00 {
+                               linux,network-index = <1>;
                                device_type = "network";
                                compatible = "ibm,emac-440ep", "ibm,emac-440gp", "ibm,emac";
                                interrupt-parent = <&UIC1>;
                                rx-fifo-size = <1000>;
                                tx-fifo-size = <800>;
                                phy-mode = "rmii";
-                               phy-map = <00000001>;
+                               phy-map = <00000000>;
                                zmii-device = <&ZMII0>;
                                zmii-channel = <1>;
                        };
index bc45f5fbb0609f924fbb9a92c9211b1cdc0c47e0..6731763f028248d2569987d7f4f0c3585d5ae2c9 100644 (file)
                };
 
                gpt@600 {       // General Purpose Timer
-                       compatible = "mpc5200-gpt";
-                       device_type = "gpt";
+                       compatible = "fsl,mpc5200-gpt";
                        cell-index = <0>;
                        reg = <600 10>;
                        interrupts = <1 9 0>;
                        interrupt-parent = <&mpc5200_pic>;
-                       has-wdt;
+                       fsl,has-wdt;
                };
 
                gpt@610 {       // General Purpose Timer
-                       compatible = "mpc5200-gpt";
-                       device_type = "gpt";
+                       compatible = "fsl,mpc5200-gpt";
                        cell-index = <1>;
                        reg = <610 10>;
                        interrupts = <1 a 0>;
@@ -89,8 +87,7 @@
                };
 
                gpt@620 {       // General Purpose Timer
-                       compatible = "mpc5200-gpt";
-                       device_type = "gpt";
+                       compatible = "fsl,mpc5200-gpt";
                        cell-index = <2>;
                        reg = <620 10>;
                        interrupts = <1 b 0>;
@@ -98,8 +95,7 @@
                };
 
                gpt@630 {       // General Purpose Timer
-                       compatible = "mpc5200-gpt";
-                       device_type = "gpt";
+                       compatible = "fsl,mpc5200-gpt";
                        cell-index = <3>;
                        reg = <630 10>;
                        interrupts = <1 c 0>;
                };
 
                gpt@640 {       // General Purpose Timer
-                       compatible = "mpc5200-gpt";
-                       device_type = "gpt";
+                       compatible = "fsl,mpc5200-gpt";
                        cell-index = <4>;
                        reg = <640 10>;
                        interrupts = <1 d 0>;
                };
 
                gpt@650 {       // General Purpose Timer
-                       compatible = "mpc5200-gpt";
-                       device_type = "gpt";
+                       compatible = "fsl,mpc5200-gpt";
                        cell-index = <5>;
                        reg = <650 10>;
                        interrupts = <1 e 0>;
                };
 
                gpt@660 {       // General Purpose Timer
-                       compatible = "mpc5200-gpt";
-                       device_type = "gpt";
+                       compatible = "fsl,mpc5200-gpt";
                        cell-index = <6>;
                        reg = <660 10>;
                        interrupts = <1 f 0>;
                };
 
                gpt@670 {       // General Purpose Timer
-                       compatible = "mpc5200-gpt";
-                       device_type = "gpt";
+                       compatible = "fsl,mpc5200-gpt";
                        cell-index = <7>;
                        reg = <670 10>;
                        interrupts = <1 10 0>;
index 6582c9a39b27aacee6f539619fab4ddf25248a6e..b540388c608c4ec9addf0a3d66c9664f6d2d5ac6 100644 (file)
                };
 
                gpt@600 {       // General Purpose Timer
-                       compatible = "mpc5200b-gpt","mpc5200-gpt";
-                       device_type = "gpt";
+                       compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
                        cell-index = <0>;
                        reg = <600 10>;
                        interrupts = <1 9 0>;
                        interrupt-parent = <&mpc5200_pic>;
-                       has-wdt;
+                       fsl,has-wdt;
                };
 
                gpt@610 {       // General Purpose Timer
-                       compatible = "mpc5200b-gpt","mpc5200-gpt";
-                       device_type = "gpt";
+                       compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
                        cell-index = <1>;
                        reg = <610 10>;
                        interrupts = <1 a 0>;
@@ -89,8 +87,7 @@
                };
 
                gpt@620 {       // General Purpose Timer
-                       compatible = "mpc5200b-gpt","mpc5200-gpt";
-                       device_type = "gpt";
+                       compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
                        cell-index = <2>;
                        reg = <620 10>;
                        interrupts = <1 b 0>;
@@ -98,8 +95,7 @@
                };
 
                gpt@630 {       // General Purpose Timer
-                       compatible = "mpc5200b-gpt","mpc5200-gpt";
-                       device_type = "gpt";
+                       compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
                        cell-index = <3>;
                        reg = <630 10>;
                        interrupts = <1 c 0>;
                };
 
                gpt@640 {       // General Purpose Timer
-                       compatible = "mpc5200b-gpt","mpc5200-gpt";
-                       device_type = "gpt";
+                       compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
                        cell-index = <4>;
                        reg = <640 10>;
                        interrupts = <1 d 0>;
                };
 
                gpt@650 {       // General Purpose Timer
-                       compatible = "mpc5200b-gpt","mpc5200-gpt";
-                       device_type = "gpt";
+                       compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
                        cell-index = <5>;
                        reg = <650 10>;
                        interrupts = <1 e 0>;
                };
 
                gpt@660 {       // General Purpose Timer
-                       compatible = "mpc5200b-gpt","mpc5200-gpt";
-                       device_type = "gpt";
+                       compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
                        cell-index = <6>;
                        reg = <660 10>;
                        interrupts = <1 f 0>;
                };
 
                gpt@670 {       // General Purpose Timer
-                       compatible = "mpc5200b-gpt","mpc5200-gpt";
-                       device_type = "gpt";
+                       compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
                        cell-index = <7>;
                        reg = <670 10>;
                        interrupts = <1 10 0>;
index 36be75b04de1dbf33a3845de199afa8a79eb9fc3..8833dfe2e8b47f97bfc4ee51a0dd8e0e3266ed4c 100644 (file)
                                reg = <ef600d00 c>;
                        };
 
+                       RGMII0: emac-rgmii@ef601000 {
+                               device_type = "rgmii-interface";
+                               compatible = "ibm,rgmii-440epx", "ibm,rgmii";
+                               reg = <ef601000 8>;
+                       };
+
                        EMAC0: ethernet@ef600e00 {
                                linux,network-index = <0>;
                                device_type = "network";
                                max-frame-size = <5dc>;
                                rx-fifo-size = <1000>;
                                tx-fifo-size = <800>;
-                               phy-mode = "rmii";
+                               phy-mode = "rgmii";
                                phy-map = <00000000>;
                                zmii-device = <&ZMII0>;
                                zmii-channel = <0>;
+                               rgmii-device = <&RGMII0>;
+                               rgmii-channel = <0>;
                        };
 
                        EMAC1: ethernet@ef600f00 {
                                max-frame-size = <5dc>;
                                rx-fifo-size = <1000>;
                                tx-fifo-size = <800>;
-                               phy-mode = "rmii";
+                               phy-mode = "rgmii";
                                phy-map = <00000000>;
                                zmii-device = <&ZMII0>;
                                zmii-channel = <1>;
+                               rgmii-device = <&RGMII0>;
+                               rgmii-channel = <1>;
                        };
                };
        };
index ec54f4e04ad6da2321e4b864f3c2e7d3a9356de9..fa681f5343fec196dd5a51cd029bd34097427aef 100644 (file)
                MAL: mcmal {
                        compatible = "ibm,mcmal-405gp", "ibm,mcmal";
                        dcr-reg = <180 62>;
-                       num-tx-chans = <2>;
+                       num-tx-chans = <1>;
                        num-rx-chans = <1>;
                        interrupt-parent = <&UIC0>;
-                       interrupts = <a 4 b 4 c 4 d 4 e 4>;
+                       interrupts = <
+                               b 4 /* TXEOB */
+                               c 4 /* RXEOB */
+                               a 4 /* SERR */
+                               d 4 /* TXDE */
+                               e 4 /* RXDE */>;
                };
 
                POB0: opb {
                                compatible = "ibm,emac-405gp", "ibm,emac";
                                interrupt-parent = <&UIC0>;
                                interrupts = <9 4 f 4>;
+                               local-mac-address = [000000000000]; /* Filled in by zImage */
                                reg = <ef600800 70>;
                                mal-device = <&MAL>;
-                               mal-tx-channel = <0 1>;
+                               mal-tx-channel = <0>;
                                mal-rx-channel = <0>;
                                cell-index = <0>;
                                max-frame-size = <5dc>;
index 3adf2d08a2304da8520793d0d65b5ab40edc0f43..bb2c309d70fcdafaf7b32c1495afe67daf6c7ea7 100644 (file)
@@ -57,8 +57,8 @@ void ibm405gp_fixup_clocks(unsigned int sysclk, unsigned int ser_clk)
        }
 
        /* setup the timebase clock to tick at the cpu frequency */
-       cpc0_cr1 = cpc0_cr1 & ~ 0x00800000;
-       mtdcr(DCRN_CPC0_CR1, cpc0_cr1);
+       cpc0_cr1 = cpc0_cr1 & ~0x00800000;
+       mtdcr(DCRN_405_CPC0_CR1, cpc0_cr1);
        tb = cpu;
 
        dt_fixup_cpu_clocks(cpu, tb, 0);
@@ -109,6 +109,7 @@ static void walnut_flashsel_fixup(void)
        setprop(sram, "reg", reg_sram, sizeof(reg_sram));
 }
 
+#define WALNUT_OPENBIOS_MAC_OFF 0xfffffe0b
 static void walnut_fixups(void)
 {
        ibm4xx_fixup_memsize();
@@ -116,6 +117,7 @@ static void walnut_fixups(void)
        ibm4xx_quiesce_eth((u32 *)0xef600800, NULL);
        ibm4xx_fixup_ebc_ranges("/plb/ebc");
        walnut_flashsel_fixup();
+       dt_fixup_mac_addresses((u8 *) WALNUT_OPENBIOS_MAC_OFF);
 }
 
 void platform_init(void)
index d22fed6d2cd9c1f894335adae9c5216c44122be1..844808ebf2454a37160d2f2f4d0c2ae99647b53f 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.23-rc1
-# Fri Aug  3 10:46:53 2007
+# Linux kernel version: 2.6.23
+# Fri Oct 19 09:01:11 2007
 #
 # CONFIG_PPC64 is not set
 
@@ -22,8 +22,13 @@ CONFIG_PHYS_64BIT=y
 # CONFIG_PPC_MM_SLICES is not set
 CONFIG_NOT_COHERENT_CACHE=y
 CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
 CONFIG_PPC_MERGE=y
 CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_IRQ_PER_CPU=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
@@ -67,6 +72,8 @@ CONFIG_POSIX_MQUEUE=y
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -87,7 +94,6 @@ 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
@@ -133,6 +139,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_PQ2ADS is not set
 CONFIG_BAMBOO=y
 # CONFIG_EBONY is not set
+# CONFIG_SEQUOIA is not set
 CONFIG_440EP=y
 CONFIG_IBM440EP_ERR42=y
 # CONFIG_MPIC is not set
@@ -146,11 +153,16 @@ CONFIG_IBM440EP_ERR42=y
 # CONFIG_GENERIC_IOMAP is not set
 # CONFIG_CPU_FREQ is not set
 # CONFIG_CPM2 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
@@ -172,6 +184,7 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_RESOURCES_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
@@ -197,10 +210,6 @@ CONFIG_PCI_SYSCALL=y
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
 # CONFIG_PCI_DEBUG is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 
@@ -215,7 +224,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y
 CONFIG_HIGHMEM_START=0xfe000000
 CONFIG_LOWMEM_SIZE=0x30000000
 CONFIG_KERNEL_START=0xc0000000
-CONFIG_TASK_SIZE=0x80000000
+CONFIG_TASK_SIZE=0xc0000000
 CONFIG_CONSISTENT_START=0xff100000
 CONFIG_CONSISTENT_SIZE=0x00200000
 CONFIG_BOOT_LOAD=0x01000000
@@ -252,6 +261,7 @@ CONFIG_IP_PNP_BOOTP=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=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -309,6 +319,7 @@ 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=y
@@ -353,10 +364,6 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_SCSI_NETLINK is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
 # CONFIG_FUSION is not set
 
 #
@@ -375,12 +382,36 @@ CONFIG_NETDEVICES=y
 # 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_NET_ETHERNET is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_IBM_NEW_EMAC=y
+CONFIG_IBM_NEW_EMAC_RXB=128
+CONFIG_IBM_NEW_EMAC_TXB=64
+CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32
+CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256
+CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0
+# CONFIG_IBM_NEW_EMAC_DEBUG is not set
+CONFIG_IBM_NEW_EMAC_ZMII=y
+# CONFIG_IBM_NEW_EMAC_RGMII 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_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -388,6 +419,7 @@ 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
@@ -396,11 +428,14 @@ CONFIG_NETDEV_1000=y
 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_TR is not set
 
 #
@@ -463,14 +498,11 @@ 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_NVRAM is not set
 # CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
 CONFIG_DEVPORT=y
@@ -484,6 +516,13 @@ CONFIG_DEVPORT=y
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
@@ -500,16 +539,17 @@ CONFIG_DAB=y
 #
 # 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
-# CONFIG_VGASTATE is not set
-CONFIG_VIDEO_OUTPUT_CONTROL=m
-# CONFIG_FB is not set
-# CONFIG_FB_IBM_GXT4500 is not set
 
 #
 # Sound
@@ -535,19 +575,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_EDAC is not set
 # CONFIG_RTC_CLASS is not set
 
-#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
 #
 # Userspace I/O
 #
@@ -600,7 +627,6 @@ CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -619,10 +645,7 @@ CONFIG_CRAMFS=y
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
@@ -648,15 +671,7 @@ CONFIG_SUNRPC=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
 # CONFIG_UCC_SLOW is not set
 
@@ -709,6 +724,7 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_LIST is not set
 CONFIG_FORCED_INLINING=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_DEBUG_STACKOVERFLOW is not set
@@ -728,6 +744,7 @@ CONFIG_PPC_EARLY_DEBUG=y
 # CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set
 # CONFIG_PPC_EARLY_DEBUG_BEAT is not set
 CONFIG_PPC_EARLY_DEBUG_44x=y
+# CONFIG_PPC_EARLY_DEBUG_CPM is not set
 CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW=0xef600300
 CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH=0x0
 
@@ -736,6 +753,7 @@ CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH=0x0
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_BLKCIPHER=y
@@ -755,6 +773,7 @@ CONFIG_CRYPTO_ECB=y
 CONFIG_CRYPTO_CBC=y
 CONFIG_CRYPTO_PCBC=y
 # CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_FCRYPT is not set
@@ -768,9 +787,12 @@ CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_ARC4 is not set
 # CONFIG_CRYPTO_KHAZAD is not set
 # CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 # CONFIG_CRYPTO_CRC32C is not set
 # CONFIG_CRYPTO_CAMELLIA is not set
 # CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_AUTHENC is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_PPC_CLOCK is not set
index 8b47c846421cba2cb064bbeff8233a31b485984b..dcd7c02727c2e713c1dac991faf7b94602322b8a 100644 (file)
@@ -68,6 +68,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=15
+CONFIG_CGROUPS=y
 CONFIG_CPUSETS=y
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
index 35a95dda681eb6e872be6b8de71577b1390d74e2..d3ef642811ef2604cb9d472f114f6d1371a244bd 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.23-rc4
-# Thu Aug 30 16:34:11 2007
+# Linux kernel version: 2.6.23
+# Thu Oct 18 08:01:57 2007
 #
 # CONFIG_PPC64 is not set
 
@@ -21,8 +21,13 @@ CONFIG_PHYS_64BIT=y
 # CONFIG_PPC_MM_SLICES is not set
 CONFIG_NOT_COHERENT_CACHE=y
 CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
 CONFIG_PPC_MERGE=y
 CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_IRQ_PER_CPU=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
@@ -66,6 +71,8 @@ CONFIG_POSIX_MQUEUE=y
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -86,7 +93,6 @@ 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
@@ -130,7 +136,9 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
+# CONFIG_BAMBOO is not set
 CONFIG_EBONY=y
+# CONFIG_SEQUOIA is not set
 CONFIG_440GP=y
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
@@ -149,6 +157,10 @@ CONFIG_440GP=y
 # Kernel options
 #
 # CONFIG_HIGHMEM is not set
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 # CONFIG_HZ_100 is not set
 CONFIG_HZ_250=y
 # CONFIG_HZ_300 is not set
@@ -170,6 +182,7 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_RESOURCES_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
@@ -194,10 +207,6 @@ CONFIG_PCI_SYSCALL=y
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
 # CONFIG_PCI_DEBUG is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 
@@ -212,7 +221,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y
 CONFIG_HIGHMEM_START=0xfe000000
 CONFIG_LOWMEM_SIZE=0x30000000
 CONFIG_KERNEL_START=0xc0000000
-CONFIG_TASK_SIZE=0x80000000
+CONFIG_TASK_SIZE=0xc0000000
 CONFIG_CONSISTENT_START=0xff100000
 CONFIG_CONSISTENT_SIZE=0x00200000
 CONFIG_BOOT_LOAD=0x01000000
@@ -249,6 +258,7 @@ CONFIG_IP_PNP_BOOTP=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=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -306,6 +316,7 @@ 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=y
@@ -332,6 +343,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
@@ -364,6 +376,7 @@ CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 # CONFIG_MTD_PHYSMAP is not set
 CONFIG_MTD_PHYSMAP_OF=y
+# CONFIG_MTD_INTEL_VR_NOR is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -423,10 +436,6 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_SCSI_NETLINK is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
 # CONFIG_FUSION is not set
 
 #
@@ -443,12 +452,36 @@ CONFIG_NETDEVICES=y
 # 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_NET_ETHERNET is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_IBM_NEW_EMAC=y
+CONFIG_IBM_NEW_EMAC_RXB=128
+CONFIG_IBM_NEW_EMAC_TXB=64
+CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32
+CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256
+CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0
+# CONFIG_IBM_NEW_EMAC_DEBUG is not set
+CONFIG_IBM_NEW_EMAC_ZMII=y
+# CONFIG_IBM_NEW_EMAC_RGMII 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_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -456,6 +489,7 @@ 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
@@ -464,11 +498,14 @@ CONFIG_NETDEV_1000=y
 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_TR is not set
 
 #
@@ -537,8 +574,6 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
 CONFIG_DEVPORT=y
@@ -553,6 +588,12 @@ CONFIG_DEVPORT=y
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
 #
 # Multifunction device drivers
 #
@@ -568,16 +609,17 @@ CONFIG_DEVPORT=y
 #
 # 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_VGASTATE is not set
-# CONFIG_VIDEO_OUTPUT_CONTROL is not set
-# CONFIG_FB is not set
-# CONFIG_FB_IBM_GXT4500 is not set
 
 #
 # Sound
@@ -603,19 +645,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_EDAC is not set
 # CONFIG_RTC_CLASS is not set
 
-#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
 #
 # Userspace I/O
 #
@@ -668,7 +697,6 @@ CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -684,10 +712,12 @@ 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=y
@@ -696,10 +726,7 @@ CONFIG_CRAMFS=y
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
@@ -725,15 +752,7 @@ CONFIG_SUNRPC=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
 # CONFIG_UCC_SLOW is not set
 
@@ -787,6 +806,7 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_LIST is not set
 CONFIG_FORCED_INLINING=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_DEBUG_STACKOVERFLOW is not set
@@ -801,6 +821,7 @@ CONFIG_FORCED_INLINING=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_BLKCIPHER=y
@@ -820,6 +841,7 @@ CONFIG_CRYPTO_ECB=y
 CONFIG_CRYPTO_CBC=y
 CONFIG_CRYPTO_PCBC=y
 # CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_FCRYPT is not set
@@ -833,9 +855,12 @@ CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_ARC4 is not set
 # CONFIG_CRYPTO_KHAZAD is not set
 # CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 # CONFIG_CRYPTO_CRC32C is not set
 # CONFIG_CRYPTO_CAMELLIA is not set
 # CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_HW is not set
+# CONFIG_PPC_CLOCK is not set
index 95b823b60c97ec9cd038f4bb45ffea8afdd6ec7a..8e5988c4a1646042d8516303828524b8b3ad45dc 100644 (file)
@@ -209,7 +209,6 @@ CONFIG_PM=y
 # CONFIG_PM_LEGACY is not set
 CONFIG_PM_DEBUG=y
 # CONFIG_PM_VERBOSE is not set
-# CONFIG_DISABLE_CONSOLE_SUSPEND is not set
 CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_HIBERNATION=y
index bb8d4e46f0c509e6283ea4f09da521e4a8006c33..05582af50c5beb8c45494b18c916b5848ac88678 100644 (file)
@@ -71,6 +71,7 @@ CONFIG_TASK_DELAY_ACCT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=17
+CONFIG_CGROUPS=y
 CONFIG_CPUSETS=y
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
index c09eb8cfbe711471786509c91b2b026811add369..62a38406b62f8a6336e053f27df9c8d90e215a0c 100644 (file)
@@ -71,6 +71,7 @@ CONFIG_AUDITSYSCALL=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=17
+CONFIG_CGROUPS=y
 CONFIG_CPUSETS=y
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
index 7724292cc06d3d9b85bfefec696788e144c406cf..02896ecba490d684f75098573da216033a785658 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.23-rc4
-# Wed Sep  5 12:06:37 2007
+# Linux kernel version: 2.6.23
+# Thu Oct 18 12:54:18 2007
 #
 # CONFIG_PPC64 is not set
 
@@ -18,8 +18,13 @@ 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_IRQ_PER_CPU=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
@@ -63,6 +68,8 @@ CONFIG_POSIX_MQUEUE=y
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -83,7 +90,6 @@ 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
@@ -127,7 +133,9 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
+# CONFIG_KILAUEA is not set
 CONFIG_WALNUT=y
+# CONFIG_XILINX_VIRTEX_GENERIC_BOARD is not set
 CONFIG_405GP=y
 CONFIG_IBM405_ERR77=y
 CONFIG_IBM405_ERR51=y
@@ -148,6 +156,10 @@ CONFIG_IBM405_ERR51=y
 # Kernel options
 #
 # CONFIG_HIGHMEM is not set
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 # CONFIG_HZ_100 is not set
 CONFIG_HZ_250=y
 # CONFIG_HZ_300 is not set
@@ -169,6 +181,7 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_RESOURCES_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
@@ -177,6 +190,8 @@ CONFIG_VIRT_TO_BUS=y
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
 # CONFIG_PM is not set
+CONFIG_SUSPEND_UP_POSSIBLE=y
+CONFIG_HIBERNATION_UP_POSSIBLE=y
 CONFIG_SECCOMP=y
 CONFIG_WANT_DEVICE_TREE=y
 CONFIG_DEVICE_TREE="walnut.dts"
@@ -190,10 +205,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_PCI_DOMAINS is not set
 # CONFIG_PCI_SYSCALL is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
 # CONFIG_PCCARD is not set
 
 #
@@ -207,7 +218,7 @@ CONFIG_ZONE_DMA=y
 CONFIG_HIGHMEM_START=0xfe000000
 CONFIG_LOWMEM_SIZE=0x30000000
 CONFIG_KERNEL_START=0xc0000000
-CONFIG_TASK_SIZE=0x80000000
+CONFIG_TASK_SIZE=0xc0000000
 CONFIG_CONSISTENT_START=0xff100000
 CONFIG_CONSISTENT_SIZE=0x00200000
 CONFIG_BOOT_LOAD=0x00400000
@@ -244,6 +255,7 @@ CONFIG_IP_PNP_BOOTP=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=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -301,6 +313,7 @@ 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=y
@@ -328,6 +341,7 @@ CONFIG_MTD_BLOCK=m
 # 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
@@ -360,7 +374,6 @@ CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 # CONFIG_MTD_PHYSMAP is not set
 CONFIG_MTD_PHYSMAP_OF=y
-# CONFIG_MTD_WALNUT is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -419,7 +432,22 @@ CONFIG_NETDEVICES=y
 # CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-# CONFIG_NET_ETHERNET is not set
+# CONFIG_VETH is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+CONFIG_IBM_NEW_EMAC=y
+CONFIG_IBM_NEW_EMAC_RXB=128
+CONFIG_IBM_NEW_EMAC_TXB=64
+CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32
+CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256
+CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0
+# CONFIG_IBM_NEW_EMAC_DEBUG is not set
+CONFIG_IBM_NEW_EMAC_ZMII=y
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
 CONFIG_NETDEV_1000=y
 CONFIG_NETDEV_10000=y
 
@@ -497,6 +525,12 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
 #
 # Multifunction device drivers
 #
@@ -512,16 +546,15 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # Graphics support
 #
+# 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
-# CONFIG_VGASTATE is not set
-CONFIG_VIDEO_OUTPUT_CONTROL=m
-# CONFIG_FB is not set
-# CONFIG_FB_IBM_GXT4500 is not set
 
 #
 # Sound
@@ -545,19 +578,6 @@ CONFIG_USB_SUPPORT=y
 # CONFIG_EDAC is not set
 # CONFIG_RTC_CLASS is not set
 
-#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
 #
 # Userspace I/O
 #
@@ -610,7 +630,6 @@ CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -630,10 +649,7 @@ CONFIG_CRAMFS=y
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
@@ -659,15 +675,7 @@ CONFIG_SUNRPC=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
 # CONFIG_UCC_SLOW is not set
 
@@ -720,6 +728,7 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_LIST is not set
 CONFIG_FORCED_INLINING=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_DEBUG_STACKOVERFLOW is not set
@@ -734,6 +743,7 @@ CONFIG_FORCED_INLINING=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_BLKCIPHER=y
@@ -753,6 +763,7 @@ CONFIG_CRYPTO_ECB=y
 CONFIG_CRYPTO_CBC=y
 CONFIG_CRYPTO_PCBC=y
 # CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_FCRYPT is not set
@@ -766,9 +777,12 @@ CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_ARC4 is not set
 # CONFIG_CRYPTO_KHAZAD is not set
 # CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 # CONFIG_CRYPTO_CRC32C is not set
 # CONFIG_CRYPTO_CAMELLIA is not set
 # CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_AUTHENC is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_PPC_CLOCK is not set
index 0ae5d57b93681fdea060bce6c6a78dc8bcd61569..2c8e756d19a39846db6f9c986dcce7ebbd099c39 100644 (file)
@@ -141,6 +141,7 @@ int main(void)
        DEFINE(PACALPPACAPTR, offsetof(struct paca_struct, lppaca_ptr));
        DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
        DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr));
+       DEFINE(PACA_STARTSPURR, offsetof(struct paca_struct, startspurr));
        DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time));
        DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
        DEFINE(PACA_SLBSHADOWPTR, offsetof(struct paca_struct, slb_shadow_ptr));
index 8b4a4ee85eca24b8b229bf1c46b42c26bba82e6d..f1ee0b3f78f26fc1e0364244b2819486e637191f 100644 (file)
@@ -113,7 +113,7 @@ setup_604_hid0:
  * around #3 and with the same fix we use. We may want to
  * check if the CPU is using 60x bus mode in which case
  * the workaround for errata #4 is useless. Also, we may
- * want to explicitely clear HID0_NOPDST as this is not
+ * want to explicitly clear HID0_NOPDST as this is not
  * needed once we have applied workaround #5 (though it's
  * not set by Apple's firmware at least).
  */
index 9001104b56b0ba983e777b66f21b83cdbdb2eeb7..14206e3f0819a963d65fc5e6d3f26846b154f336 100644 (file)
@@ -161,8 +161,7 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
        int i;
 
        for_each_sg(sgl, sg, nents, i) {
-               sg->dma_address = (page_to_phys(sg->page) + sg->offset) |
-                       dma_direct_offset;
+               sg->dma_address = sg_phys(sg) | dma_direct_offset;
                sg->dma_length = sg->length;
        }
 
index 289d7e93591857bdbe3230a95fb08568b57df491..72fd87156b24b662ee8abb08878197c3a6b6a02b 100644 (file)
@@ -102,8 +102,7 @@ static int ibmebus_map_sg(struct device *dev,
        int i;
 
        for_each_sg(sgl, sg, nents, i) {
-               sg->dma_address = (dma_addr_t)page_address(sg->page)
-                       + sg->offset;
+               sg->dma_address = (dma_addr_t) sg_virt(sg);
                sg->dma_length = sg->length;
        }
 
index 306a6f75b6c5a8004bf5f496cbe1d6b86ed8b589..2d0c9ef555e9e4578d9df93ff91e025697069c4e 100644 (file)
@@ -307,7 +307,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
                        continue;
                }
                /* Allocate iommu entries for that segment */
-               vaddr = (unsigned long)page_address(s->page) + s->offset;
+               vaddr = (unsigned long) sg_virt(s);
                npages = iommu_num_pages(vaddr, slen);
                entry = iommu_range_alloc(tbl, npages, &handle, mask >> IOMMU_PAGE_SHIFT, 0);
 
index 2250f9e6c5ca0ceb517a571bebc8967a9b1dcd4f..b0e5deb4274f89a62ee4ce4991468aec726ffed3 100644 (file)
@@ -491,7 +491,7 @@ struct irq_host *irq_alloc_host(struct device_node *of_node,
 
                        /* Legacy flags are left to default at this point,
                         * one can then use irq_create_mapping() to
-                        * explicitely change them
+                        * explicitly change them
                         */
                        ops->map(host, i, i);
                }
index 858f28ac8a06e4cee41e3b4696144dccb1724bc6..2a2f3c3f6d80321e3076cea3db5ae237a9fcbe6d 100644 (file)
@@ -1,6 +1,6 @@
 /*
        L2CR functions
-       Copyright © 1997-1998 by PowerLogix R & D, Inc.
+       Copyright Â© 1997-1998 by PowerLogix R & D, Inc.
 
        This program is free software; you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
index e60a0c544d6347684dda853203a30a9c362d3d8b..c0c8e8c3ced90a62b8c5996dcd75bb1a6bae0001 100644 (file)
@@ -61,45 +61,39 @@ NORET_TYPE void machine_kexec(struct kimage *image)
        for(;;);
 }
 
-static int __init early_parse_crashk(char *p)
-{
-       unsigned long size;
-
-       if (!p)
-               return 1;
-
-       size = memparse(p, &p);
-
-       if (*p == '@')
-               crashk_res.start = memparse(p + 1, &p);
-       else
-               crashk_res.start = KDUMP_KERNELBASE;
-
-       crashk_res.end = crashk_res.start + size - 1;
-
-       return 0;
-}
-early_param("crashkernel", early_parse_crashk);
-
 void __init reserve_crashkernel(void)
 {
-       unsigned long size;
+       unsigned long long crash_size, crash_base;
+       int ret;
+
+       /* this is necessary because of lmb_phys_mem_size() */
+       lmb_analyze();
+
+       /* use common parsing */
+       ret = parse_crashkernel(boot_command_line, lmb_phys_mem_size(),
+                       &crash_size, &crash_base);
+       if (ret == 0 && crash_size > 0) {
+               if (crash_base == 0)
+                       crash_base = KDUMP_KERNELBASE;
+               crashk_res.start = crash_base;
+       } else {
+               /* handle the device tree */
+               crash_size = crashk_res.end - crashk_res.start + 1;
+       }
 
-       if (crashk_res.start == 0)
+       if (crash_size == 0)
                return;
 
        /* We might have got these values via the command line or the
         * device tree, either way sanitise them now. */
 
-       size = crashk_res.end - crashk_res.start + 1;
-
        if (crashk_res.start != KDUMP_KERNELBASE)
                printk("Crash kernel location must be 0x%x\n",
                                KDUMP_KERNELBASE);
 
        crashk_res.start = KDUMP_KERNELBASE;
-       size = PAGE_ALIGN(size);
-       crashk_res.end = crashk_res.start + size - 1;
+       crash_size = PAGE_ALIGN(crash_size);
+       crashk_res.end = crashk_res.start + crash_size - 1;
 
        /* Crash kernel trumps memory limit */
        if (memory_limit && memory_limit <= crashk_res.end) {
@@ -108,7 +102,13 @@ void __init reserve_crashkernel(void)
                                memory_limit);
        }
 
-       lmb_reserve(crashk_res.start, size);
+       printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
+                       "for crashkernel (System RAM: %ldMB)\n",
+                       (unsigned long)(crash_size >> 20),
+                       (unsigned long)(crashk_res.start >> 20),
+                       (unsigned long)(lmb_phys_mem_size() >> 20));
+
+       lmb_reserve(crashk_res.start, crash_size);
 }
 
 int overlaps_crashkernel(unsigned long start, unsigned long size)
index ea6ad7a2a7e3df329b9e56e4aaca83e524905148..b9d88374f14f07abe21e51367110e6c82129ba99 100644 (file)
@@ -459,7 +459,7 @@ void show_regs(struct pt_regs * regs)
                printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr);
 #endif
        printk("TASK = %p[%d] '%s' THREAD: %p",
-              current, current->pid, current->comm, task_thread_info(current));
+              current, task_pid_nr(current), current->comm, task_thread_info(current));
 
 #ifdef CONFIG_SMP
        printk(" CPU: %d", smp_processor_id());
index 863a5d6d9b1890626f5eceac08bc45304e6c13ce..9eb3284deac4e5d4e9942b5e643ab59fede4af85 100644 (file)
@@ -211,24 +211,45 @@ static u64 read_purr(void)
        return mftb();
 }
 
+/*
+ * Read the SPURR on systems that have it, otherwise the purr
+ */
+static u64 read_spurr(u64 purr)
+{
+       if (cpu_has_feature(CPU_FTR_SPURR))
+               return mfspr(SPRN_SPURR);
+       return purr;
+}
+
 /*
  * Account time for a transition between system, hard irq
  * or soft irq state.
  */
 void account_system_vtime(struct task_struct *tsk)
 {
-       u64 now, delta;
+       u64 now, nowscaled, delta, deltascaled;
        unsigned long flags;
 
        local_irq_save(flags);
        now = read_purr();
        delta = now - get_paca()->startpurr;
        get_paca()->startpurr = now;
+       nowscaled = read_spurr(now);
+       deltascaled = nowscaled - get_paca()->startspurr;
+       get_paca()->startspurr = nowscaled;
        if (!in_interrupt()) {
+               /* deltascaled includes both user and system time.
+                * Hence scale it based on the purr ratio to estimate
+                * the system time */
+               deltascaled = deltascaled * get_paca()->system_time /
+                       (get_paca()->system_time + get_paca()->user_time);
                delta += get_paca()->system_time;
                get_paca()->system_time = 0;
        }
        account_system_time(tsk, 0, delta);
+       get_paca()->purrdelta = delta;
+       account_system_time_scaled(tsk, deltascaled);
+       get_paca()->spurrdelta = deltascaled;
        local_irq_restore(flags);
 }
 
@@ -240,11 +261,17 @@ void account_system_vtime(struct task_struct *tsk)
  */
 void account_process_vtime(struct task_struct *tsk)
 {
-       cputime_t utime;
+       cputime_t utime, utimescaled;
 
        utime = get_paca()->user_time;
        get_paca()->user_time = 0;
        account_user_time(tsk, utime);
+
+       /* Estimate the scaled utime by scaling the real utime based
+        * on the last spurr to purr ratio */
+       utimescaled = utime * get_paca()->spurrdelta / get_paca()->purrdelta;
+       get_paca()->spurrdelta = get_paca()->purrdelta = 0;
+       account_user_time_scaled(tsk, utimescaled);
 }
 
 static void account_process_time(struct pt_regs *regs)
@@ -266,6 +293,7 @@ struct cpu_purr_data {
        int     initialized;                    /* thread is running */
        u64     tb;                     /* last TB value read */
        u64     purr;                   /* last PURR value read */
+       u64     spurr;                  /* last SPURR value read */
 };
 
 /*
index bf9e39c6e296209f0f6bc8f5f08c35286df279d4..59c464e26f38886ff0c6d9ed7f20488dc66b4740 100644 (file)
@@ -201,7 +201,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
         * generate the same exception over and over again and we get
         * nowhere.  Better to kill it and let the kernel panic.
         */
-       if (is_init(current)) {
+       if (is_global_init(current)) {
                __sighandler_t handler;
 
                spin_lock_irq(&current->sighand->siglock);
@@ -881,7 +881,7 @@ void nonrecoverable_exception(struct pt_regs *regs)
 void trace_syscall(struct pt_regs *regs)
 {
        printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld    %s\n",
-              current, current->pid, regs->nip, regs->link, regs->gpr[0],
+              current, task_pid_nr(current), regs->nip, regs->link, regs->gpr[0],
               regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted());
 }
 
index ab3546c5ac3a2a8f4b022ba8150c13a9c7686728..a18fda361cc0fe19103add8034d5b3485b012079 100644 (file)
@@ -375,7 +375,7 @@ bad_area_nosemaphore:
  */
 out_of_memory:
        up_read(&mm->mmap_sem);
-       if (is_init(current)) {
+       if (is_global_init(current)) {
                yield();
                down_read(&mm->mmap_sem);
                goto survive;
diff --git a/arch/powerpc/oprofile/Kconfig b/arch/powerpc/oprofile/Kconfig
deleted file mode 100644 (file)
index 7089e79..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-config PROFILING
-       bool "Profiling support (EXPERIMENTAL)"
-       help
-         Say Y here to enable the extended profiling support mechanisms used
-         by profilers such as OProfile.
-
-
-config OPROFILE
-       tristate "OProfile system profiling (EXPERIMENTAL)"
-       depends on PROFILING
-       help
-         OProfile is a profiling system capable of profiling the
-         whole system, include the kernel, kernel modules, libraries,
-         and applications.
-
-         If unsure, say N.
-
-config OPROFILE_CELL
-       bool "OProfile for Cell Broadband Engine"
-       depends on (SPU_FS = y && OPROFILE = m) || (SPU_FS = y && OPROFILE = y) || (SPU_FS = m && OPROFILE = m)
-       default y
-       help
-         Profiling of Cell BE SPUs requires special support enabled
-         by this option.
index 47b3b0a3864a88db4278fcfbf729980c8b55b749..8f6699fcc14512ff92952b1506be584c91e0068a 100644 (file)
@@ -100,6 +100,7 @@ config 405GP
        bool
        select IBM405_ERR77
        select IBM405_ERR51
+       select IBM_NEW_EMAC_ZMII
 
 config 405EP
        bool
index 51f3ea40a285be0c24e3aadd1a24034a34857742..8390cc164135387baecf575317f1e6d1281d50b8 100644 (file)
@@ -43,14 +43,14 @@ config 440EP
        bool
        select PPC_FPU
        select IBM440EP_ERR42
-#      select IBM_NEW_EMAC_ZMII
+       select IBM_NEW_EMAC_ZMII
 
 config 440EPX
        bool
        select PPC_FPU
-# Disabled until the new EMAC Driver is merged.
-#      select IBM_NEW_EMAC_EMAC4
-#      select IBM_NEW_EMAC_ZMII
+       select IBM_NEW_EMAC_EMAC4
+       select IBM_NEW_EMAC_RGMII
+       select IBM_NEW_EMAC_ZMII
 
 config 440GP
        bool
index 65b7ae4262381a2b9830dd1ecbb5a487a6a56063..25d2bfa3d9dc0237c0c7d2299e94c863eaeade20 100644 (file)
@@ -145,6 +145,9 @@ static void __init lite5200_setup_arch(void)
        /* Some mpc5200 & mpc5200b related configuration */
        mpc5200_setup_xlb_arbiter();
 
+       /* Map wdt for mpc52xx_restart() */
+       mpc52xx_map_wdt();
+
 #ifdef CONFIG_PM
        mpc52xx_suspend.board_suspend_prepare = lite5200_suspend_prepare;
        mpc52xx_suspend.board_resume_finish = lite5200_resume_finish;
@@ -183,5 +186,6 @@ define_machine(lite5200) {
        .init           = mpc52xx_declare_of_platform_devices,
        .init_IRQ       = mpc52xx_init_irq,
        .get_irq        = mpc52xx_get_irq,
+       .restart        = mpc52xx_restart,
        .calibrate_decr = generic_calibrate_decr,
 };
index f26afcd41757ad1bb96f81ec78b9995d7ccc7db6..ffa14aff5248f7d18193c9fa20ba247533bb454c 100644 (file)
@@ -1,5 +1,5 @@
 #include <linux/init.h>
-#include <linux/pm.h>
+#include <linux/suspend.h>
 #include <asm/io.h>
 #include <asm/time.h>
 #include <asm/mpc52xx.h>
@@ -18,6 +18,8 @@ static void __iomem *sram;
 static const int sram_size = 0x4000;   /* 16 kBytes */
 static void __iomem *mbar;
 
+static suspend_state_t lite5200_pm_target_state;
+
 static int lite5200_pm_valid(suspend_state_t state)
 {
        switch (state) {
@@ -29,13 +31,22 @@ static int lite5200_pm_valid(suspend_state_t state)
        }
 }
 
-static int lite5200_pm_prepare(suspend_state_t state)
+static int lite5200_pm_set_target(suspend_state_t state)
+{
+       if (lite5200_pm_valid(state)) {
+               lite5200_pm_target_state = state;
+               return 0;
+       }
+       return -EINVAL;
+}
+
+static int lite5200_pm_prepare(void)
 {
        /* deep sleep? let mpc52xx code handle that */
-       if (state == PM_SUSPEND_STANDBY)
-               return mpc52xx_pm_prepare(state);
+       if (lite5200_pm_target_state == PM_SUSPEND_STANDBY)
+               return mpc52xx_pm_prepare();
 
-       if (state != PM_SUSPEND_MEM)
+       if (lite5200_pm_target_state != PM_SUSPEND_MEM)
                return -EINVAL;
 
        /* map registers */
@@ -190,17 +201,16 @@ static int lite5200_pm_enter(suspend_state_t state)
        return 0;
 }
 
-static int lite5200_pm_finish(suspend_state_t state)
+static void lite5200_pm_finish(void)
 {
        /* deep sleep? let mpc52xx code handle that */
-       if (state == PM_SUSPEND_STANDBY) {
-               return mpc52xx_pm_finish(state);
-       }
-       return 0;
+       if (lite5200_pm_target_state == PM_SUSPEND_STANDBY)
+               mpc52xx_pm_finish();
 }
 
-static struct pm_ops lite5200_pm_ops = {
+static struct platform_suspend_ops lite5200_pm_ops = {
        .valid          = lite5200_pm_valid,
+       .set_target     = lite5200_pm_set_target,
        .prepare        = lite5200_pm_prepare,
        .enter          = lite5200_pm_enter,
        .finish         = lite5200_pm_finish,
@@ -208,6 +218,6 @@ static struct pm_ops lite5200_pm_ops = {
 
 int __init lite5200_pm_init(void)
 {
-       pm_set_ops(&lite5200_pm_ops);
+       suspend_set_ops(&lite5200_pm_ops);
        return 0;
 }
index 3bc201e07e6b9a5a66a8b3f9011faa1b327971d9..9850685c542999c69a89ee65c94cba2b750e7b5e 100644 (file)
 #include <asm/prom.h>
 #include <asm/mpc52xx.h>
 
+/*
+ * This variable is mapped in mpc52xx_map_wdt() and used in mpc52xx_restart().
+ * Permanent mapping is required because mpc52xx_restart() can be called
+ * from interrupt context while node mapping (which calls ioremap())
+ * cannot be used at such point.
+ */
+static volatile struct mpc52xx_gpt *mpc52xx_wdt = NULL;
 
-void __iomem *
-mpc52xx_find_and_map(const char *compatible)
+static void __iomem *
+mpc52xx_map_node(struct device_node *ofn)
 {
-       struct device_node *ofn;
        const u32 *regaddr_p;
        u64 regaddr64, size64;
 
-       ofn = of_find_compatible_node(NULL, NULL, compatible);
        if (!ofn)
                return NULL;
 
@@ -42,8 +47,23 @@ mpc52xx_find_and_map(const char *compatible)
 
        return ioremap((u32)regaddr64, (u32)size64);
 }
+
+void __iomem *
+mpc52xx_find_and_map(const char *compatible)
+{
+       return mpc52xx_map_node(
+               of_find_compatible_node(NULL, NULL, compatible));
+}
+
 EXPORT_SYMBOL(mpc52xx_find_and_map);
 
+void __iomem *
+mpc52xx_find_and_map_path(const char *path)
+{
+       return mpc52xx_map_node(of_find_node_by_path(path));
+}
+
+EXPORT_SYMBOL(mpc52xx_find_and_map_path);
 
 /**
  *     mpc52xx_find_ipb_freq - Find the IPB bus frequency for a device
@@ -113,3 +133,46 @@ mpc52xx_declare_of_platform_devices(void)
                        "Error while probing of_platform bus\n");
 }
 
+void __init
+mpc52xx_map_wdt(void)
+{
+       const void *has_wdt;
+       struct device_node *np;
+
+       /* mpc52xx_wdt is mapped here and used in mpc52xx_restart,
+        * possibly from a interrupt context. wdt is only implement
+        * on a gpt0, so check has-wdt property before mapping.
+        */
+       for_each_compatible_node(np, NULL, "fsl,mpc5200-gpt") {
+               has_wdt = of_get_property(np, "fsl,has-wdt", NULL);
+               if (has_wdt) {
+                       mpc52xx_wdt = mpc52xx_map_node(np);
+                       return;
+               }
+       }
+       for_each_compatible_node(np, NULL, "mpc5200-gpt") {
+               has_wdt = of_get_property(np, "has-wdt", NULL);
+               if (has_wdt) {
+                       mpc52xx_wdt = mpc52xx_map_node(np);
+                       return;
+               }
+       }
+}
+
+void
+mpc52xx_restart(char *cmd)
+{
+       local_irq_disable();
+
+       /* Turn on the watchdog and wait for it to expire.
+        * It effectively does a reset. */
+       if (mpc52xx_wdt) {
+               out_be32(&mpc52xx_wdt->mode, 0x00000000);
+               out_be32(&mpc52xx_wdt->count, 0x000000ff);
+               out_be32(&mpc52xx_wdt->mode, 0x00009004);
+       } else
+               printk("mpc52xx_restart: Can't access wdt. "
+                       "Restart impossible, system halted.\n");
+
+       while (1);
+}
index ee2e7639c63e85c6d890251a2240450d048c03a1..7ffa7babf25416a8f43a98b7595a468391c75472 100644 (file)
@@ -1,5 +1,5 @@
 #include <linux/init.h>
-#include <linux/pm.h>
+#include <linux/suspend.h>
 #include <linux/io.h>
 #include <asm/time.h>
 #include <asm/cacheflush.h>
@@ -57,11 +57,8 @@ int mpc52xx_set_wakeup_gpio(u8 pin, u8 level)
        return 0;
 }
 
-int mpc52xx_pm_prepare(suspend_state_t state)
+int mpc52xx_pm_prepare(void)
 {
-       if (state != PM_SUSPEND_STANDBY)
-               return -EINVAL;
-
        /* map the whole register space */
        mbar = mpc52xx_find_and_map("mpc5200");
        if (!mbar) {
@@ -166,18 +163,16 @@ int mpc52xx_pm_enter(suspend_state_t state)
        return 0;
 }
 
-int mpc52xx_pm_finish(suspend_state_t state)
+void mpc52xx_pm_finish(void)
 {
        /* call board resume code */
        if (mpc52xx_suspend.board_resume_finish)
                mpc52xx_suspend.board_resume_finish(mbar);
 
        iounmap(mbar);
-
-       return 0;
 }
 
-static struct pm_ops mpc52xx_pm_ops = {
+static struct platform_suspend_ops mpc52xx_pm_ops = {
        .valid          = mpc52xx_pm_valid,
        .prepare        = mpc52xx_pm_prepare,
        .enter          = mpc52xx_pm_enter,
@@ -186,6 +181,6 @@ static struct pm_ops mpc52xx_pm_ops = {
 
 int __init mpc52xx_pm_init(void)
 {
-       pm_set_ops(&mpc52xx_pm_ops);
+       suspend_set_ops(&mpc52xx_pm_ops);
        return 0;
 }
index 229d355ed86a7264548e1dcb0b4145a3e0349c6a..ea22cad2cd0af5bb7cb67827abc7cbedc7d58756 100644 (file)
@@ -120,7 +120,7 @@ config PPC_PMI
        depends on PPC_IBM_CELL_BLADE
        help
          PMI (Platform Management Interrupt) is a way to
-         communicate with the BMC (Baseboard Mangement Controller).
+         communicate with the BMC (Baseboard Management Controller).
          It is used in some IBM Cell blades.
        default m
 
index 3c7325ec36ecef5a1512ba9da639aee95eb7c310..99684ea606afef4b399a46ab1e059baef6002767 100644 (file)
@@ -48,6 +48,7 @@ config 44x
        bool "AMCC 44x"
        select PPC_DCR_NATIVE
        select WANT_DEVICE_TREE
+       select PPC_UDBG_16550
 
 config E200
        bool "Freescale e200"
index d72b16d6816e065b9010ff2b51afed56d0aeb289..d9e56a503795246ee9f4848a23224a27635a2577 100644 (file)
@@ -748,7 +748,7 @@ static ssize_t spufs_wbox_write(struct file *file, const char __user *buf,
        if (count)
                goto out;
 
-       /* write aѕ much as possible */
+       /* write as much as possible */
        for (count = 4, udata++; (count + 4) <= len; count += 4, udata++) {
                int ret;
                ret = __get_user(wbox_data, udata);
index a7c548bde2e37d66170693a7d4cc2847a6c6d1f4..b59c38a06e3e46299d6d622a039660ab7e61291b 100644 (file)
@@ -36,7 +36,7 @@ static inline int uhc_clkctrl_ready(u32 val)
 }
 
 /*
- * UHC(usb host controler) enable function.
+ * UHC(usb host controller) enable function.
  * affect to both of OHCI and EHCI core module.
  */
 static void enable_scc_uhc(struct pci_dev *dev)
index 354c058616299e7fdc7102a5c55fb89ee49fbe29..144177d77cf1075bf590afb8492141d932f59200 100644 (file)
 #include <linux/root_dev.h>
 #include <linux/serial.h>
 #include <linux/smp.h>
+#include <linux/bitops.h>
 
 #include <asm/processor.h>
 #include <asm/sections.h>
 #include <asm/prom.h>
 #include <asm/system.h>
 #include <asm/pgtable.h>
-#include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/kexec.h>
 #include <asm/pci-bridge.h>
index 07e64b48e7fca2d79391466a04a7da5502bf3251..6405f4a36763b00df384c1db6153e6125db0d822 100644 (file)
@@ -628,9 +628,8 @@ static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sgl,
        int i;
 
        for_each_sg(sgl, sg, nents, i) {
-               int result = ps3_dma_map(dev->d_region,
-                       page_to_phys(sg->page) + sg->offset, sg->length,
-                                        &sg->dma_address, 0);
+               int result = ps3_dma_map(dev->d_region, sg_phys(sg),
+                                       sg->length, &sg->dma_address, 0);
 
                if (result) {
                        pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
index 3a393c7f390e1cce07e0ee0d1c4c7bfc24284057..a1ab25c7082f1031343d492445c37ce3845580dd 100644 (file)
@@ -332,7 +332,7 @@ static int recover_mce(struct pt_regs *regs, struct rtas_error_log * err)
                   err->disposition == RTAS_DISP_NOT_RECOVERED &&
                   err->target == RTAS_TARGET_MEMORY &&
                   err->type == RTAS_TYPE_ECC_UNCORR &&
-                  !(current->pid == 0 || is_init(current))) {
+                  !(current->pid == 0 || is_global_init(current))) {
                /* Kill off a user process with an ECC error */
                printk(KERN_ERR "MCE: uncorrectable ecc error for pid %d\n",
                       current->pid);
index 48492a83e5a714c78ead3db50f9f1649e3a67025..740ad73ce5cc4e3c58044053e7dcedecc844fd2e 100644 (file)
@@ -269,6 +269,7 @@ bcom_engine_init(void)
        int task;
        phys_addr_t tdt_pa, ctx_pa, var_pa, fdt_pa;
        unsigned int tdt_size, ctx_size, var_size, fdt_size;
+       u16 regval;
 
        /* Allocate & clear SRAM zones for FDT, TDTs, contexts and vars/incs */
        tdt_size = BCOM_MAX_TASKS * sizeof(struct bcom_tdt);
@@ -319,9 +320,11 @@ bcom_engine_init(void)
        /* Init 'always' initiator */
        out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ALWAYS], BCOM_IPR_ALWAYS);
 
-       /* Disable COMM Bus Prefetch, apparently it's not reliable yet */
-       /* FIXME: This should be done on 5200 and not 5200B ... */
-       out_be16(&bcom_eng->regs->PtdCntrl, in_be16(&bcom_eng->regs->PtdCntrl) | 1);
+       /* Disable COMM Bus Prefetch on the original 5200; it's broken */
+       if ((mfspr(SPRN_SVR) & MPC5200_SVR_MASK) == MPC5200_SVR) {
+               regval = in_be16(&bcom_eng->regs->PtdCntrl);
+               out_be16(&bcom_eng->regs->PtdCntrl,  regval | 1);
+       }
 
        /* Init lock */
        spin_lock_init(&bcom_eng->lock);
index 607925c8a99e050f0e1b042b531de6acc0290627..6473fa7cb4b95c43326def7b2dbe3a5d94e46d06 100644 (file)
@@ -1317,7 +1317,7 @@ endmenu
 
 source "lib/Kconfig"
 
-source "arch/powerpc/oprofile/Kconfig"
+source "kernel/Kconfig.instrumentation"
 
 source "arch/ppc/Kconfig.debug"
 
index 487dc66dcc7414d9f1ca67508b06c5dbb1f82852..500497e3c72dde5096673c2f4fc893135cfa49ea 100644 (file)
@@ -13,6 +13,8 @@
 # modified by Cort (cort@cs.nmt.edu)
 #
 
+# KBUILD_CFLAGS used when building rest of boot (takes effect recursively)
+KBUILD_CFLAGS  += -fno-builtin -D__BOOTER__ -Iarch/$(ARCH)/boot/include
 HOSTCFLAGS     += -Iarch/$(ARCH)/boot/include
 
 BOOT_TARGETS   = zImage zImage.initrd znetboot znetboot.initrd
index 3f3b292eb773ba80d2d3f79bdfd231bbcea95ecb..c78568905c3b1c2b7676446748e57774a737399a 100644 (file)
@@ -121,7 +121,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
         * generate the same exception over and over again and we get
         * nowhere.  Better to kill it and let the kernel panic.
         */
-       if (is_init(current)) {
+       if (is_global_init(current)) {
                __sighandler_t handler;
 
                spin_lock_irq(&current->sighand->siglock);
index 94913ddcf76e8524392dec4f5d9b53bccbc2011f..254c23b755e689006a7073a13a57cbf35db4643b 100644 (file)
@@ -290,7 +290,7 @@ bad_area:
  */
 out_of_memory:
        up_read(&mm->mmap_sem);
-       if (is_init(current)) {
+       if (is_global_init(current)) {
                yield();
                down_read(&mm->mmap_sem);
                goto survive;
index 248684f50dd9e4c7754503951259b0639d2cdba6..dcd6070b85eb10efa6e644e5115e17def1ab8bc5 100644 (file)
@@ -49,7 +49,6 @@ extern void gen550_progress(char *, unsigned short);
 extern void gen550_init(int, struct uart_port *);
 extern void mv64360_pcibios_fixup(mv64x60_handle_t *bh);
 
-#define BIT(x) (1<<x)
 #define CHESTNUT_PRESERVE_MASK (BIT(MV64x60_CPU2DEV_0_WIN) | \
                                BIT(MV64x60_CPU2DEV_1_WIN) | \
                                BIT(MV64x60_CPU2DEV_2_WIN) | \
index b71132166f606343f810e47387c7a26b4918fced..4ec716d8c1a623b4e123b8e2923d4443a3f3b42a 100644 (file)
@@ -529,21 +529,7 @@ source "drivers/Kconfig"
 
 source "fs/Kconfig"
 
-menu "Instrumentation Support"
-
-source "arch/s390/oprofile/Kconfig"
-
-config KPROBES
-       bool "Kprobes (EXPERIMENTAL)"
-       depends on EXPERIMENTAL && MODULES
-       help
-         Kprobes allows you to trap at almost any kernel address and
-         execute a callback function.  register_kprobe() establishes
-         a probepoint and specifies the callback.  Kprobes is useful
-         for kernel debugging, non-intrusive instrumentation and testing.
-         If in doubt, say "N".
-
-endmenu
+source "kernel/Kconfig.instrumentation"
 
 source "arch/s390/Kconfig.debug"
 
index 2aae23dba4bbc8b2a087c3a36b8145a7cdfb5656..ece7b99da8955c8e31ae82a7726e3ea5c76e7c83 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.22
-# Tue Jul 17 12:50:23 2007
+# Linux kernel version: 2.6.23
+# Mon Oct 22 12:10:44 2007
 #
 CONFIG_MMU=y
 CONFIG_ZONE_DMA=y
@@ -19,15 +19,11 @@ CONFIG_S390=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
-# Code maturity level options
+# General setup
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
@@ -42,7 +38,14 @@ CONFIG_AUDIT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=17
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+CONFIG_CGROUP_NS=y
+CONFIG_CGROUP_CPUACCT=y
 # CONFIG_CPUSETS is not set
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
+# CONFIG_FAIR_CGROUP_SCHED is not set
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -63,7 +66,6 @@ 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
@@ -83,6 +85,7 @@ CONFIG_STOP_MACHINE=y
 CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 CONFIG_BLK_DEV_BSG=y
+CONFIG_BLOCK_COMPAT=y
 
 #
 # IO Schedulers
@@ -108,7 +111,6 @@ CONFIG_64BIT=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=32
 CONFIG_HOTPLUG_CPU=y
-CONFIG_DEFAULT_MIGRATION_COST=1000000
 CONFIG_COMPAT=y
 CONFIG_SYSVIPC_COMPAT=y
 CONFIG_AUDIT_ARCH=y
@@ -143,9 +145,11 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_RESOURCES_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
 CONFIG_HOLES_IN_ZONE=y
 
@@ -219,12 +223,14 @@ CONFIG_INET_TUNNEL=y
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
 CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_LRO=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TCP_MD5SIG is not set
+# CONFIG_IP_VS is not set
 CONFIG_IPV6=y
 # CONFIG_IPV6_PRIVACY is not set
 # CONFIG_IPV6_ROUTER_PREF is not set
@@ -243,7 +249,48 @@ 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 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NF_CONNTRACK_ENABLED=m
+CONFIG_NF_CONNTRACK=m
+# CONFIG_NF_CT_ACCT is not set
+# CONFIG_NF_CONNTRACK_MARK is not set
+# CONFIG_NF_CONNTRACK_EVENTS is not set
+# CONFIG_NF_CT_PROTO_SCTP is not set
+# CONFIG_NF_CT_PROTO_UDPLITE is not set
+# CONFIG_NF_CONNTRACK_AMANDA is not set
+# CONFIG_NF_CONNTRACK_FTP is not set
+# CONFIG_NF_CONNTRACK_H323 is not set
+# CONFIG_NF_CONNTRACK_IRC is not set
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+# CONFIG_NF_CONNTRACK_PPTP is not set
+# CONFIG_NF_CONNTRACK_SANE is not set
+# CONFIG_NF_CONNTRACK_SIP is not set
+# CONFIG_NF_CONNTRACK_TFTP is not set
+# CONFIG_NF_CT_NETLINK is not set
+# CONFIG_NETFILTER_XTABLES is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_NF_CONNTRACK_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
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+# CONFIG_NF_CONNTRACK_IPV6 is not set
+# CONFIG_IP6_NF_QUEUE is not set
+# CONFIG_IP6_NF_IPTABLES is not set
 # CONFIG_IP_DCCP is not set
 CONFIG_IP_SCTP=m
 # CONFIG_SCTP_DBG_MSG is not set
@@ -263,12 +310,7 @@ CONFIG_SCTP_HMAC_MD5=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_FIFO=y
 
 #
 # Queueing/Scheduling
@@ -306,10 +348,12 @@ CONFIG_NET_CLS_ACT=y
 CONFIG_NET_ACT_POLICE=y
 # CONFIG_NET_ACT_GACT is not set
 # CONFIG_NET_ACT_MIRRED is not set
+CONFIG_NET_ACT_NAT=m
 # CONFIG_NET_ACT_PEDIT is not set
 # CONFIG_NET_ACT_SIMP is not set
 CONFIG_NET_CLS_POLICE=y
 # CONFIG_NET_CLS_IND is not set
+CONFIG_NET_SCH_FIFO=y
 
 #
 # Network testing
@@ -329,6 +373,7 @@ CONFIG_CCW=y
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
@@ -400,17 +445,11 @@ CONFIG_SCSI_FC_ATTRS=y
 # 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_ZFCP=y
-
-#
-# Multi-device support (RAID and LVM)
-#
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=y
 CONFIG_MD_LINEAR=m
@@ -429,7 +468,9 @@ CONFIG_DM_ZERO=y
 CONFIG_DM_MULTIPATH=y
 # CONFIG_DM_MULTIPATH_EMC is not set
 # CONFIG_DM_MULTIPATH_RDAC is not set
+# CONFIG_DM_MULTIPATH_HP is not set
 # CONFIG_DM_DELAY is not set
+# CONFIG_DM_UEVENT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_IFB is not set
@@ -438,8 +479,13 @@ CONFIG_BONDING=m
 # CONFIG_MACVLAN is not set
 CONFIG_EQUALIZER=m
 CONFIG_TUN=m
+CONFIG_VETH=m
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
 CONFIG_NETDEV_1000=y
 CONFIG_NETDEV_10000=y
 # CONFIG_TR is not set
@@ -473,7 +519,6 @@ CONFIG_CCWGROUP=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
-# CONFIG_WATCHDOG is not set
 CONFIG_HW_RANDOM=m
 # CONFIG_R3964 is not set
 CONFIG_RAW_DRIVER=m
@@ -490,7 +535,6 @@ CONFIG_TN3270_CONSOLE=y
 CONFIG_TN3215=y
 CONFIG_TN3215_CONSOLE=y
 CONFIG_CCW_CONSOLE=y
-CONFIG_SCLP=y
 CONFIG_SCLP_TTY=y
 CONFIG_SCLP_CONSOLE=y
 CONFIG_SCLP_VT220_TTY=y
@@ -514,6 +558,11 @@ CONFIG_S390_TAPE_34XX=m
 CONFIG_MONWRITER=m
 CONFIG_S390_VMUR=m
 # CONFIG_POWER_SUPPLY is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
 
 #
 # File systems
@@ -569,7 +618,6 @@ CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
 CONFIG_CONFIGFS_FS=m
 
 #
@@ -588,10 +636,7 @@ CONFIG_CONFIGFS_FS=m
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
@@ -638,27 +683,13 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 # CONFIG_SYSV68_PARTITION is not set
-
-#
-# Native Language Support
-#
 # CONFIG_NLS is not set
-
-#
-# Distributed Lock Manager
-#
 CONFIG_DLM=m
 # CONFIG_DLM_DEBUG is not set
-
-#
-# Instrumentation Support
-#
-
-#
-# Profiling support
-#
+CONFIG_INSTRUMENTATION=y
 # CONFIG_PROFILING is not set
 CONFIG_KPROBES=y
+# CONFIG_MARKERS is not set
 
 #
 # Kernel hacking
@@ -682,6 +713,7 @@ CONFIG_DEBUG_SPINLOCK=y
 CONFIG_DEBUG_MUTEXES=y
 # CONFIG_DEBUG_LOCK_ALLOC is not set
 # CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -694,14 +726,17 @@ CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
+CONFIG_SAMPLES=y
 
 #
 # Security options
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=m
 CONFIG_CRYPTO_BLKCIPHER=y
 CONFIG_CRYPTO_HASH=m
 CONFIG_CRYPTO_MANAGER=y
@@ -720,6 +755,7 @@ CONFIG_CRYPTO_ECB=m
 CONFIG_CRYPTO_CBC=y
 CONFIG_CRYPTO_PCBC=m
 # CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_DES is not set
 CONFIG_CRYPTO_FCRYPT=m
@@ -733,11 +769,13 @@ CONFIG_CRYPTO_FCRYPT=m
 # CONFIG_CRYPTO_ARC4 is not set
 # CONFIG_CRYPTO_KHAZAD is not set
 # CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_SEED=m
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 # CONFIG_CRYPTO_CRC32C is not set
 CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
+CONFIG_CRYPTO_AUTHENC=m
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_SHA1_S390 is not set
 # CONFIG_CRYPTO_SHA256_S390 is not set
@@ -755,5 +793,6 @@ CONFIG_BITREVERSE=m
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=m
+CONFIG_CRC7=m
 # CONFIG_LIBCRC32C is not set
 CONFIG_PLIST=y
index 66b51901c87d29be81d8c25cc0b8546ae1e970b1..ce0856d32500215ef1942d03a0a61f000767d4fa 100644 (file)
@@ -648,6 +648,8 @@ static int dump_set_type(enum dump_type type)
        case DUMP_TYPE_CCW:
                if (MACHINE_IS_VM)
                        dump_method = DUMP_METHOD_CCW_VM;
+               else if (diag308_set_works)
+                       dump_method = DUMP_METHOD_CCW_DIAG;
                else
                        dump_method = DUMP_METHOD_CCW_CIO;
                break;
index abb447a3e472443b6925b1a60f08909a28d067f0..96492cf2d491d38d4d6000cddb1a38fb4b1463fb 100644 (file)
@@ -44,6 +44,7 @@
 #include <asm/processor.h>
 #include <asm/irq.h>
 #include <asm/timer.h>
+#include <asm/cpu.h>
 
 asmlinkage void ret_from_fork(void) asm ("ret_from_fork");
 
@@ -91,6 +92,14 @@ EXPORT_SYMBOL(unregister_idle_notifier);
 
 void do_monitor_call(struct pt_regs *regs, long interruption_code)
 {
+       struct s390_idle_data *idle;
+
+       idle = &__get_cpu_var(s390_idle);
+       spin_lock(&idle->lock);
+       idle->idle_time += get_clock() - idle->idle_enter;
+       idle->in_idle = 0;
+       spin_unlock(&idle->lock);
+
        /* disable monitor call class 0 */
        __ctl_clear_bit(8, 15);
 
@@ -105,6 +114,7 @@ extern void s390_handle_mcck(void);
 static void default_idle(void)
 {
        int cpu, rc;
+       struct s390_idle_data *idle;
 
        /* CPU is going idle. */
        cpu = smp_processor_id();
@@ -142,6 +152,12 @@ static void default_idle(void)
                return;
        }
 
+       idle = &__get_cpu_var(s390_idle);
+       spin_lock(&idle->lock);
+       idle->idle_count++;
+       idle->in_idle = 1;
+       idle->idle_enter = get_clock();
+       spin_unlock(&idle->lock);
        trace_hardirqs_on();
        /* Wait for external, I/O or machine check interrupt. */
        __load_psw_mask(psw_kernel_bits | PSW_MASK_WAIT |
@@ -166,7 +182,7 @@ void show_regs(struct pt_regs *regs)
 
         printk("CPU:    %d    %s\n", task_thread_info(tsk)->cpu, print_tainted());
         printk("Process %s (pid: %d, task: %p, ksp: %p)\n",
-              current->comm, current->pid, (void *) tsk,
+              current->comm, task_pid_nr(current), (void *) tsk,
               (void *) tsk->thread.ksp);
 
        show_registers(regs);
@@ -254,14 +270,12 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long new_stackp,
        save_fp_regs(&current->thread.fp_regs);
        memcpy(&p->thread.fp_regs, &current->thread.fp_regs,
               sizeof(s390_fp_regs));
-        p->thread.user_seg = __pa((unsigned long) p->mm->pgd) | _SEGMENT_TABLE;
        /* Set a new TLS ?  */
        if (clone_flags & CLONE_SETTLS)
                p->thread.acrs[0] = regs->gprs[6];
 #else /* CONFIG_64BIT */
        /* Save the fpu registers to new thread structure. */
        save_fp_regs(&p->thread.fp_regs);
-        p->thread.user_seg = __pa((unsigned long) p->mm->pgd) | _REGION_TABLE;
        /* Set a new TLS ?  */
        if (clone_flags & CLONE_SETTLS) {
                if (test_thread_flag(TIF_31BIT)) {
index 35edbef1d2228b021b8e677f22a9bcf7a66d0eeb..1d97fe1c0e538d1df29aebd133522d09dfcf08c3 100644 (file)
@@ -42,6 +42,7 @@
 #include <asm/tlbflush.h>
 #include <asm/timer.h>
 #include <asm/lowcore.h>
+#include <asm/cpu.h>
 
 /*
  * An array with a pointer the lowcore of every CPU.
@@ -325,7 +326,7 @@ static void smp_ext_bitcall(int cpu, ec_bit_sig sig)
  */
 void smp_ptlb_callback(void *info)
 {
-       local_flush_tlb();
+       __tlb_flush_local();
 }
 
 void smp_ptlb_all(void)
@@ -494,6 +495,8 @@ int __cpuinit start_secondary(void *cpuvoid)
        return 0;
 }
 
+DEFINE_PER_CPU(struct s390_idle_data, s390_idle);
+
 static void __init smp_create_idle(unsigned int cpu)
 {
        struct task_struct *p;
@@ -506,6 +509,7 @@ static void __init smp_create_idle(unsigned int cpu)
        if (IS_ERR(p))
                panic("failed fork for CPU %u: %li", cpu, PTR_ERR(p));
        current_set[cpu] = p;
+       spin_lock_init(&(&per_cpu(s390_idle, cpu))->lock);
 }
 
 static int cpu_stopped(int cpu)
@@ -724,6 +728,7 @@ void __init smp_prepare_boot_cpu(void)
        cpu_set(0, cpu_online_map);
        S390_lowcore.percpu_offset = __per_cpu_offset[0];
        current_set[0] = current;
+       spin_lock_init(&(&__get_cpu_var(s390_idle))->lock);
 }
 
 void __init smp_cpus_done(unsigned int max_cpus)
@@ -756,22 +761,71 @@ static ssize_t show_capability(struct sys_device *dev, char *buf)
 }
 static SYSDEV_ATTR(capability, 0444, show_capability, NULL);
 
+static ssize_t show_idle_count(struct sys_device *dev, char *buf)
+{
+       struct s390_idle_data *idle;
+       unsigned long long idle_count;
+
+       idle = &per_cpu(s390_idle, dev->id);
+       spin_lock_irq(&idle->lock);
+       idle_count = idle->idle_count;
+       spin_unlock_irq(&idle->lock);
+       return sprintf(buf, "%llu\n", idle_count);
+}
+static SYSDEV_ATTR(idle_count, 0444, show_idle_count, NULL);
+
+static ssize_t show_idle_time(struct sys_device *dev, char *buf)
+{
+       struct s390_idle_data *idle;
+       unsigned long long new_time;
+
+       idle = &per_cpu(s390_idle, dev->id);
+       spin_lock_irq(&idle->lock);
+       if (idle->in_idle) {
+               new_time = get_clock();
+               idle->idle_time += new_time - idle->idle_enter;
+               idle->idle_enter = new_time;
+       }
+       new_time = idle->idle_time;
+       spin_unlock_irq(&idle->lock);
+       return sprintf(buf, "%llu us\n", new_time >> 12);
+}
+static SYSDEV_ATTR(idle_time, 0444, show_idle_time, NULL);
+
+static struct attribute *cpu_attrs[] = {
+       &attr_capability.attr,
+       &attr_idle_count.attr,
+       &attr_idle_time.attr,
+       NULL,
+};
+
+static struct attribute_group cpu_attr_group = {
+       .attrs = cpu_attrs,
+};
+
 static int __cpuinit smp_cpu_notify(struct notifier_block *self,
                                    unsigned long action, void *hcpu)
 {
        unsigned int cpu = (unsigned int)(long)hcpu;
        struct cpu *c = &per_cpu(cpu_devices, cpu);
        struct sys_device *s = &c->sysdev;
+       struct s390_idle_data *idle;
 
        switch (action) {
        case CPU_ONLINE:
        case CPU_ONLINE_FROZEN:
-               if (sysdev_create_file(s, &attr_capability))
+               idle = &per_cpu(s390_idle, cpu);
+               spin_lock_irq(&idle->lock);
+               idle->idle_enter = 0;
+               idle->idle_time = 0;
+               idle->idle_count = 0;
+               spin_unlock_irq(&idle->lock);
+               if (sysfs_create_group(&s->kobj, &cpu_attr_group))
                        return NOTIFY_BAD;
                break;
        case CPU_DEAD:
        case CPU_DEAD_FROZEN:
-               sysdev_remove_file(s, &attr_capability);
+               sysfs_remove_group(&s->kobj, &cpu_attr_group);
                break;
        }
        return NOTIFY_OK;
@@ -784,6 +838,7 @@ static struct notifier_block __cpuinitdata smp_cpu_nb = {
 static int __init topology_init(void)
 {
        int cpu;
+       int rc;
 
        register_cpu_notifier(&smp_cpu_nb);
 
@@ -796,7 +851,9 @@ static int __init topology_init(void)
                if (!cpu_online(cpu))
                        continue;
                s = &c->sysdev;
-               sysdev_create_file(s, &attr_capability);
+               rc = sysfs_create_group(&s->kobj, &cpu_attr_group);
+               if (rc)
+                       return rc;
        }
        return 0;
 }
index 60604b2819b2a0d07c4664860ecb4c462ee92ee1..7e8efaade2ea1196275dd294ec8b48d2748899d3 100644 (file)
 #include <asm/futex.h>
 #include "uaccess.h"
 
+static inline pte_t *follow_table(struct mm_struct *mm, unsigned long addr)
+{
+       pgd_t *pgd;
+       pud_t *pud;
+       pmd_t *pmd;
+
+       pgd = pgd_offset(mm, addr);
+       if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
+               return NULL;
+
+       pud = pud_offset(pgd, addr);
+       if (pud_none(*pud) || unlikely(pud_bad(*pud)))
+               return NULL;
+
+       pmd = pmd_offset(pud, addr);
+       if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
+               return NULL;
+
+       return pte_offset_map(pmd, addr);
+}
+
 static int __handle_fault(struct mm_struct *mm, unsigned long address,
                          int write_access)
 {
@@ -64,7 +85,7 @@ out:
 
 out_of_memory:
        up_read(&mm->mmap_sem);
-       if (is_init(current)) {
+       if (is_global_init(current)) {
                yield();
                down_read(&mm->mmap_sem);
                goto survive;
@@ -85,8 +106,6 @@ static size_t __user_copy_pt(unsigned long uaddr, void *kptr,
 {
        struct mm_struct *mm = current->mm;
        unsigned long offset, pfn, done, size;
-       pgd_t *pgd;
-       pmd_t *pmd;
        pte_t *pte;
        void *from, *to;
 
@@ -94,15 +113,7 @@ static size_t __user_copy_pt(unsigned long uaddr, void *kptr,
 retry:
        spin_lock(&mm->page_table_lock);
        do {
-               pgd = pgd_offset(mm, uaddr);
-               if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
-                       goto fault;
-
-               pmd = pmd_offset(pgd, uaddr);
-               if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
-                       goto fault;
-
-               pte = pte_offset_map(pmd, uaddr);
+               pte = follow_table(mm, uaddr);
                if (!pte || !pte_present(*pte) ||
                    (write_user && !pte_write(*pte)))
                        goto fault;
@@ -142,22 +153,12 @@ static unsigned long __dat_user_addr(unsigned long uaddr)
 {
        struct mm_struct *mm = current->mm;
        unsigned long pfn, ret;
-       pgd_t *pgd;
-       pmd_t *pmd;
        pte_t *pte;
        int rc;
 
        ret = 0;
 retry:
-       pgd = pgd_offset(mm, uaddr);
-       if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
-               goto fault;
-
-       pmd = pmd_offset(pgd, uaddr);
-       if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
-               goto fault;
-
-       pte = pte_offset_map(pmd, uaddr);
+       pte = follow_table(mm, uaddr);
        if (!pte || !pte_present(*pte))
                goto fault;
 
@@ -229,8 +230,6 @@ static size_t strnlen_user_pt(size_t count, const char __user *src)
        unsigned long uaddr = (unsigned long) src;
        struct mm_struct *mm = current->mm;
        unsigned long offset, pfn, done, len;
-       pgd_t *pgd;
-       pmd_t *pmd;
        pte_t *pte;
        size_t len_str;
 
@@ -240,15 +239,7 @@ static size_t strnlen_user_pt(size_t count, const char __user *src)
 retry:
        spin_lock(&mm->page_table_lock);
        do {
-               pgd = pgd_offset(mm, uaddr);
-               if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
-                       goto fault;
-
-               pmd = pmd_offset(pgd, uaddr);
-               if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
-                       goto fault;
-
-               pte = pte_offset_map(pmd, uaddr);
+               pte = follow_table(mm, uaddr);
                if (!pte || !pte_present(*pte))
                        goto fault;
 
@@ -308,8 +299,6 @@ static size_t copy_in_user_pt(size_t n, void __user *to,
                      uaddr, done, size;
        unsigned long uaddr_from = (unsigned long) from;
        unsigned long uaddr_to = (unsigned long) to;
-       pgd_t *pgd_from, *pgd_to;
-       pmd_t *pmd_from, *pmd_to;
        pte_t *pte_from, *pte_to;
        int write_user;
 
@@ -317,39 +306,14 @@ static size_t copy_in_user_pt(size_t n, void __user *to,
 retry:
        spin_lock(&mm->page_table_lock);
        do {
-               pgd_from = pgd_offset(mm, uaddr_from);
-               if (pgd_none(*pgd_from) || unlikely(pgd_bad(*pgd_from))) {
-                       uaddr = uaddr_from;
-                       write_user = 0;
-                       goto fault;
-               }
-               pgd_to = pgd_offset(mm, uaddr_to);
-               if (pgd_none(*pgd_to) || unlikely(pgd_bad(*pgd_to))) {
-                       uaddr = uaddr_to;
-                       write_user = 1;
-                       goto fault;
-               }
-
-               pmd_from = pmd_offset(pgd_from, uaddr_from);
-               if (pmd_none(*pmd_from) || unlikely(pmd_bad(*pmd_from))) {
-                       uaddr = uaddr_from;
-                       write_user = 0;
-                       goto fault;
-               }
-               pmd_to = pmd_offset(pgd_to, uaddr_to);
-               if (pmd_none(*pmd_to) || unlikely(pmd_bad(*pmd_to))) {
-                       uaddr = uaddr_to;
-                       write_user = 1;
-                       goto fault;
-               }
-
-               pte_from = pte_offset_map(pmd_from, uaddr_from);
+               pte_from = follow_table(mm, uaddr_from);
                if (!pte_from || !pte_present(*pte_from)) {
                        uaddr = uaddr_from;
                        write_user = 0;
                        goto fault;
                }
-               pte_to = pte_offset_map(pmd_to, uaddr_to);
+
+               pte_to = follow_table(mm, uaddr_to);
                if (!pte_to || !pte_present(*pte_to) || !pte_write(*pte_to)) {
                        uaddr = uaddr_to;
                        write_user = 1;
index f95449b29fa5229bcb16bdb3dd9262b9121c2f5b..66401930f83e725c4631c23c145c651a6231a7e2 100644 (file)
@@ -2,6 +2,6 @@
 # Makefile for the linux s390-specific parts of the memory manager.
 #
 
-obj-y   := init.o fault.o extmem.o mmap.o vmem.o
+obj-y   := init.o fault.o extmem.o mmap.o vmem.o pgtable.o
 obj-$(CONFIG_CMM) += cmm.o
 
index 14c241ccdd4d9aa47c8697cdb4f9492821c1e224..2456b52ed0687e4ac588fa47ae860cc0973636fa 100644 (file)
@@ -211,7 +211,7 @@ static int do_out_of_memory(struct pt_regs *regs, unsigned long error_code,
        struct mm_struct *mm = tsk->mm;
 
        up_read(&mm->mmap_sem);
-       if (is_init(tsk)) {
+       if (is_global_init(tsk)) {
                yield();
                down_read(&mm->mmap_sem);
                return 1;
index 3a25bbf2eb0ac922fc0010e0336c1ef6ad387538..b234bb4a6da7545d5ab8b5ed7387fb7b3c25b994 100644 (file)
@@ -81,6 +81,7 @@ void show_mem(void)
 static void __init setup_ro_region(void)
 {
        pgd_t *pgd;
+       pud_t *pud;
        pmd_t *pmd;
        pte_t *pte;
        pte_t new_pte;
@@ -91,7 +92,8 @@ static void __init setup_ro_region(void)
 
        for (; address < end; address += PAGE_SIZE) {
                pgd = pgd_offset_k(address);
-               pmd = pmd_offset(pgd, address);
+               pud = pud_offset(pgd, address);
+               pmd = pmd_offset(pud, address);
                pte = pte_offset_kernel(pmd, address);
                new_pte = mk_pte_phys(address, __pgprot(_PAGE_RO));
                *pte = new_pte;
@@ -103,32 +105,28 @@ static void __init setup_ro_region(void)
  */
 void __init paging_init(void)
 {
-       pgd_t *pg_dir;
-       int i;
-       unsigned long pgdir_k;
        static const int ssm_mask = 0x04000000L;
        unsigned long max_zone_pfns[MAX_NR_ZONES];
+       unsigned long pgd_type;
 
-       pg_dir = swapper_pg_dir;
-       
+       init_mm.pgd = swapper_pg_dir;
+       S390_lowcore.kernel_asce = __pa(init_mm.pgd) & PAGE_MASK;
 #ifdef CONFIG_64BIT
-       pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | _KERN_REGION_TABLE;
-       for (i = 0; i < PTRS_PER_PGD; i++)
-               pgd_clear_kernel(pg_dir + i);
+       S390_lowcore.kernel_asce |= _ASCE_TYPE_REGION3 | _ASCE_TABLE_LENGTH;
+       pgd_type = _REGION3_ENTRY_EMPTY;
 #else
-       pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | _KERNSEG_TABLE;
-       for (i = 0; i < PTRS_PER_PGD; i++)
-               pmd_clear_kernel((pmd_t *)(pg_dir + i));
+       S390_lowcore.kernel_asce |= _ASCE_TABLE_LENGTH;
+       pgd_type = _SEGMENT_ENTRY_EMPTY;
 #endif
+       clear_table((unsigned long *) init_mm.pgd, pgd_type,
+                   sizeof(unsigned long)*2048);
        vmem_map_init();
        setup_ro_region();
 
-       S390_lowcore.kernel_asce = pgdir_k;
-
         /* enable virtual mapping in kernel mode */
-       __ctl_load(pgdir_k, 1, 1);
-       __ctl_load(pgdir_k, 7, 7);
-       __ctl_load(pgdir_k, 13, 13);
+       __ctl_load(S390_lowcore.kernel_asce, 1, 1);
+       __ctl_load(S390_lowcore.kernel_asce, 7, 7);
+       __ctl_load(S390_lowcore.kernel_asce, 13, 13);
        __raw_local_irq_ssm(ssm_mask);
 
        memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
new file mode 100644 (file)
index 0000000..e60e0ae
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ *  arch/s390/mm/pgtable.c
+ *
+ *    Copyright IBM Corp. 2007
+ *    Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/smp.h>
+#include <linux/highmem.h>
+#include <linux/slab.h>
+#include <linux/pagemap.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <linux/quicklist.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/tlb.h>
+#include <asm/tlbflush.h>
+
+#ifndef CONFIG_64BIT
+#define ALLOC_ORDER    1
+#else
+#define ALLOC_ORDER    2
+#endif
+
+unsigned long *crst_table_alloc(struct mm_struct *mm, int noexec)
+{
+       struct page *page = alloc_pages(GFP_KERNEL, ALLOC_ORDER);
+
+       if (!page)
+               return NULL;
+       page->index = 0;
+       if (noexec) {
+               struct page *shadow = alloc_pages(GFP_KERNEL, ALLOC_ORDER);
+               if (!shadow) {
+                       __free_pages(page, ALLOC_ORDER);
+                       return NULL;
+               }
+               page->index = page_to_phys(shadow);
+       }
+       return (unsigned long *) page_to_phys(page);
+}
+
+void crst_table_free(unsigned long *table)
+{
+       unsigned long *shadow = get_shadow_table(table);
+
+       if (shadow)
+               free_pages((unsigned long) shadow, ALLOC_ORDER);
+       free_pages((unsigned long) table, ALLOC_ORDER);
+}
+
+/*
+ * page table entry allocation/free routines.
+ */
+unsigned long *page_table_alloc(int noexec)
+{
+       struct page *page = alloc_page(GFP_KERNEL);
+       unsigned long *table;
+
+       if (!page)
+               return NULL;
+       page->index = 0;
+       if (noexec) {
+               struct page *shadow = alloc_page(GFP_KERNEL);
+               if (!shadow) {
+                       __free_page(page);
+                       return NULL;
+               }
+               table = (unsigned long *) page_to_phys(shadow);
+               clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE);
+               page->index = (addr_t) table;
+       }
+       table = (unsigned long *) page_to_phys(page);
+       clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE);
+       return table;
+}
+
+void page_table_free(unsigned long *table)
+{
+       unsigned long *shadow = get_shadow_pte(table);
+
+       if (shadow)
+               free_page((unsigned long) shadow);
+       free_page((unsigned long) table);
+
+}
index fd594d5fe142bed0d1f1f17256ee4f98d617ce14..fb9c5a85aa563b745fafbf096fdd5d239603da8e 100644 (file)
@@ -73,31 +73,28 @@ static void __init_refok *vmem_alloc_pages(unsigned int order)
        return alloc_bootmem_pages((1 << order) * PAGE_SIZE);
 }
 
+#define vmem_pud_alloc()       ({ BUG(); ((pud_t *) NULL); })
+
 static inline pmd_t *vmem_pmd_alloc(void)
 {
-       pmd_t *pmd;
-       int i;
+       pmd_t *pmd = NULL;
 
-       pmd = vmem_alloc_pages(PMD_ALLOC_ORDER);
+#ifdef CONFIG_64BIT
+       pmd = vmem_alloc_pages(2);
        if (!pmd)
                return NULL;
-       for (i = 0; i < PTRS_PER_PMD; i++)
-               pmd_clear_kernel(pmd + i);
+       clear_table((unsigned long *) pmd, _SEGMENT_ENTRY_EMPTY, PAGE_SIZE*4);
+#endif
        return pmd;
 }
 
 static inline pte_t *vmem_pte_alloc(void)
 {
-       pte_t *pte;
-       pte_t empty_pte;
-       int i;
+       pte_t *pte = vmem_alloc_pages(0);
 
-       pte = vmem_alloc_pages(PTE_ALLOC_ORDER);
        if (!pte)
                return NULL;
-       pte_val(empty_pte) = _PAGE_TYPE_EMPTY;
-       for (i = 0; i < PTRS_PER_PTE; i++)
-               pte[i] = empty_pte;
+       clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY, PAGE_SIZE);
        return pte;
 }
 
@@ -108,6 +105,7 @@ static int vmem_add_range(unsigned long start, unsigned long size)
 {
        unsigned long address;
        pgd_t *pg_dir;
+       pud_t *pu_dir;
        pmd_t *pm_dir;
        pte_t *pt_dir;
        pte_t  pte;
@@ -116,13 +114,21 @@ static int vmem_add_range(unsigned long start, unsigned long size)
        for (address = start; address < start + size; address += PAGE_SIZE) {
                pg_dir = pgd_offset_k(address);
                if (pgd_none(*pg_dir)) {
+                       pu_dir = vmem_pud_alloc();
+                       if (!pu_dir)
+                               goto out;
+                       pgd_populate_kernel(&init_mm, pg_dir, pu_dir);
+               }
+
+               pu_dir = pud_offset(pg_dir, address);
+               if (pud_none(*pu_dir)) {
                        pm_dir = vmem_pmd_alloc();
                        if (!pm_dir)
                                goto out;
-                       pgd_populate_kernel(&init_mm, pg_dir, pm_dir);
+                       pud_populate_kernel(&init_mm, pu_dir, pm_dir);
                }
 
-               pm_dir = pmd_offset(pg_dir, address);
+               pm_dir = pmd_offset(pu_dir, address);
                if (pmd_none(*pm_dir)) {
                        pt_dir = vmem_pte_alloc();
                        if (!pt_dir)
@@ -148,6 +154,7 @@ static void vmem_remove_range(unsigned long start, unsigned long size)
 {
        unsigned long address;
        pgd_t *pg_dir;
+       pud_t *pu_dir;
        pmd_t *pm_dir;
        pte_t *pt_dir;
        pte_t  pte;
@@ -155,9 +162,10 @@ static void vmem_remove_range(unsigned long start, unsigned long size)
        pte_val(pte) = _PAGE_TYPE_EMPTY;
        for (address = start; address < start + size; address += PAGE_SIZE) {
                pg_dir = pgd_offset_k(address);
-               if (pgd_none(*pg_dir))
+               pu_dir = pud_offset(pg_dir, address);
+               if (pud_none(*pu_dir))
                        continue;
-               pm_dir = pmd_offset(pg_dir, address);
+               pm_dir = pmd_offset(pu_dir, address);
                if (pmd_none(*pm_dir))
                        continue;
                pt_dir = pte_offset_kernel(pm_dir, address);
@@ -174,6 +182,7 @@ static int vmem_add_mem_map(unsigned long start, unsigned long size)
        unsigned long address, start_addr, end_addr;
        struct page *map_start, *map_end;
        pgd_t *pg_dir;
+       pud_t *pu_dir;
        pmd_t *pm_dir;
        pte_t *pt_dir;
        pte_t  pte;
@@ -188,13 +197,21 @@ static int vmem_add_mem_map(unsigned long start, unsigned long size)
        for (address = start_addr; address < end_addr; address += PAGE_SIZE) {
                pg_dir = pgd_offset_k(address);
                if (pgd_none(*pg_dir)) {
+                       pu_dir = vmem_pud_alloc();
+                       if (!pu_dir)
+                               goto out;
+                       pgd_populate_kernel(&init_mm, pg_dir, pu_dir);
+               }
+
+               pu_dir = pud_offset(pg_dir, address);
+               if (pud_none(*pu_dir)) {
                        pm_dir = vmem_pmd_alloc();
                        if (!pm_dir)
                                goto out;
-                       pgd_populate_kernel(&init_mm, pg_dir, pm_dir);
+                       pud_populate_kernel(&init_mm, pu_dir, pm_dir);
                }
 
-               pm_dir = pmd_offset(pg_dir, address);
+               pm_dir = pmd_offset(pu_dir, address);
                if (pmd_none(*pm_dir)) {
                        pt_dir = vmem_pte_alloc();
                        if (!pt_dir)
diff --git a/arch/s390/oprofile/Kconfig b/arch/s390/oprofile/Kconfig
deleted file mode 100644 (file)
index 208220a..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-
-menu "Profiling support"
-
-config PROFILING
-       bool "Profiling support"
-       help
-         Say Y here to enable profiling support mechanisms used by
-         profilers such as readprofile or OProfile.
-
-
-config OPROFILE
-       tristate "OProfile system profiling"
-       depends on PROFILING
-       help
-         OProfile is a profiling system capable of profiling the
-         whole system, include the kernel, kernel modules, libraries,
-         and applications.
-
-         If unsure, say N.
-
-endmenu
-
index 44982c1dfa23c7adc28b422d8b2d35fa6b6c92b4..247f8a65e7333c585c06566eb4069051327c2c87 100644 (file)
@@ -758,7 +758,7 @@ source "drivers/Kconfig"
 
 source "fs/Kconfig"
 
-source "arch/sh/oprofile/Kconfig"
+source "kernel/Kconfig.instrumentation"
 
 source "arch/sh/Kconfig.debug"
 
index 8143d1b948e7e2b4d33820abba8d5984866c8eaf..d22f6eac9ccabb1816e76e10a0a0263e0c00b69c 100644 (file)
@@ -67,14 +67,14 @@ static int hp6x0_pm_enter(suspend_state_t state)
        return 0;
 }
 
-static struct pm_ops hp6x0_pm_ops = {
+static struct platform_suspend_ops hp6x0_pm_ops = {
        .enter          = hp6x0_pm_enter,
-       .valid          = pm_valid_only_mem,
+       .valid          = suspend_valid_only_mem,
 };
 
 static int __init hp6x0_pm_init(void)
 {
-       pm_set_ops(&hp6x0_pm_ops);
+       suspend_set_ops(&hp6x0_pm_ops);
        return 0;
 }
 
index 790ed69b866670de9f5ac6d63890f740e694ff8e..5c17de51987e59eed62b937e601372b824b7bc4e 100644 (file)
@@ -104,24 +104,3 @@ NORET_TYPE void machine_kexec(struct kimage *image)
        (*rnk)(page_list, reboot_code_buffer, image->start, vbr_reg);
 }
 
-/* crashkernel=size@addr specifies the location to reserve for
- * a crash kernel.  By reserving this memory we guarantee
- * that linux never sets it up as a DMA target.
- * Useful for holding code to do something appropriate
- * after a kernel panic.
- */
-static int __init parse_crashkernel(char *arg)
-{
-       unsigned long size, base;
-       size = memparse(arg, &arg);
-       if (*arg == '@') {
-               base = memparse(arg+1, &arg);
-               /* FIXME: Do I want a sanity check
-                * to validate the memory range?
-                */
-               crashk_res.start = base;
-               crashk_res.end   = base + size - 1;
-       }
-       return 0;
-}
-early_param("crashkernel", parse_crashkernel);
index b4469992d6b25aafab1e8fcc1f2cd089bee5f9e0..6d7f2b07e4917ee8ff7e25b7ca01bad63ff0f311 100644 (file)
@@ -121,7 +121,7 @@ void machine_power_off(void)
 void show_regs(struct pt_regs * regs)
 {
        printk("\n");
-       printk("Pid : %d, Comm: %20s\n", current->pid, current->comm);
+       printk("Pid : %d, Comm: %20s\n", task_pid_nr(current), current->comm);
        print_symbol("PC is at %s\n", instruction_pointer(regs));
        printk("PC  : %08lx SP  : %08lx SR  : %08lx ",
               regs->pc, regs->regs[15], regs->sr);
index b3027a6775b91106d8b5b61c85fb5ed0bbb8c5d1..b749403f6b382fe3c4108be924e5caa5e10afe80 100644 (file)
@@ -128,6 +128,37 @@ static void __init register_bootmem_low_pages(void)
        free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(pages));
 }
 
+#ifdef CONFIG_KEXEC
+static void __init reserve_crashkernel(void)
+{
+       unsigned long long free_mem;
+       unsigned long long crash_size, crash_base;
+       int ret;
+
+       free_mem = ((unsigned long long)max_low_pfn - min_low_pfn) << PAGE_SHIFT;
+
+       ret = parse_crashkernel(boot_command_line, free_mem,
+                       &crash_size, &crash_base);
+       if (ret == 0 && crash_size) {
+               if (crash_base > 0) {
+                       printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
+                                       "for crashkernel (System RAM: %ldMB)\n",
+                                       (unsigned long)(crash_size >> 20),
+                                       (unsigned long)(crash_base >> 20),
+                                       (unsigned long)(free_mem >> 20));
+                       crashk_res.start = crash_base;
+                       crashk_res.end   = crash_base + crash_size - 1;
+                       reserve_bootmem(crash_base, crash_size);
+               } else
+                       printk(KERN_INFO "crashkernel reservation failed - "
+                                       "you have to specify a base address\n");
+       }
+}
+#else
+static inline void __init reserve_crashkernel(void)
+{}
+#endif
+
 void __init setup_bootmem_allocator(unsigned long free_pfn)
 {
        unsigned long bootmap_size;
@@ -189,11 +220,8 @@ void __init setup_bootmem_allocator(unsigned long free_pfn)
                }
        }
 #endif
-#ifdef CONFIG_KEXEC
-       if (crashk_res.start != crashk_res.end)
-               reserve_bootmem(crashk_res.start,
-                       crashk_res.end - crashk_res.start + 1);
-#endif
+
+       reserve_crashkernel();
 }
 
 #ifndef CONFIG_NEED_MULTIPLE_NODES
index 2f42442cf164e9d6921b22bec246596304d3d640..ca754fd4243734eed9d80ea90266f528c7469d6e 100644 (file)
@@ -382,7 +382,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
        set_fs(USER_DS);
 
        pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n",
-                current->comm, current->pid, frame, regs->pc, regs->pr);
+                current->comm, task_pid_nr(current), frame, regs->pc, regs->pr);
 
        flush_cache_sigtramp(regs->pr);
 
@@ -462,7 +462,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        set_fs(USER_DS);
 
        pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n",
-                current->comm, current->pid, frame, regs->pc, regs->pr);
+                current->comm, task_pid_nr(current), frame, regs->pc, regs->pr);
 
        flush_cache_sigtramp(regs->pr);
 
index dcb46e71da1c6d23217c6d22a5221ff59a931ff6..cf99111cb33fd0a2d370dd62e2de694782cc2901 100644 (file)
@@ -95,8 +95,8 @@ void die(const char * str, struct pt_regs * regs, long err)
        print_modules();
        show_regs(regs);
 
-       printk("Process: %s (pid: %d, stack limit = %p)\n",
-              current->comm, current->pid, task_stack_page(current) + 1);
+       printk("Process: %s (pid: %d, stack limit = %p)\n", current->comm,
+                       task_pid_nr(current), task_stack_page(current) + 1);
 
        if (!user_mode(regs) || in_interrupt())
                dump_mem("Stack: ", regs->regs[15], THREAD_SIZE +
@@ -386,7 +386,8 @@ static int handle_unaligned_access(u16 instruction, struct pt_regs *regs)
 
                printk(KERN_NOTICE "Fixing up unaligned userspace access "
                       "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
-                      current->comm,current->pid,(u16*)regs->pc,instruction);
+                      current->comm, task_pid_nr(current),
+                      (u16 *)regs->pc, instruction);
        }
 
        ret = -EFAULT;
index 4729668ce5bf3b4ca261d689906ed14db30e01e5..f33cedb353fc6af215bc7f86b37120553d8e7532 100644 (file)
@@ -207,7 +207,7 @@ no_context:
  */
 out_of_memory:
        up_read(&mm->mmap_sem);
-       if (is_init(current)) {
+       if (is_global_init(current)) {
                yield();
                down_read(&mm->mmap_sem);
                goto survive;
diff --git a/arch/sh/oprofile/Kconfig b/arch/sh/oprofile/Kconfig
deleted file mode 100644 (file)
index 5ade198..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-
-menu "Profiling support"
-       depends on EXPERIMENTAL
-
-config PROFILING
-       bool "Profiling support (EXPERIMENTAL)"
-       help
-         Say Y here to enable the extended profiling support mechanisms used
-         by profilers such as OProfile.
-         
-
-config OPROFILE
-       tristate "OProfile system profiling (EXPERIMENTAL)"
-       depends on PROFILING
-       help
-         OProfile is a profiling system capable of profiling the
-         whole system, include the kernel, kernel modules, libraries,
-         and applications.
-
-         If unsure, say N.
-
-endmenu
-
index b3327ce8e82f464f2cf81adf92c8f8e30d571d0c..ba204bac49dfa32536ff8561821f2cc3a5ffc2cb 100644 (file)
@@ -284,7 +284,7 @@ source "drivers/Kconfig"
 
 source "fs/Kconfig"
 
-source "arch/sh64/oprofile/Kconfig"
+source "kernel/Kconfig.instrumentation"
 
 source "arch/sh64/Kconfig.debug"
 
index 388bb711f1b02ec0c46dac25723dfee1fa3a95df..b4d9534d2b0eb3861e1331299778a53e0605140d 100644 (file)
@@ -480,7 +480,7 @@ static int __init pcibios_init(void)
                 return -EINVAL;
         }
 
-       /* The pci subsytem needs to know where memory is and how much
+       /* The pci subsystem needs to know where memory is and how much
         * of it there is. I've simply made these globals. A better mechanism
         * is probably needed.
         */
index 9d0d58fb29fae75f8bb45f73e5a2a22c044052ea..c03101fab467443a8b6d33e9cf0111d4d48972cb 100644 (file)
@@ -764,7 +764,7 @@ static int misaligned_fixup(struct pt_regs *regs)
                --user_mode_unaligned_fixup_count;
                /* Only do 'count' worth of these reports, to remove a potential DoS against syslog */
                printk("Fixing up unaligned userspace access in \"%s\" pid=%d pc=0x%08x ins=0x%08lx\n",
-                      current->comm, current->pid, (__u32)regs->pc, opcode);
+                      current->comm, task_pid_nr(current), (__u32)regs->pc, opcode);
        } else
 #endif
        if (!user_mode(regs) && (kernel_mode_unaligned_fixup_count > 0)) {
@@ -774,7 +774,7 @@ static int misaligned_fixup(struct pt_regs *regs)
                               (__u32)regs->pc, opcode);
                } else {
                        printk("Fixing up unaligned kernelspace access in \"%s\" pid=%d pc=0x%08x ins=0x%08lx\n",
-                              current->comm, current->pid, (__u32)regs->pc, opcode);
+                              current->comm, task_pid_nr(current), (__u32)regs->pc, opcode);
                }
        }
 
index dd81c669c79b5b63df7c52447f320c96d8a15dd4..7c79a1ba8059347bd583913df653bbaea301535d 100644 (file)
@@ -81,7 +81,7 @@ static inline void print_vma(struct vm_area_struct *vma)
 
 static inline void print_task(struct task_struct *tsk)
 {
-       printk("Task pid %d\n", tsk->pid);
+       printk("Task pid %d\n", task_pid_nr(tsk));
 }
 
 static pte_t *lookup_pte(struct mm_struct *mm, unsigned long address)
@@ -272,13 +272,13 @@ bad_area:
                         * usermode, so only need a few */
                        count++;
                        printk("user mode bad_area address=%08lx pid=%d (%s) pc=%08lx\n",
-                               address, current->pid, current->comm,
+                               address, task_pid_nr(current), current->comm,
                                (unsigned long) regs->pc);
 #if 0
                        show_regs(regs);
 #endif
                }
-               if (is_init(tsk)) {
+               if (is_global_init(tsk)) {
                        panic("INIT had user mode bad_area\n");
                }
                tsk->thread.address = address;
@@ -320,14 +320,14 @@ no_context:
  * us unable to handle the page fault gracefully.
  */
 out_of_memory:
-       if (is_init(current)) {
+       if (is_global_init(current)) {
                panic("INIT out of memory\n");
                yield();
                goto survive;
        }
        printk("fault:Out of memory\n");
        up_read(&mm->mmap_sem);
-       if (is_init(current)) {
+       if (is_global_init(current)) {
                yield();
                down_read(&mm->mmap_sem);
                goto survive;
diff --git a/arch/sh64/oprofile/Kconfig b/arch/sh64/oprofile/Kconfig
deleted file mode 100644 (file)
index 19d3773..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-
-menu "Profiling support"
-       depends on EXPERIMENTAL
-
-config PROFILING
-       bool "Profiling support (EXPERIMENTAL)"
-       help
-         Say Y here to enable the extended profiling support mechanisms used
-         by profilers such as OProfile.
-
-
-config OPROFILE
-       tristate "OProfile system profiling (EXPERIMENTAL)"
-       depends on PROFILING
-       help
-         OProfile is a profiling system capable of profiling the
-         whole system, include the kernel, kernel modules, libraries,
-         and applications.
-
-         If unsure, say N.
-
-endmenu
-
index c0f4ba109daab7ef41e302d46de488fa29aa622b..527adc808ad6c8609bc81581d49bcceec1ceb0aa 100644 (file)
@@ -320,11 +320,7 @@ endmenu
 
 source "fs/Kconfig"
 
-menu "Instrumentation Support"
-
-source "arch/sparc/oprofile/Kconfig"
-
-endmenu
+source "kernel/Kconfig.instrumentation"
 
 source "arch/sparc/Kconfig.debug"
 
index 9c3ed88853f3d491d09575392bdb8163eb72eef0..97aa50d1e4ae053c2d61776d5880c820a2d38635 100644 (file)
@@ -727,9 +727,8 @@ int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents,
        BUG_ON(direction == PCI_DMA_NONE);
        /* IIep is write-through, not flushing. */
        for_each_sg(sgl, sg, nents, n) {
-               BUG_ON(page_address(sg->page) == NULL);
-               sg->dvma_address =
-                       virt_to_phys(page_address(sg->page)) + sg->offset;
+               BUG_ON(page_address(sg_page(sg)) == NULL);
+               sg->dvma_address = virt_to_phys(sg_virt(sg));
                sg->dvma_length = sg->length;
        }
        return nents;
@@ -748,9 +747,9 @@ void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents,
        BUG_ON(direction == PCI_DMA_NONE);
        if (direction != PCI_DMA_TODEVICE) {
                for_each_sg(sgl, sg, nents, n) {
-                       BUG_ON(page_address(sg->page) == NULL);
+                       BUG_ON(page_address(sg_page(sg)) == NULL);
                        mmu_inval_dma_area(
-                           (unsigned long) page_address(sg->page),
+                           (unsigned long) page_address(sg_page(sg)),
                            (sg->length + PAGE_SIZE-1) & PAGE_MASK);
                }
        }
@@ -798,9 +797,9 @@ void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sgl, int
        BUG_ON(direction == PCI_DMA_NONE);
        if (direction != PCI_DMA_TODEVICE) {
                for_each_sg(sgl, sg, nents, n) {
-                       BUG_ON(page_address(sg->page) == NULL);
+                       BUG_ON(page_address(sg_page(sg)) == NULL);
                        mmu_inval_dma_area(
-                           (unsigned long) page_address(sg->page),
+                           (unsigned long) page_address(sg_page(sg)),
                            (sg->length + PAGE_SIZE-1) & PAGE_MASK);
                }
        }
@@ -814,9 +813,9 @@ void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sgl,
        BUG_ON(direction == PCI_DMA_NONE);
        if (direction != PCI_DMA_TODEVICE) {
                for_each_sg(sgl, sg, nents, n) {
-                       BUG_ON(page_address(sg->page) == NULL);
+                       BUG_ON(page_address(sg_page(sg)) == NULL);
                        mmu_inval_dma_area(
-                           (unsigned long) page_address(sg->page),
+                           (unsigned long) page_address(sg_page(sg)),
                            (sg->length + PAGE_SIZE-1) & PAGE_MASK);
                }
        }
index fb2caef79cec407f0e36497567902c88c88b2418..3ea000d15e3a29b8d7273e7aad0e53667356e5df 100644 (file)
@@ -585,24 +585,6 @@ static int __init of_debug(char *str)
 
 __setup("of_debug=", of_debug);
 
-int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus)
-{
-       /* initialize common driver fields */
-       if (!drv->driver.name)
-               drv->driver.name = drv->name;
-       if (!drv->driver.owner)
-               drv->driver.owner = drv->owner;
-       drv->driver.bus = bus;
-
-       /* register with core */
-       return driver_register(&drv->driver);
-}
-
-void of_unregister_driver(struct of_platform_driver *drv)
-{
-       driver_unregister(&drv->driver);
-}
-
 struct of_device* of_platform_device_create(struct device_node *np,
                                            const char *bus_id,
                                            struct device *parent,
@@ -628,6 +610,4 @@ struct of_device* of_platform_device_create(struct device_node *np,
        return dev;
 }
 
-EXPORT_SYMBOL(of_register_driver);
-EXPORT_SYMBOL(of_unregister_driver);
 EXPORT_SYMBOL(of_platform_device_create);
index 003f8eed32f413e8ba835bdcfea2e16d703789c5..fe562db475e9c454c42d930d9f64808410aa392c 100644 (file)
@@ -155,7 +155,7 @@ static inline void read_sunos_user(struct pt_regs *regs, unsigned long offset,
                /* Rest of them are completely unsupported. */
        default:
                printk("%s [%d]: Wants to read user offset %ld\n",
-                      current->comm, current->pid, offset);
+                      current->comm, task_pid_nr(current), offset);
                pt_error_return(regs, EIO);
                return;
        }
@@ -222,7 +222,7 @@ static inline void write_sunos_user(struct pt_regs *regs, unsigned long offset,
                /* Rest of them are completely unsupported or "no-touch". */
        default:
                printk("%s [%d]: Wants to write user offset %ld\n",
-                      current->comm, current->pid, offset);
+                      current->comm, task_pid_nr(current), offset);
                goto failure;
        }
 success:
index 6c0221e9a9f5a8abafefa9f8e26aa55e0c068b5c..42bf09db9a81ffaa11972289daffcb884fa22225 100644 (file)
@@ -357,7 +357,7 @@ c_sys_nis_syscall (struct pt_regs *regs)
        if (count++ > 5)
                return -ENOSYS;
        printk ("%s[%d]: Unimplemented SPARC system call %d\n",
-               current->comm, current->pid, (int)regs->u_regs[1]);
+               current->comm, task_pid_nr(current), (int)regs->u_regs[1]);
 #ifdef DEBUG_UNIMP_SYSCALL     
        show_regs (regs);
 #endif
index f807172cab0ea139d07ea70fb7c1e795708e013b..28c187c5d9fd68dc4eea2008fa253d63d8e0b9d8 100644 (file)
@@ -866,7 +866,7 @@ asmlinkage int sunos_killpg(int pgrp, int sig)
        rcu_read_lock();
        ret = -EINVAL;
        if (pgrp > 0)
-               ret = kill_pgrp(find_pid(pgrp), sig, 0);
+               ret = kill_pgrp(find_vpid(pgrp), sig, 0);
        rcu_read_unlock();
 
        return ret;
index 3bc3bff51e08d284d376dbe061457db053111367..d404e7994527760cb6129654726ff4cd44ab145d 100644 (file)
@@ -38,7 +38,7 @@ struct trap_trace_entry trapbuf[1024];
 
 void syscall_trace_entry(struct pt_regs *regs)
 {
-       printk("%s[%d]: ", current->comm, current->pid);
+       printk("%s[%d]: ", current->comm, task_pid_nr(current));
        printk("scall<%d> (could be %d)\n", (int) regs->u_regs[UREG_G1],
               (int) regs->u_regs[UREG_I0]);
 }
@@ -99,7 +99,7 @@ void die_if_kernel(char *str, struct pt_regs *regs)
 "              /_| \\__/ |_\\\n"
 "                 \\__U_/\n");
 
-       printk("%s(%d): %s [#%d]\n", current->comm, current->pid, str, ++die_counter);
+       printk("%s(%d): %s [#%d]\n", current->comm, task_pid_nr(current), str, ++die_counter);
        show_regs(regs);
        add_taint(TAINT_DIE);
 
index 375b4db637046964afa002d700837da448d6674d..1666087c5b80e751587785046b848a1697563a35 100644 (file)
@@ -144,7 +144,7 @@ static void iounit_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus
        spin_lock_irqsave(&iounit->lock, flags);
        while (sz != 0) {
                --sz;
-               sg->dvma_address = iounit_get_area(iounit, (unsigned long)page_address(sg->page) + sg->offset, sg->length);
+               sg->dvma_address = iounit_get_area(iounit, sg_virt(sg), sg->length);
                sg->dvma_length = sg->length;
                sg = sg_next(sg);
        }
index 283656d9f6ea77ae5241ea4677b05c47c5080706..4b934270f05e062c0a3c1519b3e9a1c1a51b3632 100644 (file)
@@ -238,7 +238,7 @@ static void iommu_get_scsi_sgl_noflush(struct scatterlist *sg, int sz, struct sb
        while (sz != 0) {
                --sz;
                n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
-               sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset;
+               sg->dvma_address = iommu_get_one(sg_page(sg), n, sbus) + sg->offset;
                sg->dvma_length = (__u32) sg->length;
                sg = sg_next(sg);
        }
@@ -252,7 +252,7 @@ static void iommu_get_scsi_sgl_gflush(struct scatterlist *sg, int sz, struct sbu
        while (sz != 0) {
                --sz;
                n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
-               sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset;
+               sg->dvma_address = iommu_get_one(sg_page(sg), n, sbus) + sg->offset;
                sg->dvma_length = (__u32) sg->length;
                sg = sg_next(sg);
        }
@@ -273,7 +273,7 @@ static void iommu_get_scsi_sgl_pflush(struct scatterlist *sg, int sz, struct sbu
                 * XXX Is this a good assumption?
                 * XXX What if someone else unmaps it here and races us?
                 */
-               if ((page = (unsigned long) page_address(sg->page)) != 0) {
+               if ((page = (unsigned long) page_address(sg_page(sg))) != 0) {
                        for (i = 0; i < n; i++) {
                                if (page != oldpage) {  /* Already flushed? */
                                        flush_page_for_dma(page);
@@ -283,7 +283,7 @@ static void iommu_get_scsi_sgl_pflush(struct scatterlist *sg, int sz, struct sbu
                        }
                }
 
-               sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset;
+               sg->dvma_address = iommu_get_one(sg_page(sg), n, sbus) + sg->offset;
                sg->dvma_length = (__u32) sg->length;
                sg = sg_next(sg);
        }
index ee6708fc4492476b2d28ed7293a8fbde47c5cd94..a2cc141291c72a0a22c93b762848a888677e7d1b 100644 (file)
@@ -1228,7 +1228,7 @@ static void sun4c_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *
 {
        while (sz != 0) {
                --sz;
-               sg->dvma_address = (__u32)sun4c_lockarea(page_address(sg->page) + sg->offset, sg->length);
+               sg->dvma_address = (__u32)sun4c_lockarea(sg_virt(sg), sg->length);
                sg->dvma_length = sg->length;
                sg = sg_next(sg);
        }
diff --git a/arch/sparc/oprofile/Kconfig b/arch/sparc/oprofile/Kconfig
deleted file mode 100644 (file)
index d8a8408..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-config PROFILING
-       bool "Profiling support (EXPERIMENTAL)"
-       help
-         Say Y here to enable the extended profiling support mechanisms used
-         by profilers such as OProfile.
-         
-
-config OPROFILE
-       tristate "OProfile system profiling (EXPERIMENTAL)"
-       depends on PROFILING
-       help
-         OProfile is a profiling system capable of profiling the
-         whole system, include the kernel, kernel modules, libraries,
-         and applications.
-
-         If unsure, say N.
-
index 59c4d752d286d5638e02e9e82e190c2b56457074..03c4e5c1b94a5ae3f6cda7c836b40ffee60ff127 100644 (file)
@@ -72,6 +72,10 @@ config ARCH_NO_VIRT_TO_BUS
 config OF
        def_bool y
 
+config GENERIC_HARDIRQS_NO__DO_IRQ
+       bool
+       def_bool y
+
 choice
        prompt "Kernel page size"
        default SPARC64_PAGE_SIZE_8KB
@@ -460,20 +464,7 @@ source "drivers/fc4/Kconfig"
 
 source "fs/Kconfig"
 
-menu "Instrumentation Support"
-
-source "arch/sparc64/oprofile/Kconfig"
-
-config KPROBES
-       bool "Kprobes (EXPERIMENTAL)"
-       depends on KALLSYMS && EXPERIMENTAL && MODULES
-       help
-         Kprobes allows you to trap at almost any kernel address and
-         execute a callback function.  register_kprobe() establishes
-         a probepoint and specifies the callback.  Kprobes is useful
-         for kernel debugging, non-intrusive instrumentation and testing.
-         If in doubt, say "N".
-endmenu
+source "kernel/Kconfig.instrumentation"
 
 source "arch/sparc64/Kconfig.debug"
 
index 6c92a42efe76430ca9f2efa82398a16f2973f4ab..01159cb5f16d4d9878206027f391c45fa24f2a20 100644 (file)
@@ -18,8 +18,6 @@ NEW_GCC := $(call cc-option-yn, -m64 -mcmodel=medlow)
 NEW_GAS := $(shell if $(LD) -V 2>&1 | grep 'elf64_sparc' > /dev/null; then echo y; else echo n; fi)
 UNDECLARED_REGS := $(shell if $(CC) -c -x assembler /dev/null -Wa,--help | grep undeclared-regs > /dev/null; then echo y; else echo n; fi; )
 
-export NEW_GCC
-
 ifneq ($(NEW_GAS),y)
 AS             = sparc64-linux-as
 LD             = sparc64-linux-ld
@@ -58,8 +56,6 @@ core-y                                += arch/sparc64/kernel/ arch/sparc64/mm/
 core-$(CONFIG_SOLARIS_EMUL)    += arch/sparc64/solaris/
 core-y                         += arch/sparc64/math-emu/
 libs-y                         += arch/sparc64/prom/ arch/sparc64/lib/
-
-# FIXME: is drivers- right?
 drivers-$(CONFIG_OPROFILE)     += arch/sparc64/oprofile/
 
 boot := arch/sparc64/boot
index 1aa2c4048e4bd19700260aa6167e21440a7b2916..e023d4b2fef4c11fa49476c7f07f6d18e49c627d 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.23
-# Sat Oct 13 21:53:54 2007
+# Sun Oct 21 19:57:44 2007
 #
 CONFIG_SPARC=y
 CONFIG_SPARC64=y
@@ -49,6 +49,10 @@ CONFIG_POSIX_MQUEUE=y
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=18
+# CONFIG_CGROUPS is not set
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
+# CONFIG_FAIR_CGROUP_SCHED is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
 # CONFIG_BLK_DEV_INITRD is not set
@@ -145,7 +149,10 @@ CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_SPARSEMEM_MANUAL=y
 CONFIG_SPARSEMEM=y
 CONFIG_HAVE_MEMORY_PRESENT=y
-CONFIG_SPARSEMEM_STATIC=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
+CONFIG_SPARSEMEM_VMEMMAP=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_RESOURCES_64BIT=y
 CONFIG_ZONE_DMA_FLAG=0
@@ -275,10 +282,6 @@ CONFIG_VLAN_8021Q=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
 
 #
@@ -372,8 +375,6 @@ CONFIG_IDEPCI_PCIBUS_ORDER=y
 # CONFIG_BLK_DEV_GENERIC is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
 CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-CONFIG_IDEDMA_ONLYDISK=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 CONFIG_BLK_DEV_ALI15X3=y
 # CONFIG_WDC_ALI15X3 is not set
@@ -401,6 +402,7 @@ CONFIG_BLK_DEV_ALI15X3=y
 # CONFIG_BLK_DEV_TC86C001 is not set
 # CONFIG_IDE_ARM is not set
 CONFIG_BLK_DEV_IDEDMA=y
+CONFIG_IDE_ARCH_OBSOLETE_INIT=y
 # CONFIG_BLK_DEV_HD is not set
 
 #
@@ -441,6 +443,7 @@ CONFIG_SCSI_FC_ATTRS=y
 CONFIG_SCSI_ISCSI_ATTRS=m
 # CONFIG_SCSI_SAS_ATTRS is not set
 # CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
 CONFIG_SCSI_LOWLEVEL=y
 CONFIG_ISCSI_TCP=m
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
@@ -492,14 +495,8 @@ CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 # CONFIG_DM_MULTIPATH is not set
 # CONFIG_DM_DELAY is not set
-
-#
-# Fusion MPT device support
-#
+# CONFIG_DM_UEVENT is not set
 # 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
@@ -638,7 +635,6 @@ 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_TSDEV is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_EVBUG is not set
 
@@ -714,11 +710,9 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
 # 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
@@ -786,8 +780,6 @@ CONFIG_I2C_ALGOBIT=y
 # CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_ABITUGURU is not set
-# CONFIG_SENSORS_ABITUGURU3 is not set
 # CONFIG_SENSORS_AD7418 is not set
 # CONFIG_SENSORS_ADM1021 is not set
 # CONFIG_SENSORS_ADM1025 is not set
@@ -795,12 +787,12 @@ CONFIG_HWMON=y
 # 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_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_FSCPOS 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
@@ -836,6 +828,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_WATCHDOG is not set
 
 #
 # Sonics Silicon Backplane
@@ -858,12 +851,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Graphics support
 #
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Display device 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=y
@@ -872,6 +860,7 @@ CONFIG_FB_DDC=y
 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
@@ -890,6 +879,7 @@ CONFIG_FB_TILEBLITTING=y
 # CONFIG_FB_PM2 is not set
 # CONFIG_FB_ASILIANT is not set
 # CONFIG_FB_IMSTT is not set
+# CONFIG_FB_UVESA is not set
 # CONFIG_FB_SBUS is not set
 # CONFIG_FB_XVR500 is not set
 # CONFIG_FB_XVR2500 is not set
@@ -915,6 +905,12 @@ CONFIG_FB_RADEON_I2C=y
 # CONFIG_FB_ARK is not set
 # CONFIG_FB_PM3 is not set
 # CONFIG_FB_VIRTUAL is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
 
 #
 # Console display driver support
@@ -1066,6 +1062,7 @@ CONFIG_AC97_BUS=m
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
 # CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
 
 #
 # USB Input Devices
@@ -1186,19 +1183,6 @@ CONFIG_USB_STORAGE=m
 # CONFIG_INFINIBAND is not set
 # CONFIG_RTC_CLASS is not set
 
-#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
 #
 # Userspace I/O
 #
@@ -1275,7 +1259,6 @@ 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
 
 #
@@ -1295,10 +1278,7 @@ CONFIG_RAMFS=y
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 # CONFIG_NFS_FS is not set
 # CONFIG_NFSD is not set
 # CONFIG_SMB_FS is not set
@@ -1313,10 +1293,6 @@ CONFIG_RAMFS=y
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
 CONFIG_SUN_PARTITION=y
-
-#
-# Native Language Support
-#
 CONFIG_NLS=m
 CONFIG_NLS_DEFAULT="iso8859-1"
 # CONFIG_NLS_CODEPAGE_437 is not set
@@ -1357,18 +1333,12 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # CONFIG_NLS_KOI8_R is not set
 # CONFIG_NLS_KOI8_U is not set
 # CONFIG_NLS_UTF8 is not set
-
-#
-# Distributed Lock Manager
-#
 # CONFIG_DLM is not set
-
-#
-# Instrumentation Support
-#
+CONFIG_INSTRUMENTATION=y
 CONFIG_PROFILING=y
 CONFIG_OPROFILE=m
 CONFIG_KPROBES=y
+# CONFIG_MARKERS is not set
 
 #
 # Kernel hacking
@@ -1402,9 +1372,11 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_LIST is not set
 CONFIG_FORCED_INLINING=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_SAMPLES is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_DEBUG_DCFLUSH is not set
 # CONFIG_STACK_DEBUG is not set
@@ -1417,6 +1389,7 @@ CONFIG_FORCED_INLINING=y
 CONFIG_KEYS=y
 # CONFIG_KEYS_DEBUG_PROC_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_XOR_BLOCKS=m
 CONFIG_ASYNC_CORE=m
 CONFIG_ASYNC_MEMCPY=m
index 112c46e6657834d4fd159ea9f3683614ce57238d..ef50d217432f151f1ab3ed6e701d3ed2281c9afd 100644 (file)
@@ -39,12 +39,3 @@ else
     obj-y += sys_sunos32.o sunos_ioctl32.o
   endif
 endif
-
-ifneq ($(NEW_GCC),y)
-  CMODEL_CFLAG := -mmedlow
-else
-  CMODEL_CFLAG := -m64 -mcmodel=medlow
-endif
-
-head.o: head.S ttable.S itlb_miss.S dtlb_miss.S ktlb.S tsb.S \
-       etrap.S rtrap.S winfixup.S entry.S
index 29af777d7ac920d138d9c8e7598f5fbd0d14a3de..070a4846c0cb7d7dcb06be192bcd8879733f5112 100644 (file)
@@ -472,8 +472,7 @@ static void dma_4u_unmap_single(struct device *dev, dma_addr_t bus_addr,
        spin_unlock_irqrestore(&iommu->lock, flags);
 }
 
-#define SG_ENT_PHYS_ADDRESS(SG)        \
-       (__pa(page_address((SG)->page)) + (SG)->offset)
+#define SG_ENT_PHYS_ADDRESS(SG)        (__pa(sg_virt((SG))))
 
 static void fill_sg(iopte_t *iopte, struct scatterlist *sg,
                    int nused, int nelems,
@@ -565,9 +564,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
        /* Fast path single entry scatterlists. */
        if (nelems == 1) {
                sglist->dma_address =
-                       dma_4u_map_single(dev,
-                                         (page_address(sglist->page) +
-                                          sglist->offset),
+                       dma_4u_map_single(dev, sg_virt(sglist),
                                          sglist->length, direction);
                if (unlikely(sglist->dma_address == DMA_ERROR_CODE))
                        return 0;
index d7ca900ec51d31e1ceaae922c68bdb8327914bf9..b70324e0d83d8979f7aa65857f387fa47ebb63d5 100644 (file)
@@ -73,7 +73,7 @@ static int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg,
 
        daddr = dma_sg->dma_address;
        sglen = sg->length;
-       sgaddr = (unsigned long) (page_address(sg->page) + sg->offset);
+       sgaddr = (unsigned long) sg_virt(sg);
        while (dlen > 0) {
                unsigned long paddr;
 
@@ -123,7 +123,7 @@ static int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg,
                sg = sg_next(sg);
                if (--nents <= 0)
                        break;
-               sgaddr = (unsigned long) (page_address(sg->page) + sg->offset);
+               sgaddr = (unsigned long) sg_virt(sg);
                sglen = sg->length;
        }
        if (dlen < 0) {
@@ -191,7 +191,7 @@ void verify_sglist(struct scatterlist *sglist, int nents, iopte_t *iopte, int np
                        printk("sg(%d): page_addr(%p) off(%x) length(%x) "
                               "dma_address[%016x] dma_length[%016x]\n",
                               i,
-                              page_address(sg->page), sg->offset,
+                              page_address(sg_page(sg)), sg->offset,
                               sg->length,
                               sg->dma_address, sg->dma_length);
                }
@@ -207,15 +207,14 @@ unsigned long prepare_sg(struct scatterlist *sg, int nents)
        unsigned long prev;
        u32 dent_addr, dent_len;
 
-       prev  = (unsigned long) (page_address(sg->page) + sg->offset);
+       prev  = (unsigned long) sg_virt(sg);
        prev += (unsigned long) (dent_len = sg->length);
-       dent_addr = (u32) ((unsigned long)(page_address(sg->page) + sg->offset)
-                          & (IO_PAGE_SIZE - 1UL));
+       dent_addr = (u32) ((unsigned long)(sg_virt(sg)) & (IO_PAGE_SIZE - 1UL));
        while (--nents) {
                unsigned long addr;
 
                sg = sg_next(sg);
-               addr = (unsigned long) (page_address(sg->page) + sg->offset);
+               addr = (unsigned long) sg_virt(sg);
                if (! VCONTIG(prev, addr)) {
                        dma_sg->dma_address = dent_addr;
                        dma_sg->dma_length = dent_len;
@@ -234,6 +233,11 @@ unsigned long prepare_sg(struct scatterlist *sg, int nents)
        dma_sg->dma_address = dent_addr;
        dma_sg->dma_length = dent_len;
 
+       if (dma_sg != sg) {
+               dma_sg = next_sg(dma_sg);
+               dma_sg->dma_length = 0;
+       }
+
        return ((unsigned long) dent_addr +
                (unsigned long) dent_len +
                (IO_PAGE_SIZE - 1UL)) >> IO_PAGE_SHIFT;
index f3922e5a89f6c52330b5d6b1cf9ed23353bafba5..30431bd24e1efbe7ea2153043d2d06605433febe 100644 (file)
@@ -257,8 +257,8 @@ struct irq_handler_data {
        unsigned long   imap;
 
        void            (*pre_handler)(unsigned int, void *, void *);
-       void            *pre_handler_arg1;
-       void            *pre_handler_arg2;
+       void            *arg1;
+       void            *arg2;
 };
 
 #ifdef CONFIG_SMP
@@ -346,7 +346,7 @@ static void sun4u_irq_disable(unsigned int virt_irq)
        }
 }
 
-static void sun4u_irq_end(unsigned int virt_irq)
+static void sun4u_irq_eoi(unsigned int virt_irq)
 {
        struct irq_handler_data *data = get_irq_chip_data(virt_irq);
        struct irq_desc *desc = irq_desc + virt_irq;
@@ -401,7 +401,7 @@ static void sun4v_irq_disable(unsigned int virt_irq)
                       "err(%d)\n", ino, err);
 }
 
-static void sun4v_irq_end(unsigned int virt_irq)
+static void sun4v_irq_eoi(unsigned int virt_irq)
 {
        unsigned int ino = virt_irq_table[virt_irq].dev_ino;
        struct irq_desc *desc = irq_desc + virt_irq;
@@ -478,7 +478,7 @@ static void sun4v_virq_disable(unsigned int virt_irq)
                       dev_handle, dev_ino, err);
 }
 
-static void sun4v_virq_end(unsigned int virt_irq)
+static void sun4v_virq_eoi(unsigned int virt_irq)
 {
        struct irq_desc *desc = irq_desc + virt_irq;
        unsigned long dev_handle, dev_ino;
@@ -498,33 +498,11 @@ static void sun4v_virq_end(unsigned int virt_irq)
                       dev_handle, dev_ino, err);
 }
 
-static void run_pre_handler(unsigned int virt_irq)
-{
-       struct irq_handler_data *data = get_irq_chip_data(virt_irq);
-       unsigned int ino;
-
-       ino = virt_irq_table[virt_irq].dev_ino;
-       if (likely(data->pre_handler)) {
-               data->pre_handler(ino,
-                                 data->pre_handler_arg1,
-                                 data->pre_handler_arg2);
-       }
-}
-
 static struct irq_chip sun4u_irq = {
        .typename       = "sun4u",
        .enable         = sun4u_irq_enable,
        .disable        = sun4u_irq_disable,
-       .end            = sun4u_irq_end,
-       .set_affinity   = sun4u_set_affinity,
-};
-
-static struct irq_chip sun4u_irq_ack = {
-       .typename       = "sun4u+ack",
-       .enable         = sun4u_irq_enable,
-       .disable        = sun4u_irq_disable,
-       .ack            = run_pre_handler,
-       .end            = sun4u_irq_end,
+       .eoi            = sun4u_irq_eoi,
        .set_affinity   = sun4u_set_affinity,
 };
 
@@ -532,7 +510,7 @@ static struct irq_chip sun4v_irq = {
        .typename       = "sun4v",
        .enable         = sun4v_irq_enable,
        .disable        = sun4v_irq_disable,
-       .end            = sun4v_irq_end,
+       .eoi            = sun4v_irq_eoi,
        .set_affinity   = sun4v_set_affinity,
 };
 
@@ -540,31 +518,33 @@ static struct irq_chip sun4v_virq = {
        .typename       = "vsun4v",
        .enable         = sun4v_virq_enable,
        .disable        = sun4v_virq_disable,
-       .end            = sun4v_virq_end,
+       .eoi            = sun4v_virq_eoi,
        .set_affinity   = sun4v_virt_set_affinity,
 };
 
+static void fastcall pre_flow_handler(unsigned int virt_irq,
+                                     struct irq_desc *desc)
+{
+       struct irq_handler_data *data = get_irq_chip_data(virt_irq);
+       unsigned int ino = virt_irq_table[virt_irq].dev_ino;
+
+       data->pre_handler(ino, data->arg1, data->arg2);
+
+       handle_fasteoi_irq(virt_irq, desc);
+}
+
 void irq_install_pre_handler(int virt_irq,
                             void (*func)(unsigned int, void *, void *),
                             void *arg1, void *arg2)
 {
        struct irq_handler_data *data = get_irq_chip_data(virt_irq);
-       struct irq_chip *chip = get_irq_chip(virt_irq);
-
-       if (WARN_ON(chip == &sun4v_irq || chip == &sun4v_virq)) {
-               printk(KERN_ERR "IRQ: Trying to install pre-handler on "
-                      "sun4v irq %u\n", virt_irq);
-               return;
-       }
+       struct irq_desc *desc = irq_desc + virt_irq;
 
        data->pre_handler = func;
-       data->pre_handler_arg1 = arg1;
-       data->pre_handler_arg2 = arg2;
-
-       if (chip == &sun4u_irq_ack)
-               return;
+       data->arg1 = arg1;
+       data->arg2 = arg2;
 
-       set_irq_chip(virt_irq, &sun4u_irq_ack);
+       desc->handle_irq = pre_flow_handler;
 }
 
 unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap)
@@ -582,7 +562,10 @@ unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap)
        if (!virt_irq) {
                virt_irq = virt_irq_alloc(0, ino);
                bucket_set_virt_irq(__pa(bucket), virt_irq);
-               set_irq_chip(virt_irq, &sun4u_irq);
+               set_irq_chip_and_handler_name(virt_irq,
+                                             &sun4u_irq,
+                                             handle_fasteoi_irq,
+                                             "IVEC");
        }
 
        data = get_irq_chip_data(virt_irq);
@@ -617,7 +600,9 @@ static unsigned int sun4v_build_common(unsigned long sysino,
        if (!virt_irq) {
                virt_irq = virt_irq_alloc(0, sysino);
                bucket_set_virt_irq(__pa(bucket), virt_irq);
-               set_irq_chip(virt_irq, chip);
+               set_irq_chip_and_handler_name(virt_irq, chip,
+                                             handle_fasteoi_irq,
+                                             "IVEC");
        }
 
        data = get_irq_chip_data(virt_irq);
@@ -665,7 +650,10 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino)
 
        virt_irq = virt_irq_alloc(devhandle, devino);
        bucket_set_virt_irq(__pa(bucket), virt_irq);
-       set_irq_chip(virt_irq, &sun4v_virq);
+
+       set_irq_chip_and_handler_name(virt_irq, &sun4v_virq,
+                                     handle_fasteoi_irq,
+                                     "IVEC");
 
        data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC);
        if (unlikely(!data))
@@ -724,6 +712,7 @@ void handler_irq(int irq, struct pt_regs *regs)
                             : "memory");
 
        while (bucket_pa) {
+               struct irq_desc *desc;
                unsigned long next_pa;
                unsigned int virt_irq;
 
@@ -731,7 +720,9 @@ void handler_irq(int irq, struct pt_regs *regs)
                virt_irq = bucket_get_virt_irq(bucket_pa);
                bucket_clear_chain_pa(bucket_pa);
 
-               __do_IRQ(virt_irq);
+               desc = irq_desc + virt_irq;
+
+               desc->handle_irq(virt_irq, desc);
 
                bucket_pa = next_pa;
        }
@@ -877,7 +868,7 @@ void __cpuinit sun4v_register_mondo_queues(int this_cpu)
 static void __init alloc_one_mondo(unsigned long *pa_ptr, unsigned long qmask)
 {
        unsigned long size = PAGE_ALIGN(qmask + 1);
-       void *p = __alloc_bootmem_low(size, size, 0);
+       void *p = __alloc_bootmem(size, size, 0);
        if (!p) {
                prom_printf("SUN4V: Error, cannot allocate mondo queue.\n");
                prom_halt();
@@ -889,7 +880,7 @@ static void __init alloc_one_mondo(unsigned long *pa_ptr, unsigned long qmask)
 static void __init alloc_one_kbuf(unsigned long *pa_ptr, unsigned long qmask)
 {
        unsigned long size = PAGE_ALIGN(qmask + 1);
-       void *p = __alloc_bootmem_low(size, size, 0);
+       void *p = __alloc_bootmem(size, size, 0);
 
        if (!p) {
                prom_printf("SUN4V: Error, cannot allocate kbuf page.\n");
@@ -906,7 +897,7 @@ static void __init init_cpu_send_mondo_info(struct trap_per_cpu *tb)
 
        BUILD_BUG_ON((NR_CPUS * sizeof(u16)) > (PAGE_SIZE - 64));
 
-       page = alloc_bootmem_low_pages(PAGE_SIZE);
+       page = alloc_bootmem_pages(PAGE_SIZE);
        if (!page) {
                prom_printf("SUN4V: Error, cannot allocate cpu mondo page.\n");
                prom_halt();
@@ -953,7 +944,7 @@ void __init init_IRQ(void)
        kill_prom_timer();
 
        size = sizeof(struct ino_bucket) * NUM_IVECS;
-       ivector_table = alloc_bootmem_low(size);
+       ivector_table = alloc_bootmem(size);
        if (!ivector_table) {
                prom_printf("Fatal error, cannot allocate ivector_table\n");
                prom_halt();
index 85a2be0b0962201cc9f3237287c6dcb8c9400d85..c8313cb60f0a14562f3fd2714c0bfac1c5010bec 100644 (file)
@@ -2057,7 +2057,7 @@ static void fill_cookies(struct cookie_state *sp, unsigned long pa,
 
 static int sg_count_one(struct scatterlist *sg)
 {
-       unsigned long base = page_to_pfn(sg->page) << PAGE_SHIFT;
+       unsigned long base = page_to_pfn(sg_page(sg)) << PAGE_SHIFT;
        long len = sg->length;
 
        if ((sg->offset | len) & (8UL - 1))
index 42d779866fba394135bf7063d5b6a04e29fe1c7b..fc5c0cc793b8f3a403307c9366b3be0a4fdc84da 100644 (file)
@@ -869,26 +869,6 @@ static int __init of_debug(char *str)
 
 __setup("of_debug=", of_debug);
 
-int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus)
-{
-       /* initialize common driver fields */
-       if (!drv->driver.name)
-               drv->driver.name = drv->name;
-       if (!drv->driver.owner)
-               drv->driver.owner = drv->owner;
-       drv->driver.bus = bus;
-
-       /* register with core */
-       return driver_register(&drv->driver);
-}
-EXPORT_SYMBOL(of_register_driver);
-
-void of_unregister_driver(struct of_platform_driver *drv)
-{
-       driver_unregister(&drv->driver);
-}
-EXPORT_SYMBOL(of_unregister_driver);
-
 struct of_device* of_platform_device_create(struct device_node *np,
                                            const char *bus_id,
                                            struct device *parent,
index 9b808640a193d5c941cbb2dd16e4ec5bbffb465a..63b3ebc0c3c209fef14c8d8cc9f6e6d8bf276e82 100644 (file)
@@ -207,8 +207,7 @@ static struct {
        { "SUNW,sun4v-pci", sun4v_pci_init },
        { "pciex108e,80f0", fire_pci_init },
 };
-#define PCI_NUM_CONTROLLER_TYPES (sizeof(pci_controller_table) / \
-                                 sizeof(pci_controller_table[0]))
+#define PCI_NUM_CONTROLLER_TYPES       ARRAY_SIZE(pci_controller_table)
 
 static int __init pci_controller_init(const char *model_name, int namelen, struct device_node *dp)
 {
index c76bfbb7da085cd5538391713c13e9b86f9ed148..923e0bcc3bfdb0e65cdb6b957324957aa886040a 100644 (file)
@@ -396,6 +396,13 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
 
        saw_mem = saw_io = 0;
        pbm_ranges = of_get_property(pbm->prom_node, "ranges", &i);
+       if (!pbm_ranges) {
+               prom_printf("PCI: Fatal error, missing PBM ranges property "
+                           " for %s\n",
+                           pbm->name);
+               prom_halt();
+       }
+
        num_pbm_ranges = i / sizeof(*pbm_ranges);
 
        for (i = 0; i < num_pbm_ranges; i++) {
index 31a165fd3e48bbce768eed08fde760379d82acea..d6d64b44af63da31e2512475f4e6167203758ea3 100644 (file)
@@ -28,8 +28,15 @@ static irqreturn_t sparc64_msiq_interrupt(int irq, void *cookie)
                unsigned long msi;
 
                err = ops->dequeue_msi(pbm, msiqid, &head, &msi);
-               if (likely(err > 0))
-                       __do_IRQ(pbm->msi_irq_table[msi - pbm->msi_first]);
+               if (likely(err > 0)) {
+                       struct irq_desc *desc;
+                       unsigned int virt_irq;
+
+                       virt_irq = pbm->msi_irq_table[msi - pbm->msi_first];
+                       desc = irq_desc + virt_irq;
+
+                       desc->handle_irq(virt_irq, desc);
+               }
 
                if (unlikely(err < 0))
                        goto err_dequeue;
@@ -128,7 +135,8 @@ int sparc64_setup_msi_irq(unsigned int *virt_irq_p,
        if (!*virt_irq_p)
                goto out_err;
 
-       set_irq_chip(*virt_irq_p, &msi_irq);
+       set_irq_chip_and_handler_name(*virt_irq_p, &msi_irq,
+                                     handle_simple_irq, "MSI");
 
        err = alloc_msi(pbm);
        if (unlikely(err < 0))
index fe46ace3e59f6582a185b72641363f03d2966d3a..8c4875bdb4a89d54841787141922eff02566c625 100644 (file)
@@ -365,8 +365,7 @@ static void dma_4v_unmap_single(struct device *dev, dma_addr_t bus_addr,
        spin_unlock_irqrestore(&iommu->lock, flags);
 }
 
-#define SG_ENT_PHYS_ADDRESS(SG)        \
-       (__pa(page_address((SG)->page)) + (SG)->offset)
+#define SG_ENT_PHYS_ADDRESS(SG)        (__pa(sg_virt((SG))))
 
 static long fill_sg(long entry, struct device *dev,
                    struct scatterlist *sg,
@@ -477,9 +476,7 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
        /* Fast path single entry scatterlists. */
        if (nelems == 1) {
                sglist->dma_address =
-                       dma_4v_map_single(dev,
-                                         (page_address(sglist->page) +
-                                          sglist->offset),
+                       dma_4v_map_single(dev, sg_virt(sglist),
                                          sglist->length, direction);
                if (unlikely(sglist->dma_address == DMA_ERROR_CODE))
                        return 0;
index 8f7a06e2c7e739dfec3f3206c2b34745f222e3d7..170d6ca8de6f0e4d36b26c81ffdd0592059acfe2 100644 (file)
@@ -831,7 +831,7 @@ asmlinkage int sunos_killpg(int pgrp, int sig)
        rcu_read_lock();
        ret = -EINVAL;
        if (pgrp > 0)
-               ret = kill_pgrp(find_pid(pgrp), sig, 0);
+               ret = kill_pgrp(find_vpid(pgrp), sig, 0);
        rcu_read_unlock();
 
        return ret;
index 34573a55b6e5a92d65a420ca2daf168c65bfda65..e9c7e4f07abfd99d9f9e361ce461a7417b341aa7 100644 (file)
@@ -2225,7 +2225,7 @@ void die_if_kernel(char *str, struct pt_regs *regs)
 "              /_| \\__/ |_\\\n"
 "                 \\__U_/\n");
 
-       printk("%s(%d): %s [#%d]\n", current->comm, current->pid, str, ++die_counter);
+       printk("%s(%d): %s [#%d]\n", current->comm, task_pid_nr(current), str, ++die_counter);
        notify_die(DIE_OOPS, str, regs, 0, 255, SIGSEGV);
        __asm__ __volatile__("flushw");
        __show_regs(regs);
index 9633750167d06b3e9f4d285e105656d01a8ce32f..70ac4186f62b7afc4af36eeb5472d6db868688d8 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: atomic.S,v 1.4 2001/11/18 00:12:56 davem Exp $
- * atomic.S: These things are too big to do inline.
+/* atomic.S: These things are too big to do inline.
  *
- * Copyright (C) 1999 David S. Miller (davem@redhat.com)
+ * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net)
  */
 
 #include <asm/asi.h>
+#include <asm/backoff.h>
 
        .text
 
        .globl  atomic_add
        .type   atomic_add,#function
 atomic_add: /* %o0 = increment, %o1 = atomic_ptr */
+       BACKOFF_SETUP(%o2)
 1:     lduw    [%o1], %g1
        add     %g1, %o0, %g7
        cas     [%o1], %g1, %g7
        cmp     %g1, %g7
-       bne,pn  %icc, 1b
+       bne,pn  %icc, 2f
         nop
        retl
         nop
+2:     BACKOFF_SPIN(%o2, %o3, 1b)
        .size   atomic_add, .-atomic_add
 
        .globl  atomic_sub
        .type   atomic_sub,#function
 atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */
+       BACKOFF_SETUP(%o2)
 1:     lduw    [%o1], %g1
        sub     %g1, %o0, %g7
        cas     [%o1], %g1, %g7
        cmp     %g1, %g7
-       bne,pn  %icc, 1b
+       bne,pn  %icc, 2f
         nop
        retl
         nop
+2:     BACKOFF_SPIN(%o2, %o3, 1b)
        .size   atomic_sub, .-atomic_sub
 
        /* On SMP we need to use memory barriers to ensure
@@ -60,89 +64,101 @@ atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */
        .globl  atomic_add_ret
        .type   atomic_add_ret,#function
 atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
+       BACKOFF_SETUP(%o2)
        ATOMIC_PRE_BARRIER
 1:     lduw    [%o1], %g1
        add     %g1, %o0, %g7
        cas     [%o1], %g1, %g7
        cmp     %g1, %g7
-       bne,pn  %icc, 1b
+       bne,pn  %icc, 2f
         add    %g7, %o0, %g7
        sra     %g7, 0, %o0
        ATOMIC_POST_BARRIER
        retl
         nop
+2:     BACKOFF_SPIN(%o2, %o3, 1b)
        .size   atomic_add_ret, .-atomic_add_ret
 
        .globl  atomic_sub_ret
        .type   atomic_sub_ret,#function
 atomic_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
+       BACKOFF_SETUP(%o2)
        ATOMIC_PRE_BARRIER
 1:     lduw    [%o1], %g1
        sub     %g1, %o0, %g7
        cas     [%o1], %g1, %g7
        cmp     %g1, %g7
-       bne,pn  %icc, 1b
+       bne,pn  %icc, 2f
         sub    %g7, %o0, %g7
        sra     %g7, 0, %o0
        ATOMIC_POST_BARRIER
        retl
         nop
+2:     BACKOFF_SPIN(%o2, %o3, 1b)
        .size   atomic_sub_ret, .-atomic_sub_ret
 
        .globl  atomic64_add
        .type   atomic64_add,#function
 atomic64_add: /* %o0 = increment, %o1 = atomic_ptr */
+       BACKOFF_SETUP(%o2)
 1:     ldx     [%o1], %g1
        add     %g1, %o0, %g7
        casx    [%o1], %g1, %g7
        cmp     %g1, %g7
-       bne,pn  %xcc, 1b
+       bne,pn  %xcc, 2f
         nop
        retl
         nop
+2:     BACKOFF_SPIN(%o2, %o3, 1b)
        .size   atomic64_add, .-atomic64_add
 
        .globl  atomic64_sub
        .type   atomic64_sub,#function
 atomic64_sub: /* %o0 = decrement, %o1 = atomic_ptr */
+       BACKOFF_SETUP(%o2)
 1:     ldx     [%o1], %g1
        sub     %g1, %o0, %g7
        casx    [%o1], %g1, %g7
        cmp     %g1, %g7
-       bne,pn  %xcc, 1b
+       bne,pn  %xcc, 2f
         nop
        retl
         nop
+2:     BACKOFF_SPIN(%o2, %o3, 1b)
        .size   atomic64_sub, .-atomic64_sub
 
        .globl  atomic64_add_ret
        .type   atomic64_add_ret,#function
 atomic64_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
+       BACKOFF_SETUP(%o2)
        ATOMIC_PRE_BARRIER
 1:     ldx     [%o1], %g1
        add     %g1, %o0, %g7
        casx    [%o1], %g1, %g7
        cmp     %g1, %g7
-       bne,pn  %xcc, 1b
+       bne,pn  %xcc, 2f
         add    %g7, %o0, %g7
        mov     %g7, %o0
        ATOMIC_POST_BARRIER
        retl
         nop
+2:     BACKOFF_SPIN(%o2, %o3, 1b)
        .size   atomic64_add_ret, .-atomic64_add_ret
 
        .globl  atomic64_sub_ret
        .type   atomic64_sub_ret,#function
 atomic64_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
+       BACKOFF_SETUP(%o2)
        ATOMIC_PRE_BARRIER
 1:     ldx     [%o1], %g1
        sub     %g1, %o0, %g7
        casx    [%o1], %g1, %g7
        cmp     %g1, %g7
-       bne,pn  %xcc, 1b
+       bne,pn  %xcc, 2f
         sub    %g7, %o0, %g7
        mov     %g7, %o0
        ATOMIC_POST_BARRIER
        retl
         nop
+2:     BACKOFF_SPIN(%o2, %o3, 1b)
        .size   atomic64_sub_ret, .-atomic64_sub_ret
index 892431a821311f639e9a18aec4a70c702bd4c726..6b015a6eefb50017e7d22b2d1edc0637408a1fef 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: bitops.S,v 1.3 2001/11/18 00:12:56 davem Exp $
- * bitops.S: Sparc64 atomic bit operations.
+/* bitops.S: Sparc64 atomic bit operations.
  *
- * Copyright (C) 2000 David S. Miller (davem@redhat.com)
+ * Copyright (C) 2000, 2007 David S. Miller (davem@davemloft.net)
  */
 
 #include <asm/asi.h>
+#include <asm/backoff.h>
 
        .text
 
@@ -29,6 +29,7 @@
        .globl  test_and_set_bit
        .type   test_and_set_bit,#function
 test_and_set_bit:      /* %o0=nr, %o1=addr */
+       BACKOFF_SETUP(%o3)
        BITOP_PRE_BARRIER
        srlx    %o0, 6, %g1
        mov     1, %o2
@@ -40,18 +41,20 @@ test_and_set_bit:   /* %o0=nr, %o1=addr */
        or      %g7, %o2, %g1
        casx    [%o1], %g7, %g1
        cmp     %g7, %g1
-       bne,pn  %xcc, 1b
+       bne,pn  %xcc, 2f
         and    %g7, %o2, %g2
        clr     %o0
        movrne  %g2, 1, %o0
        BITOP_POST_BARRIER
        retl
         nop
+2:     BACKOFF_SPIN(%o3, %o4, 1b)
        .size   test_and_set_bit, .-test_and_set_bit
 
        .globl  test_and_clear_bit
        .type   test_and_clear_bit,#function
 test_and_clear_bit:    /* %o0=nr, %o1=addr */
+       BACKOFF_SETUP(%o3)
        BITOP_PRE_BARRIER
        srlx    %o0, 6, %g1
        mov     1, %o2
@@ -63,18 +66,20 @@ test_and_clear_bit: /* %o0=nr, %o1=addr */
        andn    %g7, %o2, %g1
        casx    [%o1], %g7, %g1
        cmp     %g7, %g1
-       bne,pn  %xcc, 1b
+       bne,pn  %xcc, 2f
         and    %g7, %o2, %g2
        clr     %o0
        movrne  %g2, 1, %o0
        BITOP_POST_BARRIER
        retl
         nop
+2:     BACKOFF_SPIN(%o3, %o4, 1b)
        .size   test_and_clear_bit, .-test_and_clear_bit
 
        .globl  test_and_change_bit
        .type   test_and_change_bit,#function
 test_and_change_bit:   /* %o0=nr, %o1=addr */
+       BACKOFF_SETUP(%o3)
        BITOP_PRE_BARRIER
        srlx    %o0, 6, %g1
        mov     1, %o2
@@ -86,18 +91,20 @@ test_and_change_bit:        /* %o0=nr, %o1=addr */
        xor     %g7, %o2, %g1
        casx    [%o1], %g7, %g1
        cmp     %g7, %g1
-       bne,pn  %xcc, 1b
+       bne,pn  %xcc, 2f
         and    %g7, %o2, %g2
        clr     %o0
        movrne  %g2, 1, %o0
        BITOP_POST_BARRIER
        retl
         nop
+2:     BACKOFF_SPIN(%o3, %o4, 1b)
        .size   test_and_change_bit, .-test_and_change_bit
 
        .globl  set_bit
        .type   set_bit,#function
 set_bit:               /* %o0=nr, %o1=addr */
+       BACKOFF_SETUP(%o3)
        srlx    %o0, 6, %g1
        mov     1, %o2
        sllx    %g1, 3, %g3
@@ -108,15 +115,17 @@ set_bit:          /* %o0=nr, %o1=addr */
        or      %g7, %o2, %g1
        casx    [%o1], %g7, %g1
        cmp     %g7, %g1
-       bne,pn  %xcc, 1b
+       bne,pn  %xcc, 2f
         nop
        retl
         nop
+2:     BACKOFF_SPIN(%o3, %o4, 1b)
        .size   set_bit, .-set_bit
 
        .globl  clear_bit
        .type   clear_bit,#function
 clear_bit:             /* %o0=nr, %o1=addr */
+       BACKOFF_SETUP(%o3)
        srlx    %o0, 6, %g1
        mov     1, %o2
        sllx    %g1, 3, %g3
@@ -127,15 +136,17 @@ clear_bit:                /* %o0=nr, %o1=addr */
        andn    %g7, %o2, %g1
        casx    [%o1], %g7, %g1
        cmp     %g7, %g1
-       bne,pn  %xcc, 1b
+       bne,pn  %xcc, 2f
         nop
        retl
         nop
+2:     BACKOFF_SPIN(%o3, %o4, 1b)
        .size   clear_bit, .-clear_bit
 
        .globl  change_bit
        .type   change_bit,#function
 change_bit:            /* %o0=nr, %o1=addr */
+       BACKOFF_SETUP(%o3)
        srlx    %o0, 6, %g1
        mov     1, %o2
        sllx    %g1, 3, %g3
@@ -146,8 +157,9 @@ change_bit:         /* %o0=nr, %o1=addr */
        xor     %g7, %o2, %g1
        casx    [%o1], %g7, %g1
        cmp     %g7, %g1
-       bne,pn  %xcc, 1b
+       bne,pn  %xcc, 2f
         nop
        retl
         nop
+2:     BACKOFF_SPIN(%o3, %o4, 1b)
        .size   change_bit, .-change_bit
index a0b06fd29467eb80b7c502a1277b2798bd7fd3f3..cc5cb9baf6aa559973d2eed9973a13658fdb9508 100644 (file)
@@ -4,4 +4,4 @@
 
 obj-y    := math.o
 
-EXTRA_CFLAGS = -I. -Iinclude/math-emu -w
+EXTRA_CFLAGS = -Iinclude/math-emu -w
diff --git a/arch/sparc64/oprofile/Kconfig b/arch/sparc64/oprofile/Kconfig
deleted file mode 100644 (file)
index d8a8408..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-config PROFILING
-       bool "Profiling support (EXPERIMENTAL)"
-       help
-         Say Y here to enable the extended profiling support mechanisms used
-         by profilers such as OProfile.
-         
-
-config OPROFILE
-       tristate "OProfile system profiling (EXPERIMENTAL)"
-       depends on PROFILING
-       help
-         OProfile is a profiling system capable of profiling the
-         whole system, include the kernel, kernel modules, libraries,
-         and applications.
-
-         If unsure, say N.
-
index 3b67de7455f15c45f53524cc03269e18fa987521..c86cb3091a8ea8f28201f9afc66b718f230a107a 100644 (file)
@@ -415,7 +415,7 @@ asmlinkage int solaris_procids(int cmd, s32 pid, s32 pgid)
        
        switch (cmd) {
        case 0: /* getpgrp */
-               return process_group(current);
+               return task_pgrp_nr(current);
        case 1: /* setpgrp */
                {
                        int (*sys_setpgid)(pid_t,pid_t) =
@@ -426,7 +426,7 @@ asmlinkage int solaris_procids(int cmd, s32 pid, s32 pgid)
                        ret = sys_setpgid(0, 0);
                        if (ret) return ret;
                        proc_clear_tty(current);
-                       return process_group(current);
+                       return task_pgrp_nr(current);
                }
        case 2: /* getsid */
                {
index 740d8a922e4867e457c30c513fb3fa37e912fc8c..dd1689b814cb5a842c456a0337f66ec9db2dbe2e 100644 (file)
@@ -3,7 +3,7 @@ config DEFCONFIG_LIST
        option defconfig_list
        default "arch/$ARCH/defconfig"
 
-# UML uses the generic IRQ sugsystem
+# UML uses the generic IRQ subsystem
 config GENERIC_HARDIRQS
        bool
        default y
@@ -289,4 +289,6 @@ config INPUT
        bool
        default n
 
+source "kernel/Kconfig.instrumentation"
+
 source "arch/um/Kconfig.debug"
index 76fe0b0da9960fe36bc6fd5c59e7432aa8cf511d..83bf15a3dda88472dc5aea5ade3353e3f772e0e2 100644 (file)
@@ -35,7 +35,7 @@ static void line_timer_cb(struct work_struct *work)
 /*
  * Returns the free space inside the ring buffer of this line.
  *
- * Should be called while holding line->lock (this does not modify datas).
+ * Should be called while holding line->lock (this does not modify data).
  */
 static int write_room(struct line *line)
 {
index 21ad3d7932b350605a3294f9b5b5705a7a49c7ac..2b45a1446c86b5bf34f01cfe9d71d19ec1a118cc 100644 (file)
@@ -9,7 +9,7 @@
 #include "chan_user.h"
 #include "os.h"
 
-/* This address is used only as a unique identifer */
+/* This address is used only as a unique identifier */
 static int null_chan;
 
 static void *null_init(char *str, int device, const struct chan_opts *opts)
index ae67e7158e718c495657b51b3b1c933ab61cf0e9..6b4a0f9e38deeb3d4852639ec4c3d83684e5612f 100644 (file)
@@ -31,10 +31,8 @@ void slip_init(struct net_device *dev, void *data)
        slip_proto_init(&spri->slip);
 
        dev->init = NULL;
-       dev->header_cache_update = NULL;
-       dev->hard_header_cache = NULL;
-       dev->hard_header = NULL;
        dev->hard_header_len = 0;
+       dev->header_ops = NULL;
        dev->addr_len = 0;
        dev->type = ARPHRD_SLIP;
        dev->tx_queue_len = 256;
index 240ee650865df79927d0557c81197e7be7283a31..d987af277db9d8f1cc943aa72ab46201e57cbb58 100644 (file)
@@ -34,9 +34,7 @@ void slirp_init(struct net_device *dev, void *data)
 
        dev->init = NULL;
        dev->hard_header_len = 0;
-       dev->header_cache_update = NULL;
-       dev->hard_header_cache = NULL;
-       dev->hard_header = NULL;
+       dev->header_ops = NULL;
        dev->addr_len = 0;
        dev->type = ARPHRD_SLIP;
        dev->tx_queue_len = 256;
index 4739dd527b43ab8ff5cf59ab007cfbbd033b90d8..d07a97f8b9945343791d4fb32c9ad0bf5c7d9df2 100644 (file)
@@ -8,7 +8,7 @@
 /* trivial console driver -- simply dump everything to stderr                    */
 
 /*
- * Don't register by default -- as this registeres very early in the
+ * Don't register by default -- as this registers very early in the
  * boot process it becomes the default console.
  *
  * Initialized at init time.
index 25b248a025074154985fbb0f6a041bbaaf17aa96..3a8cd3dfb51c01cf019c27dfbab86208e576a1a9 100644 (file)
@@ -1115,7 +1115,7 @@ static void do_ubd_request(struct request_queue *q)
                        }
                        prepare_request(req, io_req,
                                        (unsigned long long) req->sector << 9,
-                                       sg->offset, sg->length, sg->page);
+                                       sg->offset, sg->length, sg_page(sg));
 
                        last_sectors = sg->length >> 9;
                        n = os_write_file(thread_fd, &io_req,
index 13aa115cd1b4b521d3bdc1259454626f6b3a4a33..734f873cab12437885af0d61d7dfe3a902f1ae9b 100644 (file)
@@ -12,8 +12,8 @@ EXPORT_SYMBOL(__bb_init_func);
  * versions in libgcov.
  *
  * Since SuSE backported the fix, we cannot handle it depending on GCC version.
- * So, unconditinally export it. But also give it a weak declaration, which will
- * be overriden by any other one.
+ * So, unconditionally export it. But also give it a weak declaration, which will
+ * be overridden by any other one.
  */
 
 extern void __gcov_init(void *) __attribute__((weak));
index 277fce17b0881c7f04894a6040bb32f6a65e7d73..70c2d625b0702a284c5b72c65fa3eb4c907e4428 100644 (file)
@@ -326,7 +326,7 @@ int deactivate_all_fds(void)
 }
 
 /*
- * do_IRQ handles all normal device IRQ's (the special
+ * do_IRQ handles all normal device IRQs (the special
  * SMP cross-CPU interrupts have their own specific
  * handlers).
  */
index a0eba083306882b6f647b74d4ff3324272c3c23b..47b57b497d5529e570591e97a0f041e0d55d842e 100644 (file)
@@ -237,7 +237,7 @@ void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs,
        /* User-mode eip? */
        info.si_addr = UPT_IS_USER(regs) ? (void __user *) UPT_IP(regs) : NULL;
 
-       /* Send us the fakey SIGTRAP */
+       /* Send us the fake SIGTRAP */
        force_sig_info(SIGTRAP, &info, tsk);
 }
 
index bd060551e6190d6fc92b2148840f94c9e71098c9..cb3321f8e0a91924167b0f83ea7f34c30df55080 100644 (file)
@@ -108,7 +108,7 @@ out_nosemaphore:
  * us unable to handle the page fault gracefully.
  */
 out_of_memory:
-       if (is_init(current)) {
+       if (is_global_init(current)) {
                up_read(&mm->mmap_sem);
                yield();
                down_read(&mm->mmap_sem);
index 200c8ba2879bef1415f3b6fa8818e81ad7c7b0c6..a4360b5207db9e6c2e49676522c168942ff5b7f2 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/uaccess.h>
 
 /* Mostly copied from i386/x86_86 - eliminated the eip < PAGE_OFFSET because
- * that's not relevent in skas mode.
+ * that's not relevant in skas mode.
  */
 
 int is_valid_bugaddr(unsigned long eip)
index b02266ab5c55fbf212cd6a6734b508880d3ae9a0..fcaff86b000c7397656320d67952821e44c73be2 100644 (file)
@@ -45,7 +45,7 @@ int do_get_thread_area(struct user_desc *info)
  * XXX: Consider leaving one free slot for glibc usage at first place. This must
  * be done here (and by changing GDT_ENTRY_TLS_* macros) and nowhere else.
  *
- * Also, this must be tested when compiling in SKAS mode with dinamic linking
+ * Also, this must be tested when compiling in SKAS mode with dynamic linking
  * and running against NPTL.
  */
 static int get_free_idx(struct task_struct* task)
index 200c8ba2879bef1415f3b6fa8818e81ad7c7b0c6..a4360b5207db9e6c2e49676522c168942ff5b7f2 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/uaccess.h>
 
 /* Mostly copied from i386/x86_86 - eliminated the eip < PAGE_OFFSET because
- * that's not relevent in skas mode.
+ * that's not relevant in skas mode.
  */
 
 int is_valid_bugaddr(unsigned long eip)
index ce3e07fcf283747bdb72216bcf2f7968d2abe0af..765444031819c55ce6c51f92f09e665c57448ccd 100644 (file)
@@ -15,8 +15,8 @@ void __show_regs(struct pt_regs * regs)
 {
        printk("\n");
        print_modules();
-       printk("Pid: %d, comm: %.20s %s %s\n",
-              current->pid, current->comm, print_tainted(), init_utsname()->release);
+       printk("Pid: %d, comm: %.20s %s %s\n", task_pid_nr(current),
+               current->comm, print_tainted(), init_utsname()->release);
        printk("RIP: %04lx:[<%016lx>] ", PT_REGS_CS(regs) & 0xffff,
               PT_REGS_RIP(regs));
        printk("\nRSP: %016lx  EFLAGS: %08lx\n", PT_REGS_RSP(regs),
index ace479ab273ff329cc387ce536e8598f171054b4..b6a50b8b38de2c4edc2fdbc8b30012d772c3b672 100644 (file)
@@ -331,6 +331,8 @@ source "sound/Kconfig"
 
 source "drivers/usb/Kconfig"
 
+source "kernel/Kconfig.instrumentation"
+
 source "arch/v850/Kconfig.debug"
 
 source "security/Kconfig"
index 38be5c194f6b9a5ca782a2b71f07e66f60e0e7e3..007115dc9ce0e14d8fc380f29134ebc28a2c5e49 100644 (file)
@@ -58,13 +58,13 @@ void __init me2_init_irqs (void)
 void me2_uart_pre_configure (unsigned chan, unsigned cflags, unsigned baud)
 {
        if (chan == 0) {
-               /* Specify that the relevent pins on the chip should do
+               /* Specify that the relevant pins on the chip should do
                   serial I/O, not direct I/O.  */
                ME2_PORT1_PMC |= 0xC;
                /* Specify that we're using the UART, not the CSI device. */
                ME2_PORT1_PFC |= 0xC;
        } else if (chan == 1) {
-               /* Specify that the relevent pins on the chip should do
+               /* Specify that the relevant pins on the chip should do
                   serial I/O, not direct I/O.  */
                ME2_PORT2_PMC |= 0x6;
                /* Specify that we're using the UART, not the CSI device. */
index 35a4bd5515cb53c8903d612fc43ebda0a4cb5535..7165478824e7405757536e65d04d493d281d762c 100644 (file)
@@ -179,7 +179,7 @@ static int __devinit pcibios_init (void)
                   default uses.  */
 
                /* Significant address bits used for decoding PCI GCS5 space
-                  accessess.  */
+                  accesses.  */
                MB_A_PCI_DMRR = ~(MB_A_PCI_MEM_SIZE - 1);
 
                /* I don't understand this, but the SolutionGear example code
@@ -775,7 +775,7 @@ pci_alloc_consistent (struct pci_dev *pdev, size_t size, dma_addr_t *dma_addr)
 /* Free and unmap a consistent DMA buffer.  CPU_ADDR and DMA_ADDR must
    be values that were returned from pci_alloc_consistent.  SIZE must be
    the same as what as passed into pci_alloc_consistent.  References to
-   the memory and mappings assosciated with CPU_ADDR or DMA_ADDR past
+   the memory and mappings associated with CPU_ADDR or DMA_ADDR past
    this call are illegal.  */
 void
 pci_free_consistent (struct pci_dev *pdev, size_t size, void *cpu_addr,
index f35ea2237522c0267139af7666e2875b571dd4b4..a0ae2e7f6cecbcf0c0311a0ce6029408fd350268 100644 (file)
 #include <asm/segment.h>
 #include <asm/page.h>
 #include <asm/boot.h>
+#include <asm/asm-offsets.h>
 
 .section ".text.head","ax",@progbits
        .globl startup_32
 
 startup_32:
-       cld
-       cli
+       /* check to see if KEEP_SEGMENTS flag is meaningful */
+       cmpw $0x207, BP_version(%esi)
+       jb 1f
+
+       /* test KEEP_SEGMENTS flag to see if the bootloader is asking
+        * us to not reload segments */
+       testb $(1<<6), BP_loadflags(%esi)
+       jnz 2f
+
+1:     cli
        movl $(__BOOT_DS),%eax
        movl %eax,%ds
        movl %eax,%es
@@ -41,6 +50,8 @@ startup_32:
        movl %eax,%gs
        movl %eax,%ss
 
+2:     cld
+
 /* Calculate the delta between where we were compiled to run
  * at and where we were actually loaded at.  This can only be done
  * with a short local call on x86.  Nothing  else will tell us what
index b28505c544c9ca60306c5029326fb82b16ef4b95..b74d60d1b2fa1329f6f28c434fc47445cb39ccb4 100644 (file)
@@ -25,7 +25,7 @@
 
 /*
  * Getting to provable safe in place decompression is hard.
- * Worst case behaviours need to be analized.
+ * Worst case behaviours need to be analyzed.
  * Background information:
  *
  * The file layout is:
@@ -94,7 +94,7 @@
  * Adding 32768 instead of 32767 just makes for round numbers.
  * Adding the decompressor_size is necessary as it musht live after all
  * of the data as well.  Last I measured the decompressor is about 14K.
- * 10K of actuall data and 4K of bss.
+ * 10K of actual data and 4K of bss.
  *
  */
 
@@ -247,6 +247,9 @@ static void putstr(const char *s)
        int x,y,pos;
        char c;
 
+       if (RM_SCREEN_INFO.orig_video_mode == 0 && lines == 0 && cols == 0)
+               return;
+
        x = RM_SCREEN_INFO.orig_x;
        y = RM_SCREEN_INFO.orig_y;
 
index f932b0e89096afaf0eefdcf723a27d1957c4a3d5..6ea015aa65e4666420fe4f45de6885d64bbd8245 100644 (file)
@@ -25,7 +25,7 @@
 
 /*
  * Getting to provable safe in place decompression is hard.
- * Worst case behaviours need to be analized.
+ * Worst case behaviours need to be analyzed.
  * Background information:
  *
  * The file layout is:
@@ -94,7 +94,7 @@
  * Adding 32768 instead of 32767 just makes for round numbers.
  * Adding the decompressor_size is necessary as it musht live after all
  * of the data as well.  Last I measured the decompressor is about 14K.
- * 10K of actuall data and 4K of bss.
+ * 10K of actual data and 4K of bss.
  *
  */
 
index f3140e596d407d892eb75aa0c486bd7411e1dcb2..8353c81c41c02865384e227b24e4af8e0879bcee 100644 (file)
@@ -119,7 +119,7 @@ _start:
        # Part 2 of the header, from the old setup.S
 
                .ascii  "HdrS"          # header signature
-               .word   0x0206          # header version number (>= 0x0105)
+               .word   0x0207          # header version number (>= 0x0105)
                                        # or else old loadlin-1.5 will fail)
                .globl realmode_swtch
 realmode_swtch:        .word   0, 0            # default_switch, SETUPSEG
@@ -214,6 +214,11 @@ cmdline_size:   .long   COMMAND_LINE_SIZE-1     #length of the command line,
                                                 #added with boot protocol
                                                 #version 2.06
 
+hardware_subarch:      .long 0                 # subarchitecture, added with 2.07
+                                               # default to 0 for normal x86 PC
+
+hardware_subarch_data: .quad 0
+
 # End of setup header #####################################################
 
        .section ".inittext", "ax"
index 118b9f9ff499c251ca94bbc6e47d45233eba2c08..55822d2cf05319acdf7464acdfd3e37271279b4b 100644 (file)
@@ -5,10 +5,6 @@
  * This tricks binfmt_elf.c into loading 32bit binaries using lots 
  * of ugly preprocessor tricks. Talk about very very poor man's inheritance.
  */ 
-#define __ASM_X86_64_ELF_H 1
-
-#undef ELF_CLASS
-#define ELF_CLASS ELFCLASS32
 
 #include <linux/types.h>
 #include <linux/stddef.h>
@@ -19,6 +15,7 @@
 #include <linux/binfmts.h>
 #include <linux/mm.h>
 #include <linux/security.h>
+#include <linux/elfcore-compat.h>
 
 #include <asm/segment.h> 
 #include <asm/ptrace.h>
 #include <asm/ia32.h>
 #include <asm/vsyscall32.h>
 
+#undef ELF_ARCH
+#undef ELF_CLASS
+#define ELF_CLASS      ELFCLASS32
+#define ELF_ARCH       EM_386
+
+#undef elfhdr
+#undef elf_phdr
+#undef elf_note
+#undef elf_addr_t
+#define elfhdr         elf32_hdr
+#define elf_phdr       elf32_phdr
+#define elf_note       elf32_note
+#define elf_addr_t     Elf32_Off
+
 #define ELF_NAME "elf/i386"
 
 #define AT_SYSINFO 32
@@ -48,74 +59,20 @@ int sysctl_vsyscall32 = 1;
 } while(0)
 
 struct file;
-struct elf_phdr; 
 
 #define IA32_EMULATOR 1
 
-#define ELF_ET_DYN_BASE                (TASK_UNMAPPED_BASE + 0x1000000)
-
-#undef ELF_ARCH
-#define ELF_ARCH EM_386
-
-#define ELF_DATA       ELFDATA2LSB
+#undef ELF_ET_DYN_BASE
 
-#define USE_ELF_CORE_DUMP 1
-
-/* Override elfcore.h */ 
-#define _LINUX_ELFCORE_H 1
-typedef unsigned int elf_greg_t;
-
-#define ELF_NGREG (sizeof (struct user_regs_struct32) / sizeof(elf_greg_t))
-typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-
-struct elf_siginfo
-{
-       int     si_signo;                       /* signal number */
-       int     si_code;                        /* extra code */
-       int     si_errno;                       /* errno */
-};
+#define ELF_ET_DYN_BASE                (TASK_UNMAPPED_BASE + 0x1000000)
 
 #define jiffies_to_timeval(a,b) do { (b)->tv_usec = 0; (b)->tv_sec = (a)/HZ; }while(0)
 
-struct elf_prstatus
-{
-       struct elf_siginfo pr_info;     /* Info associated with signal */
-       short   pr_cursig;              /* Current signal */
-       unsigned int pr_sigpend;        /* Set of pending signals */
-       unsigned int pr_sighold;        /* Set of held signals */
-       pid_t   pr_pid;
-       pid_t   pr_ppid;
-       pid_t   pr_pgrp;
-       pid_t   pr_sid;
-       struct compat_timeval pr_utime; /* User time */
-       struct compat_timeval pr_stime; /* System time */
-       struct compat_timeval pr_cutime;        /* Cumulative user time */
-       struct compat_timeval pr_cstime;        /* Cumulative system time */
-       elf_gregset_t pr_reg;   /* GP registers */
-       int pr_fpvalid;         /* True if math co-processor being used.  */
-};
-
-#define ELF_PRARGSZ    (80)    /* Number of chars for args */
-
-struct elf_prpsinfo
-{
-       char    pr_state;       /* numeric process state */
-       char    pr_sname;       /* char for pr_state */
-       char    pr_zomb;        /* zombie */
-       char    pr_nice;        /* nice val */
-       unsigned int pr_flag;   /* flags */
-       __u16   pr_uid;
-       __u16   pr_gid;
-       pid_t   pr_pid, pr_ppid, pr_pgrp, pr_sid;
-       /* Lots missing */
-       char    pr_fname[16];   /* filename of executable */
-       char    pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */
-};
-
 #define _GET_SEG(x) \
        ({ __u32 seg; asm("movl %%" __stringify(x) ",%0" : "=r"(seg)); seg; })
 
 /* Assumes current==process to be dumped */
+#undef ELF_CORE_COPY_REGS
 #define ELF_CORE_COPY_REGS(pr_reg, regs)                       \
        pr_reg[0] = regs->rbx;                          \
        pr_reg[1] = regs->rcx;                          \
@@ -135,36 +92,41 @@ struct elf_prpsinfo
        pr_reg[15] = regs->rsp;                         \
        pr_reg[16] = regs->ss;
 
-#define user user32
+
+#define elf_prstatus   compat_elf_prstatus
+#define elf_prpsinfo   compat_elf_prpsinfo
+#define elf_fpregset_t struct user_i387_ia32_struct
+#define        elf_fpxregset_t struct user32_fxsr_struct
+#define user           user32
 
 #undef elf_read_implies_exec
 #define elf_read_implies_exec(ex, executable_stack)     (executable_stack != EXSTACK_DISABLE_X)
-//#include <asm/ia32.h>
-#include <linux/elf.h>
-
-typedef struct user_i387_ia32_struct elf_fpregset_t;
-typedef struct user32_fxsr_struct elf_fpxregset_t;
-
 
-static inline void elf_core_copy_regs(elf_gregset_t *elfregs, struct pt_regs *regs)
+#define elf_core_copy_regs             elf32_core_copy_regs
+static inline void elf32_core_copy_regs(compat_elf_gregset_t *elfregs,
+                                       struct pt_regs *regs)
 {
-       ELF_CORE_COPY_REGS((*elfregs), regs)
+       ELF_CORE_COPY_REGS((&elfregs->ebx), regs)
 }
 
-static inline int elf_core_copy_task_regs(struct task_struct *t, elf_gregset_t* elfregs)
+#define elf_core_copy_task_regs                elf32_core_copy_task_regs
+static inline int elf32_core_copy_task_regs(struct task_struct *t,
+                                           compat_elf_gregset_t* elfregs)
 {      
        struct pt_regs *pp = task_pt_regs(t);
-       ELF_CORE_COPY_REGS((*elfregs), pp);
+       ELF_CORE_COPY_REGS((&elfregs->ebx), pp);
        /* fix wrong segments */ 
-       (*elfregs)[7] = t->thread.ds; 
-       (*elfregs)[9] = t->thread.fsindex; 
-       (*elfregs)[10] = t->thread.gsindex; 
-       (*elfregs)[8] = t->thread.es;   
+       elfregs->ds = t->thread.ds;
+       elfregs->fs = t->thread.fsindex;
+       elfregs->gs = t->thread.gsindex;
+       elfregs->es = t->thread.es;
        return 1; 
 }
 
+#define elf_core_copy_task_fpregs      elf32_core_copy_task_fpregs
 static inline int 
-elf_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *regs, elf_fpregset_t *fpu)
+elf32_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *regs,
+                           elf_fpregset_t *fpu)
 {
        struct _fpstate_ia32 *fpstate = (void*)fpu; 
        mm_segment_t oldfs = get_fs();
@@ -186,8 +148,9 @@ elf_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *regs, elf_fpr
 
 #define ELF_CORE_COPY_XFPREGS 1
 #define ELF_CORE_XFPREG_TYPE NT_PRXFPREG
+#define elf_core_copy_task_xfpregs     elf32_core_copy_task_xfpregs
 static inline int 
-elf_core_copy_task_xfpregs(struct task_struct *t, elf_fpxregset_t *xfpu)
+elf32_core_copy_task_xfpregs(struct task_struct *t, elf_fpxregset_t *xfpu)
 {
        struct pt_regs *regs = task_pt_regs(t);
        if (!tsk_used_math(t))
@@ -206,6 +169,10 @@ elf_core_copy_task_xfpregs(struct task_struct *t, elf_fpxregset_t *xfpu)
 
 extern int force_personality32;
 
+#undef ELF_EXEC_PAGESIZE
+#undef ELF_HWCAP
+#undef ELF_PLATFORM
+#undef SET_PERSONALITY
 #define ELF_EXEC_PAGESIZE PAGE_SIZE
 #define ELF_HWCAP (boot_cpu_data.x86_capability[0])
 #define ELF_PLATFORM  ("i686")
@@ -231,6 +198,7 @@ do {                                                        \
 
 #define load_elf_binary load_elf32_binary
 
+#undef ELF_PLAT_INIT
 #define ELF_PLAT_INIT(r, load_addr)    elf32_init(r)
 
 #undef start_thread
@@ -289,7 +257,6 @@ static void elf32_init(struct pt_regs *regs)
 
 static ctl_table abi_table2[] = {
        {
-               .ctl_name       = 99,
                .procname       = "vsyscall32",
                .data           = &sysctl_vsyscall32,
                .maxlen         = sizeof(int),
index a3fa11f8f4609f6744cba78d95cd829dd617a4ea..ccea590bbb920e914358a77083ec8a7f3cdd423c 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for the linux kernel.
 #
 
-extra-y := head_32.o init_task_32.o vmlinux.lds
+extra-y := head_32.o init_task.o vmlinux.lds
 
 obj-y  := process_32.o signal_32.o entry_32.o traps_32.o irq_32.o \
                ptrace_32.o time_32.o ioport_32.o ldt_32.o setup_32.o i8259_32.o sys_i386_32.o \
@@ -17,6 +17,7 @@ obj-$(CONFIG_MCA)             += mca_32.o
 obj-$(CONFIG_X86_MSR)          += msr.o
 obj-$(CONFIG_X86_CPUID)                += cpuid.o
 obj-$(CONFIG_MICROCODE)                += microcode.o
+obj-$(CONFIG_PCI)              += early-quirks.o
 obj-$(CONFIG_APM)              += apm_32.o
 obj-$(CONFIG_X86_SMP)          += smp_32.o smpboot_32.o tsc_sync.o
 obj-$(CONFIG_SMP)              += smpcommon_32.o
index 43da66213a479117a91c05f62e4b67447d412205..dec06e769281b18751d5518e9528b84646101ec9 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for the linux kernel.
 #
 
-extra-y        := head_64.o head64.o init_task_64.o vmlinux.lds
+extra-y        := head_64.o head64.o init_task.o vmlinux.lds
 EXTRA_AFLAGS   := -traditional
 obj-y  := process_64.o signal_64.o entry_64.o traps_64.o irq_64.o \
                ptrace_64.o time_64.o ioport_64.o ldt_64.o setup_64.o i8259_64.o sys_x86_64.o \
@@ -39,7 +39,7 @@ obj-$(CONFIG_K8_NB)           += k8.o
 obj-$(CONFIG_AUDIT)            += audit_64.o
 
 obj-$(CONFIG_MODULES)          += module_64.o
-obj-$(CONFIG_PCI)              += early-quirks_64.o
+obj-$(CONFIG_PCI)              += early-quirks.o
 
 obj-y                          += topology.o
 obj-y                          += intel_cacheinfo.o
index a4852a2e9190c147f1faa66ac3ba271e9f3a8a6c..045dd54b33e052498a3f6a2ab7445156cff1d704 100644 (file)
@@ -1,7 +1,4 @@
 obj-$(CONFIG_ACPI)             += boot.o
-ifneq ($(CONFIG_PCI),)
-obj-$(CONFIG_X86_IO_APIC)      += earlyquirk_32.o
-endif
 obj-$(CONFIG_ACPI_SLEEP)       += sleep_32.o wakeup_32.o
 
 ifneq ($(CONFIG_ACPI_PROCESSOR),)
index afd2afe9102d33e26d8c837333ca4115215d578b..289247d974c60fe77ed4b989a2a2634734392ab9 100644 (file)
@@ -99,7 +99,7 @@ static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
 
 /*
  * The default interrupt routing model is PIC (8259).  This gets
- * overriden if IOAPICs are enumerated (below).
+ * overridden if IOAPICs are enumerated (below).
  */
 enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC;
 
@@ -414,8 +414,8 @@ acpi_parse_nmi_src(struct acpi_subtable_header * header, const unsigned long end
  *
  * Port 0x4d0-4d1 are ECLR1 and ECLR2, the Edge/Level Control Registers
  * for the 8259 PIC.  bit[n] = 1 means irq[n] is Level, otherwise Edge.
- * ECLR1 is IRQ's 0-7 (IRQ 0, 1, 2 must be 0)
- * ECLR2 is IRQ's 8-15 (IRQ 8, 13 must be 0)
+ * ECLR1 is IRQs 0-7 (IRQ 0, 1, 2 must be 0)
+ * ECLR2 is IRQs 8-15 (IRQ 8, 13 must be 0)
  */
 
 void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
@@ -427,7 +427,7 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
        old = inb(0x4d0) | (inb(0x4d1) << 8);
 
        /*
-        * If we use ACPI to set PCI irq's, then we should clear ELCR
+        * If we use ACPI to set PCI IRQs, then we should clear ELCR
         * since we will set it correctly as we enable the PCI irq
         * routing.
         */
@@ -555,7 +555,7 @@ EXPORT_SYMBOL(acpi_map_lsapic);
 
 int acpi_unmap_lsapic(int cpu)
 {
-       x86_cpu_to_apicid[cpu] = -1;
+       per_cpu(x86_cpu_to_apicid, cpu) = -1;
        cpu_clear(cpu, cpu_present_map);
        num_processors--;
 
index 2d39f55d29a88ca36283d2f87206cd646649e521..10b67170b133eccc3ed2dff7fef44e95a44e76ad 100644 (file)
@@ -29,7 +29,7 @@
 void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags,
                                        unsigned int cpu)
 {
-       struct cpuinfo_x86 *c = cpu_data + cpu;
+       struct cpuinfo_x86 *c = &cpu_data(cpu);
 
        flags->bm_check = 0;
        if (num_online_cpus() == 1)
@@ -72,7 +72,7 @@ int acpi_processor_ffh_cstate_probe(unsigned int cpu,
                struct acpi_processor_cx *cx, struct acpi_power_register *reg)
 {
        struct cstate_entry *percpu_entry;
-       struct cpuinfo_x86 *c = cpu_data + cpu;
+       struct cpuinfo_x86 *c = &cpu_data(cpu);
 
        cpumask_t saved_mask;
        int retval;
diff --git a/arch/x86/kernel/acpi/earlyquirk_32.c b/arch/x86/kernel/acpi/earlyquirk_32.c
deleted file mode 100644 (file)
index 23f78ef..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/* 
- * Do early PCI probing for bug detection when the main PCI subsystem is 
- * not up yet.
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/acpi.h>
-
-#include <asm/pci-direct.h>
-#include <asm/acpi.h>
-#include <asm/apic.h>
-
-#ifdef CONFIG_ACPI
-
-static int __init nvidia_hpet_check(struct acpi_table_header *header)
-{
-       return 0;
-}
-#endif
-
-static int __init check_bridge(int vendor, int device)
-{
-#ifdef CONFIG_ACPI
-       static int warned;
-       /* According to Nvidia all timer overrides are bogus unless HPET
-          is enabled. */
-       if (!acpi_use_timer_override && vendor == PCI_VENDOR_ID_NVIDIA) {
-               if (!warned && acpi_table_parse(ACPI_SIG_HPET,
-                                               nvidia_hpet_check)) {
-                       warned = 1;
-                       acpi_skip_timer_override = 1;
-                         printk(KERN_INFO "Nvidia board "
-                       "detected. Ignoring ACPI "
-                       "timer override.\n");
-                printk(KERN_INFO "If you got timer trouble "
-                                "try acpi_use_timer_override\n");
-
-               }
-       }
-#endif
-       if (vendor == PCI_VENDOR_ID_ATI && timer_over_8254 == 1) {
-               timer_over_8254 = 0;
-               printk(KERN_INFO "ATI board detected. Disabling timer routing "
-                               "over 8254.\n");
-       }
-       return 0;
-}
-
-void __init check_acpi_pci(void)
-{
-       int num, slot, func;
-
-       /* Assume the machine supports type 1. If not it will 
-          always read ffffffff and should not have any side effect.
-          Actually a few buggy systems can machine check. Allow the user
-          to disable it by command line option at least -AK */
-       if (!early_pci_allowed())
-               return;
-
-       /* Poor man's PCI discovery */
-       for (num = 0; num < 32; num++) {
-               for (slot = 0; slot < 32; slot++) {
-                       for (func = 0; func < 8; func++) {
-                               u32 class;
-                               u32 vendor;
-                               class = read_pci_config(num, slot, func,
-                                                       PCI_CLASS_REVISION);
-                               if (class == 0xffffffff)
-                                       break;
-
-                               if ((class >> 16) != PCI_CLASS_BRIDGE_PCI)
-                                       continue;
-
-                               vendor = read_pci_config(num, slot, func,
-                                                        PCI_VENDOR_ID);
-
-                               if (check_bridge(vendor & 0xffff, vendor >> 16))
-                                       return;
-                       }
-
-               }
-       }
-}
index b54fded49834ade14daa22ce53418fc501c5653f..2ed0a4ce62f02ebc77750fe11adec66e7e6f9f8e 100644 (file)
@@ -63,7 +63,7 @@ static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c)
 void arch_acpi_processor_init_pdc(struct acpi_processor *pr)
 {
        unsigned int cpu = pr->id;
-       struct cpuinfo_x86 *c = cpu_data + cpu;
+       struct cpuinfo_x86 *c = &cpu_data(cpu);
 
        pr->pdc = NULL;
        if (c->x86_vendor == X86_VENDOR_INTEL)
index f22ba8534d26ee19488753eacd2e1057ab841a33..a97313b1270ec3c5f2771744c9bc024f1d6154df 100644 (file)
@@ -11,7 +11,7 @@
 #
 # If physical address of wakeup_code is 0x12345, BIOS should call us with
 # cs = 0x1234, eip = 0x05
-# 
+#
 
 #define BEEP \
        inb     $97, %al;       \
@@ -52,7 +52,6 @@ wakeup_code:
        BEEP
 1:
        mov     $(wakeup_stack - wakeup_code), %sp              # Private stack is needed for ASUS board
-       movw    $0x0e00 + 'S', %fs:(0x12)
 
        pushl   $0                                              # Kill any dangerous flags
        popfl
@@ -90,9 +89,6 @@ wakeup_code:
        # make sure %cr4 is set correctly (features, etc)
        movl    real_save_cr4 - wakeup_code, %eax
        movl    %eax, %cr4
-       movw    $0xb800, %ax
-       movw    %ax,%fs
-       movw    $0x0e00 + 'i', %fs:(0x12)
        
        # need a gdt -- use lgdtl to force 32-bit operands, in case
        # the GDT is located past 16 megabytes.
@@ -102,8 +98,6 @@ wakeup_code:
        movl    %eax, %cr0
        jmp 1f
 1:
-       movw    $0x0e00 + 'n', %fs:(0x14)
-
        movl    real_magic - wakeup_code, %eax
        cmpl    $0x12345678, %eax
        jne     bogus_real_magic
@@ -122,13 +116,11 @@ real_save_cr4:    .long 0
 real_magic:    .long 0
 video_mode:    .long 0
 realmode_flags:        .long 0
-beep_flags:    .long 0
 real_efer_save_restore:        .long 0
 real_save_efer_edx:    .long 0
 real_save_efer_eax:    .long 0
 
 bogus_real_magic:
-       movw    $0x0e00 + 'B', %fs:(0x12)
        jmp bogus_real_magic
 
 /* This code uses an extended set of video mode numbers. These include:
@@ -194,7 +186,6 @@ wakeup_pmode_return:
        movw    %ax, %es
        movw    %ax, %fs
        movw    %ax, %gs
-       movw    $0x0e00 + 'u', 0xb8016
 
        # reload the gdt, as we need the full 32 bit address
        lgdt    saved_gdt
@@ -218,7 +209,6 @@ wakeup_pmode_return:
        jmp     *%eax
 
 bogus_magic:
-       movw    $0x0e00 + 'B', 0xb8018
        jmp     bogus_magic
 
 
index 8b4357e1efe0b97dc37b24e5d4cc66321ecfc0cb..55608ec2ed721dff6e0cd9c705e628763bfea039 100644 (file)
@@ -41,7 +41,6 @@ wakeup_code:
 
 # Running in *copy* of this code, somewhere in low 1MB.
 
-       movb    $0xa1, %al      ;  outb %al, $0x80
        cli
        cld
        # setup data segment
@@ -65,11 +64,6 @@ wakeup_code:
        cmpl    $0x12345678, %eax
        jne     bogus_real_magic
 
-       call    verify_cpu                      # Verify the cpu supports long
-                                               # mode
-       testl   %eax, %eax
-       jnz     no_longmode
-
        testl   $1, realmode_flags - wakeup_code
        jz      1f
        lcall   $0xc000,$3
@@ -84,12 +78,6 @@ wakeup_code:
        call    mode_set
 1:
 
-       movw    $0xb800, %ax
-       movw    %ax,%fs
-       movw    $0x0e00 + 'L', %fs:(0x10)
-
-       movb    $0xa2, %al      ;  outb %al, $0x80
-       
        mov     %ds, %ax                        # Find 32bit wakeup_code addr
        movzx   %ax, %esi                       # (Convert %ds:gdt to a liner ptr)
        shll    $4, %esi
@@ -117,14 +105,10 @@ wakeup_32_vector:
        .code32
 wakeup_32:
 # Running in this code, but at low address; paging is not yet turned on.
-       movb    $0xa5, %al      ;  outb %al, $0x80
 
        movl    $__KERNEL_DS, %eax
        movl    %eax, %ds
 
-       movw    $0x0e00 + 'i', %ds:(0xb8012)
-       movb    $0xa8, %al      ;  outb %al, $0x80;
-
        /*
         * Prepare for entering 64bits mode
         */
@@ -200,16 +184,11 @@ wakeup_long64:
         */
        lgdt    cpu_gdt_descr
 
-       movw    $0x0e00 + 'n', %ds:(0xb8014)
-       movb    $0xa9, %al      ;  outb %al, $0x80
-
        movq    saved_magic, %rax
        movq    $0x123456789abcdef0, %rdx
        cmpq    %rdx, %rax
        jne     bogus_64_magic
 
-       movw    $0x0e00 + 'u', %ds:(0xb8016)
-       
        nop
        nop
        movw    $__KERNEL_DS, %ax
@@ -220,13 +199,11 @@ wakeup_long64:
        movw    %ax, %gs
        movq    saved_rsp, %rsp
 
-       movw    $0x0e00 + 'x', %ds:(0xb8018)
        movq    saved_rbx, %rbx
        movq    saved_rdi, %rdi
        movq    saved_rsi, %rsi
        movq    saved_rbp, %rbp
 
-       movw    $0x0e00 + '!', %ds:(0xb801a)
        movq    saved_rip, %rax
        jmp     *%rax
 
@@ -256,21 +233,12 @@ realmode_flags:   .quad 0
 
 .code16
 bogus_real_magic:
-       movb    $0xba,%al       ;  outb %al,$0x80
        jmp bogus_real_magic
 
 .code64
 bogus_64_magic:
-       movb    $0xb3,%al       ;  outb %al,$0x80
        jmp bogus_64_magic
 
-.code16
-no_longmode:
-       movb    $0xbc,%al       ;  outb %al,$0x80
-       jmp no_longmode
-
-#include "../verify_cpu_64.S"
-       
 /* This code uses an extended set of video mode numbers. These include:
  * Aliases for standard modes
  *     NORMAL_VGA (-1)
index 3bd2688bd4432a9cab554d6c665e1ceb64e9d410..d6405e0842b55d35835a9ffa203c6b22ea41c189 100644 (file)
@@ -357,14 +357,14 @@ void alternatives_smp_switch(int smp)
        if (smp) {
                printk(KERN_INFO "SMP alternatives: switching to SMP code\n");
                clear_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability);
-               clear_bit(X86_FEATURE_UP, cpu_data[0].x86_capability);
+               clear_bit(X86_FEATURE_UP, cpu_data(0).x86_capability);
                list_for_each_entry(mod, &smp_alt_modules, next)
                        alternatives_smp_lock(mod->locks, mod->locks_end,
                                              mod->text, mod->text_end);
        } else {
                printk(KERN_INFO "SMP alternatives: switching to UP code\n");
                set_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability);
-               set_bit(X86_FEATURE_UP, cpu_data[0].x86_capability);
+               set_bit(X86_FEATURE_UP, cpu_data(0).x86_capability);
                list_for_each_entry(mod, &smp_alt_modules, next)
                        alternatives_smp_unlock(mod->locks, mod->locks_end,
                                                mod->text, mod->text_end);
@@ -432,7 +432,7 @@ void __init alternative_instructions(void)
                if (1 == num_possible_cpus()) {
                        printk(KERN_INFO "SMP alternatives: switching to UP code\n");
                        set_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability);
-                       set_bit(X86_FEATURE_UP, cpu_data[0].x86_capability);
+                       set_bit(X86_FEATURE_UP, cpu_data(0).x86_capability);
                        alternatives_smp_unlock(__smp_locks, __smp_locks_end,
                                                _text, _etext);
                }
index 793341fffc81af62eb9049fbafd535d0c216eea9..08b07c176962f9c525d402adf5609d5c7c64f771 100644 (file)
@@ -947,7 +947,7 @@ void __devinit setup_local_APIC(void)
         * Set up LVT0, LVT1:
         *
         * set up through-local-APIC on the BP's LINT0. This is not
-        * strictly necessery in pure symmetric-IO mode, but sometimes
+        * strictly necessary in pure symmetric-IO mode, but sometimes
         * we delegate interrupts to the 8259A.
         */
        /*
@@ -998,7 +998,7 @@ void __devinit setup_local_APIC(void)
        } else {
                if (esr_disable)
                        /*
-                        * Something untraceble is creating bad interrupts on
+                        * 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
index 32f2365c26ed3bcaef228f0d494f3edc18145d4f..17089a041028d5447f2c20503b10dd1058b030d5 100644 (file)
@@ -57,7 +57,7 @@
  *         screen-blanking and gpm (Stephen Rothwell); Linux 1.99.4
  *    1.2a:Simple change to stop mysterious bug reports with SMP also added
  *        levels to the printk calls. APM is not defined for SMP machines.
- *         The new replacment for it is, but Linux doesn't yet support this.
+ *         The new replacement for it is, but Linux doesn't yet support this.
  *         Alan Cox Linux 2.1.55
  *    1.3: Set up a valid data descriptor 0x40 for buggy BIOS's
  *    1.4: Upgraded to support APM 1.2. Integrated ThinkPad suspend patch by
index f1b7cdda82b358ff1e8538368848b59d9c05340d..0e45981b2dd7f15406962ec8f85d334e21451ff1 100644 (file)
@@ -15,6 +15,7 @@
 #include <asm/fixmap.h>
 #include <asm/processor.h>
 #include <asm/thread_info.h>
+#include <asm/bootparam.h>
 #include <asm/elf.h>
 
 #include <xen/interface/xen.h>
@@ -135,6 +136,7 @@ void foo(void)
 #ifdef CONFIG_LGUEST_GUEST
        BLANK();
        OFFSET(LGUEST_DATA_irq_enabled, lguest_data, irq_enabled);
+       OFFSET(LGUEST_DATA_pgdir, lguest_data, pgdir);
        OFFSET(LGUEST_PAGES_host_gdt_desc, lguest_pages, state.host_gdt_desc);
        OFFSET(LGUEST_PAGES_host_idt_desc, lguest_pages, state.host_idt_desc);
        OFFSET(LGUEST_PAGES_host_cr3, lguest_pages, state.host_cr3);
@@ -146,4 +148,10 @@ void foo(void)
        OFFSET(LGUEST_PAGES_regs_errcode, lguest_pages, regs.errcode);
        OFFSET(LGUEST_PAGES_regs, lguest_pages, regs);
 #endif
+
+       BLANK();
+       OFFSET(BP_scratch, boot_params, scratch);
+       OFFSET(BP_loadflags, boot_params, hdr.loadflags);
+       OFFSET(BP_hardware_subarch, boot_params, hdr.hardware_subarch);
+       OFFSET(BP_version, boot_params, hdr.version);
 }
index 5f8af875f457bcaa99dda66e2deee7179f925ae9..1ff88c7f45cff837b581c02cc6a8beda9bb70947 100644 (file)
@@ -266,7 +266,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
 #ifdef CONFIG_X86_HT
        /*
         * On a AMD multi core setup the lower bits of the APIC id
-        * distingush the cores.
+        * distinguish the cores.
         */
        if (c->x86_max_cores > 1) {
                int cpu = smp_processor_id();
index 473eac883c7b4133e8af4f8251bbbbd19b207da8..9681fa15ddf076f43e02741c7f4f9bbadfab6554 100644 (file)
@@ -53,7 +53,7 @@ static u32 __cpuinit ramtop(void)             /* 16388 */
                        continue;
                /*
                 *      Don't MCR over reserved space. Ignore the ISA hole
-                *      we frob around that catastrophy already
+                *      we frob around that catastrophe already
                 */
                                        
                if (e820.map[i].type == E820_RESERVED)
@@ -287,7 +287,7 @@ static void __cpuinit init_c3(struct cpuinfo_x86 *c)
                c->x86_capability[5] = cpuid_edx(0xC0000001);
        }
 
-       /* Cyrix III family needs CX8 & PGE explicity enabled. */
+       /* Cyrix III family needs CX8 & PGE explicitly enabled. */
        if (c->x86_model >=6 && c->x86_model <= 9) {
                rdmsr (MSR_VIA_FCR, lo, hi);
                lo |= (1<<1 | 1<<7);
index d506201d397c5fb2e13b364189a37d058876dd46..e2fcf2051bdb26c87161b4c6dc90b5d0a893ce7a 100644 (file)
@@ -207,7 +207,7 @@ static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c, int early)
 
 static int __init x86_fxsr_setup(char * s)
 {
-       /* Tell all the other CPU's to not use it... */
+       /* Tell all the other CPUs to not use it... */
        disable_x86_fxsr = 1;
 
        /*
similarity index 97%
rename from arch/x86/kernel/cpufreq/Kconfig
rename to arch/x86/kernel/cpu/cpufreq/Kconfig_64
index a3fd51926cbd0fe0c59185f8a94764505a961560..9c9699fdcf52b896fe0b5667d55484ea838a9b0d 100644 (file)
@@ -19,7 +19,7 @@ config X86_POWERNOW_K8
          To compile this driver as a module, choose M here: the
          module will be called powernow-k8.
 
-         For details, take a look at <file:Documentation/cpu-freq/>. 
+         For details, take a look at <file:Documentation/cpu-freq/>.
 
          If in doubt, say N.
 
index 2ca43ba32bc0ea50e99c4f872dfac269bde7ee8f..fea0af0476b96371f4c71fabcb463ab65d74fc89 100644 (file)
@@ -77,7 +77,7 @@ static unsigned int acpi_pstate_strict;
 
 static int check_est_cpu(unsigned int cpuid)
 {
-       struct cpuinfo_x86 *cpu = &cpu_data[cpuid];
+       struct cpuinfo_x86 *cpu = &cpu_data(cpuid);
 
        if (cpu->x86_vendor != X86_VENDOR_INTEL ||
            !cpu_has(cpu, X86_FEATURE_EST))
@@ -560,7 +560,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
        unsigned int cpu = policy->cpu;
        struct acpi_cpufreq_data *data;
        unsigned int result = 0;
-       struct cpuinfo_x86 *c = &cpu_data[policy->cpu];
+       struct cpuinfo_x86 *c = &cpu_data(policy->cpu);
        struct acpi_processor_performance *perf;
 
        dprintk("acpi_cpufreq_cpu_init\n");
index 32f0bda3fc953a4568c194b13773f5a70ba22c69..f03e9153618e52d68f2730f7e7a07e3d9fd71c2b 100644 (file)
@@ -260,7 +260,7 @@ static int nforce2_target(struct cpufreq_policy *policy,
 
        freqs.old = nforce2_get(policy->cpu);
        freqs.new = target_fsb * fid * 100;
-       freqs.cpu = 0;          /* Only one CPU on nForce2 plattforms */
+       freqs.cpu = 0;          /* Only one CPU on nForce2 platforms */
 
        if (freqs.old == freqs.new)
                return 0;
index c11baaf9f2b403f6624e1fa0d4fd5756491d8383..326a4c81f68493cd8802ce13093689858577ad63 100644 (file)
@@ -305,7 +305,7 @@ static struct cpufreq_driver eps_driver = {
 
 static int __init eps_init(void)
 {
-       struct cpuinfo_x86 *c = cpu_data;
+       struct cpuinfo_x86 *c = &cpu_data(0);
 
        /* This driver will work only on Centaur C7 processors with
         * Enhanced SpeedStep/PowerSaver registers */
index 1e7ae7dafcf6a50921d1271347e2f522ad13ad2b..94619c22f56326a555fa47114bf2df365634343a 100644 (file)
@@ -199,7 +199,7 @@ static int elanfreq_target (struct cpufreq_policy *policy,
 
 static int elanfreq_cpu_init(struct cpufreq_policy *policy)
 {
-       struct cpuinfo_x86 *c = cpu_data;
+       struct cpuinfo_x86 *c = &cpu_data(0);
        unsigned int i;
        int result;
 
@@ -280,7 +280,7 @@ static struct cpufreq_driver elanfreq_driver = {
 
 static int __init elanfreq_init(void)
 {
-       struct cpuinfo_x86 *c = cpu_data;
+       struct cpuinfo_x86 *c = &cpu_data(0);
 
        /* Test if we have the right hardware */
        if ((c->x86_vendor != X86_VENDOR_AMD) ||
index ed2bda127c44b8734fbc88af3bc394ed95290ff9..2ed7db2fd257b3a25c78dd61dd48683bb60a49f7 100644 (file)
  *      of any nature resulting due to the use of this software. This
  *      software is provided AS-IS with no warranties.
  *
- * Theoritical note:
+ * Theoretical note:
  *
  *     (see Geode(tm) CS5530 manual (rev.4.1) page.56)
  *
  *     CPU frequency control on NatSemi Geode GX1/GXLV processor and CS55x0
- *     are based on Suspend Moduration.
+ *     are based on Suspend Modulation.
  *
  *     Suspend Modulation works by asserting and de-asserting the SUSP# pin
  *     to CPU(GX1/GXLV) for configurable durations. When asserting SUSP#
 
 /* SUSCFG bits */
 #define SUSMOD         (1<<0)  /* enable/disable suspend modulation */
-/* the belows support only with cs5530 (after rev.1.2)/cs5530A */
+/* the below is supported only with cs5530 (after rev.1.2)/cs5530A */
 #define SMISPDUP       (1<<1)  /* select how SMI re-enable suspend modulation: */
                                /* IRQTC timer or read SMI speedup disable reg.(F1BAR[08-09h]) */
 #define SUSCFG         (1<<2)  /* enable powering down a GXLV processor. "Special 3Volt Suspend" mode */
-/* the belows support only with cs5530A */
+/* the below is supported only with cs5530A */
 #define PWRSVE_ISA     (1<<3)  /* stop ISA clock  */
 #define PWRSVE         (1<<4)  /* active idle */
 
index 5045f5d583c81954fa7123df8697188a39012583..749d00cb2ebdde52ae67719ecc4514191b6c20fe 100644 (file)
@@ -780,7 +780,7 @@ static int longhaul_setup_southbridge(void)
 
 static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
 {
-       struct cpuinfo_x86 *c = cpu_data;
+       struct cpuinfo_x86 *c = &cpu_data(0);
        char *cpuname=NULL;
        int ret;
        u32 lo, hi;
@@ -959,7 +959,7 @@ static struct cpufreq_driver longhaul_driver = {
 
 static int __init longhaul_init(void)
 {
-       struct cpuinfo_x86 *c = cpu_data;
+       struct cpuinfo_x86 *c = &cpu_data(0);
 
        if (c->x86_vendor != X86_VENDOR_CENTAUR || c->x86 != 6)
                return -ENODEV;
index b2689514295ab361057623dd7c2afb56d7deb81e..af4a867a097cdcc5f8296eca454199e39a56e675 100644 (file)
@@ -172,7 +172,7 @@ static unsigned int __init longrun_determine_freqs(unsigned int *low_freq,
        u32 save_lo, save_hi;
        u32 eax, ebx, ecx, edx;
        u32 try_hi;
-       struct cpuinfo_x86 *c = cpu_data;
+       struct cpuinfo_x86 *c = &cpu_data(0);
 
        if (!low_freq || !high_freq)
                return -EINVAL;
@@ -298,7 +298,7 @@ static struct cpufreq_driver longrun_driver = {
  */
 static int __init longrun_init(void)
 {
-       struct cpuinfo_x86 *c = cpu_data;
+       struct cpuinfo_x86 *c = &cpu_data(0);
 
        if (c->x86_vendor != X86_VENDOR_TRANSMETA ||
            !cpu_has(c, X86_FEATURE_LONGRUN))
index 793eae854f4f779e26ba95404a054c94349cc395..14791ec55cfd16798eb0366cb908b31d0dedf1e7 100644 (file)
@@ -195,7 +195,7 @@ static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c)
 
 static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
 {
-       struct cpuinfo_x86 *c = &cpu_data[policy->cpu];
+       struct cpuinfo_x86 *c = &cpu_data(policy->cpu);
        int cpuid = 0;
        unsigned int i;
 
@@ -279,7 +279,7 @@ static struct cpufreq_driver p4clockmod_driver = {
 
 static int __init cpufreq_p4_init(void)
 {
-       struct cpuinfo_x86 *c = cpu_data;
+       struct cpuinfo_x86 *c = &cpu_data(0);
        int ret;
 
        /*
index 6d02853393175305e8f749b99a8500379d1353d2..eb9b62b0830c8941ee7ea990304596e2a1d82316 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  This file was based upon code in Powertweak Linux (http://powertweak.sf.net)
- *  (C) 2000-2003  Dave Jones, Arjan van de Ven, Janne Pänkälä, Dominik Brodowski.
+ *  (C) 2000-2003  Dave Jones, Arjan van de Ven, Janne Pänkälä, Dominik Brodowski.
  *
  *  Licensed under the terms of the GNU GPL License version 2.
  *
@@ -215,7 +215,7 @@ static struct cpufreq_driver powernow_k6_driver = {
  */
 static int __init powernow_k6_init(void)
 {
-       struct cpuinfo_x86      *c = cpu_data;
+       struct cpuinfo_x86 *c = &cpu_data(0);
 
        if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 5) ||
                ((c->x86_model != 12) && (c->x86_model != 13)))
index f3686a5f2308ab0d9832fad24df58fb7bb4b07e9..b5a9863d6cdc336ce7b13f5c9d797944b179cbc6 100644 (file)
@@ -114,7 +114,7 @@ static int check_fsb(unsigned int fsbspeed)
 
 static int check_powernow(void)
 {
-       struct cpuinfo_x86 *c = cpu_data;
+       struct cpuinfo_x86 *c = &cpu_data(0);
        unsigned int maxei, eax, ebx, ecx, edx;
 
        if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 !=6)) {
index c06ac680c9cace052135ed7e790118a7b4e71c86..9c36a53676b770830e1efffb5770788d34ab2ee4 100644 (file)
@@ -168,7 +168,7 @@ static void count_off_irt(struct powernow_k8_data *data)
        return;
 }
 
-/* the voltage stabalization time */
+/* the voltage stabilization time */
 static void count_off_vst(struct powernow_k8_data *data)
 {
        udelay(data->vstable * VST_UNITS_20US);
index b06c812208ca488a8b427fcfd9bb60edc28ec900..7c4f6e0faed4a555ac599837d347dee7958d4feb 100644 (file)
@@ -148,10 +148,10 @@ struct powernow_k8_data {
 #define PLL_LOCK_CONVERSION (1000/5) /* ms to ns, then divide by clock period */
 
 #define MAXIMUM_VID_STEPS 1  /* Current cpus only allow a single step of 25mV */
-#define VST_UNITS_20US 20   /* Voltage Stabalization Time is in units of 20us */
+#define VST_UNITS_20US 20   /* Voltage Stabilization Time is in units of 20us */
 
 /*
- * Most values of interest are enocoded in a single field of the _PSS
+ * Most values of interest are encoded in a single field of the _PSS
  * entries: the "control" value.
  */
 
index d9f3e90a7ae080c9ba1e316c56ccb3afe6022231..42da9bd677d6ee91ed3cb41f2b09c62d3bf5b26b 100644 (file)
@@ -102,7 +102,7 @@ static int sc520_freq_target (struct cpufreq_policy *policy,
 
 static int sc520_freq_cpu_init(struct cpufreq_policy *policy)
 {
-       struct cpuinfo_x86 *c = cpu_data;
+       struct cpuinfo_x86 *c = &cpu_data(0);
        int result;
 
        /* capability check */
@@ -151,7 +151,7 @@ static struct cpufreq_driver sc520_freq_driver = {
 
 static int __init sc520_freq_init(void)
 {
-       struct cpuinfo_x86 *c = cpu_data;
+       struct cpuinfo_x86 *c = &cpu_data(0);
        int err;
 
        /* Test if we have the right hardware */
index 811d47438546974e41651794cecf380a26e53c33..3031f119619212d40946ee2d0b297bf8a43bc576 100644 (file)
@@ -230,7 +230,7 @@ static struct cpu_model models[] =
 
 static int centrino_cpu_init_table(struct cpufreq_policy *policy)
 {
-       struct cpuinfo_x86 *cpu = &cpu_data[policy->cpu];
+       struct cpuinfo_x86 *cpu = &cpu_data(policy->cpu);
        struct cpu_model *model;
 
        for(model = models; model->cpu_id != NULL; model++)
@@ -340,7 +340,7 @@ static unsigned int get_cur_freq(unsigned int cpu)
 
 static int centrino_cpu_init(struct cpufreq_policy *policy)
 {
-       struct cpuinfo_x86 *cpu = &cpu_data[policy->cpu];
+       struct cpuinfo_x86 *cpu = &cpu_data(policy->cpu);
        unsigned freq;
        unsigned l, h;
        int ret;
@@ -612,7 +612,7 @@ static struct cpufreq_driver centrino_driver = {
  */
 static int __init centrino_init(void)
 {
-       struct cpuinfo_x86 *cpu = cpu_data;
+       struct cpuinfo_x86 *cpu = &cpu_data(0);
 
        if (!cpu_has(cpu, X86_FEATURE_EST))
                return -ENODEV;
index b1acc8ce3167c8f02d0747f7282fc8b685e1d94a..76c3ab0da468db354af1d55da7f5b5af39fdca50 100644 (file)
@@ -228,7 +228,7 @@ EXPORT_SYMBOL_GPL(speedstep_get_processor_frequency);
 
 unsigned int speedstep_detect_processor (void)
 {
-       struct cpuinfo_x86 *c = cpu_data;
+       struct cpuinfo_x86 *c = &cpu_data(0);
        u32 ebx, msr_lo, msr_hi;
 
        dprintk("x86: %x, model: %x\n", c->x86, c->x86_model);
index 122d2d75aa9f9bbce77211038240686ebf2dc7e8..88d66fb8411d183cc5c96091b4722c165a2058bb 100644 (file)
@@ -93,7 +93,7 @@ static void __cpuinit check_cx686_slop(struct cpuinfo_x86 *c)
 
                local_irq_save(flags);
                ccr3 = getCx86(CX86_CCR3);
-               setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN  */
+               setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */
                ccr5 = getCx86(CX86_CCR5);
                if (ccr5 & 2)
                        setCx86(CX86_CCR5, ccr5 & 0xfd);  /* reset SLOP */
@@ -115,9 +115,9 @@ static void __cpuinit set_cx86_reorder(void)
 
        printk(KERN_INFO "Enable Memory access reorder on Cyrix/NSC processor.\n");
        ccr3 = getCx86(CX86_CCR3);
-       setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN  */
+       setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */
 
-       /* Load/Store Serialize to mem access disable (=reorder it)  */
+       /* Load/Store Serialize to mem access disable (=reorder it) */
        setCx86(CX86_PCR0, getCx86(CX86_PCR0) & ~0x80);
        /* set load/store serialize from 1GB to 4GB */
        ccr3 |= 0xe0;
@@ -146,7 +146,7 @@ static void __cpuinit set_cx86_inc(void)
        printk(KERN_INFO "Enable Incrementor on Cyrix/NSC processor.\n");
 
        ccr3 = getCx86(CX86_CCR3);
-       setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN  */
+       setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */
        /* PCR1 -- Performance Control */
        /* Incrementor on, whatever that is */
        setCx86(CX86_PCR1, getCx86(CX86_PCR1) | 0x02);
@@ -256,7 +256,7 @@ static void __cpuinit init_cyrix(struct cpuinfo_x86 *c)
                u32 vendor, device;
                /* It isn't really a PCI quirk directly, but the cure is the
                   same. The MediaGX has deep magic SMM stuff that handles the
-                  SB emulation. It thows away the fifo on disable_dma() which
+                  SB emulation. It throws away the fifo on disable_dma() which
                   is wrong and ruins the audio. 
 
                   Bug2: VSA1 has a wrap bug so that using maximum sized DMA 
index 1826395ebeeb48235e2a51382ce9e426073d769d..9921b01fe19907bd9fb22dc9ca00d3d61e9c4381 100644 (file)
@@ -295,7 +295,7 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
        unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */
        unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb;
 #ifdef CONFIG_X86_HT
-       unsigned int cpu = (c == &boot_cpu_data) ? 0 : (c - cpu_data);
+       unsigned int cpu = c->cpu_index;
 #endif
 
        if (c->cpuid_level > 3) {
@@ -417,14 +417,14 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
        if (new_l2) {
                l2 = new_l2;
 #ifdef CONFIG_X86_HT
-               cpu_llc_id[cpu] = l2_id;
+               per_cpu(cpu_llc_id, cpu) = l2_id;
 #endif
        }
 
        if (new_l3) {
                l3 = new_l3;
 #ifdef CONFIG_X86_HT
-               cpu_llc_id[cpu] = l3_id;
+               per_cpu(cpu_llc_id, cpu) = l3_id;
 #endif
        }
 
@@ -459,7 +459,7 @@ static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
        struct _cpuid4_info     *this_leaf, *sibling_leaf;
        unsigned long num_threads_sharing;
        int index_msb, i;
-       struct cpuinfo_x86 *c = cpu_data;
+       struct cpuinfo_x86 *c = &cpu_data(cpu);
 
        this_leaf = CPUID4_INFO_IDX(cpu, index);
        num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing;
@@ -470,8 +470,8 @@ static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
                index_msb = get_count_order(num_threads_sharing);
 
                for_each_online_cpu(i) {
-                       if (c[i].apicid >> index_msb ==
-                           c[cpu].apicid >> index_msb) {
+                       if (cpu_data(i).apicid >> index_msb ==
+                           c->apicid >> index_msb) {
                                cpu_set(i, this_leaf->shared_cpu_map);
                                if (i != cpu && cpuid4_info[i])  {
                                        sibling_leaf = CPUID4_INFO_IDX(i, index);
@@ -499,6 +499,11 @@ static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index) {
 
 static void free_cache_attributes(unsigned int cpu)
 {
+       int i;
+
+       for (i = 0; i < num_cache_leaves; i++)
+               cache_remove_shared_cpu_map(cpu, i);
+
        kfree(cpuid4_info[cpu]);
        cpuid4_info[cpu] = NULL;
 }
@@ -506,8 +511,8 @@ static void free_cache_attributes(unsigned int cpu)
 static int __cpuinit detect_cache_attributes(unsigned int cpu)
 {
        struct _cpuid4_info     *this_leaf;
-       unsigned long           j;
-       int                     retval;
+       unsigned long           j;
+       int                     retval;
        cpumask_t               oldmask;
 
        if (num_cache_leaves == 0)
@@ -524,19 +529,26 @@ static int __cpuinit detect_cache_attributes(unsigned int cpu)
                goto out;
 
        /* Do cpuid and store the results */
-       retval = 0;
        for (j = 0; j < num_cache_leaves; j++) {
                this_leaf = CPUID4_INFO_IDX(cpu, j);
                retval = cpuid4_cache_lookup(j, this_leaf);
-               if (unlikely(retval < 0))
+               if (unlikely(retval < 0)) {
+                       int i;
+
+                       for (i = 0; i < j; i++)
+                               cache_remove_shared_cpu_map(cpu, i);
                        break;
+               }
                cache_shared_cpu_map_setup(cpu, j);
        }
        set_cpus_allowed(current, oldmask);
 
 out:
-       if (retval)
-               free_cache_attributes(cpu);
+       if (retval) {
+               kfree(cpuid4_info[cpu]);
+               cpuid4_info[cpu] = NULL;
+       }
+
        return retval;
 }
 
@@ -669,7 +681,7 @@ static struct kobj_type ktype_percpu_entry = {
        .sysfs_ops      = &sysfs_ops,
 };
 
-static void cpuid4_cache_sysfs_exit(unsigned int cpu)
+static void __cpuinit cpuid4_cache_sysfs_exit(unsigned int cpu)
 {
        kfree(cache_kobject[cpu]);
        kfree(index_kobject[cpu]);
@@ -680,13 +692,14 @@ static void cpuid4_cache_sysfs_exit(unsigned int cpu)
 
 static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu)
 {
+       int err;
 
        if (num_cache_leaves == 0)
                return -ENOENT;
 
-       detect_cache_attributes(cpu);
-       if (cpuid4_info[cpu] == NULL)
-               return -ENOENT;
+       err = detect_cache_attributes(cpu);
+       if (err)
+               return err;
 
        /* Allocate all required memory */
        cache_kobject[cpu] = kzalloc(sizeof(struct kobject), GFP_KERNEL);
@@ -705,13 +718,15 @@ err_out:
        return -ENOMEM;
 }
 
+static cpumask_t cache_dev_map = CPU_MASK_NONE;
+
 /* Add/Remove cache interface for CPU device */
 static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
 {
        unsigned int cpu = sys_dev->id;
        unsigned long i, j;
        struct _index_kobject *this_object;
-       int retval = 0;
+       int retval;
 
        retval = cpuid4_cache_sysfs_init(cpu);
        if (unlikely(retval < 0))
@@ -721,6 +736,10 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
        kobject_set_name(cache_kobject[cpu], "%s", "cache");
        cache_kobject[cpu]->ktype = &ktype_percpu_entry;
        retval = kobject_register(cache_kobject[cpu]);
+       if (retval < 0) {
+               cpuid4_cache_sysfs_exit(cpu);
+               return retval;
+       }
 
        for (i = 0; i < num_cache_leaves; i++) {
                this_object = INDEX_KOBJECT_PTR(cpu,i);
@@ -740,6 +759,9 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
                        break;
                }
        }
+       if (!retval)
+               cpu_set(cpu, cache_dev_map);
+
        return retval;
 }
 
@@ -750,13 +772,14 @@ static void __cpuinit cache_remove_dev(struct sys_device * sys_dev)
 
        if (cpuid4_info[cpu] == NULL)
                return;
-       for (i = 0; i < num_cache_leaves; i++) {
-               cache_remove_shared_cpu_map(cpu, i);
+       if (!cpu_isset(cpu, cache_dev_map))
+               return;
+       cpu_clear(cpu, cache_dev_map);
+
+       for (i = 0; i < num_cache_leaves; i++)
                kobject_unregister(&(INDEX_KOBJECT_PTR(cpu,i)->kobj));
-       }
        kobject_unregister(cache_kobject[cpu]);
        cpuid4_cache_sysfs_exit(cpu);
-       return;
 }
 
 static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb,
@@ -781,7 +804,7 @@ static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb,
 
 static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier =
 {
-    .notifier_call = cacheinfo_cpu_callback,
+       .notifier_call = cacheinfo_cpu_callback,
 };
 
 static int __cpuinit cache_sysfs_init(void)
@@ -791,14 +814,15 @@ static int __cpuinit cache_sysfs_init(void)
        if (num_cache_leaves == 0)
                return 0;
 
-       register_hotcpu_notifier(&cacheinfo_cpu_notifier);
-
        for_each_online_cpu(i) {
-               struct sys_device *sys_dev = get_cpu_sysdev((unsigned int)i);
+               int err;
+               struct sys_device *sys_dev = get_cpu_sysdev(i);
 
-               cache_add_dev(sys_dev);
+               err = cache_add_dev(sys_dev);
+               if (err)
+                       return err;
        }
-
+       register_hotcpu_notifier(&cacheinfo_cpu_notifier);
        return 0;
 }
 
index 494d320d909b4959ec2a7c95fb411c02ec547e1b..24885be5c48ca5004a899506ad8fda31edf8a7a3 100644 (file)
@@ -131,17 +131,19 @@ static __cpuinit int thermal_throttle_cpu_callback(struct notifier_block *nfb,
 {
        unsigned int cpu = (unsigned long)hcpu;
        struct sys_device *sys_dev;
-       int err;
+       int err = 0;
 
        sys_dev = get_cpu_sysdev(cpu);
        switch (action) {
-       case CPU_ONLINE:
-       case CPU_ONLINE_FROZEN:
+       case CPU_UP_PREPARE:
+       case CPU_UP_PREPARE_FROZEN:
                mutex_lock(&therm_cpu_lock);
                err = thermal_throttle_add_dev(sys_dev);
                mutex_unlock(&therm_cpu_lock);
                WARN_ON(err);
                break;
+       case CPU_UP_CANCELED:
+       case CPU_UP_CANCELED_FROZEN:
        case CPU_DEAD:
        case CPU_DEAD_FROZEN:
                mutex_lock(&therm_cpu_lock);
@@ -149,7 +151,7 @@ static __cpuinit int thermal_throttle_cpu_callback(struct notifier_block *nfb,
                mutex_unlock(&therm_cpu_lock);
                break;
        }
-       return NOTIFY_OK;
+       return err ? NOTIFY_BAD : NOTIFY_OK;
 }
 
 static struct notifier_block thermal_throttle_cpu_notifier __cpuinitdata =
index 2287d4863a8a01f7b060c39ffcebfe05dc33a94e..9964be3de2b7ceb2a80b26561738ab23f5b4ffed 100644 (file)
@@ -147,10 +147,10 @@ static void prepare_set(void)
        write_cr0(cr0);
        wbinvd();
 
-       /* Cyrix ARRs - everything else were excluded at the top */
+       /* Cyrix ARRs - everything else was excluded at the top */
        ccr3 = getCx86(CX86_CCR3);
 
-       /* Cyrix ARRs - everything else were excluded at the top */
+       /* Cyrix ARRs - everything else was excluded at the top */
        setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10);
 
 }
index 56f64e34829f937e878b0855187689e1abb35bab..992f08dfbb6c39d2df5f786d4310fd7d0704cb75 100644 (file)
@@ -182,7 +182,7 @@ static inline void k8_enable_fixed_iorrs(void)
 
 /**
  * Checks and updates an fixed-range MTRR if it differs from the value it
- * should have. If K8 extenstions are wanted, update the K8 SYSCFG MSR also.
+ * should have. If K8 extentions are wanted, update the K8 SYSCFG MSR also.
  * see AMD publication no. 24593, chapter 7.8.1, page 233 for more information
  * \param msr MSR address of the MTTR which should be checked and updated
  * \param changed pointer which indicates whether the MTRR needed to be changed
index 5e4be30ff903800a47ab47bfcec5198aacc7c81e..9abbdf7562c50ffe86a3024d07cc5829f902d8d6 100644 (file)
@@ -748,7 +748,7 @@ static int __init mtrr_init_finialize(void)
        if (use_intel())
                mtrr_state_warn();
        else {
-               /* The CPUs haven't MTRR and seemes not support SMP. They have
+               /* The CPUs haven't MTRR and seem to not support SMP. They have
                 * specific drivers, we use a tricky method to support
                 * suspend/resume for them.
                 * TBD: is there any system with such CPU which supports
index 54cdbf1a40f1a054bb5d9affc0c9c77fb913482b..c02541e6e653f72ae1856df090b0719041cd2664 100644 (file)
@@ -120,7 +120,9 @@ int reserve_perfctr_nmi(unsigned int msr)
        unsigned int counter;
 
        counter = nmi_perfctr_msr_to_bit(msr);
-       BUG_ON(counter > NMI_MAX_COUNTER_BITS);
+       /* register not managed by the allocator? */
+       if (counter > NMI_MAX_COUNTER_BITS)
+               return 1;
 
        if (!test_and_set_bit(counter, perfctr_nmi_owner))
                return 1;
@@ -132,7 +134,9 @@ void release_perfctr_nmi(unsigned int msr)
        unsigned int counter;
 
        counter = nmi_perfctr_msr_to_bit(msr);
-       BUG_ON(counter > NMI_MAX_COUNTER_BITS);
+       /* register not managed by the allocator? */
+       if (counter > NMI_MAX_COUNTER_BITS)
+               return;
 
        clear_bit(counter, perfctr_nmi_owner);
 }
@@ -142,7 +146,9 @@ int reserve_evntsel_nmi(unsigned int msr)
        unsigned int counter;
 
        counter = nmi_evntsel_msr_to_bit(msr);
-       BUG_ON(counter > NMI_MAX_COUNTER_BITS);
+       /* register not managed by the allocator? */
+       if (counter > NMI_MAX_COUNTER_BITS)
+               return 1;
 
        if (!test_and_set_bit(counter, evntsel_nmi_owner))
                return 1;
@@ -154,7 +160,9 @@ void release_evntsel_nmi(unsigned int msr)
        unsigned int counter;
 
        counter = nmi_evntsel_msr_to_bit(msr);
-       BUG_ON(counter > NMI_MAX_COUNTER_BITS);
+       /* register not managed by the allocator? */
+       if (counter > NMI_MAX_COUNTER_BITS)
+               return;
 
        clear_bit(counter, evntsel_nmi_owner);
 }
index 879a0f789b1e223026ec820c873cca43a70dec89..2d42b414b7779b37604d9c564f044642c8cb0832 100644 (file)
@@ -85,12 +85,13 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                /* nothing */
        };
        struct cpuinfo_x86 *c = v;
-       int i, n = c - cpu_data;
+       int i, n = 0;
        int fpu_exception;
 
 #ifdef CONFIG_SMP
        if (!cpu_online(n))
                return 0;
+       n = c->cpu_index;
 #endif
        seq_printf(m, "processor\t: %d\n"
                "vendor_id\t: %s\n"
@@ -175,11 +176,15 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 
 static void *c_start(struct seq_file *m, loff_t *pos)
 {
-       return *pos < NR_CPUS ? cpu_data + *pos : NULL;
+       if (*pos == 0)  /* just in case, cpu 0 is not the first */
+               *pos = first_cpu(cpu_possible_map);
+       if ((*pos) < NR_CPUS && cpu_possible(*pos))
+               return &cpu_data(*pos);
+       return NULL;
 }
 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
 {
-       ++*pos;
+       *pos = next_cpu(*pos, cpu_possible_map);
        return c_start(m, pos);
 }
 static void c_stop(struct seq_file *m, void *v)
index 70dcf912d9fb3076e1116a438a3dcde699205ab9..05c9936a16ccc50c015dae4c3af81552d4564fa7 100644 (file)
@@ -114,7 +114,7 @@ static ssize_t cpuid_read(struct file *file, char __user *buf,
 static int cpuid_open(struct inode *inode, struct file *file)
 {
        unsigned int cpu = iminor(file->f_path.dentry->d_inode);
-       struct cpuinfo_x86 *c = &(cpu_data)[cpu];
+       struct cpuinfo_x86 *c = &cpu_data(cpu);
 
        if (cpu >= NR_CPUS || !cpu_online(cpu))
                return -ENXIO;  /* No such CPU */
@@ -134,15 +134,18 @@ static const struct file_operations cpuid_fops = {
        .open = cpuid_open,
 };
 
-static int __cpuinit cpuid_device_create(int i)
+static __cpuinit int cpuid_device_create(int cpu)
 {
-       int err = 0;
        struct device *dev;
 
-       dev = device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, i), "cpu%d",i);
-       if (IS_ERR(dev))
-               err = PTR_ERR(dev);
-       return err;
+       dev = device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, cpu),
+                           "cpu%d", cpu);
+       return IS_ERR(dev) ? PTR_ERR(dev) : 0;
+}
+
+static void cpuid_device_destroy(int cpu)
+{
+       device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu));
 }
 
 static int __cpuinit cpuid_class_cpu_callback(struct notifier_block *nfb,
@@ -150,18 +153,21 @@ static int __cpuinit cpuid_class_cpu_callback(struct notifier_block *nfb,
                                              void *hcpu)
 {
        unsigned int cpu = (unsigned long)hcpu;
+       int err = 0;
 
        switch (action) {
-       case CPU_ONLINE:
-       case CPU_ONLINE_FROZEN:
-               cpuid_device_create(cpu);
+       case CPU_UP_PREPARE:
+       case CPU_UP_PREPARE_FROZEN:
+               err = cpuid_device_create(cpu);
                break;
+       case CPU_UP_CANCELED:
+       case CPU_UP_CANCELED_FROZEN:
        case CPU_DEAD:
        case CPU_DEAD_FROZEN:
-               device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu));
+               cpuid_device_destroy(cpu);
                break;
        }
-       return NOTIFY_OK;
+       return err ? NOTIFY_BAD : NOTIFY_OK;
 }
 
 static struct notifier_block __cpuinitdata cpuid_class_cpu_notifier =
@@ -198,7 +204,7 @@ static int __init cpuid_init(void)
 out_class:
        i = 0;
        for_each_online_cpu(i) {
-               device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, i));
+               cpuid_device_destroy(i);
        }
        class_destroy(cpuid_class);
 out_chrdev:
@@ -212,7 +218,7 @@ static void __exit cpuid_exit(void)
        int cpu = 0;
 
        for_each_online_cpu(cpu)
-               device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu));
+               cpuid_device_destroy(cpu);
        class_destroy(cpuid_class);
        unregister_chrdev(CPUID_MAJOR, "cpu/cpuid");
        unregister_hotcpu_notifier(&cpuid_class_cpu_notifier);
index 32e75d0731a901681c118fb073944992a082fa1c..72d0c56c1b48eff12779b557a75f3aee376c5571 100644 (file)
@@ -47,6 +47,7 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
                if (!kdump_buf_page) {
                        printk(KERN_WARNING "Kdump: Kdump buffer page not"
                                " allocated\n");
+                       kunmap_atomic(vaddr, KM_PTE0);
                        return -EFAULT;
                }
                copy_page(kdump_buf_page, vaddr);
index 3c86b979a40aed829b52797cd8e90c88a6c8ed81..18f500d185a2ae182b38852d51729a32995faee4 100644 (file)
@@ -51,6 +51,13 @@ struct resource code_resource = {
        .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
 };
 
+struct resource bss_resource = {
+       .name   = "Kernel bss",
+       .start  = 0,
+       .end    = 0,
+       .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
+};
+
 static struct resource system_rom_resource = {
        .name   = "System ROM",
        .start  = 0xf0000,
@@ -254,7 +261,9 @@ static void __init probe_roms(void)
  * and also for regions reported as reserved by the e820.
  */
 static void __init
-legacy_init_iomem_resources(struct resource *code_resource, struct resource *data_resource)
+legacy_init_iomem_resources(struct resource *code_resource,
+                           struct resource *data_resource,
+                           struct resource *bss_resource)
 {
        int i;
 
@@ -287,8 +296,10 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat
                         */
                        request_resource(res, code_resource);
                        request_resource(res, data_resource);
+                       request_resource(res, bss_resource);
 #ifdef CONFIG_KEXEC
-                       request_resource(res, &crashk_res);
+                       if (crashk_res.start != crashk_res.end)
+                               request_resource(res, &crashk_res);
 #endif
                }
        }
@@ -306,9 +317,11 @@ static int __init request_standard_resources(void)
 
        printk("Setting up standard PCI resources\n");
        if (efi_enabled)
-               efi_initialize_iomem_resources(&code_resource, &data_resource);
+               efi_initialize_iomem_resources(&code_resource,
+                               &data_resource, &bss_resource);
        else
-               legacy_init_iomem_resources(&code_resource, &data_resource);
+               legacy_init_iomem_resources(&code_resource,
+                               &data_resource, &bss_resource);
 
        /* EFI systems may still have VGA */
        request_resource(&iomem_resource, &video_ram_resource);
@@ -705,7 +718,7 @@ void __init e820_register_memory(void)
        int i;
 
        /*
-        * Search for the bigest gap in the low 32 bits of the e820
+        * Search for the biggest gap in the low 32 bits of the e820
         * memory space.
         */
        last = 0x100000000ull;
index e422b8159f694a7fa2c8e3172d8d63f49c1d9c78..04698e0b056c2ccc5ad9562d2290e6520d765c82 100644 (file)
@@ -47,7 +47,7 @@ unsigned long end_pfn_map;
  */
 static unsigned long __initdata end_user_pfn = MAXMEM>>PAGE_SHIFT;
 
-extern struct resource code_resource, data_resource;
+extern struct resource code_resource, data_resource, bss_resource;
 
 /* Check for some hardcoded bad areas that early boot is not allowed to touch */ 
 static inline int bad_addr(unsigned long *addrp, unsigned long size)
@@ -225,8 +225,10 @@ void __init e820_reserve_resources(void)
                         */
                        request_resource(res, &code_resource);
                        request_resource(res, &data_resource);
+                       request_resource(res, &bss_resource);
 #ifdef CONFIG_KEXEC
-                       request_resource(res, &crashk_res);
+                       if (crashk_res.start != crashk_res.end)
+                               request_resource(res, &crashk_res);
 #endif
                }
        }
@@ -728,3 +730,22 @@ __init void e820_setup_gap(void)
        printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n",
                pci_mem_start, gapstart, gapsize);
 }
+
+int __init arch_get_ram_range(int slot, u64 *addr, u64 *size)
+{
+       int i;
+
+       if (slot < 0 || slot >= e820.nr_map)
+               return -1;
+       for (i = slot; i < e820.nr_map; i++) {
+               if (e820.map[i].type != E820_RAM)
+                       continue;
+               break;
+       }
+       if (i == e820.nr_map || e820.map[i].addr > (max_pfn << PAGE_SHIFT))
+               return -1;
+       *addr = e820.map[i].addr;
+       *size = min_t(u64, e820.map[i].size + e820.map[i].addr,
+               max_pfn << PAGE_SHIFT) - *addr;
+       return i + 1;
+}
similarity index 88%
rename from arch/x86/kernel/early-quirks_64.c
rename to arch/x86/kernel/early-quirks.c
index 13aa4fd728f3dc7543ad49a37f825852a9a8ef00..dc34acbd54aafd1710808e422eea853edaba1531 100644 (file)
 #include <linux/acpi.h>
 #include <linux/pci_ids.h>
 #include <asm/pci-direct.h>
-#include <asm/proto.h>
-#include <asm/iommu.h>
 #include <asm/dma.h>
+#include <asm/io_apic.h>
+#include <asm/apic.h>
+
+#ifdef CONFIG_IOMMU
+#include <asm/iommu.h>
+#endif
 
 static void __init via_bugs(void)
 {
@@ -23,7 +27,8 @@ static void __init via_bugs(void)
        if ((end_pfn > MAX_DMA32_PFN ||  force_iommu) &&
            !iommu_aperture_allowed) {
                printk(KERN_INFO
-  "Looks like a VIA chipset. Disabling IOMMU. Override with iommu=allowed\n");
+                      "Looks like a VIA chipset. Disabling IOMMU."
+                      " Override with iommu=allowed\n");
                iommu_aperture_disabled = 1;
        }
 #endif
@@ -40,6 +45,7 @@ static int __init nvidia_hpet_check(struct acpi_table_header *header)
 static void __init nvidia_bugs(void)
 {
 #ifdef CONFIG_ACPI
+#ifdef CONFIG_X86_IO_APIC
        /*
         * All timer overrides on Nvidia are
         * wrong unless HPET is enabled.
@@ -58,6 +64,7 @@ static void __init nvidia_bugs(void)
                printk(KERN_INFO "If you got timer trouble "
                        "try acpi_use_timer_override\n");
        }
+#endif
 #endif
        /* RED-PEN skip them on mptables too? */
 
@@ -65,11 +72,13 @@ static void __init nvidia_bugs(void)
 
 static void __init ati_bugs(void)
 {
+#ifdef CONFIG_X86_IO_APIC
        if (timer_over_8254 == 1) {
                timer_over_8254 = 0;
                printk(KERN_INFO
-               "ATI board detected. Disabling timer routing over 8254.\n");
+               "ATI board detected. Disabling timer routing over 8254.\n");
        }
+#endif
 }
 
 struct chipset {
@@ -104,7 +113,7 @@ void __init early_quirks(void)
                                if (class == 0xffffffff)
                                        break;
 
-                               if ((class >> 16) != PCI_CLASS_BRIDGE_PCI)
+                               if ((class >> 16) != PCI_CLASS_BRIDGE_PCI)
                                        continue;
 
                                vendor = read_pci_config(num, slot, func,
index b42558c48e9d8d825eb73cd2e0ea37b74c31d517..e2be78f49399b7161a3c51783fda97d4c87467bb 100644 (file)
@@ -603,7 +603,8 @@ void __init efi_enter_virtual_mode(void)
 
 void __init
 efi_initialize_iomem_resources(struct resource *code_resource,
-                              struct resource *data_resource)
+                              struct resource *data_resource,
+                              struct resource *bss_resource)
 {
        struct resource *res;
        efi_memory_desc_t *md;
@@ -675,6 +676,7 @@ efi_initialize_iomem_resources(struct resource *code_resource,
                if (md->type == EFI_CONVENTIONAL_MEMORY) {
                        request_resource(res, code_resource);
                        request_resource(res, data_resource);
+                       request_resource(res, bss_resource);
 #ifdef CONFIG_KEXEC
                        request_resource(res, &crashk_res);
 #endif
index 4ae03e3e829441a27ed27decdd8905acf9b18411..ce703e21c91212485ccf04fdae476e806e755ac4 100644 (file)
 #include <acpi/acpi_bus.h>
 #endif
 
-/* which logical CPU number maps to which CPU (physical APIC ID) */
-u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly
+/*
+ * which logical CPU number maps to which CPU (physical APIC ID)
+ *
+ * The following static array is used during kernel startup
+ * and the x86_cpu_to_apicid_ptr contains the address of the
+ * array during this time.  Is it zeroed when the per_cpu
+ * data area is removed.
+ */
+u8 x86_cpu_to_apicid_init[NR_CPUS] __initdata
                                        = { [0 ... NR_CPUS-1] = BAD_APICID };
-EXPORT_SYMBOL(x86_cpu_to_apicid);
+void *x86_cpu_to_apicid_ptr;
+DEFINE_PER_CPU(u8, x86_cpu_to_apicid) = BAD_APICID;
+EXPORT_PER_CPU_SYMBOL(x86_cpu_to_apicid);
 
 struct genapic __read_mostly *genapic = &apic_flat;
 
index 91c7526768ee8e0f934c7c7e7d8c1b987ad46112..07352b74bda6dfaac343ef5caa5674c6fde77a9e 100644 (file)
@@ -172,7 +172,7 @@ static unsigned int physflat_cpu_mask_to_apicid(cpumask_t cpumask)
         */
        cpu = first_cpu(cpumask);
        if ((unsigned)cpu < NR_CPUS)
-               return x86_cpu_to_apicid[cpu];
+               return per_cpu(x86_cpu_to_apicid, cpu);
        else
                return BAD_APICID;
 }
index a7eee0a4751d6b42568aac385c8c9625fa4e3741..6b3469311e42736a630d9d95d907c8230277ee51 100644 (file)
@@ -58,7 +58,7 @@ void __init x86_64_start_kernel(char * real_mode_data)
 
        for (i = 0; i < IDT_ENTRIES; i++)
                set_intr_gate(i, early_idt_handler);
-       asm volatile("lidt %0" :: "m" (idt_descr));
+       load_idt((const struct desc_ptr *)&idt_descr);
 
        early_printk("Kernel alive\n");
 
index 39677965e161a124eb2b298f36e68b32fe015156..00b1c2c5645417c046c55408694554e792083aea 100644 (file)
@@ -79,22 +79,30 @@ INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_
  */
 .section .text.head,"ax",@progbits
 ENTRY(startup_32)
+       /* check to see if KEEP_SEGMENTS flag is meaningful */
+       cmpw $0x207, BP_version(%esi)
+       jb 1f
+
+       /* test KEEP_SEGMENTS flag to see if the bootloader is asking
+               us to not reload segments */
+       testb $(1<<6), BP_loadflags(%esi)
+       jnz 2f
 
 /*
  * Set segments to known values.
  */
-       cld
-       lgdt boot_gdt_descr - __PAGE_OFFSET
+1:     lgdt boot_gdt_descr - __PAGE_OFFSET
        movl $(__BOOT_DS),%eax
        movl %eax,%ds
        movl %eax,%es
        movl %eax,%fs
        movl %eax,%gs
+2:
 
 /*
  * Clear BSS first so that there are no surprises...
- * No need to cld as DF is already clear from cld above...
  */
+       cld
        xorl %eax,%eax
        movl $__bss_start - __PAGE_OFFSET,%edi
        movl $__bss_stop - __PAGE_OFFSET,%ecx
@@ -128,6 +136,35 @@ ENTRY(startup_32)
        movsl
 1:
 
+#ifdef CONFIG_PARAVIRT
+       cmpw $0x207, (boot_params + BP_version - __PAGE_OFFSET)
+       jb default_entry
+
+       /* Paravirt-compatible boot parameters.  Look to see what architecture
+               we're booting under. */
+       movl (boot_params + BP_hardware_subarch - __PAGE_OFFSET), %eax
+       cmpl $num_subarch_entries, %eax
+       jae bad_subarch
+
+       movl subarch_entries - __PAGE_OFFSET(,%eax,4), %eax
+       subl $__PAGE_OFFSET, %eax
+       jmp *%eax
+
+bad_subarch:
+WEAK(lguest_entry)
+WEAK(xen_entry)
+       /* Unknown implementation; there's really
+          nothing we can do at this point. */
+       ud2a
+.data
+subarch_entries:
+       .long default_entry             /* normal x86/PC */
+       .long lguest_entry              /* lguest hypervisor */
+       .long xen_entry                 /* Xen hypervisor */
+num_subarch_entries = (. - subarch_entries) / 4
+.previous
+#endif /* CONFIG_PARAVIRT */
+
 /*
  * Initialize page tables.  This creates a PDE and a set of page
  * tables, which are located immediately beyond _end.  The variable
@@ -140,6 +177,7 @@ ENTRY(startup_32)
  */
 page_pde_offset = (__PAGE_OFFSET >> 20);
 
+default_entry:
        movl $(pg0 - __PAGE_OFFSET), %edi
        movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
        movl $0x007, %eax                       /* 0x007 = PRESENT+RW+USER */
index f8367074da0dc1919fc45049c6ccaff94e0cc2a3..53303f2e547582e282f5a941cc2311b79a821238 100644 (file)
@@ -69,12 +69,15 @@ static inline void hpet_clear_mapping(void)
  * HPET command line enable / disable
  */
 static int boot_hpet_disable;
+int hpet_force_user;
 
 static int __init hpet_setup(char* str)
 {
        if (str) {
                if (!strncmp("disable", str, 7))
                        boot_hpet_disable = 1;
+               if (!strncmp("force", str, 5))
+                       hpet_force_user = 1;
        }
        return 1;
 }
@@ -350,7 +353,7 @@ static int hpet_clocksource_register(void)
         *
         * hpet period is in femto seconds per cycle
         * so we need to convert this to ns/cyc units
-        * aproximated by mult/2^shift
+        * approximated by mult/2^shift
         *
         *  fsec/cyc * 1nsec/1000000fsec = nsec/cyc = mult/2^shift
         *  fsec/cyc * 1ns/1000000fsec * 2^shift = mult
index 5cc8841ca2c695bfeb6c514f0e461f1294312cc0..a42c807453253f83fad63373567ed050a6ae1ac1 100644 (file)
@@ -86,7 +86,7 @@ static int pit_next_event(unsigned long delta, struct clock_event_device *evt)
  * On UP the PIT can serve all of the possible timer functions. On SMP systems
  * it can be solely used for the global tick.
  *
- * The profiling and update capabilites are switched off once the local apic is
+ * The profiling and update capabilities are switched off once the local apic is
  * registered. This mechanism replaces the previous #ifdef LOCAL_APIC -
  * !using_apic_timer decisions in do_timer_interrupt_hook()
  */
index d34a10cc13a7dbe4eba3b456ed5eeca83e7be526..f634fc715c99b455d3973645d4d16c3a80e13361 100644 (file)
@@ -403,7 +403,8 @@ void __init native_init_IRQ(void)
                int vector = FIRST_EXTERNAL_VECTOR + i;
                if (i >= NR_IRQS)
                        break;
-               if (vector != SYSCALL_VECTOR) 
+               /* SYSCALL_VECTOR was reserved in trap_init. */
+               if (!test_bit(vector, used_vectors))
                        set_intr_gate(vector, interrupt[i]);
        }
 
similarity index 79%
rename from arch/x86/kernel/init_task_32.c
rename to arch/x86/kernel/init_task.c
index d26fc063a760c508dd0060b784a6d070ff0bf4dc..468c9c43784261823bbd018550d113c4a49df777 100644 (file)
@@ -15,7 +15,6 @@ static struct files_struct init_files = INIT_FILES;
 static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
 static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
 struct mm_struct init_mm = INIT_MM(init_mm);
-
 EXPORT_SYMBOL(init_mm);
 
 /*
@@ -25,7 +24,7 @@ EXPORT_SYMBOL(init_mm);
  * way process stacks are handled. This is done by having a special
  * "init_task" linker map entry..
  */
-union thread_union init_thread_union 
+union thread_union init_thread_union
        __attribute__((__section__(".data.init_task"))) =
                { INIT_THREAD_INFO(init_task) };
 
@@ -35,12 +34,14 @@ union thread_union init_thread_union
  * All other task structs will be allocated on slabs in fork.c
  */
 struct task_struct init_task = INIT_TASK(init_task);
-
 EXPORT_SYMBOL(init_task);
 
 /*
  * per-CPU TSS segments. Threads are completely 'soft' on Linux,
- * no more per-task TSS's.
- */ 
+ * no more per-task TSS's. The TSS size is kept cacheline-aligned
+ * so they are allowed to end up in the .data.cacheline_aligned
+ * section. Since TSS's are completely CPU-local, we want them
+ * on exact cacheline boundaries, to eliminate cacheline ping-pong.
+ */
 DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
 
diff --git a/arch/x86/kernel/init_task_64.c b/arch/x86/kernel/init_task_64.c
deleted file mode 100644 (file)
index 4ff33d4..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/init_task.h>
-#include <linux/fs.h>
-#include <linux/mqueue.h>
-
-#include <asm/uaccess.h>
-#include <asm/pgtable.h>
-#include <asm/desc.h>
-
-static struct fs_struct init_fs = INIT_FS;
-static struct files_struct init_files = INIT_FILES;
-static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
-static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
-struct mm_struct init_mm = INIT_MM(init_mm);
-
-EXPORT_SYMBOL(init_mm);
-
-/*
- * Initial task structure.
- *
- * We need to make sure that this is 8192-byte aligned due to the
- * way process stacks are handled. This is done by having a special
- * "init_task" linker map entry..
- */
-union thread_union init_thread_union 
-       __attribute__((__section__(".data.init_task"))) =
-               { INIT_THREAD_INFO(init_task) };
-
-/*
- * Initial task structure.
- *
- * All other task structs will be allocated on slabs in fork.c
- */
-struct task_struct init_task = INIT_TASK(init_task);
-
-EXPORT_SYMBOL(init_task);
-/*
- * per-CPU TSS segments. Threads are completely 'soft' on Linux,
- * no more per-task TSS's. The TSS size is kept cacheline-aligned
- * so they are allowed to end up in the .data.cacheline_aligned
- * section. Since TSS's are completely CPU-local, we want them
- * on exact cacheline boundaries, to eliminate cacheline ping-pong.
- */ 
-DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
-
-/* Copies of the original ist values from the tss are only accessed during
- * debugging, no special alignment required.
- */
-DEFINE_PER_CPU(struct orig_ist, orig_ist);
-
-#define ALIGN_TO_4K __attribute__((section(".data.init_task")))
index 5f10c7189534807fa2c6eddd2ef838e06c85d09f..f35c6eb33da9b7a5e0caa1dee4f0e075121349af 100644 (file)
@@ -584,7 +584,7 @@ tryanotherirq:
 
        imbalance = move_this_load;
        
-       /* For physical_balance case, we accumlated both 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. 
@@ -1198,7 +1198,7 @@ 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 = 0;
-       int vector, offset, i;
+       int vector, offset;
 
        BUG_ON((unsigned)irq >= NR_IRQ_VECTORS);
 
@@ -1215,11 +1215,8 @@ next:
        }
        if (vector == current_vector)
                return -ENOSPC;
-       if (vector == SYSCALL_VECTOR)
+       if (test_and_set_bit(vector, used_vectors))
                goto next;
-       for (i = 0; i < NR_IRQ_VECTORS; i++)
-               if (irq_vector[i] == vector)
-                       goto next;
 
        current_vector = vector;
        current_offset = offset;
@@ -2295,6 +2292,12 @@ static inline void __init check_timer(void)
 
 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();
 
        if (acpi_ioapic)
@@ -2472,7 +2475,7 @@ void destroy_irq(unsigned int irq)
 }
 
 /*
- * MSI mesage composition
+ * MSI message composition
  */
 #ifdef CONFIG_PCI_MSI
 static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
index 1c2c7bf6a9d333fb512094752aa3c7dc0fc87e9a..953328b55a30503c58f2f8b3ed0f30939ff4047c 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/sysdev.h>
 #include <linux/msi.h>
 #include <linux/htirq.h>
+#include <linux/dmar.h>
 #ifdef CONFIG_ACPI
 #include <acpi/acpi_bus.h>
 #endif
@@ -1770,7 +1771,7 @@ __setup("no_timer_check", notimercheck);
 
 /*
  *
- * IRQ's that are handled by the PIC in the MPS IOAPIC case.
+ * IRQs that are handled by the PIC in the MPS IOAPIC case.
  * - IRQ2 is the cascade IRQ, and cannot be a io-apic IRQ.
  *   Linux doesn't really care, as it's not actually used
  *   for any interrupt handling anyway.
@@ -1921,7 +1922,7 @@ void destroy_irq(unsigned int irq)
 }
 
 /*
- * MSI mesage composition
+ * MSI message composition
  */
 #ifdef CONFIG_PCI_MSI
 static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
@@ -2031,8 +2032,64 @@ void arch_teardown_msi_irq(unsigned int irq)
        destroy_irq(irq);
 }
 
-#endif /* CONFIG_PCI_MSI */
+#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;
+       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;
+
+       cpus_and(tmp, cfg->domain, mask);
+       dest = cpu_mask_to_apicid(tmp);
+
+       dmar_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);
+
+       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 = ack_apic_edge,
+#ifdef CONFIG_SMP
+       .set_affinity = dmar_msi_set_affinity,
+#endif
+       .retrigger = ioapic_retrigger_irq,
+};
+
+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
 
+#endif /* CONFIG_PCI_MSI */
 /*
  * Hypertransport interrupt support
  */
index 8459ca64bc2f9c089acca975de93434d57ad065f..11b935f4f886d34679dcf594ac8465ab2a57fe00 100644 (file)
@@ -149,28 +149,6 @@ NORET_TYPE void machine_kexec(struct kimage *image)
                        image->start, cpu_has_pae);
 }
 
-/* crashkernel=size@addr specifies the location to reserve for
- * a crash kernel.  By reserving this memory we guarantee
- * that linux never sets it up as a DMA target.
- * Useful for holding code to do something appropriate
- * after a kernel panic.
- */
-static int __init parse_crashkernel(char *arg)
-{
-       unsigned long size, base;
-       size = memparse(arg, &arg);
-       if (*arg == '@') {
-               base = memparse(arg+1, &arg);
-               /* FIXME: Do I want a sanity check
-                * to validate the memory range?
-                */
-               crashk_res.start = base;
-               crashk_res.end   = base + size - 1;
-       }
-       return 0;
-}
-early_param("crashkernel", parse_crashkernel);
-
 void arch_crash_save_vmcoreinfo(void)
 {
 #ifdef CONFIG_ARCH_DISCONTIGMEM_ENABLE
index 7450b69710b5557f2f81c4a5ebf187b9c00ac58e..0d8577f0542257c325031d45693e7458622166ad 100644 (file)
@@ -231,33 +231,6 @@ NORET_TYPE void machine_kexec(struct kimage *image)
                        image->start);
 }
 
-/* crashkernel=size@addr specifies the location to reserve for
- * a crash kernel.  By reserving this memory we guarantee
- * that linux never set's it up as a DMA target.
- * Useful for holding code to do something appropriate
- * after a kernel panic.
- */
-static int __init setup_crashkernel(char *arg)
-{
-       unsigned long size, base;
-       char *p;
-       if (!arg)
-               return -EINVAL;
-       size = memparse(arg, &p);
-       if (arg == p)
-               return -EINVAL;
-       if (*p == '@') {
-               base = memparse(p+1, &p);
-               /* FIXME: Do I want a sanity check to validate the
-                * memory range?  Yes you do, but it's too early for
-                * e820 -AK */
-               crashk_res.start = base;
-               crashk_res.end   = base + size - 1;
-       }
-       return 0;
-}
-early_param("crashkernel", setup_crashkernel);
-
 void arch_crash_save_vmcoreinfo(void)
 {
 #ifdef CONFIG_ARCH_DISCONTIGMEM_ENABLE
index 8ca8f8648969354b12a37af8f7f135c6728e31a9..07bbfe7aa7f70efa86fceb4adb87139296efad5c 100644 (file)
@@ -320,7 +320,7 @@ void do_machine_check(struct pt_regs * regs, long error_code)
 #ifdef CONFIG_X86_MCE_INTEL
 /***
  * mce_log_therm_throt_event - Logs the thermal throttling event to mcelog
- * @cpu: The CPU on which the event occured.
+ * @cpu: The CPU on which the event occurred.
  * @status: Event status information
  *
  * This function should be called by the thermal interrupt after the
@@ -688,7 +688,7 @@ static int __init mcheck_disable(char *str)
        return 1;
 }
 
-/* mce=off disables machine check. Note you can reenable it later
+/* mce=off disables machine check. Note you can re-enable it later
    using sysfs.
    mce=TOLERANCELEVEL (number, see above)
    mce=bootlog Log MCEs from before booting. Disabled by default on AMD.
@@ -799,19 +799,33 @@ static __cpuinit int mce_create_device(unsigned int cpu)
 {
        int err;
        int i;
-       if (!mce_available(&cpu_data[cpu]))
+
+       if (!mce_available(&cpu_data(cpu)))
                return -EIO;
 
+       memset(&per_cpu(device_mce, cpu).kobj, 0, sizeof(struct kobject));
        per_cpu(device_mce,cpu).id = cpu;
        per_cpu(device_mce,cpu).cls = &mce_sysclass;
 
        err = sysdev_register(&per_cpu(device_mce,cpu));
+       if (err)
+               return err;
+
+       for (i = 0; mce_attributes[i]; i++) {
+               err = sysdev_create_file(&per_cpu(device_mce,cpu),
+                                        mce_attributes[i]);
+               if (err)
+                       goto error;
+       }
 
-       if (!err) {
-               for (i = 0; mce_attributes[i]; i++)
-                       sysdev_create_file(&per_cpu(device_mce,cpu),
-                               mce_attributes[i]);
+       return 0;
+error:
+       while (i--) {
+               sysdev_remove_file(&per_cpu(device_mce,cpu),
+                                  mce_attributes[i]);
        }
+       sysdev_unregister(&per_cpu(device_mce,cpu));
+
        return err;
 }
 
@@ -823,7 +837,6 @@ static void mce_remove_device(unsigned int cpu)
                sysdev_remove_file(&per_cpu(device_mce,cpu),
                        mce_attributes[i]);
        sysdev_unregister(&per_cpu(device_mce,cpu));
-       memset(&per_cpu(device_mce, cpu).kobj, 0, sizeof(struct kobject));
 }
 
 /* Get notified when a cpu comes on/off. Be hotplug friendly. */
@@ -831,18 +844,21 @@ static int
 mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
 {
        unsigned int cpu = (unsigned long)hcpu;
+       int err = 0;
 
        switch (action) {
-       case CPU_ONLINE:
-       case CPU_ONLINE_FROZEN:
-               mce_create_device(cpu);
+       case CPU_UP_PREPARE:
+       case CPU_UP_PREPARE_FROZEN:
+               err = mce_create_device(cpu);
                break;
+       case CPU_UP_CANCELED:
+       case CPU_UP_CANCELED_FROZEN:
        case CPU_DEAD:
        case CPU_DEAD_FROZEN:
                mce_remove_device(cpu);
                break;
        }
-       return NOTIFY_OK;
+       return err ? NOTIFY_BAD : NOTIFY_OK;
 }
 
 static struct notifier_block mce_cpu_notifier = {
@@ -857,9 +873,13 @@ static __init int mce_init_device(void)
        if (!mce_available(&boot_cpu_data))
                return -EIO;
        err = sysdev_class_register(&mce_sysclass);
+       if (err)
+               return err;
 
        for_each_online_cpu(i) {
-               mce_create_device(i);
+               err = mce_create_device(i);
+               if (err)
+                       return err;
        }
 
        register_hotcpu_notifier(&mce_cpu_notifier);
index 0d2afd96aca40b7ff5a458f1890b9422ba32873e..752fb16a817d7187ac1732e66c426a12a19ff352 100644 (file)
@@ -472,11 +472,11 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
        sprintf(name, "threshold_bank%i", bank);
 
 #ifdef CONFIG_SMP
-       if (cpu_data[cpu].cpu_core_id && shared_bank[bank]) {   /* symlink */
+       if (cpu_data(cpu).cpu_core_id && shared_bank[bank]) {   /* symlink */
                i = first_cpu(per_cpu(cpu_core_map, cpu));
 
                /* first core not up yet */
-               if (cpu_data[i].cpu_core_id)
+               if (cpu_data(i).cpu_core_id)
                        goto out;
 
                /* already linked */
index 09cf78110358fadc78bbc704349b8283737f5f90..09c315214a5ec87fdddd00f039255d69f3c01b9a 100644 (file)
@@ -132,7 +132,7 @@ static struct ucode_cpu_info {
 
 static void collect_cpu_info(int cpu_num)
 {
-       struct cpuinfo_x86 *c = cpu_data + cpu_num;
+       struct cpuinfo_x86 *c = &cpu_data(cpu_num);
        struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
        unsigned int val[2];
 
@@ -522,7 +522,7 @@ static struct platform_device *microcode_pdev;
 static int cpu_request_microcode(int cpu)
 {
        char name[30];
-       struct cpuinfo_x86 *c = cpu_data + cpu;
+       struct cpuinfo_x86 *c = &cpu_data(cpu);
        const struct firmware *firmware;
        void *buf;
        unsigned long size;
@@ -570,7 +570,7 @@ static int cpu_request_microcode(int cpu)
 
 static int apply_microcode_check_cpu(int cpu)
 {
-       struct cpuinfo_x86 *c = cpu_data + cpu;
+       struct cpuinfo_x86 *c = &cpu_data(cpu);
        struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
        cpumask_t old;
        unsigned int val[2];
index 13abb4ebfb79b3f831f8b7f5373c16d31844c2bd..7a05a7f6099a4ee31b7bb72e6c11c956282588da 100644 (file)
@@ -1001,7 +1001,7 @@ void __init mp_config_acpi_legacy_irqs (void)
 
        /* 
         * Use the default configuration for the IRQs 0-15.  Unless
-        * overriden by (MADT) interrupt source override entries.
+        * overridden by (MADT) interrupt source override entries.
         */
        for (i = 0; i < 16; i++) {
                int idx;
index 8bf0ca03ac8e8a78f13ca5ea86842e02cfca9be0..ef4aab123581a54ac17019d4441138a90b36b980 100644 (file)
@@ -57,6 +57,8 @@ unsigned long mp_lapic_addr = 0;
 
 /* Processor that is doing the boot up */
 unsigned int boot_cpu_id = -1U;
+EXPORT_SYMBOL(boot_cpu_id);
+
 /* Internal processor count */
 unsigned int num_processors __cpuinitdata = 0;
 
@@ -86,7 +88,7 @@ static int __init mpf_checksum(unsigned char *mp, int len)
        return sum & 0xFF;
 }
 
-static void __cpuinit MP_processor_info (struct mpc_config_processor *m)
+static void __cpuinit MP_processor_info(struct mpc_config_processor *m)
 {
        int cpu;
        cpumask_t tmp_map;
@@ -123,7 +125,18 @@ static void __cpuinit MP_processor_info (struct mpc_config_processor *m)
                cpu = 0;
        }
        bios_cpu_apicid[cpu] = m->mpc_apicid;
-       x86_cpu_to_apicid[cpu] = m->mpc_apicid;
+       /*
+        * We get called early in the the start_kernel initialization
+        * process when the per_cpu data area is not yet setup, so we
+        * use a static array that is removed after the per_cpu data
+        * area is created.
+        */
+       if (x86_cpu_to_apicid_ptr) {
+               u8 *x86_cpu_to_apicid = (u8 *)x86_cpu_to_apicid_ptr;
+               x86_cpu_to_apicid[cpu] = m->mpc_apicid;
+       } else {
+               per_cpu(x86_cpu_to_apicid, cpu) = m->mpc_apicid;
+       }
 
        cpu_set(cpu, cpu_possible_map);
        cpu_set(cpu, cpu_present_map);
index df85c9c13601e4205fae3192538757babbe223ae..ee6eba4ecfeaadee33e8875be5a4f3b1ccd253d0 100644 (file)
@@ -112,7 +112,7 @@ static ssize_t msr_write(struct file *file, const char __user *buf,
 static int msr_open(struct inode *inode, struct file *file)
 {
        unsigned int cpu = iminor(file->f_path.dentry->d_inode);
-       struct cpuinfo_x86 *c = &(cpu_data)[cpu];
+       struct cpuinfo_x86 *c = &cpu_data(cpu);
 
        if (cpu >= NR_CPUS || !cpu_online(cpu))
                return -ENXIO;  /* No such CPU */
@@ -133,37 +133,42 @@ static const struct file_operations msr_fops = {
        .open = msr_open,
 };
 
-static int __cpuinit msr_device_create(int i)
+static int __cpuinit msr_device_create(int cpu)
 {
-       int err = 0;
        struct device *dev;
 
-       dev = device_create(msr_class, NULL, MKDEV(MSR_MAJOR, i), "msr%d",i);
-       if (IS_ERR(dev))
-               err = PTR_ERR(dev);
-       return err;
+       dev = device_create(msr_class, NULL, MKDEV(MSR_MAJOR, cpu),
+                           "msr%d", cpu);
+       return IS_ERR(dev) ? PTR_ERR(dev) : 0;
+}
+
+static void msr_device_destroy(int cpu)
+{
+       device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu));
 }
 
 static int __cpuinit msr_class_cpu_callback(struct notifier_block *nfb,
                                unsigned long action, void *hcpu)
 {
        unsigned int cpu = (unsigned long)hcpu;
+       int err = 0;
 
        switch (action) {
-       case CPU_ONLINE:
-       case CPU_ONLINE_FROZEN:
-               msr_device_create(cpu);
+       case CPU_UP_PREPARE:
+       case CPU_UP_PREPARE_FROZEN:
+               err = msr_device_create(cpu);
                break;
+       case CPU_UP_CANCELED:
+       case CPU_UP_CANCELED_FROZEN:
        case CPU_DEAD:
        case CPU_DEAD_FROZEN:
-               device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu));
+               msr_device_destroy(cpu);
                break;
        }
-       return NOTIFY_OK;
+       return err ? NOTIFY_BAD : NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata msr_class_cpu_notifier =
-{
+static struct notifier_block __cpuinitdata msr_class_cpu_notifier = {
        .notifier_call = msr_class_cpu_callback,
 };
 
@@ -196,7 +201,7 @@ static int __init msr_init(void)
 out_class:
        i = 0;
        for_each_online_cpu(i)
-               device_destroy(msr_class, MKDEV(MSR_MAJOR, i));
+               msr_device_destroy(i);
        class_destroy(msr_class);
 out_chrdev:
        unregister_chrdev(MSR_MAJOR, "cpu/msr");
@@ -208,7 +213,7 @@ static void __exit msr_exit(void)
 {
        int cpu = 0;
        for_each_online_cpu(cpu)
-               device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu));
+               msr_device_destroy(cpu);
        class_destroy(msr_class);
        unregister_chrdev(MSR_MAJOR, "cpu/msr");
        unregister_hotcpu_notifier(&msr_class_cpu_notifier);
index 5098f58063a57d537814d5031b89465faf00931f..1a20fe31338b18ea302d5ac035fd521d458bd6e7 100644 (file)
@@ -411,8 +411,10 @@ static int calgary_nontranslate_map_sg(struct device* dev,
        int i;
 
        for_each_sg(sg, s, nelems, i) {
-               BUG_ON(!s->page);
-               s->dma_address = virt_to_bus(page_address(s->page) +s->offset);
+               struct page *p = sg_page(s);
+
+               BUG_ON(!p);
+               s->dma_address = virt_to_bus(sg_virt(s));
                s->dma_length = s->length;
        }
        return nelems;
@@ -432,9 +434,9 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg,
                return calgary_nontranslate_map_sg(dev, sg, nelems, direction);
 
        for_each_sg(sg, s, nelems, i) {
-               BUG_ON(!s->page);
+               BUG_ON(!sg_page(s));
 
-               vaddr = (unsigned long)page_address(s->page) + s->offset;
+               vaddr = (unsigned long) sg_virt(s);
                npages = num_dma_pages(vaddr, s->length);
 
                entry = iommu_range_alloc(tbl, npages);
index b2b42bdb0a150c8f1d74f6630d1f9dc0be3569a2..393e2725a6e31a386a9b28817317990ef5d79871 100644 (file)
@@ -7,11 +7,12 @@
 #include <linux/string.h>
 #include <linux/pci.h>
 #include <linux/module.h>
+#include <linux/dmar.h>
 #include <asm/io.h>
 #include <asm/iommu.h>
 #include <asm/calgary.h>
 
-int iommu_merge __read_mostly = 0;
+int iommu_merge __read_mostly = 1;
 EXPORT_SYMBOL(iommu_merge);
 
 dma_addr_t bad_dma_address __read_mostly;
@@ -305,6 +306,8 @@ void __init pci_iommu_alloc(void)
        detect_calgary();
 #endif
 
+       detect_intel_iommu();
+
 #ifdef CONFIG_SWIOTLB
        pci_swiotlb_init();
 #endif
@@ -316,6 +319,8 @@ static int __init pci_iommu_init(void)
        calgary_iommu_init();
 #endif
 
+       intel_iommu_init();
+
 #ifdef CONFIG_IOMMU
        gart_iommu_init();
 #endif
index 5cdfab65e93f8d1c7ac67d75cfffe3dc7fd461f9..c56e9ee64964df91f8c27fbc681472716c109572 100644 (file)
@@ -302,7 +302,7 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
 #endif
 
        for_each_sg(sg, s, nents, i) {
-               unsigned long addr = page_to_phys(s->page) + s->offset; 
+               unsigned long addr = sg_phys(s);
                if (nonforced_iommu(dev, addr, s->length)) { 
                        addr = dma_map_area(dev, addr, s->length, dir);
                        if (addr == bad_dma_address) { 
@@ -397,7 +397,7 @@ static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents,
        start_sg = sgmap = sg;
        ps = NULL; /* shut up gcc */
        for_each_sg(sg, s, nents, i) {
-               dma_addr_t addr = page_to_phys(s->page) + s->offset;
+               dma_addr_t addr = sg_phys(s);
                s->dma_address = addr;
                BUG_ON(s->length == 0); 
 
index e85d4360360c68fe6db2166194e8a748f709f1f2..faf70bdca335c5c21dfb6e03941923234bc4deb1 100644 (file)
@@ -62,8 +62,8 @@ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg,
        int i;
 
        for_each_sg(sg, s, nents, i) {
-               BUG_ON(!s->page);
-               s->dma_address = virt_to_bus(page_address(s->page) +s->offset);
+               BUG_ON(!sg_page(s));
+               s->dma_address = virt_to_bus(sg_virt(s));
                if (!check_addr("map_sg", hwdev, s->dma_address, s->length))
                        return 0;
                s->dma_length = s->length;
index 097aeafce5fff14bf9c02874f5ca69f68aaa4f42..7b899584d290833cdbfed7dee779e20043a91ddb 100644 (file)
@@ -295,34 +295,52 @@ static int __init idle_setup(char *str)
 }
 early_param("idle", idle_setup);
 
-void show_regs(struct pt_regs * regs)
+void __show_registers(struct pt_regs *regs, int all)
 {
        unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
        unsigned long d0, d1, d2, d3, d6, d7;
+       unsigned long esp;
+       unsigned short ss, gs;
+
+       if (user_mode_vm(regs)) {
+               esp = regs->esp;
+               ss = regs->xss & 0xffff;
+               savesegment(gs, gs);
+       } else {
+               esp = (unsigned long) (&regs->esp);
+               savesegment(ss, ss);
+               savesegment(gs, gs);
+       }
 
        printk("\n");
-       printk("Pid: %d, comm: %20s\n", current->pid, current->comm);
-       printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id());
+       printk("Pid: %d, comm: %s %s (%s %.*s)\n",
+                       task_pid_nr(current), current->comm,
+                       print_tainted(), init_utsname()->release,
+                       (int)strcspn(init_utsname()->version, " "),
+                       init_utsname()->version);
+
+       printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n",
+                       0xffff & regs->xcs, regs->eip, regs->eflags,
+                       smp_processor_id());
        print_symbol("EIP is at %s\n", regs->eip);
 
-       if (user_mode_vm(regs))
-               printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
-       printk(" EFLAGS: %08lx    %s  (%s %.*s)\n",
-              regs->eflags, print_tainted(), init_utsname()->release,
-              (int)strcspn(init_utsname()->version, " "),
-              init_utsname()->version);
        printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
-               regs->eax,regs->ebx,regs->ecx,regs->edx);
-       printk("ESI: %08lx EDI: %08lx EBP: %08lx",
-               regs->esi, regs->edi, regs->ebp);
-       printk(" DS: %04x ES: %04x FS: %04x\n",
-              0xffff & regs->xds,0xffff & regs->xes, 0xffff & regs->xfs);
+               regs->eax, regs->ebx, regs->ecx, regs->edx);
+       printk("ESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx\n",
+               regs->esi, regs->edi, regs->ebp, esp);
+       printk(" DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x\n",
+              regs->xds & 0xffff, regs->xes & 0xffff,
+              regs->xfs & 0xffff, gs, ss);
+
+       if (!all)
+               return;
 
        cr0 = read_cr0();
        cr2 = read_cr2();
        cr3 = read_cr3();
        cr4 = read_cr4_safe();
-       printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4);
+       printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n",
+                       cr0, cr2, cr3, cr4);
 
        get_debugreg(d0, 0);
        get_debugreg(d1, 1);
@@ -330,10 +348,16 @@ void show_regs(struct pt_regs * regs)
        get_debugreg(d3, 3);
        printk("DR0: %08lx DR1: %08lx DR2: %08lx DR3: %08lx\n",
                        d0, d1, d2, d3);
+
        get_debugreg(d6, 6);
        get_debugreg(d7, 7);
-       printk("DR6: %08lx DR7: %08lx\n", d6, d7);
+       printk("DR6: %08lx DR7: %08lx\n",
+                       d6, d7);
+}
 
+void show_regs(struct pt_regs *regs)
+{
+       __show_registers(regs, 1);
        show_trace(NULL, regs, &regs->esp);
 }
 
index 99102ec5fade9dc79ff01fde4469ef10a39cff33..ff5431cc03ee8ea949704fa19d6f289afc7f74bd 100644 (file)
@@ -632,7 +632,7 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
        /* User-mode eip? */
        info.si_addr = user_mode_vm(regs) ? (void __user *) regs->eip : NULL;
 
-       /* Send us the fakey SIGTRAP */
+       /* Send us the fake SIGTRAP */
        force_sig_info(SIGTRAP, &info, tsk);
 }
 
index d769e204f942904b389daba44417cd9c97f61dc1..a4ce1911efdf948691b8ae2afef62ed878033bfa 100644 (file)
@@ -45,9 +45,12 @@ static void __devinit quirk_intel_irqbalance(struct pci_dev *dev)
        if (!(config & 0x2))
                pci_write_config_byte(dev, 0xf4, config);
 }
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_E7320_MCH,  quirk_intel_irqbalance);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_E7525_MCH,  quirk_intel_irqbalance);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_E7520_MCH,  quirk_intel_irqbalance);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH,
+                       quirk_intel_irqbalance);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH,
+                       quirk_intel_irqbalance);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH,
+                       quirk_intel_irqbalance);
 #endif
 
 #if defined(CONFIG_HPET_TIMER)
@@ -56,7 +59,8 @@ unsigned long force_hpet_address;
 static enum {
        NONE_FORCE_HPET_RESUME,
        OLD_ICH_FORCE_HPET_RESUME,
-       ICH_FORCE_HPET_RESUME
+       ICH_FORCE_HPET_RESUME,
+       VT8237_FORCE_HPET_RESUME
 } force_hpet_resume_type;
 
 static void __iomem *rcba_base;
@@ -146,17 +150,17 @@ static void ich_force_enable_hpet(struct pci_dev *dev)
 }
 
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_0,
-                         ich_force_enable_hpet);
+                        ich_force_enable_hpet);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1,
-                         ich_force_enable_hpet);
+                        ich_force_enable_hpet);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0,
-                         ich_force_enable_hpet);
+                        ich_force_enable_hpet);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1,
-                         ich_force_enable_hpet);
+                        ich_force_enable_hpet);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31,
-                         ich_force_enable_hpet);
+                        ich_force_enable_hpet);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_1,
-                         ich_force_enable_hpet);
+                        ich_force_enable_hpet);
 
 
 static struct pci_dev *cached_dev;
@@ -232,10 +236,91 @@ static void old_ich_force_enable_hpet(struct pci_dev *dev)
        printk(KERN_DEBUG "Failed to force enable HPET\n");
 }
 
+/*
+ * Undocumented chipset features. Make sure that the user enforced
+ * this.
+ */
+static void old_ich_force_enable_hpet_user(struct pci_dev *dev)
+{
+       if (hpet_force_user)
+               old_ich_force_enable_hpet(dev);
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0,
+                        old_ich_force_enable_hpet_user);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12,
+                        old_ich_force_enable_hpet_user);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0,
+                        old_ich_force_enable_hpet_user);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12,
+                        old_ich_force_enable_hpet_user);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0,
-                         old_ich_force_enable_hpet);
+                        old_ich_force_enable_hpet);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_12,
-                         old_ich_force_enable_hpet);
+                        old_ich_force_enable_hpet);
+
+
+static void vt8237_force_hpet_resume(void)
+{
+       u32 val;
+
+       if (!force_hpet_address || !cached_dev)
+               return;
+
+       val = 0xfed00000 | 0x80;
+       pci_write_config_dword(cached_dev, 0x68, val);
+
+       pci_read_config_dword(cached_dev, 0x68, &val);
+       if (val & 0x80)
+               printk(KERN_DEBUG "Force enabled HPET at resume\n");
+       else
+               BUG();
+}
+
+static void vt8237_force_enable_hpet(struct pci_dev *dev)
+{
+       u32 uninitialized_var(val);
+
+       if (!hpet_force_user || hpet_address || force_hpet_address)
+               return;
+
+       pci_read_config_dword(dev, 0x68, &val);
+       /*
+        * Bit 7 is HPET enable bit.
+        * Bit 31:10 is HPET base address (contrary to what datasheet claims)
+        */
+       if (val & 0x80) {
+               force_hpet_address = (val & ~0x3ff);
+               printk(KERN_DEBUG "HPET at base address 0x%lx\n",
+                              force_hpet_address);
+               return;
+       }
+
+       /*
+        * HPET is disabled. Trying enabling at FED00000 and check
+        * whether it sticks
+        */
+       val = 0xfed00000 | 0x80;
+       pci_write_config_dword(dev, 0x68, val);
+
+       pci_read_config_dword(dev, 0x68, &val);
+       if (val & 0x80) {
+               force_hpet_address = (val & ~0x3ff);
+               printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
+                              force_hpet_address);
+               cached_dev = dev;
+               force_hpet_resume_type = VT8237_FORCE_HPET_RESUME;
+               return;
+       }
+
+       printk(KERN_DEBUG "Failed to force enable HPET\n");
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235,
+                        vt8237_force_enable_hpet);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237,
+                        vt8237_force_enable_hpet);
+
 
 void force_hpet_resume(void)
 {
@@ -246,6 +331,9 @@ void force_hpet_resume(void)
            case OLD_ICH_FORCE_HPET_RESUME:
                return old_ich_force_hpet_resume();
 
+           case VT8237_FORCE_HPET_RESUME:
+               return vt8237_force_hpet_resume();
+
            default:
                break;
        }
index 368db2b9c5ac3977b0ec32edabe2aec9359df6de..776eb06b6512dcf61e0a0d85daa23992870ac7e2 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/sched.h>
 #include <asm/io.h>
 #include <asm/delay.h>
+#include <asm/desc.h>
 #include <asm/hw_irq.h>
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -136,7 +137,7 @@ void machine_emergency_restart(void)
                }
 
                case BOOT_TRIPLE: 
-                       __asm__ __volatile__("lidt (%0)": :"r" (&no_idt));
+                       load_idt((const struct desc_ptr *)&no_idt);
                        __asm__ __volatile__("int3");
 
                        reboot_type = BOOT_KBD;
index 8b30b26ad0698161276c2b87c4c64594887aa4ad..1a07bbea7be36eadcea68843d7b727eaa03ee9a4 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/interrupt.h>
 #include <asm/reboot_fixups.h>
 #include <asm/msr.h>
+#include <asm/geode.h>
 
 static void cs5530a_warm_reset(struct pci_dev *dev)
 {
@@ -24,11 +25,8 @@ static void cs5530a_warm_reset(struct pci_dev *dev)
 
 static void cs5536_warm_reset(struct pci_dev *dev)
 {
-       /*
-        * 6.6.2.12 Soft Reset (DIVIL_SOFT_RESET)
-        * writing 1 to the LSB of this MSR causes a hard reset.
-        */
-       wrmsrl(0x51400017, 1ULL);
+       /* writing 1 to the LSB of this MSR causes a hard reset */
+       wrmsrl(MSR_DIVIL_SOFT_RESET, 1ULL);
        udelay(50); /* shouldn't get here but be safe and spin a while */
 }
 
index ba9188235057b17a6002a10c36493646aa747da8..3558ac78c9265517a4eb22628708f9774ded1f8b 100644 (file)
@@ -184,6 +184,12 @@ void __cpuinit check_efer(void)
 
 unsigned long kernel_eflags;
 
+/*
+ * Copies of the original ist values from the tss are only accessed during
+ * debugging, no special alignment required.
+ */
+DEFINE_PER_CPU(struct orig_ist, orig_ist);
+
 /*
  * cpu_init() initializes state that is per-CPU. Some data is already
  * initialized (naturally) in the bootstrap process, such as the GDT
@@ -224,8 +230,8 @@ void __cpuinit cpu_init (void)
                memcpy(cpu_gdt(cpu), cpu_gdt_table, GDT_SIZE);
 
        cpu_gdt_descr[cpu].size = GDT_SIZE;
-       asm volatile("lgdt %0" :: "m" (cpu_gdt_descr[cpu]));
-       asm volatile("lidt %0" :: "m" (idt_descr));
+       load_gdt((const struct desc_ptr *)&cpu_gdt_descr[cpu]);
+       load_idt((const struct desc_ptr *)&idt_descr);
 
        memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8);
        syscall_init();
index b87a6fd5ba48739b7be30f6cbcb434be8027a5cd..cc0e91447b76252411352ba3bb18c6ad4b3ea043 100644 (file)
@@ -60,6 +60,7 @@
 #include <asm/vmi.h>
 #include <setup_arch.h>
 #include <bios_ebda.h>
+#include <asm/cacheflush.h>
 
 /* This value is set up by the early boot code to point to the value
    immediately after the boot time page tables.  It contains a *physical*
@@ -73,6 +74,7 @@ int disable_pse __devinitdata = 0;
  */
 extern struct resource code_resource;
 extern struct resource data_resource;
+extern struct resource bss_resource;
 
 /* cpu data as detected by the assembly code in head.S */
 struct cpuinfo_x86 new_cpu_data __cpuinitdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
@@ -378,6 +380,49 @@ extern unsigned long __init setup_memory(void);
 extern void zone_sizes_init(void);
 #endif /* !CONFIG_NEED_MULTIPLE_NODES */
 
+static inline unsigned long long get_total_mem(void)
+{
+       unsigned long long total;
+
+       total = max_low_pfn - min_low_pfn;
+#ifdef CONFIG_HIGHMEM
+       total += highend_pfn - highstart_pfn;
+#endif
+
+       return total << PAGE_SHIFT;
+}
+
+#ifdef CONFIG_KEXEC
+static void __init reserve_crashkernel(void)
+{
+       unsigned long long total_mem;
+       unsigned long long crash_size, crash_base;
+       int ret;
+
+       total_mem = get_total_mem();
+
+       ret = parse_crashkernel(boot_command_line, total_mem,
+                       &crash_size, &crash_base);
+       if (ret == 0 && crash_size > 0) {
+               if (crash_base > 0) {
+                       printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
+                                       "for crashkernel (System RAM: %ldMB)\n",
+                                       (unsigned long)(crash_size >> 20),
+                                       (unsigned long)(crash_base >> 20),
+                                       (unsigned long)(total_mem >> 20));
+                       crashk_res.start = crash_base;
+                       crashk_res.end   = crash_base + crash_size - 1;
+                       reserve_bootmem(crash_base, crash_size);
+               } else
+                       printk(KERN_INFO "crashkernel reservation failed - "
+                                       "you have to specify a base address\n");
+       }
+}
+#else
+static inline void __init reserve_crashkernel(void)
+{}
+#endif
+
 void __init setup_bootmem_allocator(void)
 {
        unsigned long bootmap_size;
@@ -453,11 +498,7 @@ void __init setup_bootmem_allocator(void)
                }
        }
 #endif
-#ifdef CONFIG_KEXEC
-       if (crashk_res.start != crashk_res.end)
-               reserve_bootmem(crashk_res.start,
-                       crashk_res.end - crashk_res.start + 1);
-#endif
+       reserve_crashkernel();
 }
 
 /*
@@ -561,6 +602,8 @@ void __init setup_arch(char **cmdline_p)
        code_resource.end = virt_to_phys(_etext)-1;
        data_resource.start = virt_to_phys(_etext);
        data_resource.end = virt_to_phys(_edata)-1;
+       bss_resource.start = virt_to_phys(&__bss_start);
+       bss_resource.end = virt_to_phys(&__bss_stop)-1;
 
        parse_early_param();
 
@@ -585,7 +628,7 @@ void __init setup_arch(char **cmdline_p)
        /*
         * NOTE: before this point _nobody_ is allowed to allocate
         * any memory using the bootmem allocator.  Although the
-        * alloctor is now initialised only the first 8Mb of the kernel
+        * allocator is now initialised only the first 8Mb of the kernel
         * virtual address space has been mapped.  All allocations before
         * paging_init() has completed must use the alloc_bootmem_low_pages()
         * variant (which allocates DMA'able memory) and care must be taken
@@ -622,9 +665,7 @@ void __init setup_arch(char **cmdline_p)
 #endif
 
 #ifdef CONFIG_PCI
-#ifdef CONFIG_X86_IO_APIC
-       check_acpi_pci();       /* Checks more than just ACPI actually */
-#endif
+       early_quirks();
 #endif
 
 #ifdef CONFIG_ACPI
index 5a19f0cc5b6766c8c0ea3eed1164ec3605ac7c32..e7a9e36bd52d5159ab214e457d12f3a898691be7 100644 (file)
@@ -58,6 +58,7 @@
 #include <asm/numa.h>
 #include <asm/sections.h>
 #include <asm/dmi.h>
+#include <asm/cacheflush.h>
 
 /*
  * Machine setup..
@@ -133,6 +134,12 @@ struct resource code_resource = {
        .end = 0,
        .flags = IORESOURCE_RAM,
 };
+struct resource bss_resource = {
+       .name = "Kernel bss",
+       .start = 0,
+       .end = 0,
+       .flags = IORESOURCE_RAM,
+};
 
 #ifdef CONFIG_PROC_VMCORE
 /* elfcorehdr= specifies the location of elf core header
@@ -191,6 +198,37 @@ static inline void copy_edd(void)
 }
 #endif
 
+#ifdef CONFIG_KEXEC
+static void __init reserve_crashkernel(void)
+{
+       unsigned long long free_mem;
+       unsigned long long crash_size, crash_base;
+       int ret;
+
+       free_mem = ((unsigned long long)max_low_pfn - min_low_pfn) << PAGE_SHIFT;
+
+       ret = parse_crashkernel(boot_command_line, free_mem,
+                       &crash_size, &crash_base);
+       if (ret == 0 && crash_size) {
+               if (crash_base > 0) {
+                       printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
+                                       "for crashkernel (System RAM: %ldMB)\n",
+                                       (unsigned long)(crash_size >> 20),
+                                       (unsigned long)(crash_base >> 20),
+                                       (unsigned long)(free_mem >> 20));
+                       crashk_res.start = crash_base;
+                       crashk_res.end   = crash_base + crash_size - 1;
+                       reserve_bootmem(crash_base, crash_size);
+               } else
+                       printk(KERN_INFO "crashkernel reservation failed - "
+                                       "you have to specify a base address\n");
+       }
+}
+#else
+static inline void __init reserve_crashkernel(void)
+{}
+#endif
+
 #define EBDA_ADDR_POINTER 0x40E
 
 unsigned __initdata ebda_addr;
@@ -245,6 +283,8 @@ void __init setup_arch(char **cmdline_p)
        code_resource.end = virt_to_phys(&_etext)-1;
        data_resource.start = virt_to_phys(&_etext);
        data_resource.end = virt_to_phys(&_edata)-1;
+       bss_resource.start = virt_to_phys(&__bss_start);
+       bss_resource.end = virt_to_phys(&__bss_stop)-1;
 
        early_identify_cpu(&boot_cpu_data);
 
@@ -271,6 +311,11 @@ void __init setup_arch(char **cmdline_p)
 
        dmi_scan_machine();
 
+#ifdef CONFIG_SMP
+       /* setup to use the static apicid table during kernel startup */
+       x86_cpu_to_apicid_ptr = (void *)&x86_cpu_to_apicid_init;
+#endif
+
 #ifdef CONFIG_ACPI
        /*
         * Initialize the ACPI boot-time table parser (gets the RSDP and SDT).
@@ -357,13 +402,7 @@ void __init setup_arch(char **cmdline_p)
                }
        }
 #endif
-#ifdef CONFIG_KEXEC
-       if (crashk_res.start != crashk_res.end) {
-               reserve_bootmem_generic(crashk_res.start,
-                       crashk_res.end - crashk_res.start + 1);
-       }
-#endif
-
+       reserve_crashkernel();
        paging_init();
 
 #ifdef CONFIG_PCI
@@ -529,7 +568,7 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
                   but in the same order as the HT nodeids.
                   If that doesn't result in a usable node fall back to the
                   path for the previous case.  */
-               int ht_nodeid = apicid - (cpu_data[0].phys_proc_id << bits);
+               int ht_nodeid = apicid - (cpu_data(0).phys_proc_id << bits);
                if (ht_nodeid >= 0 &&
                    apicid_to_node[ht_nodeid] != NUMA_NO_NODE)
                        node = apicid_to_node[ht_nodeid];
@@ -853,6 +892,7 @@ void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c)
 
 #ifdef CONFIG_SMP
        c->phys_proc_id = (cpuid_ebx(1) >> 24) & 0xff;
+       c->cpu_index = 0;
 #endif
 }
 
@@ -959,6 +999,7 @@ void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
 static int show_cpuinfo(struct seq_file *m, void *v)
 {
        struct cpuinfo_x86 *c = v;
+       int cpu = 0;
 
        /* 
         * These flag bits must match the definitions in <asm/cpufeature.h>.
@@ -1037,8 +1078,9 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 
 
 #ifdef CONFIG_SMP
-       if (!cpu_online(c-cpu_data))
+       if (!cpu_online(c->cpu_index))
                return 0;
+       cpu = c->cpu_index;
 #endif
 
        seq_printf(m,"processor\t: %u\n"
@@ -1046,7 +1088,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                     "cpu family\t: %d\n"
                     "model\t\t: %d\n"
                     "model name\t: %s\n",
-                    (unsigned)(c-cpu_data),
+                    (unsigned)cpu,
                     c->x86_vendor_id[0] ? c->x86_vendor_id : "unknown",
                     c->x86,
                     (int)c->x86_model,
@@ -1058,7 +1100,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                seq_printf(m, "stepping\t: unknown\n");
        
        if (cpu_has(c,X86_FEATURE_TSC)) {
-               unsigned int freq = cpufreq_quick_get((unsigned)(c-cpu_data));
+               unsigned int freq = cpufreq_quick_get((unsigned)cpu);
                if (!freq)
                        freq = cpu_khz;
                seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
@@ -1071,7 +1113,6 @@ static int show_cpuinfo(struct seq_file *m, void *v)
        
 #ifdef CONFIG_SMP
        if (smp_num_siblings * c->x86_max_cores > 1) {
-               int cpu = c - cpu_data;
                seq_printf(m, "physical id\t: %d\n", c->phys_proc_id);
                seq_printf(m, "siblings\t: %d\n",
                               cpus_weight(per_cpu(cpu_core_map, cpu)));
@@ -1129,12 +1170,16 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 
 static void *c_start(struct seq_file *m, loff_t *pos)
 {
-       return *pos < NR_CPUS ? cpu_data + *pos : NULL;
+       if (*pos == 0)  /* just in case, cpu 0 is not the first */
+               *pos = first_cpu(cpu_possible_map);
+       if ((*pos) < NR_CPUS && cpu_possible(*pos))
+               return &cpu_data(*pos);
+       return NULL;
 }
 
 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
 {
-       ++*pos;
+       *pos = next_cpu(*pos, cpu_possible_map);
        return c_start(m, pos);
 }
 
index 0d79df3c5631e015886619d29870d9c9d3a3884e..9bdd83022f5f1659588409a2704d6a157f13e23e 100644 (file)
@@ -200,8 +200,8 @@ badframe:
        if (show_unhandled_signals && printk_ratelimit())
                printk("%s%s[%d] bad frame in sigreturn frame:%p eip:%lx"
                       " esp:%lx oeax:%lx\n",
-                   current->pid > 1 ? KERN_INFO : KERN_EMERG,
-                   current->comm, current->pid, frame, regs->eip,
+                   task_pid_nr(current) > 1 ? KERN_INFO : KERN_EMERG,
+                   current->comm, task_pid_nr(current), frame, regs->eip,
                    regs->esp, regs->orig_eax);
 
        force_sig(SIGSEGV, current);
@@ -594,7 +594,7 @@ static void fastcall do_signal(struct pt_regs *regs)
 
        signr = get_signal_to_deliver(&info, &ka, regs, NULL);
        if (signr > 0) {
-               /* Reenable any watchpoints before delivering the
+               /* Re-enable any watchpoints before delivering the
                 * signal to user space. The processor register will
                 * have been cleared if the watchpoint triggered
                 * inside the kernel.
index 683802bec419121944a9ec54fc68c013e86bb600..ab086b0357fc7cc977378a97f3525ad47f105095 100644 (file)
@@ -410,7 +410,7 @@ static void do_signal(struct pt_regs *regs)
 
        signr = get_signal_to_deliver(&info, &ka, regs, NULL);
        if (signr > 0) {
-               /* Reenable any watchpoints before delivering the
+               /* Re-enable any watchpoints before delivering the
                 * signal to user space. The processor register will
                 * have been cleared if the watchpoint triggered
                 * inside the kernel.
index 791d9f8036ae94019b2def24ed94a267414baf34..f32115308399453305598431f9955f97eb22387e 100644 (file)
@@ -69,7 +69,7 @@
  *
  *             B stepping CPUs may hang. There are hardware work arounds
  *     for this. We warn about it in case your board doesn't have the work
- *     arounds. Basically thats so I can tell anyone with a B stepping
+ *     arounds. Basically that's so I can tell anyone with a B stepping
  *     CPU and SMP problems "tough".
  *
  *     Specific items [From Pentium Processor Specification Update]
@@ -273,7 +273,7 @@ void leave_mm(unsigned long cpu)
  * 1a1) cpu_clear(cpu, old_mm->cpu_vm_mask);
  *     Stop ipi delivery for the old mm. This is not synchronized with
  *     the other cpus, but smp_invalidate_interrupt ignore flush ipis
- *     for the wrong mm, and in the worst case we perform a superflous
+ *     for the wrong mm, and in the worst case we perform a superfluous
  *     tlb flush.
  * 1a2) set cpu_tlbstate to TLBSTATE_OK
  *     Now the smp_invalidate_interrupt won't call leave_mm if cpu0
@@ -610,7 +610,7 @@ static void stop_this_cpu (void * dummy)
         */
        cpu_clear(smp_processor_id(), cpu_online_map);
        disable_local_APIC();
-       if (cpu_data[smp_processor_id()].hlt_works_ok)
+       if (cpu_data(smp_processor_id()).hlt_works_ok)
                for(;;) halt();
        for (;;);
 }
@@ -676,7 +676,7 @@ static int convert_apicid_to_cpu(int apic_id)
        int i;
 
        for (i = 0; i < NR_CPUS; i++) {
-               if (x86_cpu_to_apicid[i] == apic_id)
+               if (per_cpu(x86_cpu_to_apicid, i) == apic_id)
                        return i;
        }
        return -1;
index 5c2964727d197faf6bc135e50c7c95399781bcae..03fa6ed559c637f5bf3b240184db97c16642aa65 100644 (file)
@@ -322,17 +322,27 @@ void unlock_ipi_call_lock(void)
 }
 
 /*
- * this function sends a 'generic call function' IPI to one other CPU
- * in the system.
- *
- * cpu is a standard Linux logical CPU number.
+ * this function sends a 'generic call function' IPI to all other CPU
+ * of the system defined in the mask.
  */
-static void
-__smp_call_function_single(int cpu, void (*func) (void *info), void *info,
-                               int nonatomic, int wait)
+
+static int
+__smp_call_function_mask(cpumask_t mask,
+                        void (*func)(void *), void *info,
+                        int wait)
 {
        struct call_data_struct data;
-       int cpus = 1;
+       cpumask_t allbutself;
+       int cpus;
+
+       allbutself = cpu_online_map;
+       cpu_clear(smp_processor_id(), allbutself);
+
+       cpus_and(mask, mask, allbutself);
+       cpus = cpus_weight(mask);
+
+       if (!cpus)
+               return 0;
 
        data.func = func;
        data.info = info;
@@ -343,19 +353,55 @@ __smp_call_function_single(int cpu, void (*func) (void *info), void *info,
 
        call_data = &data;
        wmb();
-       /* Send a message to all other CPUs and wait for them to respond */
-       send_IPI_mask(cpumask_of_cpu(cpu), CALL_FUNCTION_VECTOR);
+
+       /* Send a message to other CPUs */
+       if (cpus_equal(mask, allbutself))
+               send_IPI_allbutself(CALL_FUNCTION_VECTOR);
+       else
+               send_IPI_mask(mask, CALL_FUNCTION_VECTOR);
 
        /* Wait for response */
        while (atomic_read(&data.started) != cpus)
                cpu_relax();
 
        if (!wait)
-               return;
+               return 0;
 
        while (atomic_read(&data.finished) != cpus)
                cpu_relax();
+
+       return 0;
+}
+/**
+ * smp_call_function_mask(): Run a function on a set of other CPUs.
+ * @mask: The set of cpus to run on.  Must not include the current cpu.
+ * @func: The function to run. This must be fast and non-blocking.
+ * @info: An arbitrary pointer to pass to the function.
+ * @wait: If true, wait (atomically) until function has completed on other CPUs.
+ *
+ * Returns 0 on success, else a negative status code.
+ *
+ * If @wait is true, then returns once @func has returned; otherwise
+ * it returns just before the target cpu calls @func.
+ *
+ * You must not call this function with disabled interrupts or from a
+ * hardware interrupt handler or from a bottom half handler.
+ */
+int smp_call_function_mask(cpumask_t mask,
+                          void (*func)(void *), void *info,
+                          int wait)
+{
+       int ret;
+
+       /* Can deadlock when called with interrupts disabled */
+       WARN_ON(irqs_disabled());
+
+       spin_lock(&call_lock);
+       ret = __smp_call_function_mask(mask, func, info, wait);
+       spin_unlock(&call_lock);
+       return ret;
 }
+EXPORT_SYMBOL(smp_call_function_mask);
 
 /*
  * smp_call_function_single - Run a function on a specific CPU
@@ -374,6 +420,7 @@ int smp_call_function_single (int cpu, void (*func) (void *info), void *info,
        int nonatomic, int wait)
 {
        /* prevent preemption and reschedule on another processor */
+       int ret;
        int me = get_cpu();
 
        /* Can deadlock when called with interrupts disabled */
@@ -387,50 +434,13 @@ int smp_call_function_single (int cpu, void (*func) (void *info), void *info,
                return 0;
        }
 
-       spin_lock(&call_lock);
-       __smp_call_function_single(cpu, func, info, nonatomic, wait);
-       spin_unlock(&call_lock);
+       ret = smp_call_function_mask(cpumask_of_cpu(cpu), func, info, wait);
+
        put_cpu();
-       return 0;
+       return ret;
 }
 EXPORT_SYMBOL(smp_call_function_single);
 
-/*
- * this function sends a 'generic call function' IPI to all other CPUs
- * in the system.
- */
-static void __smp_call_function (void (*func) (void *info), void *info,
-                               int nonatomic, int wait)
-{
-       struct call_data_struct data;
-       int cpus = num_online_cpus()-1;
-
-       if (!cpus)
-               return;
-
-       data.func = func;
-       data.info = info;
-       atomic_set(&data.started, 0);
-       data.wait = wait;
-       if (wait)
-               atomic_set(&data.finished, 0);
-
-       call_data = &data;
-       wmb();
-       /* Send a message to all other CPUs and wait for them to respond */
-       send_IPI_allbutself(CALL_FUNCTION_VECTOR);
-
-       /* Wait for response */
-       while (atomic_read(&data.started) != cpus)
-               cpu_relax();
-
-       if (!wait)
-               return;
-
-       while (atomic_read(&data.finished) != cpus)
-               cpu_relax();
-}
-
 /*
  * smp_call_function - run a function on all other CPUs.
  * @func: The function to run. This must be fast and non-blocking.
@@ -449,10 +459,7 @@ static void __smp_call_function (void (*func) (void *info), void *info,
 int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
                        int wait)
 {
-       spin_lock(&call_lock);
-       __smp_call_function(func,info,nonatomic,wait);
-       spin_unlock(&call_lock);
-       return 0;
+       return smp_call_function_mask(cpu_online_map, func, info, wait);
 }
 EXPORT_SYMBOL(smp_call_function);
 
@@ -479,7 +486,7 @@ void smp_send_stop(void)
        /* Don't deadlock on the call lock in panic */
        nolock = !spin_trylock(&call_lock);
        local_irq_save(flags);
-       __smp_call_function(stop_this_cpu, NULL, 0, 0);
+       __smp_call_function_mask(cpu_online_map, stop_this_cpu, NULL, 0);
        if (!nolock)
                spin_unlock(&call_lock);
        disable_local_APIC();
index be3faac047190e2647d95baae8d0322dc1a922c4..ef0f34ede1ab34c4db94e1d6c5bd22f4b4a2b4d6 100644 (file)
@@ -67,7 +67,7 @@ int smp_num_siblings = 1;
 EXPORT_SYMBOL(smp_num_siblings);
 
 /* Last level cache ID of each logical CPU */
-int cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID};
+DEFINE_PER_CPU(u8, cpu_llc_id) = BAD_APICID;
 
 /* representing HT siblings of each logical CPU */
 DEFINE_PER_CPU(cpumask_t, cpu_sibling_map);
@@ -89,12 +89,20 @@ EXPORT_SYMBOL(cpu_possible_map);
 static cpumask_t smp_commenced_mask;
 
 /* Per CPU bogomips and other parameters */
-struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
-EXPORT_SYMBOL(cpu_data);
+DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info);
+EXPORT_PER_CPU_SYMBOL(cpu_info);
 
-u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly =
-                       { [0 ... NR_CPUS-1] = 0xff };
-EXPORT_SYMBOL(x86_cpu_to_apicid);
+/*
+ * The following static array is used during kernel startup
+ * and the x86_cpu_to_apicid_ptr contains the address of the
+ * array during this time.  Is it zeroed when the per_cpu
+ * data area is removed.
+ */
+u8 x86_cpu_to_apicid_init[NR_CPUS] __initdata =
+                       { [0 ... NR_CPUS-1] = BAD_APICID };
+void *x86_cpu_to_apicid_ptr;
+DEFINE_PER_CPU(u8, x86_cpu_to_apicid) = BAD_APICID;
+EXPORT_PER_CPU_SYMBOL(x86_cpu_to_apicid);
 
 u8 apicid_2_node[MAX_APICID];
 
@@ -150,9 +158,10 @@ void __init smp_alloc_memory(void)
 
 void __cpuinit smp_store_cpu_info(int id)
 {
-       struct cpuinfo_x86 *c = cpu_data + id;
+       struct cpuinfo_x86 *c = &cpu_data(id);
 
        *c = boot_cpu_data;
+       c->cpu_index = id;
        if (id!=0)
                identify_secondary_cpu(c);
        /*
@@ -294,7 +303,7 @@ static int cpucount;
 /* maps the cpu to the sched domain representing multi-core */
 cpumask_t cpu_coregroup_map(int cpu)
 {
-       struct cpuinfo_x86 *c = cpu_data + cpu;
+       struct cpuinfo_x86 *c = &cpu_data(cpu);
        /*
         * For perf, we return last level cache shared map.
         * And for power savings, we return cpu_core_map
@@ -311,41 +320,41 @@ static cpumask_t cpu_sibling_setup_map;
 void __cpuinit set_cpu_sibling_map(int cpu)
 {
        int i;
-       struct cpuinfo_x86 *c = cpu_data;
+       struct cpuinfo_x86 *c = &cpu_data(cpu);
 
        cpu_set(cpu, cpu_sibling_setup_map);
 
        if (smp_num_siblings > 1) {
                for_each_cpu_mask(i, cpu_sibling_setup_map) {
-                       if (c[cpu].phys_proc_id == c[i].phys_proc_id &&
-                           c[cpu].cpu_core_id == c[i].cpu_core_id) {
+                       if (c->phys_proc_id == cpu_data(i).phys_proc_id &&
+                           c->cpu_core_id == cpu_data(i).cpu_core_id) {
                                cpu_set(i, per_cpu(cpu_sibling_map, cpu));
                                cpu_set(cpu, per_cpu(cpu_sibling_map, i));
                                cpu_set(i, per_cpu(cpu_core_map, cpu));
                                cpu_set(cpu, per_cpu(cpu_core_map, i));
-                               cpu_set(i, c[cpu].llc_shared_map);
-                               cpu_set(cpu, c[i].llc_shared_map);
+                               cpu_set(i, c->llc_shared_map);
+                               cpu_set(cpu, cpu_data(i).llc_shared_map);
                        }
                }
        } else {
                cpu_set(cpu, per_cpu(cpu_sibling_map, cpu));
        }
 
-       cpu_set(cpu, c[cpu].llc_shared_map);
+       cpu_set(cpu, c->llc_shared_map);
 
        if (current_cpu_data.x86_max_cores == 1) {
                per_cpu(cpu_core_map, cpu) = per_cpu(cpu_sibling_map, cpu);
-               c[cpu].booted_cores = 1;
+               c->booted_cores = 1;
                return;
        }
 
        for_each_cpu_mask(i, cpu_sibling_setup_map) {
-               if (cpu_llc_id[cpu] != BAD_APICID &&
-                   cpu_llc_id[cpu] == cpu_llc_id[i]) {
-                       cpu_set(i, c[cpu].llc_shared_map);
-                       cpu_set(cpu, c[i].llc_shared_map);
+               if (per_cpu(cpu_llc_id, cpu) != BAD_APICID &&
+                   per_cpu(cpu_llc_id, cpu) == per_cpu(cpu_llc_id, i)) {
+                       cpu_set(i, c->llc_shared_map);
+                       cpu_set(cpu, cpu_data(i).llc_shared_map);
                }
-               if (c[cpu].phys_proc_id == c[i].phys_proc_id) {
+               if (c->phys_proc_id == cpu_data(i).phys_proc_id) {
                        cpu_set(i, per_cpu(cpu_core_map, cpu));
                        cpu_set(cpu, per_cpu(cpu_core_map, i));
                        /*
@@ -357,15 +366,15 @@ void __cpuinit set_cpu_sibling_map(int cpu)
                                 * the booted_cores for this new cpu
                                 */
                                if (first_cpu(per_cpu(cpu_sibling_map, i)) == i)
-                                       c[cpu].booted_cores++;
+                                       c->booted_cores++;
                                /*
                                 * increment the core count for all
                                 * the other cpus in this package
                                 */
                                if (i != cpu)
-                                       c[i].booted_cores++;
-                       } else if (i != cpu && !c[cpu].booted_cores)
-                               c[cpu].booted_cores = c[i].booted_cores;
+                                       cpu_data(i).booted_cores++;
+                       } else if (i != cpu && !c->booted_cores)
+                               c->booted_cores = cpu_data(i).booted_cores;
                }
        }
 }
@@ -412,7 +421,7 @@ static void __cpuinit start_secondary(void *unused)
        /*
         * We need to hold call_lock, so there is no inconsistency
         * between the time smp_call_function() determines number of
-        * IPI receipients, and the time when the determination is made
+        * IPI recipients, and the time when the determination is made
         * for which cpus receive the IPI. Holding this
         * lock helps us to not include this cpu in a currently in progress
         * smp_call_function().
@@ -804,7 +813,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu)
 
        irq_ctx_init(cpu);
 
-       x86_cpu_to_apicid[cpu] = apicid;
+       per_cpu(x86_cpu_to_apicid, cpu) = apicid;
        /*
         * This grunge runs the startup process for
         * the targeted processor.
@@ -844,7 +853,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu)
                        /* number CPUs logically, starting from 1 (BSP is 0) */
                        Dprintk("OK.\n");
                        printk("CPU%d: ", cpu);
-                       print_cpu_info(&cpu_data[cpu]);
+                       print_cpu_info(&cpu_data(cpu));
                        Dprintk("CPU has booted.\n");
                } else {
                        boot_error= 1;
@@ -866,7 +875,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu)
                cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */
                cpucount--;
        } else {
-               x86_cpu_to_apicid[cpu] = apicid;
+               per_cpu(x86_cpu_to_apicid, cpu) = apicid;
                cpu_set(cpu, cpu_present_map);
        }
 
@@ -915,7 +924,7 @@ static int __cpuinit __smp_prepare_cpu(int cpu)
        struct warm_boot_cpu_info info;
        int     apicid, ret;
 
-       apicid = x86_cpu_to_apicid[cpu];
+       apicid = per_cpu(x86_cpu_to_apicid, cpu);
        if (apicid == BAD_APICID) {
                ret = -ENODEV;
                goto exit;
@@ -961,11 +970,11 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
         */
        smp_store_cpu_info(0); /* Final full version of the data */
        printk("CPU%d: ", 0);
-       print_cpu_info(&cpu_data[0]);
+       print_cpu_info(&cpu_data(0));
 
        boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
        boot_cpu_logical_apicid = logical_smp_processor_id();
-       x86_cpu_to_apicid[0] = boot_cpu_physical_apicid;
+       per_cpu(x86_cpu_to_apicid, 0) = boot_cpu_physical_apicid;
 
        current_thread_info()->cpu = 0;
 
@@ -1008,6 +1017,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
                printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
                smpboot_clear_io_apic_irqs();
                phys_cpu_present_map = physid_mask_of_physid(0);
+               map_cpu_to_logical_apicid();
                cpu_set(0, per_cpu(cpu_sibling_map, 0));
                cpu_set(0, per_cpu(cpu_core_map, 0));
                return;
@@ -1029,6 +1039,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
                }
                smpboot_clear_io_apic_irqs();
                phys_cpu_present_map = physid_mask_of_physid(0);
+               map_cpu_to_logical_apicid();
                cpu_set(0, per_cpu(cpu_sibling_map, 0));
                cpu_set(0, per_cpu(cpu_core_map, 0));
                return;
@@ -1082,7 +1093,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
        Dprintk("Before bogomips.\n");
        for (cpu = 0; cpu < NR_CPUS; cpu++)
                if (cpu_isset(cpu, cpu_callout_map))
-                       bogosum += cpu_data[cpu].loops_per_jiffy;
+                       bogosum += cpu_data(cpu).loops_per_jiffy;
        printk(KERN_INFO
                "Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
                cpucount+1,
@@ -1152,7 +1163,7 @@ void __init native_smp_prepare_boot_cpu(void)
 void remove_siblinginfo(int cpu)
 {
        int sibling;
-       struct cpuinfo_x86 *c = cpu_data;
+       struct cpuinfo_x86 *c = &cpu_data(cpu);
 
        for_each_cpu_mask(sibling, per_cpu(cpu_core_map, cpu)) {
                cpu_clear(cpu, per_cpu(cpu_core_map, sibling));
@@ -1160,15 +1171,15 @@ void remove_siblinginfo(int cpu)
                 * last thread sibling in this cpu core going down
                 */
                if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1)
-                       c[sibling].booted_cores--;
+                       cpu_data(sibling).booted_cores--;
        }
                        
        for_each_cpu_mask(sibling, per_cpu(cpu_sibling_map, cpu))
                cpu_clear(cpu, per_cpu(cpu_sibling_map, sibling));
        cpus_clear(per_cpu(cpu_sibling_map, cpu));
        cpus_clear(per_cpu(cpu_core_map, cpu));
-       c[cpu].phys_proc_id = 0;
-       c[cpu].cpu_core_id = 0;
+       c->phys_proc_id = 0;
+       c->cpu_core_id = 0;
        cpu_clear(cpu, cpu_sibling_setup_map);
 }
 
index e351ac4ab5b1b2f3f430dfc4d5b974af04cbb77c..b7e768dd87c90c731770cdce985649409626b73a 100644 (file)
@@ -65,7 +65,7 @@ int smp_num_siblings = 1;
 EXPORT_SYMBOL(smp_num_siblings);
 
 /* Last level cache ID of each logical CPU */
-u8 cpu_llc_id[NR_CPUS] __cpuinitdata  = {[0 ... NR_CPUS-1] = BAD_APICID};
+DEFINE_PER_CPU(u8, cpu_llc_id) = BAD_APICID;
 
 /* Bitmask of currently online CPUs */
 cpumask_t cpu_online_map __read_mostly;
@@ -84,8 +84,8 @@ cpumask_t cpu_possible_map;
 EXPORT_SYMBOL(cpu_possible_map);
 
 /* Per CPU bogomips and other parameters */
-struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
-EXPORT_SYMBOL(cpu_data);
+DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info);
+EXPORT_PER_CPU_SYMBOL(cpu_info);
 
 /* Set when the idlers are all forked */
 int smp_threads_ready;
@@ -138,9 +138,10 @@ static unsigned long __cpuinit setup_trampoline(void)
 
 static void __cpuinit smp_store_cpu_info(int id)
 {
-       struct cpuinfo_x86 *c = cpu_data + id;
+       struct cpuinfo_x86 *c = &cpu_data(id);
 
        *c = boot_cpu_data;
+       c->cpu_index = id;
        identify_cpu(c);
        print_cpu_info(c);
 }
@@ -237,7 +238,7 @@ void __cpuinit smp_callin(void)
 /* maps the cpu to the sched domain representing multi-core */
 cpumask_t cpu_coregroup_map(int cpu)
 {
-       struct cpuinfo_x86 *c = cpu_data + cpu;
+       struct cpuinfo_x86 *c = &cpu_data(cpu);
        /*
         * For perf, we return last level cache shared map.
         * And for power savings, we return cpu_core_map
@@ -254,41 +255,41 @@ static cpumask_t cpu_sibling_setup_map;
 static inline void set_cpu_sibling_map(int cpu)
 {
        int i;
-       struct cpuinfo_x86 *c = cpu_data;
+       struct cpuinfo_x86 *c = &cpu_data(cpu);
 
        cpu_set(cpu, cpu_sibling_setup_map);
 
        if (smp_num_siblings > 1) {
                for_each_cpu_mask(i, cpu_sibling_setup_map) {
-                       if (c[cpu].phys_proc_id == c[i].phys_proc_id &&
-                           c[cpu].cpu_core_id == c[i].cpu_core_id) {
+                       if (c->phys_proc_id == cpu_data(i).phys_proc_id &&
+                           c->cpu_core_id == cpu_data(i).cpu_core_id) {
                                cpu_set(i, per_cpu(cpu_sibling_map, cpu));
                                cpu_set(cpu, per_cpu(cpu_sibling_map, i));
                                cpu_set(i, per_cpu(cpu_core_map, cpu));
                                cpu_set(cpu, per_cpu(cpu_core_map, i));
-                               cpu_set(i, c[cpu].llc_shared_map);
-                               cpu_set(cpu, c[i].llc_shared_map);
+                               cpu_set(i, c->llc_shared_map);
+                               cpu_set(cpu, cpu_data(i).llc_shared_map);
                        }
                }
        } else {
                cpu_set(cpu, per_cpu(cpu_sibling_map, cpu));
        }
 
-       cpu_set(cpu, c[cpu].llc_shared_map);
+       cpu_set(cpu, c->llc_shared_map);
 
        if (current_cpu_data.x86_max_cores == 1) {
                per_cpu(cpu_core_map, cpu) = per_cpu(cpu_sibling_map, cpu);
-               c[cpu].booted_cores = 1;
+               c->booted_cores = 1;
                return;
        }
 
        for_each_cpu_mask(i, cpu_sibling_setup_map) {
-               if (cpu_llc_id[cpu] != BAD_APICID &&
-                   cpu_llc_id[cpu] == cpu_llc_id[i]) {
-                       cpu_set(i, c[cpu].llc_shared_map);
-                       cpu_set(cpu, c[i].llc_shared_map);
+               if (per_cpu(cpu_llc_id, cpu) != BAD_APICID &&
+                   per_cpu(cpu_llc_id, cpu) == per_cpu(cpu_llc_id, i)) {
+                       cpu_set(i, c->llc_shared_map);
+                       cpu_set(cpu, cpu_data(i).llc_shared_map);
                }
-               if (c[cpu].phys_proc_id == c[i].phys_proc_id) {
+               if (c->phys_proc_id == cpu_data(i).phys_proc_id) {
                        cpu_set(i, per_cpu(cpu_core_map, cpu));
                        cpu_set(cpu, per_cpu(cpu_core_map, i));
                        /*
@@ -300,15 +301,15 @@ static inline void set_cpu_sibling_map(int cpu)
                                 * the booted_cores for this new cpu
                                 */
                                if (first_cpu(per_cpu(cpu_sibling_map, i)) == i)
-                                       c[cpu].booted_cores++;
+                                       c->booted_cores++;
                                /*
                                 * increment the core count for all
                                 * the other cpus in this package
                                 */
                                if (i != cpu)
-                                       c[i].booted_cores++;
-                       } else if (i != cpu && !c[cpu].booted_cores)
-                               c[cpu].booted_cores = c[i].booted_cores;
+                                       cpu_data(i).booted_cores++;
+                       } else if (i != cpu && !c->booted_cores)
+                               c->booted_cores = cpu_data(i).booted_cores;
                }
        }
 }
@@ -350,7 +351,7 @@ void __cpuinit start_secondary(void)
        /*
         * We need to hold call_lock, so there is no inconsistency
         * between the time smp_call_function() determines number of
-        * IPI receipients, and the time when the determination is made
+        * IPI recipients, and the time when the determination is made
         * for which cpus receive the IPI in genapic_flat.c. Holding this
         * lock helps us to not include this cpu in a currently in progress
         * smp_call_function().
@@ -694,7 +695,7 @@ do_rest:
                clear_node_cpumask(cpu); /* was set by numa_add_cpu */
                cpu_clear(cpu, cpu_present_map);
                cpu_clear(cpu, cpu_possible_map);
-               x86_cpu_to_apicid[cpu] = BAD_APICID;
+               per_cpu(x86_cpu_to_apicid, cpu) = BAD_APICID;
                return -EIO;
        }
 
@@ -840,6 +841,26 @@ static int __init smp_sanity_check(unsigned max_cpus)
        return 0;
 }
 
+/*
+ * Copy apicid's found by MP_processor_info from initial array to the per cpu
+ * data area.  The x86_cpu_to_apicid_init array is then expendable and the
+ * x86_cpu_to_apicid_ptr is zeroed indicating that the static array is no
+ * longer available.
+ */
+void __init smp_set_apicids(void)
+{
+       int cpu;
+
+       for_each_cpu_mask(cpu, cpu_possible_map) {
+               if (per_cpu_offset(cpu))
+                       per_cpu(x86_cpu_to_apicid, cpu) =
+                                               x86_cpu_to_apicid_init[cpu];
+       }
+
+       /* indicate the static array will be going away soon */
+       x86_cpu_to_apicid_ptr = NULL;
+}
+
 /*
  * Prepare for SMP bootup.  The MP table or ACPI has been read
  * earlier.  Just do some sanity checking here and enable APIC mode.
@@ -849,6 +870,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
        nmi_watchdog_default();
        current_cpu_data = boot_cpu_data;
        current_thread_info()->cpu = 0;  /* needed? */
+       smp_set_apicids();
        set_cpu_sibling_map(0);
 
        if (smp_sanity_check(max_cpus) < 0) {
@@ -968,7 +990,7 @@ void __init smp_cpus_done(unsigned int max_cpus)
 static void remove_siblinginfo(int cpu)
 {
        int sibling;
-       struct cpuinfo_x86 *c = cpu_data;
+       struct cpuinfo_x86 *c = &cpu_data(cpu);
 
        for_each_cpu_mask(sibling, per_cpu(cpu_core_map, cpu)) {
                cpu_clear(cpu, per_cpu(cpu_core_map, sibling));
@@ -976,15 +998,15 @@ static void remove_siblinginfo(int cpu)
                 * last thread sibling in this cpu core going down
                 */
                if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1)
-                       c[sibling].booted_cores--;
+                       cpu_data(sibling).booted_cores--;
        }
                        
        for_each_cpu_mask(sibling, per_cpu(cpu_sibling_map, cpu))
                cpu_clear(cpu, per_cpu(cpu_sibling_map, sibling));
        cpus_clear(per_cpu(cpu_sibling_map, cpu));
        cpus_clear(per_cpu(cpu_core_map, cpu));
-       c[cpu].phys_proc_id = 0;
-       c[cpu].cpu_core_id = 0;
+       c->phys_proc_id = 0;
+       c->cpu_core_id = 0;
        cpu_clear(cpu, cpu_sibling_setup_map);
 }
 
index 91c7acc8d999305f17c613798748d92a07b3b93e..72f463401592bfd997e502eaa9ca7264523ee640 100644 (file)
@@ -64,7 +64,7 @@ static int __init setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus)
 
        switch (rio_devs[wpeg_num]->type){
        case CompatWPEG:
-               /* The Compatability Winnipeg controls the 2 legacy buses,
+               /* The Compatibility Winnipeg controls the 2 legacy buses,
                 * the 66MHz PCI bus [2 slots] and the 2 "extra" buses in case
                 * a PCI-PCI bridge card is used in either slot: total 5 buses.
                 */
index 573c0a6e0ac636e29a1da03ae608094200f499f5..bc9f59c246fd99890da74eec868d92cc3f8f7f2b 100644 (file)
@@ -32,9 +32,9 @@ void __save_processor_state(struct saved_context *ctxt)
        /*
         * descriptor tables
         */
-       asm volatile ("sgdt %0" : "=m" (ctxt->gdt_limit));
-       asm volatile ("sidt %0" : "=m" (ctxt->idt_limit));
-       asm volatile ("str %0"  : "=m" (ctxt->tr));
+       store_gdt((struct desc_ptr *)&ctxt->gdt_limit);
+       store_idt((struct desc_ptr *)&ctxt->idt_limit);
+       store_tr(ctxt->tr);
 
        /* XMM0..XMM15 should be handled by kernel_fpu_begin(). */
        /*
@@ -91,8 +91,9 @@ void __restore_processor_state(struct saved_context *ctxt)
         * now restore the descriptor tables to their proper values
         * ltr is done i fix_processor_context().
         */
-       asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit));
-       asm volatile ("lidt %0" :: "m" (ctxt->idt_limit));
+       load_gdt((const struct desc_ptr *)&ctxt->gdt_limit);
+       load_idt((const struct desc_ptr *)&ctxt->idt_limit);
+
 
        /*
         * segment registers
@@ -123,7 +124,7 @@ void fix_processor_context(void)
        int cpu = smp_processor_id();
        struct tss_struct *t = &per_cpu(init_tss, cpu);
 
-       set_tss_desc(cpu,t);    /* This just modifies memory; should not be neccessary. But... This is neccessary, because 386 hardware has concept of busy TSS or some similar stupidity. */
+       set_tss_desc(cpu,t);    /* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */
 
        cpu_gdt(cpu)[GDT_ENTRY_TSS].type = 9;
 
@@ -150,8 +151,22 @@ void fix_processor_context(void)
 /* Defined in arch/x86_64/kernel/suspend_asm.S */
 extern int restore_image(void);
 
+/*
+ * Address to jump to in the last phase of restore in order to get to the image
+ * kernel's text (this value is passed in the image header).
+ */
+unsigned long restore_jump_address;
+
+/*
+ * Value of the cr3 register from before the hibernation (this value is passed
+ * in the image header).
+ */
+unsigned long restore_cr3;
+
 pgd_t *temp_level4_pgt;
 
+void *relocated_restore_code;
+
 static int res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long end)
 {
        long i, j;
@@ -175,7 +190,7 @@ static int res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long en
 
                        if (paddr >= end)
                                break;
-                       pe = _PAGE_NX | _PAGE_PSE | _KERNPG_TABLE | paddr;
+                       pe = __PAGE_KERNEL_LARGE_EXEC | paddr;
                        pe &= __supported_pte_mask;
                        set_pmd(pmd, __pmd(pe));
                }
@@ -183,25 +198,42 @@ static int res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long en
        return 0;
 }
 
+static int res_kernel_text_pud_init(pud_t *pud, unsigned long start)
+{
+       pmd_t *pmd;
+       unsigned long paddr;
+
+       pmd = (pmd_t *)get_safe_page(GFP_ATOMIC);
+       if (!pmd)
+               return -ENOMEM;
+       set_pud(pud + pud_index(start), __pud(__pa(pmd) | _KERNPG_TABLE));
+       for (paddr = 0; paddr < KERNEL_TEXT_SIZE; pmd++, paddr += PMD_SIZE) {
+               unsigned long pe;
+
+               pe = __PAGE_KERNEL_LARGE_EXEC | _PAGE_GLOBAL | paddr;
+               pe &= __supported_pte_mask;
+               set_pmd(pmd, __pmd(pe));
+       }
+
+       return 0;
+}
+
 static int set_up_temporary_mappings(void)
 {
        unsigned long start, end, next;
+       pud_t *pud;
        int error;
 
        temp_level4_pgt = (pgd_t *)get_safe_page(GFP_ATOMIC);
        if (!temp_level4_pgt)
                return -ENOMEM;
 
-       /* It is safe to reuse the original kernel mapping */
-       set_pgd(temp_level4_pgt + pgd_index(__START_KERNEL_map),
-               init_level4_pgt[pgd_index(__START_KERNEL_map)]);
-
        /* Set up the direct mapping from scratch */
        start = (unsigned long)pfn_to_kaddr(0);
        end = (unsigned long)pfn_to_kaddr(end_pfn);
 
        for (; start < end; start = next) {
-               pud_t *pud = (pud_t *)get_safe_page(GFP_ATOMIC);
+               pud = (pud_t *)get_safe_page(GFP_ATOMIC);
                if (!pud)
                        return -ENOMEM;
                next = start + PGDIR_SIZE;
@@ -212,7 +244,17 @@ static int set_up_temporary_mappings(void)
                set_pgd(temp_level4_pgt + pgd_index(start),
                        mk_kernel_pgd(__pa(pud)));
        }
-       return 0;
+
+       /* Set up the kernel text mapping from scratch */
+       pud = (pud_t *)get_safe_page(GFP_ATOMIC);
+       if (!pud)
+               return -ENOMEM;
+       error = res_kernel_text_pud_init(pud, __START_KERNEL_map);
+       if (!error)
+               set_pgd(temp_level4_pgt + pgd_index(__START_KERNEL_map),
+                       __pgd(__pa(pud) | _PAGE_TABLE));
+
+       return error;
 }
 
 int swsusp_arch_resume(void)
@@ -222,6 +264,13 @@ int swsusp_arch_resume(void)
        /* We have got enough memory and from now on we cannot recover */
        if ((error = set_up_temporary_mappings()))
                return error;
+
+       relocated_restore_code = (void *)get_safe_page(GFP_ATOMIC);
+       if (!relocated_restore_code)
+               return -ENOMEM;
+       memcpy(relocated_restore_code, &core_restore_code,
+              &restore_registers - &core_restore_code);
+
        restore_image();
        return 0;
 }
@@ -236,4 +285,43 @@ int pfn_is_nosave(unsigned long pfn)
        unsigned long nosave_end_pfn = PAGE_ALIGN(__pa_symbol(&__nosave_end)) >> PAGE_SHIFT;
        return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn);
 }
+
+struct restore_data_record {
+       unsigned long jump_address;
+       unsigned long cr3;
+       unsigned long magic;
+};
+
+#define RESTORE_MAGIC  0x0123456789ABCDEFUL
+
+/**
+ *     arch_hibernation_header_save - populate the architecture specific part
+ *             of a hibernation image header
+ *     @addr: address to save the data at
+ */
+int arch_hibernation_header_save(void *addr, unsigned int max_size)
+{
+       struct restore_data_record *rdr = addr;
+
+       if (max_size < sizeof(struct restore_data_record))
+               return -EOVERFLOW;
+       rdr->jump_address = restore_jump_address;
+       rdr->cr3 = restore_cr3;
+       rdr->magic = RESTORE_MAGIC;
+       return 0;
+}
+
+/**
+ *     arch_hibernation_header_restore - read the architecture specific data
+ *             from the hibernation image header
+ *     @addr: address to read the data from
+ */
+int arch_hibernation_header_restore(void *addr)
+{
+       struct restore_data_record *rdr = addr;
+
+       restore_jump_address = rdr->jump_address;
+       restore_cr3 = rdr->cr3;
+       return (rdr->magic == RESTORE_MAGIC) ? 0 : -EINVAL;
+}
 #endif /* CONFIG_HIBERNATION */
index 16d183f67bc1e66e790f6160ae54a436554b9041..48344b666d2c2e60f56d3393d82ecc48e0b9388f 100644 (file)
@@ -2,8 +2,8 @@
  *
  * Distribute under GPLv2.
  *
- * swsusp_arch_resume may not use any stack, nor any variable that is
- * not "NoSave" during copying pages:
+ * swsusp_arch_resume must not use any stack or any nonlocal variables while
+ * copying pages:
  *
  * Its rewriting one kernel image with another. What is stack in "old"
  * image could very well be data page in "new" image, and overwriting
@@ -36,6 +36,13 @@ ENTRY(swsusp_arch_suspend)
        movq %r15, saved_context_r15(%rip)
        pushfq ; popq saved_context_eflags(%rip)
 
+       /* save the address of restore_registers */
+       movq    $restore_registers, %rax
+       movq    %rax, restore_jump_address(%rip)
+       /* save cr3 */
+       movq    %cr3, %rax
+       movq    %rax, restore_cr3(%rip)
+
        call swsusp_save
        ret
 
@@ -54,7 +61,17 @@ ENTRY(restore_image)
        movq    %rcx, %cr3;
        movq    %rax, %cr4;  # turn PGE back on
 
+       /* prepare to jump to the image kernel */
+       movq    restore_jump_address(%rip), %rax
+       movq    restore_cr3(%rip), %rbx
+
+       /* prepare to copy image data to their original locations */
        movq    restore_pblist(%rip), %rdx
+       movq    relocated_restore_code(%rip), %rcx
+       jmpq    *%rcx
+
+       /* code below has been relocated to a safe page */
+ENTRY(core_restore_code)
 loop:
        testq   %rdx, %rdx
        jz      done
@@ -62,7 +79,7 @@ loop:
        /* get addresses from the pbe and copy the page */
        movq    pbe_address(%rdx), %rsi
        movq    pbe_orig_address(%rdx), %rdi
-       movq    $512, %rcx
+       movq    $(PAGE_SIZE >> 3), %rcx
        rep
        movsq
 
@@ -70,10 +87,22 @@ loop:
        movq    pbe_next(%rdx), %rdx
        jmp     loop
 done:
+       /* jump to the restore_registers address from the image header */
+       jmpq    *%rax
+       /*
+        * NOTE: This assumes that the boot kernel's text mapping covers the
+        * image kernel's page containing restore_registers and the address of
+        * this page is the same as in the image kernel's text mapping (it
+        * should always be true, because the text mapping is linear, starting
+        * from 0, and is supposed to cover the entire kernel text for every
+        * kernel).
+        *
+        * code below belongs to the image kernel
+        */
+
+ENTRY(restore_registers)
        /* go back to the original page tables */
-       movq    $(init_level4_pgt - __START_KERNEL_map), %rax
-       addq    phys_base(%rip), %rax
-       movq    %rax, %cr3
+       movq    %rbx, %cr3
 
        /* Flush TLB, including "global" things (vmalloc) */
        movq    mmu_cr4_features(%rip), %rax
@@ -84,12 +113,9 @@ done:
        movq    %rcx, %cr3
        movq    %rax, %cr4;  # turn PGE back on
 
-       movl    $24, %eax
-       movl    %eax, %ds
-
        movq saved_context_esp(%rip), %rsp
        movq saved_context_ebp(%rip), %rbp
-       /* Don't restore %rax, it must be 0 anyway */
+       /* restore GPRs (we don't restore %rax, it must be 0 anyway) */
        movq saved_context_ebx(%rip), %rbx
        movq saved_context_ecx(%rip), %rcx
        movq saved_context_edx(%rip), %rdx
@@ -107,4 +133,7 @@ done:
 
        xorq    %rax, %rax
 
+       /* tell the hibernation core that we've just restored the memory */
+       movq    %rax, in_suspend(%rip)
+
        ret
index b132d3957dfc48c88684cb5b3fe492238f02480f..cc9acace7e23ba05b810afcf3c9d96bff0516d6c 100644 (file)
@@ -63,6 +63,9 @@
 
 int panic_on_unrecovered_nmi;
 
+DECLARE_BITMAP(used_vectors, NR_VECTORS);
+EXPORT_SYMBOL_GPL(used_vectors);
+
 asmlinkage int system_call(void);
 
 /* Do we ignore FPU interrupts ? */
@@ -288,48 +291,24 @@ EXPORT_SYMBOL(dump_stack);
 void show_registers(struct pt_regs *regs)
 {
        int i;
-       int in_kernel = 1;
-       unsigned long esp;
-       unsigned short ss, gs;
-
-       esp = (unsigned long) (&regs->esp);
-       savesegment(ss, ss);
-       savesegment(gs, gs);
-       if (user_mode_vm(regs)) {
-               in_kernel = 0;
-               esp = regs->esp;
-               ss = regs->xss & 0xffff;
-       }
+
        print_modules();
-       printk(KERN_EMERG "CPU:    %d\n"
-               KERN_EMERG "EIP:    %04x:[<%08lx>]    %s VLI\n"
-               KERN_EMERG "EFLAGS: %08lx   (%s %.*s)\n",
-               smp_processor_id(), 0xffff & regs->xcs, regs->eip,
-               print_tainted(), regs->eflags, init_utsname()->release,
-               (int)strcspn(init_utsname()->version, " "),
-               init_utsname()->version);
-       print_symbol(KERN_EMERG "EIP is at %s\n", regs->eip);
-       printk(KERN_EMERG "eax: %08lx   ebx: %08lx   ecx: %08lx   edx: %08lx\n",
-               regs->eax, regs->ebx, regs->ecx, regs->edx);
-       printk(KERN_EMERG "esi: %08lx   edi: %08lx   ebp: %08lx   esp: %08lx\n",
-               regs->esi, regs->edi, regs->ebp, esp);
-       printk(KERN_EMERG "ds: %04x   es: %04x   fs: %04x  gs: %04x  ss: %04x\n",
-              regs->xds & 0xffff, regs->xes & 0xffff, regs->xfs & 0xffff, gs, ss);
+       __show_registers(regs, 0);
        printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)",
-               TASK_COMM_LEN, current->comm, current->pid,
+               TASK_COMM_LEN, current->comm, task_pid_nr(current),
                current_thread_info(), current, task_thread_info(current));
        /*
         * When in-kernel, we also print out the stack and code at the
         * time of the fault..
         */
-       if (in_kernel) {
+       if (!user_mode_vm(regs)) {
                u8 *eip;
                unsigned int code_prologue = code_bytes * 43 / 64;
                unsigned int code_len = code_bytes;
                unsigned char c;
 
                printk("\n" KERN_EMERG "Stack: ");
-               show_stack_log_lvl(NULL, regs, (unsigned long *)esp, KERN_EMERG);
+               show_stack_log_lvl(NULL, regs, &regs->esp, KERN_EMERG);
 
                printk(KERN_EMERG "Code: ");
 
@@ -374,11 +353,11 @@ int is_valid_bugaddr(unsigned long eip)
 void die(const char * str, struct pt_regs * regs, long err)
 {
        static struct {
-               spinlock_t lock;
+               raw_spinlock_t lock;
                u32 lock_owner;
                int lock_owner_depth;
        } die = {
-               .lock =                 __SPIN_LOCK_UNLOCKED(die.lock),
+               .lock =                 __RAW_SPIN_LOCK_UNLOCKED,
                .lock_owner =           -1,
                .lock_owner_depth =     0
        };
@@ -389,13 +368,14 @@ void die(const char * str, struct pt_regs * regs, long err)
 
        if (die.lock_owner != raw_smp_processor_id()) {
                console_verbose();
-               spin_lock_irqsave(&die.lock, flags);
+               __raw_spin_lock(&die.lock);
+               raw_local_save_flags(flags);
                die.lock_owner = smp_processor_id();
                die.lock_owner_depth = 0;
                bust_spinlocks(1);
        }
        else
-               local_save_flags(flags);
+               raw_local_save_flags(flags);
 
        if (++die.lock_owner_depth < 3) {
                unsigned long esp;
@@ -439,7 +419,8 @@ void die(const char * str, struct pt_regs * regs, long err)
        bust_spinlocks(0);
        die.lock_owner = -1;
        add_taint(TAINT_DIE);
-       spin_unlock_irqrestore(&die.lock, flags);
+       __raw_spin_unlock(&die.lock);
+       raw_local_irq_restore(flags);
 
        if (!regs)
                return;
@@ -622,7 +603,7 @@ fastcall void __kprobes do_general_protection(struct pt_regs * regs,
            printk_ratelimit())
                printk(KERN_INFO
                    "%s[%d] general protection eip:%lx esp:%lx error:%lx\n",
-                   current->comm, current->pid,
+                   current->comm, task_pid_nr(current),
                    regs->eip, regs->esp, error_code);
 
        force_sig(SIGSEGV, current);
@@ -1142,6 +1123,8 @@ static void __init set_task_gate(unsigned int n, unsigned int gdt_entry)
 
 void __init trap_init(void)
 {
+       int i;
+
 #ifdef CONFIG_EISA
        void __iomem *p = ioremap(0x0FFFD9, 4);
        if (readl(p) == 'E'+('I'<<8)+('S'<<16)+('A'<<24)) {
@@ -1201,6 +1184,11 @@ void __init trap_init(void)
 
        set_system_gate(SYSCALL_VECTOR,&system_call);
 
+       /* Reserve all the builtin and the syscall vector. */
+       for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++)
+               set_bit(i, used_vectors);
+       set_bit(SYSCALL_VECTOR, used_vectors);
+
        /*
         * Should be a barrier for any external CPU state.
         */
index b4a9b3db19941ee62359798d05e5964bd954de91..d0c2bc7ab2ec561dc91e12dee87fde8b563f8770 100644 (file)
@@ -201,7 +201,7 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
 #define MSG(txt) ops->warning(data, txt)
 
 /*
- * x86-64 can have upto three kernel stacks: 
+ * x86-64 can have up to three kernel stacks: 
  * process stack
  * interrupt stack
  * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack
@@ -462,7 +462,7 @@ void out_of_line_bug(void)
 EXPORT_SYMBOL(out_of_line_bug);
 #endif
 
-static DEFINE_SPINLOCK(die_lock);
+static raw_spinlock_t die_lock = __RAW_SPIN_LOCK_UNLOCKED;
 static int die_owner = -1;
 static unsigned int die_nest_count;
 
@@ -474,13 +474,13 @@ unsigned __kprobes long oops_begin(void)
        oops_enter();
 
        /* racy, but better than risking deadlock. */
-       local_irq_save(flags);
+       raw_local_irq_save(flags);
        cpu = smp_processor_id();
-       if (!spin_trylock(&die_lock)) { 
+       if (!__raw_spin_trylock(&die_lock)) {
                if (cpu == die_owner) 
                        /* nested oops. should stop eventually */;
                else
-                       spin_lock(&die_lock);
+                       __raw_spin_lock(&die_lock);
        }
        die_nest_count++;
        die_owner = cpu;
@@ -494,12 +494,10 @@ void __kprobes oops_end(unsigned long flags)
        die_owner = -1;
        bust_spinlocks(0);
        die_nest_count--;
-       if (die_nest_count)
-               /* We still own the lock */
-               local_irq_restore(flags);
-       else
+       if (!die_nest_count)
                /* Nest count reaches zero, release the lock. */
-               spin_unlock_irqrestore(&die_lock, flags);
+               __raw_spin_unlock(&die_lock);
+       raw_local_irq_restore(flags);
        if (panic_on_oops)
                panic("Fatal exception");
        oops_exit();
index e87a3939ed406d37fa8dfac066fc803a4a9ece58..d78444c788a3b8f8c4fa6824a6afcf3860d2f4fe 100644 (file)
@@ -59,7 +59,7 @@ int check_tsc_unstable(void)
 }
 EXPORT_SYMBOL_GPL(check_tsc_unstable);
 
-/* Accellerators for sched_clock()
+/* Accelerators for sched_clock()
  * convert from cycles(64bits) => nanoseconds (64bits)
  *  basic equation:
  *             ns = cycles / (freq / ns_per_sec)
@@ -74,7 +74,7 @@ EXPORT_SYMBOL_GPL(check_tsc_unstable);
  *     And since SC is a constant power of two, we can convert the div
  *  into a shift.
  *
- *  We can use khz divisor instead of mhz to keep a better percision, since
+ *  We can use khz divisor instead of mhz to keep a better precision, since
  *  cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits.
  *  (mathieu.desnoyers@polymtl.ca)
  *
@@ -181,8 +181,8 @@ int recalibrate_cpu_khz(void)
        if (cpu_has_tsc) {
                cpu_khz = calculate_cpu_khz();
                tsc_khz = cpu_khz;
-               cpu_data[0].loops_per_jiffy =
-                       cpufreq_scale(cpu_data[0].loops_per_jiffy,
+               cpu_data(0).loops_per_jiffy =
+                       cpufreq_scale(cpu_data(0).loops_per_jiffy,
                                        cpu_khz_old, cpu_khz);
                return 0;
        } else
@@ -215,7 +215,7 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data)
                        return 0;
                }
                ref_freq = freq->old;
-               loops_per_jiffy_ref = cpu_data[freq->cpu].loops_per_jiffy;
+               loops_per_jiffy_ref = cpu_data(freq->cpu).loops_per_jiffy;
                cpu_khz_ref = cpu_khz;
        }
 
@@ -223,7 +223,7 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data)
            (val == CPUFREQ_POSTCHANGE && freq->old > freq->new) ||
            (val == CPUFREQ_RESUMECHANGE)) {
                if (!(freq->flags & CPUFREQ_CONST_LOOPS))
-                       cpu_data[freq->cpu].loops_per_jiffy =
+                       cpu_data(freq->cpu).loops_per_jiffy =
                                cpufreq_scale(loops_per_jiffy_ref,
                                                ref_freq, freq->new);
 
index 9f22e542c37409e84967b4903f4a24bb7db56dfd..9c70af45b42bcbe7683cf2c37b593f4da7b793ee 100644 (file)
@@ -73,13 +73,13 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
        struct cpufreq_freqs *freq = data;
        unsigned long *lpj, dummy;
 
-       if (cpu_has(&cpu_data[freq->cpu], X86_FEATURE_CONSTANT_TSC))
+       if (cpu_has(&cpu_data(freq->cpu), X86_FEATURE_CONSTANT_TSC))
                return 0;
 
        lpj = &dummy;
        if (!(freq->flags & CPUFREQ_CONST_LOOPS))
 #ifdef CONFIG_SMP
-               lpj = &cpu_data[freq->cpu].loops_per_jiffy;
+               lpj = &cpu_data(freq->cpu).loops_per_jiffy;
 #else
                lpj = &boot_cpu_data.loops_per_jiffy;
 #endif
index 8a67e282cb5e69837a9fbba529428de8f78201e0..ad4005c6d4a1113d47c289a06d46328743fd2b2b 100644 (file)
        ({unsigned long v;              \
        extern char __vsyscall_0;       \
          asm("" : "=r" (v) : "0" (x)); \
-         ((v - VSYSCALL_FIRST_PAGE) + __pa_symbol(&__vsyscall_0)); })
+         ((v - VSYSCALL_START) + __pa_symbol(&__vsyscall_0)); })
 
 /*
  * vsyscall_gtod_data contains data that is :
  * - readonly from vsyscalls
- * - writen by timer interrupt or systcl (/proc/sys/kernel/vsyscall64)
+ * - written by timer interrupt or systcl (/proc/sys/kernel/vsyscall64)
  * Try to keep this structure as small as possible to avoid cache line ping pongs
  */
 int __vgetcpu_mode __section_vgetcpu_mode;
@@ -64,6 +64,16 @@ struct vsyscall_gtod_data __vsyscall_gtod_data __section_vsyscall_gtod_data =
        .sysctl_enabled = 1,
 };
 
+void update_vsyscall_tz(void)
+{
+       unsigned long flags;
+
+       write_seqlock_irqsave(&vsyscall_gtod_data.lock, flags);
+       /* sys_tz has changed */
+       vsyscall_gtod_data.sys_tz = sys_tz;
+       write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags);
+}
+
 void update_vsyscall(struct timespec *wall_time, struct clocksource *clock)
 {
        unsigned long flags;
@@ -77,7 +87,6 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock)
        vsyscall_gtod_data.clock.shift = clock->shift;
        vsyscall_gtod_data.wall_time_sec = wall_time->tv_sec;
        vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec;
-       vsyscall_gtod_data.sys_tz = sys_tz;
        vsyscall_gtod_data.wall_to_monotonic = wall_to_monotonic;
        write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags);
 }
@@ -163,7 +172,7 @@ time_t __vsyscall(1) vtime(time_t *t)
        if (unlikely(!__vsyscall_gtod_data.sysctl_enabled))
                return time_syscall(t);
 
-       vgettimeofday(&tv, 0);
+       vgettimeofday(&tv, NULL);
        result = tv.tv_sec;
        if (t)
                *t = result;
@@ -257,18 +266,10 @@ out:
        return ret;
 }
 
-static int vsyscall_sysctl_nostrat(ctl_table *t, int __user *name, int nlen,
-                               void __user *oldval, size_t __user *oldlenp,
-                               void __user *newval, size_t newlen)
-{
-       return -ENOSYS;
-}
-
 static ctl_table kernel_table2[] = {
-       { .ctl_name = 99, .procname = "vsyscall64",
+       { .procname = "vsyscall64",
          .data = &vsyscall_gtod_data.sysctl_enabled, .maxlen = sizeof(int),
          .mode = 0644,
-         .strategy = vsyscall_sysctl_nostrat,
          .proc_handler = vsyscall_sysctl_change },
        {}
 };
@@ -290,7 +291,7 @@ static void __cpuinit vsyscall_set_cpu(int cpu)
 #ifdef CONFIG_NUMA
        node = cpu_to_node(cpu);
 #endif
-       if (cpu_has(&cpu_data[cpu], X86_FEATURE_RDTSCP))
+       if (cpu_has(&cpu_data(cpu), X86_FEATURE_RDTSCP))
                write_rdtscp_aux((node << 12) | cpu);
 
        /* Store cpu number in limit so that it can be loaded quickly
diff --git a/arch/x86/lguest/Kconfig b/arch/x86/lguest/Kconfig
new file mode 100644 (file)
index 0000000..c4dffbe
--- /dev/null
@@ -0,0 +1,14 @@
+config LGUEST_GUEST
+       bool "Lguest guest support"
+       select PARAVIRT
+       depends on !X86_PAE
+       select VIRTIO
+       select VIRTIO_RING
+       select VIRTIO_CONSOLE
+       help
+         Lguest is a tiny in-kernel hypervisor.  Selecting this will
+         allow your kernel to boot under lguest.  This option will increase
+         your kernel size by about 6k.  If in doubt, say N.
+
+         If you say Y here, make sure you say Y (or M) to the virtio block
+         and net drivers which lguest needs.
diff --git a/arch/x86/lguest/Makefile b/arch/x86/lguest/Makefile
new file mode 100644 (file)
index 0000000..27f0c9e
--- /dev/null
@@ -0,0 +1 @@
+obj-y          := i386_head.o boot.o
similarity index 93%
rename from drivers/lguest/lguest.c
rename to arch/x86/lguest/boot.c
index 3ba337dde8575e1570ed9f0ee77d0c9170247efc..d2235db4085f4b4c58ada4bc984933ce415121a2 100644 (file)
@@ -55,7 +55,7 @@
 #include <linux/clockchips.h>
 #include <linux/lguest.h>
 #include <linux/lguest_launcher.h>
-#include <linux/lguest_bus.h>
+#include <linux/virtio_console.h>
 #include <asm/paravirt.h>
 #include <asm/param.h>
 #include <asm/page.h>
@@ -65,6 +65,7 @@
 #include <asm/e820.h>
 #include <asm/mce.h>
 #include <asm/io.h>
+#include <asm/i387.h>
 
 /*G:010 Welcome to the Guest!
  *
@@ -85,9 +86,10 @@ struct lguest_data lguest_data = {
        .hcall_status = { [0 ... LHCALL_RING_SIZE-1] = 0xFF },
        .noirq_start = (u32)lguest_noirq_start,
        .noirq_end = (u32)lguest_noirq_end,
+       .kernel_address = PAGE_OFFSET,
        .blocked_interrupts = { 1 }, /* Block timer interrupts */
+       .syscall_vec = SYSCALL_VECTOR,
 };
-struct lguest_device_desc *lguest_devices;
 static cycle_t clock_base;
 
 /*G:035 Notice the lazy_hcall() above, rather than hcall().  This is our first
@@ -146,10 +148,10 @@ void async_hcall(unsigned long call,
                /* Table full, so do normal hcall which will flush table. */
                hcall(call, arg1, arg2, arg3);
        } else {
-               lguest_data.hcalls[next_call].eax = call;
-               lguest_data.hcalls[next_call].edx = arg1;
-               lguest_data.hcalls[next_call].ebx = arg2;
-               lguest_data.hcalls[next_call].ecx = arg3;
+               lguest_data.hcalls[next_call].arg0 = call;
+               lguest_data.hcalls[next_call].arg1 = arg1;
+               lguest_data.hcalls[next_call].arg2 = arg2;
+               lguest_data.hcalls[next_call].arg3 = arg3;
                /* Arguments must all be written before we mark it to go */
                wmb();
                lguest_data.hcall_status[next_call] = 0;
@@ -160,46 +162,6 @@ void async_hcall(unsigned long call,
 }
 /*:*/
 
-/* Wrappers for the SEND_DMA and BIND_DMA hypercalls.  This is mainly because
- * Jeff Garzik complained that __pa() should never appear in drivers, and this
- * helps remove most of them.   But also, it wraps some ugliness. */
-void lguest_send_dma(unsigned long key, struct lguest_dma *dma)
-{
-       /* The hcall might not write this if something goes wrong */
-       dma->used_len = 0;
-       hcall(LHCALL_SEND_DMA, key, __pa(dma), 0);
-}
-
-int lguest_bind_dma(unsigned long key, struct lguest_dma *dmas,
-                   unsigned int num, u8 irq)
-{
-       /* This is the only hypercall which actually wants 5 arguments, and we
-        * only support 4.  Fortunately the interrupt number is always less
-        * than 256, so we can pack it with the number of dmas in the final
-        * argument.  */
-       if (!hcall(LHCALL_BIND_DMA, key, __pa(dmas), (num << 8) | irq))
-               return -ENOMEM;
-       return 0;
-}
-
-/* Unbinding is the same hypercall as binding, but with 0 num & irq. */
-void lguest_unbind_dma(unsigned long key, struct lguest_dma *dmas)
-{
-       hcall(LHCALL_BIND_DMA, key, __pa(dmas), 0);
-}
-
-/* For guests, device memory can be used as normal memory, so we cast away the
- * __iomem to quieten sparse. */
-void *lguest_map(unsigned long phys_addr, unsigned long pages)
-{
-       return (__force void *)ioremap(phys_addr, PAGE_SIZE*pages);
-}
-
-void lguest_unmap(void *addr)
-{
-       iounmap((__force void __iomem *)addr);
-}
-
 /*G:033
  * Here are our first native-instruction replacements: four functions for
  * interrupt control.
@@ -680,6 +642,7 @@ static struct clocksource lguest_clock = {
        .mask           = CLOCKSOURCE_MASK(64),
        .mult           = 1 << 22,
        .shift          = 22,
+       .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
 /* The "scheduler clock" is just our real clock, adjusted to start at zero */
@@ -761,11 +724,9 @@ static void lguest_time_init(void)
         * the TSC, otherwise it's a dumb nanosecond-resolution clock.  Either
         * way, the "rating" is initialized so high that it's always chosen
         * over any other clocksource. */
-       if (lguest_data.tsc_khz) {
+       if (lguest_data.tsc_khz)
                lguest_clock.mult = clocksource_khz2mult(lguest_data.tsc_khz,
                                                         lguest_clock.shift);
-               lguest_clock.flags = CLOCK_SOURCE_IS_CONTINUOUS;
-       }
        clock_base = lguest_clock_read();
        clocksource_register(&lguest_clock);
 
@@ -889,6 +850,23 @@ static __init char *lguest_memory_setup(void)
        return "LGUEST";
 }
 
+/* Before virtqueues are set up, we use LHCALL_NOTIFY on normal memory to
+ * produce console output. */
+static __init int early_put_chars(u32 vtermno, const char *buf, int count)
+{
+       char scratch[17];
+       unsigned int len = count;
+
+       if (len > sizeof(scratch) - 1)
+               len = sizeof(scratch) - 1;
+       scratch[len] = '\0';
+       memcpy(scratch, buf, len);
+       hcall(LHCALL_NOTIFY, __pa(scratch), 0, 0);
+
+       /* This routine returns the number of bytes actually written. */
+       return len;
+}
+
 /*G:050
  * Patching (Powerfully Placating Performance Pedants)
  *
@@ -950,18 +928,8 @@ static unsigned lguest_patch(u8 type, u16 clobber, void *ibuf,
 /*G:030 Once we get to lguest_init(), we know we're a Guest.  The pv_ops
  * structures in the kernel provide points for (almost) every routine we have
  * to override to avoid privileged instructions. */
-__init void lguest_init(void *boot)
+__init void lguest_init(void)
 {
-       /* Copy boot parameters first: the Launcher put the physical location
-        * in %esi, and head.S converted that to a virtual address and handed
-        * it to us.  We use "__memcpy" because "memcpy" sometimes tries to do
-        * tricky things to go faster, and we're not ready for that. */
-       __memcpy(&boot_params, boot, PARAM_SIZE);
-       /* The boot parameters also tell us where the command-line is: save
-        * that, too. */
-       __memcpy(boot_command_line, __va(boot_params.hdr.cmd_line_ptr),
-              COMMAND_LINE_SIZE);
-
        /* We're under lguest, paravirt is enabled, and we're running at
         * privilege level 1, not 0 as normal. */
        pv_info.name = "lguest";
@@ -1033,11 +1001,7 @@ __init void lguest_init(void *boot)
 
        /*G:070 Now we've seen all the paravirt_ops, we return to
         * lguest_init() where the rest of the fairly chaotic boot setup
-        * occurs.
-        *
-        * The Host expects our first hypercall to tell it where our "struct
-        * lguest_data" is, so we do that first. */
-       hcall(LHCALL_LGUEST_INIT, __pa(&lguest_data), 0, 0);
+        * occurs. */
 
        /* The native boot code sets up initial page tables immediately after
         * the kernel itself, and sets init_pg_tables_end so they're not
@@ -1050,11 +1014,6 @@ __init void lguest_init(void *boot)
         * the normal data segment to get through booting. */
        asm volatile ("mov %0, %%fs" : : "r" (__KERNEL_DS) : "memory");
 
-       /* Clear the part of the kernel data which is expected to be zero.
-        * Normally it will be anyway, but if we're loading from a bzImage with
-        * CONFIG_RELOCATALE=y, the relocations will be sitting here. */
-       memset(__bss_start, 0, __bss_stop - __bss_start);
-
        /* The Host uses the top of the Guest's virtual address space for the
         * Host<->Guest Switcher, and it tells us how much it needs in
         * lguest_data.reserve_mem, set up on the LGUEST_INIT hypercall. */
@@ -1092,6 +1051,9 @@ __init void lguest_init(void *boot)
         * adapted for lguest's use. */
        add_preferred_console("hvc", 0, NULL);
 
+       /* Register our very early console. */
+       virtio_cons_early_init(early_put_chars);
+
        /* Last of all, we set the power management poweroff hook to point to
         * the Guest routine to power off. */
        pm_power_off = lguest_power_off;
similarity index 73%
rename from drivers/lguest/lguest_asm.S
rename to arch/x86/lguest/i386_head.S
index 1ddcd5cd20f6070b72428622b80f531f3ac9fe08..ebc6ac733899c2566bcd9c5ada700b83aab292cb 100644 (file)
@@ -1,25 +1,47 @@
 #include <linux/linkage.h>
 #include <linux/lguest.h>
+#include <asm/lguest_hcall.h>
 #include <asm/asm-offsets.h>
 #include <asm/thread_info.h>
 #include <asm/processor-flags.h>
 
-/*G:020 This is where we begin: we have a magic signature which the launcher
- * looks for.  The plan is that the Linux boot protocol will be extended with a
- * "platform type" field which will guide us here from the normal entry point,
- * but for the moment this suffices.  The normal boot code uses %esi for the
- * boot header, so we do too.  We convert it to a virtual address by adding
- * PAGE_OFFSET, and hand it to lguest_init() as its argument (ie. %eax).
+/*G:020 This is where we begin: head.S notes that the boot header's platform
+ * type field is "1" (lguest), so calls us here.  The boot header is in %esi.
+ *
+ * WARNING: be very careful here!  We're running at addresses equal to physical
+ * addesses (around 0), not above PAGE_OFFSET as most code expectes
+ * (eg. 0xC0000000).  Jumps are relative, so they're OK, but we can't touch any
+ * data.
  *
  * The .section line puts this code in .init.text so it will be discarded after
  * boot. */
 .section .init.text, "ax", @progbits
-.ascii "GenuineLguest"
-       /* Set up initial stack. */
-       movl $(init_thread_union+THREAD_SIZE),%esp
-       movl %esi, %eax
-       addl $__PAGE_OFFSET, %eax
-       jmp lguest_init
+ENTRY(lguest_entry)
+       /* Make initial hypercall now, so we can set up the pagetables. */
+       movl $LHCALL_LGUEST_INIT, %eax
+       movl $lguest_data - __PAGE_OFFSET, %edx
+       int $LGUEST_TRAP_ENTRY
+
+       /* The Host put the toplevel pagetable in lguest_data.pgdir.  The movsl
+        * instruction uses %esi implicitly. */
+       movl lguest_data - __PAGE_OFFSET + LGUEST_DATA_pgdir, %esi
+
+       /* Copy first 32 entries of page directory to __PAGE_OFFSET entries.
+        * This means the first 128M of kernel memory will be mapped at
+        * PAGE_OFFSET where the kernel expects to run.  This will get it far
+        * enough through boot to switch to its own pagetables. */
+       movl $32, %ecx
+       movl %esi, %edi
+       addl $((__PAGE_OFFSET >> 22) * 4), %edi
+       rep
+       movsl
+
+       /* Set up the initial stack so we can run C code. */
+       movl $(init_thread_union+THREAD_SIZE),%esp
+
+       /* Jumps are relative, and we're running __PAGE_OFFSET too low at the
+        * moment. */
+       jmp lguest_init+__PAGE_OFFSET
 
 /*G:055 We create a macro which puts the assembler code between lgstart_ and
  * lgend_ markers.  These templates are put in the .text section: they can't be
index f6edb11364dfe5edef9ffac33341b24307a85434..952e7a89c2ac4f0cc218b310e6a0f84da3845d99 100644 (file)
@@ -82,7 +82,7 @@ inline void __const_udelay(unsigned long xloops)
        __asm__("mull %0"
                :"=d" (xloops), "=&a" (d0)
                :"1" (xloops), "0"
-               (cpu_data[raw_smp_processor_id()].loops_per_jiffy * (HZ/4)));
+               (cpu_data(raw_smp_processor_id()).loops_per_jiffy * (HZ/4)));
 
        __delay(++xloops);
 }
index 2dbebd308347f21be2ad931ce480a6ade16e72b2..0ebbfb9e7c7f8d2b86abeb23f07b0cfbf0ebe56f 100644 (file)
@@ -40,7 +40,8 @@ EXPORT_SYMBOL(__delay);
 
 inline void __const_udelay(unsigned long xloops)
 {
-       __delay(((xloops * HZ * cpu_data[raw_smp_processor_id()].loops_per_jiffy) >> 32) + 1);
+       __delay(((xloops * HZ *
+               cpu_data(raw_smp_processor_id()).loops_per_jiffy) >> 32) + 1);
 }
 EXPORT_SYMBOL(__const_udelay);
 
index 9f38b12b4af1bf103b1261b1ceee185c541a28cd..8bab2b2efaff86c2707ccc929b996f5a245cecd5 100644 (file)
@@ -748,7 +748,7 @@ survive:
                        retval = get_user_pages(current, current->mm,
                                        (unsigned long )to, 1, 1, 0, &pg, NULL);
 
-                       if (retval == -ENOMEM && is_init(current)) {
+                       if (retval == -ENOMEM && is_global_init(current)) {
                                up_read(&current->mm->mmap_sem);
                                congestion_wait(WRITE, HZ/50);
                                goto survive;
index 3f08010f3517287e595585c2dfed73890e054c25..0c28a071824c2bd0789eb9c7d929615e8ba944d1 100644 (file)
@@ -108,7 +108,7 @@ void __init time_init_hook(void)
  * mca_nmi_hook - hook into MCA specific NMI chain
  *
  * Description:
- *     The MCA (Microchannel Arcitecture) has an NMI chain for NMI sources
+ *     The MCA (Microchannel Architecture) has an NMI chain for NMI sources
  *     along the MCA bus.  Use this to hook into that chain if you will need
  *     it.
  **/
@@ -131,7 +131,7 @@ static __init int no_ipi_broadcast(char *str)
        return 1;
 }
 
-__setup("no_ipi_broadcast", no_ipi_broadcast);
+__setup("no_ipi_broadcast=", no_ipi_broadcast);
 
 static int __init print_ipi_mode(void)
 {
index 8685208d85125fab08ba234a4dcaafdfbf6894dd..1af0cc7648f0487bcef1546510a91c7bc2e237d9 100644 (file)
@@ -1,5 +1,5 @@
 /* 
- * Default generic APIC driver. This handles upto 8 CPUs.
+ * Default generic APIC driver. This handles up to 8 CPUs.
  */
 #define APIC_DEFINITION 1
 #include <linux/threads.h>
index 4121d1551800053a48c160d0a70eea7b635a3029..f410d3cb565945565bf8270dd5aef93e30b24ab8 100644 (file)
@@ -56,7 +56,7 @@ void __init generic_bigsmp_probe(void)
        /*
         * This routine is used to switch to bigsmp mode when
         * - There is no apic= option specified by the user
-        * - generic_apic_probe() has choosen apic_default as the sub_arch
+        * - generic_apic_probe() has chosen apic_default as the sub_arch
         * - we find more than 8 CPUs in acpi LAPIC listing with xAPIC support
         */
 
index e4928aa6bdfb783a57363364c159b5223ad5262a..361ac5107b33efcc2331eabc6342912e071e2090 100644 (file)
@@ -36,8 +36,8 @@ static unsigned long cpu_irq_affinity[NR_CPUS] __cacheline_aligned = { [0 ... NR
 
 /* per CPU data structure (for /proc/cpuinfo et al), visible externally
  * indexed physically */
-struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
-EXPORT_SYMBOL(cpu_data);
+DEFINE_PER_CPU(cpuinfo_x86, cpu_info) __cacheline_aligned;
+EXPORT_PER_CPU_SYMBOL(cpu_info);
 
 /* physical ID of the CPU used to boot the system */
 unsigned char boot_cpu_id;
@@ -389,7 +389,7 @@ find_smp_config(void)
 
        /* The boot CPU must be extended */
        voyager_extended_vic_processors = 1<<boot_cpu_id;
-       /* initially, all of the first 8 cpu's can boot */
+       /* initially, all of the first 8 CPUs can boot */
        voyager_allowed_boot_processors = 0xff;
        /* set up everything for just this CPU, we can alter
         * this as we start the other CPUs later */
@@ -430,7 +430,7 @@ find_smp_config(void)
 void __init
 smp_store_cpu_info(int id)
 {
-       struct cpuinfo_x86 *c=&cpu_data[id];
+       struct cpuinfo_x86 *c = &cpu_data(id);
 
        *c = boot_cpu_data;
 
@@ -634,7 +634,7 @@ do_boot_cpu(__u8 cpu)
                        cpu, smp_processor_id()));
        
                printk("CPU%d: ", cpu);
-               print_cpu_info(&cpu_data[cpu]);
+               print_cpu_info(&cpu_data(cpu));
                wmb();
                cpu_set(cpu, cpu_callout_map);
                cpu_set(cpu, cpu_present_map);
@@ -683,7 +683,7 @@ smp_boot_cpus(void)
         */
        smp_store_cpu_info(boot_cpu_id);
        printk("CPU%d: ", boot_cpu_id);
-       print_cpu_info(&cpu_data[boot_cpu_id]);
+       print_cpu_info(&cpu_data(boot_cpu_id));
 
        if(is_cpu_quad()) {
                /* booting on a Quad CPU */
@@ -714,7 +714,7 @@ smp_boot_cpus(void)
                unsigned long bogosum = 0;
                for (i = 0; i < NR_CPUS; i++)
                        if (cpu_isset(i, cpu_online_map))
-                               bogosum += cpu_data[i].loops_per_jiffy;
+                               bogosum += cpu_data(i).loops_per_jiffy;
                printk(KERN_INFO "Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
                        cpucount+1,
                        bogosum/(500000/HZ),
@@ -1010,7 +1010,7 @@ static struct call_data_struct * call_data;
 
 /* execute a thread on a new CPU.  The function to be called must be
  * previously set up.  This is used to schedule a function for
- * execution on all CPU's - set up the function then broadcast a
+ * execution on all CPUs - set up the function then broadcast a
  * function_interrupt CPI to come here on each CPU */
 static void
 smp_call_function_interrupt(void)
@@ -1095,7 +1095,7 @@ voyager_smp_call_function_mask (cpumask_t cpumask,
  * CPI here.  We don't use this actually for counting so losing
  * ticks doesn't matter 
  *
- * FIXME: For those CPU's which actually have a local APIC, we could
+ * FIXME: For those CPUs which actually have a local APIC, we could
  * try to use it to trigger this interrupt instead of having to
  * broadcast the timer tick.  Unfortunately, all my pentium DYADs have
  * no local APIC, so I can't do this
@@ -1287,7 +1287,7 @@ smp_local_timer_interrupt(void)
 
        /*
         * We take the 'long' return path, and there every subsystem
-        * grabs the apropriate locks (kernel lock/ irq lock).
+        * grabs the appropriate locks (kernel lock/ irq lock).
         *
         * we might want to decouple profiling from the 'long path',
         * and do the profiling totally in assembly.
@@ -1759,7 +1759,7 @@ set_vic_irq_affinity(unsigned int irq, cpumask_t mask)
        real_mask = cpus_addr(mask)[0] & voyager_extended_vic_processors;
        
        if(cpus_addr(mask)[0] == 0)
-               /* can't have no cpu's to accept the interrupt -- extremely
+               /* can't have no CPUs to accept the interrupt -- extremely
                 * bad things will happen */
                return;
 
@@ -1791,7 +1791,7 @@ set_vic_irq_affinity(unsigned int irq, cpumask_t mask)
        }
        /* this is magic, we now have the correct affinity maps, so
         * enable the interrupt.  This will send an enable CPI to
-        * those cpu's who need to enable it in their local masks,
+        * those CPUs who need to enable it in their local masks,
         * causing them to correct for the new affinity . If the
         * interrupt is currently globally disabled, it will simply be
         * disabled again as it comes in (voyager lazy disable).  If
index f9d5953381595bdef0df4671d1e8cd4cbdc05bbe..50f9366c411edb94ce6daa8f6b5546ad9657e650 100644 (file)
@@ -64,7 +64,7 @@ check_from_kernel(void)
 {
        if(voyager_status.switch_off) {
                
-               /* FIXME: This should be configureable via proc */
+               /* FIXME: This should be configurable via proc */
                execute("umask 600; echo 0 > /etc/initrunlvl; kill -HUP 1");
        } else if(voyager_status.power_fail) {
                VDEBUG(("Voyager daemon detected AC power failure\n"));
index 4de95a17a7d4de6e7cefc8604da03f3dda0fa56f..f14da2a53ecea61124959c9db146173a9ad4822c 100644 (file)
@@ -10,7 +10,7 @@
 
 /*
  * We need to use the 2-level pagetable functions, but CONFIG_X86_PAE
- * keeps that from happenning.  If anyone has a better way, I'm listening.
+ * keeps that from happening.  If anyone has a better way, I'm listening.
  *
  * boot_pte_t is defined only if this all works correctly
  */
index 13893772cc48c9da72a8370dbf423898b105c0ce..fe608a45ffb66956e67b31b60d80b1c83bfa408f 100644 (file)
@@ -273,7 +273,7 @@ unsigned long __init setup_memory(void)
         * When mapping a NUMA machine we allocate the node_mem_map arrays
         * from node local memory.  They are then mapped directly into KVA
         * between zone normal and vmalloc space.  Calculate the size of
-        * this space and use it to adjust the boundry between ZONE_NORMAL
+        * this space and use it to adjust the boundary between ZONE_NORMAL
         * and ZONE_HIGHMEM.
         */
        find_max_pfn();
index 6555c3d143716c74dc97d466ffafd1baf1399f35..503dfc05111b051de74265e2d44ae7de86a80145 100644 (file)
@@ -354,7 +354,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs,
 
        /* When running in the kernel we expect faults to occur only to
         * addresses in user space.  All other faults represent errors in the
-        * kernel and should generate an OOPS.  Unfortunatly, in the case of an
+        * kernel and should generate an OOPS.  Unfortunately, in the case of an
         * erroneous fault occurring in a code path which already holds mmap_sem
         * we will deadlock attempting to validate the fault against the
         * address space.  Luckily the kernel only validly references user
@@ -362,7 +362,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs,
         * exceptions table.
         *
         * As the vast majority of faults will be valid we will only perform
-        * the source reference check when there is a possibilty of a deadlock.
+        * the source reference check when there is a possibility of a deadlock.
         * Attempt to lock the address space, if we cannot we then validate the
         * source.  If this is invalid we can skip the address space check,
         * thus avoiding the deadlock.
@@ -471,8 +471,8 @@ bad_area_nosemaphore:
                    printk_ratelimit()) {
                        printk("%s%s[%d]: segfault at %08lx eip %08lx "
                            "esp %08lx error %lx\n",
-                           tsk->pid > 1 ? KERN_INFO : KERN_EMERG,
-                           tsk->comm, tsk->pid, address, regs->eip,
+                           task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
+                           tsk->comm, task_pid_nr(tsk), address, regs->eip,
                            regs->esp, error_code);
                }
                tsk->thread.cr2 = address;
@@ -564,7 +564,8 @@ no_context:
                 * it's allocated already.
                 */
                if ((page >> PAGE_SHIFT) < max_low_pfn
-                   && (page & _PAGE_PRESENT)) {
+                   && (page & _PAGE_PRESENT)
+                   && !(page & _PAGE_PSE)) {
                        page &= PAGE_MASK;
                        page = ((__typeof__(page) *) __va(page))[(address >> PAGE_SHIFT)
                                                                 & (PTRS_PER_PTE - 1)];
@@ -587,7 +588,7 @@ no_context:
  */
 out_of_memory:
        up_read(&mm->mmap_sem);
-       if (is_init(tsk)) {
+       if (is_global_init(tsk)) {
                yield();
                down_read(&mm->mmap_sem);
                goto survive;
index 5e0e54906c488fe5b7266d013c072672a606ba29..644b4f7ece10acc498fd9ac61c0d93637f519a82 100644 (file)
@@ -169,7 +169,7 @@ void dump_pagetable(unsigned long address)
        pmd = pmd_offset(pud, address);
        if (bad_address(pmd)) goto bad;
        printk("PMD %lx ", pmd_val(*pmd));
-       if (!pmd_present(*pmd)) goto ret;        
+       if (!pmd_present(*pmd) || pmd_large(*pmd)) goto ret;
 
        pte = pte_offset_kernel(pmd, address);
        if (bad_address(pte)) goto bad;
@@ -285,7 +285,6 @@ static int vmalloc_fault(unsigned long address)
        return 0;
 }
 
-static int page_fault_trace;
 int show_unhandled_signals = 1;
 
 /*
@@ -354,10 +353,6 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
        if (likely(regs->eflags & X86_EFLAGS_IF))
                local_irq_enable();
 
-       if (unlikely(page_fault_trace))
-               printk("pagefault rip:%lx rsp:%lx cs:%lu ss:%lu address %lx error %lx\n",
-                      regs->rip,regs->rsp,regs->cs,regs->ss,address,error_code); 
-
        if (unlikely(error_code & PF_RSVD))
                pgtable_bad(address, regs, error_code);
 
@@ -378,7 +373,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
  again:
        /* When running in the kernel we expect faults to occur only to
         * addresses in user space.  All other faults represent errors in the
-        * kernel and should generate an OOPS.  Unfortunatly, in the case of an
+        * kernel and should generate an OOPS.  Unfortunately, in the case of an
         * erroneous fault occurring in a code path which already holds mmap_sem
         * we will deadlock attempting to validate the fault against the
         * address space.  Luckily the kernel only validly references user
@@ -386,7 +381,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
         * exceptions table.
         *
         * As the vast majority of faults will be valid we will only perform
-        * the source reference check when there is a possibilty of a deadlock.
+        * the source reference check when there is a possibility of a deadlock.
         * Attempt to lock the address space, if we cannot we then validate the
         * source.  If this is invalid we can skip the address space check,
         * thus avoiding the deadlock.
@@ -488,7 +483,7 @@ bad_area_nosemaphore:
                if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
                    printk_ratelimit()) {
                        printk(
-                      "%s%s[%d]: segfault at %016lx rip %016lx rsp %016lx error %lx\n",
+                      "%s%s[%d]: segfault at %lx rip %lx rsp %lx error %lx\n",
                                        tsk->pid > 1 ? KERN_INFO : KERN_EMERG,
                                        tsk->comm, tsk->pid, address, regs->rip,
                                        regs->rsp, error_code);
@@ -554,7 +549,7 @@ no_context:
  */
 out_of_memory:
        up_read(&mm->mmap_sem);
-       if (is_init(current)) {
+       if (is_global_init(current)) {
                yield();
                goto again;
        }
@@ -621,10 +616,3 @@ void vmalloc_sync_all(void)
        BUILD_BUG_ON(!(((MODULES_END - 1) & PGDIR_MASK) == 
                                (__START_KERNEL & PGDIR_MASK)));
 }
-
-static int __init enable_pagefaulttrace(char *str)
-{
-       page_fault_trace = 1;
-       return 1;
-}
-__setup("pagefaulttrace", enable_pagefaulttrace);
index 5eec5e56d07f3a2b7d5bb6b48b1d4acadf15e689..3d6926ba8995e4d54131c2660ffb1348955d6e32 100644 (file)
@@ -612,7 +612,7 @@ void __init init_cpu_to_node(void)
 {
        int i;
        for (i = 0; i < NR_CPUS; i++) {
-               u8 apicid = x86_cpu_to_apicid[i];
+               u8 apicid = x86_cpu_to_apicid_init[i];
                if (apicid == BAD_APICID)
                        continue;
                if (apicid_to_node[apicid] == NUMA_NO_NODE)
index 8a4f65bf956ea85ef45ecb6157eccceca82f92a5..c40afbaaf93da9f74e36ef6ca2a2a3e29fa46043 100644 (file)
@@ -61,10 +61,10 @@ static struct page *split_large_page(unsigned long address, pgprot_t prot,
        return base;
 } 
 
-static void cache_flush_page(void *adr)
+void clflush_cache_range(void *adr, int size)
 {
        int i;
-       for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size)
+       for (i = 0; i < size; i += boot_cpu_data.x86_clflush_size)
                clflush(adr+i);
 }
 
@@ -80,7 +80,7 @@ static void flush_kernel_map(void *arg)
                asm volatile("wbinvd" ::: "memory");
        else list_for_each_entry(pg, l, lru) {
                void *adr = page_address(pg);
-               cache_flush_page(adr);
+               clflush_cache_range(adr, PAGE_SIZE);
        }
        __flush_tlb_all();
 }
@@ -230,9 +230,14 @@ void global_flush_tlb(void)
        struct page *pg, *next;
        struct list_head l;
 
-       down_read(&init_mm.mmap_sem);
+       /*
+        * Write-protect the semaphore, to exclude two contexts
+        * doing a list_replace_init() call in parallel and to
+        * exclude new additions to the deferred_pages list:
+        */
+       down_write(&init_mm.mmap_sem);
        list_replace_init(&deferred_pages, &l);
-       up_read(&init_mm.mmap_sem);
+       up_write(&init_mm.mmap_sem);
 
        flush_map(&l);
 
index 56089ccc394927d50465476fe65935b7e3c4e023..ea85172fc0cc6c33fd20ec49981411ea9b73d031 100644 (file)
@@ -218,7 +218,7 @@ static inline int save_add_info(void) {return 0;}
 /*
  * Update nodes_add and decide if to include add are in the zone.
  * Both SPARSE and RESERVE need nodes_add infomation.
- * This code supports one contigious hot add area per node.
+ * This code supports one contiguous hot add area per node.
  */
 static int reserve_hotadd(int node, unsigned long start, unsigned long end)
 {
index c049ce414f010359c0c312e08c6bd903b683797d..0ed046a187f77fb1d29228780c395f4e8d4636a1 100644 (file)
 #include <linux/mm.h>
 #include <asm/ptrace.h>
 #include <asm/uaccess.h>
+#include <asm/stacktrace.h>
 
-struct frame_head {
-       struct frame_head * ebp;
-       unsigned long ret;
-} __attribute__((packed));
+static void backtrace_warning_symbol(void *data, char *msg,
+                                    unsigned long symbol)
+{
+       /* Ignore warnings */
+}
 
-static struct frame_head *
-dump_kernel_backtrace(struct frame_head * head)
+static void backtrace_warning(void *data, char *msg)
 {
-       oprofile_add_trace(head->ret);
+       /* Ignore warnings */
+}
 
-       /* frame pointers should strictly progress back up the stack
-        * (towards higher addresses) */
-       if (head >= head->ebp)
-               return NULL;
+static int backtrace_stack(void *data, char *name)
+{
+       /* Yes, we want all stacks */
+       return 0;
+}
+
+static void backtrace_address(void *data, unsigned long addr)
+{
+       unsigned int *depth = data;
 
-       return head->ebp;
+       if ((*depth)--)
+               oprofile_add_trace(addr);
 }
 
+static struct stacktrace_ops backtrace_ops = {
+       .warning = backtrace_warning,
+       .warning_symbol = backtrace_warning_symbol,
+       .stack = backtrace_stack,
+       .address = backtrace_address,
+};
+
+struct frame_head {
+       struct frame_head *ebp;
+       unsigned long ret;
+} __attribute__((packed));
+
 static struct frame_head *
 dump_user_backtrace(struct frame_head * head)
 {
@@ -53,72 +73,16 @@ dump_user_backtrace(struct frame_head * head)
        return bufhead[0].ebp;
 }
 
-/*
- * |             | /\ Higher addresses
- * |             |
- * --------------- stack base (address of current_thread_info)
- * | thread info |
- * .             .
- * |    stack    |
- * --------------- saved regs->ebp value if valid (frame_head address)
- * .             .
- * --------------- saved regs->rsp value if x86_64
- * |             |
- * --------------- struct pt_regs * stored on stack if 32-bit
- * |             |
- * .             .
- * |             |
- * --------------- %esp
- * |             |
- * |             | \/ Lower addresses
- *
- * Thus, regs (or regs->rsp for x86_64) <-> stack base restricts the
- * valid(ish) ebp values. Note: (1) for x86_64, NMI and several other
- * exceptions use special stacks, maintained by the interrupt stack table
- * (IST). These stacks are set up in trap_init() in
- * arch/x86_64/kernel/traps.c. Thus, for x86_64, regs now does not point
- * to the kernel stack; instead, it points to some location on the NMI
- * stack. On the other hand, regs->rsp is the stack pointer saved when the
- * NMI occurred. (2) For 32-bit, regs->esp is not valid because the
- * processor does not save %esp on the kernel stack when interrupts occur
- * in the kernel mode.
- */
-#ifdef CONFIG_FRAME_POINTER
-static int valid_kernel_stack(struct frame_head * head, struct pt_regs * regs)
-{
-       unsigned long headaddr = (unsigned long)head;
-#ifdef CONFIG_X86_64
-       unsigned long stack = (unsigned long)regs->rsp;
-#else
-       unsigned long stack = (unsigned long)regs;
-#endif
-       unsigned long stack_base = (stack & ~(THREAD_SIZE - 1)) + THREAD_SIZE;
-
-       return headaddr > stack && headaddr < stack_base;
-}
-#else
-/* without fp, it's just junk */
-static int valid_kernel_stack(struct frame_head * head, struct pt_regs * regs)
-{
-       return 0;
-}
-#endif
-
-
 void
 x86_backtrace(struct pt_regs * const regs, unsigned int depth)
 {
-       struct frame_head *head;
-
-#ifdef CONFIG_X86_64
-       head = (struct frame_head *)regs->rbp;
-#else
-       head = (struct frame_head *)regs->ebp;
-#endif
+       struct frame_head *head = (struct frame_head *)frame_pointer(regs);
+       unsigned long stack = stack_pointer(regs);
 
        if (!user_mode_vm(regs)) {
-               while (depth-- && valid_kernel_stack(head, regs))
-                       head = dump_kernel_backtrace(head);
+               if (depth)
+                       dump_trace(NULL, regs, (unsigned long *)stack,
+                                  &backtrace_ops, &depth);
                return;
        }
 
index abb1aa95b979f8dbc0fa65a90210d11409715f61..45b605fa71d06f6064b7fb6f3d34a017106b3cb9 100644 (file)
@@ -29,7 +29,7 @@ struct op_msrs {
 struct pt_regs;
 
 /* The model vtable abstracts the differences between
- * various x86 CPU model's perfctr support.
+ * various x86 CPU models' perfctr support.
  */
 struct op_x86_model_spec {
        unsigned int const num_counters;
index c52150fdf82b51015515c1a7bb3716be515a7ef7..88d8f5c0ecb5e2e8bb5bc05f5aff97790ddd667a 100644 (file)
@@ -169,7 +169,7 @@ void eisa_set_level_irq(unsigned int irq)
 }
 
 /*
- * Common IRQ routing practice: nybbles in config space,
+ * Common IRQ routing practice: nibbles in config space,
  * offset by some magic constant.
  */
 static unsigned int read_config_nybble(struct pci_dev *router, unsigned offset, unsigned nr)
@@ -585,7 +585,7 @@ static __init int via_router_probe(struct irq_router *r,
        /* FIXME: We should move some of the quirk fixup stuff here */
 
        /*
-        * work arounds for some buggy BIOSes
+        * workarounds for some buggy BIOSes
         */
        if (device == PCI_DEVICE_ID_VIA_82C586_0) {
                switch(router->device) {
index 9df99e1885a43ccd90eba7834df1dab259046083..fbfa55ce0d5566fbb7634d695fe9709ab63fbe07 100644 (file)
@@ -3,8 +3,9 @@
 #
 
 config XEN
-       bool "Enable support for Xen hypervisor"
-       depends on PARAVIRT && X86_CMPXCHG && X86_TSC && !NEED_MULTIPLE_NODES
+       bool "Xen guest support"
+       select PARAVIRT
+       depends on X86_CMPXCHG && X86_TSC && !NEED_MULTIPLE_NODES && !(X86_VISWS || X86_VOYAGER)
        help
          This is the Linux Xen port.  Enabling this will allow the
          kernel to boot in a paravirtualized environment under the
diff --git a/arch/x86_64/.gitignore b/arch/x86_64/.gitignore
new file mode 100644 (file)
index 0000000..36ef4c3
--- /dev/null
@@ -0,0 +1 @@
+boot
index 43fafe9e9c080db10bc0e5b0e7f52291b35e718a..c2d24991bb2bd708f8d5485638906d95c343de50 100644 (file)
@@ -716,9 +716,16 @@ menu "Power management options"
 
 source kernel/power/Kconfig
 
+config ARCH_HIBERNATION_HEADER
+       bool
+       depends on HIBERNATION
+       default y
+
 source "drivers/acpi/Kconfig"
 
-source "arch/x86/kernel/cpufreq/Kconfig"
+source "arch/x86/kernel/cpu/cpufreq/Kconfig_64"
+
+source "drivers/cpuidle/Kconfig"
 
 endmenu
 
@@ -743,6 +750,38 @@ config PCI_DOMAINS
        depends on PCI
        default y
 
+config DMAR
+       bool "Support for DMA Remapping Devices (EXPERIMENTAL)"
+       depends on PCI_MSI && ACPI && EXPERIMENTAL
+       default y
+       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.
+
+config DMAR_GFX_WA
+       bool "Support for Graphics workaround"
+       depends on DMAR
+       default y
+       help
+        Current Graphics drivers tend to use physical address
+        for DMA and avoid using DMA APIs. Setting this config
+        option permits the IOMMU driver to set a unity map for
+        all the OS-visible memory. Hence the driver can continue
+        to use physical addresses for DMA.
+
+config DMAR_FLOPPY_WA
+       bool
+       depends on DMAR
+       default y
+       help
+        Floppy disk drivers are know to bypass DMA API calls
+        thereby failing to work when IOMMU is enabled. This
+        workaround will setup a 1:1 mapping for the first
+        16M to make floppy (an ISA device) work.
+
 source "drivers/pci/pcie/Kconfig"
 
 source "drivers/pci/Kconfig"
@@ -761,9 +800,9 @@ source "fs/Kconfig.binfmt"
 config IA32_EMULATION
        bool "IA32 Emulation"
        help
-         Include code to run 32-bit programs under a 64-bit kernel. You should likely
-         turn this on, unless you're 100% sure that you don't have any 32-bit programs
-         left.
+         Include code to run 32-bit programs under a 64-bit kernel. You should
+         likely turn this on, unless you're 100% sure that you don't have any
+         32-bit programs left.
 
 config IA32_AOUT
        tristate "IA32 a.out support"
@@ -794,21 +833,6 @@ source "drivers/firmware/Kconfig"
 
 source fs/Kconfig
 
-menu "Instrumentation Support"
-
-source "arch/x86/oprofile/Kconfig"
-
-config KPROBES
-       bool "Kprobes"
-       depends on KALLSYMS && MODULES
-       help
-         Kprobes allows you to trap at almost any kernel address and
-         execute a callback function.  register_kprobe() establishes
-         a probepoint and specifies the callback.  Kprobes is useful
-         for kernel debugging, non-intrusive instrumentation and testing.
-         If in doubt, say "N".
-endmenu
-
 source "arch/x86_64/Kconfig.debug"
 
 source "security/Kconfig"
index 03e1ede27b8541c627f8db895ae5e8534cff3166..6d89ab762ffcf759b2dc6d344babe73ce056a239 100644 (file)
@@ -74,7 +74,7 @@ KBUILD_CFLAGS += $(cflags-y)
 CFLAGS_KERNEL += $(cflags-kernel-y)
 KBUILD_AFLAGS += -m64
 
-head-y := arch/x86/kernel/head_64.o arch/x86/kernel/head64.o arch/x86/kernel/init_task_64.o
+head-y := arch/x86/kernel/head_64.o arch/x86/kernel/head64.o arch/x86/kernel/init_task.o
 
 libs-y                                         += arch/x86/lib/
 core-y                                 += arch/x86/kernel/ \
@@ -97,9 +97,9 @@ BOOTIMAGE                     := arch/x86/boot/bzImage
 KBUILD_IMAGE                  := $(BOOTIMAGE)
 
 bzImage: vmlinux
-       $(Q)mkdir -p $(objtree)/arch/x86_64/boot
-       $(Q)ln -fsn $(objtree)/arch/x86/boot/bzImage $(objtree)/arch/x86_64/boot/bzImage
        $(Q)$(MAKE) $(build)=$(boot) $(BOOTIMAGE)
+       $(Q)mkdir -p $(objtree)/arch/x86_64/boot
+       $(Q)ln -fsn ../../x86/boot/bzImage $(objtree)/arch/x86_64/boot/bzImage
 
 bzlilo: vmlinux
        $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) zlilo
index 7fbb44bea37f85048ebb8c6c55e2a9063477083d..85ffbb491490b47f78b4347c4af35d375ca6c988 100644 (file)
@@ -251,6 +251,8 @@ config EMBEDDED_RAMDISK_IMAGE
          provide one yourself.
 endmenu
 
+source "kernel/Kconfig.instrumentation"
+
 source "arch/xtensa/Kconfig.debug"
 
 source "security/Kconfig"
index 9c5185f605b666f7a9e3a51daf244762a56b9f4c..40aa55b485be91747ebc401f5d5d4047ce71aa11 100644 (file)
@@ -8,7 +8,8 @@
 #
 
 
-EXTRA_CFLAGS   += -fno-builtin -Iarch/$(ARCH)/boot/include
+# KBUILD_CFLAGS used when building rest of boot (takes effect recursively)
+KBUILD_CFLAGS  += -fno-builtin -Iarch/$(ARCH)/boot/include
 HOSTFLAGS      += -Iarch/$(ARCH)/boot/include
 
 BIG_ENDIAN     := $(shell echo -e __XTENSA_EB__ | $(CC) -E - | grep -v "\#")
index 8be99c777d9d2b55c69c39f8252630f82192a1b1..397bcd6ad08d4ca860e8d936862fd22f1f1629ac 100644 (file)
@@ -176,7 +176,7 @@ void do_unhandled(struct pt_regs *regs, unsigned long exccause)
        printk("Caught unhandled exception in '%s' "
               "(pid = %d, pc = %#010lx) - should not happen\n"
               "\tEXCCAUSE is %ld\n",
-              current->comm, current->pid, regs->pc, exccause);
+              current->comm, task_pid_nr(current), regs->pc, exccause);
        force_sig(SIGILL, current);
 }
 
@@ -228,7 +228,7 @@ do_illegal_instruction(struct pt_regs *regs)
        /* If in user mode, send SIGILL signal to current process. */
 
        printk("Illegal Instruction in '%s' (pid = %d, pc = %#010lx)\n",
-           current->comm, current->pid, regs->pc);
+           current->comm, task_pid_nr(current), regs->pc);
        force_sig(SIGILL, current);
 }
 
@@ -254,7 +254,7 @@ do_unaligned_user (struct pt_regs *regs)
        current->thread.error_code = -3;
        printk("Unaligned memory access to %08lx in '%s' "
               "(pid = %d, pc = %#010lx)\n",
-              regs->excvaddr, current->comm, current->pid, regs->pc);
+              regs->excvaddr, current->comm, task_pid_nr(current), regs->pc);
        info.si_signo = SIGBUS;
        info.si_errno = 0;
        info.si_code = BUS_ADRALN;
index 2f842859948f5993780b83fae5d3e66390bf1d6d..33f366be323fc05f075519a0dde7826795f8c568 100644 (file)
@@ -145,7 +145,7 @@ bad_area:
         */
 out_of_memory:
        up_read(&mm->mmap_sem);
-       if (is_init(current)) {
+       if (is_global_init(current)) {
                yield();
                down_read(&mm->mmap_sem);
                goto survive;
index f09962fa98c09a5594358d22c23b0b7d993209f0..b61fb36674e7f7e571aac77bb534165aa750d875 100644 (file)
@@ -798,7 +798,7 @@ static int iss_net_setup(char *str)
 
 #undef ERR
 
-__setup("eth", iss_net_setup);
+__setup("eth=", iss_net_setup);
 
 /*
  * Initialize all ISS Ethernet devices previously registered in iss_net_setup.
index 952aee04a68ad7cc240b8ecb7a8a0e1590b9a33f..446aea2a3cfbd17e6ff8d15fc0b069785d196e7f 100644 (file)
@@ -390,7 +390,7 @@ EXPORT_SYMBOL(elv_rb_find);
 
 /*
  * Insert rq into dispatch queue of q.  Queue lock must be held on
- * entry.  rq is sort insted into the dispatch queue. To be used by
+ * entry.  rq is sort instead into the dispatch queue. To be used by
  * specific elevators.
  */
 void elv_dispatch_sort(struct request_queue *q, struct request *rq)
index 3935469e366222c793a429f65461bf4a0becf62e..de5ba479c2245b9e747558757fb6444eebc6745e 100644 (file)
@@ -1351,11 +1351,22 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
 new_segment:
                        if (!sg)
                                sg = sglist;
-                       else
+                       else {
+                               /*
+                                * If the driver previously mapped a shorter
+                                * list, we could see a termination bit
+                                * prematurely unless it fully inits the sg
+                                * table on each mapping. We KNOW that there
+                                * must be more entries here or the driver
+                                * would be buggy, so force clear the
+                                * termination bit to avoid doing a full
+                                * sg_init_table() in drivers for each command.
+                                */
+                               sg->page_link &= ~0x02;
                                sg = sg_next(sg);
+                       }
 
-                       memset(sg, 0, sizeof(*sg));
-                       sg->page = bvec->bv_page;
+                       sg_set_page(sg, bvec->bv_page);
                        sg->length = nbytes;
                        sg->offset = bvec->bv_offset;
                        nsegs++;
@@ -1363,6 +1374,9 @@ new_segment:
                bvprv = bvec;
        } /* segments in rq */
 
+       if (sg)
+               __sg_mark_end(sg);
+
        return nsegs;
 }
 
@@ -3367,7 +3381,7 @@ void submit_bio(int rw, struct bio *bio)
                if (unlikely(block_dump)) {
                        char b[BDEVNAME_SIZE];
                        printk(KERN_DEBUG "%s(%d): %s block %Lu on %s\n",
-                               current->comm, current->pid,
+                       current->comm, task_pid_nr(current),
                                (rw & WRITE) ? "WRITE" : "READ",
                                (unsigned long long)bio->bi_sector,
                                bdevname(bio->bi_bdev,b));
@@ -3739,7 +3753,7 @@ EXPORT_SYMBOL(end_dequeued_request);
 
 /**
  * end_request - end I/O on the current segment of the request
- * @rq:                the request being processed
+ * @req:       the request being processed
  * @uptodate:  error value or 0/1 uptodate flag
  *
  * Description:
index 4ccc5af6c26530c81d0da2a6fed9b7bf609c2b8c..1f5c724773568acf31f7dde568972f4925f39407 100644 (file)
@@ -6,7 +6,7 @@
  * Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au>
  *
  * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
- * and Nettle, by Niels Möller.
+ * and Nettle, by Niels Möller.
  *
  * 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
index e56de6748b155eadf0f749c801e911a9a2d23577..8871dec8cae7484a1fe34e68966563ad1d6032b9 100644 (file)
@@ -41,7 +41,7 @@ static int update2(struct hash_desc *desc,
                return 0;
 
        for (;;) {
-               struct page *pg = sg->page;
+               struct page *pg = sg_page(sg);
                unsigned int offset = sg->offset;
                unsigned int l = sg->length;
 
index 9c2bb535b09ab7fa78872ff72756931292b0743e..d161949fdb94d28eb318a70cfae495ac2a742434 100644 (file)
@@ -10,7 +10,7 @@
  *
  * Based on code:
  *
- * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+ * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
index 8802fb6dd5a6c857e4d78880944d5f9c3cc6c9d4..e4eb6ac53b5c0b68e01643ce0ec2be97bca35939 100644 (file)
@@ -159,7 +159,8 @@ static int hmac_digest(struct hash_desc *pdesc, struct scatterlist *sg,
        desc.flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP;
 
        sg_set_buf(sg1, ipad, bs);
-       sg1[1].page = (void *)sg;
+
+       sg_set_page(&sg[1], (void *) sg);
        sg1[1].length = 0;
        sg_set_buf(sg2, opad, bs + ds);
 
index d6852c33cfb78f2ac2300280f90dadc6acb3b5a7..b9bbda0bb9f968efc4a728dd316952b7516f617b 100644 (file)
@@ -54,7 +54,7 @@ static void scatterwalk_pagedone(struct scatter_walk *walk, int out,
        if (out) {
                struct page *page;
 
-               page = walk->sg->page + ((walk->offset - 1) >> PAGE_SHIFT);
+               page = sg_page(walk->sg) + ((walk->offset - 1) >> PAGE_SHIFT);
                flush_dcache_page(page);
        }
 
index 9c73e37a42cef9ad9eb63133cf78a35ac78ae9fd..87ed681cceba4fa42d9d46399560d6972aadbce2 100644 (file)
 
 static inline struct scatterlist *scatterwalk_sg_next(struct scatterlist *sg)
 {
-       return (++sg)->length ? sg : (void *)sg->page;
+       return (++sg)->length ? sg : (void *) sg_page(sg);
 }
 
 static inline unsigned long scatterwalk_samebuf(struct scatter_walk *walk_in,
                                                struct scatter_walk *walk_out)
 {
-       return !(((walk_in->sg->page - walk_out->sg->page) << PAGE_SHIFT) +
+       return !(((sg_page(walk_in->sg) - sg_page(walk_out->sg)) << PAGE_SHIFT) +
                 (int)(walk_in->offset - walk_out->offset));
 }
 
@@ -60,7 +60,7 @@ static inline unsigned int scatterwalk_aligned(struct scatter_walk *walk,
 
 static inline struct page *scatterwalk_page(struct scatter_walk *walk)
 {
-       return walk->sg->page + (walk->offset >> PAGE_SHIFT);
+       return sg_page(walk->sg) + (walk->offset >> PAGE_SHIFT);
 }
 
 static inline void scatterwalk_unmap(void *vaddr, int out)
index 18d489c8b935f3834fdf72743d1e1ef0e2acd457..d741c63af42c501f357eb9d666de461265d9c6e8 100644 (file)
@@ -317,7 +317,7 @@ static void test_cipher(char *algo, int enc,
                                goto out;
                        }
 
-                       q = kmap(sg[0].page) + sg[0].offset;
+                       q = kmap(sg_page(&sg[0])) + sg[0].offset;
                        hexdump(q, cipher_tv[i].rlen);
 
                        printk("%s\n",
@@ -390,7 +390,7 @@ static void test_cipher(char *algo, int enc,
                        temp = 0;
                        for (k = 0; k < cipher_tv[i].np; k++) {
                                printk("page %u\n", k);
-                               q = kmap(sg[k].page) + sg[k].offset;
+                               q = kmap(sg_page(&sg[k])) + sg[k].offset;
                                hexdump(q, cipher_tv[i].tap[k]);
                                printk("%s\n",
                                        memcmp(q, cipher_tv[i].result + temp,
index 9f502b86e0ea563ac04b31fbf96dcd534367e05a..ac68f3b62fde7c533cd1d1faf8c169c313864773 100644 (file)
@@ -120,7 +120,7 @@ static int crypto_xcbc_digest_update2(struct hash_desc *pdesc,
 
        do {
 
-               struct page *pg = sg[i].page;
+               struct page *pg = sg_page(&sg[i]);
                unsigned int offset = sg[i].offset;
                unsigned int slen = sg[i].length;
 
index 4fb134d50da731e96ce25aef47c3f3b8c21f45f1..f4076d9e9902b88981c840097a9f283526c1e522 100644 (file)
@@ -58,6 +58,8 @@ source "drivers/power/Kconfig"
 
 source "drivers/hwmon/Kconfig"
 
+source "drivers/watchdog/Kconfig"
+
 source "drivers/ssb/Kconfig"
 
 source "drivers/mfd/Kconfig"
@@ -92,5 +94,5 @@ source "drivers/kvm/Kconfig"
 
 source "drivers/uio/Kconfig"
 
-source "drivers/lguest/Kconfig"
+source "drivers/virtio/Kconfig"
 endmenu
index 174c27eb443032f06ad3b8a61c7410bd6f0d4566..560496b43306234ebf5f6fc2274206248bad9628 100644 (file)
@@ -66,7 +66,7 @@ obj-y                         += i2c/
 obj-$(CONFIG_W1)               += w1/
 obj-$(CONFIG_POWER_SUPPLY)     += power/
 obj-$(CONFIG_HWMON)            += hwmon/
-obj-$(CONFIG_WATCHDOG)         += char/watchdog/
+obj-$(CONFIG_WATCHDOG)         += watchdog/
 obj-$(CONFIG_PHONE)            += telephony/
 obj-$(CONFIG_MD)               += md/
 obj-$(CONFIG_BT)               += bluetooth/
@@ -76,6 +76,7 @@ obj-$(CONFIG_MCA)             += mca/
 obj-$(CONFIG_EISA)             += eisa/
 obj-$(CONFIG_LGUEST_GUEST)     += lguest/
 obj-$(CONFIG_CPU_FREQ)         += cpufreq/
+obj-$(CONFIG_CPU_IDLE)         += cpuidle/
 obj-$(CONFIG_MMC)              += mmc/
 obj-$(CONFIG_NEW_LEDS)         += leds/
 obj-$(CONFIG_INFINIBAND)       += infiniband/
@@ -90,3 +91,4 @@ obj-$(CONFIG_HID)             += hid/
 obj-$(CONFIG_PPC_PS3)          += ps3/
 obj-$(CONFIG_OF)               += of/
 obj-$(CONFIG_SSB)              += ssb/
+obj-$(CONFIG_VIRTIO)           += virtio/
index 4875f0149eb48c499461bf4fce570f7580ec1034..5d0e26a5c34cd55455ee776891acac0e861b93f6 100644 (file)
@@ -52,7 +52,7 @@ config ACPI_PROCFS
        depends on PROC_FS
        ---help---
          For backwards compatibility, this option allows
-         depricated /proc/acpi/ files to exist, even when
+         deprecated /proc/acpi/ files to exist, even when
          they have been replaced by functions in /sys.
          The deprecated files (and their replacements) include:
 
@@ -88,7 +88,7 @@ config ACPI_PROC_EVENT
 
 config ACPI_AC
        tristate "AC Adapter"
-       depends on X86
+       depends on X86 && POWER_SUPPLY
        default y
        help
          This driver adds support for the AC Adapter object, which indicates
@@ -97,7 +97,7 @@ config ACPI_AC
 
 config ACPI_BATTERY
        tristate "Battery"
-       depends on X86
+       depends on X86 && POWER_SUPPLY
        default y
        help
          This driver adds support for battery information through
@@ -117,6 +117,7 @@ config ACPI_BUTTON
 config ACPI_VIDEO
        tristate "Video"
        depends on X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL
+       depends on INPUT
        help
          This driver implement the ACPI Extensions For Display Adapters
          for integrated graphics devices on motherboard, as specified in
@@ -349,12 +350,11 @@ config ACPI_HOTPLUG_MEMORY
                $>modprobe acpi_memhotplug 
 
 config ACPI_SBS
-       tristate "Smart Battery System (EXPERIMENTAL)"
+       tristate "Smart Battery System"
        depends on X86
-       depends on EXPERIMENTAL
+       depends on POWER_SUPPLY
        help
-         This driver adds support for the Smart Battery System.
-         A "Smart Battery" is quite old and quite rare compared
-         to today's ACPI "Control Method" battery.
+         This driver adds support for the Smart Battery System, another
+         type of access to battery information, found on some laptops.
 
 endif  # ACPI
index d4336f1730e9a0324ff61cfed04bd7215e03a816..54e3ab0e5fc011e3a807eec08304a2603251fbbb 100644 (file)
@@ -60,3 +60,4 @@ obj-$(CONFIG_ACPI_TOSHIBA)    += toshiba_acpi.o
 obj-$(CONFIG_ACPI_HOTPLUG_MEMORY)      += acpi_memhotplug.o
 obj-y                          += cm_sbs.o
 obj-$(CONFIG_ACPI_SBS)         += sbs.o
+obj-$(CONFIG_ACPI_SBS)         += sbshc.o
index 26d70702b3134124fc4e10111499c7fc990436c6..e03de37a750d547d7e69d91264b224500dc063b8 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/types.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/power_supply.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
@@ -72,16 +73,37 @@ static struct acpi_driver acpi_ac_driver = {
 };
 
 struct acpi_ac {
+       struct power_supply charger;
        struct acpi_device * device;
        unsigned long state;
 };
 
+#define to_acpi_ac(x) container_of(x, struct acpi_ac, charger);
+
 static const struct file_operations acpi_ac_fops = {
        .open = acpi_ac_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
        .release = single_release,
 };
+static int get_ac_property(struct power_supply *psy,
+                          enum power_supply_property psp,
+                          union power_supply_propval *val)
+{
+       struct acpi_ac *ac = to_acpi_ac(psy);
+       switch (psp) {
+       case POWER_SUPPLY_PROP_ONLINE:
+               val->intval = ac->state;
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static enum power_supply_property ac_props[] = {
+       POWER_SUPPLY_PROP_ONLINE,
+};
 
 /* --------------------------------------------------------------------------
                                AC Adapter Management
@@ -208,6 +230,7 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
                acpi_bus_generate_netlink_event(device->pnp.device_class,
                                                  device->dev.bus_id, event,
                                                  (u32) ac->state);
+               kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE);
                break;
        default:
                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -244,7 +267,12 @@ static int acpi_ac_add(struct acpi_device *device)
        result = acpi_ac_add_fs(device);
        if (result)
                goto end;
-
+       ac->charger.name = acpi_device_bid(device);
+       ac->charger.type = POWER_SUPPLY_TYPE_MAINS;
+       ac->charger.properties = ac_props;
+       ac->charger.num_properties = ARRAY_SIZE(ac_props);
+       ac->charger.get_property = get_ac_property;
+       power_supply_register(&ac->device->dev, &ac->charger);
        status = acpi_install_notify_handler(device->handle,
                                             ACPI_ALL_NOTIFY, acpi_ac_notify,
                                             ac);
@@ -279,7 +307,8 @@ static int acpi_ac_remove(struct acpi_device *device, int type)
 
        status = acpi_remove_notify_handler(device->handle,
                                            ACPI_ALL_NOTIFY, acpi_ac_notify);
-
+       if (ac->charger.dev)
+               power_supply_unregister(&ac->charger);
        acpi_ac_remove_fs(device);
 
        kfree(ac);
index 9b2c0f74f869a6c4ce74e64462432c24ebf770b0..681e26b56b11c2b37a3e242db63ee9ef1dc6444a 100644 (file)
@@ -1,6 +1,8 @@
 /*
- *  acpi_battery.c - ACPI Battery Driver ($Revision: 37 $)
+ *  battery.c - ACPI Battery Driver (Revision: 2.0)
  *
+ *  Copyright (C) 2007 Alexey Starikovskiy <astarikovskiy@suse.de>
+ *  Copyright (C) 2004-2007 Vladimir Lebedev <vladimir.p.lebedev@intel.com>
  *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
  *
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
+#include <linux/jiffies.h>
+
+#ifdef CONFIG_ACPI_PROCFS
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <asm/uaccess.h>
+#endif
 
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
-#define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF
+#include <linux/power_supply.h>
 
-#define ACPI_BATTERY_FORMAT_BIF        "NNNNNNNNNSSSS"
-#define ACPI_BATTERY_FORMAT_BST        "NNNN"
+#define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF
 
 #define ACPI_BATTERY_COMPONENT         0x00040000
 #define ACPI_BATTERY_CLASS             "battery"
 #define ACPI_BATTERY_DEVICE_NAME       "Battery"
 #define ACPI_BATTERY_NOTIFY_STATUS     0x80
 #define ACPI_BATTERY_NOTIFY_INFO       0x81
-#define ACPI_BATTERY_UNITS_WATTS       "mW"
-#define ACPI_BATTERY_UNITS_AMPS                "mA"
 
 #define _COMPONENT             ACPI_BATTERY_COMPONENT
 
-#define ACPI_BATTERY_UPDATE_TIME       0
-
-#define ACPI_BATTERY_NONE_UPDATE       0
-#define ACPI_BATTERY_EASY_UPDATE       1
-#define ACPI_BATTERY_INIT_UPDATE       2
-
 ACPI_MODULE_NAME("battery");
 
 MODULE_AUTHOR("Paul Diefenbaugh");
+MODULE_AUTHOR("Alexey Starikovskiy <astarikovskiy@suse.de>");
 MODULE_DESCRIPTION("ACPI Battery Driver");
 MODULE_LICENSE("GPL");
 
-static unsigned int update_time = ACPI_BATTERY_UPDATE_TIME;
-
-/* 0 - every time, > 0 - by update_time */
-module_param(update_time, uint, 0644);
+static unsigned int cache_time = 1000;
+module_param(cache_time, uint, 0644);
+MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
 
+#ifdef CONFIG_ACPI_PROCFS
 extern struct proc_dir_entry *acpi_lock_battery_dir(void);
 extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
 
-static int acpi_battery_add(struct acpi_device *device);
-static int acpi_battery_remove(struct acpi_device *device, int type);
-static int acpi_battery_resume(struct acpi_device *device);
+enum acpi_battery_files {
+       info_tag = 0,
+       state_tag,
+       alarm_tag,
+       ACPI_BATTERY_NUMFILES,
+};
+
+#endif
 
 static const struct acpi_device_id battery_device_ids[] = {
        {"PNP0C0A", 0},
        {"", 0},
 };
-MODULE_DEVICE_TABLE(acpi, battery_device_ids);
-
-static struct acpi_driver acpi_battery_driver = {
-       .name = "battery",
-       .class = ACPI_BATTERY_CLASS,
-       .ids = battery_device_ids,
-       .ops = {
-               .add = acpi_battery_add,
-               .resume = acpi_battery_resume,
-               .remove = acpi_battery_remove,
-               },
-};
 
-struct acpi_battery_state {
-       acpi_integer state;
-       acpi_integer present_rate;
-       acpi_integer remaining_capacity;
-       acpi_integer present_voltage;
-};
-
-struct acpi_battery_info {
-       acpi_integer power_unit;
-       acpi_integer design_capacity;
-       acpi_integer last_full_capacity;
-       acpi_integer battery_technology;
-       acpi_integer design_voltage;
-       acpi_integer design_capacity_warning;
-       acpi_integer design_capacity_low;
-       acpi_integer battery_capacity_granularity_1;
-       acpi_integer battery_capacity_granularity_2;
-       acpi_string model_number;
-       acpi_string serial_number;
-       acpi_string battery_type;
-       acpi_string oem_info;
-};
-
-enum acpi_battery_files{
-       ACPI_BATTERY_INFO = 0,
-       ACPI_BATTERY_STATE,
-       ACPI_BATTERY_ALARM,
-       ACPI_BATTERY_NUMFILES,
-};
+MODULE_DEVICE_TABLE(acpi, battery_device_ids);
 
-struct acpi_battery_flags {
-       u8 battery_present_prev;
-       u8 alarm_present;
-       u8 init_update;
-       u8 update[ACPI_BATTERY_NUMFILES];
-       u8 power_unit;
-};
 
 struct acpi_battery {
-       struct mutex mutex;
+       struct mutex lock;
+       struct power_supply bat;
        struct acpi_device *device;
-       struct acpi_battery_flags flags;
-       struct acpi_buffer bif_data;
-       struct acpi_buffer bst_data;
-       unsigned long alarm;
-       unsigned long update_time[ACPI_BATTERY_NUMFILES];
+       unsigned long update_time;
+       int current_now;
+       int capacity_now;
+       int voltage_now;
+       int design_capacity;
+       int full_charge_capacity;
+       int technology;
+       int design_voltage;
+       int design_capacity_warning;
+       int design_capacity_low;
+       int capacity_granularity_1;
+       int capacity_granularity_2;
+       int alarm;
+       char model_number[32];
+       char serial_number[32];
+       char type[32];
+       char oem_info[32];
+       int state;
+       int power_unit;
+       u8 alarm_present;
 };
 
+#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
+
 inline int acpi_battery_present(struct acpi_battery *battery)
 {
        return battery->device->status.battery_present;
 }
-inline char *acpi_battery_power_units(struct acpi_battery *battery)
-{
-       if (battery->flags.power_unit)
-               return ACPI_BATTERY_UNITS_AMPS;
-       else
-               return ACPI_BATTERY_UNITS_WATTS;
-}
 
-inline acpi_handle acpi_battery_handle(struct acpi_battery *battery)
+static int acpi_battery_technology(struct acpi_battery *battery)
 {
-       return battery->device->handle;
+       if (!strcasecmp("NiCd", battery->type))
+               return POWER_SUPPLY_TECHNOLOGY_NiCd;
+       if (!strcasecmp("NiMH", battery->type))
+               return POWER_SUPPLY_TECHNOLOGY_NiMH;
+       if (!strcasecmp("LION", battery->type))
+               return POWER_SUPPLY_TECHNOLOGY_LION;
+       if (!strcasecmp("LiP", battery->type))
+               return POWER_SUPPLY_TECHNOLOGY_LIPO;
+       return POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
 }
 
-/* --------------------------------------------------------------------------
-                               Battery Management
-   -------------------------------------------------------------------------- */
-
-static void acpi_battery_check_result(struct acpi_battery *battery, int result)
+static int acpi_battery_get_property(struct power_supply *psy,
+                                    enum power_supply_property psp,
+                                    union power_supply_propval *val)
 {
-       if (!battery)
-               return;
+       struct acpi_battery *battery = to_acpi_battery(psy);
 
-       if (result) {
-               battery->flags.init_update = 1;
+       if ((!acpi_battery_present(battery)) &&
+            psp != POWER_SUPPLY_PROP_PRESENT)
+               return -ENODEV;
+       switch (psp) {
+       case POWER_SUPPLY_PROP_STATUS:
+               if (battery->state & 0x01)
+                       val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+               else if (battery->state & 0x02)
+                       val->intval = POWER_SUPPLY_STATUS_CHARGING;
+               else if (battery->state == 0)
+                       val->intval = POWER_SUPPLY_STATUS_FULL;
+               break;
+       case POWER_SUPPLY_PROP_PRESENT:
+               val->intval = acpi_battery_present(battery);
+               break;
+       case POWER_SUPPLY_PROP_TECHNOLOGY:
+               val->intval = acpi_battery_technology(battery);
+               break;
+       case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
+               val->intval = battery->design_voltage * 1000;
+               break;
+       case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+               val->intval = battery->voltage_now * 1000;
+               break;
+       case POWER_SUPPLY_PROP_CURRENT_NOW:
+               val->intval = battery->current_now * 1000;
+               break;
+       case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
+       case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
+               val->intval = battery->design_capacity * 1000;
+               break;
+       case POWER_SUPPLY_PROP_CHARGE_FULL:
+       case POWER_SUPPLY_PROP_ENERGY_FULL:
+               val->intval = battery->full_charge_capacity * 1000;
+               break;
+       case POWER_SUPPLY_PROP_CHARGE_NOW:
+       case POWER_SUPPLY_PROP_ENERGY_NOW:
+               val->intval = battery->capacity_now * 1000;
+               break;
+       case POWER_SUPPLY_PROP_MODEL_NAME:
+               val->strval = battery->model_number;
+               break;
+       case POWER_SUPPLY_PROP_MANUFACTURER:
+               val->strval = battery->oem_info;
+               break;
+       default:
+               return -EINVAL;
        }
+       return 0;
 }
 
-static int acpi_battery_extract_package(struct acpi_battery *battery,
-                                       union acpi_object *package,
-                                       struct acpi_buffer *format,
-                                       struct acpi_buffer *data,
-                                       char *package_name)
+static enum power_supply_property charge_battery_props[] = {
+       POWER_SUPPLY_PROP_STATUS,
+       POWER_SUPPLY_PROP_PRESENT,
+       POWER_SUPPLY_PROP_TECHNOLOGY,
+       POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+       POWER_SUPPLY_PROP_VOLTAGE_NOW,
+       POWER_SUPPLY_PROP_CURRENT_NOW,
+       POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
+       POWER_SUPPLY_PROP_CHARGE_FULL,
+       POWER_SUPPLY_PROP_CHARGE_NOW,
+       POWER_SUPPLY_PROP_MODEL_NAME,
+       POWER_SUPPLY_PROP_MANUFACTURER,
+};
+
+static enum power_supply_property energy_battery_props[] = {
+       POWER_SUPPLY_PROP_STATUS,
+       POWER_SUPPLY_PROP_PRESENT,
+       POWER_SUPPLY_PROP_TECHNOLOGY,
+       POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+       POWER_SUPPLY_PROP_VOLTAGE_NOW,
+       POWER_SUPPLY_PROP_CURRENT_NOW,
+       POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
+       POWER_SUPPLY_PROP_ENERGY_FULL,
+       POWER_SUPPLY_PROP_ENERGY_NOW,
+       POWER_SUPPLY_PROP_MODEL_NAME,
+       POWER_SUPPLY_PROP_MANUFACTURER,
+};
+
+#ifdef CONFIG_ACPI_PROCFS
+inline char *acpi_battery_units(struct acpi_battery *battery)
 {
-       acpi_status status = AE_OK;
-       struct acpi_buffer data_null = { 0, NULL };
+       return (battery->power_unit)?"mA":"mW";
+}
+#endif
 
-       status = acpi_extract_package(package, format, &data_null);
-       if (status != AE_BUFFER_OVERFLOW) {
-               ACPI_EXCEPTION((AE_INFO, status, "Extracting size %s",
-                               package_name));
-               return -ENODEV;
-       }
+/* --------------------------------------------------------------------------
+                               Battery Management
+   -------------------------------------------------------------------------- */
+struct acpi_offsets {
+       size_t offset;          /* offset inside struct acpi_sbs_battery */
+       u8 mode;                /* int or string? */
+};
 
-       if (data_null.length != data->length) {
-               kfree(data->pointer);
-               data->pointer = kzalloc(data_null.length, GFP_KERNEL);
-               if (!data->pointer) {
-                       ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, "kzalloc()"));
-                       return -ENOMEM;
-               }
-               data->length = data_null.length;
-       }
+static struct acpi_offsets state_offsets[] = {
+       {offsetof(struct acpi_battery, state), 0},
+       {offsetof(struct acpi_battery, current_now), 0},
+       {offsetof(struct acpi_battery, capacity_now), 0},
+       {offsetof(struct acpi_battery, voltage_now), 0},
+};
 
-       status = acpi_extract_package(package, format, data);
-       if (ACPI_FAILURE(status)) {
-               ACPI_EXCEPTION((AE_INFO, status, "Extracting %s",
-                               package_name));
-               return -ENODEV;
-       }
+static struct acpi_offsets info_offsets[] = {
+       {offsetof(struct acpi_battery, power_unit), 0},
+       {offsetof(struct acpi_battery, design_capacity), 0},
+       {offsetof(struct acpi_battery, full_charge_capacity), 0},
+       {offsetof(struct acpi_battery, technology), 0},
+       {offsetof(struct acpi_battery, design_voltage), 0},
+       {offsetof(struct acpi_battery, design_capacity_warning), 0},
+       {offsetof(struct acpi_battery, design_capacity_low), 0},
+       {offsetof(struct acpi_battery, capacity_granularity_1), 0},
+       {offsetof(struct acpi_battery, capacity_granularity_2), 0},
+       {offsetof(struct acpi_battery, model_number), 1},
+       {offsetof(struct acpi_battery, serial_number), 1},
+       {offsetof(struct acpi_battery, type), 1},
+       {offsetof(struct acpi_battery, oem_info), 1},
+};
 
+static int extract_package(struct acpi_battery *battery,
+                          union acpi_object *package,
+                          struct acpi_offsets *offsets, int num)
+{
+       int i, *x;
+       union acpi_object *element;
+       if (package->type != ACPI_TYPE_PACKAGE)
+               return -EFAULT;
+       for (i = 0; i < num; ++i) {
+               if (package->package.count <= i)
+                       return -EFAULT;
+               element = &package->package.elements[i];
+               if (offsets[i].mode) {
+                       if (element->type != ACPI_TYPE_STRING &&
+                           element->type != ACPI_TYPE_BUFFER)
+                               return -EFAULT;
+                       strncpy((u8 *)battery + offsets[i].offset,
+                               element->string.pointer, 32);
+               } else {
+                       if (element->type != ACPI_TYPE_INTEGER)
+                               return -EFAULT;
+                       x = (int *)((u8 *)battery + offsets[i].offset);
+                       *x = element->integer.value;
+               }
+       }
        return 0;
 }
 
 static int acpi_battery_get_status(struct acpi_battery *battery)
 {
-       int result = 0;
-
-       result = acpi_bus_get_status(battery->device);
-       if (result) {
+       if (acpi_bus_get_status(battery->device)) {
                ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA"));
                return -ENODEV;
        }
-       return result;
+       return 0;
 }
 
 static int acpi_battery_get_info(struct acpi_battery *battery)
 {
-       int result = 0;
+       int result = -EFAULT;
        acpi_status status = 0;
        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-       struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BIF),
-               ACPI_BATTERY_FORMAT_BIF
-       };
-       union acpi_object *package = NULL;
-       struct acpi_buffer *data = NULL;
-       struct acpi_battery_info *bif = NULL;
-
-       battery->update_time[ACPI_BATTERY_INFO] = get_seconds();
 
        if (!acpi_battery_present(battery))
                return 0;
+       mutex_lock(&battery->lock);
+       status = acpi_evaluate_object(battery->device->handle, "_BIF",
+                                     NULL, &buffer);
+       mutex_unlock(&battery->lock);
 
-       /* Evaluate _BIF */
-
-       status =
-           acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", NULL,
-                                &buffer);
        if (ACPI_FAILURE(status)) {
                ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF"));
                return -ENODEV;
        }
 
-       package = buffer.pointer;
-
-       data = &battery->bif_data;
-
-       /* Extract Package Data */
-
-       result =
-           acpi_battery_extract_package(battery, package, &format, data,
-                                        "_BIF");
-       if (result)
-               goto end;
-
-      end:
-
+       result = extract_package(battery, buffer.pointer,
+                                info_offsets, ARRAY_SIZE(info_offsets));
        kfree(buffer.pointer);
-
-       if (!result) {
-               bif = data->pointer;
-               battery->flags.power_unit = bif->power_unit;
-       }
-
        return result;
 }
 
@@ -273,342 +319,203 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
        int result = 0;
        acpi_status status = 0;
        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-       struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BST),
-               ACPI_BATTERY_FORMAT_BST
-       };
-       union acpi_object *package = NULL;
-       struct acpi_buffer *data = NULL;
-
-       battery->update_time[ACPI_BATTERY_STATE] = get_seconds();
 
        if (!acpi_battery_present(battery))
                return 0;
 
-       /* Evaluate _BST */
+       if (battery->update_time &&
+           time_before(jiffies, battery->update_time +
+                       msecs_to_jiffies(cache_time)))
+               return 0;
+
+       mutex_lock(&battery->lock);
+       status = acpi_evaluate_object(battery->device->handle, "_BST",
+                                     NULL, &buffer);
+       mutex_unlock(&battery->lock);
 
-       status =
-           acpi_evaluate_object(acpi_battery_handle(battery), "_BST", NULL,
-                                &buffer);
        if (ACPI_FAILURE(status)) {
                ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST"));
                return -ENODEV;
        }
 
-       package = buffer.pointer;
-
-       data = &battery->bst_data;
-
-       /* Extract Package Data */
-
-       result =
-           acpi_battery_extract_package(battery, package, &format, data,
-                                        "_BST");
-       if (result)
-               goto end;
-
-      end:
+       result = extract_package(battery, buffer.pointer,
+                                state_offsets, ARRAY_SIZE(state_offsets));
+       battery->update_time = jiffies;
        kfree(buffer.pointer);
-
        return result;
 }
 
-static int acpi_battery_get_alarm(struct acpi_battery *battery)
-{
-       battery->update_time[ACPI_BATTERY_ALARM] = get_seconds();
-
-       return 0;
-}
-
-static int acpi_battery_set_alarm(struct acpi_battery *battery,
-                                 unsigned long alarm)
+static int acpi_battery_set_alarm(struct acpi_battery *battery)
 {
        acpi_status status = 0;
-       union acpi_object arg0 = { ACPI_TYPE_INTEGER };
+       union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER };
        struct acpi_object_list arg_list = { 1, &arg0 };
 
-       battery->update_time[ACPI_BATTERY_ALARM] = get_seconds();
-
-       if (!acpi_battery_present(battery))
+       if (!acpi_battery_present(battery)|| !battery->alarm_present)
                return -ENODEV;
 
-       if (!battery->flags.alarm_present)
-               return -ENODEV;
-
-       arg0.integer.value = alarm;
+       arg0.integer.value = battery->alarm;
 
-       status =
-           acpi_evaluate_object(acpi_battery_handle(battery), "_BTP",
+       mutex_lock(&battery->lock);
+       status = acpi_evaluate_object(battery->device->handle, "_BTP",
                                 &arg_list, NULL);
+       mutex_unlock(&battery->lock);
+
        if (ACPI_FAILURE(status))
                return -ENODEV;
 
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", (u32) alarm));
-
-       battery->alarm = alarm;
-
+       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", battery->alarm));
        return 0;
 }
 
 static int acpi_battery_init_alarm(struct acpi_battery *battery)
 {
-       int result = 0;
        acpi_status status = AE_OK;
        acpi_handle handle = NULL;
-       struct acpi_battery_info *bif = battery->bif_data.pointer;
-       unsigned long alarm = battery->alarm;
 
        /* See if alarms are supported, and if so, set default */
-
-       status = acpi_get_handle(acpi_battery_handle(battery), "_BTP", &handle);
-       if (ACPI_SUCCESS(status)) {
-               battery->flags.alarm_present = 1;
-               if (!alarm && bif) {
-                       alarm = bif->design_capacity_warning;
-               }
-               result = acpi_battery_set_alarm(battery, alarm);
-               if (result)
-                       goto end;
-       } else {
-               battery->flags.alarm_present = 0;
+       status = acpi_get_handle(battery->device->handle, "_BTP", &handle);
+       if (ACPI_FAILURE(status)) {
+               battery->alarm_present = 0;
+               return 0;
        }
-
-      end:
-
-       return result;
+       battery->alarm_present = 1;
+       if (!battery->alarm)
+               battery->alarm = battery->design_capacity_warning;
+       return acpi_battery_set_alarm(battery);
 }
 
-static int acpi_battery_init_update(struct acpi_battery *battery)
+static int acpi_battery_update(struct acpi_battery *battery)
 {
-       int result = 0;
-
-       result = acpi_battery_get_status(battery);
-       if (result)
+       int saved_present = acpi_battery_present(battery);
+       int result = acpi_battery_get_status(battery);
+       if (result || !acpi_battery_present(battery))
                return result;
-
-       battery->flags.battery_present_prev = acpi_battery_present(battery);
-
-       if (acpi_battery_present(battery)) {
+       if (saved_present != acpi_battery_present(battery) ||
+           !battery->update_time) {
+               battery->update_time = 0;
                result = acpi_battery_get_info(battery);
                if (result)
                        return result;
-               result = acpi_battery_get_state(battery);
-               if (result)
-                       return result;
-
-               acpi_battery_init_alarm(battery);
-       }
-
-       return result;
-}
-
-static int acpi_battery_update(struct acpi_battery *battery,
-                              int update, int *update_result_ptr)
-{
-       int result = 0;
-       int update_result = ACPI_BATTERY_NONE_UPDATE;
-
-       if (!acpi_battery_present(battery)) {
-               update = 1;
-       }
-
-       if (battery->flags.init_update) {
-               result = acpi_battery_init_update(battery);
-               if (result)
-                       goto end;
-               update_result = ACPI_BATTERY_INIT_UPDATE;
-       } else if (update) {
-               result = acpi_battery_get_status(battery);
-               if (result)
-                       goto end;
-               if ((!battery->flags.battery_present_prev & acpi_battery_present(battery))
-                   || (battery->flags.battery_present_prev & !acpi_battery_present(battery))) {
-                       result = acpi_battery_init_update(battery);
-                       if (result)
-                               goto end;
-                       update_result = ACPI_BATTERY_INIT_UPDATE;
+               if (battery->power_unit) {
+                       battery->bat.properties = charge_battery_props;
+                       battery->bat.num_properties =
+                               ARRAY_SIZE(charge_battery_props);
                } else {
-                       update_result = ACPI_BATTERY_EASY_UPDATE;
+                       battery->bat.properties = energy_battery_props;
+                       battery->bat.num_properties =
+                               ARRAY_SIZE(energy_battery_props);
                }
+               acpi_battery_init_alarm(battery);
        }
-
-      end:
-
-       battery->flags.init_update = (result != 0);
-
-       *update_result_ptr = update_result;
-
-       return result;
-}
-
-static void acpi_battery_notify_update(struct acpi_battery *battery)
-{
-       acpi_battery_get_status(battery);
-
-       if (battery->flags.init_update) {
-               return;
-       }
-
-       if ((!battery->flags.battery_present_prev &
-            acpi_battery_present(battery)) ||
-           (battery->flags.battery_present_prev &
-            !acpi_battery_present(battery))) {
-               battery->flags.init_update = 1;
-       } else {
-               battery->flags.update[ACPI_BATTERY_INFO] = 1;
-               battery->flags.update[ACPI_BATTERY_STATE] = 1;
-               battery->flags.update[ACPI_BATTERY_ALARM] = 1;
-       }
+       return acpi_battery_get_state(battery);
 }
 
 /* --------------------------------------------------------------------------
                               FS Interface (/proc)
    -------------------------------------------------------------------------- */
 
+#ifdef CONFIG_ACPI_PROCFS
 static struct proc_dir_entry *acpi_battery_dir;
 
 static int acpi_battery_print_info(struct seq_file *seq, int result)
 {
        struct acpi_battery *battery = seq->private;
-       struct acpi_battery_info *bif = NULL;
-       char *units = "?";
 
        if (result)
                goto end;
 
-       if (acpi_battery_present(battery))
-               seq_printf(seq, "present:                 yes\n");
-       else {
-               seq_printf(seq, "present:                 no\n");
-               goto end;
-       }
-
-       bif = battery->bif_data.pointer;
-       if (!bif) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BIF buffer is NULL"));
-               result = -ENODEV;
+       seq_printf(seq, "present:                 %s\n",
+                  acpi_battery_present(battery)?"yes":"no");
+       if (!acpi_battery_present(battery))
                goto end;
-       }
-
-       /* Battery Units */
-
-       units = acpi_battery_power_units(battery);
-
-       if (bif->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
+       if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
                seq_printf(seq, "design capacity:         unknown\n");
        else
                seq_printf(seq, "design capacity:         %d %sh\n",
-                          (u32) bif->design_capacity, units);
+                          battery->design_capacity,
+                          acpi_battery_units(battery));
 
-       if (bif->last_full_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
+       if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
                seq_printf(seq, "last full capacity:      unknown\n");
        else
                seq_printf(seq, "last full capacity:      %d %sh\n",
-                          (u32) bif->last_full_capacity, units);
+                          battery->full_charge_capacity,
+                          acpi_battery_units(battery));
 
-       switch ((u32) bif->battery_technology) {
-       case 0:
-               seq_printf(seq, "battery technology:      non-rechargeable\n");
-               break;
-       case 1:
-               seq_printf(seq, "battery technology:      rechargeable\n");
-               break;
-       default:
-               seq_printf(seq, "battery technology:      unknown\n");
-               break;
-       }
+       seq_printf(seq, "battery technology:      %srechargeable\n",
+                  (!battery->technology)?"non-":"");
 
-       if (bif->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
+       if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
                seq_printf(seq, "design voltage:          unknown\n");
        else
                seq_printf(seq, "design voltage:          %d mV\n",
-                          (u32) bif->design_voltage);
+                          battery->design_voltage);
        seq_printf(seq, "design capacity warning: %d %sh\n",
-                  (u32) bif->design_capacity_warning, units);
+                  battery->design_capacity_warning,
+                  acpi_battery_units(battery));
        seq_printf(seq, "design capacity low:     %d %sh\n",
-                  (u32) bif->design_capacity_low, units);
+                  battery->design_capacity_low,
+                  acpi_battery_units(battery));
        seq_printf(seq, "capacity granularity 1:  %d %sh\n",
-                  (u32) bif->battery_capacity_granularity_1, units);
+                  battery->capacity_granularity_1,
+                  acpi_battery_units(battery));
        seq_printf(seq, "capacity granularity 2:  %d %sh\n",
-                  (u32) bif->battery_capacity_granularity_2, units);
-       seq_printf(seq, "model number:            %s\n", bif->model_number);
-       seq_printf(seq, "serial number:           %s\n", bif->serial_number);
-       seq_printf(seq, "battery type:            %s\n", bif->battery_type);
-       seq_printf(seq, "OEM info:                %s\n", bif->oem_info);
-
+                  battery->capacity_granularity_2,
+                  acpi_battery_units(battery));
+       seq_printf(seq, "model number:            %s\n", battery->model_number);
+       seq_printf(seq, "serial number:           %s\n", battery->serial_number);
+       seq_printf(seq, "battery type:            %s\n", battery->type);
+       seq_printf(seq, "OEM info:                %s\n", battery->oem_info);
       end:
-
        if (result)
                seq_printf(seq, "ERROR: Unable to read battery info\n");
-
        return result;
 }
 
 static int acpi_battery_print_state(struct seq_file *seq, int result)
 {
        struct acpi_battery *battery = seq->private;
-       struct acpi_battery_state *bst = NULL;
-       char *units = "?";
 
        if (result)
                goto end;
 
-       if (acpi_battery_present(battery))
-               seq_printf(seq, "present:                 yes\n");
-       else {
-               seq_printf(seq, "present:                 no\n");
-               goto end;
-       }
-
-       bst = battery->bst_data.pointer;
-       if (!bst) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BST buffer is NULL"));
-               result = -ENODEV;
+       seq_printf(seq, "present:                 %s\n",
+                  acpi_battery_present(battery)?"yes":"no");
+       if (!acpi_battery_present(battery))
                goto end;
-       }
-
-       /* Battery Units */
-
-       units = acpi_battery_power_units(battery);
-
-       if (!(bst->state & 0x04))
-               seq_printf(seq, "capacity state:          ok\n");
-       else
-               seq_printf(seq, "capacity state:          critical\n");
 
-       if ((bst->state & 0x01) && (bst->state & 0x02)) {
+       seq_printf(seq, "capacity state:          %s\n",
+                       (battery->state & 0x04)?"critical":"ok");
+       if ((battery->state & 0x01) && (battery->state & 0x02))
                seq_printf(seq,
                           "charging state:          charging/discharging\n");
-       } else if (bst->state & 0x01)
+       else if (battery->state & 0x01)
                seq_printf(seq, "charging state:          discharging\n");
-       else if (bst->state & 0x02)
+       else if (battery->state & 0x02)
                seq_printf(seq, "charging state:          charging\n");
-       else {
+       else
                seq_printf(seq, "charging state:          charged\n");
-       }
 
-       if (bst->present_rate == ACPI_BATTERY_VALUE_UNKNOWN)
+       if (battery->current_now == ACPI_BATTERY_VALUE_UNKNOWN)
                seq_printf(seq, "present rate:            unknown\n");
        else
                seq_printf(seq, "present rate:            %d %s\n",
-                          (u32) bst->present_rate, units);
+                          battery->current_now, acpi_battery_units(battery));
 
-       if (bst->remaining_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
+       if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
                seq_printf(seq, "remaining capacity:      unknown\n");
        else
                seq_printf(seq, "remaining capacity:      %d %sh\n",
-                          (u32) bst->remaining_capacity, units);
-
-       if (bst->present_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
+                          battery->capacity_now, acpi_battery_units(battery));
+       if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN)
                seq_printf(seq, "present voltage:         unknown\n");
        else
                seq_printf(seq, "present voltage:         %d mV\n",
-                          (u32) bst->present_voltage);
-
+                          battery->voltage_now);
       end:
-
-       if (result) {
+       if (result)
                seq_printf(seq, "ERROR: Unable to read battery state\n");
-       }
 
        return result;
 }
@@ -616,7 +523,6 @@ static int acpi_battery_print_state(struct seq_file *seq, int result)
 static int acpi_battery_print_alarm(struct seq_file *seq, int result)
 {
        struct acpi_battery *battery = seq->private;
-       char *units = "?";
 
        if (result)
                goto end;
@@ -625,189 +531,121 @@ static int acpi_battery_print_alarm(struct seq_file *seq, int result)
                seq_printf(seq, "present:                 no\n");
                goto end;
        }
-
-       /* Battery Units */
-
-       units = acpi_battery_power_units(battery);
-
        seq_printf(seq, "alarm:                   ");
        if (!battery->alarm)
                seq_printf(seq, "unsupported\n");
        else
-               seq_printf(seq, "%lu %sh\n", battery->alarm, units);
-
+               seq_printf(seq, "%u %sh\n", battery->alarm,
+                               acpi_battery_units(battery));
       end:
-
        if (result)
                seq_printf(seq, "ERROR: Unable to read battery alarm\n");
-
        return result;
 }
 
-static ssize_t
-acpi_battery_write_alarm(struct file *file,
-                        const char __user * buffer,
-                        size_t count, loff_t * ppos)
+static ssize_t acpi_battery_write_alarm(struct file *file,
+                                       const char __user * buffer,
+                                       size_t count, loff_t * ppos)
 {
        int result = 0;
        char alarm_string[12] = { '\0' };
        struct seq_file *m = file->private_data;
        struct acpi_battery *battery = m->private;
-       int update_result = ACPI_BATTERY_NONE_UPDATE;
 
        if (!battery || (count > sizeof(alarm_string) - 1))
                return -EINVAL;
-
-       mutex_lock(&battery->mutex);
-
-       result = acpi_battery_update(battery, 1, &update_result);
        if (result) {
                result = -ENODEV;
                goto end;
        }
-
        if (!acpi_battery_present(battery)) {
                result = -ENODEV;
                goto end;
        }
-
        if (copy_from_user(alarm_string, buffer, count)) {
                result = -EFAULT;
                goto end;
        }
-
        alarm_string[count] = '\0';
-
-       result = acpi_battery_set_alarm(battery,
-                                       simple_strtoul(alarm_string, NULL, 0));
-       if (result)
-               goto end;
-
+       battery->alarm = simple_strtol(alarm_string, NULL, 0);
+       result = acpi_battery_set_alarm(battery);
       end:
-
-       acpi_battery_check_result(battery, result);
-
        if (!result)
-               result = count;
-
-       mutex_unlock(&battery->mutex);
-
+               return count;
        return result;
 }
 
 typedef int(*print_func)(struct seq_file *seq, int result);
-typedef int(*get_func)(struct acpi_battery *battery);
-
-static struct acpi_read_mux {
-       print_func print;
-       get_func get;
-} acpi_read_funcs[ACPI_BATTERY_NUMFILES] = {
-       {.get = acpi_battery_get_info, .print = acpi_battery_print_info},
-       {.get = acpi_battery_get_state, .print = acpi_battery_print_state},
-       {.get = acpi_battery_get_alarm, .print = acpi_battery_print_alarm},
+
+static print_func acpi_print_funcs[ACPI_BATTERY_NUMFILES] = {
+       acpi_battery_print_info,
+       acpi_battery_print_state,
+       acpi_battery_print_alarm,
 };
 
 static int acpi_battery_read(int fid, struct seq_file *seq)
 {
        struct acpi_battery *battery = seq->private;
-       int result = 0;
-       int update_result = ACPI_BATTERY_NONE_UPDATE;
-       int update = 0;
-
-       mutex_lock(&battery->mutex);
-
-       update = (get_seconds() - battery->update_time[fid] >= update_time);
-       update = (update | battery->flags.update[fid]);
-
-       result = acpi_battery_update(battery, update, &update_result);
-       if (result)
-               goto end;
-
-       if (update_result == ACPI_BATTERY_EASY_UPDATE) {
-               result = acpi_read_funcs[fid].get(battery);
-               if (result)
-                       goto end;
+       int result = acpi_battery_update(battery);
+       return acpi_print_funcs[fid](seq, result);
+}
+
+#define DECLARE_FILE_FUNCTIONS(_name) \
+static int acpi_battery_read_##_name(struct seq_file *seq, void *offset) \
+{ \
+       return acpi_battery_read(_name##_tag, seq); \
+} \
+static int acpi_battery_##_name##_open_fs(struct inode *inode, struct file *file) \
+{ \
+       return single_open(file, acpi_battery_read_##_name, PDE(inode)->data); \
+}
+
+DECLARE_FILE_FUNCTIONS(info);
+DECLARE_FILE_FUNCTIONS(state);
+DECLARE_FILE_FUNCTIONS(alarm);
+
+#undef DECLARE_FILE_FUNCTIONS
+
+#define FILE_DESCRIPTION_RO(_name) \
+       { \
+       .name = __stringify(_name), \
+       .mode = S_IRUGO, \
+       .ops = { \
+               .open = acpi_battery_##_name##_open_fs, \
+               .read = seq_read, \
+               .llseek = seq_lseek, \
+               .release = single_release, \
+               .owner = THIS_MODULE, \
+               }, \
+       }
+
+#define FILE_DESCRIPTION_RW(_name) \
+       { \
+       .name = __stringify(_name), \
+       .mode = S_IFREG | S_IRUGO | S_IWUSR, \
+       .ops = { \
+               .open = acpi_battery_##_name##_open_fs, \
+               .read = seq_read, \
+               .llseek = seq_lseek, \
+               .write = acpi_battery_write_##_name, \
+               .release = single_release, \
+               .owner = THIS_MODULE, \
+               }, \
        }
 
-      end:
-       result = acpi_read_funcs[fid].print(seq, result);
-       acpi_battery_check_result(battery, result);
-       battery->flags.update[fid] = result;
-       mutex_unlock(&battery->mutex);
-       return result;
-}
-
-static int acpi_battery_read_info(struct seq_file *seq, void *offset)
-{
-       return acpi_battery_read(ACPI_BATTERY_INFO, seq);
-}
-
-static int acpi_battery_read_state(struct seq_file *seq, void *offset)
-{
-       return acpi_battery_read(ACPI_BATTERY_STATE, seq);
-}
-
-static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
-{
-       return acpi_battery_read(ACPI_BATTERY_ALARM, seq);
-}
-
-static int acpi_battery_info_open_fs(struct inode *inode, struct file *file)
-{
-       return single_open(file, acpi_battery_read_info, PDE(inode)->data);
-}
-
-static int acpi_battery_state_open_fs(struct inode *inode, struct file *file)
-{
-       return single_open(file, acpi_battery_read_state, PDE(inode)->data);
-}
-
-static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
-{
-       return single_open(file, acpi_battery_read_alarm, PDE(inode)->data);
-}
-
 static struct battery_file {
        struct file_operations ops;
        mode_t mode;
        char *name;
 } acpi_battery_file[] = {
-       {
-       .name = "info",
-       .mode = S_IRUGO,
-       .ops = {
-       .open = acpi_battery_info_open_fs,
-       .read = seq_read,
-       .llseek = seq_lseek,
-       .release = single_release,
-       .owner = THIS_MODULE,
-       },
-       },
-       {
-       .name = "state",
-       .mode = S_IRUGO,
-       .ops = {
-       .open = acpi_battery_state_open_fs,
-       .read = seq_read,
-       .llseek = seq_lseek,
-       .release = single_release,
-       .owner = THIS_MODULE,
-       },
-       },
-       {
-       .name = "alarm",
-       .mode = S_IFREG | S_IRUGO | S_IWUSR,
-       .ops = {
-       .open = acpi_battery_alarm_open_fs,
-       .read = seq_read,
-       .write = acpi_battery_write_alarm,
-       .llseek = seq_lseek,
-       .release = single_release,
-       .owner = THIS_MODULE,
-       },
-       },
+       FILE_DESCRIPTION_RO(info),
+       FILE_DESCRIPTION_RO(state),
+       FILE_DESCRIPTION_RW(alarm),
 };
 
+#undef FILE_DESCRIPTION_RO
+#undef FILE_DESCRIPTION_RW
+
 static int acpi_battery_add_fs(struct acpi_device *device)
 {
        struct proc_dir_entry *entry = NULL;
@@ -832,25 +670,51 @@ static int acpi_battery_add_fs(struct acpi_device *device)
                        entry->owner = THIS_MODULE;
                }
        }
-
        return 0;
 }
 
-static int acpi_battery_remove_fs(struct acpi_device *device)
+static void acpi_battery_remove_fs(struct acpi_device *device)
 {
        int i;
-       if (acpi_device_dir(device)) {
-               for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) {
-                       remove_proc_entry(acpi_battery_file[i].name,
+       if (!acpi_device_dir(device))
+               return;
+       for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i)
+               remove_proc_entry(acpi_battery_file[i].name,
                                  acpi_device_dir(device));
-               }
-               remove_proc_entry(acpi_device_bid(device), acpi_battery_dir);
-               acpi_device_dir(device) = NULL;
-       }
 
-       return 0;
+       remove_proc_entry(acpi_device_bid(device), acpi_battery_dir);
+       acpi_device_dir(device) = NULL;
+}
+
+#endif
+
+static ssize_t acpi_battery_alarm_show(struct device *dev,
+                                       struct device_attribute *attr,
+                                       char *buf)
+{
+       struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
+       return sprintf(buf, "%d\n", battery->alarm * 1000);
+}
+
+static ssize_t acpi_battery_alarm_store(struct device *dev,
+                                       struct device_attribute *attr,
+                                       const char *buf, size_t count)
+{
+       unsigned long x;
+       struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
+       if (sscanf(buf, "%ld\n", &x) == 1)
+               battery->alarm = x/1000;
+       if (acpi_battery_present(battery))
+               acpi_battery_set_alarm(battery);
+       return count;
 }
 
+static struct device_attribute alarm_attr = {
+       .attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE},
+       .show = acpi_battery_alarm_show,
+       .store = acpi_battery_alarm_store,
+};
+
 /* --------------------------------------------------------------------------
                                  Driver Interface
    -------------------------------------------------------------------------- */
@@ -858,33 +722,17 @@ static int acpi_battery_remove_fs(struct acpi_device *device)
 static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
 {
        struct acpi_battery *battery = data;
-       struct acpi_device *device = NULL;
-
+       struct acpi_device *device;
        if (!battery)
                return;
-
        device = battery->device;
-
-       switch (event) {
-       case ACPI_BATTERY_NOTIFY_STATUS:
-       case ACPI_BATTERY_NOTIFY_INFO:
-       case ACPI_NOTIFY_BUS_CHECK:
-       case ACPI_NOTIFY_DEVICE_CHECK:
-               device = battery->device;
-               acpi_battery_notify_update(battery);
-               acpi_bus_generate_proc_event(device, event,
+       acpi_battery_update(battery);
+       acpi_bus_generate_proc_event(device, event,
+                                    acpi_battery_present(battery));
+       acpi_bus_generate_netlink_event(device->pnp.device_class,
+                                       device->dev.bus_id, event,
                                        acpi_battery_present(battery));
-               acpi_bus_generate_netlink_event(device->pnp.device_class,
-                                                 device->dev.bus_id, event,
-                                                 acpi_battery_present(battery));
-               break;
-       default:
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                                 "Unsupported event [0x%x]\n", event));
-               break;
-       }
-
-       return;
+       kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE);
 }
 
 static int acpi_battery_add(struct acpi_device *device)
@@ -892,33 +740,27 @@ static int acpi_battery_add(struct acpi_device *device)
        int result = 0;
        acpi_status status = 0;
        struct acpi_battery *battery = NULL;
-
        if (!device)
                return -EINVAL;
-
        battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL);
        if (!battery)
                return -ENOMEM;
-
-       mutex_init(&battery->mutex);
-
-       mutex_lock(&battery->mutex);
-
        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;
-
-       result = acpi_battery_get_status(battery);
-       if (result)
-               goto end;
-
-       battery->flags.init_update = 1;
-
+       mutex_init(&battery->lock);
+       acpi_battery_update(battery);
+#ifdef CONFIG_ACPI_PROCFS
        result = acpi_battery_add_fs(device);
        if (result)
                goto end;
-
+#endif
+       battery->bat.name = acpi_device_bid(device);
+       battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
+       battery->bat.get_property = acpi_battery_get_property;
+       result = power_supply_register(&battery->device->dev, &battery->bat);
+       result = device_create_file(battery->bat.dev, &alarm_attr);
        status = acpi_install_notify_handler(device->handle,
                                             ACPI_ALL_NOTIFY,
                                             acpi_battery_notify, battery);
@@ -927,20 +769,16 @@ static int acpi_battery_add(struct acpi_device *device)
                result = -ENODEV;
                goto end;
        }
-
        printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
               ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
               device->status.battery_present ? "present" : "absent");
-
       end:
-
        if (result) {
+#ifdef CONFIG_ACPI_PROCFS
                acpi_battery_remove_fs(device);
+#endif
                kfree(battery);
        }
-
-       mutex_unlock(&battery->mutex);
-
        return result;
 }
 
@@ -951,27 +789,19 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
 
        if (!device || !acpi_driver_data(device))
                return -EINVAL;
-
        battery = acpi_driver_data(device);
-
-       mutex_lock(&battery->mutex);
-
        status = acpi_remove_notify_handler(device->handle,
                                            ACPI_ALL_NOTIFY,
                                            acpi_battery_notify);
-
+#ifdef CONFIG_ACPI_PROCFS
        acpi_battery_remove_fs(device);
-
-       kfree(battery->bif_data.pointer);
-
-       kfree(battery->bst_data.pointer);
-
-       mutex_unlock(&battery->mutex);
-
-       mutex_destroy(&battery->mutex);
-
+#endif
+       if (battery->bat.dev) {
+               device_remove_file(battery->bat.dev, &alarm_attr);
+               power_supply_unregister(&battery->bat);
+       }
+       mutex_destroy(&battery->lock);
        kfree(battery);
-
        return 0;
 }
 
@@ -979,44 +809,48 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
 static int acpi_battery_resume(struct acpi_device *device)
 {
        struct acpi_battery *battery;
-
        if (!device)
                return -EINVAL;
-
-       battery = device->driver_data;
-
-       battery->flags.init_update = 1;
-
+       battery = acpi_driver_data(device);
+       battery->update_time = 0;
        return 0;
 }
 
+static struct acpi_driver acpi_battery_driver = {
+       .name = "battery",
+       .class = ACPI_BATTERY_CLASS,
+       .ids = battery_device_ids,
+       .ops = {
+               .add = acpi_battery_add,
+               .resume = acpi_battery_resume,
+               .remove = acpi_battery_remove,
+               },
+};
+
 static int __init acpi_battery_init(void)
 {
-       int result;
-
        if (acpi_disabled)
                return -ENODEV;
-
+#ifdef CONFIG_ACPI_PROCFS
        acpi_battery_dir = acpi_lock_battery_dir();
        if (!acpi_battery_dir)
                return -ENODEV;
-
-       result = acpi_bus_register_driver(&acpi_battery_driver);
-       if (result < 0) {
+#endif
+       if (acpi_bus_register_driver(&acpi_battery_driver) < 0) {
+#ifdef CONFIG_ACPI_PROCFS
                acpi_unlock_battery_dir(acpi_battery_dir);
+#endif
                return -ENODEV;
        }
-
        return 0;
 }
 
 static void __exit acpi_battery_exit(void)
 {
        acpi_bus_unregister_driver(&acpi_battery_driver);
-
+#ifdef CONFIG_ACPI_PROCFS
        acpi_unlock_battery_dir(acpi_battery_dir);
-
-       return;
+#endif
 }
 
 module_init(acpi_battery_init);
index cbfc81579c9af5ddf5760e6ac410174cff203e38..fb2cff9a2d24679cf99e9c82b9f04a4e32ea4bb0 100644 (file)
@@ -286,15 +286,11 @@ DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue);
 
 extern int event_is_open;
 
-int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
+int acpi_bus_generate_proc_event4(const char *device_class, const char *bus_id, u8 type, int data)
 {
-       struct acpi_bus_event *event = NULL;
+       struct acpi_bus_event *event;
        unsigned long flags = 0;
 
-
-       if (!device)
-               return -EINVAL;
-
        /* drop event on the floor if no one's listening */
        if (!event_is_open)
                return 0;
@@ -303,8 +299,8 @@ int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
        if (!event)
                return -ENOMEM;
 
-       strcpy(event->device_class, device->pnp.device_class);
-       strcpy(event->bus_id, device->pnp.bus_id);
+       strcpy(event->device_class, device_class);
+       strcpy(event->bus_id, bus_id);
        event->type = type;
        event->data = data;
 
@@ -315,6 +311,17 @@ int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
        wake_up_interruptible(&acpi_bus_event_queue);
 
        return 0;
+
+}
+
+EXPORT_SYMBOL_GPL(acpi_bus_generate_proc_event4);
+
+int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
+{
+       if (!device)
+               return -EINVAL;
+       return acpi_bus_generate_proc_event4(device->pnp.device_class,
+                                            device->pnp.bus_id, type, data);
 }
 
 EXPORT_SYMBOL(acpi_bus_generate_proc_event);
index 2e79a3395ecffca8641cc02e64b616ef88be5ba6..301e832e6961290912396f92fd54244f30b5ba7f 100644 (file)
@@ -434,18 +434,18 @@ static int acpi_button_add(struct acpi_device *device)
        switch (button->type) {
        case ACPI_BUTTON_TYPE_POWER:
        case ACPI_BUTTON_TYPE_POWERF:
-               input->evbit[0] = BIT(EV_KEY);
+               input->evbit[0] = BIT_MASK(EV_KEY);
                set_bit(KEY_POWER, input->keybit);
                break;
 
        case ACPI_BUTTON_TYPE_SLEEP:
        case ACPI_BUTTON_TYPE_SLEEPF:
-               input->evbit[0] = BIT(EV_KEY);
+               input->evbit[0] = BIT_MASK(EV_KEY);
                set_bit(KEY_SLEEP, input->keybit);
                break;
 
        case ACPI_BUTTON_TYPE_LID:
-               input->evbit[0] = BIT(EV_SW);
+               input->evbit[0] = BIT_MASK(EV_SW);
                set_bit(SW_LID, input->swbit);
                break;
        }
index 3f7935ab0cf53c0d6ca21b89096ba3c727e0e7b6..7b4178393e34856e8b6525a0c476a99a37b6962e 100644 (file)
@@ -121,6 +121,7 @@ static struct acpi_ec {
        atomic_t event_count;
        wait_queue_head_t wait;
        struct list_head list;
+       u8 handlers_installed;
 } *boot_ec, *first_ec;
 
 /* --------------------------------------------------------------------------
@@ -425,7 +426,7 @@ int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
        handler->func = func;
        handler->data = data;
        mutex_lock(&ec->lock);
-       list_add_tail(&handler->node, &ec->list);
+       list_add(&handler->node, &ec->list);
        mutex_unlock(&ec->lock);
        return 0;
 }
@@ -440,7 +441,6 @@ void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)
                if (query_bit == handler->query_bit) {
                        list_del(&handler->node);
                        kfree(handler);
-                       break;
                }
        }
        mutex_unlock(&ec->lock);
@@ -680,32 +680,50 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
        status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe);
        if (ACPI_FAILURE(status))
                return status;
-
        /* Find and register all query methods */
        acpi_walk_namespace(ACPI_TYPE_METHOD, handle, 1,
                            acpi_ec_register_query_methods, ec, NULL);
-
        /* Use the global lock for all EC transactions? */
        acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
-
        ec->handle = handle;
-
-       printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
-                         ec->gpe, ec->command_addr, ec->data_addr);
-
        return AE_CTRL_TERMINATE;
 }
 
+static void ec_remove_handlers(struct acpi_ec *ec)
+{
+       if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle,
+                               ACPI_ADR_SPACE_EC, &acpi_ec_space_handler)))
+               printk(KERN_ERR PREFIX "failed to remove space handler\n");
+       if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe,
+                               &acpi_ec_gpe_handler)))
+               printk(KERN_ERR PREFIX "failed to remove gpe handler\n");
+       ec->handlers_installed = 0;
+}
+
 static int acpi_ec_add(struct acpi_device *device)
 {
        struct acpi_ec *ec = NULL;
 
        if (!device)
                return -EINVAL;
-
        strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
        strcpy(acpi_device_class(device), ACPI_EC_CLASS);
 
+       /* Check for boot EC */
+       if (boot_ec) {
+               if (boot_ec->handle == device->handle) {
+                       /* Pre-loaded EC from DSDT, just move pointer */
+                       ec = boot_ec;
+                       boot_ec = NULL;
+                       goto end;
+               } else if (boot_ec->handle == ACPI_ROOT_OBJECT) {
+                       /* ECDT-based EC, time to shut it down */
+                       ec_remove_handlers(boot_ec);
+                       kfree(boot_ec);
+                       first_ec = boot_ec = NULL;
+               }
+       }
+
        ec = make_acpi_ec();
        if (!ec)
                return -ENOMEM;
@@ -715,25 +733,14 @@ static int acpi_ec_add(struct acpi_device *device)
                kfree(ec);
                return -EINVAL;
        }
-
-       /* Check if we found the boot EC */
-       if (boot_ec) {
-               if (boot_ec->gpe == ec->gpe) {
-                       /* We might have incorrect info for GL at boot time */
-                       mutex_lock(&boot_ec->lock);
-                       boot_ec->global_lock = ec->global_lock;
-                       /* Copy handlers from new ec into boot ec */
-                       list_splice(&ec->list, &boot_ec->list);
-                       mutex_unlock(&boot_ec->lock);
-                       kfree(ec);
-                       ec = boot_ec;
-               }
-       } else
-               first_ec = ec;
        ec->handle = device->handle;
+      end:
+       if (!first_ec)
+               first_ec = ec;
        acpi_driver_data(device) = ec;
-
        acpi_ec_add_fs(device);
+       printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
+                         ec->gpe, ec->command_addr, ec->data_addr);
        return 0;
 }
 
@@ -756,10 +763,7 @@ static int acpi_ec_remove(struct acpi_device *device, int type)
        acpi_driver_data(device) = NULL;
        if (ec == first_ec)
                first_ec = NULL;
-
-       /* Don't touch boot EC */
-       if (boot_ec != ec)
-               kfree(ec);
+       kfree(ec);
        return 0;
 }
 
@@ -789,6 +793,8 @@ 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)
+               return 0;
        status = acpi_install_gpe_handler(NULL, ec->gpe,
                                          ACPI_GPE_EDGE_TRIGGERED,
                                          &acpi_ec_gpe_handler, ec);
@@ -807,6 +813,7 @@ static int ec_install_handlers(struct acpi_ec *ec)
                return -ENODEV;
        }
 
+       ec->handlers_installed = 1;
        return 0;
 }
 
@@ -823,41 +830,22 @@ static int acpi_ec_start(struct acpi_device *device)
        if (!ec)
                return -EINVAL;
 
-       /* Boot EC is already working */
-       if (ec != boot_ec)
-               ret = ec_install_handlers(ec);
+       ret = ec_install_handlers(ec);
 
        /* EC is fully operational, allow queries */
        atomic_set(&ec->query_pending, 0);
-
        return ret;
 }
 
 static int acpi_ec_stop(struct acpi_device *device, int type)
 {
-       acpi_status status;
        struct acpi_ec *ec;
-
        if (!device)
                return -EINVAL;
-
        ec = acpi_driver_data(device);
        if (!ec)
                return -EINVAL;
-
-       /* Don't touch boot EC */
-       if (ec == boot_ec)
-               return 0;
-
-       status = acpi_remove_address_space_handler(ec->handle,
-                                                  ACPI_ADR_SPACE_EC,
-                                                  &acpi_ec_space_handler);
-       if (ACPI_FAILURE(status))
-               return -ENODEV;
-
-       status = acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
-       if (ACPI_FAILURE(status))
-               return -ENODEV;
+       ec_remove_handlers(ec);
 
        return 0;
 }
@@ -877,7 +865,7 @@ int __init acpi_ec_ecdt_probe(void)
        status = acpi_get_table(ACPI_SIG_ECDT, 1,
                                (struct acpi_table_header **)&ecdt_ptr);
        if (ACPI_SUCCESS(status)) {
-               printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n\n");
+               printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n");
                boot_ec->command_addr = ecdt_ptr->control.address;
                boot_ec->data_addr = ecdt_ptr->data.address;
                boot_ec->gpe = ecdt_ptr->gpe;
@@ -899,7 +887,6 @@ int __init acpi_ec_ecdt_probe(void)
       error:
        kfree(boot_ec);
        boot_ec = NULL;
-
        return -ENODEV;
 }
 
index a1f87b5def2abfd6eb0f382b7b7f4b43de0c44ba..e41287815ea1c864176ad507110ff88a4eaf2894 100644 (file)
@@ -239,10 +239,8 @@ u32 acpi_ev_fixed_event_detect(void)
         * Read the fixed feature status and enable registers, as all the cases
         * depend on their values.  Ignore errors here.
         */
-       (void)acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
-                                   ACPI_REGISTER_PM1_STATUS, &fixed_status);
-       (void)acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
-                                   ACPI_REGISTER_PM1_ENABLE, &fixed_enable);
+       (void)acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, &fixed_status);
+       (void)acpi_hw_register_read(ACPI_REGISTER_PM1_ENABLE, &fixed_enable);
 
        ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
                          "Fixed Event Block: Enable %08X Status %08X\n",
index 1d371fa663f2492a23bb3ae7d4aa0585c80ba7c6..73f9c5fb1ba74b54022ed1490d8fc378c693b8af 100644 (file)
@@ -75,8 +75,7 @@ acpi_status acpi_hw_clear_acpi_status(void)
 
        lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
 
-       status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
-                                       ACPI_REGISTER_PM1_STATUS,
+       status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
                                        ACPI_BITMASK_ALL_FIXED_STATUS);
        if (ACPI_FAILURE(status)) {
                goto unlock_and_exit;
@@ -259,7 +258,7 @@ struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id)
  *
  ******************************************************************************/
 
-acpi_status acpi_get_register(u32 register_id, u32 * return_value)
+acpi_status acpi_get_register_unlocked(u32 register_id, u32 * return_value)
 {
        u32 register_value = 0;
        struct acpi_bit_register_info *bit_reg_info;
@@ -276,8 +275,7 @@ acpi_status acpi_get_register(u32 register_id, u32 * return_value)
 
        /* Read from the register */
 
-       status = acpi_hw_register_read(ACPI_MTX_LOCK,
-                                      bit_reg_info->parent_register,
+       status = acpi_hw_register_read(bit_reg_info->parent_register,
                                       &register_value);
 
        if (ACPI_SUCCESS(status)) {
@@ -298,6 +296,16 @@ acpi_status acpi_get_register(u32 register_id, u32 * return_value)
        return_ACPI_STATUS(status);
 }
 
+acpi_status acpi_get_register(u32 register_id, u32 * return_value)
+{
+       acpi_status status;
+       acpi_cpu_flags flags;
+       flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
+       status = acpi_get_register_unlocked(register_id, return_value);
+       acpi_os_release_lock(acpi_gbl_hardware_lock, flags);
+       return status;
+}
+
 ACPI_EXPORT_SYMBOL(acpi_get_register)
 
 /*******************************************************************************
@@ -335,8 +343,7 @@ acpi_status acpi_set_register(u32 register_id, u32 value)
 
        /* Always do a register read first so we can insert the new bits  */
 
-       status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
-                                      bit_reg_info->parent_register,
+       status = acpi_hw_register_read(bit_reg_info->parent_register,
                                       &register_value);
        if (ACPI_FAILURE(status)) {
                goto unlock_and_exit;
@@ -363,8 +370,7 @@ acpi_status acpi_set_register(u32 register_id, u32 value)
                                                   bit_reg_info->
                                                   access_bit_mask);
                if (value) {
-                       status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
-                                                       ACPI_REGISTER_PM1_STATUS,
+                       status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
                                                        (u16) value);
                        register_value = 0;
                }
@@ -377,8 +383,7 @@ acpi_status acpi_set_register(u32 register_id, u32 value)
                                           bit_reg_info->access_bit_mask,
                                           value);
 
-               status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
-                                               ACPI_REGISTER_PM1_ENABLE,
+               status = acpi_hw_register_write(ACPI_REGISTER_PM1_ENABLE,
                                                (u16) register_value);
                break;
 
@@ -397,15 +402,13 @@ acpi_status acpi_set_register(u32 register_id, u32 value)
                                           bit_reg_info->access_bit_mask,
                                           value);
 
-               status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
-                                               ACPI_REGISTER_PM1_CONTROL,
+               status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL,
                                                (u16) register_value);
                break;
 
        case ACPI_REGISTER_PM2_CONTROL:
 
-               status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
-                                              ACPI_REGISTER_PM2_CONTROL,
+               status = acpi_hw_register_read(ACPI_REGISTER_PM2_CONTROL,
                                               &register_value);
                if (ACPI_FAILURE(status)) {
                        goto unlock_and_exit;
@@ -430,8 +433,7 @@ acpi_status acpi_set_register(u32 register_id, u32 value)
                                                     xpm2_control_block.
                                                     address)));
 
-               status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
-                                               ACPI_REGISTER_PM2_CONTROL,
+               status = acpi_hw_register_write(ACPI_REGISTER_PM2_CONTROL,
                                                (u8) (register_value));
                break;
 
@@ -461,8 +463,7 @@ ACPI_EXPORT_SYMBOL(acpi_set_register)
  *
  * FUNCTION:    acpi_hw_register_read
  *
- * PARAMETERS:  use_lock            - Lock hardware? True/False
- *              register_id         - ACPI Register ID
+ * PARAMETERS:  register_id         - ACPI Register ID
  *              return_value        - Where the register value is returned
  *
  * RETURN:      Status and the value read.
@@ -471,19 +472,14 @@ ACPI_EXPORT_SYMBOL(acpi_set_register)
  *
  ******************************************************************************/
 acpi_status
-acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
+acpi_hw_register_read(u32 register_id, u32 * return_value)
 {
        u32 value1 = 0;
        u32 value2 = 0;
        acpi_status status;
-       acpi_cpu_flags lock_flags = 0;
 
        ACPI_FUNCTION_TRACE(hw_register_read);
 
-       if (ACPI_MTX_LOCK == use_lock) {
-               lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
-       }
-
        switch (register_id) {
        case ACPI_REGISTER_PM1_STATUS:  /* 16-bit access */
 
@@ -491,7 +487,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
                    acpi_hw_low_level_read(16, &value1,
                                           &acpi_gbl_FADT.xpm1a_event_block);
                if (ACPI_FAILURE(status)) {
-                       goto unlock_and_exit;
+                       goto exit;
                }
 
                /* PM1B is optional */
@@ -507,7 +503,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
                status =
                    acpi_hw_low_level_read(16, &value1, &acpi_gbl_xpm1a_enable);
                if (ACPI_FAILURE(status)) {
-                       goto unlock_and_exit;
+                       goto exit;
                }
 
                /* PM1B is optional */
@@ -523,7 +519,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
                    acpi_hw_low_level_read(16, &value1,
                                           &acpi_gbl_FADT.xpm1a_control_block);
                if (ACPI_FAILURE(status)) {
-                       goto unlock_and_exit;
+                       goto exit;
                }
 
                status =
@@ -558,10 +554,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
                break;
        }
 
-      unlock_and_exit:
-       if (ACPI_MTX_LOCK == use_lock) {
-               acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
-       }
+      exit:
 
        if (ACPI_SUCCESS(status)) {
                *return_value = value1;
@@ -574,8 +567,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
  *
  * FUNCTION:    acpi_hw_register_write
  *
- * PARAMETERS:  use_lock            - Lock hardware? True/False
- *              register_id         - ACPI Register ID
+ * PARAMETERS:  register_id         - ACPI Register ID
  *              Value               - The value to write
  *
  * RETURN:      Status
@@ -597,28 +589,22 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
  *
  ******************************************************************************/
 
-acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
+acpi_status acpi_hw_register_write(u32 register_id, u32 value)
 {
        acpi_status status;
-       acpi_cpu_flags lock_flags = 0;
        u32 read_value;
 
        ACPI_FUNCTION_TRACE(hw_register_write);
 
-       if (ACPI_MTX_LOCK == use_lock) {
-               lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
-       }
-
        switch (register_id) {
        case ACPI_REGISTER_PM1_STATUS:  /* 16-bit access */
 
                /* Perform a read first to preserve certain bits (per ACPI spec) */
 
-               status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
-                                              ACPI_REGISTER_PM1_STATUS,
+               status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS,
                                               &read_value);
                if (ACPI_FAILURE(status)) {
-                       goto unlock_and_exit;
+                       goto exit;
                }
 
                /* Insert the bits to be preserved */
@@ -632,7 +618,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
                    acpi_hw_low_level_write(16, value,
                                            &acpi_gbl_FADT.xpm1a_event_block);
                if (ACPI_FAILURE(status)) {
-                       goto unlock_and_exit;
+                       goto exit;
                }
 
                /* PM1B is optional */
@@ -647,7 +633,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
                status =
                    acpi_hw_low_level_write(16, value, &acpi_gbl_xpm1a_enable);
                if (ACPI_FAILURE(status)) {
-                       goto unlock_and_exit;
+                       goto exit;
                }
 
                /* PM1B is optional */
@@ -661,11 +647,10 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
                /*
                 * Perform a read first to preserve certain bits (per ACPI spec)
                 */
-               status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
-                                              ACPI_REGISTER_PM1_CONTROL,
+               status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
                                               &read_value);
                if (ACPI_FAILURE(status)) {
-                       goto unlock_and_exit;
+                       goto exit;
                }
 
                /* Insert the bits to be preserved */
@@ -679,7 +664,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
                    acpi_hw_low_level_write(16, value,
                                            &acpi_gbl_FADT.xpm1a_control_block);
                if (ACPI_FAILURE(status)) {
-                       goto unlock_and_exit;
+                       goto exit;
                }
 
                status =
@@ -728,11 +713,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
                break;
        }
 
-      unlock_and_exit:
-       if (ACPI_MTX_LOCK == use_lock) {
-               acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
-       }
-
+      exit:
        return_ACPI_STATUS(status);
 }
 
index cf69c0040a390d407d0cd2b2da6c4e21882e22af..81b2484297037e4b4c4e86e9b82d431e50021f00 100644 (file)
@@ -234,15 +234,11 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
                                "While executing method _SST"));
        }
 
-       /*
-        * 1) Disable/Clear all GPEs
-        */
+       /* Disable/Clear all GPEs */
+
        status = acpi_hw_disable_all_gpes();
-       if (ACPI_FAILURE(status)) {
-               return_ACPI_STATUS(status);
-       }
 
-       return_ACPI_STATUS(AE_OK);
+       return_ACPI_STATUS(status);
 }
 
 ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep)
@@ -313,8 +309,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
 
        /* Get current value of PM1A control */
 
-       status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
-                                      ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
+       status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
        if (ACPI_FAILURE(status)) {
                return_ACPI_STATUS(status);
        }
@@ -341,15 +336,13 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
 
        /* Write #1: fill in SLP_TYP data */
 
-       status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
-                                       ACPI_REGISTER_PM1A_CONTROL,
+       status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
                                        PM1Acontrol);
        if (ACPI_FAILURE(status)) {
                return_ACPI_STATUS(status);
        }
 
-       status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
-                                       ACPI_REGISTER_PM1B_CONTROL,
+       status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
                                        PM1Bcontrol);
        if (ACPI_FAILURE(status)) {
                return_ACPI_STATUS(status);
@@ -364,15 +357,13 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
 
        ACPI_FLUSH_CPU_CACHE();
 
-       status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
-                                       ACPI_REGISTER_PM1A_CONTROL,
+       status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
                                        PM1Acontrol);
        if (ACPI_FAILURE(status)) {
                return_ACPI_STATUS(status);
        }
 
-       status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
-                                       ACPI_REGISTER_PM1B_CONTROL,
+       status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
                                        PM1Bcontrol);
        if (ACPI_FAILURE(status)) {
                return_ACPI_STATUS(status);
@@ -392,8 +383,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
                 */
                acpi_os_stall(10000000);
 
-               status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
-                                               ACPI_REGISTER_PM1_CONTROL,
+               status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL,
                                                sleep_enable_reg_info->
                                                access_bit_mask);
                if (ACPI_FAILURE(status)) {
@@ -404,7 +394,8 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
        /* Wait until we enter sleep state */
 
        do {
-               status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value);
+               status = acpi_get_register_unlocked(ACPI_BITREG_WAKE_STATUS,
+                                                   &in_value);
                if (ACPI_FAILURE(status)) {
                        return_ACPI_STATUS(status);
                }
@@ -520,8 +511,7 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
 
                /* Get current value of PM1A control */
 
-               status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
-                                              ACPI_REGISTER_PM1_CONTROL,
+               status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
                                               &PM1Acontrol);
                if (ACPI_SUCCESS(status)) {
 
@@ -543,11 +533,9 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
 
                        /* Just ignore any errors */
 
-                       (void)acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
-                                                    ACPI_REGISTER_PM1A_CONTROL,
+                       (void)acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
                                                     PM1Acontrol);
-                       (void)acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
-                                                    ACPI_REGISTER_PM1B_CONTROL,
+                       (void)acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
                                                     PM1Bcontrol);
                }
        }
index 352cf81af5818de3569848038714052cbfd0353d..aabc6ca4a81c72463529c3e711b012f8b6e909a7 100644 (file)
@@ -1042,14 +1042,6 @@ static int __init acpi_wake_gpes_always_on_setup(char *str)
 
 __setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup);
 
-/*
- * max_cstate is defined in the base kernel so modules can
- * change it w/o depending on the state of the processor module.
- */
-unsigned int max_cstate = ACPI_PROCESSOR_MAX_POWER;
-
-EXPORT_SYMBOL(max_cstate);
-
 /*
  * Acquire a spinlock.
  *
index 9f11dc296cdd7bc29f5545cd8524eb03ede594e3..235a51e328c3467522e16ac1d4bb26c5a7227537 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/seq_file.h>
 #include <linux/dmi.h>
 #include <linux/moduleparam.h>
+#include <linux/cpuidle.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
@@ -421,12 +422,6 @@ static int map_lsapic_id(struct acpi_subtable_header *entry,
        return 0;
 }
 
-#ifdef CONFIG_IA64
-#define arch_cpu_to_apicid     ia64_cpu_to_sapicid
-#else
-#define arch_cpu_to_apicid     x86_cpu_to_apicid
-#endif
-
 static int map_madt_entry(u32 acpi_id)
 {
        unsigned long madt_end, entry;
@@ -500,7 +495,7 @@ static int get_cpu_id(acpi_handle handle, u32 acpi_id)
                return apic_id;
 
        for (i = 0; i < NR_CPUS; ++i) {
-               if (arch_cpu_to_apicid[i] == apic_id)
+               if (cpu_physical_id(i) == apic_id)
                        return i;
        }
        return -1;
@@ -1049,11 +1044,13 @@ static int __init acpi_processor_init(void)
                return -ENOMEM;
        acpi_processor_dir->owner = THIS_MODULE;
 
+       result = cpuidle_register_driver(&acpi_idle_driver);
+       if (result < 0)
+               goto out_proc;
+
        result = acpi_bus_register_driver(&acpi_processor_driver);
-       if (result < 0) {
-               remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
-               return result;
-       }
+       if (result < 0)
+               goto out_cpuidle;
 
        acpi_processor_install_hotplug_notify();
 
@@ -1062,11 +1059,18 @@ static int __init acpi_processor_init(void)
        acpi_processor_ppc_init();
 
        return 0;
+
+out_cpuidle:
+       cpuidle_unregister_driver(&acpi_idle_driver);
+
+out_proc:
+       remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
+
+       return result;
 }
 
 static void __exit acpi_processor_exit(void)
 {
-
        acpi_processor_ppc_exit();
 
        acpi_thermal_cpufreq_exit();
@@ -1075,6 +1079,8 @@ static void __exit acpi_processor_exit(void)
 
        acpi_bus_unregister_driver(&acpi_processor_driver);
 
+       cpuidle_unregister_driver(&acpi_idle_driver);
+
        remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
 
        return;
index 1f6fb38de017fc2c16dcd067b96efec802b1e155..f996d0e37689c402642a0c884b0126ad15a505bc 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/sched.h>       /* need_resched() */
 #include <linux/latency.h>
 #include <linux/clockchips.h>
+#include <linux/cpuidle.h>
 
 /*
  * Include the apic definitions for x86 to have the APIC timer related defines
@@ -64,14 +65,22 @@ ACPI_MODULE_NAME("processor_idle");
 #define ACPI_PROCESSOR_FILE_POWER      "power"
 #define US_TO_PM_TIMER_TICKS(t)                ((t * (PM_TIMER_FREQUENCY/1000)) / 1000)
 #define PM_TIMER_TICK_NS               (1000000000ULL/PM_TIMER_FREQUENCY)
+#ifndef CONFIG_CPU_IDLE
 #define C2_OVERHEAD                    4       /* 1us (3.579 ticks per us) */
 #define C3_OVERHEAD                    4       /* 1us (3.579 ticks per us) */
 static void (*pm_idle_save) (void) __read_mostly;
-module_param(max_cstate, uint, 0644);
+#else
+#define C2_OVERHEAD                    1       /* 1us */
+#define C3_OVERHEAD                    1       /* 1us */
+#endif
+#define PM_TIMER_TICKS_TO_US(p)                (((p) * 1000)/(PM_TIMER_FREQUENCY/1000))
 
+static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER;
+module_param(max_cstate, uint, 0000);
 static unsigned int nocst __read_mostly;
 module_param(nocst, uint, 0000);
 
+#ifndef CONFIG_CPU_IDLE
 /*
  * bm_history -- bit-mask with a bit per jiffy of bus-master activity
  * 1000 HZ: 0xFFFFFFFF: 32 jiffies = 32ms
@@ -82,9 +91,10 @@ module_param(nocst, uint, 0000);
 static unsigned int bm_history __read_mostly =
     (HZ >= 800 ? 0xFFFFFFFF : ((1U << (HZ / 25)) - 1));
 module_param(bm_history, uint, 0644);
-/* --------------------------------------------------------------------------
-                                Power Management
-   -------------------------------------------------------------------------- */
+
+static int acpi_processor_set_power_policy(struct acpi_processor *pr);
+
+#endif
 
 /*
  * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3.
@@ -177,6 +187,18 @@ static inline u32 ticks_elapsed(u32 t1, u32 t2)
                return ((0xFFFFFFFF - t1) + t2);
 }
 
+static inline u32 ticks_elapsed_in_us(u32 t1, u32 t2)
+{
+       if (t2 >= t1)
+               return PM_TIMER_TICKS_TO_US(t2 - t1);
+       else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER))
+               return PM_TIMER_TICKS_TO_US(((0x00FFFFFF - t1) + t2) & 0x00FFFFFF);
+       else
+               return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2);
+}
+
+#ifndef CONFIG_CPU_IDLE
+
 static void
 acpi_processor_power_activate(struct acpi_processor *pr,
                              struct acpi_processor_cx *new)
@@ -248,6 +270,7 @@ static void acpi_cstate_enter(struct acpi_processor_cx *cstate)
                unused = inl(acpi_gbl_FADT.xpm_timer_block.address);
        }
 }
+#endif /* !CONFIG_CPU_IDLE */
 
 #ifdef ARCH_APICTIMER_STOPS_ON_C3
 
@@ -330,6 +353,7 @@ int acpi_processor_resume(struct acpi_device * device)
        return 0;
 }
 
+#ifndef CONFIG_CPU_IDLE
 static void acpi_processor_idle(void)
 {
        struct acpi_processor *pr = NULL;
@@ -427,7 +451,7 @@ static void acpi_processor_idle(void)
         * an SMP system. We do it here instead of doing it at _CST/P_LVL
         * detection phase, to work cleanly with logical CPU hotplug.
         */
-       if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) && 
+       if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) &&
            !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
                cx = &pr->power.states[ACPI_STATE_C1];
 #endif
@@ -727,6 +751,7 @@ static int acpi_processor_set_power_policy(struct acpi_processor *pr)
 
        return 0;
 }
+#endif /* !CONFIG_CPU_IDLE */
 
 static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
 {
@@ -744,7 +769,7 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
 #ifndef CONFIG_HOTPLUG_CPU
        /*
         * Check for P_LVL2_UP flag before entering C2 and above on
-        * an SMP system. 
+        * an SMP system.
         */
        if ((num_online_cpus() > 1) &&
            !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
@@ -945,7 +970,12 @@ static void acpi_processor_power_verify_c2(struct acpi_processor_cx *cx)
         * Normalize the C2 latency to expidite policy
         */
        cx->valid = 1;
+
+#ifndef CONFIG_CPU_IDLE
        cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency);
+#else
+       cx->latency_ticks = cx->latency;
+#endif
 
        return;
 }
@@ -1025,7 +1055,12 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
         * use this in our C3 policy
         */
        cx->valid = 1;
+
+#ifndef CONFIG_CPU_IDLE
        cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency);
+#else
+       cx->latency_ticks = cx->latency;
+#endif
 
        return;
 }
@@ -1090,6 +1125,7 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr)
 
        pr->power.count = acpi_processor_power_verify(pr);
 
+#ifndef CONFIG_CPU_IDLE
        /*
         * Set Default Policy
         * ------------------
@@ -1101,6 +1137,7 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr)
        result = acpi_processor_set_power_policy(pr);
        if (result)
                return result;
+#endif
 
        /*
         * if one state of type C2 or C3 is available, mark this
@@ -1117,35 +1154,6 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr)
        return 0;
 }
 
-int acpi_processor_cst_has_changed(struct acpi_processor *pr)
-{
-       int result = 0;
-
-
-       if (!pr)
-               return -EINVAL;
-
-       if (nocst) {
-               return -ENODEV;
-       }
-
-       if (!pr->flags.power_setup_done)
-               return -ENODEV;
-
-       /* Fall back to the default idle loop */
-       pm_idle = pm_idle_save;
-       synchronize_sched();    /* Relies on interrupts forcing exit from idle. */
-
-       pr->flags.power = 0;
-       result = acpi_processor_get_power_info(pr);
-       if ((pr->flags.power == 1) && (pr->flags.power_setup_done))
-               pm_idle = acpi_processor_idle;
-
-       return result;
-}
-
-/* proc interface */
-
 static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)
 {
        struct acpi_processor *pr = seq->private;
@@ -1227,6 +1235,35 @@ static const struct file_operations acpi_processor_power_fops = {
        .release = single_release,
 };
 
+#ifndef CONFIG_CPU_IDLE
+
+int acpi_processor_cst_has_changed(struct acpi_processor *pr)
+{
+       int result = 0;
+
+
+       if (!pr)
+               return -EINVAL;
+
+       if (nocst) {
+               return -ENODEV;
+       }
+
+       if (!pr->flags.power_setup_done)
+               return -ENODEV;
+
+       /* Fall back to the default idle loop */
+       pm_idle = pm_idle_save;
+       synchronize_sched();    /* Relies on interrupts forcing exit from idle. */
+
+       pr->flags.power = 0;
+       result = acpi_processor_get_power_info(pr);
+       if ((pr->flags.power == 1) && (pr->flags.power_setup_done))
+               pm_idle = acpi_processor_idle;
+
+       return result;
+}
+
 #ifdef CONFIG_SMP
 static void smp_callback(void *v)
 {
@@ -1249,7 +1286,366 @@ static int acpi_processor_latency_notify(struct notifier_block *b,
 static struct notifier_block acpi_processor_latency_notifier = {
        .notifier_call = acpi_processor_latency_notify,
 };
+
+#endif
+
+#else /* CONFIG_CPU_IDLE */
+
+/**
+ * acpi_idle_bm_check - checks if bus master activity was detected
+ */
+static int acpi_idle_bm_check(void)
+{
+       u32 bm_status = 0;
+
+       acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
+       if (bm_status)
+               acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
+       /*
+        * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect
+        * the true state of bus mastering activity; forcing us to
+        * manually check the BMIDEA bit of each IDE channel.
+        */
+       else if (errata.piix4.bmisx) {
+               if ((inb_p(errata.piix4.bmisx + 0x02) & 0x01)
+                   || (inb_p(errata.piix4.bmisx + 0x0A) & 0x01))
+                       bm_status = 1;
+       }
+       return bm_status;
+}
+
+/**
+ * acpi_idle_update_bm_rld - updates the BM_RLD bit depending on target state
+ * @pr: the processor
+ * @target: the new target state
+ */
+static inline void acpi_idle_update_bm_rld(struct acpi_processor *pr,
+                                          struct acpi_processor_cx *target)
+{
+       if (pr->flags.bm_rld_set && target->type != ACPI_STATE_C3) {
+               acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
+               pr->flags.bm_rld_set = 0;
+       }
+
+       if (!pr->flags.bm_rld_set && target->type == ACPI_STATE_C3) {
+               acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
+               pr->flags.bm_rld_set = 1;
+       }
+}
+
+/**
+ * acpi_idle_do_entry - a helper function that does C2 and C3 type entry
+ * @cx: cstate data
+ */
+static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx)
+{
+       if (cx->space_id == ACPI_CSTATE_FFH) {
+               /* Call into architectural FFH based C-state */
+               acpi_processor_ffh_cstate_enter(cx);
+       } else {
+               int unused;
+               /* IO port based C-state */
+               inb(cx->address);
+               /* Dummy wait op - must do something useless after P_LVL2 read
+                  because chipsets cannot guarantee that STPCLK# signal
+                  gets asserted in time to freeze execution properly. */
+               unused = inl(acpi_gbl_FADT.xpm_timer_block.address);
+       }
+}
+
+/**
+ * acpi_idle_enter_c1 - enters an ACPI C1 state-type
+ * @dev: the target CPU
+ * @state: the state data
+ *
+ * This is equivalent to the HALT instruction.
+ */
+static int acpi_idle_enter_c1(struct cpuidle_device *dev,
+                             struct cpuidle_state *state)
+{
+       struct acpi_processor *pr;
+       struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
+       pr = processors[smp_processor_id()];
+
+       if (unlikely(!pr))
+               return 0;
+
+       if (pr->flags.bm_check)
+               acpi_idle_update_bm_rld(pr, cx);
+
+       current_thread_info()->status &= ~TS_POLLING;
+       /*
+        * TS_POLLING-cleared state must be visible before we test
+        * NEED_RESCHED:
+        */
+       smp_mb();
+       if (!need_resched())
+               safe_halt();
+       current_thread_info()->status |= TS_POLLING;
+
+       cx->usage++;
+
+       return 0;
+}
+
+/**
+ * acpi_idle_enter_simple - enters an ACPI state without BM handling
+ * @dev: the target CPU
+ * @state: the state data
+ */
+static int acpi_idle_enter_simple(struct cpuidle_device *dev,
+                                 struct cpuidle_state *state)
+{
+       struct acpi_processor *pr;
+       struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
+       u32 t1, t2;
+       pr = processors[smp_processor_id()];
+
+       if (unlikely(!pr))
+               return 0;
+
+       if (acpi_idle_suspend)
+               return(acpi_idle_enter_c1(dev, state));
+
+       if (pr->flags.bm_check)
+               acpi_idle_update_bm_rld(pr, cx);
+
+       local_irq_disable();
+       current_thread_info()->status &= ~TS_POLLING;
+       /*
+        * TS_POLLING-cleared state must be visible before we test
+        * NEED_RESCHED:
+        */
+       smp_mb();
+
+       if (unlikely(need_resched())) {
+               current_thread_info()->status |= TS_POLLING;
+               local_irq_enable();
+               return 0;
+       }
+
+       if (cx->type == ACPI_STATE_C3)
+               ACPI_FLUSH_CPU_CACHE();
+
+       t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+       acpi_state_timer_broadcast(pr, cx, 1);
+       acpi_idle_do_entry(cx);
+       t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+
+#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
+       /* TSC could halt in idle, so notify users */
+       mark_tsc_unstable("TSC halts in idle");;
+#endif
+
+       local_irq_enable();
+       current_thread_info()->status |= TS_POLLING;
+
+       cx->usage++;
+
+       acpi_state_timer_broadcast(pr, cx, 0);
+       cx->time += ticks_elapsed(t1, t2);
+       return ticks_elapsed_in_us(t1, t2);
+}
+
+static int c3_cpu_count;
+static DEFINE_SPINLOCK(c3_lock);
+
+/**
+ * acpi_idle_enter_bm - enters C3 with proper BM handling
+ * @dev: the target CPU
+ * @state: the state data
+ *
+ * If BM is detected, the deepest non-C3 idle state is entered instead.
+ */
+static int acpi_idle_enter_bm(struct cpuidle_device *dev,
+                             struct cpuidle_state *state)
+{
+       struct acpi_processor *pr;
+       struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
+       u32 t1, t2;
+       pr = processors[smp_processor_id()];
+
+       if (unlikely(!pr))
+               return 0;
+
+       if (acpi_idle_suspend)
+               return(acpi_idle_enter_c1(dev, state));
+
+       local_irq_disable();
+       current_thread_info()->status &= ~TS_POLLING;
+       /*
+        * TS_POLLING-cleared state must be visible before we test
+        * NEED_RESCHED:
+        */
+       smp_mb();
+
+       if (unlikely(need_resched())) {
+               current_thread_info()->status |= TS_POLLING;
+               local_irq_enable();
+               return 0;
+       }
+
+       /*
+        * Must be done before busmaster disable as we might need to
+        * access HPET !
+        */
+       acpi_state_timer_broadcast(pr, cx, 1);
+
+       if (acpi_idle_bm_check()) {
+               cx = pr->power.bm_state;
+
+               acpi_idle_update_bm_rld(pr, cx);
+
+               t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+               acpi_idle_do_entry(cx);
+               t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+       } else {
+               acpi_idle_update_bm_rld(pr, cx);
+
+               spin_lock(&c3_lock);
+               c3_cpu_count++;
+               /* Disable bus master arbitration when all CPUs are in C3 */
+               if (c3_cpu_count == num_online_cpus())
+                       acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
+               spin_unlock(&c3_lock);
+
+               t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+               acpi_idle_do_entry(cx);
+               t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+
+               spin_lock(&c3_lock);
+               /* Re-enable bus master arbitration */
+               if (c3_cpu_count == num_online_cpus())
+                       acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
+               c3_cpu_count--;
+               spin_unlock(&c3_lock);
+       }
+
+#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
+       /* TSC could halt in idle, so notify users */
+       mark_tsc_unstable("TSC halts in idle");
+#endif
+
+       local_irq_enable();
+       current_thread_info()->status |= TS_POLLING;
+
+       cx->usage++;
+
+       acpi_state_timer_broadcast(pr, cx, 0);
+       cx->time += ticks_elapsed(t1, t2);
+       return ticks_elapsed_in_us(t1, t2);
+}
+
+struct cpuidle_driver acpi_idle_driver = {
+       .name =         "acpi_idle",
+       .owner =        THIS_MODULE,
+};
+
+/**
+ * acpi_processor_setup_cpuidle - prepares and configures CPUIDLE
+ * @pr: the ACPI processor
+ */
+static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
+{
+       int i, count = 0;
+       struct acpi_processor_cx *cx;
+       struct cpuidle_state *state;
+       struct cpuidle_device *dev = &pr->power.dev;
+
+       if (!pr->flags.power_setup_done)
+               return -EINVAL;
+
+       if (pr->flags.power == 0) {
+               return -EINVAL;
+       }
+
+       for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) {
+               cx = &pr->power.states[i];
+               state = &dev->states[count];
+
+               if (!cx->valid)
+                       continue;
+
+#ifdef CONFIG_HOTPLUG_CPU
+               if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) &&
+                   !pr->flags.has_cst &&
+                   !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
+                       continue;
 #endif
+               cpuidle_set_statedata(state, cx);
+
+               snprintf(state->name, CPUIDLE_NAME_LEN, "C%d", i);
+               state->exit_latency = cx->latency;
+               state->target_residency = cx->latency * 6;
+               state->power_usage = cx->power;
+
+               state->flags = 0;
+               switch (cx->type) {
+                       case ACPI_STATE_C1:
+                       state->flags |= CPUIDLE_FLAG_SHALLOW;
+                       state->enter = acpi_idle_enter_c1;
+                       break;
+
+                       case ACPI_STATE_C2:
+                       state->flags |= CPUIDLE_FLAG_BALANCED;
+                       state->flags |= CPUIDLE_FLAG_TIME_VALID;
+                       state->enter = acpi_idle_enter_simple;
+                       break;
+
+                       case ACPI_STATE_C3:
+                       state->flags |= CPUIDLE_FLAG_DEEP;
+                       state->flags |= CPUIDLE_FLAG_TIME_VALID;
+                       state->flags |= CPUIDLE_FLAG_CHECK_BM;
+                       state->enter = pr->flags.bm_check ?
+                                       acpi_idle_enter_bm :
+                                       acpi_idle_enter_simple;
+                       break;
+               }
+
+               count++;
+       }
+
+       dev->state_count = count;
+
+       if (!count)
+               return -EINVAL;
+
+       /* find the deepest state that can handle active BM */
+       if (pr->flags.bm_check) {
+               for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++)
+                       if (pr->power.states[i].type == ACPI_STATE_C3)
+                               break;
+               pr->power.bm_state = &pr->power.states[i-1];
+       }
+
+       return 0;
+}
+
+int acpi_processor_cst_has_changed(struct acpi_processor *pr)
+{
+       int ret;
+
+       if (!pr)
+               return -EINVAL;
+
+       if (nocst) {
+               return -ENODEV;
+       }
+
+       if (!pr->flags.power_setup_done)
+               return -ENODEV;
+
+       cpuidle_pause_and_lock();
+       cpuidle_disable_device(&pr->power.dev);
+       acpi_processor_get_power_info(pr);
+       acpi_processor_setup_cpuidle(pr);
+       ret = cpuidle_enable_device(&pr->power.dev);
+       cpuidle_resume_and_unlock();
+
+       return ret;
+}
+
+#endif /* CONFIG_CPU_IDLE */
 
 int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
                              struct acpi_device *device)
@@ -1267,7 +1663,7 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
                               "ACPI: processor limited to max C-state %d\n",
                               max_cstate);
                first_run++;
-#ifdef CONFIG_SMP
+#if !defined (CONFIG_CPU_IDLE) && defined (CONFIG_SMP)
                register_latency_notifier(&acpi_processor_latency_notifier);
 #endif
        }
@@ -1285,6 +1681,7 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
        }
 
        acpi_processor_get_power_info(pr);
+       pr->flags.power_setup_done = 1;
 
        /*
         * Install the idle handler if processor power management is supported.
@@ -1292,6 +1689,13 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
         * platforms that only support C1.
         */
        if ((pr->flags.power) && (!boot_option_idle_override)) {
+#ifdef CONFIG_CPU_IDLE
+               acpi_processor_setup_cpuidle(pr);
+               pr->power.dev.cpu = pr->id;
+               if (cpuidle_register_device(&pr->power.dev))
+                       return -EIO;
+#endif
+
                printk(KERN_INFO PREFIX "CPU%d (power states:", pr->id);
                for (i = 1; i <= pr->power.count; i++)
                        if (pr->power.states[i].valid)
@@ -1299,10 +1703,12 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
                                       pr->power.states[i].type);
                printk(")\n");
 
+#ifndef CONFIG_CPU_IDLE
                if (pr->id == 0) {
                        pm_idle_save = pm_idle;
                        pm_idle = acpi_processor_idle;
                }
+#endif
        }
 
        /* 'power' [R] */
@@ -1316,21 +1722,24 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
                entry->owner = THIS_MODULE;
        }
 
-       pr->flags.power_setup_done = 1;
-
        return 0;
 }
 
 int acpi_processor_power_exit(struct acpi_processor *pr,
                              struct acpi_device *device)
 {
-
+#ifdef CONFIG_CPU_IDLE
+       if ((pr->flags.power) && (!boot_option_idle_override))
+               cpuidle_unregister_device(&pr->power.dev);
+#endif
        pr->flags.power_setup_done = 0;
 
        if (acpi_device_dir(device))
                remove_proc_entry(ACPI_PROCESSOR_FILE_POWER,
                                  acpi_device_dir(device));
 
+#ifndef CONFIG_CPU_IDLE
+
        /* Unregister the idle handler when processor #0 is removed. */
        if (pr->id == 0) {
                pm_idle = pm_idle_save;
@@ -1345,6 +1754,7 @@ int acpi_processor_power_exit(struct acpi_processor *pr,
                unregister_latency_notifier(&acpi_processor_latency_notifier);
 #endif
        }
+#endif
 
        return 0;
 }
index a578986e3214fc9b479ef6978d645e9002137bed..90fd09c65f95eed69d07fc624277d20fb9c44f8b 100644 (file)
@@ -1,6 +1,8 @@
 /*
- *  acpi_sbs.c - ACPI Smart Battery System Driver ($Revision: 1.16 $)
+ *  sbs.c - ACPI Smart Battery System Driver ($Revision: 2.0 $)
  *
+ *  Copyright (c) 2007 Alexey Starikovskiy <astarikovskiy@suse.de>
+ *  Copyright (c) 2005-2007 Vladimir Lebedev <vladimir.p.lebedev@intel.com>
  *  Copyright (c) 2005 Rich Townsend <rhdt@bartol.udel.edu>
  *
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
+
+#ifdef CONFIG_ACPI_PROCFS
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <asm/uaccess.h>
+#endif
+
 #include <linux/acpi.h>
 #include <linux/timer.h>
 #include <linux/jiffies.h>
 #include <linux/delay.h>
 
-#define ACPI_SBS_COMPONENT             0x00080000
+#include <linux/power_supply.h>
+
+#include "sbshc.h"
+
 #define ACPI_SBS_CLASS                 "sbs"
 #define ACPI_AC_CLASS                  "ac_adapter"
 #define ACPI_BATTERY_CLASS             "battery"
 #define ACPI_SBS_FILE_ALARM            "alarm"
 #define ACPI_BATTERY_DIR_NAME          "BAT%i"
 #define ACPI_AC_DIR_NAME               "AC0"
-#define ACPI_SBC_SMBUS_ADDR            0x9
-#define ACPI_SBSM_SMBUS_ADDR           0xa
-#define ACPI_SB_SMBUS_ADDR             0xb
-#define ACPI_SBS_AC_NOTIFY_STATUS      0x80
-#define ACPI_SBS_BATTERY_NOTIFY_STATUS 0x80
-#define ACPI_SBS_BATTERY_NOTIFY_INFO   0x81
 
-#define _COMPONENT                     ACPI_SBS_COMPONENT
+enum acpi_sbs_device_addr {
+       ACPI_SBS_CHARGER = 0x9,
+       ACPI_SBS_MANAGER = 0xa,
+       ACPI_SBS_BATTERY = 0xb,
+};
 
-ACPI_MODULE_NAME("sbs");
+#define ACPI_SBS_NOTIFY_STATUS         0x80
+#define ACPI_SBS_NOTIFY_INFO           0x81
 
-MODULE_AUTHOR("Rich Townsend");
+MODULE_AUTHOR("Alexey Starikovskiy <astarikovskiy@suse.de>");
 MODULE_DESCRIPTION("Smart Battery System ACPI interface driver");
 MODULE_LICENSE("GPL");
 
-#define        xmsleep(t)      msleep(t)
-
-#define ACPI_EC_SMB_PRTCL      0x00    /* protocol, PEC */
-
-#define ACPI_EC_SMB_STS                0x01    /* status */
-#define ACPI_EC_SMB_ADDR       0x02    /* address */
-#define ACPI_EC_SMB_CMD                0x03    /* command */
-#define ACPI_EC_SMB_DATA       0x04    /* 32 data registers */
-#define ACPI_EC_SMB_BCNT       0x24    /* number of data bytes */
-
-#define ACPI_EC_SMB_STS_DONE   0x80
-#define ACPI_EC_SMB_STS_STATUS 0x1f
-
-#define ACPI_EC_SMB_PRTCL_WRITE                0x00
-#define ACPI_EC_SMB_PRTCL_READ         0x01
-#define ACPI_EC_SMB_PRTCL_WORD_DATA    0x08
-#define ACPI_EC_SMB_PRTCL_BLOCK_DATA   0x0a
-
-#define ACPI_EC_SMB_TRANSACTION_SLEEP  1
-#define ACPI_EC_SMB_ACCESS_SLEEP1      1
-#define ACPI_EC_SMB_ACCESS_SLEEP2      10
-
-#define        DEF_CAPACITY_UNIT       3
-#define        MAH_CAPACITY_UNIT       1
-#define        MWH_CAPACITY_UNIT       2
-#define        CAPACITY_UNIT           DEF_CAPACITY_UNIT
-
-#define        REQUEST_UPDATE_MODE     1
-#define        QUEUE_UPDATE_MODE       2
-
-#define        DATA_TYPE_COMMON        0
-#define        DATA_TYPE_INFO          1
-#define        DATA_TYPE_STATE         2
-#define        DATA_TYPE_ALARM         3
-#define        DATA_TYPE_AC_STATE      4
+static unsigned int cache_time = 1000;
+module_param(cache_time, uint, 0644);
+MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
 
 extern struct proc_dir_entry *acpi_lock_ac_dir(void);
 extern struct proc_dir_entry *acpi_lock_battery_dir(void);
 extern void acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir);
 extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
 
-#define        MAX_SBS_BAT                     4
+#define MAX_SBS_BAT                    4
 #define ACPI_SBS_BLOCK_MAX             32
 
-#define ACPI_SBS_SMBUS_READ            1
-#define ACPI_SBS_SMBUS_WRITE           2
-
-#define ACPI_SBS_WORD_DATA             1
-#define ACPI_SBS_BLOCK_DATA            2
-
-#define        UPDATE_DELAY    10
-
-/* 0 - every time, > 0 - by update_time */
-static unsigned int update_time = 120;
-
-static unsigned int capacity_mode = CAPACITY_UNIT;
-
-module_param(update_time, uint, 0644);
-module_param(capacity_mode, uint, 0444);
-
-static int acpi_sbs_add(struct acpi_device *device);
-static int acpi_sbs_remove(struct acpi_device *device, int type);
-static int acpi_sbs_resume(struct acpi_device *device);
-
 static const struct acpi_device_id sbs_device_ids[] = {
-       {"ACPI0001", 0},
-       {"ACPI0005", 0},
+       {"ACPI0002", 0},
        {"", 0},
 };
 MODULE_DEVICE_TABLE(acpi, sbs_device_ids);
 
-static struct acpi_driver acpi_sbs_driver = {
-       .name = "sbs",
-       .class = ACPI_SBS_CLASS,
-       .ids = sbs_device_ids,
-       .ops = {
-               .add = acpi_sbs_add,
-               .remove = acpi_sbs_remove,
-               .resume = acpi_sbs_resume,
-               },
-};
-
-struct acpi_ac {
-       int ac_present;
-};
-
-struct acpi_battery_info {
-       int capacity_mode;
-       s16 full_charge_capacity;
-       s16 design_capacity;
-       s16 design_voltage;
-       int vscale;
-       int ipscale;
-       s16 serial_number;
-       char manufacturer_name[ACPI_SBS_BLOCK_MAX + 3];
-       char device_name[ACPI_SBS_BLOCK_MAX + 3];
-       char device_chemistry[ACPI_SBS_BLOCK_MAX + 3];
-};
-
-struct acpi_battery_state {
-       s16 voltage;
-       s16 amperage;
-       s16 remaining_capacity;
-       s16 battery_state;
-};
-
-struct acpi_battery_alarm {
-       s16 remaining_capacity;
-};
-
 struct acpi_battery {
-       int alive;
-       int id;
-       int init_state;
-       int battery_present;
+       struct power_supply bat;
        struct acpi_sbs *sbs;
-       struct acpi_battery_info info;
-       struct acpi_battery_state state;
-       struct acpi_battery_alarm alarm;
-       struct proc_dir_entry *battery_entry;
+#ifdef CONFIG_ACPI_PROCFS
+       struct proc_dir_entry *proc_entry;
+#endif
+       unsigned long update_time;
+       char name[8];
+       char manufacturer_name[ACPI_SBS_BLOCK_MAX];
+       char device_name[ACPI_SBS_BLOCK_MAX];
+       char device_chemistry[ACPI_SBS_BLOCK_MAX];
+       u16 alarm_capacity;
+       u16 full_charge_capacity;
+       u16 design_capacity;
+       u16 design_voltage;
+       u16 serial_number;
+       u16 cycle_count;
+       u16 temp_now;
+       u16 voltage_now;
+       s16 current_now;
+       s16 current_avg;
+       u16 capacity_now;
+       u16 state_of_charge;
+       u16 state;
+       u16 mode;
+       u16 spec;
+       u8 id;
+       u8 present:1;
 };
 
+#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
+
 struct acpi_sbs {
-       int base;
+       struct power_supply charger;
        struct acpi_device *device;
-       struct mutex mutex;
-       int sbsm_present;
-       int sbsm_batteries_supported;
-       struct proc_dir_entry *ac_entry;
-       struct acpi_ac ac;
+       struct acpi_smb_hc *hc;
+       struct mutex lock;
+#ifdef CONFIG_ACPI_PROCFS
+       struct proc_dir_entry *charger_entry;
+#endif
        struct acpi_battery battery[MAX_SBS_BAT];
-       int zombie;
-       struct timer_list update_timer;
-       int run_cnt;
-       int update_proc_flg;
+       u8 batteries_supported:4;
+       u8 manager_present:1;
+       u8 charger_present:1;
 };
 
-static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type);
-static void acpi_sbs_update_time(void *data);
+#define to_acpi_sbs(x) container_of(x, struct acpi_sbs, charger)
 
-union sbs_rw_data {
-       u16 word;
-       u8 block[ACPI_SBS_BLOCK_MAX + 2];
-};
-
-static int acpi_ec_sbs_access(struct acpi_sbs *sbs, u16 addr,
-                             char read_write, u8 command, int size,
-                             union sbs_rw_data *data);
-
-/* --------------------------------------------------------------------------
-                               SMBus Communication
-   -------------------------------------------------------------------------- */
-
-static int acpi_ec_sbs_read(struct acpi_sbs *sbs, u8 address, u8 * data)
-{
-       u8 val;
-       int err;
-
-       err = ec_read(sbs->base + address, &val);
-       if (!err) {
-               *data = val;
-       }
-       xmsleep(ACPI_EC_SMB_TRANSACTION_SLEEP);
-       return (err);
-}
-
-static int acpi_ec_sbs_write(struct acpi_sbs *sbs, u8 address, u8 data)
+static inline int battery_scale(int log)
 {
-       int err;
-
-       err = ec_write(sbs->base + address, data);
-       return (err);
-}
-
-static int
-acpi_ec_sbs_access(struct acpi_sbs *sbs, u16 addr,
-                  char read_write, u8 command, int size,
-                  union sbs_rw_data *data)
-{
-       unsigned char protocol, len = 0, temp[2] = { 0, 0 };
-       int i;
-
-       if (read_write == ACPI_SBS_SMBUS_READ) {
-               protocol = ACPI_EC_SMB_PRTCL_READ;
-       } else {
-               protocol = ACPI_EC_SMB_PRTCL_WRITE;
-       }
-
-       switch (size) {
-
-       case ACPI_SBS_WORD_DATA:
-               acpi_ec_sbs_write(sbs, ACPI_EC_SMB_CMD, command);
-               if (read_write == ACPI_SBS_SMBUS_WRITE) {
-                       acpi_ec_sbs_write(sbs, ACPI_EC_SMB_DATA, data->word);
-                       acpi_ec_sbs_write(sbs, ACPI_EC_SMB_DATA + 1,
-                                         data->word >> 8);
-               }
-               protocol |= ACPI_EC_SMB_PRTCL_WORD_DATA;
-               break;
-       case ACPI_SBS_BLOCK_DATA:
-               acpi_ec_sbs_write(sbs, ACPI_EC_SMB_CMD, command);
-               if (read_write == ACPI_SBS_SMBUS_WRITE) {
-                       len = min_t(u8, data->block[0], 32);
-                       acpi_ec_sbs_write(sbs, ACPI_EC_SMB_BCNT, len);
-                       for (i = 0; i < len; i++)
-                               acpi_ec_sbs_write(sbs, ACPI_EC_SMB_DATA + i,
-                                                 data->block[i + 1]);
-               }
-               protocol |= ACPI_EC_SMB_PRTCL_BLOCK_DATA;
-               break;
-       default:
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "unsupported transaction %d", size));
-               return (-1);
-       }
-
-       acpi_ec_sbs_write(sbs, ACPI_EC_SMB_ADDR, addr << 1);
-       acpi_ec_sbs_write(sbs, ACPI_EC_SMB_PRTCL, protocol);
-
-       acpi_ec_sbs_read(sbs, ACPI_EC_SMB_STS, temp);
-
-       if (~temp[0] & ACPI_EC_SMB_STS_DONE) {
-               xmsleep(ACPI_EC_SMB_ACCESS_SLEEP1);
-               acpi_ec_sbs_read(sbs, ACPI_EC_SMB_STS, temp);
-       }
-       if (~temp[0] & ACPI_EC_SMB_STS_DONE) {
-               xmsleep(ACPI_EC_SMB_ACCESS_SLEEP2);
-               acpi_ec_sbs_read(sbs, ACPI_EC_SMB_STS, temp);
-       }
-       if ((~temp[0] & ACPI_EC_SMB_STS_DONE)
-           || (temp[0] & ACPI_EC_SMB_STS_STATUS)) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "transaction %d error", size));
-               return (-1);
-       }
-
-       if (read_write == ACPI_SBS_SMBUS_WRITE) {
-               return (0);
-       }
-
-       switch (size) {
-
-       case ACPI_SBS_WORD_DATA:
-               acpi_ec_sbs_read(sbs, ACPI_EC_SMB_DATA, temp);
-               acpi_ec_sbs_read(sbs, ACPI_EC_SMB_DATA + 1, temp + 1);
-               data->word = (temp[1] << 8) | temp[0];
-               break;
-
-       case ACPI_SBS_BLOCK_DATA:
-               len = 0;
-               acpi_ec_sbs_read(sbs, ACPI_EC_SMB_BCNT, &len);
-               len = min_t(u8, len, 32);
-               for (i = 0; i < len; i++)
-                       acpi_ec_sbs_read(sbs, ACPI_EC_SMB_DATA + i,
-                                        data->block + i + 1);
-               data->block[0] = len;
-               break;
-       default:
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "unsupported transaction %d", size));
-               return (-1);
-       }
-
-       return (0);
+       int scale = 1;
+       while (log--)
+               scale *= 10;
+       return scale;
 }
 
-static int
-acpi_sbs_read_word(struct acpi_sbs *sbs, int addr, int func, u16 * word)
+static inline int acpi_battery_vscale(struct acpi_battery *battery)
 {
-       union sbs_rw_data data;
-       int result = 0;
-
-       result = acpi_ec_sbs_access(sbs, addr,
-                                   ACPI_SBS_SMBUS_READ, func,
-                                   ACPI_SBS_WORD_DATA, &data);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_ec_sbs_access() failed"));
-       } else {
-               *word = data.word;
-       }
-
-       return result;
+       return battery_scale((battery->spec & 0x0f00) >> 8);
 }
 
-static int
-acpi_sbs_read_str(struct acpi_sbs *sbs, int addr, int func, char *str)
+static inline int acpi_battery_ipscale(struct acpi_battery *battery)
 {
-       union sbs_rw_data data;
-       int result = 0;
-
-       result = acpi_ec_sbs_access(sbs, addr,
-                                   ACPI_SBS_SMBUS_READ, func,
-                                   ACPI_SBS_BLOCK_DATA, &data);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_ec_sbs_access() failed"));
-       } else {
-               strncpy(str, (const char *)data.block + 1, data.block[0]);
-               str[data.block[0]] = 0;
-       }
-
-       return result;
+       return battery_scale((battery->spec & 0xf000) >> 12);
 }
 
-static int
-acpi_sbs_write_word(struct acpi_sbs *sbs, int addr, int func, int word)
+static inline int acpi_battery_mode(struct acpi_battery *battery)
 {
-       union sbs_rw_data data;
-       int result = 0;
-
-       data.word = word;
-
-       result = acpi_ec_sbs_access(sbs, addr,
-                                   ACPI_SBS_SMBUS_WRITE, func,
-                                   ACPI_SBS_WORD_DATA, &data);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_ec_sbs_access() failed"));
-       }
-
-       return result;
+       return (battery->mode & 0x8000);
 }
 
-static int sbs_zombie(struct acpi_sbs *sbs)
+static inline int acpi_battery_scale(struct acpi_battery *battery)
 {
-       return (sbs->zombie);
+       return (acpi_battery_mode(battery) ? 10 : 1) *
+           acpi_battery_ipscale(battery);
 }
 
-static int sbs_mutex_lock(struct acpi_sbs *sbs)
+static int sbs_get_ac_property(struct power_supply *psy,
+                              enum power_supply_property psp,
+                              union power_supply_propval *val)
 {
-       if (sbs_zombie(sbs)) {
-               return -ENODEV;
+       struct acpi_sbs *sbs = to_acpi_sbs(psy);
+       switch (psp) {
+       case POWER_SUPPLY_PROP_ONLINE:
+               val->intval = sbs->charger_present;
+               break;
+       default:
+               return -EINVAL;
        }
-       mutex_lock(&sbs->mutex);
        return 0;
 }
 
-static void sbs_mutex_unlock(struct acpi_sbs *sbs)
+static int acpi_battery_technology(struct acpi_battery *battery)
 {
-       mutex_unlock(&sbs->mutex);
+       if (!strcasecmp("NiCd", battery->device_chemistry))
+               return POWER_SUPPLY_TECHNOLOGY_NiCd;
+       if (!strcasecmp("NiMH", battery->device_chemistry))
+               return POWER_SUPPLY_TECHNOLOGY_NiMH;
+       if (!strcasecmp("LION", battery->device_chemistry))
+               return POWER_SUPPLY_TECHNOLOGY_LION;
+       if (!strcasecmp("LiP", battery->device_chemistry))
+               return POWER_SUPPLY_TECHNOLOGY_LIPO;
+       return POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
 }
 
-/* --------------------------------------------------------------------------
-                            Smart Battery System Management
-   -------------------------------------------------------------------------- */
-
-static int acpi_check_update_proc(struct acpi_sbs *sbs)
+static int acpi_sbs_battery_get_property(struct power_supply *psy,
+                                        enum power_supply_property psp,
+                                        union power_supply_propval *val)
 {
-       acpi_status status = AE_OK;
+       struct acpi_battery *battery = to_acpi_battery(psy);
 
-       if (update_time == 0) {
-               sbs->update_proc_flg = 0;
-               return 0;
-       }
-       if (sbs->update_proc_flg == 0) {
-               status = acpi_os_execute(OSL_GPE_HANDLER,
-                                        acpi_sbs_update_time, sbs);
-               if (status != AE_OK) {
-                       ACPI_EXCEPTION((AE_INFO, status,
-                                       "acpi_os_execute() failed"));
-                       return 1;
-               }
-               sbs->update_proc_flg = 1;
+       if ((!battery->present) && psp != POWER_SUPPLY_PROP_PRESENT)
+               return -ENODEV;
+       switch (psp) {
+       case POWER_SUPPLY_PROP_STATUS:
+               if (battery->current_now < 0)
+                       val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+               else if (battery->current_now > 0)
+                       val->intval = POWER_SUPPLY_STATUS_CHARGING;
+               else
+                       val->intval = POWER_SUPPLY_STATUS_FULL;
+               break;
+       case POWER_SUPPLY_PROP_PRESENT:
+               val->intval = battery->present;
+               break;
+       case POWER_SUPPLY_PROP_TECHNOLOGY:
+               val->intval = acpi_battery_technology(battery);
+               break;
+       case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
+               val->intval = battery->design_voltage *
+                       acpi_battery_vscale(battery) * 1000;
+               break;
+       case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+               val->intval = battery->voltage_now *
+                               acpi_battery_vscale(battery) * 1000;
+               break;
+       case POWER_SUPPLY_PROP_CURRENT_NOW:
+               val->intval = abs(battery->current_now) *
+                               acpi_battery_ipscale(battery) * 1000;
+               break;
+       case POWER_SUPPLY_PROP_CURRENT_AVG:
+               val->intval = abs(battery->current_avg) *
+                               acpi_battery_ipscale(battery) * 1000;
+               break;
+       case POWER_SUPPLY_PROP_CAPACITY:
+               val->intval = battery->state_of_charge;
+               break;
+       case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
+       case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
+               val->intval = battery->design_capacity *
+                       acpi_battery_scale(battery) * 1000;
+               break;
+       case POWER_SUPPLY_PROP_CHARGE_FULL:
+       case POWER_SUPPLY_PROP_ENERGY_FULL:
+               val->intval = battery->full_charge_capacity *
+                       acpi_battery_scale(battery) * 1000;
+               break;
+       case POWER_SUPPLY_PROP_CHARGE_NOW:
+       case POWER_SUPPLY_PROP_ENERGY_NOW:
+               val->intval = battery->capacity_now *
+                               acpi_battery_scale(battery) * 1000;
+               break;
+       case POWER_SUPPLY_PROP_TEMP:
+               val->intval = battery->temp_now - 2730; // dK -> dC
+               break;
+       case POWER_SUPPLY_PROP_MODEL_NAME:
+               val->strval = battery->device_name;
+               break;
+       case POWER_SUPPLY_PROP_MANUFACTURER:
+               val->strval = battery->manufacturer_name;
+               break;
+       default:
+               return -EINVAL;
        }
        return 0;
 }
 
-static int acpi_sbs_generate_event(struct acpi_device *device,
-                                  int event, int state, char *bid, char *class)
-{
-       char bid_saved[5];
-       char class_saved[20];
-       int result = 0;
-
-       strcpy(bid_saved, acpi_device_bid(device));
-       strcpy(class_saved, acpi_device_class(device));
-
-       strcpy(acpi_device_bid(device), bid);
-       strcpy(acpi_device_class(device), class);
-
-       result = acpi_bus_generate_proc_event(device, event, state);
-
-       strcpy(acpi_device_bid(device), bid_saved);
-       strcpy(acpi_device_class(device), class_saved);
-
-       acpi_bus_generate_netlink_event(class, bid, event, state);
-       return result;
-}
-
-static int acpi_battery_get_present(struct acpi_battery *battery)
-{
-       s16 state;
-       int result = 0;
-       int is_present = 0;
-
-       result = acpi_sbs_read_word(battery->sbs,
-                                   ACPI_SBSM_SMBUS_ADDR, 0x01, &state);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_sbs_read_word() failed"));
-       }
-       if (!result) {
-               is_present = (state & 0x000f) & (1 << battery->id);
-       }
-       battery->battery_present = is_present;
-
-       return result;
-}
+static enum power_supply_property sbs_ac_props[] = {
+       POWER_SUPPLY_PROP_ONLINE,
+};
 
-static int acpi_battery_select(struct acpi_battery *battery)
-{
-       struct acpi_sbs *sbs = battery->sbs;
-       int result = 0;
-       s16 state;
-       int foo;
+static enum power_supply_property sbs_charge_battery_props[] = {
+       POWER_SUPPLY_PROP_STATUS,
+       POWER_SUPPLY_PROP_PRESENT,
+       POWER_SUPPLY_PROP_TECHNOLOGY,
+       POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+       POWER_SUPPLY_PROP_VOLTAGE_NOW,
+       POWER_SUPPLY_PROP_CURRENT_NOW,
+       POWER_SUPPLY_PROP_CURRENT_AVG,
+       POWER_SUPPLY_PROP_CAPACITY,
+       POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
+       POWER_SUPPLY_PROP_CHARGE_FULL,
+       POWER_SUPPLY_PROP_CHARGE_NOW,
+       POWER_SUPPLY_PROP_TEMP,
+       POWER_SUPPLY_PROP_MODEL_NAME,
+       POWER_SUPPLY_PROP_MANUFACTURER,
+};
 
-       if (sbs->sbsm_present) {
+static enum power_supply_property sbs_energy_battery_props[] = {
+       POWER_SUPPLY_PROP_STATUS,
+       POWER_SUPPLY_PROP_PRESENT,
+       POWER_SUPPLY_PROP_TECHNOLOGY,
+       POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+       POWER_SUPPLY_PROP_VOLTAGE_NOW,
+       POWER_SUPPLY_PROP_CURRENT_NOW,
+       POWER_SUPPLY_PROP_CURRENT_AVG,
+       POWER_SUPPLY_PROP_CAPACITY,
+       POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
+       POWER_SUPPLY_PROP_ENERGY_FULL,
+       POWER_SUPPLY_PROP_ENERGY_NOW,
+       POWER_SUPPLY_PROP_TEMP,
+       POWER_SUPPLY_PROP_MODEL_NAME,
+       POWER_SUPPLY_PROP_MANUFACTURER,
+};
 
-               /* Take special care not to knobble other nibbles of
-                * state (aka selector_state), since
-                * it causes charging to halt on SBSELs */
+/* --------------------------------------------------------------------------
+                            Smart Battery System Management
+   -------------------------------------------------------------------------- */
 
-               result =
-                   acpi_sbs_read_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x01, &state);
-               if (result) {
-                       ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                                       "acpi_sbs_read_word() failed"));
-                       goto end;
-               }
+struct acpi_battery_reader {
+       u8 command;             /* command for battery */
+       u8 mode;                /* word or block? */
+       size_t offset;          /* offset inside struct acpi_sbs_battery */
+};
 
-               foo = (state & 0x0fff) | (1 << (battery->id + 12));
-               result =
-                   acpi_sbs_write_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x01, foo);
-               if (result) {
-                       ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                                       "acpi_sbs_write_word() failed"));
-                       goto end;
-               }
-       }
+static struct acpi_battery_reader info_readers[] = {
+       {0x01, SMBUS_READ_WORD, offsetof(struct acpi_battery, alarm_capacity)},
+       {0x03, SMBUS_READ_WORD, offsetof(struct acpi_battery, mode)},
+       {0x10, SMBUS_READ_WORD, offsetof(struct acpi_battery, full_charge_capacity)},
+       {0x17, SMBUS_READ_WORD, offsetof(struct acpi_battery, cycle_count)},
+       {0x18, SMBUS_READ_WORD, offsetof(struct acpi_battery, design_capacity)},
+       {0x19, SMBUS_READ_WORD, offsetof(struct acpi_battery, design_voltage)},
+       {0x1a, SMBUS_READ_WORD, offsetof(struct acpi_battery, spec)},
+       {0x1c, SMBUS_READ_WORD, offsetof(struct acpi_battery, serial_number)},
+       {0x20, SMBUS_READ_BLOCK, offsetof(struct acpi_battery, manufacturer_name)},
+       {0x21, SMBUS_READ_BLOCK, offsetof(struct acpi_battery, device_name)},
+       {0x22, SMBUS_READ_BLOCK, offsetof(struct acpi_battery, device_chemistry)},
+};
 
-      end:
-       return result;
-}
+static struct acpi_battery_reader state_readers[] = {
+       {0x08, SMBUS_READ_WORD, offsetof(struct acpi_battery, temp_now)},
+       {0x09, SMBUS_READ_WORD, offsetof(struct acpi_battery, voltage_now)},
+       {0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_now)},
+       {0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_avg)},
+       {0x0f, SMBUS_READ_WORD, offsetof(struct acpi_battery, capacity_now)},
+       {0x0e, SMBUS_READ_WORD, offsetof(struct acpi_battery, state_of_charge)},
+       {0x16, SMBUS_READ_WORD, offsetof(struct acpi_battery, state)},
+};
 
-static int acpi_sbsm_get_info(struct acpi_sbs *sbs)
+static int acpi_manager_get_info(struct acpi_sbs *sbs)
 {
        int result = 0;
-       s16 battery_system_info;
-
-       result = acpi_sbs_read_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x04,
-                                   &battery_system_info);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_sbs_read_word() failed"));
-               goto end;
-       }
-       sbs->sbsm_present = 1;
-       sbs->sbsm_batteries_supported = battery_system_info & 0x000f;
-
-      end:
+       u16 battery_system_info;
 
+       result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_MANAGER,
+                                0x04, (u8 *)&battery_system_info);
+       if (!result)
+               sbs->batteries_supported = battery_system_info & 0x000f;
        return result;
 }
 
 static int acpi_battery_get_info(struct acpi_battery *battery)
 {
-       struct acpi_sbs *sbs = battery->sbs;
-       int result = 0;
-       s16 battery_mode;
-       s16 specification_info;
-
-       result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x03,
-                                   &battery_mode);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_sbs_read_word() failed"));
-               goto end;
-       }
-       battery->info.capacity_mode = (battery_mode & 0x8000) >> 15;
-
-       result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x10,
-                                   &battery->info.full_charge_capacity);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_sbs_read_word() failed"));
-               goto end;
-       }
-
-       result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x18,
-                                   &battery->info.design_capacity);
-
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_sbs_read_word() failed"));
-               goto end;
-       }
-
-       result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x19,
-                                   &battery->info.design_voltage);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_sbs_read_word() failed"));
-               goto end;
-       }
-
-       result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x1a,
-                                   &specification_info);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_sbs_read_word() failed"));
-               goto end;
-       }
-
-       switch ((specification_info & 0x0f00) >> 8) {
-       case 1:
-               battery->info.vscale = 10;
-               break;
-       case 2:
-               battery->info.vscale = 100;
-               break;
-       case 3:
-               battery->info.vscale = 1000;
-               break;
-       default:
-               battery->info.vscale = 1;
-       }
-
-       switch ((specification_info & 0xf000) >> 12) {
-       case 1:
-               battery->info.ipscale = 10;
-               break;
-       case 2:
-               battery->info.ipscale = 100;
-               break;
-       case 3:
-               battery->info.ipscale = 1000;
-               break;
-       default:
-               battery->info.ipscale = 1;
-       }
-
-       result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x1c,
-                                   &battery->info.serial_number);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_sbs_read_word() failed"));
-               goto end;
-       }
-
-       result = acpi_sbs_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x20,
-                                  battery->info.manufacturer_name);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_sbs_read_str() failed"));
-               goto end;
-       }
-
-       result = acpi_sbs_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x21,
-                                  battery->info.device_name);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_sbs_read_str() failed"));
-               goto end;
+       int i, result = 0;
+
+       for (i = 0; i < ARRAY_SIZE(info_readers); ++i) {
+               result = acpi_smbus_read(battery->sbs->hc,
+                                        info_readers[i].mode,
+                                        ACPI_SBS_BATTERY,
+                                        info_readers[i].command,
+                                        (u8 *) battery +
+                                               info_readers[i].offset);
+               if (result)
+                       break;
        }
-
-       result = acpi_sbs_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x22,
-                                  battery->info.device_chemistry);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_sbs_read_str() failed"));
-               goto end;
-       }
-
-      end:
        return result;
 }
 
 static int acpi_battery_get_state(struct acpi_battery *battery)
 {
-       struct acpi_sbs *sbs = battery->sbs;
-       int result = 0;
-
-       result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x09,
-                                   &battery->state.voltage);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_sbs_read_word() failed"));
-               goto end;
-       }
-
-       result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x0a,
-                                   &battery->state.amperage);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_sbs_read_word() failed"));
-               goto end;
-       }
-
-       result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x0f,
-                                   &battery->state.remaining_capacity);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_sbs_read_word() failed"));
-               goto end;
-       }
+       int i, result = 0;
 
-       result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x16,
-                                   &battery->state.battery_state);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_sbs_read_word() failed"));
-               goto end;
+       if (battery->update_time &&
+           time_before(jiffies, battery->update_time +
+                               msecs_to_jiffies(cache_time)))
+               return 0;
+       for (i = 0; i < ARRAY_SIZE(state_readers); ++i) {
+               result = acpi_smbus_read(battery->sbs->hc,
+                                        state_readers[i].mode,
+                                        ACPI_SBS_BATTERY,
+                                        state_readers[i].command,
+                                        (u8 *)battery +
+                                               state_readers[i].offset);
+               if (result)
+                       goto end;
        }
-
       end:
+       battery->update_time = jiffies;
        return result;
 }
 
 static int acpi_battery_get_alarm(struct acpi_battery *battery)
 {
-       struct acpi_sbs *sbs = battery->sbs;
-       int result = 0;
-
-       result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01,
-                                   &battery->alarm.remaining_capacity);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_sbs_read_word() failed"));
-               goto end;
-       }
-
-      end:
-
-       return result;
+       return acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
+                                ACPI_SBS_BATTERY, 0x01,
+                                (u8 *)&battery->alarm_capacity);
 }
 
-static int acpi_battery_set_alarm(struct acpi_battery *battery,
-                                 unsigned long alarm)
+static int acpi_battery_set_alarm(struct acpi_battery *battery)
 {
        struct acpi_sbs *sbs = battery->sbs;
-       int result = 0;
-       s16 battery_mode;
-       int foo;
+       u16 value, sel = 1 << (battery->id + 12);
 
-       result = acpi_battery_select(battery);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_battery_select() failed"));
-               goto end;
-       }
+       int ret;
 
-       /* If necessary, enable the alarm */
 
-       if (alarm > 0) {
-               result =
-                   acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x03,
-                                      &battery_mode);
-               if (result) {
-                       ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                                       "acpi_sbs_read_word() failed"));
+       if (sbs->manager_present) {
+               ret = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_MANAGER,
+                               0x01, (u8 *)&value);
+               if (ret)
                        goto end;
-               }
-
-               result =
-                   acpi_sbs_write_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01,
-                                       battery_mode & 0xbfff);
-               if (result) {
-                       ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                                       "acpi_sbs_write_word() failed"));
+               if ((value & 0xf000) != sel) {
+                       value &= 0x0fff;
+                       value |= sel;
+               ret = acpi_smbus_write(sbs->hc, SMBUS_WRITE_WORD,
+                                        ACPI_SBS_MANAGER,
+                                        0x01, (u8 *)&value, 2);
+               if (ret)
                        goto end;
                }
        }
-
-       foo = alarm / (battery->info.capacity_mode ? 10 : 1);
-       result = acpi_sbs_write_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01, foo);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_sbs_write_word() failed"));
-               goto end;
-       }
-
+       ret = acpi_smbus_write(sbs->hc, SMBUS_WRITE_WORD, ACPI_SBS_BATTERY,
+                               0x01, (u8 *)&battery->alarm_capacity, 2);
       end:
-
-       return result;
+       return ret;
 }
 
-static int acpi_battery_set_mode(struct acpi_battery *battery)
+static int acpi_ac_get_present(struct acpi_sbs *sbs)
 {
-       struct acpi_sbs *sbs = battery->sbs;
-       int result = 0;
-       s16 battery_mode;
-
-       if (capacity_mode == DEF_CAPACITY_UNIT) {
-               goto end;
-       }
-
-       result = acpi_sbs_read_word(sbs,
-                                   ACPI_SB_SMBUS_ADDR, 0x03, &battery_mode);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_sbs_read_word() failed"));
-               goto end;
-       }
-
-       if (capacity_mode == MAH_CAPACITY_UNIT) {
-               battery_mode &= 0x7fff;
-       } else {
-               battery_mode |= 0x8000;
-       }
-       result = acpi_sbs_write_word(sbs,
-                                    ACPI_SB_SMBUS_ADDR, 0x03, battery_mode);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_sbs_write_word() failed"));
-               goto end;
-       }
-
-       result = acpi_sbs_read_word(sbs,
-                                   ACPI_SB_SMBUS_ADDR, 0x03, &battery_mode);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_sbs_read_word() failed"));
-               goto end;
-       }
+       int result;
+       u16 status;
 
-      end:
+       result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_CHARGER,
+                                0x13, (u8 *) & status);
+       if (!result)
+               sbs->charger_present = (status >> 15) & 0x1;
        return result;
 }
 
-static int acpi_battery_init(struct acpi_battery *battery)
+static ssize_t acpi_battery_alarm_show(struct device *dev,
+                                       struct device_attribute *attr,
+                                       char *buf)
 {
-       int result = 0;
-
-       result = acpi_battery_select(battery);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_battery_select() failed"));
-               goto end;
-       }
-
-       result = acpi_battery_set_mode(battery);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_battery_set_mode() failed"));
-               goto end;
-       }
-
-       result = acpi_battery_get_info(battery);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_battery_get_info() failed"));
-               goto end;
-       }
-
-       result = acpi_battery_get_state(battery);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_battery_get_state() failed"));
-               goto end;
-       }
-
-       result = acpi_battery_get_alarm(battery);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_battery_get_alarm() failed"));
-               goto end;
-       }
-
-      end:
-       return result;
+       struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
+       acpi_battery_get_alarm(battery);
+       return sprintf(buf, "%d\n", battery->alarm_capacity *
+                               acpi_battery_scale(battery) * 1000);
 }
 
-static int acpi_ac_get_present(struct acpi_sbs *sbs)
+static ssize_t acpi_battery_alarm_store(struct device *dev,
+                                       struct device_attribute *attr,
+                                       const char *buf, size_t count)
 {
-       int result = 0;
-       s16 charger_status;
-
-       result = acpi_sbs_read_word(sbs, ACPI_SBC_SMBUS_ADDR, 0x13,
-                                   &charger_status);
-
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_sbs_read_word() failed"));
-               goto end;
-       }
-
-       sbs->ac.ac_present = (charger_status & 0x8000) >> 15;
-
-      end:
-
-       return result;
+       unsigned long x;
+       struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
+       if (sscanf(buf, "%ld\n", &x) == 1)
+               battery->alarm_capacity = x /
+                       (1000 * acpi_battery_scale(battery));
+       if (battery->present)
+               acpi_battery_set_alarm(battery);
+       return count;
 }
 
+static struct device_attribute alarm_attr = {
+       .attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE},
+       .show = acpi_battery_alarm_show,
+       .store = acpi_battery_alarm_store,
+};
+
 /* --------------------------------------------------------------------------
                               FS Interface (/proc/acpi)
    -------------------------------------------------------------------------- */
 
+#ifdef CONFIG_ACPI_PROCFS
 /* Generic Routines */
-
 static int
-acpi_sbs_generic_add_fs(struct proc_dir_entry **dir,
-                       struct proc_dir_entry *parent_dir,
-                       char *dir_name,
-                       struct file_operations *info_fops,
-                       struct file_operations *state_fops,
-                       struct file_operations *alarm_fops, void *data)
+acpi_sbs_add_fs(struct proc_dir_entry **dir,
+               struct proc_dir_entry *parent_dir,
+               char *dir_name,
+               struct file_operations *info_fops,
+               struct file_operations *state_fops,
+               struct file_operations *alarm_fops, void *data)
 {
        struct proc_dir_entry *entry = NULL;
 
        if (!*dir) {
                *dir = proc_mkdir(dir_name, parent_dir);
                if (!*dir) {
-                       ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                                       "proc_mkdir() failed"));
                        return -ENODEV;
                }
                (*dir)->owner = THIS_MODULE;
@@ -882,10 +491,7 @@ acpi_sbs_generic_add_fs(struct proc_dir_entry **dir,
        /* 'info' [R] */
        if (info_fops) {
                entry = create_proc_entry(ACPI_SBS_FILE_INFO, S_IRUGO, *dir);
-               if (!entry) {
-                       ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                                       "create_proc_entry() failed"));
-               } else {
+               if (entry) {
                        entry->proc_fops = info_fops;
                        entry->data = data;
                        entry->owner = THIS_MODULE;
@@ -895,10 +501,7 @@ acpi_sbs_generic_add_fs(struct proc_dir_entry **dir,
        /* 'state' [R] */
        if (state_fops) {
                entry = create_proc_entry(ACPI_SBS_FILE_STATE, S_IRUGO, *dir);
-               if (!entry) {
-                       ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                                       "create_proc_entry() failed"));
-               } else {
+               if (entry) {
                        entry->proc_fops = state_fops;
                        entry->data = data;
                        entry->owner = THIS_MODULE;
@@ -908,24 +511,19 @@ acpi_sbs_generic_add_fs(struct proc_dir_entry **dir,
        /* 'alarm' [R/W] */
        if (alarm_fops) {
                entry = create_proc_entry(ACPI_SBS_FILE_ALARM, S_IRUGO, *dir);
-               if (!entry) {
-                       ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                                       "create_proc_entry() failed"));
-               } else {
+               if (entry) {
                        entry->proc_fops = alarm_fops;
                        entry->data = data;
                        entry->owner = THIS_MODULE;
                }
        }
-
        return 0;
 }
 
 static void
-acpi_sbs_generic_remove_fs(struct proc_dir_entry **dir,
+acpi_sbs_remove_fs(struct proc_dir_entry **dir,
                           struct proc_dir_entry *parent_dir)
 {
-
        if (*dir) {
                remove_proc_entry(ACPI_SBS_FILE_INFO, *dir);
                remove_proc_entry(ACPI_SBS_FILE_STATE, *dir);
@@ -933,82 +531,52 @@ acpi_sbs_generic_remove_fs(struct proc_dir_entry **dir,
                remove_proc_entry((*dir)->name, parent_dir);
                *dir = NULL;
        }
-
 }
 
 /* Smart Battery Interface */
-
 static struct proc_dir_entry *acpi_battery_dir = NULL;
 
+static inline char *acpi_battery_units(struct acpi_battery *battery)
+{
+       return acpi_battery_mode(battery) ? " mWh" : " mAh";
+}
+
+
 static int acpi_battery_read_info(struct seq_file *seq, void *offset)
 {
        struct acpi_battery *battery = seq->private;
        struct acpi_sbs *sbs = battery->sbs;
-       int cscale;
        int result = 0;
 
-       if (sbs_mutex_lock(sbs)) {
-               return -ENODEV;
-       }
+       mutex_lock(&sbs->lock);
 
-       result = acpi_check_update_proc(sbs);
-       if (result)
+       seq_printf(seq, "present:                 %s\n",
+                  (battery->present) ? "yes" : "no");
+       if (!battery->present)
                goto end;
 
-       if (update_time == 0) {
-               result = acpi_sbs_update_run(sbs, battery->id, DATA_TYPE_INFO);
-               if (result) {
-                       ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                                       "acpi_sbs_update_run() failed"));
-               }
-       }
-
-       if (battery->battery_present) {
-               seq_printf(seq, "present:                 yes\n");
-       } else {
-               seq_printf(seq, "present:                 no\n");
-               goto end;
-       }
-
-       if (battery->info.capacity_mode) {
-               cscale = battery->info.vscale * battery->info.ipscale;
-       } else {
-               cscale = battery->info.ipscale;
-       }
        seq_printf(seq, "design capacity:         %i%s\n",
-                  battery->info.design_capacity * cscale,
-                  battery->info.capacity_mode ? "0 mWh" : " mAh");
-
+                  battery->design_capacity * acpi_battery_scale(battery),
+                  acpi_battery_units(battery));
        seq_printf(seq, "last full capacity:      %i%s\n",
-                  battery->info.full_charge_capacity * cscale,
-                  battery->info.capacity_mode ? "0 mWh" : " mAh");
-
+                  battery->full_charge_capacity * acpi_battery_scale(battery),
+                  acpi_battery_units(battery));
        seq_printf(seq, "battery technology:      rechargeable\n");
-
        seq_printf(seq, "design voltage:          %i mV\n",
-                  battery->info.design_voltage * battery->info.vscale);
-
+                  battery->design_voltage * acpi_battery_vscale(battery));
        seq_printf(seq, "design capacity warning: unknown\n");
        seq_printf(seq, "design capacity low:     unknown\n");
        seq_printf(seq, "capacity granularity 1:  unknown\n");
        seq_printf(seq, "capacity granularity 2:  unknown\n");
-
-       seq_printf(seq, "model number:            %s\n",
-                  battery->info.device_name);
-
+       seq_printf(seq, "model number:            %s\n", battery->device_name);
        seq_printf(seq, "serial number:           %i\n",
-                  battery->info.serial_number);
-
+                  battery->serial_number);
        seq_printf(seq, "battery type:            %s\n",
-                  battery->info.device_chemistry);
-
+                  battery->device_chemistry);
        seq_printf(seq, "OEM info:                %s\n",
-                  battery->info.manufacturer_name);
-
+                  battery->manufacturer_name);
       end:
-
-       sbs_mutex_unlock(sbs);
-
+       mutex_unlock(&sbs->lock);
        return result;
 }
 
@@ -1022,73 +590,29 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset)
        struct acpi_battery *battery = seq->private;
        struct acpi_sbs *sbs = battery->sbs;
        int result = 0;
-       int cscale;
-       int foo;
-
-       if (sbs_mutex_lock(sbs)) {
-               return -ENODEV;
-       }
-
-       result = acpi_check_update_proc(sbs);
-       if (result)
-               goto end;
-
-       if (update_time == 0) {
-               result = acpi_sbs_update_run(sbs, battery->id, DATA_TYPE_STATE);
-               if (result) {
-                       ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                                       "acpi_sbs_update_run() failed"));
-               }
-       }
 
-       if (battery->battery_present) {
-               seq_printf(seq, "present:                 yes\n");
-       } else {
-               seq_printf(seq, "present:                 no\n");
+       mutex_lock(&sbs->lock);
+       seq_printf(seq, "present:                 %s\n",
+                  (battery->present) ? "yes" : "no");
+       if (!battery->present)
                goto end;
-       }
-
-       if (battery->info.capacity_mode) {
-               cscale = battery->info.vscale * battery->info.ipscale;
-       } else {
-               cscale = battery->info.ipscale;
-       }
-
-       if (battery->state.battery_state & 0x0010) {
-               seq_printf(seq, "capacity state:          critical\n");
-       } else {
-               seq_printf(seq, "capacity state:          ok\n");
-       }
-
-       foo = (s16) battery->state.amperage * battery->info.ipscale;
-       if (battery->info.capacity_mode) {
-               foo = foo * battery->info.design_voltage / 1000;
-       }
-       if (battery->state.amperage < 0) {
-               seq_printf(seq, "charging state:          discharging\n");
-               seq_printf(seq, "present rate:            %d %s\n",
-                          -foo, battery->info.capacity_mode ? "mW" : "mA");
-       } else if (battery->state.amperage > 0) {
-               seq_printf(seq, "charging state:          charging\n");
-               seq_printf(seq, "present rate:            %d %s\n",
-                          foo, battery->info.capacity_mode ? "mW" : "mA");
-       } else {
-               seq_printf(seq, "charging state:          charged\n");
-               seq_printf(seq, "present rate:            0 %s\n",
-                          battery->info.capacity_mode ? "mW" : "mA");
-       }
 
+       acpi_battery_get_state(battery);
+       seq_printf(seq, "capacity state:          %s\n",
+                  (battery->state & 0x0010) ? "critical" : "ok");
+       seq_printf(seq, "charging state:          %s\n",
+                  (battery->current_now < 0) ? "discharging" :
+                  ((battery->current_now > 0) ? "charging" : "charged"));
+       seq_printf(seq, "present rate:            %d mA\n",
+                  abs(battery->current_now) * acpi_battery_ipscale(battery));
        seq_printf(seq, "remaining capacity:      %i%s\n",
-                  battery->state.remaining_capacity * cscale,
-                  battery->info.capacity_mode ? "0 mWh" : " mAh");
-
+                  battery->capacity_now * acpi_battery_scale(battery),
+                  acpi_battery_units(battery));
        seq_printf(seq, "present voltage:         %i mV\n",
-                  battery->state.voltage * battery->info.vscale);
+                  battery->voltage_now * acpi_battery_vscale(battery));
 
       end:
-
-       sbs_mutex_unlock(sbs);
-
+       mutex_unlock(&sbs->lock);
        return result;
 }
 
@@ -1102,48 +626,25 @@ static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
        struct acpi_battery *battery = seq->private;
        struct acpi_sbs *sbs = battery->sbs;
        int result = 0;
-       int cscale;
-
-       if (sbs_mutex_lock(sbs)) {
-               return -ENODEV;
-       }
 
-       result = acpi_check_update_proc(sbs);
-       if (result)
-               goto end;
-
-       if (update_time == 0) {
-               result = acpi_sbs_update_run(sbs, battery->id, DATA_TYPE_ALARM);
-               if (result) {
-                       ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                                       "acpi_sbs_update_run() failed"));
-               }
-       }
+       mutex_lock(&sbs->lock);
 
-       if (!battery->battery_present) {
+       if (!battery->present) {
                seq_printf(seq, "present:                 no\n");
                goto end;
        }
 
-       if (battery->info.capacity_mode) {
-               cscale = battery->info.vscale * battery->info.ipscale;
-       } else {
-               cscale = battery->info.ipscale;
-       }
-
+       acpi_battery_get_alarm(battery);
        seq_printf(seq, "alarm:                   ");
-       if (battery->alarm.remaining_capacity) {
+       if (battery->alarm_capacity)
                seq_printf(seq, "%i%s\n",
-                          battery->alarm.remaining_capacity * cscale,
-                          battery->info.capacity_mode ? "0 mWh" : " mAh");
-       } else {
+                          battery->alarm_capacity *
+                          acpi_battery_scale(battery),
+                          acpi_battery_units(battery));
+       else
                seq_printf(seq, "disabled\n");
-       }
-
       end:
-
-       sbs_mutex_unlock(sbs);
-
+       mutex_unlock(&sbs->lock);
        return result;
 }
 
@@ -1155,59 +656,29 @@ acpi_battery_write_alarm(struct file *file, const char __user * buffer,
        struct acpi_battery *battery = seq->private;
        struct acpi_sbs *sbs = battery->sbs;
        char alarm_string[12] = { '\0' };
-       int result, old_alarm, new_alarm;
-
-       if (sbs_mutex_lock(sbs)) {
-               return -ENODEV;
-       }
-
-       result = acpi_check_update_proc(sbs);
-       if (result)
-               goto end;
-
-       if (!battery->battery_present) {
+       int result = 0;
+       mutex_lock(&sbs->lock);
+       if (!battery->present) {
                result = -ENODEV;
                goto end;
        }
-
        if (count > sizeof(alarm_string) - 1) {
                result = -EINVAL;
                goto end;
        }
-
        if (copy_from_user(alarm_string, buffer, count)) {
                result = -EFAULT;
                goto end;
        }
-
        alarm_string[count] = 0;
-
-       old_alarm = battery->alarm.remaining_capacity;
-       new_alarm = simple_strtoul(alarm_string, NULL, 0);
-
-       result = acpi_battery_set_alarm(battery, new_alarm);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_battery_set_alarm() failed"));
-               acpi_battery_set_alarm(battery, old_alarm);
-               goto end;
-       }
-       result = acpi_battery_get_alarm(battery);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_battery_get_alarm() failed"));
-               acpi_battery_set_alarm(battery, old_alarm);
-               goto end;
-       }
-
+       battery->alarm_capacity = simple_strtoul(alarm_string, NULL, 0) /
+                                       acpi_battery_scale(battery);
+       acpi_battery_set_alarm(battery);
       end:
-       sbs_mutex_unlock(sbs);
-
-       if (result) {
+       mutex_unlock(&sbs->lock);
+       if (result)
                return result;
-       } else {
-               return count;
-       }
+       return count;
 }
 
 static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
@@ -1246,26 +717,15 @@ static struct proc_dir_entry *acpi_ac_dir = NULL;
 
 static int acpi_ac_read_state(struct seq_file *seq, void *offset)
 {
-       struct acpi_sbs *sbs = seq->private;
-       int result;
 
-       if (sbs_mutex_lock(sbs)) {
-               return -ENODEV;
-       }
+       struct acpi_sbs *sbs = seq->private;
 
-       if (update_time == 0) {
-               result = acpi_sbs_update_run(sbs, -1, DATA_TYPE_AC_STATE);
-               if (result) {
-                       ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                                       "acpi_sbs_update_run() failed"));
-               }
-       }
+       mutex_lock(&sbs->lock);
 
        seq_printf(seq, "state:                   %s\n",
-                  sbs->ac.ac_present ? "on-line" : "off-line");
-
-       sbs_mutex_unlock(sbs);
+                  sbs->charger_present ? "on-line" : "off-line");
 
+       mutex_unlock(&sbs->lock);
        return 0;
 }
 
@@ -1282,429 +742,203 @@ static struct file_operations acpi_ac_state_fops = {
        .owner = THIS_MODULE,
 };
 
+#endif
+
 /* --------------------------------------------------------------------------
                                  Driver Interface
    -------------------------------------------------------------------------- */
+static int acpi_battery_read(struct acpi_battery *battery)
+{
+       int result = 0, saved_present = battery->present;
+       u16 state;
+
+       if (battery->sbs->manager_present) {
+               result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
+                               ACPI_SBS_MANAGER, 0x01, (u8 *)&state);
+               if (!result)
+                       battery->present = state & (1 << battery->id);
+               state &= 0x0fff;
+               state |= 1 << (battery->id + 12);
+               acpi_smbus_write(battery->sbs->hc, SMBUS_WRITE_WORD,
+                                 ACPI_SBS_MANAGER, 0x01, (u8 *)&state, 2);
+       } else if (battery->id == 0)
+               battery->present = 1;
+       if (result || !battery->present)
+               return result;
 
-/* Smart Battery */
+       if (saved_present != battery->present) {
+               battery->update_time = 0;
+               result = acpi_battery_get_info(battery);
+               if (result)
+                       return result;
+       }
+       result = acpi_battery_get_state(battery);
+       return result;
+}
 
+/* Smart Battery */
 static int acpi_battery_add(struct acpi_sbs *sbs, int id)
 {
-       int is_present;
+       struct acpi_battery *battery = &sbs->battery[id];
        int result;
-       char dir_name[32];
-       struct acpi_battery *battery;
 
-       battery = &sbs->battery[id];
-
-       battery->alive = 0;
-
-       battery->init_state = 0;
        battery->id = id;
        battery->sbs = sbs;
+       result = acpi_battery_read(battery);
+       if (result)
+               return result;
 
-       result = acpi_battery_select(battery);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_battery_select() failed"));
-               goto end;
-       }
-
-       result = acpi_battery_get_present(battery);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_battery_get_present() failed"));
-               goto end;
-       }
-
-       is_present = battery->battery_present;
-
-       if (is_present) {
-               result = acpi_battery_init(battery);
-               if (result) {
-                       ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                                       "acpi_battery_init() failed"));
-                       goto end;
-               }
-               battery->init_state = 1;
-       }
-
-       sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
-
-       result = acpi_sbs_generic_add_fs(&battery->battery_entry,
-                                        acpi_battery_dir,
-                                        dir_name,
-                                        &acpi_battery_info_fops,
-                                        &acpi_battery_state_fops,
-                                        &acpi_battery_alarm_fops, battery);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_sbs_generic_add_fs() failed"));
-               goto end;
+       sprintf(battery->name, ACPI_BATTERY_DIR_NAME, id);
+#ifdef CONFIG_ACPI_PROCFS
+       acpi_sbs_add_fs(&battery->proc_entry, acpi_battery_dir,
+                       battery->name, &acpi_battery_info_fops,
+                       &acpi_battery_state_fops, &acpi_battery_alarm_fops,
+                       battery);
+#endif
+       battery->bat.name = battery->name;
+       battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
+       if (!acpi_battery_mode(battery)) {
+               battery->bat.properties = sbs_charge_battery_props;
+               battery->bat.num_properties =
+                   ARRAY_SIZE(sbs_charge_battery_props);
+       } else {
+               battery->bat.properties = sbs_energy_battery_props;
+               battery->bat.num_properties =
+                   ARRAY_SIZE(sbs_energy_battery_props);
        }
-       battery->alive = 1;
-
+       battery->bat.get_property = acpi_sbs_battery_get_property;
+       result = power_supply_register(&sbs->device->dev, &battery->bat);
+       device_create_file(battery->bat.dev, &alarm_attr);
        printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n",
-              ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), dir_name,
-              sbs->battery->battery_present ? "present" : "absent");
-
-      end:
+              ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
+              battery->name, sbs->battery->present ? "present" : "absent");
        return result;
 }
 
 static void acpi_battery_remove(struct acpi_sbs *sbs, int id)
 {
-
-       if (sbs->battery[id].battery_entry) {
-               acpi_sbs_generic_remove_fs(&(sbs->battery[id].battery_entry),
-                                          acpi_battery_dir);
-       }
+       if (sbs->battery[id].bat.dev)
+               device_remove_file(sbs->battery[id].bat.dev, &alarm_attr);
+               power_supply_unregister(&sbs->battery[id].bat);
+#ifdef CONFIG_ACPI_PROCFS
+       if (sbs->battery[id].proc_entry) {
+               acpi_sbs_remove_fs(&(sbs->battery[id].proc_entry),
+                                  acpi_battery_dir);
+       }
+#endif
 }
 
-static int acpi_ac_add(struct acpi_sbs *sbs)
+static int acpi_charger_add(struct acpi_sbs *sbs)
 {
        int result;
 
        result = acpi_ac_get_present(sbs);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_ac_get_present() failed"));
+       if (result)
                goto end;
-       }
-
-       result = acpi_sbs_generic_add_fs(&sbs->ac_entry,
-                                        acpi_ac_dir,
-                                        ACPI_AC_DIR_NAME,
-                                        NULL, &acpi_ac_state_fops, NULL, sbs);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_sbs_generic_add_fs() failed"));
+#ifdef CONFIG_ACPI_PROCFS
+       result = acpi_sbs_add_fs(&sbs->charger_entry, acpi_ac_dir,
+                                ACPI_AC_DIR_NAME, NULL,
+                                &acpi_ac_state_fops, NULL, sbs);
+       if (result)
                goto end;
-       }
-
+#endif
+       sbs->charger.name = "sbs-charger";
+       sbs->charger.type = POWER_SUPPLY_TYPE_MAINS;
+       sbs->charger.properties = sbs_ac_props;
+       sbs->charger.num_properties = ARRAY_SIZE(sbs_ac_props);
+       sbs->charger.get_property = sbs_get_ac_property;
+       power_supply_register(&sbs->device->dev, &sbs->charger);
        printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n",
               ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
-              ACPI_AC_DIR_NAME, sbs->ac.ac_present ? "on-line" : "off-line");
-
+              ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line");
       end:
-
        return result;
 }
 
-static void acpi_ac_remove(struct acpi_sbs *sbs)
-{
-
-       if (sbs->ac_entry) {
-               acpi_sbs_generic_remove_fs(&sbs->ac_entry, acpi_ac_dir);
-       }
-}
-
-static void acpi_sbs_update_time_run(unsigned long data)
+static void acpi_charger_remove(struct acpi_sbs *sbs)
 {
-       acpi_os_execute(OSL_GPE_HANDLER, acpi_sbs_update_time, (void *)data);
+       if (sbs->charger.dev)
+               power_supply_unregister(&sbs->charger);
+#ifdef CONFIG_ACPI_PROCFS
+       if (sbs->charger_entry)
+               acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir);
+#endif
 }
 
-static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)
+void acpi_sbs_callback(void *context)
 {
-       struct acpi_battery *battery;
-       int result = 0, cnt;
-       int old_ac_present = -1;
-       int old_battery_present = -1;
-       int new_ac_present = -1;
-       int new_battery_present = -1;
-       int id_min = 0, id_max = MAX_SBS_BAT - 1;
-       char dir_name[32];
-       int do_battery_init = 0, do_ac_init = 0;
-       int old_remaining_capacity = 0;
-       int update_battery = 1;
-       int up_tm = update_time;
-
-       if (sbs_zombie(sbs)) {
-               goto end;
-       }
-
-       if (id >= 0) {
-               id_min = id_max = id;
-       }
-
-       if (data_type == DATA_TYPE_COMMON && up_tm > 0) {
-               cnt = up_tm / (up_tm > UPDATE_DELAY ? UPDATE_DELAY : up_tm);
-               if (sbs->run_cnt % cnt != 0) {
-                       update_battery = 0;
-               }
-       }
-
-       sbs->run_cnt++;
-
-       old_ac_present = sbs->ac.ac_present;
-
-       result = acpi_ac_get_present(sbs);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_ac_get_present() failed"));
-       }
-
-       new_ac_present = sbs->ac.ac_present;
-
-       do_ac_init = (old_ac_present != new_ac_present);
-       if (sbs->run_cnt == 1 && data_type == DATA_TYPE_COMMON) {
-               do_ac_init = 1;
-       }
-
-       if (do_ac_init) {
-               result = acpi_sbs_generate_event(sbs->device,
-                                                ACPI_SBS_AC_NOTIFY_STATUS,
-                                                new_ac_present,
-                                                ACPI_AC_DIR_NAME,
-                                                ACPI_AC_CLASS);
-               if (result) {
-                       ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                                       "acpi_sbs_generate_event() failed"));
-               }
-       }
-
-       if (data_type == DATA_TYPE_COMMON) {
-               if (!do_ac_init && !update_battery) {
-                       goto end;
-               }
-       }
-
-       if (data_type == DATA_TYPE_AC_STATE && !do_ac_init) {
-               goto end;
-       }
-
-       for (id = id_min; id <= id_max; id++) {
-               battery = &sbs->battery[id];
-               if (battery->alive == 0) {
-                       continue;
-               }
-
-               old_remaining_capacity = battery->state.remaining_capacity;
-
-               old_battery_present = battery->battery_present;
-
-               result = acpi_battery_select(battery);
-               if (result) {
-                       ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                                       "acpi_battery_select() failed"));
-               }
-
-               result = acpi_battery_get_present(battery);
-               if (result) {
-                       ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                                       "acpi_battery_get_present() failed"));
-               }
-
-               new_battery_present = battery->battery_present;
-
-               do_battery_init = ((old_battery_present != new_battery_present)
-                                  && new_battery_present);
-               if (!new_battery_present)
-                       goto event;
-               if (do_ac_init || do_battery_init) {
-                       result = acpi_battery_init(battery);
-                       if (result) {
-                               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                                               "acpi_battery_init() "
-                                               "failed"));
-                       }
-               }
-               if (sbs_zombie(sbs)) {
-                       goto end;
-               }
-
-               if ((data_type == DATA_TYPE_COMMON
-                    || data_type == DATA_TYPE_INFO)
-                   && new_battery_present) {
-                       result = acpi_battery_get_info(battery);
-                       if (result) {
-                               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                                               "acpi_battery_get_info() failed"));
-                       }
-               }
-               if (data_type == DATA_TYPE_INFO) {
-                       continue;
-               }
-               if (sbs_zombie(sbs)) {
-                       goto end;
-               }
-
-               if ((data_type == DATA_TYPE_COMMON
-                    || data_type == DATA_TYPE_STATE)
-                   && new_battery_present) {
-                       result = acpi_battery_get_state(battery);
-                       if (result) {
-                               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                                               "acpi_battery_get_state() failed"));
-                       }
-               }
-               if (data_type == DATA_TYPE_STATE) {
-                       goto event;
-               }
-               if (sbs_zombie(sbs)) {
-                       goto end;
-               }
-
-               if ((data_type == DATA_TYPE_COMMON
-                    || data_type == DATA_TYPE_ALARM)
-                   && new_battery_present) {
-                       result = acpi_battery_get_alarm(battery);
-                       if (result) {
-                               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                                               "acpi_battery_get_alarm() "
-                                               "failed"));
-                       }
-               }
-               if (data_type == DATA_TYPE_ALARM) {
-                       continue;
-               }
-               if (sbs_zombie(sbs)) {
-                       goto end;
-               }
-
-             event:
-
-               if (old_battery_present != new_battery_present || do_ac_init ||
-                   old_remaining_capacity !=
-                   battery->state.remaining_capacity) {
-                       sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
-                       result = acpi_sbs_generate_event(sbs->device,
-                                                        ACPI_SBS_BATTERY_NOTIFY_STATUS,
-                                                        new_battery_present,
-                                                        dir_name,
-                                                        ACPI_BATTERY_CLASS);
-                       if (result) {
-                               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                                               "acpi_sbs_generate_event() "
-                                               "failed"));
-                       }
+       int id;
+       struct acpi_sbs *sbs = context;
+       struct acpi_battery *bat;
+       u8 saved_charger_state = sbs->charger_present;
+       u8 saved_battery_state;
+       acpi_ac_get_present(sbs);
+       if (sbs->charger_present != saved_charger_state) {
+#ifdef CONFIG_ACPI_PROC_EVENT
+               acpi_bus_generate_proc_event4(ACPI_AC_CLASS, ACPI_AC_DIR_NAME,
+                                             ACPI_SBS_NOTIFY_STATUS,
+                                             sbs->charger_present);
+#endif
+               kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE);
+       }
+       if (sbs->manager_present) {
+               for (id = 0; id < MAX_SBS_BAT; ++id) {
+                       if (!(sbs->batteries_supported & (1 << id)))
+                               continue;
+                       bat = &sbs->battery[id];
+                       saved_battery_state = bat->present;
+                       acpi_battery_read(bat);
+                       if (saved_battery_state == bat->present)
+                               continue;
+#ifdef CONFIG_ACPI_PROC_EVENT
+                       acpi_bus_generate_proc_event4(ACPI_BATTERY_CLASS,
+                                                     bat->name,
+                                                     ACPI_SBS_NOTIFY_STATUS,
+                                                     bat->present);
+#endif
+                       kobject_uevent(&bat->bat.dev->kobj, KOBJ_CHANGE);
                }
        }
-
-      end:
-
-       return result;
 }
 
-static void acpi_sbs_update_time(void *data)
-{
-       struct acpi_sbs *sbs = data;
-       unsigned long delay = -1;
-       int result;
-       unsigned int up_tm = update_time;
-
-       if (sbs_mutex_lock(sbs))
-               return;
-
-       result = acpi_sbs_update_run(sbs, -1, DATA_TYPE_COMMON);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_sbs_update_run() failed"));
-       }
-
-       if (sbs_zombie(sbs)) {
-               goto end;
-       }
-
-       if (!up_tm) {
-               if (timer_pending(&sbs->update_timer))
-                       del_timer(&sbs->update_timer);
-       } else {
-               delay = (up_tm > UPDATE_DELAY ? UPDATE_DELAY : up_tm);
-               delay = jiffies + HZ * delay;
-               if (timer_pending(&sbs->update_timer)) {
-                       mod_timer(&sbs->update_timer, delay);
-               } else {
-                       sbs->update_timer.data = (unsigned long)data;
-                       sbs->update_timer.function = acpi_sbs_update_time_run;
-                       sbs->update_timer.expires = delay;
-                       add_timer(&sbs->update_timer);
-               }
-       }
-
-      end:
-
-       sbs_mutex_unlock(sbs);
-}
+static int acpi_sbs_remove(struct acpi_device *device, int type);
 
 static int acpi_sbs_add(struct acpi_device *device)
 {
-       struct acpi_sbs *sbs = NULL;
-       int result = 0, remove_result = 0;
+       struct acpi_sbs *sbs;
+       int result = 0;
        int id;
-       acpi_status status = AE_OK;
-       unsigned long val;
-
-       status =
-           acpi_evaluate_integer(device->handle, "_EC", NULL, &val);
-       if (ACPI_FAILURE(status)) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Error obtaining _EC"));
-               return -EIO;
-       }
 
        sbs = kzalloc(sizeof(struct acpi_sbs), GFP_KERNEL);
        if (!sbs) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR, "kzalloc() failed"));
                result = -ENOMEM;
                goto end;
        }
 
-       mutex_init(&sbs->mutex);
+       mutex_init(&sbs->lock);
 
-       sbs_mutex_lock(sbs);
-
-       sbs->base = 0xff & (val >> 8);
+       sbs->hc = acpi_driver_data(device->parent);
        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;
 
-       result = acpi_ac_add(sbs);
-       if (result) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_ac_add() failed"));
-               goto end;
-       }
-
-       acpi_sbsm_get_info(sbs);
-
-       if (!sbs->sbsm_present) {
-               result = acpi_battery_add(sbs, 0);
-               if (result) {
-                       ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                                       "acpi_battery_add() failed"));
-                       goto end;
-               }
-       } else {
-               for (id = 0; id < MAX_SBS_BAT; id++) {
-                       if ((sbs->sbsm_batteries_supported & (1 << id))) {
-                               result = acpi_battery_add(sbs, id);
-                               if (result) {
-                                       ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                                                       "acpi_battery_add() failed"));
-                                       goto end;
-                               }
-                       }
-               }
-       }
-
-       init_timer(&sbs->update_timer);
-       result = acpi_check_update_proc(sbs);
+       result = acpi_charger_add(sbs);
        if (result)
                goto end;
 
+       result = acpi_manager_get_info(sbs);
+       if (!result) {
+               sbs->manager_present = 1;
+               for (id = 0; id < MAX_SBS_BAT; ++id)
+                       if ((sbs->batteries_supported & (1 << id)))
+                               acpi_battery_add(sbs, id);
+       } else
+               acpi_battery_add(sbs, 0);
+       acpi_smbus_register_callback(sbs->hc, acpi_sbs_callback, sbs);
       end:
-
-       sbs_mutex_unlock(sbs);
-
-       if (result) {
-               remove_result = acpi_sbs_remove(device, 0);
-               if (remove_result) {
-                       ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                                       "acpi_sbs_remove() failed"));
-               }
-       }
-
+       if (result)
+               acpi_sbs_remove(device, 0);
        return result;
 }
 
@@ -1713,39 +947,25 @@ static int acpi_sbs_remove(struct acpi_device *device, int type)
        struct acpi_sbs *sbs;
        int id;
 
-       if (!device) {
+       if (!device)
                return -EINVAL;
-       }
-
        sbs = acpi_driver_data(device);
-       if (!sbs) {
+       if (!sbs)
                return -EINVAL;
-       }
-
-       sbs_mutex_lock(sbs);
-
-       sbs->zombie = 1;
-       del_timer_sync(&sbs->update_timer);
-       acpi_os_wait_events_complete(NULL);
-       del_timer_sync(&sbs->update_timer);
-
-       for (id = 0; id < MAX_SBS_BAT; id++) {
+       mutex_lock(&sbs->lock);
+       acpi_smbus_unregister_callback(sbs->hc);
+       for (id = 0; id < MAX_SBS_BAT; ++id)
                acpi_battery_remove(sbs, id);
-       }
-
-       acpi_ac_remove(sbs);
-
-       sbs_mutex_unlock(sbs);
-
-       mutex_destroy(&sbs->mutex);
-
+       acpi_charger_remove(sbs);
+       mutex_unlock(&sbs->lock);
+       mutex_destroy(&sbs->lock);
        kfree(sbs);
-
        return 0;
 }
 
 static void acpi_sbs_rmdirs(void)
 {
+#ifdef CONFIG_ACPI_PROCFS
        if (acpi_ac_dir) {
                acpi_unlock_ac_dir(acpi_ac_dir);
                acpi_ac_dir = NULL;
@@ -1754,69 +974,58 @@ static void acpi_sbs_rmdirs(void)
                acpi_unlock_battery_dir(acpi_battery_dir);
                acpi_battery_dir = NULL;
        }
+#endif
 }
 
 static int acpi_sbs_resume(struct acpi_device *device)
 {
        struct acpi_sbs *sbs;
-
        if (!device)
                return -EINVAL;
-
        sbs = device->driver_data;
-
-       sbs->run_cnt = 0;
-
+       acpi_sbs_callback(sbs);
        return 0;
 }
 
+static struct acpi_driver acpi_sbs_driver = {
+       .name = "sbs",
+       .class = ACPI_SBS_CLASS,
+       .ids = sbs_device_ids,
+       .ops = {
+               .add = acpi_sbs_add,
+               .remove = acpi_sbs_remove,
+               .resume = acpi_sbs_resume,
+               },
+};
+
 static int __init acpi_sbs_init(void)
 {
        int result = 0;
 
        if (acpi_disabled)
                return -ENODEV;
-
-       if (capacity_mode != DEF_CAPACITY_UNIT
-           && capacity_mode != MAH_CAPACITY_UNIT
-           && capacity_mode != MWH_CAPACITY_UNIT) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "invalid capacity_mode = %d", capacity_mode));
-               return -EINVAL;
-       }
-
+#ifdef CONFIG_ACPI_PROCFS
        acpi_ac_dir = acpi_lock_ac_dir();
-       if (!acpi_ac_dir) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_lock_ac_dir() failed"));
+       if (!acpi_ac_dir)
                return -ENODEV;
-       }
-
        acpi_battery_dir = acpi_lock_battery_dir();
        if (!acpi_battery_dir) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_lock_battery_dir() failed"));
                acpi_sbs_rmdirs();
                return -ENODEV;
        }
-
+#endif
        result = acpi_bus_register_driver(&acpi_sbs_driver);
        if (result < 0) {
-               ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                               "acpi_bus_register_driver() failed"));
                acpi_sbs_rmdirs();
                return -ENODEV;
        }
-
        return 0;
 }
 
 static void __exit acpi_sbs_exit(void)
 {
        acpi_bus_unregister_driver(&acpi_sbs_driver);
-
        acpi_sbs_rmdirs();
-
        return;
 }
 
diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c
new file mode 100644 (file)
index 0000000..046d7c3
--- /dev/null
@@ -0,0 +1,309 @@
+/*
+ * SMBus driver for ACPI Embedded Controller (v0.1)
+ *
+ * Copyright (c) 2007 Alexey Starikovskiy
+ *
+ * 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.
+ */
+
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+#include <acpi/actypes.h>
+#include <linux/wait.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include "sbshc.h"
+
+#define ACPI_SMB_HC_CLASS      "smbus_host_controller"
+#define ACPI_SMB_HC_DEVICE_NAME        "ACPI SMBus HC"
+
+struct acpi_smb_hc {
+       struct acpi_ec *ec;
+       struct mutex lock;
+       wait_queue_head_t wait;
+       u8 offset;
+       u8 query_bit;
+       smbus_alarm_callback callback;
+       void *context;
+};
+
+static int acpi_smbus_hc_add(struct acpi_device *device);
+static int acpi_smbus_hc_remove(struct acpi_device *device, int type);
+
+static const struct acpi_device_id sbs_device_ids[] = {
+       {"ACPI0001", 0},
+       {"ACPI0005", 0},
+       {"", 0},
+};
+
+MODULE_DEVICE_TABLE(acpi, sbs_device_ids);
+
+static struct acpi_driver acpi_smb_hc_driver = {
+       .name = "smbus_hc",
+       .class = ACPI_SMB_HC_CLASS,
+       .ids = sbs_device_ids,
+       .ops = {
+               .add = acpi_smbus_hc_add,
+               .remove = acpi_smbus_hc_remove,
+               },
+};
+
+union acpi_smb_status {
+       u8 raw;
+       struct {
+               u8 status:5;
+               u8 reserved:1;
+               u8 alarm:1;
+               u8 done:1;
+       } fields;
+};
+
+enum acpi_smb_status_codes {
+       SMBUS_OK = 0,
+       SMBUS_UNKNOWN_FAILURE = 0x07,
+       SMBUS_DEVICE_ADDRESS_NACK = 0x10,
+       SMBUS_DEVICE_ERROR = 0x11,
+       SMBUS_DEVICE_COMMAND_ACCESS_DENIED = 0x12,
+       SMBUS_UNKNOWN_ERROR = 0x13,
+       SMBUS_DEVICE_ACCESS_DENIED = 0x17,
+       SMBUS_TIMEOUT = 0x18,
+       SMBUS_HOST_UNSUPPORTED_PROTOCOL = 0x19,
+       SMBUS_BUSY = 0x1a,
+       SMBUS_PEC_ERROR = 0x1f,
+};
+
+enum acpi_smb_offset {
+       ACPI_SMB_PROTOCOL = 0,  /* protocol, PEC */
+       ACPI_SMB_STATUS = 1,    /* status */
+       ACPI_SMB_ADDRESS = 2,   /* address */
+       ACPI_SMB_COMMAND = 3,   /* command */
+       ACPI_SMB_DATA = 4,      /* 32 data registers */
+       ACPI_SMB_BLOCK_COUNT = 0x24,    /* number of data bytes */
+       ACPI_SMB_ALARM_ADDRESS = 0x25,  /* alarm address */
+       ACPI_SMB_ALARM_DATA = 0x26,     /* 2 bytes alarm data */
+};
+
+static inline int smb_hc_read(struct acpi_smb_hc *hc, u8 address, u8 *data)
+{
+       return ec_read(hc->offset + address, data);
+}
+
+static inline int smb_hc_write(struct acpi_smb_hc *hc, u8 address, u8 data)
+{
+       return ec_write(hc->offset + address, data);
+}
+
+static inline int smb_check_done(struct acpi_smb_hc *hc)
+{
+       union acpi_smb_status status = {.raw = 0};
+       smb_hc_read(hc, ACPI_SMB_STATUS, &status.raw);
+       return status.fields.done && (status.fields.status == SMBUS_OK);
+}
+
+static int wait_transaction_complete(struct acpi_smb_hc *hc, int timeout)
+{
+       if (wait_event_timeout(hc->wait, smb_check_done(hc),
+                              msecs_to_jiffies(timeout)))
+               return 0;
+       else
+               return -ETIME;
+}
+
+int acpi_smbus_transaction(struct acpi_smb_hc *hc, u8 protocol, u8 address,
+                   u8 command, u8 *data, u8 length)
+{
+       int ret = -EFAULT, i;
+       u8 temp, sz = 0;
+
+       mutex_lock(&hc->lock);
+       if (smb_hc_read(hc, ACPI_SMB_PROTOCOL, &temp))
+               goto end;
+       if (temp) {
+               ret = -EBUSY;
+               goto end;
+       }
+       smb_hc_write(hc, ACPI_SMB_COMMAND, command);
+       smb_hc_write(hc, ACPI_SMB_COMMAND, command);
+       if (!(protocol & 0x01)) {
+               smb_hc_write(hc, ACPI_SMB_BLOCK_COUNT, length);
+               for (i = 0; i < length; ++i)
+                       smb_hc_write(hc, ACPI_SMB_DATA + i, data[i]);
+       }
+       smb_hc_write(hc, ACPI_SMB_ADDRESS, address << 1);
+       smb_hc_write(hc, ACPI_SMB_PROTOCOL, protocol);
+       /*
+        * Wait for completion. Save the status code, data size,
+        * and data into the return package (if required by the protocol).
+        */
+       ret = wait_transaction_complete(hc, 1000);
+       if (ret || !(protocol & 0x01))
+               goto end;
+       switch (protocol) {
+       case SMBUS_RECEIVE_BYTE:
+       case SMBUS_READ_BYTE:
+               sz = 1;
+               break;
+       case SMBUS_READ_WORD:
+               sz = 2;
+               break;
+       case SMBUS_READ_BLOCK:
+               if (smb_hc_read(hc, ACPI_SMB_BLOCK_COUNT, &sz)) {
+                       ret = -EFAULT;
+                       goto end;
+               }
+               sz &= 0x1f;
+               break;
+       }
+       for (i = 0; i < sz; ++i)
+               smb_hc_read(hc, ACPI_SMB_DATA + i, &data[i]);
+      end:
+       mutex_unlock(&hc->lock);
+       return ret;
+}
+
+int acpi_smbus_read(struct acpi_smb_hc *hc, u8 protocol, u8 address,
+                   u8 command, u8 *data)
+{
+       return acpi_smbus_transaction(hc, protocol, address, command, data, 0);
+}
+
+EXPORT_SYMBOL_GPL(acpi_smbus_read);
+
+int acpi_smbus_write(struct acpi_smb_hc *hc, u8 protocol, u8 address,
+                    u8 command, u8 *data, u8 length)
+{
+       return acpi_smbus_transaction(hc, protocol, address, command, data, length);
+}
+
+EXPORT_SYMBOL_GPL(acpi_smbus_write);
+
+int acpi_smbus_register_callback(struct acpi_smb_hc *hc,
+                                smbus_alarm_callback callback, void *context)
+{
+       mutex_lock(&hc->lock);
+       hc->callback = callback;
+       hc->context = context;
+       mutex_unlock(&hc->lock);
+       return 0;
+}
+
+EXPORT_SYMBOL_GPL(acpi_smbus_register_callback);
+
+int acpi_smbus_unregister_callback(struct acpi_smb_hc *hc)
+{
+       mutex_lock(&hc->lock);
+       hc->callback = NULL;
+       hc->context = NULL;
+       mutex_unlock(&hc->lock);
+       return 0;
+}
+
+EXPORT_SYMBOL_GPL(acpi_smbus_unregister_callback);
+
+static void acpi_smbus_callback(void *context)
+{
+       struct acpi_smb_hc *hc = context;
+
+       if (hc->callback)
+               hc->callback(hc->context);
+}
+
+static int smbus_alarm(void *context)
+{
+       struct acpi_smb_hc *hc = context;
+       union acpi_smb_status status;
+       if (smb_hc_read(hc, ACPI_SMB_STATUS, &status.raw))
+               return 0;
+       /* Check if it is only a completion notify */
+       if (status.fields.done)
+               wake_up(&hc->wait);
+       if (!status.fields.alarm)
+               return 0;
+       mutex_lock(&hc->lock);
+       smb_hc_write(hc, ACPI_SMB_STATUS, status.raw);
+       if (hc->callback)
+               acpi_os_execute(OSL_GPE_HANDLER, acpi_smbus_callback, hc);
+       mutex_unlock(&hc->lock);
+       return 0;
+}
+
+typedef int (*acpi_ec_query_func) (void *data);
+
+extern int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
+                             acpi_handle handle, acpi_ec_query_func func,
+                             void *data);
+
+static int acpi_smbus_hc_add(struct acpi_device *device)
+{
+       int status;
+       unsigned long val;
+       struct acpi_smb_hc *hc;
+
+       if (!device)
+               return -EINVAL;
+
+       status = acpi_evaluate_integer(device->handle, "_EC", NULL, &val);
+       if (ACPI_FAILURE(status)) {
+               printk(KERN_ERR PREFIX "error obtaining _EC.\n");
+               return -EIO;
+       }
+
+       strcpy(acpi_device_name(device), ACPI_SMB_HC_DEVICE_NAME);
+       strcpy(acpi_device_class(device), ACPI_SMB_HC_CLASS);
+
+       hc = kzalloc(sizeof(struct acpi_smb_hc), GFP_KERNEL);
+       if (!hc)
+               return -ENOMEM;
+       mutex_init(&hc->lock);
+       init_waitqueue_head(&hc->wait);
+
+       hc->ec = acpi_driver_data(device->parent);
+       hc->offset = (val >> 8) & 0xff;
+       hc->query_bit = val & 0xff;
+       acpi_driver_data(device) = 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",
+               hc->ec, hc->offset, hc->query_bit);
+
+       return 0;
+}
+
+extern void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit);
+
+static int acpi_smbus_hc_remove(struct acpi_device *device, int type)
+{
+       struct acpi_smb_hc *hc;
+
+       if (!device)
+               return -EINVAL;
+
+       hc = acpi_driver_data(device);
+       acpi_ec_remove_query_handler(hc->ec, hc->query_bit);
+       kfree(hc);
+       return 0;
+}
+
+static int __init acpi_smb_hc_init(void)
+{
+       int result;
+
+       result = acpi_bus_register_driver(&acpi_smb_hc_driver);
+       if (result < 0)
+               return -ENODEV;
+       return 0;
+}
+
+static void __exit acpi_smb_hc_exit(void)
+{
+       acpi_bus_unregister_driver(&acpi_smb_hc_driver);
+}
+
+module_init(acpi_smb_hc_init);
+module_exit(acpi_smb_hc_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Alexey Starikovskiy");
+MODULE_DESCRIPTION("ACPI SMBus HC driver");
diff --git a/drivers/acpi/sbshc.h b/drivers/acpi/sbshc.h
new file mode 100644 (file)
index 0000000..3bda349
--- /dev/null
@@ -0,0 +1,27 @@
+struct acpi_smb_hc;
+enum acpi_smb_protocol {
+       SMBUS_WRITE_QUICK = 2,
+       SMBUS_READ_QUICK = 3,
+       SMBUS_SEND_BYTE = 4,
+       SMBUS_RECEIVE_BYTE = 5,
+       SMBUS_WRITE_BYTE = 6,
+       SMBUS_READ_BYTE = 7,
+       SMBUS_WRITE_WORD  = 8,
+       SMBUS_READ_WORD  = 9,
+       SMBUS_WRITE_BLOCK = 0xa,
+       SMBUS_READ_BLOCK = 0xb,
+       SMBUS_PROCESS_CALL = 0xc,
+       SMBUS_BLOCK_PROCESS_CALL = 0xd,
+};
+
+static const u8 SMBUS_PEC = 0x80;
+
+typedef void (*smbus_alarm_callback)(void *context);
+
+extern int acpi_smbus_read(struct acpi_smb_hc *hc, u8 protocol, u8 address,
+              u8 command, u8 * data);
+extern int acpi_smbus_write(struct acpi_smb_hc *hc, u8 protocol, u8 slave_address,
+               u8 command, u8 * data, u8 length);
+extern int acpi_smbus_register_callback(struct acpi_smb_hc *hc,
+                                smbus_alarm_callback callback, void *context);
+extern int acpi_smbus_unregister_callback(struct acpi_smb_hc *hc);
index 5055acf2163c6d4e55fec3f68871c90ec6c41c1d..f3d3867303ec61602958f135494cc1ccbe86309b 100644 (file)
@@ -44,13 +44,12 @@ int acpi_sleep_prepare(u32 acpi_state)
        ACPI_FLUSH_CPU_CACHE();
        acpi_enable_wakeup_device_prep(acpi_state);
 #endif
-       acpi_gpe_sleep_prepare(acpi_state);
        acpi_enter_sleep_state_prep(acpi_state);
        return 0;
 }
 
 #ifdef CONFIG_SUSPEND
-static struct pm_ops acpi_pm_ops;
+static struct platform_suspend_ops acpi_pm_ops;
 
 extern void do_suspend_lowlevel(void);
 
@@ -85,13 +84,12 @@ static int acpi_pm_set_target(suspend_state_t pm_state)
 
 /**
  *     acpi_pm_prepare - Do preliminary suspend work.
- *     @pm_state: ignored
  *
  *     If necessary, set the firmware waking vector and do arch-specific
  *     nastiness to get the wakeup code to the waking vector.
  */
 
-static int acpi_pm_prepare(suspend_state_t pm_state)
+static int acpi_pm_prepare(void)
 {
        int error = acpi_sleep_prepare(acpi_target_sleep_state);
 
@@ -160,13 +158,12 @@ static int acpi_pm_enter(suspend_state_t pm_state)
 
 /**
  *     acpi_pm_finish - Finish up suspend sequence.
- *     @pm_state: ignored
  *
  *     This is called after we wake back up (or if entering the sleep state
  *     failed). 
  */
 
-static int acpi_pm_finish(suspend_state_t pm_state)
+static void acpi_pm_finish(void)
 {
        u32 acpi_state = acpi_target_sleep_state;
 
@@ -184,7 +181,6 @@ static int acpi_pm_finish(suspend_state_t pm_state)
                init_8259A(0);
        }
 #endif
-       return 0;
 }
 
 static int acpi_pm_state_valid(suspend_state_t pm_state)
@@ -203,7 +199,7 @@ static int acpi_pm_state_valid(suspend_state_t pm_state)
        }
 }
 
-static struct pm_ops acpi_pm_ops = {
+static struct platform_suspend_ops acpi_pm_ops = {
        .valid = acpi_pm_state_valid,
        .set_target = acpi_pm_set_target,
        .prepare = acpi_pm_prepare,
@@ -233,6 +229,12 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
 #endif /* CONFIG_SUSPEND */
 
 #ifdef CONFIG_HIBERNATION
+static int acpi_hibernation_start(void)
+{
+       acpi_target_sleep_state = ACPI_STATE_S4;
+       return 0;
+}
+
 static int acpi_hibernation_prepare(void)
 {
        return acpi_sleep_prepare(ACPI_STATE_S4);
@@ -254,13 +256,29 @@ static int acpi_hibernation_enter(void)
        return ACPI_SUCCESS(status) ? 0 : -EFAULT;
 }
 
+static void acpi_hibernation_leave(void)
+{
+       /*
+        * If ACPI is not enabled by the BIOS and the boot kernel, we need to
+        * enable it here.
+        */
+       acpi_enable();
+}
+
 static void acpi_hibernation_finish(void)
 {
+       /*
+        * If ACPI is not enabled by the BIOS and the boot kernel, we need to
+        * enable it here.
+        */
+       acpi_enable();
        acpi_leave_sleep_state(ACPI_STATE_S4);
        acpi_disable_wakeup_device(ACPI_STATE_S4);
 
        /* reset firmware waking vector */
        acpi_set_firmware_waking_vector((acpi_physical_address) 0);
+
+       acpi_target_sleep_state = ACPI_STATE_S0;
 }
 
 static int acpi_hibernation_pre_restore(void)
@@ -277,10 +295,13 @@ static void acpi_hibernation_restore_cleanup(void)
        acpi_hw_enable_all_runtime_gpes();
 }
 
-static struct hibernation_ops acpi_hibernation_ops = {
+static struct platform_hibernation_ops acpi_hibernation_ops = {
+       .start = acpi_hibernation_start,
+       .pre_snapshot = acpi_hibernation_prepare,
+       .finish = acpi_hibernation_finish,
        .prepare = acpi_hibernation_prepare,
        .enter = acpi_hibernation_enter,
-       .finish = acpi_hibernation_finish,
+       .leave = acpi_hibernation_leave,
        .pre_restore = acpi_hibernation_pre_restore,
        .restore_cleanup = acpi_hibernation_restore_cleanup,
 };
@@ -417,7 +438,7 @@ int __init acpi_sleep_init(void)
                }
        }
 
-       pm_set_ops(&acpi_pm_ops);
+       suspend_set_ops(&acpi_pm_ops);
 #endif
 
 #ifdef CONFIG_HIBERNATION
index ff1f8504f497e9a5127de4ce95a484b147771733..a2ea125ae2d0e961c52aa909bdbb9083e2e5ea97 100644 (file)
@@ -5,6 +5,5 @@ extern int acpi_suspend (u32 state);
 extern void acpi_enable_wakeup_device_prep(u8 sleep_state);
 extern void acpi_enable_wakeup_device(u8 sleep_state);
 extern void acpi_disable_wakeup_device(u8 sleep_state);
-extern void acpi_gpe_sleep_prepare(u32 sleep_state);
 
 extern int acpi_sleep_prepare(u32 acpi_state);
index 97c27ddb144ddced0025b646825ab06bdac60287..ed8e41becf0c4997177697157ac8ee8a368d9ab1 100644 (file)
@@ -64,36 +64,29 @@ void acpi_enable_wakeup_device(u8 sleep_state)
        ACPI_FUNCTION_TRACE("acpi_enable_wakeup_device");
        spin_lock(&acpi_device_lock);
        list_for_each_safe(node, next, &acpi_wakeup_device_list) {
-               struct acpi_device *dev = container_of(node,
-                                                      struct acpi_device,
-                                                      wakeup_list);
-
+               struct acpi_device *dev =
+                       container_of(node, struct acpi_device, wakeup_list);
+               if (!dev->wakeup.flags.valid)
+                       continue;
                /* If users want to disable run-wake GPE,
                 * we only disable it for wake and leave it for runtime
                 */
-               if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) {
-                       spin_unlock(&acpi_device_lock);
-                       acpi_set_gpe_type(dev->wakeup.gpe_device,
-                                         dev->wakeup.gpe_number,
-                                         ACPI_GPE_TYPE_RUNTIME);
-                       /* Re-enable it, since set_gpe_type will disable it */
-                       acpi_enable_gpe(dev->wakeup.gpe_device,
-                                       dev->wakeup.gpe_number, ACPI_ISR);
-                       spin_lock(&acpi_device_lock);
+               if (!dev->wakeup.state.enabled ||
+                   sleep_state > (u32) dev->wakeup.sleep_state) {
+                       if (dev->wakeup.flags.run_wake) {
+                               spin_unlock(&acpi_device_lock);
+                               /* set_gpe_type will disable GPE, leave it like that */
+                               acpi_set_gpe_type(dev->wakeup.gpe_device,
+                                                 dev->wakeup.gpe_number,
+                                                 ACPI_GPE_TYPE_RUNTIME);
+                               spin_lock(&acpi_device_lock);
+                       }
                        continue;
                }
-
-               if (!dev->wakeup.flags.valid ||
-                   !dev->wakeup.state.enabled ||
-                   (sleep_state > (u32) dev->wakeup.sleep_state))
-                       continue;
-
                spin_unlock(&acpi_device_lock);
-               /* run-wake GPE has been enabled */
                if (!dev->wakeup.flags.run_wake)
                        acpi_enable_gpe(dev->wakeup.gpe_device,
                                        dev->wakeup.gpe_number, ACPI_ISR);
-               dev->wakeup.state.active = 1;
                spin_lock(&acpi_device_lock);
        }
        spin_unlock(&acpi_device_lock);
@@ -112,26 +105,25 @@ void acpi_disable_wakeup_device(u8 sleep_state)
 
        spin_lock(&acpi_device_lock);
        list_for_each_safe(node, next, &acpi_wakeup_device_list) {
-               struct acpi_device *dev = container_of(node,
-                                                      struct acpi_device,
-                                                      wakeup_list);
+               struct acpi_device *dev =
+                       container_of(node, struct acpi_device, wakeup_list);
 
-               if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) {
-                       spin_unlock(&acpi_device_lock);
-                       acpi_set_gpe_type(dev->wakeup.gpe_device,
-                                         dev->wakeup.gpe_number,
-                                         ACPI_GPE_TYPE_WAKE_RUN);
-                       /* Re-enable it, since set_gpe_type will disable it */
-                       acpi_enable_gpe(dev->wakeup.gpe_device,
-                                       dev->wakeup.gpe_number, ACPI_NOT_ISR);
-                       spin_lock(&acpi_device_lock);
+               if (!dev->wakeup.flags.valid)
                        continue;
-               }
-
-               if (!dev->wakeup.flags.valid ||
-                   !dev->wakeup.state.active ||
-                   (sleep_state > (u32) dev->wakeup.sleep_state))
+               if (!dev->wakeup.state.enabled ||
+                   sleep_state > (u32) dev->wakeup.sleep_state) {
+                       if (dev->wakeup.flags.run_wake) {
+                               spin_unlock(&acpi_device_lock);
+                               acpi_set_gpe_type(dev->wakeup.gpe_device,
+                                                 dev->wakeup.gpe_number,
+                                                 ACPI_GPE_TYPE_WAKE_RUN);
+                               /* Re-enable it, since set_gpe_type will disable it */
+                               acpi_enable_gpe(dev->wakeup.gpe_device,
+                                               dev->wakeup.gpe_number, ACPI_NOT_ISR);
+                               spin_lock(&acpi_device_lock);
+                       }
                        continue;
+               }
 
                spin_unlock(&acpi_device_lock);
                acpi_disable_wakeup_device_power(dev);
@@ -142,7 +134,6 @@ void acpi_disable_wakeup_device(u8 sleep_state)
                        acpi_clear_gpe(dev->wakeup.gpe_device,
                                       dev->wakeup.gpe_number, ACPI_NOT_ISR);
                }
-               dev->wakeup.state.active = 0;
                spin_lock(&acpi_device_lock);
        }
        spin_unlock(&acpi_device_lock);
@@ -160,48 +151,20 @@ static int __init acpi_wakeup_device_init(void)
                struct acpi_device *dev = container_of(node,
                                                       struct acpi_device,
                                                       wakeup_list);
-
                /* In case user doesn't load button driver */
-               if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) {
-                       spin_unlock(&acpi_device_lock);
-                       acpi_set_gpe_type(dev->wakeup.gpe_device,
-                                         dev->wakeup.gpe_number,
-                                         ACPI_GPE_TYPE_WAKE_RUN);
-                       acpi_enable_gpe(dev->wakeup.gpe_device,
-                                       dev->wakeup.gpe_number, ACPI_NOT_ISR);
-                       dev->wakeup.state.enabled = 1;
-                       spin_lock(&acpi_device_lock);
-               }
+               if (!dev->wakeup.flags.run_wake || dev->wakeup.state.enabled)
+                       continue;
+               spin_unlock(&acpi_device_lock);
+               acpi_set_gpe_type(dev->wakeup.gpe_device,
+                                 dev->wakeup.gpe_number,
+                                 ACPI_GPE_TYPE_WAKE_RUN);
+               acpi_enable_gpe(dev->wakeup.gpe_device,
+                               dev->wakeup.gpe_number, ACPI_NOT_ISR);
+               dev->wakeup.state.enabled = 1;
+               spin_lock(&acpi_device_lock);
        }
        spin_unlock(&acpi_device_lock);
-
        return 0;
 }
 
 late_initcall(acpi_wakeup_device_init);
-
-/*
- * Disable all wakeup GPEs before entering requested sleep state.
- *     @sleep_state:   ACPI state
- * Since acpi_enter_sleep_state() will disable all
- * RUNTIME GPEs, we simply mark all GPES that
- * are not enabled for wakeup from requested state as RUNTIME.
- */
-void acpi_gpe_sleep_prepare(u32 sleep_state)
-{
-       struct list_head *node, *next;
-
-       list_for_each_safe(node, next, &acpi_wakeup_device_list) {
-               struct acpi_device *dev = container_of(node,
-                                                      struct acpi_device,
-                                                      wakeup_list);
-
-               /* The GPE can wakeup system from this state, don't touch it */
-               if ((u32) dev->wakeup.sleep_state >= sleep_state)
-                       continue;
-               /* acpi_set_gpe_type will automatically disable GPE */
-               acpi_set_gpe_type(dev->wakeup.gpe_device,
-                                 dev->wakeup.gpe_number,
-                                 ACPI_GPE_TYPE_RUNTIME);
-       }
-}
index 8cc9492ffbf209eadd01ff3f403d1ce964fd2bbc..5f1d85f2ffe4cf375b19a97d0a392bc5ed52d18a 100644 (file)
@@ -400,7 +400,7 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
        u32 table_count;
        struct acpi_table_header *table;
        acpi_physical_address address;
-       acpi_physical_address rsdt_address;
+       acpi_physical_address uninitialized_var(rsdt_address);
        u32 length;
        u8 *table_entry;
        acpi_status status;
index ad898e10c1a91162b42a18827678de93744a7a09..5f79b44512120e489950f65a22d912aa88ed66ec 100644 (file)
@@ -195,6 +195,7 @@ struct acpi_thermal {
        struct acpi_thermal_trips trips;
        struct acpi_handle_list devices;
        struct timer_list timer;
+       struct mutex lock;
 };
 
 static const struct file_operations acpi_thermal_state_fops = {
@@ -711,6 +712,7 @@ static void acpi_thermal_check(void *data)
        int result = 0;
        struct acpi_thermal *tz = data;
        unsigned long sleep_time = 0;
+       unsigned long timeout_jiffies = 0;
        int i = 0;
        struct acpi_thermal_state state;
 
@@ -720,11 +722,15 @@ static void acpi_thermal_check(void *data)
                return;
        }
 
+       /* Check if someone else is already running */
+       if (!mutex_trylock(&tz->lock))
+               return;
+
        state = tz->state;
 
        result = acpi_thermal_get_temperature(tz);
        if (result)
-               return;
+               goto unlock;
 
        memset(&tz->state, 0, sizeof(tz->state));
 
@@ -787,10 +793,13 @@ static void acpi_thermal_check(void *data)
         * a thermal event occurs).  Note that _TSP and _TZD values are
         * given in 1/10th seconds (we must covert to milliseconds).
         */
-       if (tz->state.passive)
+       if (tz->state.passive) {
                sleep_time = tz->trips.passive.tsp * 100;
-       else if (tz->polling_frequency > 0)
+               timeout_jiffies =  jiffies + (HZ * sleep_time) / 1000;
+       } else if (tz->polling_frequency > 0) {
                sleep_time = tz->polling_frequency * 100;
+               timeout_jiffies =  round_jiffies(jiffies + (HZ * sleep_time) / 1000);
+       }
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n",
                          tz->name, tz->temperature, sleep_time));
@@ -804,17 +813,16 @@ static void acpi_thermal_check(void *data)
                        del_timer(&(tz->timer));
        } else {
                if (timer_pending(&(tz->timer)))
-                       mod_timer(&(tz->timer),
-                                       jiffies + (HZ * sleep_time) / 1000);
+                       mod_timer(&(tz->timer), timeout_jiffies);
                else {
                        tz->timer.data = (unsigned long)tz;
                        tz->timer.function = acpi_thermal_run;
-                       tz->timer.expires = jiffies + (HZ * sleep_time) / 1000;
+                       tz->timer.expires = timeout_jiffies;
                        add_timer(&(tz->timer));
                }
        }
-
-       return;
+      unlock:
+       mutex_unlock(&tz->lock);
 }
 
 /* --------------------------------------------------------------------------
@@ -1251,7 +1259,7 @@ static int acpi_thermal_add(struct acpi_device *device)
        strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME);
        strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS);
        acpi_driver_data(device) = tz;
-
+       mutex_init(&tz->lock);
        result = acpi_thermal_get_info(tz);
        if (result)
                goto end;
@@ -1321,7 +1329,7 @@ static int acpi_thermal_remove(struct acpi_device *device, int type)
        }
 
        acpi_thermal_remove_fs(device);
-
+       mutex_destroy(&tz->lock);
        kfree(tz);
        return 0;
 }
index b8a2095cb5ee44f3ceea40ccdf7d11c9c9c58ca0..bac956b30c57b94fafe71c951331723122bbd926 100644 (file)
@@ -409,14 +409,17 @@ acpi_video_device_lcd_query_levels(struct acpi_video_device *device,
 static int
 acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
 {
-       int status;
+       int status = AE_OK;
        union acpi_object arg0 = { ACPI_TYPE_INTEGER };
        struct acpi_object_list args = { 1, &arg0 };
 
 
        arg0.integer.value = level;
-       status = acpi_evaluate_object(device->dev->handle, "_BCM", &args, NULL);
 
+       if (device->cap._BCM)
+               status = acpi_evaluate_object(device->dev->handle, "_BCM",
+                                             &args, NULL);
+       device->brightness->curr = level;
        return status;
 }
 
@@ -424,11 +427,11 @@ static int
 acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
                                        unsigned long *level)
 {
-       int status;
-
-       status = acpi_evaluate_integer(device->dev->handle, "_BQC", NULL, level);
-
-       return status;
+       if (device->cap._BQC)
+               return acpi_evaluate_integer(device->dev->handle, "_BQC", NULL,
+                                            level);
+       *level = device->brightness->curr;
+       return AE_OK;
 }
 
 static int
@@ -1633,9 +1636,20 @@ static int
 acpi_video_get_next_level(struct acpi_video_device *device,
                          u32 level_current, u32 event)
 {
-       int min, max, min_above, max_below, i, l;
+       int min, max, min_above, max_below, i, l, delta = 255;
        max = max_below = 0;
        min = min_above = 255;
+       /* Find closest level to level_current */
+       for (i = 0; i < device->brightness->count; i++) {
+               l = device->brightness->levels[i];
+               if (abs(l - level_current) < abs(delta)) {
+                       delta = l - level_current;
+                       if (!delta)
+                               break;
+               }
+       }
+       /* Ajust level_current to closest available level */
+       level_current += delta;
        for (i = 0; i < device->brightness->count; i++) {
                l = device->brightness->levels[i];
                if (l < min)
index 33f5eb038773afa73b893c4d0f91825a24bf2f37..ba63619ae5df20623ec530cc6eb7188da0b0c1df 100644 (file)
@@ -182,6 +182,15 @@ config PATA_ACPI
          firmware in the BIOS. This driver can sometimes handle
          otherwise unsupported hardware.
 
+config SATA_FSL
+       tristate "Freescale 3.0Gbps SATA support"
+       depends on PPC_MPC837x
+       help
+         This option enables support for Freescale 3.0Gbps SATA controller.
+         It can be found on MPC837x and MPC8315.
+
+         If unsure, say N.
+
 config PATA_ALI
        tristate "ALi PATA support (Experimental)"
        depends on PCI && EXPERIMENTAL
@@ -641,11 +650,4 @@ config PATA_BF54X
 
          If unsure, say N.
 
-config PATA_BF54X_DMA
-       bool "DMA mode"
-       depends on PATA_BF54X
-       default y
-       help
-         Enable DMA mode for Blackfin ATAPI controller.
-
 endif # ATA
index 6bdc307649e67fc66e12feb505017c29b5886395..b13feb2c5dae02cf934e1447b743a396749113fe 100644 (file)
@@ -17,6 +17,7 @@ obj-$(CONFIG_SATA_ULI)                += sata_uli.o
 obj-$(CONFIG_SATA_MV)          += sata_mv.o
 obj-$(CONFIG_SATA_INIC162X)    += sata_inic162x.o
 obj-$(CONFIG_PDC_ADMA)         += pdc_adma.o
+obj-$(CONFIG_SATA_FSL)         += sata_fsl.o
 
 obj-$(CONFIG_PATA_ALI)         += pata_ali.o
 obj-$(CONFIG_PATA_AMD)         += pata_amd.o
index 10bc3f64c453d50896be9178d20879aef65abb1a..47c8060405240bb7b2ac6797821a8b7d2d86ea52 100644 (file)
@@ -1479,7 +1479,7 @@ static void ahci_port_intr(struct ata_port *ap)
                return;
        }
 
-       /* hmmm... a spurious interupt */
+       /* hmmm... a spurious interrupt */
 
        /* if !NCQ, ignore.  No modern ATA device has broken HSM
         * implementation for non-NCQ commands.
index bbaa545ea999817200366d54f3ea4b65cb6f32af..69092bce1ada0a1c50557d2feaed479055b11def 100644 (file)
@@ -1392,7 +1392,7 @@ static void ata_qc_complete_internal(struct ata_queued_cmd *qc)
  *     @tf: Taskfile registers for the command and the result
  *     @cdb: CDB for packet command
  *     @dma_dir: Data tranfer direction of the command
- *     @sg: sg list for the data buffer of the command
+ *     @sgl: sg list for the data buffer of the command
  *     @n_elem: Number of sg entries
  *     @timeout: Timeout in msecs (0 for default)
  *
@@ -4296,7 +4296,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
                sg_last(sg, qc->orig_n_elem)->length += qc->pad_len;
                if (pad_buf) {
                        struct scatterlist *psg = &qc->pad_sgent;
-                       void *addr = kmap_atomic(psg->page, KM_IRQ0);
+                       void *addr = kmap_atomic(sg_page(psg), KM_IRQ0);
                        memcpy(addr + psg->offset, pad_buf, qc->pad_len);
                        kunmap_atomic(addr, KM_IRQ0);
                }
@@ -4686,11 +4686,11 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
                 * data in this function or read data in ata_sg_clean.
                 */
                offset = lsg->offset + lsg->length - qc->pad_len;
-               psg->page = nth_page(lsg->page, offset >> PAGE_SHIFT);
+               sg_set_page(psg, nth_page(sg_page(lsg), offset >> PAGE_SHIFT));
                psg->offset = offset_in_page(offset);
 
                if (qc->tf.flags & ATA_TFLAG_WRITE) {
-                       void *addr = kmap_atomic(psg->page, KM_IRQ0);
+                       void *addr = kmap_atomic(sg_page(psg), KM_IRQ0);
                        memcpy(pad_buf, addr + psg->offset, qc->pad_len);
                        kunmap_atomic(addr, KM_IRQ0);
                }
@@ -4836,7 +4836,7 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
        if (qc->curbytes == qc->nbytes - qc->sect_size)
                ap->hsm_task_state = HSM_ST_LAST;
 
-       page = qc->cursg->page;
+       page = sg_page(qc->cursg);
        offset = qc->cursg->offset + qc->cursg_ofs;
 
        /* get the current page and offset */
@@ -4988,7 +4988,7 @@ next_sg:
 
        sg = qc->cursg;
 
-       page = sg->page;
+       page = sg_page(sg);
        offset = sg->offset + qc->cursg_ofs;
 
        /* get the current page and offset */
index 9fbb39cd0f5892414a6cb72d4378de8c99da960f..5b758b9ad0b8186e7d925d87c52148d84316bcaa 100644 (file)
@@ -1544,7 +1544,7 @@ static unsigned int ata_scsi_rbuf_get(struct scsi_cmnd *cmd, u8 **buf_out)
        struct scatterlist *sg = scsi_sglist(cmd);
 
        if (sg) {
-               buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+               buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
                buflen = sg->length;
        } else {
                buf = NULL;
index 026439e05afe5e9a1a75ebaf246123c7fdc6c18b..8227c45109ecd95771a5cf7eb775fe715902971e 100644 (file)
@@ -156,7 +156,7 @@ void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
 {
        struct ata_ioports *ioaddr = &ap->ioaddr;
 
-       tf->command = ata_check_status(ap);
+       tf->command = ata_chk_status(ap);
        tf->feature = ioread8(ioaddr->error_addr);
        tf->nsect = ioread8(ioaddr->nsect_addr);
        tf->lbal = ioread8(ioaddr->lbal_addr);
@@ -856,7 +856,7 @@ err_out:
  *     @pdev: PCI device
  *
  *     Some PCI ATA devices report simplex mode but in fact can be told to
- *     enter non simplex mode. This implements the neccessary logic to
+ *     enter non simplex mode. This implements the necessary logic to
  *     perform the task on such devices. Calling it on other devices will
  *     have -undefined- behaviour.
  */
@@ -882,7 +882,7 @@ unsigned long ata_pci_default_filter(struct ata_device *adev, unsigned long xfer
        /* Filter out DMA modes if the device has been configured by
           the BIOS as PIO only */
 
-       if (adev->link->ap->ioaddr.bmdma_addr == 0)
+       if (adev->link->ap->ioaddr.bmdma_addr == NULL)
                xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
        return xfer_mask;
 }
index 5d3920f6fd690f0c3a145865026dfadfc6bc790d..0f6f7bcc3defa8e39bdb235bcdd7b18e086b4614 100644 (file)
@@ -370,8 +370,10 @@ static struct pci_driver pacpi_pci_driver = {
        .id_table               = pacpi_pci_tbl,
        .probe                  = pacpi_init_one,
        .remove                 = ata_pci_remove_one,
+#ifdef CONFIG_PM
        .suspend                = ata_pci_device_suspend,
        .resume                 = ata_pci_device_resume,
+#endif
 };
 
 static int __init pacpi_init(void)
index 747549e4563a0feaad6493965deed41032c6a82d..b5e38426b815ec4ed64854d467ee0548f1a90c8b 100644 (file)
@@ -1092,14 +1092,15 @@ static unsigned int bfin_bus_softreset(struct ata_port *ap,
  *     Note: Original code is ata_std_softreset().
  */
 
-static int bfin_std_softreset(struct ata_port *ap, unsigned int *classes,
+static int bfin_std_softreset(struct ata_link *link, unsigned int *classes,
                unsigned long deadline)
 {
+       struct ata_port *ap = link->ap;
        unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
        unsigned int devmask = 0, err_mask;
        u8 err;
 
-       if (ata_port_offline(ap)) {
+       if (ata_link_offline(link)) {
                classes[0] = ATA_DEV_NONE;
                goto out;
        }
@@ -1122,9 +1123,11 @@ static int bfin_std_softreset(struct ata_port *ap, unsigned int *classes,
        }
 
        /* determine by signature whether we have ATA or ATAPI devices */
-       classes[0] = ata_dev_try_classify(ap, 0, &err);
+       classes[0] = ata_dev_try_classify(&ap->link.device[0],
+                               devmask & (1 << 0), &err);
        if (slave_possible && err != 0x81)
-               classes[1] = ata_dev_try_classify(ap, 1, &err);
+               classes[1] = ata_dev_try_classify(&ap->link.device[1],
+                                       devmask & (1 << 1), &err);
 
  out:
        return 0;
@@ -1167,7 +1170,7 @@ static unsigned char bfin_bmdma_status(struct ata_port *ap)
 static void bfin_data_xfer(struct ata_device *adev, unsigned char *buf,
                           unsigned int buflen, int write_data)
 {
-       struct ata_port *ap = adev->ap;
+       struct ata_port *ap = adev->link->ap;
        unsigned int words = buflen >> 1;
        unsigned short *buf16 = (u16 *) buf;
        void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
@@ -1206,7 +1209,10 @@ static void bfin_irq_clear(struct ata_port *ap)
        void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
 
        pr_debug("in atapi irq clear\n");
-       ATAPI_SET_INT_STATUS(base, 0x1FF);
+
+       ATAPI_SET_INT_STATUS(base, ATAPI_GET_INT_STATUS(base)|ATAPI_DEV_INT
+               | MULTI_DONE_INT | UDMAIN_DONE_INT | UDMAOUT_DONE_INT
+               | MULTI_TERM_INT | UDMAIN_TERM_INT | UDMAOUT_TERM_INT);
 }
 
 /**
@@ -1233,33 +1239,6 @@ static unsigned char bfin_irq_on(struct ata_port *ap)
        return tmp;
 }
 
-/**
- *     bfin_irq_ack - Acknowledge a device interrupt.
- *     @ap: Port on which interrupts are enabled.
- *
- *     Note: Original code is ata_irq_ack().
- */
-
-static unsigned char bfin_irq_ack(struct ata_port *ap, unsigned int chk_drq)
-{
-       void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
-       unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
-       unsigned char status;
-
-       pr_debug("in atapi irq ack\n");
-       status = ata_busy_wait(ap, bits, 1000);
-       if (status & bits)
-               if (ata_msg_err(ap))
-                       dev_err(ap->dev, "abnormal status 0x%X\n", status);
-
-       /* get controller status; clear intr, err bits */
-       ATAPI_SET_INT_STATUS(base, ATAPI_GET_INT_STATUS(base)|ATAPI_DEV_INT
-               | MULTI_DONE_INT | UDMAIN_DONE_INT | UDMAOUT_DONE_INT
-               | MULTI_TERM_INT | UDMAIN_TERM_INT | UDMAOUT_TERM_INT);
-
-       return bfin_bmdma_status(ap);
-}
-
 /**
  *     bfin_bmdma_freeze - Freeze DMA controller port
  *     @ap: port to freeze
@@ -1308,8 +1287,9 @@ void bfin_bmdma_thaw(struct ata_port *ap)
  *     Note: Original code is ata_std_postreset().
  */
 
-static void bfin_std_postreset(struct ata_port *ap, unsigned int *classes)
+static void bfin_std_postreset(struct ata_link *link, unsigned int *classes)
 {
+       struct ata_port *ap = link->ap;
        void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
 
        /* re-enable interrupts */
@@ -1395,7 +1375,6 @@ static struct scsi_host_template bfin_sht = {
 };
 
 static const struct ata_port_operations bfin_pata_ops = {
-       .port_disable           = ata_port_disable,
        .set_piomode            = bfin_set_piomode,
        .set_dmamode            = bfin_set_dmamode,
 
@@ -1423,7 +1402,6 @@ static const struct ata_port_operations bfin_pata_ops = {
        .irq_handler            = ata_interrupt,
        .irq_clear              = bfin_irq_clear,
        .irq_on                 = bfin_irq_on,
-       .irq_ack                = bfin_irq_ack,
 
        .port_start             = bfin_port_start,
        .port_stop              = bfin_port_stop,
@@ -1437,11 +1415,7 @@ static struct ata_port_info bfin_port_info[] = {
                                | ATA_FLAG_NO_LEGACY,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0,
-#ifdef CONFIG_PATA_BF54X_DMA
-               .udma_mask      = ATA_UDMA5,
-#else
                .udma_mask      = 0,
-#endif
                .port_ops       = &bfin_pata_ops,
        },
 };
@@ -1607,9 +1581,25 @@ static struct platform_driver bfin_atapi_driver = {
        },
 };
 
+#define ATAPI_MODE_SIZE                10
+static char bfin_atapi_mode[ATAPI_MODE_SIZE];
+
 static int __init bfin_atapi_init(void)
 {
        pr_info("register bfin atapi driver\n");
+
+       switch(bfin_atapi_mode[0]) {
+       case 'p':
+       case 'P':
+               break;
+       case 'm':
+       case 'M':
+               bfin_port_info[0].mwdma_mask = ATA_MWDMA2;
+               break;
+       default:
+               bfin_port_info[0].udma_mask = ATA_UDMA5;
+       };
+
        return platform_driver_register(&bfin_atapi_driver);
 }
 
@@ -1620,6 +1610,13 @@ static void __exit bfin_atapi_exit(void)
 
 module_init(bfin_atapi_init);
 module_exit(bfin_atapi_exit);
+/*
+ * ATAPI mode:
+ * pio/PIO
+ * udma/UDMA (default)
+ * mwdma/MWDMA
+ */
+module_param_string(bfin_atapi_mode, bfin_atapi_mode, ATAPI_MODE_SIZE, 0);
 
 MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
 MODULE_DESCRIPTION("PATA driver for blackfin 54x ATAPI controller");
index 9e412c26b2a360202f951055071c4a3d82abd3da..7acbbd9ee4691d81ab576659e16feeb400457fa1 100644 (file)
@@ -215,7 +215,7 @@ static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
        regU &= ~(0x05 << adev->devno);
 
        if (adev->dma_mode >= XFER_UDMA_0) {
-               /* Merge thge timing value */
+               /* Merge the timing value */
                regU |= udma_data[adev->dma_mode - XFER_UDMA_0] << shift;
                /* Merge the control bits */
                regU |= 1 << adev->devno; /* UDMA on */
index 57e827e4109e939ac9e83561f8284bf19a0d6a9e..e1818fdd9159eaa4a87fc5326ce660c3531d3fcb 100644 (file)
@@ -138,7 +138,7 @@ static void cs5530_set_dmamode(struct ata_port *ap, struct ata_device *adev)
  *
  *     Called when the libata layer is about to issue a command. We wrap
  *     this interface so that we can load the correct ATA timings if
- *     neccessary.  Specifically we have a problem that there is only
+ *     necessary.  Specifically we have a problem that there is only
  *     one MWDMA/UDMA bit.
  */
 
index 3578593a882b503921ca139d2dfec11192ab2467..01324530d052c807ae31d82e94a1b22ae3002df6 100644 (file)
@@ -25,7 +25,7 @@
  * Documentation:
  *     Available from AMD web site.
  * TODO
- *     Review errata to see if serializing is neccessary
+ *     Review errata to see if serializing is necessary
  */
 
 #include <linux/kernel.h>
index 53070f6b1fc4e1c7e005482cb95c9f00cc92a351..d753e568588ea585e4fed4970e1940b63d4382d3 100644 (file)
@@ -40,7 +40,7 @@
 #include <asm/msr.h>
 
 #define DRV_NAME       "pata_cs5536"
-#define DRV_VERSION    "0.0.5"
+#define DRV_VERSION    "0.0.6"
 
 enum {
        CFG                     = 0,
@@ -214,7 +214,7 @@ static void cs5536_set_dmamode(struct ata_port *ap, struct ata_device *adev)
                cs5536_read(pdev, DTC, &dtc);
 
                dtc &= ~(IDE_DRV_MASK << dshift);
-               dtc |= mwdma_timings[mode] << dshift;
+               dtc |= mwdma_timings[mode - XFER_MW_DMA_0] << dshift;
 
                cs5536_write(pdev, DTC, dtc);
        }
index 988ef736b936ca7db206d62fbc6a9809bbdcff76..ca9aae09daed17b5dacfbf7b23e964a77b3d6077 100644 (file)
@@ -105,7 +105,7 @@ struct it821x_dev
 
 /*
  *     We allow users to force the card into non raid mode without
- *     flashing the alternative BIOS. This is also neccessary right now
+ *     flashing the alternative BIOS. This is also necessary right now
  *     for embedded platforms that cannot run a PC BIOS but are using this
  *     device.
  */
@@ -383,7 +383,7 @@ static void it821x_passthru_bmdma_stop(struct ata_queued_cmd *qc)
  *     @ap: ATA port
  *     @device: Device number (not pointer)
  *
- *     Device selection hook. If neccessary perform clock switching
+ *     Device selection hook. If necessary perform clock switching
  */
 
 static void it821x_passthru_dev_select(struct ata_port *ap,
index d5483087a3faa366db7895c15d26bcf827c38bd7..c0d9e0cf208c5737f57f32bac833b3f42d29feaa 100644 (file)
@@ -129,7 +129,7 @@ static void mpiix_set_piomode(struct ata_port *ap, struct ata_device *adev)
  *
  *     Called when the libata layer is about to issue a command. We wrap
  *     this interface so that we can load the correct ATA timings if
- *     neccessary. Our logic also clears TIME0/TIME1 for the other device so
+ *     necessary. Our logic also clears TIME0/TIME1 for the other device so
  *     that, even if we get this wrong, cycles to the other device will
  *     be made PIO0.
  */
index 6e8e55745b7b3943c6e9c757a38236ee7cfb65f1..9fe66fd75017ef692c98c141f523b7512d4329b0 100644 (file)
@@ -124,7 +124,7 @@ static void ns87410_set_piomode(struct ata_port *ap, struct ata_device *adev)
  *
  *     Called when the libata layer is about to issue a command. We wrap
  *     this interface so that we can load the correct ATA timings if
- *     neccessary.
+ *     necessary.
  */
 
 static unsigned int ns87410_qc_issue_prot(struct ata_queued_cmd *qc)
index 3cd5eb2b6c9191383ee2fa64acc81d7e129d9315..44da09ace52c53e98280f18f39659663ad87fe3a 100644 (file)
@@ -200,7 +200,7 @@ static void oldpiix_set_dmamode (struct ata_port *ap, struct ata_device *adev)
  *
  *     Called when the libata layer is about to issue a command. We wrap
  *     this interface so that we can load the correct ATA timings if
- *     neccessary. Our logic also clears TIME0/TIME1 for the other device so
+ *     necessary. Our logic also clears TIME0/TIME1 for the other device so
  *     that, even if we get this wrong, cycles to the other device will
  *     be made PIO0.
  */
index d5b76497f4a24ad891776e5d0a1b71d221954f05..8109b08fc0246f483f78fd350f1c0991abbc8b12 100644 (file)
@@ -161,7 +161,7 @@ static void radisys_set_dmamode (struct ata_port *ap, struct ata_device *adev)
  *
  *     Called when the libata layer is about to issue a command. We wrap
  *     this interface so that we can load the correct ATA timings if
- *     neccessary. Our logic also clears TIME0/TIME1 for the other device so
+ *     necessary. Our logic also clears TIME0/TIME1 for the other device so
  *     that, even if we get this wrong, cycles to the other device will
  *     be made PIO0.
  */
index 21ebc485ca4b4d71913a0ae302b35ba7f2924e35..725a8586cd6e40744a04c5091d3a642d2f9b65ca 100644 (file)
@@ -156,7 +156,7 @@ static void sc1200_set_dmamode(struct ata_port *ap, struct ata_device *adev)
  *
  *     Called when the libata layer is about to issue a command. We wrap
  *     this interface so that we can load the correct ATA timings if
- *     neccessary.  Specifically we have a problem that there is only
+ *     necessary.  Specifically we have a problem that there is only
  *     one MWDMA/UDMA bit.
  */
 
index 4dc2e73298fdeae67bfdbcc81a8031ed5a9b97bc..5c1e9cb59ecb66ed07ace0e1739516300e7c0280 100644 (file)
@@ -16,7 +16,7 @@
  *
  *     If you have strange problems with nVidia chipset systems please
  *     see the SI support documentation and update your system BIOS
- *     if neccessary
+ *     if necessary
  *
  * TODO
  *     If we know all our devices are LBA28 (or LBA28 sized)  we could use
index 5d41b6612d7f2626189e6a2653f47153f0cfd282..ea7a9a652e6118c8ab1cc2c20088abcb67670067 100644 (file)
@@ -420,7 +420,7 @@ static struct ata_port_operations via_port_ops_noirq = {
  *     @pdev: PCI device
  *     @flags: configuration flags
  *
- *     Set the FIFO properties for this device if neccessary. Used both on
+ *     Set the FIFO properties for this device if necessary. Used both on
  *     set up and on and the resume path
  */
 
index 8d1b03d5bcb1e65d63c5b67121791e8fe1eee77a..199f7e150eb37822f556753f7b7902580926aa3b 100644 (file)
@@ -318,7 +318,7 @@ static int adma_fill_sg(struct ata_queued_cmd *qc)
        struct scatterlist *sg;
        struct ata_port *ap = qc->ap;
        struct adma_port_priv *pp = ap->private_data;
-       u8  *buf = pp->pkt;
+       u8  *buf = pp->pkt, *last_buf = NULL;
        int i = (2 + buf[3]) * 8;
        u8 pFLAGS = pORD | ((qc->tf.flags & ATA_TFLAG_WRITE) ? pDIRO : 0);
 
@@ -334,8 +334,7 @@ static int adma_fill_sg(struct ata_queued_cmd *qc)
                *(__le32 *)(buf + i) = cpu_to_le32(len);
                i += 4;
 
-               if (ata_sg_is_last(sg, qc))
-                       pFLAGS |= pEND;
+               last_buf = &buf[i];
                buf[i++] = pFLAGS;
                buf[i++] = qc->dev->dma_mode & 0xf;
                buf[i++] = 0;   /* pPKLW */
@@ -348,6 +347,10 @@ static int adma_fill_sg(struct ata_queued_cmd *qc)
                VPRINTK("PRD[%u] = (0x%lX, 0x%X)\n", i/4,
                                        (unsigned long)addr, len);
        }
+
+       if (likely(last_buf))
+               *last_buf |= pEND;
+
        return i;
 }
 
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
new file mode 100644 (file)
index 0000000..b4c37b9
--- /dev/null
@@ -0,0 +1,1490 @@
+/*
+ * drivers/ata/sata_fsl.c
+ *
+ * Freescale 3.0Gbps SATA device driver
+ *
+ * Author: Ashish Kalra <ashish.kalra@freescale.com>
+ * Li Yang <leoli@freescale.com>
+ *
+ * Copyright (c) 2006-2007 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_cmnd.h>
+#include <linux/libata.h>
+#include <asm/io.h>
+#include <linux/of_platform.h>
+
+/* Controller information */
+enum {
+       SATA_FSL_QUEUE_DEPTH    = 16,
+       SATA_FSL_MAX_PRD        = 63,
+       SATA_FSL_MAX_PRD_USABLE = SATA_FSL_MAX_PRD - 1,
+       SATA_FSL_MAX_PRD_DIRECT = 16,   /* Direct PRDT entries */
+
+       SATA_FSL_HOST_FLAGS     = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+                               ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
+                               ATA_FLAG_NCQ  | ATA_FLAG_SKIP_D2H_BSY),
+
+       SATA_FSL_MAX_CMDS       = SATA_FSL_QUEUE_DEPTH,
+       SATA_FSL_CMD_HDR_SIZE   = 16,   /* 4 DWORDS */
+       SATA_FSL_CMD_SLOT_SIZE  = (SATA_FSL_MAX_CMDS * SATA_FSL_CMD_HDR_SIZE),
+
+       /*
+        * SATA-FSL host controller supports a max. of (15+1) direct PRDEs, and
+        * chained indirect PRDEs upto a max count of 63.
+        * We are allocating an array of 63 PRDEs contigiously, but PRDE#15 will
+        * be setup as an indirect descriptor, pointing to it's next
+        * (contigious) PRDE. Though chained indirect PRDE arrays are
+        * supported,it will be more efficient to use a direct PRDT and
+        * a single chain/link to indirect PRDE array/PRDT.
+        */
+
+       SATA_FSL_CMD_DESC_CFIS_SZ       = 32,
+       SATA_FSL_CMD_DESC_SFIS_SZ       = 32,
+       SATA_FSL_CMD_DESC_ACMD_SZ       = 16,
+       SATA_FSL_CMD_DESC_RSRVD         = 16,
+
+       SATA_FSL_CMD_DESC_SIZE  = (SATA_FSL_CMD_DESC_CFIS_SZ +
+                                SATA_FSL_CMD_DESC_SFIS_SZ +
+                                SATA_FSL_CMD_DESC_ACMD_SZ +
+                                SATA_FSL_CMD_DESC_RSRVD +
+                                SATA_FSL_MAX_PRD * 16),
+
+       SATA_FSL_CMD_DESC_OFFSET_TO_PRDT        =
+                               (SATA_FSL_CMD_DESC_CFIS_SZ +
+                                SATA_FSL_CMD_DESC_SFIS_SZ +
+                                SATA_FSL_CMD_DESC_ACMD_SZ +
+                                SATA_FSL_CMD_DESC_RSRVD),
+
+       SATA_FSL_CMD_DESC_AR_SZ = (SATA_FSL_CMD_DESC_SIZE * SATA_FSL_MAX_CMDS),
+       SATA_FSL_PORT_PRIV_DMA_SZ = (SATA_FSL_CMD_SLOT_SIZE +
+                                       SATA_FSL_CMD_DESC_AR_SZ),
+
+       /*
+        * MPC8315 has two SATA controllers, SATA1 & SATA2
+        * (one port per controller)
+        * MPC837x has 2/4 controllers, one port per controller
+        */
+
+       SATA_FSL_MAX_PORTS      = 1,
+
+       SATA_FSL_IRQ_FLAG       = IRQF_SHARED,
+};
+
+/*
+* Host Controller command register set - per port
+*/
+enum {
+       CQ = 0,
+       CA = 8,
+       CC = 0x10,
+       CE = 0x18,
+       DE = 0x20,
+       CHBA = 0x24,
+       HSTATUS = 0x28,
+       HCONTROL = 0x2C,
+       CQPMP = 0x30,
+       SIGNATURE = 0x34,
+       ICC = 0x38,
+
+       /*
+        * Host Status Register (HStatus) bitdefs
+        */
+       ONLINE = (1 << 31),
+       GOING_OFFLINE = (1 << 30),
+       BIST_ERR = (1 << 29),
+
+       FATAL_ERR_HC_MASTER_ERR = (1 << 18),
+       FATAL_ERR_PARITY_ERR_TX = (1 << 17),
+       FATAL_ERR_PARITY_ERR_RX = (1 << 16),
+       FATAL_ERR_DATA_UNDERRUN = (1 << 13),
+       FATAL_ERR_DATA_OVERRUN = (1 << 12),
+       FATAL_ERR_CRC_ERR_TX = (1 << 11),
+       FATAL_ERR_CRC_ERR_RX = (1 << 10),
+       FATAL_ERR_FIFO_OVRFL_TX = (1 << 9),
+       FATAL_ERR_FIFO_OVRFL_RX = (1 << 8),
+
+       FATAL_ERROR_DECODE = FATAL_ERR_HC_MASTER_ERR |
+           FATAL_ERR_PARITY_ERR_TX |
+           FATAL_ERR_PARITY_ERR_RX |
+           FATAL_ERR_DATA_UNDERRUN |
+           FATAL_ERR_DATA_OVERRUN |
+           FATAL_ERR_CRC_ERR_TX |
+           FATAL_ERR_CRC_ERR_RX |
+           FATAL_ERR_FIFO_OVRFL_TX | FATAL_ERR_FIFO_OVRFL_RX,
+
+       INT_ON_FATAL_ERR = (1 << 5),
+       INT_ON_PHYRDY_CHG = (1 << 4),
+
+       INT_ON_SIGNATURE_UPDATE = (1 << 3),
+       INT_ON_SNOTIFY_UPDATE = (1 << 2),
+       INT_ON_SINGL_DEVICE_ERR = (1 << 1),
+       INT_ON_CMD_COMPLETE = 1,
+
+       INT_ON_ERROR = INT_ON_FATAL_ERR |
+           INT_ON_PHYRDY_CHG | INT_ON_SINGL_DEVICE_ERR,
+
+       /*
+        * Host Control Register (HControl) bitdefs
+        */
+       HCONTROL_ONLINE_PHY_RST = (1 << 31),
+       HCONTROL_FORCE_OFFLINE = (1 << 30),
+       HCONTROL_PARITY_PROT_MOD = (1 << 14),
+       HCONTROL_DPATH_PARITY = (1 << 12),
+       HCONTROL_SNOOP_ENABLE = (1 << 10),
+       HCONTROL_PMP_ATTACHED = (1 << 9),
+       HCONTROL_COPYOUT_STATFIS = (1 << 8),
+       IE_ON_FATAL_ERR = (1 << 5),
+       IE_ON_PHYRDY_CHG = (1 << 4),
+       IE_ON_SIGNATURE_UPDATE = (1 << 3),
+       IE_ON_SNOTIFY_UPDATE = (1 << 2),
+       IE_ON_SINGL_DEVICE_ERR = (1 << 1),
+       IE_ON_CMD_COMPLETE = 1,
+
+       DEFAULT_PORT_IRQ_ENABLE_MASK = IE_ON_FATAL_ERR | IE_ON_PHYRDY_CHG |
+           IE_ON_SIGNATURE_UPDATE |
+           IE_ON_SINGL_DEVICE_ERR | IE_ON_CMD_COMPLETE,
+
+       EXT_INDIRECT_SEG_PRD_FLAG = (1 << 31),
+       DATA_SNOOP_ENABLE = (1 << 22),
+};
+
+/*
+ * SATA Superset Registers
+ */
+enum {
+       SSTATUS = 0,
+       SERROR = 4,
+       SCONTROL = 8,
+       SNOTIFY = 0xC,
+};
+
+/*
+ * Control Status Register Set
+ */
+enum {
+       TRANSCFG = 0,
+       TRANSSTATUS = 4,
+       LINKCFG = 8,
+       LINKCFG1 = 0xC,
+       LINKCFG2 = 0x10,
+       LINKSTATUS = 0x14,
+       LINKSTATUS1 = 0x18,
+       PHYCTRLCFG = 0x1C,
+       COMMANDSTAT = 0x20,
+};
+
+/* PHY (link-layer) configuration control */
+enum {
+       PHY_BIST_ENABLE = 0x01,
+};
+
+/*
+ * Command Header Table entry, i.e, command slot
+ * 4 Dwords per command slot, command header size ==  64 Dwords.
+ */
+struct cmdhdr_tbl_entry {
+       u32 cda;
+       u32 prde_fis_len;
+       u32 ttl;
+       u32 desc_info;
+};
+
+/*
+ * Description information bitdefs
+ */
+enum {
+       VENDOR_SPECIFIC_BIST = (1 << 10),
+       CMD_DESC_SNOOP_ENABLE = (1 << 9),
+       FPDMA_QUEUED_CMD = (1 << 8),
+       SRST_CMD = (1 << 7),
+       BIST = (1 << 6),
+       ATAPI_CMD = (1 << 5),
+};
+
+/*
+ * Command Descriptor
+ */
+struct command_desc {
+       u8 cfis[8 * 4];
+       u8 sfis[8 * 4];
+       u8 acmd[4 * 4];
+       u8 fill[4 * 4];
+       u32 prdt[SATA_FSL_MAX_PRD_DIRECT * 4];
+       u32 prdt_indirect[(SATA_FSL_MAX_PRD - SATA_FSL_MAX_PRD_DIRECT) * 4];
+};
+
+/*
+ * Physical region table descriptor(PRD)
+ */
+
+struct prde {
+       u32 dba;
+       u8 fill[2 * 4];
+       u32 ddc_and_ext;
+};
+
+/*
+ * ata_port private data
+ * This is our per-port instance data.
+ */
+struct sata_fsl_port_priv {
+       struct cmdhdr_tbl_entry *cmdslot;
+       dma_addr_t cmdslot_paddr;
+       struct command_desc *cmdentry;
+       dma_addr_t cmdentry_paddr;
+
+       /*
+        * SATA FSL controller has a Status FIS which should contain the
+        * received D2H FIS & taskfile registers. This SFIS is present in
+        * the command descriptor, and to have a ready reference to it,
+        * we are caching it here, quite similar to what is done in H/W on
+        * AHCI compliant devices by copying taskfile fields to a 32-bit
+        * register.
+        */
+
+       struct ata_taskfile tf;
+};
+
+/*
+ * ata_port->host_set private data
+ */
+struct sata_fsl_host_priv {
+       void __iomem *hcr_base;
+       void __iomem *ssr_base;
+       void __iomem *csr_base;
+};
+
+static inline unsigned int sata_fsl_tag(unsigned int tag,
+                                       void __iomem * hcr_base)
+{
+       /* We let libATA core do actual (queue) tag allocation */
+
+       /* all non NCQ/queued commands should have tag#0 */
+       if (ata_tag_internal(tag)) {
+               DPRINTK("mapping internal cmds to tag#0\n");
+               return 0;
+       }
+
+       if (unlikely(tag >= SATA_FSL_QUEUE_DEPTH)) {
+               DPRINTK("tag %d invalid : out of range\n", tag);
+               return 0;
+       }
+
+       if (unlikely((ioread32(hcr_base + CQ)) & (1 << tag))) {
+               DPRINTK("tag %d invalid : in use!!\n", tag);
+               return 0;
+       }
+
+       return tag;
+}
+
+static void sata_fsl_setup_cmd_hdr_entry(struct sata_fsl_port_priv *pp,
+                                        unsigned int tag, u32 desc_info,
+                                        u32 data_xfer_len, u8 num_prde,
+                                        u8 fis_len)
+{
+       dma_addr_t cmd_descriptor_address;
+
+       cmd_descriptor_address = pp->cmdentry_paddr +
+           tag * SATA_FSL_CMD_DESC_SIZE;
+
+       /* NOTE: both data_xfer_len & fis_len are Dword counts */
+
+       pp->cmdslot[tag].cda = cpu_to_le32(cmd_descriptor_address);
+       pp->cmdslot[tag].prde_fis_len =
+           cpu_to_le32((num_prde << 16) | (fis_len << 2));
+       pp->cmdslot[tag].ttl = cpu_to_le32(data_xfer_len & ~0x03);
+       pp->cmdslot[tag].desc_info = cpu_to_le32((desc_info | (tag & 0x1F)));
+
+       VPRINTK("cda=0x%x, prde_fis_len=0x%x, ttl=0x%x, di=0x%x\n",
+               pp->cmdslot[tag].cda,
+               pp->cmdslot[tag].prde_fis_len,
+               pp->cmdslot[tag].ttl, pp->cmdslot[tag].desc_info);
+
+}
+
+static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc,
+                                    u32 * ttl, dma_addr_t cmd_desc_paddr)
+{
+       struct scatterlist *sg;
+       unsigned int num_prde = 0;
+       u32 ttl_dwords = 0;
+
+       /*
+        * NOTE : direct & indirect prdt's are contigiously allocated
+        */
+       struct prde *prd = (struct prde *)&((struct command_desc *)
+                                           cmd_desc)->prdt;
+
+       struct prde *prd_ptr_to_indirect_ext = NULL;
+       unsigned indirect_ext_segment_sz = 0;
+       dma_addr_t indirect_ext_segment_paddr;
+
+       VPRINTK("SATA FSL : cd = 0x%x, prd = 0x%x\n", cmd_desc, prd);
+
+       indirect_ext_segment_paddr = cmd_desc_paddr +
+           SATA_FSL_CMD_DESC_OFFSET_TO_PRDT + SATA_FSL_MAX_PRD_DIRECT * 16;
+
+       ata_for_each_sg(sg, qc) {
+               dma_addr_t sg_addr = sg_dma_address(sg);
+               u32 sg_len = sg_dma_len(sg);
+
+               VPRINTK("SATA FSL : fill_sg, sg_addr = 0x%x, sg_len = %d\n",
+                       sg_addr, sg_len);
+
+               /* warn if each s/g element is not dword aligned */
+               if (sg_addr & 0x03)
+                       ata_port_printk(qc->ap, KERN_ERR,
+                                       "s/g addr unaligned : 0x%x\n", sg_addr);
+               if (sg_len & 0x03)
+                       ata_port_printk(qc->ap, KERN_ERR,
+                                       "s/g len unaligned : 0x%x\n", sg_len);
+
+               if ((num_prde == (SATA_FSL_MAX_PRD_DIRECT - 1)) &&
+                   !ata_sg_is_last(sg, qc)) {
+                       VPRINTK("setting indirect prde\n");
+                       prd_ptr_to_indirect_ext = prd;
+                       prd->dba = cpu_to_le32(indirect_ext_segment_paddr);
+                       indirect_ext_segment_sz = 0;
+                       ++prd;
+                       ++num_prde;
+               }
+
+               ttl_dwords += sg_len;
+               prd->dba = cpu_to_le32(sg_addr);
+               prd->ddc_and_ext =
+                   cpu_to_le32(DATA_SNOOP_ENABLE | (sg_len & ~0x03));
+
+               VPRINTK("sg_fill, ttl=%d, dba=0x%x, ddc=0x%x\n",
+                       ttl_dwords, prd->dba, prd->ddc_and_ext);
+
+               ++num_prde;
+               ++prd;
+               if (prd_ptr_to_indirect_ext)
+                       indirect_ext_segment_sz += sg_len;
+       }
+
+       if (prd_ptr_to_indirect_ext) {
+               /* set indirect extension flag along with indirect ext. size */
+               prd_ptr_to_indirect_ext->ddc_and_ext =
+                   cpu_to_le32((EXT_INDIRECT_SEG_PRD_FLAG |
+                                DATA_SNOOP_ENABLE |
+                                (indirect_ext_segment_sz & ~0x03)));
+       }
+
+       *ttl = ttl_dwords;
+       return num_prde;
+}
+
+static void sata_fsl_qc_prep(struct ata_queued_cmd *qc)
+{
+       struct ata_port *ap = qc->ap;
+       struct sata_fsl_port_priv *pp = ap->private_data;
+       struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+       void __iomem *hcr_base = host_priv->hcr_base;
+       unsigned int tag = sata_fsl_tag(qc->tag, hcr_base);
+       struct command_desc *cd;
+       u32 desc_info = CMD_DESC_SNOOP_ENABLE;
+       u32 num_prde = 0;
+       u32 ttl_dwords = 0;
+       dma_addr_t cd_paddr;
+
+       cd = (struct command_desc *)pp->cmdentry + tag;
+       cd_paddr = pp->cmdentry_paddr + tag * SATA_FSL_CMD_DESC_SIZE;
+
+       ata_tf_to_fis(&qc->tf, 0, 1, (u8 *) & cd->cfis);
+
+       VPRINTK("Dumping cfis : 0x%x, 0x%x, 0x%x\n",
+               cd->cfis[0], cd->cfis[1], cd->cfis[2]);
+
+       if (qc->tf.protocol == ATA_PROT_NCQ) {
+               VPRINTK("FPDMA xfer,Sctor cnt[0:7],[8:15] = %d,%d\n",
+                       cd->cfis[3], cd->cfis[11]);
+       }
+
+       /* setup "ACMD - atapi command" in cmd. desc. if this is ATAPI cmd */
+       if (is_atapi_taskfile(&qc->tf)) {
+               desc_info |= ATAPI_CMD;
+               memset((void *)&cd->acmd, 0, 32);
+               memcpy((void *)&cd->acmd, qc->cdb, qc->dev->cdb_len);
+       }
+
+       if (qc->flags & ATA_QCFLAG_DMAMAP)
+               num_prde = sata_fsl_fill_sg(qc, (void *)cd,
+                                           &ttl_dwords, cd_paddr);
+
+       if (qc->tf.protocol == ATA_PROT_NCQ)
+               desc_info |= FPDMA_QUEUED_CMD;
+
+       sata_fsl_setup_cmd_hdr_entry(pp, tag, desc_info, ttl_dwords,
+                                    num_prde, 5);
+
+       VPRINTK("SATA FSL : xx_qc_prep, di = 0x%x, ttl = %d, num_prde = %d\n",
+               desc_info, ttl_dwords, num_prde);
+}
+
+static unsigned int sata_fsl_qc_issue(struct ata_queued_cmd *qc)
+{
+       struct ata_port *ap = qc->ap;
+       struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+       void __iomem *hcr_base = host_priv->hcr_base;
+       unsigned int tag = sata_fsl_tag(qc->tag, hcr_base);
+
+       VPRINTK("xx_qc_issue called,CQ=0x%x,CA=0x%x,CE=0x%x,CC=0x%x\n",
+               ioread32(CQ + hcr_base),
+               ioread32(CA + hcr_base),
+               ioread32(CE + hcr_base), ioread32(CC + hcr_base));
+
+       /* Simply queue command to the controller/device */
+       iowrite32(1 << tag, CQ + hcr_base);
+
+       VPRINTK("xx_qc_issue called, tag=%d, CQ=0x%x, CA=0x%x\n",
+               tag, ioread32(CQ + hcr_base), ioread32(CA + hcr_base));
+
+       VPRINTK("CE=0x%x, DE=0x%x, CC=0x%x, CmdStat = 0x%x\n",
+               ioread32(CE + hcr_base),
+               ioread32(DE + hcr_base),
+               ioread32(CC + hcr_base), ioread32(COMMANDSTAT + csr_base));
+
+       return 0;
+}
+
+static int sata_fsl_scr_write(struct ata_port *ap, unsigned int sc_reg_in,
+                              u32 val)
+{
+       struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+       void __iomem *ssr_base = host_priv->ssr_base;
+       unsigned int sc_reg;
+
+       switch (sc_reg_in) {
+       case SCR_STATUS:
+               sc_reg = 0;
+               break;
+       case SCR_ERROR:
+               sc_reg = 1;
+               break;
+       case SCR_CONTROL:
+               sc_reg = 2;
+               break;
+       case SCR_ACTIVE:
+               sc_reg = 3;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       VPRINTK("xx_scr_write, reg_in = %d\n", sc_reg);
+
+       iowrite32(val, (void __iomem *)ssr_base + (sc_reg * 4));
+       return 0;
+}
+
+static int sata_fsl_scr_read(struct ata_port *ap, unsigned int sc_reg_in,
+                       u32 *val)
+{
+       struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+       void __iomem *ssr_base = host_priv->ssr_base;
+       unsigned int sc_reg;
+
+       switch (sc_reg_in) {
+       case SCR_STATUS:
+               sc_reg = 0;
+               break;
+       case SCR_ERROR:
+               sc_reg = 1;
+               break;
+       case SCR_CONTROL:
+               sc_reg = 2;
+               break;
+       case SCR_ACTIVE:
+               sc_reg = 3;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       VPRINTK("xx_scr_read, reg_in = %d\n", sc_reg);
+
+       *val = ioread32((void __iomem *)ssr_base + (sc_reg * 4));
+       return 0;
+}
+
+static void sata_fsl_freeze(struct ata_port *ap)
+{
+       struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+       void __iomem *hcr_base = host_priv->hcr_base;
+       u32 temp;
+
+       VPRINTK("xx_freeze, CQ=0x%x, CA=0x%x, CE=0x%x, DE=0x%x\n",
+               ioread32(CQ + hcr_base),
+               ioread32(CA + hcr_base),
+               ioread32(CE + hcr_base), ioread32(DE + hcr_base));
+       VPRINTK("CmdStat = 0x%x\n", ioread32(csr_base + COMMANDSTAT));
+
+       /* disable interrupts on the controller/port */
+       temp = ioread32(hcr_base + HCONTROL);
+       iowrite32((temp & ~0x3F), hcr_base + HCONTROL);
+
+       VPRINTK("in xx_freeze : HControl = 0x%x, HStatus = 0x%x\n",
+               ioread32(hcr_base + HCONTROL), ioread32(hcr_base + HSTATUS));
+}
+
+static void sata_fsl_thaw(struct ata_port *ap)
+{
+       struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+       void __iomem *hcr_base = host_priv->hcr_base;
+       u32 temp;
+
+       /* ack. any pending IRQs for this controller/port */
+       temp = ioread32(hcr_base + HSTATUS);
+
+       VPRINTK("xx_thaw, pending IRQs = 0x%x\n", (temp & 0x3F));
+
+       if (temp & 0x3F)
+               iowrite32((temp & 0x3F), hcr_base + HSTATUS);
+
+       /* enable interrupts on the controller/port */
+       temp = ioread32(hcr_base + HCONTROL);
+       iowrite32((temp | DEFAULT_PORT_IRQ_ENABLE_MASK), hcr_base + HCONTROL);
+
+       VPRINTK("xx_thaw : HControl = 0x%x, HStatus = 0x%x\n",
+               ioread32(hcr_base + HCONTROL), ioread32(hcr_base + HSTATUS));
+}
+
+/*
+ * NOTE : 1st D2H FIS from device does not update sfis in command descriptor.
+ */
+static inline void sata_fsl_cache_taskfile_from_d2h_fis(struct ata_queued_cmd
+                                                       *qc,
+                                                       struct ata_port *ap)
+{
+       struct sata_fsl_port_priv *pp = ap->private_data;
+       u8 fis[6 * 4];
+       struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+       void __iomem *hcr_base = host_priv->hcr_base;
+       unsigned int tag = sata_fsl_tag(qc->tag, hcr_base);
+       struct command_desc *cd;
+
+       cd = pp->cmdentry + tag;
+
+       memcpy(fis, &cd->sfis, 6 * 4);  /* should we use memcpy_from_io() */
+       ata_tf_from_fis(fis, &pp->tf);
+}
+
+static u8 sata_fsl_check_status(struct ata_port *ap)
+{
+       struct sata_fsl_port_priv *pp = ap->private_data;
+
+       return pp->tf.command;
+}
+
+static void sata_fsl_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
+{
+       struct sata_fsl_port_priv *pp = ap->private_data;
+
+       *tf = pp->tf;
+}
+
+static int sata_fsl_port_start(struct ata_port *ap)
+{
+       struct device *dev = ap->host->dev;
+       struct sata_fsl_port_priv *pp;
+       int retval;
+       void *mem;
+       dma_addr_t mem_dma;
+       struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+       void __iomem *hcr_base = host_priv->hcr_base;
+       u32 temp;
+
+       pp = kzalloc(sizeof(*pp), GFP_KERNEL);
+       if (!pp)
+               return -ENOMEM;
+
+       /*
+        * allocate per command dma alignment pad buffer, which is used
+        * internally by libATA to ensure that all transfers ending on
+        * unaligned boundaries are padded, to align on Dword boundaries
+        */
+       retval = ata_pad_alloc(ap, dev);
+       if (retval) {
+               kfree(pp);
+               return retval;
+       }
+
+       mem = dma_alloc_coherent(dev, SATA_FSL_PORT_PRIV_DMA_SZ, &mem_dma,
+                                GFP_KERNEL);
+       if (!mem) {
+               ata_pad_free(ap, dev);
+               kfree(pp);
+               return -ENOMEM;
+       }
+       memset(mem, 0, SATA_FSL_PORT_PRIV_DMA_SZ);
+
+       pp->cmdslot = mem;
+       pp->cmdslot_paddr = mem_dma;
+
+       mem += SATA_FSL_CMD_SLOT_SIZE;
+       mem_dma += SATA_FSL_CMD_SLOT_SIZE;
+
+       pp->cmdentry = mem;
+       pp->cmdentry_paddr = mem_dma;
+
+       ap->private_data = pp;
+
+       VPRINTK("CHBA = 0x%x, cmdentry_phys = 0x%x\n",
+               pp->cmdslot_paddr, pp->cmdentry_paddr);
+
+       /* Now, update the CHBA register in host controller cmd register set */
+       iowrite32(pp->cmdslot_paddr & 0xffffffff, hcr_base + CHBA);
+
+       /*
+        * Now, we can bring the controller on-line & also initiate
+        * the COMINIT sequence, we simply return here and the boot-probing
+        * & device discovery process is re-initiated by libATA using a
+        * Softreset EH (dummy) session. Hence, boot probing and device
+        * discovey will be part of sata_fsl_softreset() callback.
+        */
+
+       temp = ioread32(hcr_base + HCONTROL);
+       iowrite32((temp | HCONTROL_ONLINE_PHY_RST), hcr_base + HCONTROL);
+
+       VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
+       VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
+       VPRINTK("CHBA  = 0x%x\n", ioread32(hcr_base + CHBA));
+
+       /*
+        * Workaround for 8315DS board 3gbps link-up issue,
+        * currently limit SATA port to GEN1 speed
+        */
+       sata_fsl_scr_read(ap, SCR_CONTROL, &temp);
+       temp &= ~(0xF << 4);
+       temp |= (0x1 << 4);
+       sata_fsl_scr_write(ap, SCR_CONTROL, temp);
+
+       sata_fsl_scr_read(ap, SCR_CONTROL, &temp);
+       dev_printk(KERN_WARNING, dev, "scr_control, speed limited to %x\n",
+                       temp);
+
+       return 0;
+}
+
+static void sata_fsl_port_stop(struct ata_port *ap)
+{
+       struct device *dev = ap->host->dev;
+       struct sata_fsl_port_priv *pp = ap->private_data;
+       struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+       void __iomem *hcr_base = host_priv->hcr_base;
+       u32 temp;
+
+       /*
+        * Force host controller to go off-line, aborting current operations
+        */
+       temp = ioread32(hcr_base + HCONTROL);
+       temp &= ~HCONTROL_ONLINE_PHY_RST;
+       temp |= HCONTROL_FORCE_OFFLINE;
+       iowrite32(temp, hcr_base + HCONTROL);
+
+       /* Poll for controller to go offline - should happen immediately */
+       ata_wait_register(hcr_base + HSTATUS, ONLINE, ONLINE, 1, 1);
+
+       ap->private_data = NULL;
+       dma_free_coherent(dev, SATA_FSL_PORT_PRIV_DMA_SZ,
+                         pp->cmdslot, pp->cmdslot_paddr);
+
+       ata_pad_free(ap, dev);
+       kfree(pp);
+}
+
+static unsigned int sata_fsl_dev_classify(struct ata_port *ap)
+{
+       struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+       void __iomem *hcr_base = host_priv->hcr_base;
+       struct ata_taskfile tf;
+       u32 temp;
+
+       temp = ioread32(hcr_base + SIGNATURE);
+
+       VPRINTK("raw sig = 0x%x\n", temp);
+       VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
+       VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
+
+       tf.lbah = (temp >> 24) & 0xff;
+       tf.lbam = (temp >> 16) & 0xff;
+       tf.lbal = (temp >> 8) & 0xff;
+       tf.nsect = temp & 0xff;
+
+       return ata_dev_classify(&tf);
+}
+
+static int sata_fsl_softreset(struct ata_port *ap, unsigned int *class,
+                             unsigned long deadline)
+{
+       struct sata_fsl_port_priv *pp = ap->private_data;
+       struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+       void __iomem *hcr_base = host_priv->hcr_base;
+       u32 temp;
+       struct ata_taskfile tf;
+       u8 *cfis;
+       u32 Serror;
+       int i = 0;
+       struct ata_queued_cmd qc;
+       u8 *buf;
+       dma_addr_t dma_address;
+       struct scatterlist *sg;
+       unsigned long start_jiffies;
+
+       DPRINTK("in xx_softreset\n");
+
+try_offline_again:
+       /*
+        * Force host controller to go off-line, aborting current operations
+        */
+       temp = ioread32(hcr_base + HCONTROL);
+       temp &= ~HCONTROL_ONLINE_PHY_RST;
+       iowrite32(temp, hcr_base + HCONTROL);
+
+       /* Poll for controller to go offline */
+       temp = ata_wait_register(hcr_base + HSTATUS, ONLINE, ONLINE, 1, 500);
+
+       if (temp & ONLINE) {
+               ata_port_printk(ap, KERN_ERR,
+                               "Softreset failed, not off-lined %d\n", i);
+
+               /*
+                * Try to offline controller atleast twice
+                */
+               i++;
+               if (i == 2)
+                       goto err;
+               else
+                       goto try_offline_again;
+       }
+
+       DPRINTK("softreset, controller off-lined\n");
+       VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
+       VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
+
+       /*
+        * PHY reset should remain asserted for atleast 1ms
+        */
+       msleep(1);
+
+       /*
+        * Now, bring the host controller online again, this can take time
+        * as PHY reset and communication establishment, 1st D2H FIS and
+        * device signature update is done, on safe side assume 500ms
+        * NOTE : Host online status may be indicated immediately!!
+        */
+
+       temp = ioread32(hcr_base + HCONTROL);
+       temp |= (HCONTROL_ONLINE_PHY_RST | HCONTROL_SNOOP_ENABLE);
+       iowrite32(temp, hcr_base + HCONTROL);
+
+       temp = ata_wait_register(hcr_base + HSTATUS, ONLINE, 0, 1, 500);
+
+       if (!(temp & ONLINE)) {
+               ata_port_printk(ap, KERN_ERR,
+                               "Softreset failed, not on-lined\n");
+               goto err;
+       }
+
+       DPRINTK("softreset, controller off-lined & on-lined\n");
+       VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
+       VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
+
+       /*
+        * First, wait for the PHYRDY change to occur before waiting for
+        * the signature, and also verify if SStatus indicates device
+        * presence
+        */
+
+       temp = ata_wait_register(hcr_base + HSTATUS, 0xFF, 0, 1, 500);
+       if ((!(temp & 0x10)) || ata_port_offline(ap)) {
+               ata_port_printk(ap, KERN_WARNING,
+                               "No Device OR PHYRDY change,Hstatus = 0x%x\n",
+                               ioread32(hcr_base + HSTATUS));
+               goto err;
+       }
+
+       /*
+        * Wait for the first D2H from device,i.e,signature update notification
+        */
+       start_jiffies = jiffies;
+       temp = ata_wait_register(hcr_base + HSTATUS, 0xFF, 0x10,
+                       500, jiffies_to_msecs(deadline - start_jiffies));
+
+       if ((temp & 0xFF) != 0x18) {
+               ata_port_printk(ap, KERN_WARNING, "No Signature Update\n");
+               goto err;
+       } else {
+               ata_port_printk(ap, KERN_INFO,
+                               "Signature Update detected @ %d msecs\n",
+                               jiffies_to_msecs(jiffies - start_jiffies));
+       }
+
+       /*
+        * Send a device reset (SRST) explicitly on command slot #0
+        * Check : will the command queue (reg) be cleared during offlining ??
+        * Also we will be online only if Phy commn. has been established
+        * and device presence has been detected, therefore if we have
+        * reached here, we can send a command to the target device
+        */
+
+       if (ap->sactive)
+               goto skip_srst_do_ncq_error_handling;
+
+       DPRINTK("Sending SRST/device reset\n");
+
+       ata_tf_init(ap->device, &tf);
+       cfis = (u8 *) & pp->cmdentry->cfis;
+
+       /* device reset/SRST is a control register update FIS, uses tag0 */
+       sata_fsl_setup_cmd_hdr_entry(pp, 0,
+                                    SRST_CMD | CMD_DESC_SNOOP_ENABLE, 0, 0, 5);
+
+       tf.ctl |= ATA_SRST;     /* setup SRST bit in taskfile control reg */
+       ata_tf_to_fis(&tf, 0, 0, cfis);
+
+       DPRINTK("Dumping cfis : 0x%x, 0x%x, 0x%x, 0x%x\n",
+               cfis[0], cfis[1], cfis[2], cfis[3]);
+
+       /*
+        * Queue SRST command to the controller/device, ensure that no
+        * other commands are active on the controller/device
+        */
+
+       DPRINTK("@Softreset, CQ = 0x%x, CA = 0x%x, CC = 0x%x\n",
+               ioread32(CQ + hcr_base),
+               ioread32(CA + hcr_base), ioread32(CC + hcr_base));
+
+       iowrite32(0xFFFF, CC + hcr_base);
+       iowrite32(1, CQ + hcr_base);
+
+       temp = ata_wait_register(CQ + hcr_base, 0x1, 0x1, 1, 5000);
+       if (temp & 0x1) {
+               ata_port_printk(ap, KERN_WARNING, "ATA_SRST issue failed\n");
+
+               DPRINTK("Softreset@5000,CQ=0x%x,CA=0x%x,CC=0x%x\n",
+                       ioread32(CQ + hcr_base),
+                       ioread32(CA + hcr_base), ioread32(CC + hcr_base));
+
+               sata_fsl_scr_read(ap, SCR_ERROR, &Serror);
+
+               DPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
+               DPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
+               DPRINTK("Serror = 0x%x\n", Serror);
+               goto err;
+       }
+
+       msleep(1);
+
+       /*
+        * SATA device enters reset state after receving a Control register
+        * FIS with SRST bit asserted and it awaits another H2D Control reg.
+        * FIS with SRST bit cleared, then the device does internal diags &
+        * initialization, followed by indicating it's initialization status
+        * using ATA signature D2H register FIS to the host controller.
+        */
+
+       sata_fsl_setup_cmd_hdr_entry(pp, 0, CMD_DESC_SNOOP_ENABLE, 0, 0, 5);
+
+       tf.ctl &= ~ATA_SRST;    /* 2nd H2D Ctl. register FIS */
+       ata_tf_to_fis(&tf, 0, 0, cfis);
+
+       iowrite32(1, CQ + hcr_base);
+       msleep(150);            /* ?? */
+
+       /*
+        * The above command would have signalled an interrupt on command
+        * complete, which needs special handling, by clearing the Nth
+        * command bit of the CCreg
+        */
+       iowrite32(0x01, CC + hcr_base); /* We know it will be cmd#0 always */
+       goto check_device_signature;
+
+skip_srst_do_ncq_error_handling:
+
+       VPRINTK("Sending read log ext(10h) command\n");
+
+       memset(&qc, 0, sizeof(struct ata_queued_cmd));
+       ata_tf_init(ap->device, &tf);
+
+       tf.command = ATA_CMD_READ_LOG_EXT;
+       tf.lbal = ATA_LOG_SATA_NCQ;
+       tf.nsect = 1;
+       tf.hob_nsect = 0;
+       tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_LBA48 | ATA_TFLAG_DEVICE;
+       tf.protocol = ATA_PROT_PIO;
+
+       qc.tag = ATA_TAG_INTERNAL;
+       qc.scsicmd = NULL;
+       qc.ap = ap;
+       qc.dev = ap->device;
+
+       qc.tf = tf;
+       qc.flags |= ATA_QCFLAG_RESULT_TF;
+       qc.dma_dir = DMA_FROM_DEVICE;
+
+       buf = ap->sector_buf;
+       ata_sg_init_one(&qc, buf, 1 * ATA_SECT_SIZE);
+
+       /*
+        * Need to DMA-map the memory buffer associated with the command
+        */
+
+       sg = qc.__sg;
+       dma_address = dma_map_single(ap->dev, qc.buf_virt,
+                                    sg->length, DMA_FROM_DEVICE);
+
+       sg_dma_address(sg) = dma_address;
+       sg_dma_len(sg) = sg->length;
+
+       VPRINTK("EH, addr = 0x%x, len = 0x%x\n", dma_address, sg->length);
+
+       sata_fsl_qc_prep(&qc);
+       sata_fsl_qc_issue(&qc);
+
+       temp = ata_wait_register(CQ + hcr_base, 0x1, 0x1, 1, 5000);
+       if (temp & 0x1) {
+               VPRINTK("READ_LOG_EXT_10H issue failed\n");
+
+               VPRINTK("READ_LOG@5000,CQ=0x%x,CA=0x%x,CC=0x%x\n",
+                       ioread32(CQ + hcr_base),
+                       ioread32(CA + hcr_base), ioread32(CC + hcr_base));
+
+               sata_fsl_scr_read(ap, SCR_ERROR, &Serror);
+
+               VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
+               VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
+               VPRINTK("Serror = 0x%x\n", Serror);
+               goto err;
+       }
+
+       iowrite32(0x01, CC + hcr_base); /* We know it will be cmd#0 always */
+
+      check_device_signature:
+
+       DPRINTK("SATA FSL : Now checking device signature\n");
+
+       *class = ATA_DEV_NONE;
+
+       /* Verify if SStatus indicates device presence */
+       if (ata_port_online(ap)) {
+               /*
+                * if we are here, device presence has been detected,
+                * 1st D2H FIS would have been received, but sfis in
+                * command desc. is not updated, but signature register
+                * would have been updated
+                */
+
+               *class = sata_fsl_dev_classify(ap);
+
+               DPRINTK("class = %d\n", *class);
+               VPRINTK("ccreg = 0x%x\n", ioread32(hcr_base + CC));
+               VPRINTK("cereg = 0x%x\n", ioread32(hcr_base + CE));
+       }
+
+       return 0;
+
+err:
+       return -EIO;
+}
+
+static int sata_fsl_hardreset(struct ata_port *ap, unsigned int *class,
+                             unsigned long deadline)
+{
+       int retval;
+
+       retval = sata_std_hardreset(ap, class, deadline);
+
+       DPRINTK("SATA FSL : in xx_hardreset, retval = 0x%d\n", retval);
+
+       return retval;
+}
+
+static void sata_fsl_error_handler(struct ata_port *ap)
+{
+
+       DPRINTK("in xx_error_handler\n");
+
+       /* perform recovery */
+       ata_do_eh(ap, ata_std_prereset, sata_fsl_softreset, sata_fsl_hardreset,
+                 ata_std_postreset);
+}
+
+static void sata_fsl_post_internal_cmd(struct ata_queued_cmd *qc)
+{
+       if (qc->flags & ATA_QCFLAG_FAILED)
+               qc->err_mask |= AC_ERR_OTHER;
+
+       if (qc->err_mask) {
+               /* make DMA engine forget about the failed command */
+
+       }
+}
+
+static void sata_fsl_irq_clear(struct ata_port *ap)
+{
+       /* unused */
+}
+
+static void sata_fsl_error_intr(struct ata_port *ap)
+{
+       struct ata_eh_info *ehi = &ap->eh_info;
+       struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+       void __iomem *hcr_base = host_priv->hcr_base;
+       u32 hstatus, dereg, cereg = 0, SError = 0;
+       unsigned int err_mask = 0, action = 0;
+       struct ata_queued_cmd *qc;
+       int freeze = 0;
+
+       hstatus = ioread32(hcr_base + HSTATUS);
+       cereg = ioread32(hcr_base + CE);
+
+       ata_ehi_clear_desc(ehi);
+
+       /*
+        * Handle & Clear SError
+        */
+
+       sata_fsl_scr_read(ap, SCR_ERROR, &SError);
+       if (unlikely(SError & 0xFFFF0000)) {
+               sata_fsl_scr_write(ap, SCR_ERROR, SError);
+               err_mask |= AC_ERR_ATA_BUS;
+       }
+
+       DPRINTK("error_intr,hStat=0x%x,CE=0x%x,DE =0x%x,SErr=0x%x\n",
+               hstatus, cereg, ioread32(hcr_base + DE), SError);
+
+       /* handle single device errors */
+       if (cereg) {
+               /*
+                * clear the command error, also clears queue to the device
+                * in error, and we can (re)issue commands to this device.
+                * When a device is in error all commands queued into the
+                * host controller and at the device are considered aborted
+                * and the queue for that device is stopped. Now, after
+                * clearing the device error, we can issue commands to the
+                * device to interrogate it to find the source of the error.
+                */
+               dereg = ioread32(hcr_base + DE);
+               iowrite32(dereg, hcr_base + DE);
+               iowrite32(cereg, hcr_base + CE);
+
+               DPRINTK("single device error, CE=0x%x, DE=0x%x\n",
+                       ioread32(hcr_base + CE), ioread32(hcr_base + DE));
+               /*
+                * We should consider this as non fatal error, and TF must
+                * be updated as done below.
+                */
+
+               err_mask |= AC_ERR_DEV;
+       }
+
+       /* handle fatal errors */
+       if (hstatus & FATAL_ERROR_DECODE) {
+               err_mask |= AC_ERR_ATA_BUS;
+               action |= ATA_EH_SOFTRESET;
+               /* how will fatal error interrupts be completed ?? */
+               freeze = 1;
+       }
+
+       /* Handle PHYRDY change notification */
+       if (hstatus & INT_ON_PHYRDY_CHG) {
+               DPRINTK("SATA FSL: PHYRDY change indication\n");
+
+               /* Setup a soft-reset EH action */
+               ata_ehi_hotplugged(ehi);
+               freeze = 1;
+       }
+
+       /* record error info */
+       qc = ata_qc_from_tag(ap, ap->active_tag);
+
+       if (qc) {
+               sata_fsl_cache_taskfile_from_d2h_fis(qc, qc->ap);
+               qc->err_mask |= err_mask;
+       } else
+               ehi->err_mask |= err_mask;
+
+       ehi->action |= action;
+       ehi->serror |= SError;
+
+       /* freeze or abort */
+       if (freeze)
+               ata_port_freeze(ap);
+       else
+               ata_port_abort(ap);
+}
+
+static void sata_fsl_qc_complete(struct ata_queued_cmd *qc)
+{
+       if (qc->flags & ATA_QCFLAG_RESULT_TF) {
+               DPRINTK("xx_qc_complete called\n");
+               sata_fsl_cache_taskfile_from_d2h_fis(qc, qc->ap);
+       }
+}
+
+static void sata_fsl_host_intr(struct ata_port *ap)
+{
+       struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+       void __iomem *hcr_base = host_priv->hcr_base;
+       u32 hstatus, qc_active = 0;
+       struct ata_queued_cmd *qc;
+       u32 SError;
+
+       hstatus = ioread32(hcr_base + HSTATUS);
+
+       sata_fsl_scr_read(ap, SCR_ERROR, &SError);
+
+       if (unlikely(SError & 0xFFFF0000)) {
+               DPRINTK("serror @host_intr : 0x%x\n", SError);
+               sata_fsl_error_intr(ap);
+
+       }
+
+       if (unlikely(hstatus & INT_ON_ERROR)) {
+               DPRINTK("error interrupt!!\n");
+               sata_fsl_error_intr(ap);
+               return;
+       }
+
+       if (ap->sactive) {      /* only true for NCQ commands */
+               int i;
+               /* Read command completed register */
+               qc_active = ioread32(hcr_base + CC);
+               /* clear CC bit, this will also complete the interrupt */
+               iowrite32(qc_active, hcr_base + CC);
+
+               DPRINTK("Status of all queues :\n");
+               DPRINTK("qc_active/CC = 0x%x, CA = 0x%x, CE=0x%x\n",
+                       qc_active, ioread32(hcr_base + CA),
+                       ioread32(hcr_base + CE));
+
+               for (i = 0; i < SATA_FSL_QUEUE_DEPTH; i++) {
+                       if (qc_active & (1 << i)) {
+                               qc = ata_qc_from_tag(ap, i);
+                               if (qc) {
+                                       sata_fsl_qc_complete(qc);
+                                       ata_qc_complete(qc);
+                               }
+                               DPRINTK
+                                   ("completing ncq cmd,tag=%d,CC=0x%x,CA=0x%x\n",
+                                    i, ioread32(hcr_base + CC),
+                                    ioread32(hcr_base + CA));
+                       }
+               }
+               return;
+
+       } else if (ap->qc_active) {
+               iowrite32(1, hcr_base + CC);
+               qc = ata_qc_from_tag(ap, ap->active_tag);
+
+               DPRINTK("completing non-ncq cmd, tag=%d,CC=0x%x\n",
+                       ap->active_tag, ioread32(hcr_base + CC));
+
+               if (qc) {
+                       sata_fsl_qc_complete(qc);
+                       ata_qc_complete(qc);
+               }
+       } else {
+               /* Spurious Interrupt!! */
+               DPRINTK("spurious interrupt!!, CC = 0x%x\n",
+                       ioread32(hcr_base + CC));
+               return;
+       }
+}
+
+static irqreturn_t sata_fsl_interrupt(int irq, void *dev_instance)
+{
+       struct ata_host *host = dev_instance;
+       struct sata_fsl_host_priv *host_priv = host->private_data;
+       void __iomem *hcr_base = host_priv->hcr_base;
+       u32 interrupt_enables;
+       unsigned handled = 0;
+       struct ata_port *ap;
+
+       /* ack. any pending IRQs for this controller/port */
+       interrupt_enables = ioread32(hcr_base + HSTATUS);
+       interrupt_enables &= 0x3F;
+
+       DPRINTK("interrupt status 0x%x\n", interrupt_enables);
+
+       if (!interrupt_enables)
+               return IRQ_NONE;
+
+       spin_lock(&host->lock);
+
+       /* Assuming one port per host controller */
+
+       ap = host->ports[0];
+       if (ap) {
+               sata_fsl_host_intr(ap);
+       } else {
+               dev_printk(KERN_WARNING, host->dev,
+                          "interrupt on disabled port 0\n");
+       }
+
+       iowrite32(interrupt_enables, hcr_base + HSTATUS);
+       handled = 1;
+
+       spin_unlock(&host->lock);
+
+       return IRQ_RETVAL(handled);
+}
+
+/*
+ * Multiple ports are represented by multiple SATA controllers with
+ * one port per controller
+ */
+static int sata_fsl_init_controller(struct ata_host *host)
+{
+       struct sata_fsl_host_priv *host_priv = host->private_data;
+       void __iomem *hcr_base = host_priv->hcr_base;
+       u32 temp;
+
+       /*
+        * NOTE : We cannot bring the controller online before setting
+        * the CHBA, hence main controller initialization is done as
+        * part of the port_start() callback
+        */
+
+       /* ack. any pending IRQs for this controller/port */
+       temp = ioread32(hcr_base + HSTATUS);
+       if (temp & 0x3F)
+               iowrite32((temp & 0x3F), hcr_base + HSTATUS);
+
+       /* Keep interrupts disabled on the controller */
+       temp = ioread32(hcr_base + HCONTROL);
+       iowrite32((temp & ~0x3F), hcr_base + HCONTROL);
+
+       /* Disable interrupt coalescing control(icc), for the moment */
+       DPRINTK("icc = 0x%x\n", ioread32(hcr_base + ICC));
+       iowrite32(0x01000000, hcr_base + ICC);
+
+       /* clear error registers, SError is cleared by libATA  */
+       iowrite32(0x00000FFFF, hcr_base + CE);
+       iowrite32(0x00000FFFF, hcr_base + DE);
+
+       /* initially assuming no Port multiplier, set CQPMP to 0 */
+       iowrite32(0x0, hcr_base + CQPMP);
+
+       /*
+        * host controller will be brought on-line, during xx_port_start()
+        * callback, that should also initiate the OOB, COMINIT sequence
+        */
+
+       DPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
+       DPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
+
+       return 0;
+}
+
+/*
+ * scsi mid-layer and libata interface structures
+ */
+static struct scsi_host_template sata_fsl_sht = {
+       .module = THIS_MODULE,
+       .name = "sata_fsl",
+       .ioctl = ata_scsi_ioctl,
+       .queuecommand = ata_scsi_queuecmd,
+       .change_queue_depth = ata_scsi_change_queue_depth,
+       .can_queue = SATA_FSL_QUEUE_DEPTH,
+       .this_id = ATA_SHT_THIS_ID,
+       .sg_tablesize = SATA_FSL_MAX_PRD_USABLE,
+       .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
+       .emulated = ATA_SHT_EMULATED,
+       .use_clustering = ATA_SHT_USE_CLUSTERING,
+       .proc_name = "sata_fsl",
+       .dma_boundary = ATA_DMA_BOUNDARY,
+       .slave_configure = ata_scsi_slave_config,
+       .slave_destroy = ata_scsi_slave_destroy,
+       .bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
+       .suspend = ata_scsi_device_suspend,
+       .resume = ata_scsi_device_resume,
+#endif
+};
+
+static const struct ata_port_operations sata_fsl_ops = {
+       .port_disable = ata_port_disable,
+
+       .check_status = sata_fsl_check_status,
+       .check_altstatus = sata_fsl_check_status,
+       .dev_select = ata_noop_dev_select,
+
+       .tf_read = sata_fsl_tf_read,
+
+       .qc_prep = sata_fsl_qc_prep,
+       .qc_issue = sata_fsl_qc_issue,
+       .irq_clear = sata_fsl_irq_clear,
+       .irq_on = ata_dummy_irq_on,
+       .irq_ack = ata_dummy_irq_ack,
+
+       .scr_read = sata_fsl_scr_read,
+       .scr_write = sata_fsl_scr_write,
+
+       .freeze = sata_fsl_freeze,
+       .thaw = sata_fsl_thaw,
+       .error_handler = sata_fsl_error_handler,
+       .post_internal_cmd = sata_fsl_post_internal_cmd,
+
+       .port_start = sata_fsl_port_start,
+       .port_stop = sata_fsl_port_stop,
+};
+
+static const struct ata_port_info sata_fsl_port_info[] = {
+       {
+        .flags = SATA_FSL_HOST_FLAGS,
+        .pio_mask = 0x1f,      /* pio 0-4 */
+        .udma_mask = 0x7f,     /* udma 0-6 */
+        .port_ops = &sata_fsl_ops,
+        },
+};
+
+static int sata_fsl_probe(struct of_device *ofdev,
+                       const struct of_device_id *match)
+{
+       int retval = 0;
+       void __iomem *hcr_base = NULL;
+       void __iomem *ssr_base = NULL;
+       void __iomem *csr_base = NULL;
+       struct sata_fsl_host_priv *host_priv = NULL;
+       struct resource *r;
+       int irq;
+       struct ata_host *host;
+
+       struct ata_port_info pi = sata_fsl_port_info[0];
+       const struct ata_port_info *ppi[] = { &pi, NULL };
+
+       dev_printk(KERN_INFO, &ofdev->dev,
+                  "Sata FSL Platform/CSB Driver init\n");
+
+       r = kmalloc(sizeof(struct resource), GFP_KERNEL);
+
+       hcr_base = of_iomap(ofdev->node, 0);
+       if (!hcr_base)
+               goto error_exit_with_cleanup;
+
+       ssr_base = hcr_base + 0x100;
+       csr_base = hcr_base + 0x140;
+
+       DPRINTK("@reset i/o = 0x%x\n", ioread32(csr_base + TRANSCFG));
+       DPRINTK("sizeof(cmd_desc) = %d\n", sizeof(struct command_desc));
+       DPRINTK("sizeof(#define cmd_desc) = %d\n", SATA_FSL_CMD_DESC_SIZE);
+
+       host_priv = kzalloc(sizeof(struct sata_fsl_host_priv), GFP_KERNEL);
+       if (!host_priv)
+               goto error_exit_with_cleanup;
+
+       host_priv->hcr_base = hcr_base;
+       host_priv->ssr_base = ssr_base;
+       host_priv->csr_base = csr_base;
+
+       irq = irq_of_parse_and_map(ofdev->node, 0);
+       if (irq < 0) {
+               dev_printk(KERN_ERR, &ofdev->dev, "invalid irq from platform\n");
+               goto error_exit_with_cleanup;
+       }
+
+       /* allocate host structure */
+       host = ata_host_alloc_pinfo(&ofdev->dev, ppi, SATA_FSL_MAX_PORTS);
+
+       /* host->iomap is not used currently */
+       host->private_data = host_priv;
+
+       /* setup port(s) */
+
+       host->ports[0]->ioaddr.cmd_addr = host_priv->hcr_base;
+       host->ports[0]->ioaddr.scr_addr = host_priv->ssr_base;
+
+       /* initialize host controller */
+       sata_fsl_init_controller(host);
+
+       /*
+        * Now, register with libATA core, this will also initiate the
+        * device discovery process, invoking our port_start() handler &
+        * error_handler() to execute a dummy Softreset EH session
+        */
+       ata_host_activate(host, irq, sata_fsl_interrupt, SATA_FSL_IRQ_FLAG,
+                         &sata_fsl_sht);
+
+       dev_set_drvdata(&ofdev->dev, host);
+
+       return 0;
+
+error_exit_with_cleanup:
+
+       if (hcr_base)
+               iounmap(hcr_base);
+       if (host_priv)
+               kfree(host_priv);
+
+       return retval;
+}
+
+static int sata_fsl_remove(struct of_device *ofdev)
+{
+       struct ata_host *host = dev_get_drvdata(&ofdev->dev);
+       struct sata_fsl_host_priv *host_priv = host->private_data;
+
+       ata_host_detach(host);
+
+       dev_set_drvdata(&ofdev->dev, NULL);
+
+       irq_dispose_mapping(host->irq);
+       iounmap(host_priv->hcr_base);
+       kfree(host_priv);
+
+       return 0;
+}
+
+static struct of_device_id fsl_sata_match[] = {
+       {
+               .compatible = "fsl,mpc8315-sata",
+       },
+       {
+               .compatible = "fsl,mpc8379-sata",
+       },
+       {},
+};
+
+MODULE_DEVICE_TABLE(of, fsl_sata_match);
+
+static struct of_platform_driver fsl_sata_driver = {
+       .name           = "fsl-sata",
+       .match_table    = fsl_sata_match,
+       .probe          = sata_fsl_probe,
+       .remove         = sata_fsl_remove,
+};
+
+static int __init sata_fsl_init(void)
+{
+       of_register_platform_driver(&fsl_sata_driver);
+       return 0;
+}
+
+static void __exit sata_fsl_exit(void)
+{
+       of_unregister_platform_driver(&fsl_sata_driver);
+}
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ashish Kalra, Freescale Semiconductor");
+MODULE_DESCRIPTION("Freescale 3.0Gbps SATA controller low level driver");
+MODULE_VERSION("1.10");
+
+module_init(sata_fsl_init);
+module_exit(sata_fsl_exit);
index 4df8311968e9e3f04325a7823cc53d78c21f1754..7f1b13e89cf74c5cb75cd8f67b2a19abf816d88c 100644 (file)
@@ -421,7 +421,6 @@ static void mv_error_handler(struct ata_port *ap);
 static void mv_post_int_cmd(struct ata_queued_cmd *qc);
 static void mv_eh_freeze(struct ata_port *ap);
 static void mv_eh_thaw(struct ata_port *ap);
-static int mv_slave_config(struct scsi_device *sdev);
 static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 
 static void mv5_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio,
@@ -459,7 +458,7 @@ static struct scsi_host_template mv5_sht = {
        .use_clustering         = 1,
        .proc_name              = DRV_NAME,
        .dma_boundary           = MV_DMA_BOUNDARY,
-       .slave_configure        = mv_slave_config,
+       .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
 };
@@ -477,7 +476,7 @@ static struct scsi_host_template mv6_sht = {
        .use_clustering         = 1,
        .proc_name              = DRV_NAME,
        .dma_boundary           = MV_DMA_BOUNDARY,
-       .slave_configure        = mv_slave_config,
+       .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
 };
@@ -756,17 +755,6 @@ static void mv_irq_clear(struct ata_port *ap)
 {
 }
 
-static int mv_slave_config(struct scsi_device *sdev)
-{
-       int rc = ata_scsi_slave_config(sdev);
-       if (rc)
-               return rc;
-
-       blk_queue_max_phys_segments(sdev->request_queue, MV_MAX_SG_CT / 2);
-
-       return 0;       /* scsi layer doesn't check return value, sigh */
-}
-
 static void mv_set_edma_ptrs(void __iomem *port_mmio,
                             struct mv_host_priv *hpriv,
                             struct mv_port_priv *pp)
@@ -1138,7 +1126,7 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
 {
        struct mv_port_priv *pp = qc->ap->private_data;
        struct scatterlist *sg;
-       struct mv_sg *mv_sg;
+       struct mv_sg *mv_sg, *last_sg = NULL;
 
        mv_sg = pp->sg_tbl;
        ata_for_each_sg(sg, qc) {
@@ -1159,13 +1147,13 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
                        sg_len -= len;
                        addr += len;
 
-                       if (!sg_len && ata_sg_is_last(sg, qc))
-                               mv_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
-
+                       last_sg = mv_sg;
                        mv_sg++;
                }
-
        }
+
+       if (likely(last_sg))
+               last_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
 }
 
 static inline void mv_crqb_pack_cmd(__le16 *cmdw, u8 data, u8 addr, unsigned last)
index b0619278454a17e513f374640065996bc3622ed9..26ebffc10f3e1254634d3ed9272e567ac4d33fe0 100644 (file)
@@ -796,16 +796,19 @@ static inline void sil24_fill_sg(struct ata_queued_cmd *qc,
                                 struct sil24_sge *sge)
 {
        struct scatterlist *sg;
+       struct sil24_sge *last_sge = NULL;
 
        ata_for_each_sg(sg, qc) {
                sge->addr = cpu_to_le64(sg_dma_address(sg));
                sge->cnt = cpu_to_le32(sg_dma_len(sg));
-               if (ata_sg_is_last(sg, qc))
-                       sge->flags = cpu_to_le32(SGE_TRM);
-               else
-                       sge->flags = 0;
+               sge->flags = 0;
+
+               last_sge = sge;
                sge++;
        }
+
+       if (likely(last_sge))
+               last_sge->flags = cpu_to_le32(SGE_TRM);
 }
 
 static int sil24_qc_defer(struct ata_queued_cmd *qc)
index 8d98a9fb0a42d12162f744204b25c279a3706dde..f147dc7bf464ff74f404440bb74c75df0f3ea622 100644 (file)
@@ -92,7 +92,7 @@ static struct scsi_host_template sis_sht = {
        .queuecommand           = ata_scsi_queuecmd,
        .can_queue              = ATA_DEF_QUEUE,
        .this_id                = ATA_SHT_THIS_ID,
-       .sg_tablesize           = ATA_MAX_PRD,
+       .sg_tablesize           = LIBATA_MAX_PRD,
        .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
        .emulated               = ATA_SHT_EMULATED,
        .use_clustering         = ATA_SHT_USE_CLUSTERING,
@@ -166,11 +166,11 @@ static unsigned int get_scr_cfg_addr(struct ata_port *ap, unsigned int sc_reg)
        return addr;
 }
 
-static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
+static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg, u32 *val)
 {
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
        unsigned int cfg_addr = get_scr_cfg_addr(ap, sc_reg);
-       u32 val, val2 = 0;
+       u32 val2 = 0;
        u8 pmr;
 
        if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */
@@ -178,13 +178,16 @@ static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
 
        pci_read_config_byte(pdev, SIS_PMR, &pmr);
 
-       pci_read_config_dword(pdev, cfg_addr, &val);
+       pci_read_config_dword(pdev, cfg_addr, val);
 
        if ((pdev->device == 0x0182) || (pdev->device == 0x0183) ||
            (pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED))
                pci_read_config_dword(pdev, cfg_addr+0x10, &val2);
 
-       return (val|val2) &  0xfffffffb; /* avoid problems with powerdowned ports */
+       *val |= val2;
+       *val &= 0xfffffffb;     /* avoid problems with powerdowned ports */
+
+       return 0;
 }
 
 static void sis_scr_cfg_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
@@ -214,7 +217,7 @@ static int sis_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
                return -EINVAL;
 
        if (ap->flags & SIS_FLAG_CFGSCR)
-               return sis_scr_cfg_read(ap, sc_reg);
+               return sis_scr_cfg_read(ap, sc_reg, val);
 
        pci_read_config_byte(pdev, SIS_PMR, &pmr);
 
index 94ebc9dc40fd64434f06e48f1923ad21e5db5112..f8f7139c07c1a9997954e7bb97db1aed5affafd2 100644 (file)
@@ -1596,7 +1596,7 @@ static irqreturn_t fs_irq (int irq, void *dev_id)
 
        /* print the bits in the ISR register. */
        if (fs_debug & FS_DEBUG_IRQ) {
-               /* The FS_DEBUG things are unneccesary here. But this way it is
+               /* The FS_DEBUG things are unnecessary here. But this way it is
                   clear for grep that these are debug prints. */
                fs_dprintk (FS_DEBUG_IRQ,  "IRQ status:");
                for (i=0;i<27;i++) 
index fbae8674e491f105269c30a1f10e1c9c4b9929cc..5beddc322e6f86f0df9c43b1207f5cef8aad753a 100644 (file)
@@ -366,7 +366,7 @@ dma_pool_free (struct dma_pool *pool, void *vaddr, dma_addr_t dma)
        unsigned long           flags;
        int                     map, block;
 
-       if ((page = pool_find_page (pool, dma)) == 0) {
+       if ((page = pool_find_page(pool, dma)) == NULL) {
                if (pool->dev)
                        dev_err(pool->dev, "dma_pool_free %s, %p/%lx (bad dma)\n",
                                pool->name, vaddr, (unsigned long) dma);
index c41d0728efe2699079ef0884745084161cd1bb69..7868707c7eda30035ea2eff7e3309011c11a2669 100644 (file)
@@ -137,7 +137,7 @@ static ssize_t show_mem_state(struct sys_device *dev, char *buf)
        return len;
 }
 
-static inline int memory_notify(unsigned long val, void *v)
+int memory_notify(unsigned long val, void *v)
 {
        return blocking_notifier_call_chain(&memory_chain, val, v);
 }
@@ -183,7 +183,6 @@ memory_block_action(struct memory_block *mem, unsigned long action)
                        break;
                case MEM_OFFLINE:
                        mem->state = MEM_GOING_OFFLINE;
-                       memory_notify(MEM_GOING_OFFLINE, NULL);
                        start_paddr = page_to_pfn(first_page) << PAGE_SHIFT;
                        ret = remove_memory(start_paddr,
                                            PAGES_PER_SECTION << PAGE_SHIFT);
@@ -191,7 +190,6 @@ memory_block_action(struct memory_block *mem, unsigned long action)
                                mem->state = old_state;
                                break;
                        }
-                       memory_notify(MEM_MAPPING_INVALID, NULL);
                        break;
                default:
                        printk(KERN_WARNING "%s(%p, %ld) unknown action: %ld\n",
@@ -199,11 +197,6 @@ memory_block_action(struct memory_block *mem, unsigned long action)
                        WARN_ON(1);
                        ret = -EINVAL;
        }
-       /*
-        * For now, only notify on successful memory operations
-        */
-       if (!ret)
-               memory_notify(action, NULL);
 
        return ret;
 }
index 2b0c601e422e13640759aa73dffa882c8c62272d..2b4b392dcbc1761339db874b4f9a02a5b49305c0 100644 (file)
@@ -114,7 +114,7 @@ static unsigned int read_magic_time(void)
        get_rtc_time(&time);
        printk("Time: %2d:%02d:%02d  Date: %02d/%02d/%02d\n",
                time.tm_hour, time.tm_min, time.tm_sec,
-               time.tm_mon, time.tm_mday, time.tm_year);
+               time.tm_mon + 1, time.tm_mday, time.tm_year % 100);
        val = time.tm_year;                             /* 100 years */
        if (val > 100)
                val -= 100;
index 8d8cdfec6529e683a194cd49547b81aa8c3680f6..e1d3ad4db2f04355631efd8120946c07313789c8 100644 (file)
@@ -94,27 +94,18 @@ static struct attribute_group topology_attr_group = {
        .name = "topology"
 };
 
-static cpumask_t topology_dev_map = CPU_MASK_NONE;
-
 /* Add/Remove cpu_topology interface for CPU device */
 static int __cpuinit topology_add_dev(unsigned int cpu)
 {
-       int rc;
        struct sys_device *sys_dev = get_cpu_sysdev(cpu);
 
-       rc = sysfs_create_group(&sys_dev->kobj, &topology_attr_group);
-       if (!rc)
-               cpu_set(cpu, topology_dev_map);
-       return rc;
+       return sysfs_create_group(&sys_dev->kobj, &topology_attr_group);
 }
 
 static void __cpuinit topology_remove_dev(unsigned int cpu)
 {
        struct sys_device *sys_dev = get_cpu_sysdev(cpu);
 
-       if (!cpu_isset(cpu, topology_dev_map))
-               return;
-       cpu_clear(cpu, topology_dev_map);
        sysfs_remove_group(&sys_dev->kobj, &topology_attr_group);
 }
 
index 84d6aa500e26b24a3e73ada55c87d4c44efb6be9..9030c373ce675db9e671d49551f4b6d913a902e6 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/init.h>
 #include <linux/jiffies.h>
 #include <linux/random.h>
+#include <linux/scatterlist.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include "DAC960.h"
@@ -345,6 +346,7 @@ static bool DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
        Command->V1.ScatterGatherList =
                (DAC960_V1_ScatterGatherSegment_T *)ScatterGatherCPU;
        Command->V1.ScatterGatherListDMA = ScatterGatherDMA;
+       sg_init_table(Command->cmd_sglist, DAC960_V1_ScatterGatherLimit);
       } else {
         Command->cmd_sglist = Command->V2.ScatterList;
        Command->V2.ScatterGatherList =
@@ -353,6 +355,7 @@ static bool DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
        Command->V2.RequestSense =
                                (DAC960_SCSI_RequestSense_T *)RequestSenseCPU;
        Command->V2.RequestSenseDMA = RequestSenseDMA;
+       sg_init_table(Command->cmd_sglist, DAC960_V2_ScatterGatherLimit);
       }
     }
   return true;
index ca4d7f0d09b79af954b814ce11299b4e69e996b8..4d0119ea9e351ce1a4d302b810fe3b709b3c713c 100644 (file)
@@ -204,23 +204,6 @@ config BLK_DEV_COW_COMMON
        bool
        default BLK_DEV_UBD
 
-config MMAPPER
-       tristate "Example IO memory driver (BROKEN)"
-       depends on UML && BROKEN
-       ---help---
-          The User-Mode Linux port can provide support for IO Memory
-          emulation with this option.  This allows a host file to be
-          specified as an I/O region on the kernel command line. That file
-          will be mapped into UML's kernel address space where a driver can
-          locate it and do whatever it wants with the memory, including
-          providing an interface to it for UML processes to use.
-
-          For more information, see
-          <http://user-mode-linux.sourceforge.net/iomem.html>.
-
-          If you'd like to be able to provide a simulated IO port space for
-          User-Mode Linux processes, say Y.  If unsure, say N.
-
 config BLK_DEV_LOOP
        tristate "Loopback device support"
        ---help---
@@ -351,7 +334,7 @@ config BLK_DEV_RAM_COUNT
        default "16"
        depends on BLK_DEV_RAM
        help
-         The default value is 16 RAM disks. Change this if you know what
+         The default value is 16 RAM disks. Change this if you know what you
          are doing. If you boot from a filesystem that needs to be extracted
          in memory, you will need at least one RAM disk (e.g. root on cramfs).
 
@@ -361,7 +344,7 @@ config BLK_DEV_RAM_SIZE
        default "4096"
        help
          The default value is 4096 kilobytes. Only change this if you know
-         what are you doing.
+         what you are doing.
 
 config BLK_DEV_RAM_BLOCKSIZE
        int "Default RAM disk block size (bytes)"
@@ -442,4 +425,10 @@ config XEN_BLKDEV_FRONTEND
          block device driver.  It communicates with a back-end driver
          in another domain which drives the actual block device.
 
+config VIRTIO_BLK
+       tristate "Virtio block driver (EXPERIMENTAL)"
+       depends on EXPERIMENTAL && VIRTIO
+       ---help---
+         This is the virtual block driver for lguest.  Say Y or M.
+
 endif # BLK_DEV
index 014e72121b5a255ae835d56b3ed7dd9989eab136..7691505a2e12ee8621d93a5c0b78f3a4b8e6dcc1 100644 (file)
@@ -25,10 +25,10 @@ obj-$(CONFIG_SUNVDC)                += sunvdc.o
 obj-$(CONFIG_BLK_DEV_UMEM)     += umem.o
 obj-$(CONFIG_BLK_DEV_NBD)      += nbd.o
 obj-$(CONFIG_BLK_DEV_CRYPTOLOOP) += cryptoloop.o
+obj-$(CONFIG_VIRTIO_BLK)       += virtio_blk.o
 
 obj-$(CONFIG_VIODASD)          += viodasd.o
 obj-$(CONFIG_BLK_DEV_SX8)      += sx8.o
 obj-$(CONFIG_BLK_DEV_UB)       += ub.o
 
 obj-$(CONFIG_XEN_BLKDEV_FRONTEND)      += xen-blkfront.o
-obj-$(CONFIG_LGUEST_BLOCK)     += lguest_blk.o
index 7c2cfde08f18612db0ce05ae086bb75126660bc8..5a6fe17fc6382bec43217bb11ce8a316f20e804a 100644 (file)
@@ -2610,7 +2610,7 @@ static void do_cciss_request(struct request_queue *q)
               (int)creq->nr_sectors);
 #endif                         /* CCISS_DEBUG */
 
-       memset(tmp_sg, 0, sizeof(tmp_sg));
+       sg_init_table(tmp_sg, MAXSGENTRIES);
        seg = blk_rq_map_sg(q, creq, tmp_sg);
 
        /* get the DMA records for the setup */
@@ -2621,7 +2621,7 @@ static void do_cciss_request(struct request_queue *q)
 
        for (i = 0; i < seg; i++) {
                c->SG[i].Len = tmp_sg[i].length;
-               temp64.val = (__u64) pci_map_page(h->pdev, tmp_sg[i].page,
+               temp64.val = (__u64) pci_map_page(h->pdev, sg_page(&tmp_sg[i]),
                                                  tmp_sg[i].offset,
                                                  tmp_sg[i].length, dir);
                c->SG[i].Addr.lower = temp64.val32.lower;
index 568603d3043e66d1743437095b5fb28c7008596b..c8132d9587953dfcc851f7d6295a00d7f35cf5f1 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/spinlock.h>
 #include <linux/blkdev.h>
 #include <linux/genhd.h>
+#include <linux/scatterlist.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
@@ -918,6 +919,7 @@ queue_next:
 DBGPX(
        printk("sector=%d, nr_sectors=%d\n", creq->sector, creq->nr_sectors);
 );
+       sg_init_table(tmp_sg, SG_MAX);
        seg = blk_rq_map_sg(q, creq, tmp_sg);
 
        /* Now do all the DMA Mappings */
@@ -929,7 +931,7 @@ DBGPX(
        {
                c->req.sg[i].size = tmp_sg[i].length;
                c->req.sg[i].addr = (__u32) pci_map_page(h->pci_dev,
-                                                tmp_sg[i].page,
+                                                sg_page(&tmp_sg[i]),
                                                 tmp_sg[i].offset,
                                                 tmp_sg[i].length, dir);
        }
index 40535036e8936140c44ad8079526c0aed7ecbf68..1b58b010797f198332299cfa959aed18256d5e68 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/crypto.h>
 #include <linux/blkdev.h>
 #include <linux/loop.h>
+#include <linux/scatterlist.h>
 #include <asm/semaphore.h>
 #include <asm/uaccess.h>
 
@@ -119,14 +120,17 @@ cryptoloop_transfer(struct loop_device *lo, int cmd,
                .tfm = tfm,
                .flags = CRYPTO_TFM_REQ_MAY_SLEEP,
        };
-       struct scatterlist sg_out = { NULL, };
-       struct scatterlist sg_in = { NULL, };
+       struct scatterlist sg_out;
+       struct scatterlist sg_in;
 
        encdec_cbc_t encdecfunc;
        struct page *in_page, *out_page;
        unsigned in_offs, out_offs;
        int err;
 
+       sg_init_table(&sg_out, 1);
+       sg_init_table(&sg_in, 1);
+
        if (cmd == READ) {
                in_page = raw_page;
                in_offs = raw_off;
@@ -146,11 +150,11 @@ cryptoloop_transfer(struct loop_device *lo, int cmd,
                u32 iv[4] = { 0, };
                iv[0] = cpu_to_le32(IV & 0xffffffff);
 
-               sg_in.page = in_page;
+               sg_set_page(&sg_in, in_page);
                sg_in.offset = in_offs;
                sg_in.length = sz;
 
-               sg_out.page = out_page;
+               sg_set_page(&sg_out, out_page);
                sg_out.offset = out_offs;
                sg_out.length = sz;
 
diff --git a/drivers/block/lguest_blk.c b/drivers/block/lguest_blk.c
deleted file mode 100644 (file)
index fa8e423..0000000
+++ /dev/null
@@ -1,421 +0,0 @@
-/*D:400
- * The Guest block driver
- *
- * This is a simple block driver, which appears as /dev/lgba, lgbb, lgbc etc.
- * The mechanism is simple: we place the information about the request in the
- * device page, then use SEND_DMA (containing the data for a write, or an empty
- * "ping" DMA for a read).
- :*/
-/* Copyright 2006 Rusty Russell <rusty@rustcorp.com.au> 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
- */
-//#define DEBUG
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/blkdev.h>
-#include <linux/interrupt.h>
-#include <linux/lguest_bus.h>
-
-static char next_block_index = 'a';
-
-/*D:420 Here is the structure which holds all the information we need about
- * each Guest block device.
- *
- * I'm sure at this stage, you're wondering "hey, where was the adventure I was
- * promised?" and thinking "Rusty sucks, I shall say nasty things about him on
- * my blog".  I think Real adventures have boring bits, too, and you're in the
- * middle of one.  But it gets better.  Just not quite yet. */
-struct blockdev
-{
-       /* The block queue infrastructure wants a spinlock: it is held while it
-        * calls our block request function.  We grab it in our interrupt
-        * handler so the responses don't mess with new requests. */
-       spinlock_t lock;
-
-       /* The disk structure registered with kernel. */
-       struct gendisk *disk;
-
-       /* The major device number for this disk, and the interrupt.  We only
-        * really keep them here for completeness; we'd need them if we
-        * supported device unplugging. */
-       int major;
-       int irq;
-
-       /* The physical address of this device's memory page */
-       unsigned long phys_addr;
-       /* The mapped memory page for convenient acces. */
-       struct lguest_block_page *lb_page;
-
-       /* We only have a single request outstanding at a time: this is it. */
-       struct lguest_dma dma;
-       struct request *req;
-};
-
-/*D:495 We originally used end_request() throughout the driver, but it turns
- * out that end_request() is deprecated, and doesn't actually end the request
- * (which seems like a good reason to deprecate it!).  It simply ends the first
- * bio.  So if we had 3 bios in a "struct request" we would do all 3,
- * end_request(), do 2, end_request(), do 1 and end_request(): twice as much
- * work as we needed to do.
- *
- * This reinforced to me that I do not understand the block layer.
- *
- * Nonetheless, Jens Axboe gave me this nice helper to end all chunks of a
- * request.  This improved disk speed by 130%. */
-static void end_entire_request(struct request *req, int uptodate)
-{
-       if (end_that_request_first(req, uptodate, req->hard_nr_sectors))
-               BUG();
-       add_disk_randomness(req->rq_disk);
-       blkdev_dequeue_request(req);
-       end_that_request_last(req, uptodate);
-}
-
-/* I'm told there are only two stories in the world worth telling: love and
- * hate.  So there used to be a love scene here like this:
- *
- *  Launcher:  We could make beautiful I/O together, you and I.
- *  Guest:     My, that's a big disk!
- *
- * Unfortunately, it was just too raunchy for our otherwise-gentle tale. */
-
-/*D:490 This is the interrupt handler, called when a block read or write has
- * been completed for us. */
-static irqreturn_t lgb_irq(int irq, void *_bd)
-{
-       /* We handed our "struct blockdev" as the argument to request_irq(), so
-        * it is passed through to us here.  This tells us which device we're
-        * dealing with in case we have more than one. */
-       struct blockdev *bd = _bd;
-       unsigned long flags;
-
-       /* We weren't doing anything?  Strange, but could happen if we shared
-        * interrupts (we don't!). */
-       if (!bd->req) {
-               pr_debug("No work!\n");
-               return IRQ_NONE;
-       }
-
-       /* Not done yet?  That's equally strange. */
-       if (!bd->lb_page->result) {
-               pr_debug("No result!\n");
-               return IRQ_NONE;
-       }
-
-       /* We have to grab the lock before ending the request. */
-       spin_lock_irqsave(&bd->lock, flags);
-       /* "result" is 1 for success, 2 for failure: end_entire_request() wants
-        * to know whether this succeeded or not. */
-       end_entire_request(bd->req, bd->lb_page->result == 1);
-       /* Clear out request, it's done. */
-       bd->req = NULL;
-       /* Reset incoming DMA for next time. */
-       bd->dma.used_len = 0;
-       /* Ready for more reads or writes */
-       blk_start_queue(bd->disk->queue);
-       spin_unlock_irqrestore(&bd->lock, flags);
-
-       /* The interrupt was for us, we dealt with it. */
-       return IRQ_HANDLED;
-}
-
-/*D:480 The block layer's "struct request" contains a number of "struct bio"s,
- * each of which contains "struct bio_vec"s, each of which contains a page, an
- * offset and a length.
- *
- * Fortunately there are iterators to help us walk through the "struct
- * request".  Even more fortunately, there were plenty of places to steal the
- * code from.  We pack the "struct request" into our "struct lguest_dma" and
- * return the total length. */
-static unsigned int req_to_dma(struct request *req, struct lguest_dma *dma)
-{
-       unsigned int i = 0, len = 0;
-       struct req_iterator iter;
-       struct bio_vec *bvec;
-
-       rq_for_each_segment(bvec, req, iter) {
-               /* We told the block layer not to give us too many. */
-               BUG_ON(i == LGUEST_MAX_DMA_SECTIONS);
-               /* If we had a zero-length segment, it would look like
-                * the end of the data referred to by the "struct
-                * lguest_dma", so make sure that doesn't happen. */
-               BUG_ON(!bvec->bv_len);
-               /* Convert page & offset to a physical address */
-               dma->addr[i] = page_to_phys(bvec->bv_page)
-                       + bvec->bv_offset;
-               dma->len[i] = bvec->bv_len;
-               len += bvec->bv_len;
-               i++;
-       }
-       /* If the array isn't full, we mark the end with a 0 length */
-       if (i < LGUEST_MAX_DMA_SECTIONS)
-               dma->len[i] = 0;
-       return len;
-}
-
-/* This creates an empty DMA, useful for prodding the Host without sending data
- * (ie. when we want to do a read) */
-static void empty_dma(struct lguest_dma *dma)
-{
-       dma->len[0] = 0;
-}
-
-/*D:470 Setting up a request is fairly easy: */
-static void setup_req(struct blockdev *bd,
-                     int type, struct request *req, struct lguest_dma *dma)
-{
-       /* The type is 1 (write) or 0 (read). */
-       bd->lb_page->type = type;
-       /* The sector on disk where the read or write starts. */
-       bd->lb_page->sector = req->sector;
-       /* The result is initialized to 0 (unfinished). */
-       bd->lb_page->result = 0;
-       /* The current request (so we can end it in the interrupt handler). */
-       bd->req = req;
-       /* The number of bytes: returned as a side-effect of req_to_dma(),
-        * which packs the block layer's "struct request" into our "struct
-        * lguest_dma" */
-       bd->lb_page->bytes = req_to_dma(req, dma);
-}
-
-/*D:450 Write is pretty straightforward: we pack the request into a "struct
- * lguest_dma", then use SEND_DMA to send the request. */
-static void do_write(struct blockdev *bd, struct request *req)
-{
-       struct lguest_dma send;
-
-       pr_debug("lgb: WRITE sector %li\n", (long)req->sector);
-       setup_req(bd, 1, req, &send);
-
-       lguest_send_dma(bd->phys_addr, &send);
-}
-
-/* Read is similar to write, except we pack the request into our receive
- * "struct lguest_dma" and send through an empty DMA just to tell the Host that
- * there's a request pending. */
-static void do_read(struct blockdev *bd, struct request *req)
-{
-       struct lguest_dma ping;
-
-       pr_debug("lgb: READ sector %li\n", (long)req->sector);
-       setup_req(bd, 0, req, &bd->dma);
-
-       empty_dma(&ping);
-       lguest_send_dma(bd->phys_addr, &ping);
-}
-
-/*D:440 This where requests come in: we get handed the request queue and are
- * expected to pull a "struct request" off it until we've finished them or
- * we're waiting for a reply: */
-static void do_lgb_request(struct request_queue *q)
-{
-       struct blockdev *bd;
-       struct request *req;
-
-again:
-       /* This sometimes returns NULL even on the very first time around.  I
-        * wonder if it's something to do with letting elves handle the request
-        * queue... */
-       req = elv_next_request(q);
-       if (!req)
-               return;
-
-       /* We attached the struct blockdev to the disk: get it back */
-       bd = req->rq_disk->private_data;
-       /* Sometimes we get repeated requests after blk_stop_queue(), but we
-        * can only handle one at a time. */
-       if (bd->req)
-               return;
-
-       /* We only do reads and writes: no tricky business! */
-       if (!blk_fs_request(req)) {
-               pr_debug("Got non-command 0x%08x\n", req->cmd_type);
-               req->errors++;
-               end_entire_request(req, 0);
-               goto again;
-       }
-
-       if (rq_data_dir(req) == WRITE)
-               do_write(bd, req);
-       else
-               do_read(bd, req);
-
-       /* We've put out the request, so stop any more coming in until we get
-        * an interrupt, which takes us to lgb_irq() to re-enable the queue. */
-       blk_stop_queue(q);
-}
-
-/*D:430 This is the "struct block_device_operations" we attach to the disk at
- * the end of lguestblk_probe().  It doesn't seem to want much. */
-static struct block_device_operations lguestblk_fops = {
-       .owner = THIS_MODULE,
-};
-
-/*D:425 Setting up a disk device seems to involve a lot of code.  I'm not sure
- * quite why.  I do know that the IDE code sent two or three of the maintainers
- * insane, perhaps this is the fringe of the same disease?
- *
- * As in the console code, the probe function gets handed the generic
- * lguest_device from lguest_bus.c: */
-static int lguestblk_probe(struct lguest_device *lgdev)
-{
-       struct blockdev *bd;
-       int err;
-       int irqflags = IRQF_SHARED;
-
-       /* First we allocate our own "struct blockdev" and initialize the easy
-        * fields. */
-       bd = kmalloc(sizeof(*bd), GFP_KERNEL);
-       if (!bd)
-               return -ENOMEM;
-
-       spin_lock_init(&bd->lock);
-       bd->irq = lgdev_irq(lgdev);
-       bd->req = NULL;
-       bd->dma.used_len = 0;
-       bd->dma.len[0] = 0;
-       /* The descriptor in the lguest_devices array provided by the Host
-        * gives the Guest the physical page number of the device's page. */
-       bd->phys_addr = (lguest_devices[lgdev->index].pfn << PAGE_SHIFT);
-
-       /* We use lguest_map() to get a pointer to the device page */
-       bd->lb_page = lguest_map(bd->phys_addr, 1);
-       if (!bd->lb_page) {
-               err = -ENOMEM;
-               goto out_free_bd;
-       }
-
-       /* We need a major device number: 0 means "assign one dynamically". */
-       bd->major = register_blkdev(0, "lguestblk");
-       if (bd->major < 0) {
-               err = bd->major;
-               goto out_unmap;
-       }
-
-       /* This allocates a "struct gendisk" where we pack all the information
-        * about the disk which the rest of Linux sees.  The argument is the
-        * number of minor devices desired: we need one minor for the main
-        * disk, and one for each partition.  Of course, we can't possibly know
-        * how many partitions are on the disk (add_disk does that).
-        */
-       bd->disk = alloc_disk(16);
-       if (!bd->disk) {
-               err = -ENOMEM;
-               goto out_unregister_blkdev;
-       }
-
-       /* Every disk needs a queue for requests to come in: we set up the
-        * queue with a callback function (the core of our driver) and the lock
-        * to use. */
-       bd->disk->queue = blk_init_queue(do_lgb_request, &bd->lock);
-       if (!bd->disk->queue) {
-               err = -ENOMEM;
-               goto out_put_disk;
-       }
-
-       /* We can only handle a certain number of pointers in our SEND_DMA
-        * call, so we set that with blk_queue_max_hw_segments().  This is not
-        * to be confused with blk_queue_max_phys_segments() of course!  I
-        * know, who could possibly confuse the two?
-        *
-        * Well, it's simple to tell them apart: this one seems to work and the
-        * other one didn't. */
-       blk_queue_max_hw_segments(bd->disk->queue, LGUEST_MAX_DMA_SECTIONS);
-
-       /* Due to technical limitations of our Host (and simple coding) we
-        * can't have a single buffer which crosses a page boundary.  Tell it
-        * here.  This means that our maximum request size is 16
-        * (LGUEST_MAX_DMA_SECTIONS) pages. */
-       blk_queue_segment_boundary(bd->disk->queue, PAGE_SIZE-1);
-
-       /* We name our disk: this becomes the device name when udev does its
-        * magic thing and creates the device node, such as /dev/lgba.
-        * next_block_index is a global which starts at 'a'.  Unfortunately
-        * this simple increment logic means that the 27th disk will be called
-        * "/dev/lgb{".  In that case, I recommend having at least 29 disks, so
-        * your /dev directory will be balanced. */
-       sprintf(bd->disk->disk_name, "lgb%c", next_block_index++);
-
-       /* We look to the device descriptor again to see if this device's
-        * interrupts are expected to be random.  If they are, we tell the irq
-        * subsystem.  At the moment this bit is always set. */
-       if (lguest_devices[lgdev->index].features & LGUEST_DEVICE_F_RANDOMNESS)
-               irqflags |= IRQF_SAMPLE_RANDOM;
-
-       /* Now we have the name and irqflags, we can request the interrupt; we
-        * give it the "struct blockdev" we have set up to pass to lgb_irq()
-        * when there is an interrupt. */
-       err = request_irq(bd->irq, lgb_irq, irqflags, bd->disk->disk_name, bd);
-       if (err)
-               goto out_cleanup_queue;
-
-       /* We bind our one-entry DMA pool to the key for this block device so
-        * the Host can reply to our requests.  The key is equal to the
-        * physical address of the device's page, which is conveniently
-        * unique. */
-       err = lguest_bind_dma(bd->phys_addr, &bd->dma, 1, bd->irq);
-       if (err)
-               goto out_free_irq;
-
-       /* We finish our disk initialization and add the disk to the system. */
-       bd->disk->major = bd->major;
-       bd->disk->first_minor = 0;
-       bd->disk->private_data = bd;
-       bd->disk->fops = &lguestblk_fops;
-       /* This is initialized to the disk size by the Launcher. */
-       set_capacity(bd->disk, bd->lb_page->num_sectors);
-       add_disk(bd->disk);
-
-       printk(KERN_INFO "%s: device %i at major %d\n",
-              bd->disk->disk_name, lgdev->index, bd->major);
-
-       /* We don't need to keep the "struct blockdev" around, but if we ever
-        * implemented device removal, we'd need this. */
-       lgdev->private = bd;
-       return 0;
-
-out_free_irq:
-       free_irq(bd->irq, bd);
-out_cleanup_queue:
-       blk_cleanup_queue(bd->disk->queue);
-out_put_disk:
-       put_disk(bd->disk);
-out_unregister_blkdev:
-       unregister_blkdev(bd->major, "lguestblk");
-out_unmap:
-       lguest_unmap(bd->lb_page);
-out_free_bd:
-       kfree(bd);
-       return err;
-}
-
-/*D:410 The boilerplate code for registering the lguest block driver is just
- * like the console: */
-static struct lguest_driver lguestblk_drv = {
-       .name = "lguestblk",
-       .owner = THIS_MODULE,
-       .device_type = LGUEST_DEVICE_T_BLOCK,
-       .probe = lguestblk_probe,
-};
-
-static __init int lguestblk_init(void)
-{
-       return register_lguest_driver(&lguestblk_drv);
-}
-module_init(lguestblk_init);
-
-MODULE_DESCRIPTION("Lguest block driver");
-MODULE_LICENSE("GPL");
index 589cbbd9cd4f4f54f77338ee9ec09bb2f8af591a..56e23042728ae093776a86a499da310511d51a91 100644 (file)
@@ -29,7 +29,7 @@
  *
  * Maximum number of loop devices when compiled-in now selectable by passing
  * max_loop=<1-255> to the kernel on boot.
- * Erik I. Bolsø, <eriki@himolde.no>, Oct 31, 1999
+ * Erik I. Bolsø, <eriki@himolde.no>, Oct 31, 1999
  *
  * Completely rewrite request handling to be make_request_fn style and
  * non blocking, pushing work to a helper thread. Lots of fixes from
index cb136a919f2a83f1f97e6936949cebe6e4fd9f72..6332acad078c5f6976854b0f394e3496dc1f4e81 100644 (file)
@@ -188,7 +188,7 @@ static int sock_xmit(struct nbd_device *lo, int send, void *buf, int size,
                if (signal_pending(current)) {
                        siginfo_t info;
                        printk(KERN_WARNING "nbd (pid %d: %s) got signal %d\n",
-                               current->pid, current->comm,
+                               task_pid_nr(current), current->comm,
                                dequeue_signal_lock(current, &current->blocked, &info));
                        result = -EINTR;
                        sock_shutdown(lo, !send);
@@ -508,7 +508,6 @@ error_out:
                nbd_end_request(req);
                spin_lock(q->queue_lock);
        }
-       return;
 }
 
 static int nbd_ioctl(struct inode *inode, struct file *file,
index 08176d23a46cd421690aca1d13a2edecf1499b71..47f8ac6cce574c81b1e845099000e019a0098468 100644 (file)
@@ -365,7 +365,7 @@ static int rd_open(struct inode *inode, struct file *filp)
                /*
                 * Deep badness.  rd_blkdev_pagecache_IO() needs to allocate
                 * pagecache pages within a request_fn.  We cannot recur back
-                * into the filesytem which is mounted atop the ramdisk, because
+                * into the filesystem which is mounted atop the ramdisk, because
                 * that would deadlock on fs locks.  And we really don't want
                 * to reenter rd_blkdev_pagecache_IO when we're already within
                 * that function.
index 317a790c153b91c7748972dfa78890e64f13c7fb..7276f7d207c2f3cfcfc3d036efce68a35ca84620 100644 (file)
@@ -388,6 +388,7 @@ static int __send_request(struct request *req)
                op = VD_OP_BWRITE;
        }
 
+       sg_init_table(sg, port->ring_cookies);
        nsg = blk_rq_map_sg(req->q, req, sg);
 
        len = 0;
index 402209fec59a75dbfe0b356b89c4537e4dcb1c46..52dc5e1317184ada37a8af3bc3a41e5a967626ab 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/hdreg.h>
 #include <linux/dma-mapping.h>
 #include <linux/completion.h>
+#include <linux/scatterlist.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
@@ -522,6 +523,7 @@ static struct carm_request *carm_get_request(struct carm_host *host)
                        host->n_msgs++;
 
                        assert(host->n_msgs <= CARM_MAX_REQ);
+                       sg_init_table(crq->sg, CARM_MAX_REQ_SG);
                        return crq;
                }
 
index c57dd2b3a0c8df57216cd93a81360de22473cb68..14143f2c484d0ac28be1fc60b9d765c19d3c4b25 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/usb_usual.h>
 #include <linux/blkdev.h>
 #include <linux/timer.h>
+#include <linux/scatterlist.h>
 #include <scsi/scsi.h>
 
 #define DRV_NAME "ub"
@@ -656,6 +657,7 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq)
        if ((cmd = ub_get_cmd(lun)) == NULL)
                return -1;
        memset(cmd, 0, sizeof(struct ub_scsi_cmd));
+       sg_init_table(cmd->sgv, UB_MAX_REQ_SG);
 
        blkdev_dequeue_request(rq);
 
@@ -1309,9 +1311,8 @@ static void ub_data_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
        else
                pipe = sc->send_bulk_pipe;
        sc->last_pipe = pipe;
-       usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe,
-           page_address(sg->page) + sg->offset, sg->length,
-           ub_urb_complete, sc);
+       usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe, sg_virt(sg),
+           sg->length, ub_urb_complete, sc);
        sc->work_urb.actual_length = 0;
        sc->work_urb.error_count = 0;
        sc->work_urb.status = 0;
@@ -1427,7 +1428,7 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
        scmd->state = UB_CMDST_INIT;
        scmd->nsg = 1;
        sg = &scmd->sgv[0];
-       sg->page = virt_to_page(sc->top_sense);
+       sg_set_page(sg, virt_to_page(sc->top_sense));
        sg->offset = (unsigned long)sc->top_sense & (PAGE_SIZE-1);
        sg->length = UB_SENSE_SIZE;
        scmd->len = UB_SENSE_SIZE;
@@ -1863,7 +1864,7 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
        cmd->state = UB_CMDST_INIT;
        cmd->nsg = 1;
        sg = &cmd->sgv[0];
-       sg->page = virt_to_page(p);
+       sg_set_page(sg, virt_to_page(p));
        sg->offset = (unsigned long)p & (PAGE_SIZE-1);
        sg->length = 8;
        cmd->len = 8;
index e824b672e05a23c75473d6d2a04b4462eb709bec..ab5d404faa1163030c9ee347d5649262a3c26601 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/completion.h>
 #include <linux/device.h>
+#include <linux/scatterlist.h>
 
 #include <asm/uaccess.h>
 #include <asm/vio.h>
@@ -270,6 +271,7 @@ static int send_request(struct request *req)
         d = req->rq_disk->private_data;
 
        /* Now build the scatter-gather list */
+       sg_init_table(sg, VIOMAXBLOCKDMA);
        nsg = blk_rq_map_sg(req->q, req, sg);
        nsg = dma_map_sg(d->dev, sg, nsg, direction);
 
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
new file mode 100644 (file)
index 0000000..a901eee
--- /dev/null
@@ -0,0 +1,308 @@
+//#define DEBUG
+#include <linux/spinlock.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+#include <linux/virtio.h>
+#include <linux/virtio_blk.h>
+#include <linux/virtio_blk.h>
+
+static unsigned char virtblk_index = 'a';
+struct virtio_blk
+{
+       spinlock_t lock;
+
+       struct virtio_device *vdev;
+       struct virtqueue *vq;
+
+       /* The disk structure for the kernel. */
+       struct gendisk *disk;
+
+       /* Request tracking. */
+       struct list_head reqs;
+
+       mempool_t *pool;
+
+       /* Scatterlist: can be too big for stack. */
+       struct scatterlist sg[3+MAX_PHYS_SEGMENTS];
+};
+
+struct virtblk_req
+{
+       struct list_head list;
+       struct request *req;
+       struct virtio_blk_outhdr out_hdr;
+       struct virtio_blk_inhdr in_hdr;
+};
+
+static bool blk_done(struct virtqueue *vq)
+{
+       struct virtio_blk *vblk = vq->vdev->priv;
+       struct virtblk_req *vbr;
+       unsigned int len;
+       unsigned long flags;
+
+       spin_lock_irqsave(&vblk->lock, flags);
+       while ((vbr = vblk->vq->vq_ops->get_buf(vblk->vq, &len)) != NULL) {
+               int uptodate;
+               switch (vbr->in_hdr.status) {
+               case VIRTIO_BLK_S_OK:
+                       uptodate = 1;
+                       break;
+               case VIRTIO_BLK_S_UNSUPP:
+                       uptodate = -ENOTTY;
+                       break;
+               default:
+                       uptodate = 0;
+                       break;
+               }
+
+               end_dequeued_request(vbr->req, uptodate);
+               list_del(&vbr->list);
+               mempool_free(vbr, vblk->pool);
+       }
+       /* In case queue is stopped waiting for more buffers. */
+       blk_start_queue(vblk->disk->queue);
+       spin_unlock_irqrestore(&vblk->lock, flags);
+       return true;
+}
+
+static bool do_req(struct request_queue *q, struct virtio_blk *vblk,
+                  struct request *req)
+{
+       unsigned long num, out, in;
+       struct virtblk_req *vbr;
+
+       vbr = mempool_alloc(vblk->pool, GFP_ATOMIC);
+       if (!vbr)
+               /* When another request finishes we'll try again. */
+               return false;
+
+       vbr->req = req;
+       if (blk_fs_request(vbr->req)) {
+               vbr->out_hdr.type = 0;
+               vbr->out_hdr.sector = vbr->req->sector;
+               vbr->out_hdr.ioprio = vbr->req->ioprio;
+       } else if (blk_pc_request(vbr->req)) {
+               vbr->out_hdr.type = VIRTIO_BLK_T_SCSI_CMD;
+               vbr->out_hdr.sector = 0;
+               vbr->out_hdr.ioprio = vbr->req->ioprio;
+       } else {
+               /* We don't put anything else in the queue. */
+               BUG();
+       }
+
+       if (blk_barrier_rq(vbr->req))
+               vbr->out_hdr.type |= VIRTIO_BLK_T_BARRIER;
+
+       /* We have to zero this, otherwise blk_rq_map_sg gets upset. */
+       memset(vblk->sg, 0, sizeof(vblk->sg));
+       sg_set_buf(&vblk->sg[0], &vbr->out_hdr, sizeof(vbr->out_hdr));
+       num = blk_rq_map_sg(q, vbr->req, vblk->sg+1);
+       sg_set_buf(&vblk->sg[num+1], &vbr->in_hdr, sizeof(vbr->in_hdr));
+
+       if (rq_data_dir(vbr->req) == WRITE) {
+               vbr->out_hdr.type |= VIRTIO_BLK_T_OUT;
+               out = 1 + num;
+               in = 1;
+       } else {
+               vbr->out_hdr.type |= VIRTIO_BLK_T_IN;
+               out = 1;
+               in = 1 + num;
+       }
+
+       if (vblk->vq->vq_ops->add_buf(vblk->vq, vblk->sg, out, in, vbr)) {
+               mempool_free(vbr, vblk->pool);
+               return false;
+       }
+
+       list_add_tail(&vbr->list, &vblk->reqs);
+       return true;
+}
+
+static void do_virtblk_request(struct request_queue *q)
+{
+       struct virtio_blk *vblk = NULL;
+       struct request *req;
+       unsigned int issued = 0;
+
+       while ((req = elv_next_request(q)) != NULL) {
+               vblk = req->rq_disk->private_data;
+               BUG_ON(req->nr_phys_segments > ARRAY_SIZE(vblk->sg));
+
+               /* If this request fails, stop queue and wait for something to
+                  finish to restart it. */
+               if (!do_req(q, vblk, req)) {
+                       blk_stop_queue(q);
+                       break;
+               }
+               blkdev_dequeue_request(req);
+               issued++;
+       }
+
+       if (issued)
+               vblk->vq->vq_ops->kick(vblk->vq);
+}
+
+static int virtblk_ioctl(struct inode *inode, struct file *filp,
+                        unsigned cmd, unsigned long data)
+{
+       return scsi_cmd_ioctl(filp, inode->i_bdev->bd_disk->queue,
+                             inode->i_bdev->bd_disk, cmd,
+                             (void __user *)data);
+}
+
+static struct block_device_operations virtblk_fops = {
+       .ioctl = virtblk_ioctl,
+       .owner = THIS_MODULE,
+};
+
+static int virtblk_probe(struct virtio_device *vdev)
+{
+       struct virtio_blk *vblk;
+       int err, major;
+       void *token;
+       unsigned int len;
+       u64 cap;
+       u32 v;
+
+       vdev->priv = vblk = kmalloc(sizeof(*vblk), GFP_KERNEL);
+       if (!vblk) {
+               err = -ENOMEM;
+               goto out;
+       }
+
+       INIT_LIST_HEAD(&vblk->reqs);
+       spin_lock_init(&vblk->lock);
+       vblk->vdev = vdev;
+
+       /* We expect one virtqueue, for output. */
+       vblk->vq = vdev->config->find_vq(vdev, blk_done);
+       if (IS_ERR(vblk->vq)) {
+               err = PTR_ERR(vblk->vq);
+               goto out_free_vblk;
+       }
+
+       vblk->pool = mempool_create_kmalloc_pool(1,sizeof(struct virtblk_req));
+       if (!vblk->pool) {
+               err = -ENOMEM;
+               goto out_free_vq;
+       }
+
+       major = register_blkdev(0, "virtblk");
+       if (major < 0) {
+               err = major;
+               goto out_mempool;
+       }
+
+       /* FIXME: How many partitions?  How long is a piece of string? */
+       vblk->disk = alloc_disk(1 << 4);
+       if (!vblk->disk) {
+               err = -ENOMEM;
+               goto out_unregister_blkdev;
+       }
+
+       vblk->disk->queue = blk_init_queue(do_virtblk_request, &vblk->lock);
+       if (!vblk->disk->queue) {
+               err = -ENOMEM;
+               goto out_put_disk;
+       }
+
+       sprintf(vblk->disk->disk_name, "vd%c", virtblk_index++);
+       vblk->disk->major = major;
+       vblk->disk->first_minor = 0;
+       vblk->disk->private_data = vblk;
+       vblk->disk->fops = &virtblk_fops;
+
+       /* If barriers are supported, tell block layer that queue is ordered */
+       token = vdev->config->find(vdev, VIRTIO_CONFIG_BLK_F, &len);
+       if (virtio_use_bit(vdev, token, len, VIRTIO_BLK_F_BARRIER))
+               blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_TAG, NULL);
+
+       err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_CAPACITY, &cap);
+       if (err) {
+               dev_err(&vdev->dev, "Bad/missing capacity in config\n");
+               goto out_put_disk;
+       }
+
+       /* If capacity is too big, truncate with warning. */
+       if ((sector_t)cap != cap) {
+               dev_warn(&vdev->dev, "Capacity %llu too large: truncating\n",
+                        (unsigned long long)cap);
+               cap = (sector_t)-1;
+       }
+       set_capacity(vblk->disk, cap);
+
+       err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_SIZE_MAX, &v);
+       if (!err)
+               blk_queue_max_segment_size(vblk->disk->queue, v);
+       else if (err != -ENOENT) {
+               dev_err(&vdev->dev, "Bad SIZE_MAX in config\n");
+               goto out_put_disk;
+       }
+
+       err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_SEG_MAX, &v);
+       if (!err)
+               blk_queue_max_hw_segments(vblk->disk->queue, v);
+       else if (err != -ENOENT) {
+               dev_err(&vdev->dev, "Bad SEG_MAX in config\n");
+               goto out_put_disk;
+       }
+
+       add_disk(vblk->disk);
+       return 0;
+
+out_put_disk:
+       put_disk(vblk->disk);
+out_unregister_blkdev:
+       unregister_blkdev(major, "virtblk");
+out_mempool:
+       mempool_destroy(vblk->pool);
+out_free_vq:
+       vdev->config->del_vq(vblk->vq);
+out_free_vblk:
+       kfree(vblk);
+out:
+       return err;
+}
+
+static void virtblk_remove(struct virtio_device *vdev)
+{
+       struct virtio_blk *vblk = vdev->priv;
+       int major = vblk->disk->major;
+
+       BUG_ON(!list_empty(&vblk->reqs));
+       blk_cleanup_queue(vblk->disk->queue);
+       put_disk(vblk->disk);
+       unregister_blkdev(major, "virtblk");
+       mempool_destroy(vblk->pool);
+       kfree(vblk);
+}
+
+static struct virtio_device_id id_table[] = {
+       { VIRTIO_ID_BLOCK, VIRTIO_DEV_ANY_ID },
+       { 0 },
+};
+
+static struct virtio_driver virtio_blk = {
+       .driver.name =  KBUILD_MODNAME,
+       .driver.owner = THIS_MODULE,
+       .id_table =     id_table,
+       .probe =        virtblk_probe,
+       .remove =       __devexit_p(virtblk_remove),
+};
+
+static int __init init(void)
+{
+       return register_virtio_driver(&virtio_blk);
+}
+
+static void __exit fini(void)
+{
+       unregister_virtio_driver(&virtio_blk);
+}
+module_init(init);
+module_exit(fini);
+
+MODULE_DEVICE_TABLE(virtio, id_table);
+MODULE_DESCRIPTION("Virtio block driver");
+MODULE_LICENSE("GPL");
index 9e7652dcde6cd46f1d1d19c2fa0462f8754d9536..82effce97c514601dfbc3f5d9f5e953fe98bcd5b 100644 (file)
@@ -390,8 +390,8 @@ static inline void ace_dump_mem(void *base, int len)
 static void ace_dump_regs(struct ace_device *ace)
 {
        dev_info(ace->dev, "    ctrl:  %.8x  seccnt/cmd: %.4x      ver:%.4x\n"
-                "    status:%.8x  mpu_lba:%.8x  busmode:%4x\n"
-                "    error: %.8x  cfg_lba:%.8x  fatstat:%.4x\n",
+                KERN_INFO "    status:%.8x  mpu_lba:%.8x  busmode:%4x\n"
+                KERN_INFO "    error: %.8x  cfg_lba:%.8x  fatstat:%.4x\n",
                 ace_in32(ace, ACE_CTRL),
                 ace_in(ace, ACE_SECCNTCMD),
                 ace_in(ace, ACE_VERSION),
index b9fbe6e7f9ae6e6fd9da5e78990efd5e87229bc4..075598e1c50240d743edb8c4e566fa6c509d4160 100644 (file)
@@ -22,6 +22,30 @@ config BT_HCIUSB_SCO
 
          Say Y here to compile support for SCO over HCI USB.
 
+config BT_HCIBTUSB
+       tristate "HCI USB driver (alternate version)"
+       depends on USB && EXPERIMENTAL && BT_HCIUSB=n
+       help
+         Bluetooth HCI USB driver.
+         This driver is required if you want to use Bluetooth devices with
+         USB interface.
+
+          This driver is still experimental and has no SCO support.
+
+         Say Y here to compile support for Bluetooth USB devices into the
+         kernel or say M to compile it as module (btusb).
+
+config BT_HCIBTSDIO
+       tristate "HCI SDIO driver"
+       depends on MMC
+       help
+         Bluetooth HCI SDIO driver.
+         This driver is required if you want to use Bluetooth device with
+         SDIO interface.
+
+         Say Y here to compile support for Bluetooth SDIO devices into the
+         kernel or say M to compile it as module (btsdio).
+
 config BT_HCIUART
        tristate "HCI UART driver"
        help
@@ -55,6 +79,17 @@ config BT_HCIUART_BCSP
 
          Say Y here to compile support for HCI BCSP protocol.
 
+config BT_HCIUART_LL
+       bool "HCILL protocol support"
+       depends on BT_HCIUART
+       help
+         HCILL (HCI Low Level) is a serial protocol for communication
+         between Bluetooth device and host. This protocol is required for
+         serial Bluetooth devices that are based on Texas Instruments'
+         BRF chips.
+
+         Say Y here to compile support for HCILL protocol.
+
 config BT_HCIBCM203X
        tristate "HCI BCM203x USB driver"
        depends on USB
index 08c10e178e02400fd3aae0027943a94b6c91daea..77444afbf107281de422a950d1e0a4ac63469cc0 100644 (file)
@@ -13,7 +13,11 @@ obj-$(CONFIG_BT_HCIBT3C)     += bt3c_cs.o
 obj-$(CONFIG_BT_HCIBLUECARD)   += bluecard_cs.o
 obj-$(CONFIG_BT_HCIBTUART)     += btuart_cs.o
 
+obj-$(CONFIG_BT_HCIBTUSB)      += btusb.o
+obj-$(CONFIG_BT_HCIBTSDIO)     += btsdio.o
+
 hci_uart-y                             := hci_ldisc.o
 hci_uart-$(CONFIG_BT_HCIUART_H4)       += hci_h4.o
 hci_uart-$(CONFIG_BT_HCIUART_BCSP)     += hci_bcsp.o
+hci_uart-$(CONFIG_BT_HCIUART_LL)       += hci_ll.o
 hci_uart-objs                          := $(hci_uart-y)
index 851de4d5b7de1af899dc219a1a5bf950736a19b3..bcf57927b7a8ff7e9e377f03e798c37f650689f2 100644 (file)
@@ -503,10 +503,7 @@ static irqreturn_t bluecard_interrupt(int irq, void *dev_inst)
        unsigned int iobase;
        unsigned char reg;
 
-       if (!info || !info->hdev) {
-               BT_ERR("Call of irq %d for unknown device", irq);
-               return IRQ_NONE;
-       }
+       BUG_ON(!info->hdev);
 
        if (!test_bit(CARD_READY, &(info->hw_state)))
                return IRQ_HANDLED;
index e8ebd5d3de864e4402a31dce96ec5ff7c17ffacd..1375b5345a0a1466045204b80a2804672b6c4756 100644 (file)
@@ -2,7 +2,7 @@
  *
  *  Digianswer Bluetooth USB driver
  *
- *  Copyright (C) 2004-2005  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2004-2007  Marcel Holtmann <marcel@holtmann.org>
  *
  *
  *  This program is free software; you can redistribute it and/or modify
  *
  */
 
-#include <linux/module.h>
-
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/types.h>
+#include <linux/sched.h>
 #include <linux/errno.h>
+#include <linux/skbuff.h>
 
 #include <linux/usb.h>
 
@@ -39,7 +40,7 @@
 #define BT_DBG(D...)
 #endif
 
-#define VERSION "0.8"
+#define VERSION "0.9"
 
 static int ignore = 0;
 
@@ -52,393 +53,285 @@ static struct usb_device_id bpa10x_table[] = {
 
 MODULE_DEVICE_TABLE(usb, bpa10x_table);
 
-#define BPA10X_CMD_EP          0x00
-#define BPA10X_EVT_EP          0x81
-#define BPA10X_TX_EP           0x02
-#define BPA10X_RX_EP           0x82
-
-#define BPA10X_CMD_BUF_SIZE    252
-#define BPA10X_EVT_BUF_SIZE    16
-#define BPA10X_TX_BUF_SIZE     384
-#define BPA10X_RX_BUF_SIZE     384
-
 struct bpa10x_data {
-       struct hci_dev          *hdev;
-       struct usb_device       *udev;
+       struct hci_dev    *hdev;
+       struct usb_device *udev;
 
-       rwlock_t                lock;
+       struct usb_anchor tx_anchor;
+       struct usb_anchor rx_anchor;
 
-       struct sk_buff_head     cmd_queue;
-       struct urb              *cmd_urb;
-       struct urb              *evt_urb;
-       struct sk_buff          *evt_skb;
-       unsigned int            evt_len;
-
-       struct sk_buff_head     tx_queue;
-       struct urb              *tx_urb;
-       struct urb              *rx_urb;
+       struct sk_buff *rx_skb[2];
 };
 
-#define HCI_VENDOR_HDR_SIZE    5
+#define HCI_VENDOR_HDR_SIZE 5
 
 struct hci_vendor_hdr {
-       __u8    type;
-       __le16  snum;
-       __le16  dlen;
+       __u8    type;
+       __le16  snum;
+       __le16  dlen;
 } __attribute__ ((packed));
 
-static void bpa10x_recv_bulk(struct bpa10x_data *data, unsigned char *buf, int count)
+static int bpa10x_recv(struct hci_dev *hdev, int queue, void *buf, int count)
 {
-       struct hci_acl_hdr *ah;
-       struct hci_sco_hdr *sh;
-       struct hci_vendor_hdr *vh;
-       struct sk_buff *skb;
-       int len;
+       struct bpa10x_data *data = hdev->driver_data;
+
+       BT_DBG("%s queue %d buffer %p count %d", hdev->name,
+                                                       queue, buf, count);
+
+       if (queue < 0 || queue > 1)
+               return -EILSEQ;
+
+       hdev->stat.byte_rx += count;
 
        while (count) {
-               switch (*buf++) {
-               case HCI_ACLDATA_PKT:
-                       ah = (struct hci_acl_hdr *) buf;
-                       len = HCI_ACL_HDR_SIZE + __le16_to_cpu(ah->dlen);
-                       skb = bt_skb_alloc(len, GFP_ATOMIC);
-                       if (skb) {
-                               memcpy(skb_put(skb, len), buf, len);
-                               skb->dev = (void *) data->hdev;
-                               bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
-                               hci_recv_frame(skb);
-                       }
-                       break;
+               struct sk_buff *skb = data->rx_skb[queue];
+               struct { __u8 type; int expect; } *scb;
+               int type, len = 0;
 
-               case HCI_SCODATA_PKT:
-                       sh = (struct hci_sco_hdr *) buf;
-                       len = HCI_SCO_HDR_SIZE + sh->dlen;
-                       skb = bt_skb_alloc(len, GFP_ATOMIC);
-                       if (skb) {
-                               memcpy(skb_put(skb, len), buf, len);
-                               skb->dev = (void *) data->hdev;
-                               bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
-                               hci_recv_frame(skb);
+               if (!skb) {
+                       /* Start of the frame */
+
+                       type = *((__u8 *) buf);
+                       count--; buf++;
+
+                       switch (type) {
+                       case HCI_EVENT_PKT:
+                               if (count >= HCI_EVENT_HDR_SIZE) {
+                                       struct hci_event_hdr *h = buf;
+                                       len = HCI_EVENT_HDR_SIZE + h->plen;
+                               } else
+                                       return -EILSEQ;
+                               break;
+
+                       case HCI_ACLDATA_PKT:
+                               if (count >= HCI_ACL_HDR_SIZE) {
+                                       struct hci_acl_hdr *h = buf;
+                                       len = HCI_ACL_HDR_SIZE +
+                                                       __le16_to_cpu(h->dlen);
+                               } else
+                                       return -EILSEQ;
+                               break;
+
+                       case HCI_SCODATA_PKT:
+                               if (count >= HCI_SCO_HDR_SIZE) {
+                                       struct hci_sco_hdr *h = buf;
+                                       len = HCI_SCO_HDR_SIZE + h->dlen;
+                               } else
+                                       return -EILSEQ;
+                               break;
+
+                       case HCI_VENDOR_PKT:
+                               if (count >= HCI_VENDOR_HDR_SIZE) {
+                                       struct hci_vendor_hdr *h = buf;
+                                       len = HCI_VENDOR_HDR_SIZE +
+                                                       __le16_to_cpu(h->dlen);
+                               } else
+                                       return -EILSEQ;
+                               break;
                        }
-                       break;
 
-               case HCI_VENDOR_PKT:
-                       vh = (struct hci_vendor_hdr *) buf;
-                       len = HCI_VENDOR_HDR_SIZE + __le16_to_cpu(vh->dlen);
                        skb = bt_skb_alloc(len, GFP_ATOMIC);
-                       if (skb) {
-                               memcpy(skb_put(skb, len), buf, len);
-                               skb->dev = (void *) data->hdev;
-                               bt_cb(skb)->pkt_type = HCI_VENDOR_PKT;
-                               hci_recv_frame(skb);
+                       if (!skb) {
+                               BT_ERR("%s no memory for packet", hdev->name);
+                               return -ENOMEM;
                        }
-                       break;
-
-               default:
-                       len = count - 1;
-                       break;
-               }
 
-               buf   += len;
-               count -= (len + 1);
-       }
-}
-
-static int bpa10x_recv_event(struct bpa10x_data *data, unsigned char *buf, int size)
-{
-       BT_DBG("data %p buf %p size %d", data, buf, size);
+                       skb->dev = (void *) hdev;
 
-       if (data->evt_skb) {
-               struct sk_buff *skb = data->evt_skb;
+                       data->rx_skb[queue] = skb;
 
-               memcpy(skb_put(skb, size), buf, size);
+                       scb = (void *) skb->cb;
+                       scb->type = type;
+                       scb->expect = len;
+               } else {
+                       /* Continuation */
 
-               if (skb->len == data->evt_len) {
-                       data->evt_skb = NULL;
-                       data->evt_len = 0;
-                       hci_recv_frame(skb);
-               }
-       } else {
-               struct sk_buff *skb;
-               struct hci_event_hdr *hdr;
-               unsigned char pkt_type;
-               int pkt_len = 0;
-
-               if (size < HCI_EVENT_HDR_SIZE + 1) {
-                       BT_ERR("%s event packet block with size %d is too short",
-                                                       data->hdev->name, size);
-                       return -EILSEQ;
+                       scb = (void *) skb->cb;
+                       len = scb->expect;
                }
 
-               pkt_type = *buf++;
-               size--;
-
-               if (pkt_type != HCI_EVENT_PKT) {
-                       BT_ERR("%s unexpected event packet start byte 0x%02x",
-                                                       data->hdev->name, pkt_type);
-                       return -EPROTO;
-               }
+               len = min(len, count);
 
-               hdr = (struct hci_event_hdr *) buf;
-               pkt_len = HCI_EVENT_HDR_SIZE + hdr->plen;
+               memcpy(skb_put(skb, len), buf, len);
 
-               skb = bt_skb_alloc(pkt_len, GFP_ATOMIC);
-               if (!skb) {
-                       BT_ERR("%s no memory for new event packet",
-                                                       data->hdev->name);
-                       return -ENOMEM;
-               }
+               scb->expect -= len;
 
-               skb->dev = (void *) data->hdev;
-               bt_cb(skb)->pkt_type = pkt_type;
+               if (scb->expect == 0) {
+                       /* Complete frame */
 
-               memcpy(skb_put(skb, size), buf, size);
+                       data->rx_skb[queue] = NULL;
 
-               if (pkt_len == size) {
+                       bt_cb(skb)->pkt_type = scb->type;
                        hci_recv_frame(skb);
-               } else {
-                       data->evt_skb = skb;
-                       data->evt_len = pkt_len;
                }
+
+               count -= len; buf += len;
        }
 
        return 0;
 }
 
-static void bpa10x_wakeup(struct bpa10x_data *data)
+static void bpa10x_tx_complete(struct urb *urb)
 {
-       struct urb *urb;
-       struct sk_buff *skb;
-       int err;
+       struct sk_buff *skb = urb->context;
+       struct hci_dev *hdev = (struct hci_dev *) skb->dev;
 
-       BT_DBG("data %p", data);
+       BT_DBG("%s urb %p status %d count %d", hdev->name,
+                                       urb, urb->status, urb->actual_length);
 
-       urb = data->cmd_urb;
-       if (urb->status == -EINPROGRESS)
-               skb = NULL;
+       if (!test_bit(HCI_RUNNING, &hdev->flags))
+               goto done;
+
+       if (!urb->status)
+               hdev->stat.byte_tx += urb->transfer_buffer_length;
        else
-               skb = skb_dequeue(&data->cmd_queue);
+               hdev->stat.err_tx++;
 
-       if (skb) {
-               struct usb_ctrlrequest *cr;
+done:
+       kfree(urb->setup_packet);
 
-               if (skb->len > BPA10X_CMD_BUF_SIZE) {
-                       BT_ERR("%s command packet with size %d is too big",
-                                                       data->hdev->name, skb->len);
-                       kfree_skb(skb);
-                       return;
-               }
+       kfree_skb(skb);
+}
+
+static void bpa10x_rx_complete(struct urb *urb)
+{
+       struct hci_dev *hdev = urb->context;
+       struct bpa10x_data *data = hdev->driver_data;
+       int err;
 
-               cr = (struct usb_ctrlrequest *) urb->setup_packet;
-               cr->wLength = __cpu_to_le16(skb->len);
+       BT_DBG("%s urb %p status %d count %d", hdev->name,
+                                       urb, urb->status, urb->actual_length);
 
-               skb_copy_from_linear_data(skb, urb->transfer_buffer, skb->len);
-               urb->transfer_buffer_length = skb->len;
+       if (!test_bit(HCI_RUNNING, &hdev->flags))
+               return;
 
-               err = usb_submit_urb(urb, GFP_ATOMIC);
-               if (err < 0 && err != -ENODEV) {
-                       BT_ERR("%s submit failed for command urb %p with error %d",
-                                                       data->hdev->name, urb, err);
-                       skb_queue_head(&data->cmd_queue, skb);
-               } else
-                       kfree_skb(skb);
+       if (urb->status == 0) {
+               if (bpa10x_recv(hdev, usb_pipebulk(urb->pipe),
+                                               urb->transfer_buffer,
+                                               urb->actual_length) < 0) {
+                       BT_ERR("%s corrupted event packet", hdev->name);
+                       hdev->stat.err_rx++;
+               }
        }
 
-       urb = data->tx_urb;
-       if (urb->status == -EINPROGRESS)
-               skb = NULL;
-       else
-               skb = skb_dequeue(&data->tx_queue);
-
-       if (skb) {
-               skb_copy_from_linear_data(skb, urb->transfer_buffer, skb->len);
-               urb->transfer_buffer_length = skb->len;
-
-               err = usb_submit_urb(urb, GFP_ATOMIC);
-               if (err < 0 && err != -ENODEV) {
-                       BT_ERR("%s submit failed for command urb %p with error %d",
-                                                       data->hdev->name, urb, err);
-                       skb_queue_head(&data->tx_queue, skb);
-               } else
-                       kfree_skb(skb);
+       usb_anchor_urb(urb, &data->rx_anchor);
+
+       err = usb_submit_urb(urb, GFP_ATOMIC);
+       if (err < 0) {
+               BT_ERR("%s urb %p failed to resubmit (%d)",
+                                               hdev->name, urb, -err);
+               usb_unanchor_urb(urb);
        }
 }
 
-static void bpa10x_complete(struct urb *urb)
+static inline int bpa10x_submit_intr_urb(struct hci_dev *hdev)
 {
-       struct bpa10x_data *data = urb->context;
-       unsigned char *buf = urb->transfer_buffer;
-       int err, count = urb->actual_length;
+       struct bpa10x_data *data = hdev->driver_data;
+       struct urb *urb;
+       unsigned char *buf;
+       unsigned int pipe;
+       int err, size = 16;
 
-       BT_DBG("data %p urb %p buf %p count %d", data, urb, buf, count);
+       BT_DBG("%s", hdev->name);
 
-       read_lock(&data->lock);
+       urb = usb_alloc_urb(0, GFP_KERNEL);
+       if (!urb)
+               return -ENOMEM;
 
-       if (!test_bit(HCI_RUNNING, &data->hdev->flags))
-               goto unlock;
+       buf = kmalloc(size, GFP_KERNEL);
+       if (!buf) {
+               usb_free_urb(urb);
+               return -ENOMEM;
+       }
 
-       if (urb->status < 0 || !count)
-               goto resubmit;
+       pipe = usb_rcvintpipe(data->udev, 0x81);
 
-       if (usb_pipein(urb->pipe)) {
-               data->hdev->stat.byte_rx += count;
+       usb_fill_int_urb(urb, data->udev, pipe, buf, size,
+                                               bpa10x_rx_complete, hdev, 1);
 
-               if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT)
-                       bpa10x_recv_event(data, buf, count);
+       urb->transfer_flags |= URB_FREE_BUFFER;
 
-               if (usb_pipetype(urb->pipe) == PIPE_BULK)
-                       bpa10x_recv_bulk(data, buf, count);
-       } else {
-               data->hdev->stat.byte_tx += count;
+       usb_anchor_urb(urb, &data->rx_anchor);
 
-               bpa10x_wakeup(data);
+       err = usb_submit_urb(urb, GFP_KERNEL);
+       if (err < 0) {
+               BT_ERR("%s urb %p submission failed (%d)",
+                                               hdev->name, urb, -err);
+               usb_unanchor_urb(urb);
+               kfree(buf);
        }
 
-resubmit:
-       if (usb_pipein(urb->pipe)) {
-               err = usb_submit_urb(urb, GFP_ATOMIC);
-               if (err < 0 && err != -ENODEV) {
-                       BT_ERR("%s urb %p type %d resubmit status %d",
-                               data->hdev->name, urb, usb_pipetype(urb->pipe), err);
-               }
-       }
+       usb_free_urb(urb);
 
-unlock:
-       read_unlock(&data->lock);
+       return err;
 }
 
-static inline struct urb *bpa10x_alloc_urb(struct usb_device *udev, unsigned int pipe,
-                                       size_t size, gfp_t flags, void *data)
+static inline int bpa10x_submit_bulk_urb(struct hci_dev *hdev)
 {
+       struct bpa10x_data *data = hdev->driver_data;
        struct urb *urb;
-       struct usb_ctrlrequest *cr;
        unsigned char *buf;
+       unsigned int pipe;
+       int err, size = 64;
 
-       BT_DBG("udev %p data %p", udev, data);
+       BT_DBG("%s", hdev->name);
 
-       urb = usb_alloc_urb(0, flags);
+       urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!urb)
-               return NULL;
+               return -ENOMEM;
 
-       buf = kmalloc(size, flags);
+       buf = kmalloc(size, GFP_KERNEL);
        if (!buf) {
                usb_free_urb(urb);
-               return NULL;
+               return -ENOMEM;
        }
 
-       switch (usb_pipetype(pipe)) {
-       case PIPE_CONTROL:
-               cr = kmalloc(sizeof(*cr), flags);
-               if (!cr) {
-                       kfree(buf);
-                       usb_free_urb(urb);
-                       return NULL;
-               }
+       pipe = usb_rcvbulkpipe(data->udev, 0x82);
 
-               cr->bRequestType = USB_TYPE_VENDOR;
-               cr->bRequest     = 0;
-               cr->wIndex       = 0;
-               cr->wValue       = 0;
-               cr->wLength      = __cpu_to_le16(0);
+       usb_fill_bulk_urb(urb, data->udev, pipe,
+                                       buf, size, bpa10x_rx_complete, hdev);
 
-               usb_fill_control_urb(urb, udev, pipe, (void *) cr, buf, 0, bpa10x_complete, data);
-               break;
+       urb->transfer_flags |= URB_FREE_BUFFER;
 
-       case PIPE_INTERRUPT:
-               usb_fill_int_urb(urb, udev, pipe, buf, size, bpa10x_complete, data, 1);
-               break;
+       usb_anchor_urb(urb, &data->rx_anchor);
 
-       case PIPE_BULK:
-               usb_fill_bulk_urb(urb, udev, pipe, buf, size, bpa10x_complete, data);
-               break;
-
-       default:
+       err = usb_submit_urb(urb, GFP_KERNEL);
+       if (err < 0) {
+               BT_ERR("%s urb %p submission failed (%d)",
+                                               hdev->name, urb, -err);
+               usb_unanchor_urb(urb);
                kfree(buf);
-               usb_free_urb(urb);
-               return NULL;
        }
 
-       return urb;
-}
-
-static inline void bpa10x_free_urb(struct urb *urb)
-{
-       BT_DBG("urb %p", urb);
-
-       if (!urb)
-               return;
-
-       kfree(urb->setup_packet);
-       kfree(urb->transfer_buffer);
-
        usb_free_urb(urb);
+
+       return err;
 }
 
 static int bpa10x_open(struct hci_dev *hdev)
 {
        struct bpa10x_data *data = hdev->driver_data;
-       struct usb_device *udev = data->udev;
-       unsigned long flags;
        int err;
 
-       BT_DBG("hdev %p data %p", hdev, data);
+       BT_DBG("%s", hdev->name);
 
        if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
                return 0;
 
-       data->cmd_urb = bpa10x_alloc_urb(udev, usb_sndctrlpipe(udev, BPA10X_CMD_EP),
-                                       BPA10X_CMD_BUF_SIZE, GFP_KERNEL, data);
-       if (!data->cmd_urb) {
-               err = -ENOMEM;
-               goto done;
-       }
-
-       data->evt_urb = bpa10x_alloc_urb(udev, usb_rcvintpipe(udev, BPA10X_EVT_EP),
-                                       BPA10X_EVT_BUF_SIZE, GFP_KERNEL, data);
-       if (!data->evt_urb) {
-               bpa10x_free_urb(data->cmd_urb);
-               err = -ENOMEM;
-               goto done;
-       }
-
-       data->rx_urb = bpa10x_alloc_urb(udev, usb_rcvbulkpipe(udev, BPA10X_RX_EP),
-                                       BPA10X_RX_BUF_SIZE, GFP_KERNEL, data);
-       if (!data->rx_urb) {
-               bpa10x_free_urb(data->evt_urb);
-               bpa10x_free_urb(data->cmd_urb);
-               err = -ENOMEM;
-               goto done;
-       }
-
-       data->tx_urb = bpa10x_alloc_urb(udev, usb_sndbulkpipe(udev, BPA10X_TX_EP),
-                                       BPA10X_TX_BUF_SIZE, GFP_KERNEL, data);
-       if (!data->rx_urb) {
-               bpa10x_free_urb(data->rx_urb);
-               bpa10x_free_urb(data->evt_urb);
-               bpa10x_free_urb(data->cmd_urb);
-               err = -ENOMEM;
-               goto done;
-       }
+       err = bpa10x_submit_intr_urb(hdev);
+       if (err < 0)
+               goto error;
 
-       write_lock_irqsave(&data->lock, flags);
+       err = bpa10x_submit_bulk_urb(hdev);
+       if (err < 0)
+               goto error;
 
-       err = usb_submit_urb(data->evt_urb, GFP_ATOMIC);
-       if (err < 0) {
-               BT_ERR("%s submit failed for event urb %p with error %d",
-                                       data->hdev->name, data->evt_urb, err);
-       } else {
-               err = usb_submit_urb(data->rx_urb, GFP_ATOMIC);
-               if (err < 0) {
-                       BT_ERR("%s submit failed for rx urb %p with error %d",
-                                       data->hdev->name, data->evt_urb, err);
-                       usb_kill_urb(data->evt_urb);
-               }
-       }
+       return 0;
 
-       write_unlock_irqrestore(&data->lock, flags);
+error:
+       usb_kill_anchored_urbs(&data->rx_anchor);
 
-done:
-       if (err < 0)
-               clear_bit(HCI_RUNNING, &hdev->flags);
+       clear_bit(HCI_RUNNING, &hdev->flags);
 
        return err;
 }
@@ -446,27 +339,13 @@ done:
 static int bpa10x_close(struct hci_dev *hdev)
 {
        struct bpa10x_data *data = hdev->driver_data;
-       unsigned long flags;
 
-       BT_DBG("hdev %p data %p", hdev, data);
+       BT_DBG("%s", hdev->name);
 
        if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
                return 0;
 
-       write_lock_irqsave(&data->lock, flags);
-
-       skb_queue_purge(&data->cmd_queue);
-       usb_kill_urb(data->cmd_urb);
-       usb_kill_urb(data->evt_urb);
-       usb_kill_urb(data->rx_urb);
-       usb_kill_urb(data->tx_urb);
-
-       write_unlock_irqrestore(&data->lock, flags);
-
-       bpa10x_free_urb(data->cmd_urb);
-       bpa10x_free_urb(data->evt_urb);
-       bpa10x_free_urb(data->rx_urb);
-       bpa10x_free_urb(data->tx_urb);
+       usb_kill_anchored_urbs(&data->rx_anchor);
 
        return 0;
 }
@@ -475,9 +354,9 @@ static int bpa10x_flush(struct hci_dev *hdev)
 {
        struct bpa10x_data *data = hdev->driver_data;
 
-       BT_DBG("hdev %p data %p", hdev, data);
+       BT_DBG("%s", hdev->name);
 
-       skb_queue_purge(&data->cmd_queue);
+       usb_kill_anchored_urbs(&data->tx_anchor);
 
        return 0;
 }
@@ -485,45 +364,78 @@ static int bpa10x_flush(struct hci_dev *hdev)
 static int bpa10x_send_frame(struct sk_buff *skb)
 {
        struct hci_dev *hdev = (struct hci_dev *) skb->dev;
-       struct bpa10x_data *data;
-
-       BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, bt_cb(skb)->pkt_type, skb->len);
+       struct bpa10x_data *data = hdev->driver_data;
+       struct usb_ctrlrequest *dr;
+       struct urb *urb;
+       unsigned int pipe;
+       int err;
 
-       if (!hdev) {
-               BT_ERR("Frame for unknown HCI device");
-               return -ENODEV;
-       }
+       BT_DBG("%s", hdev->name);
 
        if (!test_bit(HCI_RUNNING, &hdev->flags))
                return -EBUSY;
 
-       data = hdev->driver_data;
+       urb = usb_alloc_urb(0, GFP_ATOMIC);
+       if (!urb)
+               return -ENOMEM;
 
        /* Prepend skb with frame type */
-       memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
+       *skb_push(skb, 1) = bt_cb(skb)->pkt_type;
 
        switch (bt_cb(skb)->pkt_type) {
        case HCI_COMMAND_PKT:
+               dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
+               if (!dr) {
+                       usb_free_urb(urb);
+                       return -ENOMEM;
+               }
+
+               dr->bRequestType = USB_TYPE_VENDOR;
+               dr->bRequest     = 0;
+               dr->wIndex       = 0;
+               dr->wValue       = 0;
+               dr->wLength      = __cpu_to_le16(skb->len);
+
+               pipe = usb_sndctrlpipe(data->udev, 0x00);
+
+               usb_fill_control_urb(urb, data->udev, pipe, (void *) dr,
+                               skb->data, skb->len, bpa10x_tx_complete, skb);
+
                hdev->stat.cmd_tx++;
-               skb_queue_tail(&data->cmd_queue, skb);
                break;
 
        case HCI_ACLDATA_PKT:
+               pipe = usb_sndbulkpipe(data->udev, 0x02);
+
+               usb_fill_bulk_urb(urb, data->udev, pipe,
+                               skb->data, skb->len, bpa10x_tx_complete, skb);
+
                hdev->stat.acl_tx++;
-               skb_queue_tail(&data->tx_queue, skb);
                break;
 
        case HCI_SCODATA_PKT:
+               pipe = usb_sndbulkpipe(data->udev, 0x02);
+
+               usb_fill_bulk_urb(urb, data->udev, pipe,
+                               skb->data, skb->len, bpa10x_tx_complete, skb);
+
                hdev->stat.sco_tx++;
-               skb_queue_tail(&data->tx_queue, skb);
                break;
-       };
 
-       read_lock(&data->lock);
+       default:
+               return -EILSEQ;
+       }
+
+       usb_anchor_urb(urb, &data->tx_anchor);
 
-       bpa10x_wakeup(data);
+       err = usb_submit_urb(urb, GFP_ATOMIC);
+       if (err < 0) {
+               BT_ERR("%s urb %p submission failed", hdev->name, urb);
+               kfree(urb->setup_packet);
+               usb_unanchor_urb(urb);
+       }
 
-       read_unlock(&data->lock);
+       usb_free_urb(urb);
 
        return 0;
 }
@@ -532,16 +444,17 @@ static void bpa10x_destruct(struct hci_dev *hdev)
 {
        struct bpa10x_data *data = hdev->driver_data;
 
-       BT_DBG("hdev %p data %p", hdev, data);
+       BT_DBG("%s", hdev->name);
 
+       kfree(data->rx_skb[0]);
+       kfree(data->rx_skb[1]);
        kfree(data);
 }
 
 static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
-       struct usb_device *udev = interface_to_usbdev(intf);
-       struct hci_dev *hdev;
        struct bpa10x_data *data;
+       struct hci_dev *hdev;
        int err;
 
        BT_DBG("intf %p id %p", intf, id);
@@ -549,48 +462,43 @@ static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *
        if (ignore)
                return -ENODEV;
 
-       if (intf->cur_altsetting->desc.bInterfaceNumber > 0)
+       if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
                return -ENODEV;
 
        data = kzalloc(sizeof(*data), GFP_KERNEL);
-       if (!data) {
-               BT_ERR("Can't allocate data structure");
+       if (!data)
                return -ENOMEM;
-       }
-
-       data->udev = udev;
 
-       rwlock_init(&data->lock);
+       data->udev = interface_to_usbdev(intf);
 
-       skb_queue_head_init(&data->cmd_queue);
-       skb_queue_head_init(&data->tx_queue);
+       init_usb_anchor(&data->tx_anchor);
+       init_usb_anchor(&data->rx_anchor);
 
        hdev = hci_alloc_dev();
        if (!hdev) {
-               BT_ERR("Can't allocate HCI device");
                kfree(data);
                return -ENOMEM;
        }
 
-       data->hdev = hdev;
-
        hdev->type = HCI_USB;
        hdev->driver_data = data;
+
+       data->hdev = hdev;
+
        SET_HCIDEV_DEV(hdev, &intf->dev);
 
-       hdev->open      = bpa10x_open;
-       hdev->close     = bpa10x_close;
-       hdev->flush     = bpa10x_flush;
-       hdev->send      = bpa10x_send_frame;
-       hdev->destruct  = bpa10x_destruct;
+       hdev->open     = bpa10x_open;
+       hdev->close    = bpa10x_close;
+       hdev->flush    = bpa10x_flush;
+       hdev->send     = bpa10x_send_frame;
+       hdev->destruct = bpa10x_destruct;
 
        hdev->owner = THIS_MODULE;
 
        err = hci_register_dev(hdev);
        if (err < 0) {
-               BT_ERR("Can't register HCI device");
-               kfree(data);
                hci_free_dev(hdev);
+               kfree(data);
                return err;
        }
 
@@ -602,19 +510,17 @@ static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *
 static void bpa10x_disconnect(struct usb_interface *intf)
 {
        struct bpa10x_data *data = usb_get_intfdata(intf);
-       struct hci_dev *hdev = data->hdev;
 
        BT_DBG("intf %p", intf);
 
-       if (!hdev)
+       if (!data)
                return;
 
        usb_set_intfdata(intf, NULL);
 
-       if (hci_unregister_dev(hdev) < 0)
-               BT_ERR("Can't unregister HCI device %s", hdev->name);
+       hci_unregister_dev(data->hdev);
 
-       hci_free_dev(hdev);
+       hci_free_dev(data->hdev);
 }
 
 static struct usb_driver bpa10x_driver = {
@@ -626,15 +532,9 @@ static struct usb_driver bpa10x_driver = {
 
 static int __init bpa10x_init(void)
 {
-       int err;
-
        BT_INFO("Digianswer Bluetooth USB driver ver %s", VERSION);
 
-       err = usb_register(&bpa10x_driver);
-       if (err < 0)
-               BT_ERR("Failed to register USB driver");
-
-       return err;
+       return usb_register(&bpa10x_driver);
 }
 
 static void __exit bpa10x_exit(void)
index 39516074636b86b1446b8904af9963b7a15925a7..a18f9b8c9e128c33e8c3942ce55d3b7197d22ecb 100644 (file)
@@ -344,10 +344,7 @@ static irqreturn_t bt3c_interrupt(int irq, void *dev_inst)
        unsigned int iobase;
        int iir;
 
-       if (!info || !info->hdev) {
-               BT_ERR("Call of irq %d for unknown device", irq);
-               return IRQ_NONE;
-       }
+       BUG_ON(!info->hdev);
 
        iobase = info->p_dev->io.BasePort1;
 
diff --git a/drivers/bluetooth/btsdio.c b/drivers/bluetooth/btsdio.c
new file mode 100644 (file)
index 0000000..b786f61
--- /dev/null
@@ -0,0 +1,406 @@
+/*
+ *
+ *  Generic Bluetooth SDIO driver
+ *
+ *  Copyright (C) 2007  Cambridge Silicon Radio Ltd.
+ *  Copyright (C) 2007  Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, 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/slab.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/skbuff.h>
+
+#include <linux/mmc/sdio_ids.h>
+#include <linux/mmc/sdio_func.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#ifndef CONFIG_BT_HCIBTSDIO_DEBUG
+#undef  BT_DBG
+#define BT_DBG(D...)
+#endif
+
+#define VERSION "0.1"
+
+static const struct sdio_device_id btsdio_table[] = {
+       /* Generic Bluetooth Type-A SDIO device */
+       { SDIO_DEVICE_CLASS(SDIO_CLASS_BT_A) },
+
+       /* Generic Bluetooth Type-B SDIO device */
+       { SDIO_DEVICE_CLASS(SDIO_CLASS_BT_B) },
+
+       { }     /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(sdio, btsdio_table);
+
+struct btsdio_data {
+       struct hci_dev   *hdev;
+       struct sdio_func *func;
+
+       struct work_struct work;
+
+       struct sk_buff_head txq;
+};
+
+#define REG_RDAT     0x00      /* Receiver Data */
+#define REG_TDAT     0x00      /* Transmitter Data */
+#define REG_PC_RRT   0x10      /* Read Packet Control */
+#define REG_PC_WRT   0x11      /* Write Packet Control */
+#define REG_RTC_STAT 0x12      /* Retry Control Status */
+#define REG_RTC_SET  0x12      /* Retry Control Set */
+#define REG_INTRD    0x13      /* Interrupt Indication */
+#define REG_CL_INTRD 0x13      /* Interrupt Clear */
+#define REG_EN_INTRD 0x14      /* Interrupt Enable */
+#define REG_MD_STAT  0x20      /* Bluetooth Mode Status */
+
+static int btsdio_tx_packet(struct btsdio_data *data, struct sk_buff *skb)
+{
+       int err;
+
+       BT_DBG("%s", data->hdev->name);
+
+       /* Prepend Type-A header */
+       skb_push(skb, 4);
+       skb->data[0] = (skb->len & 0x0000ff);
+       skb->data[1] = (skb->len & 0x00ff00) >> 8;
+       skb->data[2] = (skb->len & 0xff0000) >> 16;
+       skb->data[3] = bt_cb(skb)->pkt_type;
+
+       err = sdio_writesb(data->func, REG_TDAT, skb->data, skb->len);
+       if (err < 0) {
+               sdio_writeb(data->func, 0x01, REG_PC_WRT, NULL);
+               return err;
+       }
+
+       data->hdev->stat.byte_tx += skb->len;
+
+       kfree_skb(skb);
+
+       return 0;
+}
+
+static void btsdio_work(struct work_struct *work)
+{
+       struct btsdio_data *data = container_of(work, struct btsdio_data, work);
+       struct sk_buff *skb;
+       int err;
+
+       BT_DBG("%s", data->hdev->name);
+
+       sdio_claim_host(data->func);
+
+       while ((skb = skb_dequeue(&data->txq))) {
+               err = btsdio_tx_packet(data, skb);
+               if (err < 0) {
+                       data->hdev->stat.err_tx++;
+                       skb_queue_head(&data->txq, skb);
+                       break;
+               }
+       }
+
+       sdio_release_host(data->func);
+}
+
+static int btsdio_rx_packet(struct btsdio_data *data)
+{
+       u8 hdr[4] __attribute__ ((aligned(4)));
+       struct sk_buff *skb;
+       int err, len;
+
+       BT_DBG("%s", data->hdev->name);
+
+       err = sdio_readsb(data->func, hdr, REG_RDAT, 4);
+       if (err < 0)
+               return err;
+
+       len = hdr[0] | (hdr[1] << 8) | (hdr[2] << 16);
+       if (len < 4 || len > 65543)
+               return -EILSEQ;
+
+       skb = bt_skb_alloc(len - 4, GFP_KERNEL);
+       if (!skb) {
+               /* Out of memory. Prepare a read retry and just
+                * return with the expectation that the next time
+                * we're called we'll have more memory. */
+               return -ENOMEM;
+       }
+
+       skb_put(skb, len - 4);
+
+       err = sdio_readsb(data->func, skb->data, REG_RDAT, len - 4);
+       if (err < 0) {
+               kfree(skb);
+               return err;
+       }
+
+       data->hdev->stat.byte_rx += len;
+
+       skb->dev = (void *) data->hdev;
+       bt_cb(skb)->pkt_type = hdr[3];
+
+       err = hci_recv_frame(skb);
+       if (err < 0) {
+               kfree(skb);
+               return err;
+       }
+
+       sdio_writeb(data->func, 0x00, REG_PC_RRT, NULL);
+
+       return 0;
+}
+
+static void btsdio_interrupt(struct sdio_func *func)
+{
+       struct btsdio_data *data = sdio_get_drvdata(func);
+       int intrd;
+
+       BT_DBG("%s", data->hdev->name);
+
+       intrd = sdio_readb(func, REG_INTRD, NULL);
+       if (intrd & 0x01) {
+               sdio_writeb(func, 0x01, REG_CL_INTRD, NULL);
+
+               if (btsdio_rx_packet(data) < 0) {
+                       data->hdev->stat.err_rx++;
+                       sdio_writeb(data->func, 0x01, REG_PC_RRT, NULL);
+               }
+       }
+}
+
+static int btsdio_open(struct hci_dev *hdev)
+{
+       struct btsdio_data *data = hdev->driver_data;
+       int err;
+
+       BT_DBG("%s", hdev->name);
+
+       if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
+               return 0;
+
+       sdio_claim_host(data->func);
+
+       err = sdio_enable_func(data->func);
+       if (err < 0) {
+               clear_bit(HCI_RUNNING, &hdev->flags);
+               goto release;
+       }
+
+       err = sdio_claim_irq(data->func, btsdio_interrupt);
+       if (err < 0) {
+               sdio_disable_func(data->func);
+               clear_bit(HCI_RUNNING, &hdev->flags);
+               goto release;
+       }
+
+       if (data->func->class == SDIO_CLASS_BT_B)
+               sdio_writeb(data->func, 0x00, REG_MD_STAT, NULL);
+
+       sdio_writeb(data->func, 0x01, REG_EN_INTRD, NULL);
+
+release:
+       sdio_release_host(data->func);
+
+       return err;
+}
+
+static int btsdio_close(struct hci_dev *hdev)
+{
+       struct btsdio_data *data = hdev->driver_data;
+
+       BT_DBG("%s", hdev->name);
+
+       if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
+               return 0;
+
+       sdio_claim_host(data->func);
+
+       sdio_writeb(data->func, 0x00, REG_EN_INTRD, NULL);
+
+       sdio_release_irq(data->func);
+       sdio_disable_func(data->func);
+
+       sdio_release_host(data->func);
+
+       return 0;
+}
+
+static int btsdio_flush(struct hci_dev *hdev)
+{
+       struct btsdio_data *data = hdev->driver_data;
+
+       BT_DBG("%s", hdev->name);
+
+       skb_queue_purge(&data->txq);
+
+       return 0;
+}
+
+static int btsdio_send_frame(struct sk_buff *skb)
+{
+       struct hci_dev *hdev = (struct hci_dev *) skb->dev;
+       struct btsdio_data *data = hdev->driver_data;
+
+       BT_DBG("%s", hdev->name);
+
+       if (!test_bit(HCI_RUNNING, &hdev->flags))
+               return -EBUSY;
+
+       switch (bt_cb(skb)->pkt_type) {
+       case HCI_COMMAND_PKT:
+               hdev->stat.cmd_tx++;
+               break;
+
+       case HCI_ACLDATA_PKT:
+               hdev->stat.acl_tx++;
+               break;
+
+       case HCI_SCODATA_PKT:
+               hdev->stat.sco_tx++;
+               break;
+
+       default:
+               return -EILSEQ;
+       }
+
+       skb_queue_tail(&data->txq, skb);
+
+       schedule_work(&data->work);
+
+       return 0;
+}
+
+static void btsdio_destruct(struct hci_dev *hdev)
+{
+       struct btsdio_data *data = hdev->driver_data;
+
+       BT_DBG("%s", hdev->name);
+
+       kfree(data);
+}
+
+static int btsdio_probe(struct sdio_func *func,
+                               const struct sdio_device_id *id)
+{
+       struct btsdio_data *data;
+       struct hci_dev *hdev;
+       struct sdio_func_tuple *tuple = func->tuples;
+       int err;
+
+       BT_DBG("func %p id %p class 0x%04x", func, id, func->class);
+
+       while (tuple) {
+               BT_DBG("code 0x%x size %d", tuple->code, tuple->size);
+               tuple = tuple->next;
+       }
+
+       data = kzalloc(sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       data->func = func;
+
+       INIT_WORK(&data->work, btsdio_work);
+
+       skb_queue_head_init(&data->txq);
+
+       hdev = hci_alloc_dev();
+       if (!hdev) {
+               kfree(data);
+               return -ENOMEM;
+       }
+
+       hdev->type = HCI_SDIO;
+       hdev->driver_data = data;
+
+       data->hdev = hdev;
+
+       SET_HCIDEV_DEV(hdev, &func->dev);
+
+       hdev->open     = btsdio_open;
+       hdev->close    = btsdio_close;
+       hdev->flush    = btsdio_flush;
+       hdev->send     = btsdio_send_frame;
+       hdev->destruct = btsdio_destruct;
+
+       hdev->owner = THIS_MODULE;
+
+       err = hci_register_dev(hdev);
+       if (err < 0) {
+               hci_free_dev(hdev);
+               kfree(data);
+               return err;
+       }
+
+       sdio_set_drvdata(func, data);
+
+       return 0;
+}
+
+static void btsdio_remove(struct sdio_func *func)
+{
+       struct btsdio_data *data = sdio_get_drvdata(func);
+       struct hci_dev *hdev;
+
+       BT_DBG("func %p", func);
+
+       if (!data)
+               return;
+
+       hdev = data->hdev;
+
+       sdio_set_drvdata(func, NULL);
+
+       hci_unregister_dev(hdev);
+
+       hci_free_dev(hdev);
+}
+
+static struct sdio_driver btsdio_driver = {
+       .name           = "btsdio",
+       .probe          = btsdio_probe,
+       .remove         = btsdio_remove,
+       .id_table       = btsdio_table,
+};
+
+static int __init btsdio_init(void)
+{
+       BT_INFO("Generic Bluetooth SDIO driver ver %s", VERSION);
+
+       return sdio_register_driver(&btsdio_driver);
+}
+
+static void __exit btsdio_exit(void)
+{
+       sdio_unregister_driver(&btsdio_driver);
+}
+
+module_init(btsdio_init);
+module_exit(btsdio_exit);
+
+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
+MODULE_DESCRIPTION("Generic Bluetooth SDIO driver ver " VERSION);
+MODULE_VERSION(VERSION);
+MODULE_LICENSE("GPL");
index d7d2ea0d86a179a3330d4f96feeaf66f55c0b632..08f48d577ababf1b38bb0cf4693a311922392a8e 100644 (file)
@@ -294,10 +294,7 @@ static irqreturn_t btuart_interrupt(int irq, void *dev_inst)
        int boguscount = 0;
        int iir, lsr;
 
-       if (!info || !info->hdev) {
-               BT_ERR("Call of irq %d for unknown device", irq);
-               return IRQ_NONE;
-       }
+       BUG_ON(!info->hdev);
 
        iobase = info->p_dev->io.BasePort1;
 
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
new file mode 100644 (file)
index 0000000..12e1089
--- /dev/null
@@ -0,0 +1,564 @@
+/*
+ *
+ *  Generic Bluetooth USB driver
+ *
+ *  Copyright (C) 2005-2007  Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, 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/slab.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/skbuff.h>
+
+#include <linux/usb.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+//#define CONFIG_BT_HCIBTUSB_DEBUG
+#ifndef CONFIG_BT_HCIBTUSB_DEBUG
+#undef  BT_DBG
+#define BT_DBG(D...)
+#endif
+
+#define VERSION "0.1"
+
+static struct usb_device_id btusb_table[] = {
+       /* Generic Bluetooth USB device */
+       { USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
+
+       { }     /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, btusb_table);
+
+static struct usb_device_id blacklist_table[] = {
+       { }     /* Terminating entry */
+};
+
+#define BTUSB_INTR_RUNNING     0
+#define BTUSB_BULK_RUNNING     1
+
+struct btusb_data {
+       struct hci_dev       *hdev;
+       struct usb_device    *udev;
+
+       spinlock_t lock;
+
+       unsigned long flags;
+
+       struct work_struct work;
+
+       struct usb_anchor tx_anchor;
+       struct usb_anchor intr_anchor;
+       struct usb_anchor bulk_anchor;
+
+       struct usb_endpoint_descriptor *intr_ep;
+       struct usb_endpoint_descriptor *bulk_tx_ep;
+       struct usb_endpoint_descriptor *bulk_rx_ep;
+};
+
+static void btusb_intr_complete(struct urb *urb)
+{
+       struct hci_dev *hdev = urb->context;
+       struct btusb_data *data = hdev->driver_data;
+       int err;
+
+       BT_DBG("%s urb %p status %d count %d", hdev->name,
+                                       urb, urb->status, urb->actual_length);
+
+       if (!test_bit(HCI_RUNNING, &hdev->flags))
+               return;
+
+       if (urb->status == 0) {
+               if (hci_recv_fragment(hdev, HCI_EVENT_PKT,
+                                               urb->transfer_buffer,
+                                               urb->actual_length) < 0) {
+                       BT_ERR("%s corrupted event packet", hdev->name);
+                       hdev->stat.err_rx++;
+               }
+       }
+
+       if (!test_bit(BTUSB_INTR_RUNNING, &data->flags))
+               return;
+
+       usb_anchor_urb(urb, &data->intr_anchor);
+
+       err = usb_submit_urb(urb, GFP_ATOMIC);
+       if (err < 0) {
+               BT_ERR("%s urb %p failed to resubmit (%d)",
+                                               hdev->name, urb, -err);
+               usb_unanchor_urb(urb);
+       }
+}
+
+static inline int btusb_submit_intr_urb(struct hci_dev *hdev)
+{
+       struct btusb_data *data = hdev->driver_data;
+       struct urb *urb;
+       unsigned char *buf;
+       unsigned int pipe;
+       int err, size;
+
+       BT_DBG("%s", hdev->name);
+
+       urb = usb_alloc_urb(0, GFP_ATOMIC);
+       if (!urb)
+               return -ENOMEM;
+
+       size = le16_to_cpu(data->intr_ep->wMaxPacketSize);
+
+       buf = kmalloc(size, GFP_ATOMIC);
+       if (!buf) {
+               usb_free_urb(urb);
+               return -ENOMEM;
+       }
+
+       pipe = usb_rcvintpipe(data->udev, data->intr_ep->bEndpointAddress);
+
+       usb_fill_int_urb(urb, data->udev, pipe, buf, size,
+                                               btusb_intr_complete, hdev,
+                                               data->intr_ep->bInterval);
+
+       urb->transfer_flags |= URB_FREE_BUFFER;
+
+       usb_anchor_urb(urb, &data->intr_anchor);
+
+       err = usb_submit_urb(urb, GFP_ATOMIC);
+       if (err < 0) {
+               BT_ERR("%s urb %p submission failed (%d)",
+                                               hdev->name, urb, -err);
+               usb_unanchor_urb(urb);
+               kfree(buf);
+       }
+
+       usb_free_urb(urb);
+
+       return err;
+}
+
+static void btusb_bulk_complete(struct urb *urb)
+{
+       struct hci_dev *hdev = urb->context;
+       struct btusb_data *data = hdev->driver_data;
+       int err;
+
+       BT_DBG("%s urb %p status %d count %d", hdev->name,
+                                       urb, urb->status, urb->actual_length);
+
+       if (!test_bit(HCI_RUNNING, &hdev->flags))
+               return;
+
+       if (urb->status == 0) {
+               if (hci_recv_fragment(hdev, HCI_ACLDATA_PKT,
+                                               urb->transfer_buffer,
+                                               urb->actual_length) < 0) {
+                       BT_ERR("%s corrupted ACL packet", hdev->name);
+                       hdev->stat.err_rx++;
+               }
+       }
+
+       if (!test_bit(BTUSB_BULK_RUNNING, &data->flags))
+               return;
+
+       usb_anchor_urb(urb, &data->bulk_anchor);
+
+       err = usb_submit_urb(urb, GFP_ATOMIC);
+       if (err < 0) {
+               BT_ERR("%s urb %p failed to resubmit (%d)",
+                                               hdev->name, urb, -err);
+               usb_unanchor_urb(urb);
+       }
+}
+
+static inline int btusb_submit_bulk_urb(struct hci_dev *hdev)
+{
+       struct btusb_data *data = hdev->driver_data;
+       struct urb *urb;
+       unsigned char *buf;
+       unsigned int pipe;
+       int err, size;
+
+       BT_DBG("%s", hdev->name);
+
+       urb = usb_alloc_urb(0, GFP_KERNEL);
+       if (!urb)
+               return -ENOMEM;
+
+       size = le16_to_cpu(data->bulk_rx_ep->wMaxPacketSize);
+
+       buf = kmalloc(size, GFP_KERNEL);
+       if (!buf) {
+               usb_free_urb(urb);
+               return -ENOMEM;
+       }
+
+       pipe = usb_rcvbulkpipe(data->udev, data->bulk_rx_ep->bEndpointAddress);
+
+       usb_fill_bulk_urb(urb, data->udev, pipe,
+                                       buf, size, btusb_bulk_complete, hdev);
+
+       urb->transfer_flags |= URB_FREE_BUFFER;
+
+       usb_anchor_urb(urb, &data->bulk_anchor);
+
+       err = usb_submit_urb(urb, GFP_KERNEL);
+       if (err < 0) {
+               BT_ERR("%s urb %p submission failed (%d)",
+                                               hdev->name, urb, -err);
+               usb_unanchor_urb(urb);
+               kfree(buf);
+       }
+
+       usb_free_urb(urb);
+
+       return err;
+}
+
+static void btusb_tx_complete(struct urb *urb)
+{
+       struct sk_buff *skb = urb->context;
+       struct hci_dev *hdev = (struct hci_dev *) skb->dev;
+
+       BT_DBG("%s urb %p status %d count %d", hdev->name,
+                                       urb, urb->status, urb->actual_length);
+
+       if (!test_bit(HCI_RUNNING, &hdev->flags))
+               goto done;
+
+       if (!urb->status)
+               hdev->stat.byte_tx += urb->transfer_buffer_length;
+       else
+               hdev->stat.err_tx++;
+
+done:
+       kfree(urb->setup_packet);
+
+       kfree_skb(skb);
+}
+
+static int btusb_open(struct hci_dev *hdev)
+{
+       struct btusb_data *data = hdev->driver_data;
+       int err;
+
+       BT_DBG("%s", hdev->name);
+
+       if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
+               return 0;
+
+       if (test_and_set_bit(BTUSB_INTR_RUNNING, &data->flags))
+               return 0;
+
+       err = btusb_submit_intr_urb(hdev);
+       if (err < 0) {
+               clear_bit(BTUSB_INTR_RUNNING, &hdev->flags);
+               clear_bit(HCI_RUNNING, &hdev->flags);
+       }
+
+       return err;
+}
+
+static int btusb_close(struct hci_dev *hdev)
+{
+       struct btusb_data *data = hdev->driver_data;
+
+       BT_DBG("%s", hdev->name);
+
+       if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
+               return 0;
+
+       clear_bit(BTUSB_BULK_RUNNING, &data->flags);
+       usb_kill_anchored_urbs(&data->bulk_anchor);
+
+       clear_bit(BTUSB_INTR_RUNNING, &data->flags);
+       usb_kill_anchored_urbs(&data->intr_anchor);
+
+       return 0;
+}
+
+static int btusb_flush(struct hci_dev *hdev)
+{
+       struct btusb_data *data = hdev->driver_data;
+
+       BT_DBG("%s", hdev->name);
+
+       usb_kill_anchored_urbs(&data->tx_anchor);
+
+       return 0;
+}
+
+static int btusb_send_frame(struct sk_buff *skb)
+{
+       struct hci_dev *hdev = (struct hci_dev *) skb->dev;
+       struct btusb_data *data = hdev->driver_data;
+       struct usb_ctrlrequest *dr;
+       struct urb *urb;
+       unsigned int pipe;
+       int err;
+
+       BT_DBG("%s", hdev->name);
+
+       if (!test_bit(HCI_RUNNING, &hdev->flags))
+               return -EBUSY;
+
+       switch (bt_cb(skb)->pkt_type) {
+       case HCI_COMMAND_PKT:
+               urb = usb_alloc_urb(0, GFP_ATOMIC);
+               if (!urb)
+                       return -ENOMEM;
+
+               dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
+               if (!dr) {
+                       usb_free_urb(urb);
+                       return -ENOMEM;
+               }
+
+               dr->bRequestType = USB_TYPE_CLASS;
+               dr->bRequest     = 0;
+               dr->wIndex       = 0;
+               dr->wValue       = 0;
+               dr->wLength      = __cpu_to_le16(skb->len);
+
+               pipe = usb_sndctrlpipe(data->udev, 0x00);
+
+               usb_fill_control_urb(urb, data->udev, pipe, (void *) dr,
+                               skb->data, skb->len, btusb_tx_complete, skb);
+
+               hdev->stat.cmd_tx++;
+               break;
+
+       case HCI_ACLDATA_PKT:
+               urb = usb_alloc_urb(0, GFP_ATOMIC);
+               if (!urb)
+                       return -ENOMEM;
+
+               pipe = usb_sndbulkpipe(data->udev,
+                                       data->bulk_tx_ep->bEndpointAddress);
+
+               usb_fill_bulk_urb(urb, data->udev, pipe,
+                               skb->data, skb->len, btusb_tx_complete, skb);
+
+               hdev->stat.acl_tx++;
+               break;
+
+       case HCI_SCODATA_PKT:
+               hdev->stat.sco_tx++;
+               kfree_skb(skb);
+               return 0;
+
+       default:
+               return -EILSEQ;
+       }
+
+       usb_anchor_urb(urb, &data->tx_anchor);
+
+       err = usb_submit_urb(urb, GFP_ATOMIC);
+       if (err < 0) {
+               BT_ERR("%s urb %p submission failed", hdev->name, urb);
+               kfree(urb->setup_packet);
+               usb_unanchor_urb(urb);
+       }
+
+       usb_free_urb(urb);
+
+       return err;
+}
+
+static void btusb_destruct(struct hci_dev *hdev)
+{
+       struct btusb_data *data = hdev->driver_data;
+
+       BT_DBG("%s", hdev->name);
+
+       kfree(data);
+}
+
+static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
+{
+       struct btusb_data *data = hdev->driver_data;
+
+       BT_DBG("%s evt %d", hdev->name, evt);
+
+       if (evt == HCI_NOTIFY_CONN_ADD || evt == HCI_NOTIFY_CONN_DEL)
+               schedule_work(&data->work);
+}
+
+static void btusb_work(struct work_struct *work)
+{
+       struct btusb_data *data = container_of(work, struct btusb_data, work);
+       struct hci_dev *hdev = data->hdev;
+
+       if (hdev->conn_hash.acl_num == 0) {
+               clear_bit(BTUSB_BULK_RUNNING, &data->flags);
+               usb_kill_anchored_urbs(&data->bulk_anchor);
+               return;
+       }
+
+       if (!test_and_set_bit(BTUSB_BULK_RUNNING, &data->flags)) {
+               if (btusb_submit_bulk_urb(hdev) < 0)
+                       clear_bit(BTUSB_BULK_RUNNING, &data->flags);
+               else
+                       btusb_submit_bulk_urb(hdev);
+       }
+}
+
+static int btusb_probe(struct usb_interface *intf,
+                               const struct usb_device_id *id)
+{
+       struct usb_endpoint_descriptor *ep_desc;
+       struct btusb_data *data;
+       struct hci_dev *hdev;
+       int i, err;
+
+       BT_DBG("intf %p id %p", intf, id);
+
+       if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
+               return -ENODEV;
+
+       if (!id->driver_info) {
+               const struct usb_device_id *match;
+               match = usb_match_id(intf, blacklist_table);
+               if (match)
+                       id = match;
+       }
+
+       data = kzalloc(sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
+               ep_desc = &intf->cur_altsetting->endpoint[i].desc;
+
+               if (!data->intr_ep && usb_endpoint_is_int_in(ep_desc)) {
+                       data->intr_ep = ep_desc;
+                       continue;
+               }
+
+               if (!data->bulk_tx_ep && usb_endpoint_is_bulk_out(ep_desc)) {
+                       data->bulk_tx_ep = ep_desc;
+                       continue;
+               }
+
+               if (!data->bulk_rx_ep && usb_endpoint_is_bulk_in(ep_desc)) {
+                       data->bulk_rx_ep = ep_desc;
+                       continue;
+               }
+       }
+
+       if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep) {
+               kfree(data);
+               return -ENODEV;
+       }
+
+       data->udev = interface_to_usbdev(intf);
+
+       spin_lock_init(&data->lock);
+
+       INIT_WORK(&data->work, btusb_work);
+
+       init_usb_anchor(&data->tx_anchor);
+       init_usb_anchor(&data->intr_anchor);
+       init_usb_anchor(&data->bulk_anchor);
+
+       hdev = hci_alloc_dev();
+       if (!hdev) {
+               kfree(data);
+               return -ENOMEM;
+       }
+
+       hdev->type = HCI_USB;
+       hdev->driver_data = data;
+
+       data->hdev = hdev;
+
+       SET_HCIDEV_DEV(hdev, &intf->dev);
+
+       hdev->open     = btusb_open;
+       hdev->close    = btusb_close;
+       hdev->flush    = btusb_flush;
+       hdev->send     = btusb_send_frame;
+       hdev->destruct = btusb_destruct;
+       hdev->notify   = btusb_notify;
+
+       hdev->owner = THIS_MODULE;
+
+       set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks);
+
+       err = hci_register_dev(hdev);
+       if (err < 0) {
+               hci_free_dev(hdev);
+               kfree(data);
+               return err;
+       }
+
+       usb_set_intfdata(intf, data);
+
+       return 0;
+}
+
+static void btusb_disconnect(struct usb_interface *intf)
+{
+       struct btusb_data *data = usb_get_intfdata(intf);
+       struct hci_dev *hdev;
+
+       BT_DBG("intf %p", intf);
+
+       if (!data)
+               return;
+
+       hdev = data->hdev;
+
+       usb_set_intfdata(intf, NULL);
+
+       hci_unregister_dev(hdev);
+
+       hci_free_dev(hdev);
+}
+
+static struct usb_driver btusb_driver = {
+       .name           = "btusb",
+       .probe          = btusb_probe,
+       .disconnect     = btusb_disconnect,
+       .id_table       = btusb_table,
+};
+
+static int __init btusb_init(void)
+{
+       BT_INFO("Generic Bluetooth USB driver ver %s", VERSION);
+
+       return usb_register(&btusb_driver);
+}
+
+static void __exit btusb_exit(void)
+{
+       usb_deregister(&btusb_driver);
+}
+
+module_init(btusb_init);
+module_exit(btusb_exit);
+
+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
+MODULE_DESCRIPTION("Generic Bluetooth USB driver ver " VERSION);
+MODULE_VERSION(VERSION);
+MODULE_LICENSE("GPL");
index 7f9c54b9964a22fac39628bba97a322ffb76353a..dae45cdf02b2db78db84531bd5b0a41243ad891b 100644 (file)
@@ -298,10 +298,7 @@ static irqreturn_t dtl1_interrupt(int irq, void *dev_inst)
        int boguscount = 0;
        int iir, lsr;
 
-       if (!info || !info->hdev) {
-               BT_ERR("Call of irq %d for unknown device", irq);
-               return IRQ_NONE;
-       }
+       BUG_ON(!info->hdev);
 
        iobase = info->p_dev->io.BasePort1;
 
index d66064ccb31c49ce57315b53d0449c773c076ab7..696f7528f022d44ef18bb0c84134a997288916a7 100644 (file)
@@ -237,7 +237,8 @@ static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
        if (hciextn && chan == 5) {
                struct hci_command_hdr *hdr = (struct hci_command_hdr *) data;
 
-               if (hci_opcode_ogf(__le16_to_cpu(hdr->opcode)) == OGF_VENDOR_CMD) {
+               /* Vendor specific commands */
+               if (hci_opcode_ogf(__le16_to_cpu(hdr->opcode)) == 0x3f) {
                        u8 desc = *(data + HCI_COMMAND_HDR_SIZE);
                        if ((desc & 0xf0) == 0xc0) {
                                data += HCI_COMMAND_HDR_SIZE + 1;
index 6055b9c0ac0f0b2f96380bebbb227b1fcaad055f..e68821d074b0ad90a24f1e686f1b5da9875e808a 100644 (file)
@@ -549,7 +549,10 @@ static int __init hci_uart_init(void)
 #ifdef CONFIG_BT_HCIUART_BCSP
        bcsp_init();
 #endif
-       
+#ifdef CONFIG_BT_HCIUART_LL
+       ll_init();
+#endif
+
        return 0;
 }
 
@@ -563,6 +566,9 @@ static void __exit hci_uart_exit(void)
 #ifdef CONFIG_BT_HCIUART_BCSP
        bcsp_deinit();
 #endif
+#ifdef CONFIG_BT_HCIUART_LL
+       ll_deinit();
+#endif
 
        /* Release tty registration of line discipline */
        if ((err = tty_unregister_ldisc(N_HCI)))
diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c
new file mode 100644 (file)
index 0000000..8c3e62a
--- /dev/null
@@ -0,0 +1,531 @@
+/*
+ *  Texas Instruments' Bluetooth HCILL UART protocol
+ *
+ *  HCILL (HCI Low Level) is a Texas Instruments' power management
+ *  protocol extension to H4.
+ *
+ *  Copyright (C) 2007 Texas Instruments, Inc.
+ *
+ *  Written by Ohad Ben-Cohen <ohad@bencohen.org>
+ *
+ *  Acknowledgements:
+ *  This file is based on hci_h4.c, which was written
+ *  by Maxim Krasnyansky and Marcel Holtmann.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2
+ *  as published by the Free Software Foundation
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/poll.h>
+
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/signal.h>
+#include <linux/ioctl.h>
+#include <linux/skbuff.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#include "hci_uart.h"
+
+/* HCILL commands */
+#define HCILL_GO_TO_SLEEP_IND  0x30
+#define HCILL_GO_TO_SLEEP_ACK  0x31
+#define HCILL_WAKE_UP_IND      0x32
+#define HCILL_WAKE_UP_ACK      0x33
+
+/* HCILL receiver States */
+#define HCILL_W4_PACKET_TYPE   0
+#define HCILL_W4_EVENT_HDR     1
+#define HCILL_W4_ACL_HDR       2
+#define HCILL_W4_SCO_HDR       3
+#define HCILL_W4_DATA          4
+
+/* HCILL states */
+enum hcill_states_e {
+       HCILL_ASLEEP,
+       HCILL_ASLEEP_TO_AWAKE,
+       HCILL_AWAKE,
+       HCILL_AWAKE_TO_ASLEEP
+};
+
+struct hcill_cmd {
+       u8 cmd;
+} __attribute__((packed));
+
+struct ll_struct {
+       unsigned long rx_state;
+       unsigned long rx_count;
+       struct sk_buff *rx_skb;
+       struct sk_buff_head txq;
+       spinlock_t hcill_lock;          /* HCILL state lock     */
+       unsigned long hcill_state;      /* HCILL power state    */
+       struct sk_buff_head tx_wait_q;  /* HCILL wait queue     */
+};
+
+/*
+ * Builds and sends an HCILL command packet.
+ * These are very simple packets with only 1 cmd byte
+ */
+static int send_hcill_cmd(u8 cmd, struct hci_uart *hu)
+{
+       int err = 0;
+       struct sk_buff *skb = NULL;
+       struct ll_struct *ll = hu->priv;
+       struct hcill_cmd *hcill_packet;
+
+       BT_DBG("hu %p cmd 0x%x", hu, cmd);
+
+       /* allocate packet */
+       skb = bt_skb_alloc(1, GFP_ATOMIC);
+       if (!skb) {
+               BT_ERR("cannot allocate memory for HCILL packet");
+               err = -ENOMEM;
+               goto out;
+       }
+
+       /* prepare packet */
+       hcill_packet = (struct hcill_cmd *) skb_put(skb, 1);
+       hcill_packet->cmd = cmd;
+       skb->dev = (void *) hu->hdev;
+
+       /* send packet */
+       skb_queue_tail(&ll->txq, skb);
+out:
+       return err;
+}
+
+/* Initialize protocol */
+static int ll_open(struct hci_uart *hu)
+{
+       struct ll_struct *ll;
+
+       BT_DBG("hu %p", hu);
+
+       ll = kzalloc(sizeof(*ll), GFP_ATOMIC);
+       if (!ll)
+               return -ENOMEM;
+
+       skb_queue_head_init(&ll->txq);
+       skb_queue_head_init(&ll->tx_wait_q);
+       spin_lock_init(&ll->hcill_lock);
+
+       ll->hcill_state = HCILL_AWAKE;
+
+       hu->priv = ll;
+
+       return 0;
+}
+
+/* Flush protocol data */
+static int ll_flush(struct hci_uart *hu)
+{
+       struct ll_struct *ll = hu->priv;
+
+       BT_DBG("hu %p", hu);
+
+       skb_queue_purge(&ll->tx_wait_q);
+       skb_queue_purge(&ll->txq);
+
+       return 0;
+}
+
+/* Close protocol */
+static int ll_close(struct hci_uart *hu)
+{
+       struct ll_struct *ll = hu->priv;
+
+       BT_DBG("hu %p", hu);
+
+       skb_queue_purge(&ll->tx_wait_q);
+       skb_queue_purge(&ll->txq);
+
+       if (ll->rx_skb)
+               kfree_skb(ll->rx_skb);
+
+       hu->priv = NULL;
+
+       kfree(ll);
+
+       return 0;
+}
+
+/*
+ * internal function, which does common work of the device wake up process:
+ * 1. places all pending packets (waiting in tx_wait_q list) in txq list.
+ * 2. changes internal state to HCILL_AWAKE.
+ * Note: assumes that hcill_lock spinlock is taken,
+ * shouldn't be called otherwise!
+ */
+static void __ll_do_awake(struct ll_struct *ll)
+{
+       struct sk_buff *skb = NULL;
+
+       while ((skb = skb_dequeue(&ll->tx_wait_q)))
+               skb_queue_tail(&ll->txq, skb);
+
+       ll->hcill_state = HCILL_AWAKE;
+}
+
+/*
+ * Called upon a wake-up-indication from the device
+ */
+static void ll_device_want_to_wakeup(struct hci_uart *hu)
+{
+       unsigned long flags;
+       struct ll_struct *ll = hu->priv;
+
+       BT_DBG("hu %p", hu);
+
+       /* lock hcill state */
+       spin_lock_irqsave(&ll->hcill_lock, flags);
+
+       switch (ll->hcill_state) {
+       case HCILL_ASLEEP:
+               /* acknowledge device wake up */
+               if (send_hcill_cmd(HCILL_WAKE_UP_ACK, hu) < 0) {
+                       BT_ERR("cannot acknowledge device wake up");
+                       goto out;
+               }
+               break;
+       case HCILL_ASLEEP_TO_AWAKE:
+               /*
+                * this state means that a wake-up-indication
+                * is already on its way to the device,
+                * and will serve as the required wake-up-ack
+                */
+               BT_DBG("dual wake-up-indication");
+               break;
+       default:
+               /* any other state are illegal */
+               BT_ERR("received HCILL_WAKE_UP_IND in state %ld", ll->hcill_state);
+               break;
+       }
+
+       /* send pending packets and change state to HCILL_AWAKE */
+       __ll_do_awake(ll);
+
+out:
+       spin_unlock_irqrestore(&ll->hcill_lock, flags);
+
+       /* actually send the packets */
+       hci_uart_tx_wakeup(hu);
+}
+
+/*
+ * Called upon a sleep-indication from the device
+ */
+static void ll_device_want_to_sleep(struct hci_uart *hu)
+{
+       unsigned long flags;
+       struct ll_struct *ll = hu->priv;
+
+       BT_DBG("hu %p", hu);
+
+       /* lock hcill state */
+       spin_lock_irqsave(&ll->hcill_lock, flags);
+
+       /* sanity check */
+       if (ll->hcill_state != HCILL_AWAKE)
+               BT_ERR("ERR: HCILL_GO_TO_SLEEP_IND in state %ld", ll->hcill_state);
+
+       /* acknowledge device sleep */
+       if (send_hcill_cmd(HCILL_GO_TO_SLEEP_ACK, hu) < 0) {
+               BT_ERR("cannot acknowledge device sleep");
+               goto out;
+       }
+
+       /* update state */
+       ll->hcill_state = HCILL_ASLEEP;
+
+out:
+       spin_unlock_irqrestore(&ll->hcill_lock, flags);
+
+       /* actually send the sleep ack packet */
+       hci_uart_tx_wakeup(hu);
+}
+
+/*
+ * Called upon wake-up-acknowledgement from the device
+ */
+static void ll_device_woke_up(struct hci_uart *hu)
+{
+       unsigned long flags;
+       struct ll_struct *ll = hu->priv;
+
+       BT_DBG("hu %p", hu);
+
+       /* lock hcill state */
+       spin_lock_irqsave(&ll->hcill_lock, flags);
+
+       /* sanity check */
+       if (ll->hcill_state != HCILL_ASLEEP_TO_AWAKE)
+               BT_ERR("received HCILL_WAKE_UP_ACK in state %ld", ll->hcill_state);
+
+       /* send pending packets and change state to HCILL_AWAKE */
+       __ll_do_awake(ll);
+
+       spin_unlock_irqrestore(&ll->hcill_lock, flags);
+
+       /* actually send the packets */
+       hci_uart_tx_wakeup(hu);
+}
+
+/* Enqueue frame for transmittion (padding, crc, etc) */
+/* may be called from two simultaneous tasklets */
+static int ll_enqueue(struct hci_uart *hu, struct sk_buff *skb)
+{
+       unsigned long flags = 0;
+       struct ll_struct *ll = hu->priv;
+
+       BT_DBG("hu %p skb %p", hu, skb);
+
+       /* Prepend skb with frame type */
+       memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
+
+       /* lock hcill state */
+       spin_lock_irqsave(&ll->hcill_lock, flags);
+
+       /* act according to current state */
+       switch (ll->hcill_state) {
+       case HCILL_AWAKE:
+               BT_DBG("device awake, sending normally");
+               skb_queue_tail(&ll->txq, skb);
+               break;
+       case HCILL_ASLEEP:
+               BT_DBG("device asleep, waking up and queueing packet");
+               /* save packet for later */
+               skb_queue_tail(&ll->tx_wait_q, skb);
+               /* awake device */
+               if (send_hcill_cmd(HCILL_WAKE_UP_IND, hu) < 0) {
+                       BT_ERR("cannot wake up device");
+                       break;
+               }
+               ll->hcill_state = HCILL_ASLEEP_TO_AWAKE;
+               break;
+       case HCILL_ASLEEP_TO_AWAKE:
+               BT_DBG("device waking up, queueing packet");
+               /* transient state; just keep packet for later */
+               skb_queue_tail(&ll->tx_wait_q, skb);
+               break;
+       default:
+               BT_ERR("illegal hcill state: %ld (losing packet)", ll->hcill_state);
+               kfree_skb(skb);
+               break;
+       }
+
+       spin_unlock_irqrestore(&ll->hcill_lock, flags);
+
+       return 0;
+}
+
+static inline int ll_check_data_len(struct ll_struct *ll, int len)
+{
+       register int room = skb_tailroom(ll->rx_skb);
+
+       BT_DBG("len %d room %d", len, room);
+
+       if (!len) {
+               hci_recv_frame(ll->rx_skb);
+       } else if (len > room) {
+               BT_ERR("Data length is too large");
+               kfree_skb(ll->rx_skb);
+       } else {
+               ll->rx_state = HCILL_W4_DATA;
+               ll->rx_count = len;
+               return len;
+       }
+
+       ll->rx_state = HCILL_W4_PACKET_TYPE;
+       ll->rx_skb   = NULL;
+       ll->rx_count = 0;
+
+       return 0;
+}
+
+/* Recv data */
+static int ll_recv(struct hci_uart *hu, void *data, int count)
+{
+       struct ll_struct *ll = hu->priv;
+       register char *ptr;
+       struct hci_event_hdr *eh;
+       struct hci_acl_hdr   *ah;
+       struct hci_sco_hdr   *sh;
+       register int len, type, dlen;
+
+       BT_DBG("hu %p count %d rx_state %ld rx_count %ld", hu, count, ll->rx_state, ll->rx_count);
+
+       ptr = data;
+       while (count) {
+               if (ll->rx_count) {
+                       len = min_t(unsigned int, ll->rx_count, count);
+                       memcpy(skb_put(ll->rx_skb, len), ptr, len);
+                       ll->rx_count -= len; count -= len; ptr += len;
+
+                       if (ll->rx_count)
+                               continue;
+
+                       switch (ll->rx_state) {
+                       case HCILL_W4_DATA:
+                               BT_DBG("Complete data");
+                               hci_recv_frame(ll->rx_skb);
+
+                               ll->rx_state = HCILL_W4_PACKET_TYPE;
+                               ll->rx_skb = NULL;
+                               continue;
+
+                       case HCILL_W4_EVENT_HDR:
+                               eh = (struct hci_event_hdr *) ll->rx_skb->data;
+
+                               BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
+
+                               ll_check_data_len(ll, eh->plen);
+                               continue;
+
+                       case HCILL_W4_ACL_HDR:
+                               ah = (struct hci_acl_hdr *) ll->rx_skb->data;
+                               dlen = __le16_to_cpu(ah->dlen);
+
+                               BT_DBG("ACL header: dlen %d", dlen);
+
+                               ll_check_data_len(ll, dlen);
+                               continue;
+
+                       case HCILL_W4_SCO_HDR:
+                               sh = (struct hci_sco_hdr *) ll->rx_skb->data;
+
+                               BT_DBG("SCO header: dlen %d", sh->dlen);
+
+                               ll_check_data_len(ll, sh->dlen);
+                               continue;
+                       }
+               }
+
+               /* HCILL_W4_PACKET_TYPE */
+               switch (*ptr) {
+               case HCI_EVENT_PKT:
+                       BT_DBG("Event packet");
+                       ll->rx_state = HCILL_W4_EVENT_HDR;
+                       ll->rx_count = HCI_EVENT_HDR_SIZE;
+                       type = HCI_EVENT_PKT;
+                       break;
+
+               case HCI_ACLDATA_PKT:
+                       BT_DBG("ACL packet");
+                       ll->rx_state = HCILL_W4_ACL_HDR;
+                       ll->rx_count = HCI_ACL_HDR_SIZE;
+                       type = HCI_ACLDATA_PKT;
+                       break;
+
+               case HCI_SCODATA_PKT:
+                       BT_DBG("SCO packet");
+                       ll->rx_state = HCILL_W4_SCO_HDR;
+                       ll->rx_count = HCI_SCO_HDR_SIZE;
+                       type = HCI_SCODATA_PKT;
+                       break;
+
+               /* HCILL signals */
+               case HCILL_GO_TO_SLEEP_IND:
+                       BT_DBG("HCILL_GO_TO_SLEEP_IND packet");
+                       ll_device_want_to_sleep(hu);
+                       ptr++; count--;
+                       continue;
+
+               case HCILL_GO_TO_SLEEP_ACK:
+                       /* shouldn't happen */
+                       BT_ERR("received HCILL_GO_TO_SLEEP_ACK (in state %ld)", ll->hcill_state);
+                       ptr++; count--;
+                       continue;
+
+               case HCILL_WAKE_UP_IND:
+                       BT_DBG("HCILL_WAKE_UP_IND packet");
+                       ll_device_want_to_wakeup(hu);
+                       ptr++; count--;
+                       continue;
+
+               case HCILL_WAKE_UP_ACK:
+                       BT_DBG("HCILL_WAKE_UP_ACK packet");
+                       ll_device_woke_up(hu);
+                       ptr++; count--;
+                       continue;
+
+               default:
+                       BT_ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
+                       hu->hdev->stat.err_rx++;
+                       ptr++; count--;
+                       continue;
+               };
+
+               ptr++; count--;
+
+               /* Allocate packet */
+               ll->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
+               if (!ll->rx_skb) {
+                       BT_ERR("Can't allocate mem for new packet");
+                       ll->rx_state = HCILL_W4_PACKET_TYPE;
+                       ll->rx_count = 0;
+                       return 0;
+               }
+
+               ll->rx_skb->dev = (void *) hu->hdev;
+               bt_cb(ll->rx_skb)->pkt_type = type;
+       }
+
+       return count;
+}
+
+static struct sk_buff *ll_dequeue(struct hci_uart *hu)
+{
+       struct ll_struct *ll = hu->priv;
+       return skb_dequeue(&ll->txq);
+}
+
+static struct hci_uart_proto llp = {
+       .id             = HCI_UART_LL,
+       .open           = ll_open,
+       .close          = ll_close,
+       .recv           = ll_recv,
+       .enqueue        = ll_enqueue,
+       .dequeue        = ll_dequeue,
+       .flush          = ll_flush,
+};
+
+int ll_init(void)
+{
+       int err = hci_uart_register_proto(&llp);
+
+       if (!err)
+               BT_INFO("HCILL protocol initialized");
+       else
+               BT_ERR("HCILL protocol registration failed");
+
+       return err;
+}
+
+int ll_deinit(void)
+{
+       return hci_uart_unregister_proto(&llp);
+}
index 1097ce72393f2813bc82d140df1cca0495124b30..50113db06b9f54144e455193279deec4900028cc 100644 (file)
 #define HCIUARTGETDEVICE       _IOR('U', 202, int)
 
 /* UART protocols */
-#define HCI_UART_MAX_PROTO     4
+#define HCI_UART_MAX_PROTO     5
 
 #define HCI_UART_H4    0
 #define HCI_UART_BCSP  1
 #define HCI_UART_3WIRE 2
 #define HCI_UART_H4DS  3
+#define HCI_UART_LL    4
 
 struct hci_uart;
 
@@ -85,3 +86,8 @@ int h4_deinit(void);
 int bcsp_init(void);
 int bcsp_deinit(void);
 #endif
+
+#ifdef CONFIG_BT_HCIUART_LL
+int ll_init(void);
+int ll_deinit(void);
+#endif
index 79245714f0a777430d459eb2a3c09aa7746410b4..af0561053167cd177d89c499c3d9f2b108843d46 100644 (file)
@@ -1107,7 +1107,7 @@ int open_for_data(struct cdrom_device_info * cdi)
                       is the default case! */
                    cdinfo(CD_OPEN, "bummer. wrong media type.\n"); 
                    cdinfo(CD_WARNING, "pid %d must open device O_NONBLOCK!\n",
-                                       (unsigned int)current->pid); 
+                                       (unsigned int)task_pid_nr(current));
                    ret=-EMEDIUMTYPE;
                    goto clean_up_and_return;
                }
@@ -3458,47 +3458,19 @@ static void cdrom_update_settings(void)
 static int cdrom_sysctl_handler(ctl_table *ctl, int write, struct file * filp,
                                void __user *buffer, size_t *lenp, loff_t *ppos)
 {
-       int *valp = ctl->data;
-       int val = *valp;
        int ret;
        
        ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
 
-       if (write && *valp != val) {
+       if (write) {
        
                /* we only care for 1 or 0. */
-               if (*valp)
-                       *valp = 1;
-               else
-                       *valp = 0;
+               autoclose        = !!cdrom_sysctl_settings.autoclose;
+               autoeject        = !!cdrom_sysctl_settings.autoeject;
+               debug            = !!cdrom_sysctl_settings.debug;
+               lockdoor         = !!cdrom_sysctl_settings.lock;
+               check_media_type = !!cdrom_sysctl_settings.check;
 
-               switch (ctl->ctl_name) {
-               case DEV_CDROM_AUTOCLOSE: {
-                       if (valp == &cdrom_sysctl_settings.autoclose)
-                               autoclose = cdrom_sysctl_settings.autoclose;
-                       break;
-                       }
-               case DEV_CDROM_AUTOEJECT: {
-                       if (valp == &cdrom_sysctl_settings.autoeject)
-                               autoeject = cdrom_sysctl_settings.autoeject;
-                       break;
-                       }
-               case DEV_CDROM_DEBUG: {
-                       if (valp == &cdrom_sysctl_settings.debug)
-                               debug = cdrom_sysctl_settings.debug;
-                       break;
-                       }
-               case DEV_CDROM_LOCK: {
-                       if (valp == &cdrom_sysctl_settings.lock)
-                               lockdoor = cdrom_sysctl_settings.lock;
-                       break;
-                       }
-               case DEV_CDROM_CHECK_MEDIA: {
-                       if (valp == &cdrom_sysctl_settings.check)
-                               check_media_type = cdrom_sysctl_settings.check;
-                       break;
-                       }
-               }
                /* update the option flags according to the changes. we
                   don't have per device options through sysctl yet,
                   but we will have and then this will disappear. */
@@ -3511,7 +3483,6 @@ static int cdrom_sysctl_handler(ctl_table *ctl, int write, struct file * filp,
 /* Place files in /proc/sys/dev/cdrom */
 static ctl_table cdrom_table[] = {
        {
-               .ctl_name       = DEV_CDROM_INFO,
                .procname       = "info",
                .data           = &cdrom_sysctl_settings.info, 
                .maxlen         = CDROM_STR_SIZE,
@@ -3519,7 +3490,6 @@ static ctl_table cdrom_table[] = {
                .proc_handler   = &cdrom_sysctl_info,
        },
        {
-               .ctl_name       = DEV_CDROM_AUTOCLOSE,
                .procname       = "autoclose",
                .data           = &cdrom_sysctl_settings.autoclose,
                .maxlen         = sizeof(int),
@@ -3527,7 +3497,6 @@ static ctl_table cdrom_table[] = {
                .proc_handler   = &cdrom_sysctl_handler,
        },
        {
-               .ctl_name       = DEV_CDROM_AUTOEJECT,
                .procname       = "autoeject",
                .data           = &cdrom_sysctl_settings.autoeject,
                .maxlen         = sizeof(int),
@@ -3535,7 +3504,6 @@ static ctl_table cdrom_table[] = {
                .proc_handler   = &cdrom_sysctl_handler,
        },
        {
-               .ctl_name       = DEV_CDROM_DEBUG,
                .procname       = "debug",
                .data           = &cdrom_sysctl_settings.debug,
                .maxlen         = sizeof(int),
@@ -3543,7 +3511,6 @@ static ctl_table cdrom_table[] = {
                .proc_handler   = &cdrom_sysctl_handler,
        },
        {
-               .ctl_name       = DEV_CDROM_LOCK,
                .procname       = "lock",
                .data           = &cdrom_sysctl_settings.lock,
                .maxlen         = sizeof(int),
@@ -3551,7 +3518,6 @@ static ctl_table cdrom_table[] = {
                .proc_handler   = &cdrom_sysctl_handler,
        },
        {
-               .ctl_name       = DEV_CDROM_CHECK_MEDIA,
                .procname       = "check_media",
                .data           = &cdrom_sysctl_settings.check,
                .maxlen         = sizeof(int),
index 204d53e506de40af3d37d42e2a1030dbdda323d0..bf18d757b87641e2413ab712626f6c0e55b6c7ff 100644 (file)
@@ -36,23 +36,6 @@ config VT
          If unsure, say Y, or else you won't be able to do much with your new
          shiny Linux system :-)
 
-config VT_UNICODE
-       bool "Virtual console is Unicode by default"
-       depends on VT
-       default n
-       ---help---
-         If you say Y here, the virtual terminal will be in UTF-8 by default,
-         and the keyboard will run in unicode mode.
-
-         If you say N here, the virtual terminal will not be in UTF-8 by
-         default, and the keyboard will run in XLATE mode.
-
-         This can also be changed by passing 'default_utf8=<0|1>' on the
-         kernel command line.
-
-         Historically, the kernel has defaulted to non-UTF8 and XLATE mode.
-         If unsure, say N here.
-
 config VT_CONSOLE
        bool "Support for console on virtual terminal" if EMBEDDED
        depends on VT
@@ -630,6 +613,10 @@ config HVC_XEN
        help
          Xen virtual console device driver
 
+config VIRTIO_CONSOLE
+       bool
+       select HVC_DRIVER
+
 config HVCS
        tristate "IBM Hypervisor Virtual Console Server support"
        depends on PPC_PSERIES
@@ -649,8 +636,6 @@ config HVCS
 
 source "drivers/char/ipmi/Kconfig"
 
-source "drivers/char/watchdog/Kconfig"
-
 config DS1620
        tristate "NetWinder thermometer support"
        depends on ARCH_NETWINDER
index c78ff26647ee2ba0642017e15e1d6f9805b9de37..07304d50e0cbcbde89e5cb26273bfbad73fdc3fc 100644 (file)
@@ -42,7 +42,6 @@ obj-$(CONFIG_SYNCLINK_GT)     += synclink_gt.o
 obj-$(CONFIG_N_HDLC)           += n_hdlc.o
 obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o
 obj-$(CONFIG_SX)               += sx.o generic_serial.o
-obj-$(CONFIG_LGUEST_GUEST)     += hvc_lguest.o
 obj-$(CONFIG_RIO)              += rio/ generic_serial.o
 obj-$(CONFIG_HVC_CONSOLE)      += hvc_vio.o hvsi.o
 obj-$(CONFIG_HVC_ISERIES)      += hvc_iseries.o
@@ -50,6 +49,7 @@ obj-$(CONFIG_HVC_RTAS)                += hvc_rtas.o
 obj-$(CONFIG_HVC_BEAT)         += hvc_beat.o
 obj-$(CONFIG_HVC_DRIVER)       += hvc_console.o
 obj-$(CONFIG_HVC_XEN)          += hvc_xen.o
+obj-$(CONFIG_VIRTIO_CONSOLE)   += virtio_console.o
 obj-$(CONFIG_RAW_DRIVER)       += raw.o
 obj-$(CONFIG_SGI_SNSC)         += snsc.o snsc_event.o
 obj-$(CONFIG_MSPEC)            += mspec.o
index ec116df919d97c043b45ed89637e73624d59810f..c99e43b837f5ce50010fefb57259699884a79418 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/apm_bios.h>
 #include <linux/capability.h>
 #include <linux/sched.h>
-#include <linux/pm.h>
+#include <linux/suspend.h>
 #include <linux/apm-emulation.h>
 #include <linux/freezer.h>
 #include <linux/device.h>
index 9e0adfe27c12d56cf8d36515f0c6061a47db4a8a..e4f579c3e2455640a3d1dc27c742e20d26ea2c01 100644 (file)
  *
  * Revision 1.36.3.8  1996/06/07 16:29:00  bentson
  * starting minor number at zero; added missing verify_area
- * as noted by Heiko Eissfeldt <heiko@colossus.escape.de>
+ * as noted by Heiko Eißfeldt <heiko@colossus.escape.de>
  *
  * Revision 1.36.3.7  1996/04/19 21:06:18  bentson
  * remove unneeded boot message & fix CLOCAL hardware flow
 static void cy_throttle(struct tty_struct *tty);
 static void cy_send_xchar(struct tty_struct *tty, char ch);
 
-#define IS_CYC_Z(card) ((card).num_chips == -1)
+#define IS_CYC_Z(card) ((card).num_chips == (unsigned int)-1)
 
 #define Z_FPGA_CHECK(card) \
        ((readl(&((struct RUNTIME_9060 __iomem *) \
@@ -727,8 +727,6 @@ static struct tty_driver *cy_serial_driver;
    driver to probe addresses at a different address, add it to
    this table.  If the driver is probing some other board and
    causing problems, remove the offending address from this table.
-   The cy_setup function extracts additional addresses from the
-   boot options line.  The form is "cyclades=address,address..."
 */
 
 static unsigned int cy_isa_addresses[] = {
@@ -897,71 +895,6 @@ static inline int serial_paranoia_check(struct cyclades_port *info,
        return 0;
 }                              /* serial_paranoia_check */
 
-/*
- * This routine is used by the interrupt handler to schedule
- * processing in the software interrupt portion of the driver
- * (also known as the "bottom half").  This can be called any
- * number of times for any channel without harm.
- */
-static inline void cy_sched_event(struct cyclades_port *info, int event)
-{
-       info->event |= 1 << event; /* remember what kind of event and who */
-       schedule_work(&info->tqueue);
-}                              /* cy_sched_event */
-
-/*
- * This routine is used to handle the "bottom half" processing for the
- * serial driver, known also the "software interrupt" processing.
- * This processing is done at the kernel interrupt level, after the
- * cy#/_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
- * is where time-consuming activities which can not be done in the
- * interrupt driver proper are done; the interrupt driver schedules
- * them using cy_sched_event(), and they get done here.
- *
- * This is done through one level of indirection--the task queue.
- * When a hardware interrupt service routine wants service by the
- * driver's bottom half, it enqueues the appropriate tq_struct (one
- * per port) to the keventd work queue and sets a request flag
- * that the work queue be processed.
- *
- * Although this may seem unwieldy, it gives the system a way to
- * pass an argument (in this case the pointer to the cyclades_port
- * structure) to the bottom half of the driver.  Previous kernels
- * had to poll every port to see if that port needed servicing.
- */
-static void
-do_softint(struct work_struct *work)
-{
-       struct cyclades_port *info =
-               container_of(work, struct cyclades_port, tqueue);
-       struct tty_struct    *tty;
-
-       tty = info->tty;
-       if (!tty)
-               return;
-
-       if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) {
-               tty_hangup(info->tty);
-               wake_up_interruptible(&info->open_wait);
-                       info->flags &= ~ASYNC_NORMAL_ACTIVE;
-       }
-       if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event))
-               wake_up_interruptible(&info->open_wait);
-#ifdef CONFIG_CYZ_INTR
-       if (test_and_clear_bit(Cy_EVENT_Z_RX_FULL, &info->event) &&
-                       !timer_pending(&cyz_rx_full_timer[info->line]))
-               mod_timer(&cyz_rx_full_timer[info->line], jiffies + 1);
-#endif
-       if (test_and_clear_bit(Cy_EVENT_DELTA_WAKEUP, &info->event))
-               wake_up_interruptible(&info->delta_msr_wait);
-       tty_wakeup(tty);
-#ifdef Z_WAKE
-       if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event))
-               complete(&info->shutdown_wait);
-#endif
-} /* do_softint */
-
-
 /***********************************************************/
 /********* Start of block of Cyclom-Y specific code ********/
 
@@ -1045,382 +978,332 @@ static unsigned detect_isa_irq(void __iomem * address)
 }
 #endif                         /* CONFIG_ISA */
 
-static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
-                       void __iomem * base_addr, int status, int index)
+static void cyy_chip_rx(struct cyclades_card *cinfo, int chip,
+               void __iomem *base_addr)
 {
        struct cyclades_port *info;
        struct tty_struct *tty;
-       int char_count;
-       int j, len, mdm_change, mdm_status, outch;
-       int save_xir, channel, save_car;
-       char data;
+       int len, index = cinfo->bus_index;
+       u8 save_xir, channel, save_car, data, char_count;
 
-       if (status & CySRReceive) {     /* reception interrupt */
 #ifdef CY_DEBUG_INTERRUPTS
-               printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip);
+       printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip);
 #endif
-               /* determine the channel & change to that context */
-               spin_lock(&cinfo->card_lock);
-               save_xir = (u_char) readb(base_addr + (CyRIR << index));
-               channel = (u_short) (save_xir & CyIRChannel);
-               info = &cinfo->ports[channel + chip * 4];
-               save_car = readb(base_addr + (CyCAR << index));
-               cy_writeb(base_addr + (CyCAR << index), save_xir);
-
-               /* if there is nowhere to put the data, discard it */
-               if (info->tty == NULL) {
-                       j = (readb(base_addr + (CyRIVR << index)) &
-                               CyIVRMask);
-                       if (j == CyIVRRxEx) {   /* exception */
+       /* determine the channel & change to that context */
+       save_xir = readb(base_addr + (CyRIR << index));
+       channel = save_xir & CyIRChannel;
+       info = &cinfo->ports[channel + chip * 4];
+       save_car = readb(base_addr + (CyCAR << index));
+       cy_writeb(base_addr + (CyCAR << index), save_xir);
+
+       /* if there is nowhere to put the data, discard it */
+       if (info->tty == NULL) {
+               if ((readb(base_addr + (CyRIVR << index)) & CyIVRMask) ==
+                               CyIVRRxEx) {    /* exception */
+                       data = readb(base_addr + (CyRDSR << index));
+               } else {        /* normal character reception */
+                       char_count = readb(base_addr + (CyRDCR << index));
+                       while (char_count--)
                                data = readb(base_addr + (CyRDSR << index));
-                       } else {        /* normal character reception */
-                               char_count = readb(base_addr +
-                                               (CyRDCR << index));
-                               while (char_count--) {
-                                       data = readb(base_addr +
-                                               (CyRDSR << index));
-                               }
-                       }
-               } else {        /* there is an open port for this data */
-                       tty = info->tty;
-                       j = (readb(base_addr + (CyRIVR << index)) &
-                                       CyIVRMask);
-                       if (j == CyIVRRxEx) {   /* exception */
-                               data = readb(base_addr + (CyRDSR << index));
-
-                               /* For statistics only */
-                               if (data & CyBREAK)
-                                       info->icount.brk++;
-                               else if (data & CyFRAME)
-                                       info->icount.frame++;
-                               else if (data & CyPARITY)
-                                       info->icount.parity++;
-                               else if (data & CyOVERRUN)
-                                       info->icount.overrun++;
-
-                               if (data & info->ignore_status_mask) {
+               }
+               goto end;
+       }
+       /* there is an open port for this data */
+       tty = info->tty;
+       if ((readb(base_addr + (CyRIVR << index)) & CyIVRMask) ==
+                       CyIVRRxEx) {    /* exception */
+               data = readb(base_addr + (CyRDSR << index));
+
+               /* For statistics only */
+               if (data & CyBREAK)
+                       info->icount.brk++;
+               else if (data & CyFRAME)
+                       info->icount.frame++;
+               else if (data & CyPARITY)
+                       info->icount.parity++;
+               else if (data & CyOVERRUN)
+                       info->icount.overrun++;
+
+               if (data & info->ignore_status_mask) {
+                       info->icount.rx++;
+                       return;
+               }
+               if (tty_buffer_request_room(tty, 1)) {
+                       if (data & info->read_status_mask) {
+                               if (data & CyBREAK) {
+                                       tty_insert_flip_char(tty,
+                                               readb(base_addr + (CyRDSR <<
+                                                       index)), TTY_BREAK);
+                                       info->icount.rx++;
+                                       if (info->flags & ASYNC_SAK)
+                                               do_SAK(tty);
+                               } else if (data & CyFRAME) {
+                                       tty_insert_flip_char( tty,
+                                               readb(base_addr + (CyRDSR <<
+                                                       index)), TTY_FRAME);
+                                       info->icount.rx++;
+                                       info->idle_stats.frame_errs++;
+                               } else if (data & CyPARITY) {
+                                       /* Pieces of seven... */
+                                       tty_insert_flip_char(tty,
+                                               readb(base_addr + (CyRDSR <<
+                                                       index)), TTY_PARITY);
+                                       info->icount.rx++;
+                                       info->idle_stats.parity_errs++;
+                               } else if (data & CyOVERRUN) {
+                                       tty_insert_flip_char(tty, 0,
+                                                       TTY_OVERRUN);
+                                       info->icount.rx++;
+                                       /* If the flip buffer itself is
+                                          overflowing, we still lose
+                                          the next incoming character.
+                                        */
+                                       tty_insert_flip_char(tty,
+                                               readb(base_addr + (CyRDSR <<
+                                                       index)), TTY_FRAME);
                                        info->icount.rx++;
-                                       spin_unlock(&cinfo->card_lock);
-                                       return;
-                               }
-                               if (tty_buffer_request_room(tty, 1)) {
-                                       if (data & info->read_status_mask) {
-                                               if (data & CyBREAK) {
-                                                       tty_insert_flip_char(
-                                                               tty,
-                                                               readb(
-                                                               base_addr +
-                                                               (CyRDSR <<
-                                                                       index)),
-                                                               TTY_BREAK);
-                                                       info->icount.rx++;
-                                                       if (info->flags &
-                                                           ASYNC_SAK) {
-                                                               do_SAK(tty);
-                                                       }
-                                               } else if (data & CyFRAME) {
-                                                       tty_insert_flip_char(
-                                                               tty,
-                                                               readb(
-                                                               base_addr +
-                                                               (CyRDSR <<
-                                                                       index)),
-                                                               TTY_FRAME);
-                                                       info->icount.rx++;
-                                                       info->idle_stats.
-                                                               frame_errs++;
-                                               } else if (data & CyPARITY) {
-                                                       /* Pieces of seven... */
-                                                       tty_insert_flip_char(
-                                                               tty,
-                                                               readb(
-                                                               base_addr +
-                                                               (CyRDSR <<
-                                                                       index)),
-                                                               TTY_PARITY);
-                                                       info->icount.rx++;
-                                                       info->idle_stats.
-                                                               parity_errs++;
-                                               } else if (data & CyOVERRUN) {
-                                                       tty_insert_flip_char(
-                                                               tty, 0,
-                                                               TTY_OVERRUN);
-                                                       info->icount.rx++;
-                                               /* If the flip buffer itself is
-                                                  overflowing, we still lose
-                                                  the next incoming character.
-                                                */
-                                                       tty_insert_flip_char(
-                                                               tty,
-                                                               readb(
-                                                               base_addr +
-                                                               (CyRDSR <<
-                                                                       index)),
-                                                               TTY_FRAME);
-                                                       info->icount.rx++;
-                                                       info->idle_stats.
-                                                               overruns++;
-                                       /* These two conditions may imply */
-                                       /* a normal read should be done. */
-                                       /* }else if(data & CyTIMEOUT){ */
-                                       /* }else if(data & CySPECHAR){ */
-                                               } else {
-                                                       tty_insert_flip_char(
-                                                               tty, 0,
-                                                               TTY_NORMAL);
-                                                       info->icount.rx++;
-                                               }
-                                       } else {
-                                               tty_insert_flip_char(tty, 0,
-                                                               TTY_NORMAL);
-                                               info->icount.rx++;
-                                       }
-                               } else {
-                                       /* there was a software buffer
-                                          overrun and nothing could be
-                                          done about it!!! */
-                                       info->icount.buf_overrun++;
                                        info->idle_stats.overruns++;
+                               /* These two conditions may imply */
+                               /* a normal read should be done. */
+                               /* } else if(data & CyTIMEOUT) { */
+                               /* } else if(data & CySPECHAR) { */
+                               } else {
+                                       tty_insert_flip_char(tty, 0,
+                                                       TTY_NORMAL);
+                                       info->icount.rx++;
                                }
-                       } else {        /* normal character reception */
-                               /* load # chars available from the chip */
-                               char_count = readb(base_addr +
-                                               (CyRDCR << index));
+                       } else {
+                               tty_insert_flip_char(tty, 0, TTY_NORMAL);
+                               info->icount.rx++;
+                       }
+               } else {
+                       /* there was a software buffer overrun and nothing
+                        * could be done about it!!! */
+                       info->icount.buf_overrun++;
+                       info->idle_stats.overruns++;
+               }
+       } else {        /* normal character reception */
+               /* load # chars available from the chip */
+               char_count = readb(base_addr + (CyRDCR << index));
 
 #ifdef CY_ENABLE_MONITORING
-                               ++info->mon.int_count;
-                               info->mon.char_count += char_count;
-                               if (char_count > info->mon.char_max)
-                                       info->mon.char_max = char_count;
-                               info->mon.char_last = char_count;
+               ++info->mon.int_count;
+               info->mon.char_count += char_count;
+               if (char_count > info->mon.char_max)
+                       info->mon.char_max = char_count;
+               info->mon.char_last = char_count;
 #endif
-                               len = tty_buffer_request_room(tty, char_count);
-                               while (len--) {
-                                       data = readb(base_addr +
-                                                       (CyRDSR << index));
-                                       tty_insert_flip_char(tty, data,
-                                                       TTY_NORMAL);
-                                       info->idle_stats.recv_bytes++;
-                                       info->icount.rx++;
+               len = tty_buffer_request_room(tty, char_count);
+               while (len--) {
+                       data = readb(base_addr + (CyRDSR << index));
+                       tty_insert_flip_char(tty, data, TTY_NORMAL);
+                       info->idle_stats.recv_bytes++;
+                       info->icount.rx++;
 #ifdef CY_16Y_HACK
-                                       udelay(10L);
+                       udelay(10L);
 #endif
-                               }
-                               info->idle_stats.recv_idle = jiffies;
-                       }
-                       tty_schedule_flip(tty);
                }
-               /* end of service */
-               cy_writeb(base_addr + (CyRIR << index), (save_xir & 0x3f));
-               cy_writeb(base_addr + (CyCAR << index), (save_car));
-               spin_unlock(&cinfo->card_lock);
+               info->idle_stats.recv_idle = jiffies;
        }
+       tty_schedule_flip(tty);
+end:
+       /* end of service */
+       cy_writeb(base_addr + (CyRIR << index), save_xir & 0x3f);
+       cy_writeb(base_addr + (CyCAR << index), save_car);
+}
+
+static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip,
+               void __iomem *base_addr)
+{
+       struct cyclades_port *info;
+       int char_count, index = cinfo->bus_index;
+       u8 save_xir, channel, save_car, outch;
 
-       if (status & CySRTransmit) {    /* transmission interrupt */
-               /* Since we only get here when the transmit buffer
-                  is empty, we know we can always stuff a dozen
-                  characters. */
+       /* Since we only get here when the transmit buffer
+          is empty, we know we can always stuff a dozen
+          characters. */
 #ifdef CY_DEBUG_INTERRUPTS
-               printk(KERN_DEBUG "cyy_interrupt: xmit intr, chip %d\n", chip);
+       printk(KERN_DEBUG "cyy_interrupt: xmit intr, chip %d\n", chip);
 #endif
 
-               /* determine the channel & change to that context */
-               spin_lock(&cinfo->card_lock);
-               save_xir = (u_char) readb(base_addr + (CyTIR << index));
-               channel = (u_short) (save_xir & CyIRChannel);
-               save_car = readb(base_addr + (CyCAR << index));
-               cy_writeb(base_addr + (CyCAR << index), save_xir);
+       /* determine the channel & change to that context */
+       save_xir = readb(base_addr + (CyTIR << index));
+       channel = save_xir & CyIRChannel;
+       save_car = readb(base_addr + (CyCAR << index));
+       cy_writeb(base_addr + (CyCAR << index), save_xir);
 
-               /* validate the port# (as configured and open) */
-               if (channel + chip * 4 >= cinfo->nports) {
-                       cy_writeb(base_addr + (CySRER << index),
-                                 readb(base_addr + (CySRER << index)) &
-                                 ~CyTxRdy);
-                       goto txend;
-               }
-               info = &cinfo->ports[channel + chip * 4];
-               if (info->tty == NULL) {
-                       cy_writeb(base_addr + (CySRER << index),
-                                 readb(base_addr + (CySRER << index)) &
-                                 ~CyTxRdy);
-                       goto txdone;
-               }
+       /* validate the port# (as configured and open) */
+       if (channel + chip * 4 >= cinfo->nports) {
+               cy_writeb(base_addr + (CySRER << index),
+                         readb(base_addr + (CySRER << index)) & ~CyTxRdy);
+               goto end;
+       }
+       info = &cinfo->ports[channel + chip * 4];
+       if (info->tty == NULL) {
+               cy_writeb(base_addr + (CySRER << index),
+                         readb(base_addr + (CySRER << index)) & ~CyTxRdy);
+               goto end;
+       }
 
-               /* load the on-chip space for outbound data */
-               char_count = info->xmit_fifo_size;
+       /* load the on-chip space for outbound data */
+       char_count = info->xmit_fifo_size;
 
-               if (info->x_char) {     /* send special char */
-                       outch = info->x_char;
-                       cy_writeb(base_addr + (CyTDR << index), outch);
-                       char_count--;
-                       info->icount.tx++;
-                       info->x_char = 0;
-               }
+       if (info->x_char) {     /* send special char */
+               outch = info->x_char;
+               cy_writeb(base_addr + (CyTDR << index), outch);
+               char_count--;
+               info->icount.tx++;
+               info->x_char = 0;
+       }
 
-               if (info->breakon || info->breakoff) {
-                       if (info->breakon) {
-                               cy_writeb(base_addr + (CyTDR << index), 0);
-                               cy_writeb(base_addr + (CyTDR << index), 0x81);
-                               info->breakon = 0;
-                               char_count -= 2;
-                       }
-                       if (info->breakoff) {
-                               cy_writeb(base_addr + (CyTDR << index), 0);
-                               cy_writeb(base_addr + (CyTDR << index), 0x83);
-                               info->breakoff = 0;
-                               char_count -= 2;
-                       }
+       if (info->breakon || info->breakoff) {
+               if (info->breakon) {
+                       cy_writeb(base_addr + (CyTDR << index), 0);
+                       cy_writeb(base_addr + (CyTDR << index), 0x81);
+                       info->breakon = 0;
+                       char_count -= 2;
+               }
+               if (info->breakoff) {
+                       cy_writeb(base_addr + (CyTDR << index), 0);
+                       cy_writeb(base_addr + (CyTDR << index), 0x83);
+                       info->breakoff = 0;
+                       char_count -= 2;
                }
+       }
 
-               while (char_count-- > 0) {
-                       if (!info->xmit_cnt) {
-                               if (readb(base_addr + (CySRER << index)) &
-                                               CyTxMpty) {
-                                       cy_writeb(base_addr + (CySRER << index),
-                                               readb(base_addr +
-                                                       (CySRER << index)) &
+       while (char_count-- > 0) {
+               if (!info->xmit_cnt) {
+                       if (readb(base_addr + (CySRER << index)) & CyTxMpty) {
+                               cy_writeb(base_addr + (CySRER << index),
+                                       readb(base_addr + (CySRER << index)) &
                                                ~CyTxMpty);
-                               } else {
-                                       cy_writeb(base_addr + (CySRER << index),
-                                               (readb(base_addr +
-                                                       (CySRER << index)) &
+                       } else {
+                               cy_writeb(base_addr + (CySRER << index),
+                                       (readb(base_addr + (CySRER << index)) &
                                                ~CyTxRdy) | CyTxMpty);
-                               }
-                               goto txdone;
                        }
-                       if (info->xmit_buf == NULL) {
-                               cy_writeb(base_addr + (CySRER << index),
-                                       readb(base_addr + (CySRER << index)) &
+                       goto done;
+               }
+               if (info->xmit_buf == NULL) {
+                       cy_writeb(base_addr + (CySRER << index),
+                               readb(base_addr + (CySRER << index)) &
                                        ~CyTxRdy);
-                               goto txdone;
-                       }
-                       if (info->tty->stopped || info->tty->hw_stopped) {
-                               cy_writeb(base_addr + (CySRER << index),
-                                       readb(base_addr + (CySRER << index)) &
+                       goto done;
+               }
+               if (info->tty->stopped || info->tty->hw_stopped) {
+                       cy_writeb(base_addr + (CySRER << index),
+                               readb(base_addr + (CySRER << index)) &
                                        ~CyTxRdy);
-                               goto txdone;
-                       }
-                       /* Because the Embedded Transmit Commands have
-                          been enabled, we must check to see if the
-                          escape character, NULL, is being sent.  If it
-                          is, we must ensure that there is room for it
-                          to be doubled in the output stream.  Therefore
-                          we no longer advance the pointer when the
-                          character is fetched, but rather wait until
-                          after the check for a NULL output character.
-                          This is necessary because there may not be
-                          room for the two chars needed to send a NULL.)
-                        */
-                       outch = info->xmit_buf[info->xmit_tail];
-                       if (outch) {
+                       goto done;
+               }
+               /* Because the Embedded Transmit Commands have been enabled,
+                * we must check to see if the escape character, NULL, is being
+                * sent. If it is, we must ensure that there is room for it to
+                * be doubled in the output stream.  Therefore we no longer
+                * advance the pointer when the character is fetched, but
+                * rather wait until after the check for a NULL output
+                * character. This is necessary because there may not be room
+                * for the two chars needed to send a NULL.)
+                */
+               outch = info->xmit_buf[info->xmit_tail];
+               if (outch) {
+                       info->xmit_cnt--;
+                       info->xmit_tail = (info->xmit_tail + 1) &
+                                       (SERIAL_XMIT_SIZE - 1);
+                       cy_writeb(base_addr + (CyTDR << index), outch);
+                       info->icount.tx++;
+               } else {
+                       if (char_count > 1) {
                                info->xmit_cnt--;
                                info->xmit_tail = (info->xmit_tail + 1) &
-                                               (SERIAL_XMIT_SIZE - 1);
+                                       (SERIAL_XMIT_SIZE - 1);
                                cy_writeb(base_addr + (CyTDR << index), outch);
+                               cy_writeb(base_addr + (CyTDR << index), 0);
                                info->icount.tx++;
-                       } else {
-                               if (char_count > 1) {
-                                       info->xmit_cnt--;
-                                       info->xmit_tail = (info->xmit_tail + 1)&
-                                               (SERIAL_XMIT_SIZE - 1);
-                                       cy_writeb(base_addr + (CyTDR << index),
-                                               outch);
-                                       cy_writeb(base_addr + (CyTDR << index),
-                                               0);
-                                       info->icount.tx++;
-                                       char_count--;
-                               }
+                               char_count--;
                        }
                }
-
-txdone:
-               if (info->xmit_cnt < WAKEUP_CHARS) {
-                       cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
-               }
-txend:
-               /* end of service */
-               cy_writeb(base_addr + (CyTIR << index), (save_xir & 0x3f));
-               cy_writeb(base_addr + (CyCAR << index), (save_car));
-               spin_unlock(&cinfo->card_lock);
        }
 
-       if (status & CySRModem) {       /* modem interrupt */
+done:
+       tty_wakeup(info->tty);
+end:
+       /* end of service */
+       cy_writeb(base_addr + (CyTIR << index), save_xir & 0x3f);
+       cy_writeb(base_addr + (CyCAR << index), save_car);
+}
 
-               /* determine the channel & change to that context */
-               spin_lock(&cinfo->card_lock);
-               save_xir = (u_char) readb(base_addr + (CyMIR << index));
-               channel = (u_short) (save_xir & CyIRChannel);
-               info = &cinfo->ports[channel + chip * 4];
-               save_car = readb(base_addr + (CyCAR << index));
-               cy_writeb(base_addr + (CyCAR << index), save_xir);
+static void cyy_chip_modem(struct cyclades_card *cinfo, int chip,
+               void __iomem *base_addr)
+{
+       struct cyclades_port *info;
+       int index = cinfo->bus_index;
+       u8 save_xir, channel, save_car, mdm_change, mdm_status;
 
-               mdm_change = readb(base_addr + (CyMISR << index));
-               mdm_status = readb(base_addr + (CyMSVR1 << index));
+       /* determine the channel & change to that context */
+       save_xir = readb(base_addr + (CyMIR << index));
+       channel = save_xir & CyIRChannel;
+       info = &cinfo->ports[channel + chip * 4];
+       save_car = readb(base_addr + (CyCAR << index));
+       cy_writeb(base_addr + (CyCAR << index), save_xir);
 
-               if (info->tty) {
-                       if (mdm_change & CyANY_DELTA) {
-                               /* For statistics only */
-                               if (mdm_change & CyDCD)
-                                       info->icount.dcd++;
-                               if (mdm_change & CyCTS)
-                                       info->icount.cts++;
-                               if (mdm_change & CyDSR)
-                                       info->icount.dsr++;
-                               if (mdm_change & CyRI)
-                                       info->icount.rng++;
-
-                               cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP);
-                       }
+       mdm_change = readb(base_addr + (CyMISR << index));
+       mdm_status = readb(base_addr + (CyMSVR1 << index));
 
-                       if ((mdm_change & CyDCD) &&
-                                       (info->flags & ASYNC_CHECK_CD)) {
-                               if (mdm_status & CyDCD) {
-                                       cy_sched_event(info,
-                                                       Cy_EVENT_OPEN_WAKEUP);
-                               } else {
-                                       cy_sched_event(info, Cy_EVENT_HANGUP);
-                               }
-                       }
-                       if ((mdm_change & CyCTS) &&
-                                       (info->flags & ASYNC_CTS_FLOW)) {
-                               if (info->tty->hw_stopped) {
-                                       if (mdm_status & CyCTS) {
-                                               /* cy_start isn't used
-                                                  because... !!! */
-                                               info->tty->hw_stopped = 0;
-                                               cy_writeb(base_addr +
-                                                       (CySRER << index),
-                                                       readb(base_addr +
-                                                               (CySRER <<
-                                                                       index))|
-                                                       CyTxRdy);
-                                               cy_sched_event(info,
-                                                       Cy_EVENT_WRITE_WAKEUP);
-                                       }
-                               } else {
-                                       if (!(mdm_status & CyCTS)) {
-                                               /* cy_stop isn't used
-                                                  because ... !!! */
-                                               info->tty->hw_stopped = 1;
-                                               cy_writeb(base_addr +
-                                                       (CySRER << index),
-                                                       readb(base_addr +
-                                                               (CySRER <<
-                                                               index)) &
-                                                       ~CyTxRdy);
-                                       }
-                               }
+       if (!info->tty)
+               goto end;
+
+       if (mdm_change & CyANY_DELTA) {
+               /* For statistics only */
+               if (mdm_change & CyDCD)
+                       info->icount.dcd++;
+               if (mdm_change & CyCTS)
+                       info->icount.cts++;
+               if (mdm_change & CyDSR)
+                       info->icount.dsr++;
+               if (mdm_change & CyRI)
+                       info->icount.rng++;
+
+               wake_up_interruptible(&info->delta_msr_wait);
+       }
+
+       if ((mdm_change & CyDCD) && (info->flags & ASYNC_CHECK_CD)) {
+               if (!(mdm_status & CyDCD)) {
+                       tty_hangup(info->tty);
+                       info->flags &= ~ASYNC_NORMAL_ACTIVE;
+               }
+               wake_up_interruptible(&info->open_wait);
+       }
+       if ((mdm_change & CyCTS) && (info->flags & ASYNC_CTS_FLOW)) {
+               if (info->tty->hw_stopped) {
+                       if (mdm_status & CyCTS) {
+                               /* cy_start isn't used
+                                  because... !!! */
+                               info->tty->hw_stopped = 0;
+                               cy_writeb(base_addr + (CySRER << index),
+                                       readb(base_addr + (CySRER << index)) |
+                                               CyTxRdy);
+                               tty_wakeup(info->tty);
                        }
-/*                     if (mdm_change & CyDSR) {
+               } else {
+                       if (!(mdm_status & CyCTS)) {
+                               /* cy_stop isn't used
+                                  because ... !!! */
+                               info->tty->hw_stopped = 1;
+                               cy_writeb(base_addr + (CySRER << index),
+                                       readb(base_addr + (CySRER << index)) &
+                                               ~CyTxRdy);
                        }
-                       if (mdm_change & CyRI) {
-                       }*/
                }
-               /* end of service */
-               cy_writeb(base_addr + (CyMIR << index), (save_xir & 0x3f));
-               cy_writeb(base_addr + (CyCAR << index), save_car);
-               spin_unlock(&cinfo->card_lock);
        }
+/*     if (mdm_change & CyDSR) {
+       }
+       if (mdm_change & CyRI) {
+       }*/
+end:
+       /* end of service */
+       cy_writeb(base_addr + (CyMIR << index), save_xir & 0x3f);
+       cy_writeb(base_addr + (CyCAR << index), save_car);
 }
 
 /* The real interrupt service routine is called
@@ -1432,10 +1315,8 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id)
        int status;
        struct cyclades_card *cinfo = dev_id;
        void __iomem *base_addr, *card_base_addr;
-       int chip;
+       unsigned int chip, too_many, had_work;
        int index;
-       int too_many;
-       int had_work;
 
        if (unlikely(cinfo == NULL)) {
 #ifdef CY_DEBUG_INTERRUPTS
@@ -1470,11 +1351,16 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id)
                           chips to be checked in a round-robin fashion (after
                           draining each of a bunch (1000) of characters).
                         */
-                               if (1000 < too_many++) {
+                               if (1000 < too_many++)
                                        break;
-                               }
-                               cyy_intr_chip(cinfo, chip, base_addr, status,
-                                               index);
+                               spin_lock(&cinfo->card_lock);
+                               if (status & CySRReceive) /* rx intr */
+                                       cyy_chip_rx(cinfo, chip, base_addr);
+                               if (status & CySRTransmit) /* tx intr */
+                                       cyy_chip_tx(cinfo, chip, base_addr);
+                               if (status & CySRModem) /* modem intr */
+                                       cyy_chip_modem(cinfo, chip, base_addr);
+                               spin_unlock(&cinfo->card_lock);
                        }
                }
        } while (had_work);
@@ -1529,7 +1415,7 @@ cyz_issue_cmd(struct cyclades_card *cinfo,
        struct ZFW_CTRL __iomem *zfw_ctrl;
        struct BOARD_CTRL __iomem *board_ctrl;
        __u32 __iomem *pci_doorbell;
-       int index;
+       unsigned int index;
 
        firm_id = cinfo->base_addr + ID_ADDRESS;
        if (!ISZLOADED(*cinfo)) {
@@ -1554,13 +1440,12 @@ cyz_issue_cmd(struct cyclades_card *cinfo,
        return 0;
 }                              /* cyz_issue_cmd */
 
-static void
-cyz_handle_rx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl,
+static void cyz_handle_rx(struct cyclades_port *info,
                struct BUF_CTRL __iomem *buf_ctrl)
 {
        struct cyclades_card *cinfo = info->card;
        struct tty_struct *tty = info->tty;
-       int char_count;
+       unsigned int char_count;
        int len;
 #ifdef BLOCKMOVE
        unsigned char *buf;
@@ -1633,9 +1518,11 @@ cyz_handle_rx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl,
                                char_count = rx_put - rx_get;
                        else
                                char_count = rx_put - rx_get + rx_bufsize;
-                       if (char_count >= (int)readl(&buf_ctrl->rx_threshold)) {
-                               cy_sched_event(info, Cy_EVENT_Z_RX_FULL);
-                       }
+                       if (char_count >= readl(&buf_ctrl->rx_threshold) &&
+                                       !timer_pending(&cyz_rx_full_timer[
+                                                       info->line]))
+                               mod_timer(&cyz_rx_full_timer[info->line],
+                                               jiffies + 1);
 #endif
                        info->idle_stats.recv_idle = jiffies;
                        tty_schedule_flip(tty);
@@ -1645,14 +1532,13 @@ cyz_handle_rx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl,
        }
 }
 
-static void
-cyz_handle_tx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl,
+static void cyz_handle_tx(struct cyclades_port *info,
                struct BUF_CTRL __iomem *buf_ctrl)
 {
        struct cyclades_card *cinfo = info->card;
        struct tty_struct *tty = info->tty;
-       char data;
-       int char_count;
+       u8 data;
+       unsigned int char_count;
 #ifdef BLOCKMOVE
        int small_count;
 #endif
@@ -1716,10 +1602,8 @@ cyz_handle_tx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl,
                        info->icount.tx++;
                }
 #endif
+               tty_wakeup(tty);
 ztxdone:
-               if (info->xmit_cnt < WAKEUP_CHARS) {
-                       cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
-               }
                /* Update tx_put */
                cy_writel(&buf_ctrl->tx_put, tx_put);
        }
@@ -1781,10 +1665,11 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
                                if ((fw_ver > 241 ? ((u_long) param) :
                                                readl(&ch_ctrl->rs_status)) &
                                                C_RS_DCD) {
-                                       cy_sched_event(info,
-                                                       Cy_EVENT_OPEN_WAKEUP);
+                                       wake_up_interruptible(&info->open_wait);
                                } else {
-                                       cy_sched_event(info, Cy_EVENT_HANGUP);
+                                       tty_hangup(info->tty);
+                                       wake_up_interruptible(&info->open_wait);
+                                       info->flags &= ~ASYNC_NORMAL_ACTIVE;
                                }
                        }
                        break;
@@ -1802,7 +1687,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
                        break;
 #ifdef Z_WAKE
                case C_CM_IOCTLW:
-                       cy_sched_event(info, Cy_EVENT_SHUTDOWN_WAKEUP);
+                       complete(&info->shutdown_wait);
                        break;
 #endif
 #ifdef CONFIG_CYZ_INTR
@@ -1814,7 +1699,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
                        printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, "
                                        "port %ld\n", info->card, channel);
 #endif
-                       cyz_handle_rx(info, ch_ctrl, buf_ctrl);
+                       cyz_handle_rx(info, buf_ctrl);
                        break;
                case C_CM_TXBEMPTY:
                case C_CM_TXLOWWM:
@@ -1824,7 +1709,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
                        printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, "
                                        "port %ld\n", info->card, channel);
 #endif
-                       cyz_handle_tx(info, ch_ctrl, buf_ctrl);
+                       cyz_handle_tx(info, buf_ctrl);
                        break;
 #endif                         /* CONFIG_CYZ_INTR */
                case C_CM_FATAL:
@@ -1834,7 +1719,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
                        break;
                }
                if (delta_count)
-                       cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP);
+                       wake_up_interruptible(&info->delta_msr_wait);
                if (special_count)
                        tty_schedule_flip(tty);
        }
@@ -1893,10 +1778,9 @@ static void cyz_poll(unsigned long arg)
        struct FIRM_ID __iomem *firm_id;
        struct ZFW_CTRL __iomem *zfw_ctrl;
        struct BOARD_CTRL __iomem *board_ctrl;
-       struct CH_CTRL __iomem *ch_ctrl;
        struct BUF_CTRL __iomem *buf_ctrl;
        unsigned long expires = jiffies + HZ;
-       int card, port;
+       unsigned int port, card;
 
        for (card = 0; card < NR_CARDS; card++) {
                cinfo = &cy_card[card];
@@ -1923,12 +1807,11 @@ static void cyz_poll(unsigned long arg)
                for (port = 0; port < cinfo->nports; port++) {
                        info = &cinfo->ports[port];
                        tty = info->tty;
-                       ch_ctrl = &(zfw_ctrl->ch_ctrl[port]);
                        buf_ctrl = &(zfw_ctrl->buf_ctrl[port]);
 
                        if (!info->throttle)
-                               cyz_handle_rx(info, ch_ctrl, buf_ctrl);
-                       cyz_handle_tx(info, ch_ctrl, buf_ctrl);
+                               cyz_handle_rx(info, buf_ctrl);
+                       cyz_handle_tx(info, buf_ctrl);
                }
                /* poll every 'cyz_polling_cycle' period */
                expires = jiffies + cyz_polling_cycle;
@@ -2491,11 +2374,11 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
 static int cy_open(struct tty_struct *tty, struct file *filp)
 {
        struct cyclades_port *info;
-       unsigned int i;
-       int retval, line;
+       unsigned int i, line;
+       int retval;
 
        line = tty->index;
-       if ((line < 0) || (NR_PORTS <= line)) {
+       if ((tty->index < 0) || (NR_PORTS <= line)) {
                return -ENODEV;
        }
        for (i = 0; i < NR_CARDS; i++)
@@ -2812,7 +2695,6 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
        spin_lock_irqsave(&card->card_lock, flags);
 
        tty->closing = 0;
-       info->event = 0;
        info->tty = NULL;
        if (info->blocked_open) {
                spin_unlock_irqrestore(&card->card_lock, flags);
@@ -4444,7 +4326,6 @@ static void cy_hangup(struct tty_struct *tty)
 
        cy_flush_buffer(tty);
        shutdown(info);
-       info->event = 0;
        info->count = 0;
 #ifdef CY_DEBUG_COUNT
        printk(KERN_DEBUG "cyc:cy_hangup (%d): setting count to 0\n",
@@ -4467,9 +4348,9 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo)
 {
        struct cyclades_port *info;
        u32 uninitialized_var(mailbox);
-       unsigned int nports;
+       unsigned int nports, port;
        unsigned short chip_number;
-       int uninitialized_var(index), port;
+       int uninitialized_var(index);
 
        spin_lock_init(&cinfo->card_lock);
 
@@ -4502,7 +4383,6 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo)
                info->closing_wait = CLOSING_WAIT_DELAY;
                info->close_delay = 5 * HZ / 10;
 
-               INIT_WORK(&info->tqueue, do_softint);
                init_waitqueue_head(&info->open_wait);
                init_waitqueue_head(&info->close_wait);
                init_completion(&info->shutdown_wait);
@@ -5236,7 +5116,7 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev,
                        }
                }
 #endif                         /* CONFIG_CYZ_INTR */
-               cy_card[card_no].num_chips = -1;
+               cy_card[card_no].num_chips = (unsigned int)-1;
        }
 
        /* set cy_card */
@@ -5480,13 +5360,13 @@ static int __init cy_init(void)
 #ifdef CONFIG_PCI
        /* look for pci boards */
        retval = pci_register_driver(&cy_pci_driver);
-       if (retval && !nboards)
-               goto err_unr;
+       if (retval && !nboards) {
+               tty_unregister_driver(cy_serial_driver);
+               goto err_frtty;
+       }
 #endif
 
        return 0;
-err_unr:
-       tty_unregister_driver(cy_serial_driver);
 err_frtty:
        put_tty_driver(cy_serial_driver);
 err:
@@ -5496,7 +5376,7 @@ err:
 static void __exit cy_cleanup_module(void)
 {
        struct cyclades_card *card;
-       int i, e1;
+       unsigned int i, e1;
 
 #ifndef CONFIG_CYZ_INTR
        del_timer_sync(&cyz_timerlist);
@@ -5524,8 +5404,7 @@ static void __exit cy_cleanup_module(void)
 #endif /* CONFIG_CYZ_INTR */
                                )
                                free_irq(card->irq, card);
-                       for (e1 = card->first_line;
-                                       e1 < card->first_line +
+                       for (e1 = card->first_line; e1 < card->first_line +
                                        card->nports; e1++)
                                tty_unregister_device(cy_serial_driver, e1);
                        kfree(card->ports);
index 856774fbe025f17e6f7ed4b3014d2d37e8b08c22..d24a6c2c2c24e10f33d7498fccd30e16a8574ec0 100644 (file)
@@ -1456,7 +1456,7 @@ int drm_freebufs(struct drm_device *dev, void *data,
                buf = dma->buflist[idx];
                if (buf->file_priv != file_priv) {
                        DRM_ERROR("Process %d freeing buffer not owned\n",
-                                 current->pid);
+                                 task_pid_nr(current));
                        return -EINVAL;
                }
                drm_free_buffer(dev, buf);
index 72668b15e5ce2a5a8db7aedce9b73691762a8f05..44a46268b02b138c310c345b6ed6ecbdad7599f3 100644 (file)
@@ -463,7 +463,7 @@ int drm_ioctl(struct inode *inode, struct file *filp,
        ++file_priv->ioctl_count;
 
        DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
-                 current->pid, cmd, nr,
+                 task_pid_nr(current), cmd, nr,
                  (long)old_encode_dev(file_priv->head->device),
                  file_priv->authenticated);
 
index f383fc37190c1a1d2a3a18396adda4d130a6b3f4..3992f73299cc8e161ffd67db642040051a9c8243 100644 (file)
@@ -234,7 +234,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
        if (!drm_cpu_valid())
                return -EINVAL;
 
-       DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor);
+       DRM_DEBUG("pid = %d, minor = %d\n", task_pid_nr(current), minor);
 
        priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES);
        if (!priv)
@@ -244,7 +244,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
        filp->private_data = priv;
        priv->filp = filp;
        priv->uid = current->euid;
-       priv->pid = current->pid;
+       priv->pid = task_pid_nr(current);
        priv->minor = minor;
        priv->head = drm_heads[minor];
        priv->ioctl_count = 0;
@@ -339,7 +339,8 @@ int drm_release(struct inode *inode, struct file *filp)
         */
 
        DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
-                 current->pid, (long)old_encode_dev(file_priv->head->device),
+                 task_pid_nr(current),
+                 (long)old_encode_dev(file_priv->head->device),
                  dev->open_count);
 
        if (dev->driver->reclaim_buffers_locked && dev->lock.hw_lock) {
index 3ad319070704ca7921b5016e35f17384ce5e19d3..4b8e7db5a23256452bff323f1d1b6acd0de34dc2 100644 (file)
@@ -29,7 +29,7 @@
  * Simple open hash tab implementation.
  *
  * Authors:
- * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
  */
 
 #include "drmP.h"
index 0f1376774168bdd8796d04780e719cfa88101a42..573e333ac4573168b6e073847f7e4ce88c1ca63d 100644 (file)
@@ -29,7 +29,7 @@
  * Simple open hash tab implementation.
  *
  * Authors:
- * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
  */
 
 #ifndef DRM_HASHTAB_H
index c6b73e744d67baba2fcd96094e3e3748f8738df2..bea2a7d5b2b22f695d3c6131d2068450ed55f074 100644 (file)
@@ -58,12 +58,12 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv)
 
        if (lock->context == DRM_KERNEL_CONTEXT) {
                DRM_ERROR("Process %d using kernel context %d\n",
-                         current->pid, lock->context);
+                         task_pid_nr(current), lock->context);
                return -EINVAL;
        }
 
        DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
-                 lock->context, current->pid,
+                 lock->context, task_pid_nr(current),
                  dev->lock.hw_lock->lock, lock->flags);
 
        if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE))
@@ -153,7 +153,7 @@ int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv)
 
        if (lock->context == DRM_KERNEL_CONTEXT) {
                DRM_ERROR("Process %d using kernel context %d\n",
-                         current->pid, lock->context);
+                         task_pid_nr(current), lock->context);
                return -EINVAL;
        }
 
index 3e6bc14f744139c758df485a30d30568e4370142..86f4eb61a6a46c2a26247852231e5a612bf1a73e 100644 (file)
@@ -38,7 +38,7 @@
  * Aligned allocations can also see improvement.
  *
  * Authors:
- * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
  */
 
 #include "drmP.h"
index 114e54e0f61bc8d5f0cc1c7d85d2c72cfa1f9750..76e44ac94fb52f4315a6c3498359d1e7d523ec69 100644 (file)
@@ -7,7 +7,7 @@
 #include <linux/delay.h>
 
 /** Current process ID */
-#define DRM_CURRENTPID                 current->pid
+#define DRM_CURRENTPID                 task_pid_nr(current)
 #define DRM_SUSER(p)                   capable(CAP_SYS_ADMIN)
 #define DRM_UDELAY(d)                  udelay(d)
 /** Read a byte from a MMIO region */
index e292bb0eaca2a3c4a303b76939ed94d38dd54be3..b55d5bc6ea612922209ff9236b75789762697515 100644 (file)
@@ -8,12 +8,12 @@
  * \todo Implement the remaining ioctl's for the PCI pools.
  * \todo The wrappers here are so thin that they would be better off inlined..
  *
- * \author Jose Fonseca <jrfonseca@tungstengraphics.com>
+ * \author José Fonseca <jrfonseca@tungstengraphics.com>
  * \author Leif Delgass <ldelgass@retinalburn.net>
  */
 
 /*
- * Copyright 2003 JosFonseca.
+ * Copyright 2003 José Fonseca.
  * Copyright 2003 Leif Delgass.
  * All Rights Reserved.
  *
index f5466966081e9446eda11a1f0b51d2990ab7cf2d..e040f47f369f94255c9e0e4bd843be71b9184e22 100644 (file)
@@ -2,7 +2,7 @@
  * \file drm_sarea.h
  * \brief SAREA definitions
  *
- * \author Michel Dänzer <michel@daenzer.net>
+ * \author Michel Dänzer <michel@daenzer.net>
  */
 
 /*
index 8421a93946d864ed3e44af7d3e168f8f7a06522b..926f146390cec73e40aec3f2eee185f6d311b65b 100644 (file)
@@ -33,7 +33,7 @@
  * struct or a context identifier.
  *
  * Authors:
- * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
  */
 
 #include "drm_sman.h"
index 39a39fefeef14784f6f4a5bbe292a692e2ae427b..08ecf83ad5d4ac73f763663eaf7be302b58e0e60 100644 (file)
@@ -33,7 +33,7 @@
  * struct or a context identifier.
  *
  * Authors:
- * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
  */
 
 #ifndef DRM_SMAN_H
index 8e841bdee6dc219c067032c7add3b74152f5fa63..eb381a7c5beed40920fa577061ebec084331da86 100644 (file)
@@ -1024,7 +1024,7 @@ static int i810_getbuf(struct drm_device *dev, void *data,
        retcode = i810_dma_get_buffer(dev, d, file_priv);
 
        DRM_DEBUG("i810_dma: %d returning %d, granted = %d\n",
-                 current->pid, retcode, d->granted);
+                 task_pid_nr(current), retcode, d->granted);
 
        sarea_priv->last_dispatch = (int)hw_status[5];
 
index 43a1f78712d6cc784f24048d10b9ca71cbc060a9..69a363edb0d202b157d262ea0150aa185384eb1a 100644 (file)
@@ -1409,7 +1409,7 @@ static int i830_getbuf(struct drm_device *dev, void *data,
        retcode = i830_dma_get_buffer(dev, d, file_priv);
 
        DRM_DEBUG("i830_dma: %d returning %d, granted = %d\n",
-                 current->pid, retcode, d->granted);
+                 task_pid_nr(current), retcode, d->granted);
 
        sarea_priv->last_dispatch = (int)hw_status[5];
 
index 250d2aa46581750a349a85fe8742ea0b0aa519d9..5041bd8dbed86b40f719c5d3eac865a7ccf02eaa 100644 (file)
@@ -29,7 +29,7 @@
  *    Rickard E. (Rik) Faith <faith@valinux.com>
  *    Kevin E. Martin <martin@valinux.com>
  *    Gareth Hughes <gareth@valinux.com>
- *    Michel Dzer <daenzerm@student.ethz.ch>
+ *    Michel Dänzer <daenzerm@student.ethz.ch>
  */
 
 #ifndef __R128_DRV_H__
index 2b2407ee490e784c1fc4c12f5344f0c9b4a8ab59..84f5bc36252b92d8cbaf6fc9a5a4a00ee835f463 100644 (file)
@@ -27,7 +27,7 @@
  *
  * Authors:
  *    Keith Whitwell <keith@tungstengraphics.com>
- *    Michel Dzer <michel@daenzer.net>
+ *    Michel Dänzer <michel@daenzer.net>
  */
 
 #include "drmP.h"
index 69c9f2febf43a9b42bb05dada49ac9df8e572c46..f824f2f5fdc29d4474c2da6c57dedf27456e8809 100644 (file)
@@ -3005,7 +3005,7 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil
                /*
                 * This ioctl() doesn't work on 64-bit platforms because hw_lock is a
                 * pointer which can't fit into an int-sized variable.  According to
-                * Michel Dänzer, the ioctl() is only used on embedded platforms, so
+                * Michel Dänzer, the ioctl() is only used on embedded platforms, so
                 * not supporting it shouldn't be a problem.  If the same functionality
                 * is needed on 64-bit platforms, a new ioctl() would have to be added,
                 * so backwards-compatibility for the embedded platforms can be
index 8c66838ff515cf3904832ed070b988312f58fd92..6be1c575758063ff0721bf723544ff3d3d418a63 100644 (file)
@@ -28,7 +28,7 @@
 
 /*
  * Authors:
- *    Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ *    Thomas Hellström <thomas-at-tungstengraphics-dot-com>
  */
 
 #include "drmP.h"
index 9afc1684348d443d7cba58788484337776be6d93..3ffbf86498331453f64bdf1d7b7060d655088099 100644 (file)
@@ -22,7 +22,7 @@
  * DEALINGS IN THE SOFTWARE.
  */
 /*
- * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
  */
 
 #include "drmP.h"
index 28b50296a7bdfb18453a0eff61b59c7c4d7269fc..d6f8214b69f59ab3e2934a810205b81e699a7956 100644 (file)
@@ -20,7 +20,7 @@
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  *
- * Author: Thomas Hellström 2004.
+ * Author: Thomas Hellström 2004.
  */
 
 #ifndef _VIA_VERIFIER_H_
index 2e7ae42a5503be7b3120ee91acc2e9fb50e00cde..28607763ae649001d31894bdd1654c470ebc7818 100644 (file)
@@ -19,7 +19,7 @@
  *
  *  rs_set_termios fixed to look also for changes of the input
  *      flags INPCK, BRKINT, PARMRK, IGNPAR and IGNBRK.
- *                                            Bernd Anhpl 05/17/96.
+ *                                            Bernd Anhäupl 05/17/96.
  *
  * --- End of notices from serial.c ---
  *
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/bitops.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
-#include <asm/bitops.h>
 
 #include <asm/dma.h>
 #include <linux/slab.h>
diff --git a/drivers/char/hvc_lguest.c b/drivers/char/hvc_lguest.c
deleted file mode 100644 (file)
index efccb21..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-/*D:300
- * The Guest console driver
- *
- * This is a trivial console driver: we use lguest's DMA mechanism to send
- * bytes out, and register a DMA buffer to receive bytes in.  It is assumed to
- * be present and available from the very beginning of boot.
- *
- * Writing console drivers is one of the few remaining Dark Arts in Linux.
- * Fortunately for us, the path of virtual consoles has been well-trodden by
- * the PowerPC folks, who wrote "hvc_console.c" to generically support any
- * virtual console.  We use that infrastructure which only requires us to write
- * the basic put_chars and get_chars functions and call the right register
- * functions.
- :*/
-
-/*M:002 The console can be flooded: while the Guest is processing input the
- * Host can send more.  Buffering in the Host could alleviate this, but it is a
- * difficult problem in general. :*/
-/* Copyright (C) 2006 Rusty Russell, 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/err.h>
-#include <linux/init.h>
-#include <linux/lguest_bus.h>
-#include <asm/paravirt.h>
-#include "hvc_console.h"
-
-/*D:340 This is our single console input buffer, with associated "struct
- * lguest_dma" referring to it.  Note the 0-terminated length array, and the
- * use of physical address for the buffer itself. */
-static char inbuf[256];
-static struct lguest_dma cons_input = { .used_len = 0,
-                                       .addr[0] = __pa(inbuf),
-                                       .len[0] = sizeof(inbuf),
-                                       .len[1] = 0 };
-
-/*D:310 The put_chars() callback is pretty straightforward.
- *
- * First we put the pointer and length in a "struct lguest_dma": we only have
- * one pointer, so we set the second length to 0.  Then we use SEND_DMA to send
- * the data to (Host) buffers attached to the console key.  Usually a device's
- * key is a physical address within the device's memory, but because the
- * console device doesn't have any associated physical memory, we use the
- * LGUEST_CONSOLE_DMA_KEY constant (aka 0). */
-static int put_chars(u32 vtermno, const char *buf, int count)
-{
-       struct lguest_dma dma;
-
-       /* FIXME: DMA buffers in a "struct lguest_dma" are not allowed
-        * to go over page boundaries.  This never seems to happen,
-        * but if it did we'd need to fix this code. */
-       dma.len[0] = count;
-       dma.len[1] = 0;
-       dma.addr[0] = __pa(buf);
-
-       lguest_send_dma(LGUEST_CONSOLE_DMA_KEY, &dma);
-       /* We're expected to return the amount of data we wrote: all of it. */
-       return count;
-}
-
-/*D:350 get_chars() is the callback from the hvc_console infrastructure when
- * an interrupt is received.
- *
- * Firstly we see if our buffer has been filled: if not, we return.  The rest
- * of the code deals with the fact that the hvc_console() infrastructure only
- * asks us for 16 bytes at a time.  We keep a "cons_offset" variable for
- * partially-read buffers. */
-static int get_chars(u32 vtermno, char *buf, int count)
-{
-       static int cons_offset;
-
-       /* Nothing left to see here... */
-       if (!cons_input.used_len)
-               return 0;
-
-       /* You want more than we have to give?  Well, try wanting less! */
-       if (cons_input.used_len - cons_offset < count)
-               count = cons_input.used_len - cons_offset;
-
-       /* Copy across to their buffer and increment offset. */
-       memcpy(buf, inbuf + cons_offset, count);
-       cons_offset += count;
-
-       /* Finished?  Zero offset, and reset cons_input so Host will use it
-        * again. */
-       if (cons_offset == cons_input.used_len) {
-               cons_offset = 0;
-               cons_input.used_len = 0;
-       }
-       return count;
-}
-/*:*/
-
-static struct hv_ops lguest_cons = {
-       .get_chars = get_chars,
-       .put_chars = put_chars,
-};
-
-/*D:320 Console drivers are initialized very early so boot messages can go
- * out.  At this stage, the console is output-only.  Our driver checks we're a
- * Guest, and if so hands hvc_instantiate() the console number (0), priority
- * (0), and the struct hv_ops containing the put_chars() function. */
-static int __init cons_init(void)
-{
-       if (strcmp(pv_info.name, "lguest") != 0)
-               return 0;
-
-       return hvc_instantiate(0, 0, &lguest_cons);
-}
-console_initcall(cons_init);
-
-/*D:370 To set up and manage our virtual console, we call hvc_alloc() and
- * stash the result in the private pointer of the "struct lguest_device".
- * Since we never remove the console device we never need this pointer again,
- * but using ->private is considered good form, and you never know who's going
- * to copy your driver.
- *
- * Once the console is set up, we bind our input buffer ready for input. */
-static int lguestcons_probe(struct lguest_device *lgdev)
-{
-       int err;
-
-       /* The first argument of hvc_alloc() is the virtual console number, so
-        * we use zero.  The second argument is the interrupt number.
-        *
-        * The third argument is a "struct hv_ops" containing the put_chars()
-        * and get_chars() pointers.  The final argument is the output buffer
-        * size: we use 256 and expect the Host to have room for us to send
-        * that much. */
-       lgdev->private = hvc_alloc(0, lgdev_irq(lgdev), &lguest_cons, 256);
-       if (IS_ERR(lgdev->private))
-               return PTR_ERR(lgdev->private);
-
-       /* We bind a single DMA buffer at key LGUEST_CONSOLE_DMA_KEY.
-        * "cons_input" is that statically-initialized global DMA buffer we saw
-        * above, and we also give the interrupt we want. */
-       err = lguest_bind_dma(LGUEST_CONSOLE_DMA_KEY, &cons_input, 1,
-                             lgdev_irq(lgdev));
-       if (err)
-               printk("lguest console: failed to bind buffer.\n");
-       return err;
-}
-/* Note the use of lgdev_irq() for the interrupt number.  We tell hvc_alloc()
- * to expect input when this interrupt is triggered, and then tell
- * lguest_bind_dma() that is the interrupt to send us when input comes in. */
-
-/*D:360 From now on the console driver follows standard Guest driver form:
- * register_lguest_driver() registers the device type and probe function, and
- * the probe function sets up the device.
- *
- * The standard "struct lguest_driver": */
-static struct lguest_driver lguestcons_drv = {
-       .name = "lguestcons",
-       .owner = THIS_MODULE,
-       .device_type = LGUEST_DEVICE_T_CONSOLE,
-       .probe = lguestcons_probe,
-};
-
-/* The standard init function */
-static int __init hvc_lguest_init(void)
-{
-       return register_lguest_driver(&lguestcons_drv);
-}
-module_init(hvc_lguest_init);
index e13dd1892bfdf95bb8c8e731528c12eab1a4fb4d..3f35a1c562b1a1bb6c1fa211577caa87ac92c015 100644 (file)
@@ -10,7 +10,7 @@
  * Mostly based on original driver:
  *
  * Copyright (C) 2005 Nokia Corporation
- * Author: Juha Yrj��<juha.yrjola@nokia.com>
+ * Author: Juha Yrjölä <juha.yrjola@nokia.com>
  *
  * This file is licensed under  the terms of the GNU General Public
  * License version 2. This program is licensed "as is" without any
index cd406416effdb30eba7d25c97495052d2b8151f2..30e564516422edd31d42996d520c2fdb6bb7206b 100644 (file)
@@ -371,14 +371,14 @@ static int i8k_proc_show(struct seq_file *seq, void *offset)
        int fn_key, cpu_temp, ac_power;
        int left_fan, right_fan, left_speed, right_speed;
 
-       cpu_temp        = i8k_get_temp(0);                      /* 11100 µs */
-       left_fan        = i8k_get_fan_status(I8K_FAN_LEFT);     /*   580 µs */
-       right_fan       = i8k_get_fan_status(I8K_FAN_RIGHT);    /*   580 µs */
-       left_speed      = i8k_get_fan_speed(I8K_FAN_LEFT);      /*   580 µs */
-       right_speed     = i8k_get_fan_speed(I8K_FAN_RIGHT);     /*   580 µs */
-       fn_key          = i8k_get_fn_status();                  /*   750 µs */
+       cpu_temp        = i8k_get_temp(0);                      /* 11100 Âµs */
+       left_fan        = i8k_get_fan_status(I8K_FAN_LEFT);     /*   580 Âµs */
+       right_fan       = i8k_get_fan_status(I8K_FAN_RIGHT);    /*   580 Âµs */
+       left_speed      = i8k_get_fan_speed(I8K_FAN_LEFT);      /*   580 Âµs */
+       right_speed     = i8k_get_fan_speed(I8K_FAN_RIGHT);     /*   580 Âµs */
+       fn_key          = i8k_get_fn_status();                  /*   750 Âµs */
        if (power_status)
-               ac_power = i8k_get_power_status();              /* 14700 µs */
+               ac_power = i8k_get_power_status();              /* 14700 Âµs */
        else
                ac_power = -1;
 
index 8435fba73dafdcd8e847403e25dee71d2feee90c..5dc1265ce1d5b288c7049c9ecb305e72d223f618 100644 (file)
@@ -221,10 +221,8 @@ struct ipmi_smi
        void                     *send_info;
 
 #ifdef CONFIG_PROC_FS
-       /* A list of proc entries for this interface.  This does not
-          need a lock, only one thread creates it and only one thread
-          destroys it. */
-       spinlock_t             proc_entry_lock;
+       /* A list of proc entries for this interface. */
+       struct mutex           proc_entry_lock;
        struct ipmi_proc_entry *proc_entries;
 #endif
 
@@ -1891,11 +1889,11 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
                file->write_proc = write_proc;
                file->owner = owner;
 
-               spin_lock(&smi->proc_entry_lock);
+               mutex_lock(&smi->proc_entry_lock);
                /* Stick it on the list. */
                entry->next = smi->proc_entries;
                smi->proc_entries = entry;
-               spin_unlock(&smi->proc_entry_lock);
+               mutex_unlock(&smi->proc_entry_lock);
        }
 #endif /* CONFIG_PROC_FS */
 
@@ -1939,7 +1937,7 @@ static void remove_proc_entries(ipmi_smi_t smi)
 #ifdef CONFIG_PROC_FS
        struct ipmi_proc_entry *entry;
 
-       spin_lock(&smi->proc_entry_lock);
+       mutex_lock(&smi->proc_entry_lock);
        while (smi->proc_entries) {
                entry = smi->proc_entries;
                smi->proc_entries = entry->next;
@@ -1948,7 +1946,7 @@ static void remove_proc_entries(ipmi_smi_t smi)
                kfree(entry->name);
                kfree(entry);
        }
-       spin_unlock(&smi->proc_entry_lock);
+       mutex_unlock(&smi->proc_entry_lock);
        remove_proc_entry(smi->proc_dir_name, proc_ipmi_root);
 #endif /* CONFIG_PROC_FS */
 }
@@ -2614,6 +2612,14 @@ channel_handler(ipmi_smi_t intf, struct ipmi_recv_msg *msg)
        return;
 }
 
+void ipmi_poll_interface(ipmi_user_t user)
+{
+       ipmi_smi_t intf = user->intf;
+
+       if (intf->handlers->poll)
+               intf->handlers->poll(intf->send_info);
+}
+
 int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
                      void                     *send_info,
                      struct ipmi_device_id    *device_id,
@@ -2671,7 +2677,7 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
        }
        intf->curr_seq = 0;
 #ifdef CONFIG_PROC_FS
-       spin_lock_init(&intf->proc_entry_lock);
+       mutex_init(&intf->proc_entry_lock);
 #endif
        spin_lock_init(&intf->waiting_msgs_lock);
        INIT_LIST_HEAD(&intf->waiting_msgs);
@@ -4166,6 +4172,7 @@ EXPORT_SYMBOL(ipmi_destroy_user);
 EXPORT_SYMBOL(ipmi_get_version);
 EXPORT_SYMBOL(ipmi_request_settime);
 EXPORT_SYMBOL(ipmi_request_supply_msgs);
+EXPORT_SYMBOL(ipmi_poll_interface);
 EXPORT_SYMBOL(ipmi_register_smi);
 EXPORT_SYMBOL(ipmi_unregister_smi);
 EXPORT_SYMBOL(ipmi_register_for_cmd);
index c1222e98525dad9c19b9ac78c02255ea0f0579a3..4f560d0bb8089fa296dadeaee3a21bfb7a91b052 100644 (file)
@@ -675,7 +675,8 @@ static void handle_transaction_done(struct smi_info *smi_info)
 }
 
 /* Called on timeouts and events.  Timeouts should pass the elapsed
-   time, interrupts should pass in zero. */
+   time, interrupts should pass in zero.  Must be called with
+   si_lock held and interrupts disabled. */
 static enum si_sm_result smi_event_handler(struct smi_info *smi_info,
                                           int time)
 {
@@ -892,13 +893,16 @@ static int ipmi_thread(void *data)
 static void poll(void *send_info)
 {
        struct smi_info *smi_info = send_info;
+       unsigned long flags;
 
        /*
         * Make sure there is some delay in the poll loop so we can
         * drive time forward and timeout things.
         */
        udelay(10);
+       spin_lock_irqsave(&smi_info->si_lock, flags);
        smi_event_handler(smi_info, 10);
+       spin_unlock_irqrestore(&smi_info->si_lock, flags);
 }
 
 static void request_events(void *send_info)
@@ -1006,6 +1010,10 @@ static int smi_start_processing(void       *send_info,
 
        new_smi->intf = intf;
 
+       /* Try to claim any interrupts. */
+       if (new_smi->irq_setup)
+               new_smi->irq_setup(new_smi);
+
        /* Set up the timer that drives the interface. */
        setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi);
        new_smi->last_timeout_jiffies = jiffies;
@@ -2372,20 +2380,9 @@ static int try_get_dev_id(struct smi_info *smi_info)
        /* Otherwise, we got some data. */
        resp_len = smi_info->handlers->get_result(smi_info->si_sm,
                                                  resp, IPMI_MAX_MSG_LENGTH);
-       if (resp_len < 14) {
-               /* That's odd, it should be longer. */
-               rv = -EINVAL;
-               goto out;
-       }
 
-       if ((resp[1] != IPMI_GET_DEVICE_ID_CMD) || (resp[2] != 0)) {
-               /* That's odd, it shouldn't be able to fail. */
-               rv = -EINVAL;
-               goto out;
-       }
-
-       /* Record info from the get device id, in case we need it. */
-       ipmi_demangle_device_id(resp+3, resp_len-3, &smi_info->device_id);
+       /* Check and record info from the get device id, in case we need it. */
+       rv = ipmi_demangle_device_id(resp, resp_len, &smi_info->device_id);
 
  out:
        kfree(resp);
@@ -2765,10 +2762,6 @@ static int try_smi_init(struct smi_info *new_smi)
        setup_oem_data_handler(new_smi);
        setup_xaction_handlers(new_smi);
 
-       /* Try to claim any interrupts. */
-       if (new_smi->irq_setup)
-               new_smi->irq_setup(new_smi);
-
        INIT_LIST_HEAD(&(new_smi->xmit_msgs));
        INIT_LIST_HEAD(&(new_smi->hp_xmit_msgs));
        new_smi->curr_msg = NULL;
index 41f78e2c158f453543ba8d315df7d0b580efa341..e686fc925168a16614cb41ed3932554f3217d3df 100644 (file)
 #include <linux/poll.h>
 #include <linux/string.h>
 #include <linux/ctype.h>
+#include <linux/delay.h>
 #include <asm/atomic.h>
 
-#ifdef CONFIG_X86_LOCAL_APIC
-#include <asm/apic.h>
+#ifdef CONFIG_X86
+/* This is ugly, but I've determined that x86 is the only architecture
+   that can reasonably support the IPMI NMI watchdog timeout at this
+   time.  If another architecture adds this capability somehow, it
+   will have to be a somewhat different mechanism and I have no idea
+   how it will work.  So in the unlikely event that another
+   architecture supports this, we can figure out a good generic
+   mechanism for it at that time. */
+#include <asm/kdebug.h>
+#define HAVE_DIE_NMI
 #endif
 
 #define        PFX "IPMI Watchdog: "
@@ -166,8 +175,6 @@ static char expect_close;
 
 static int ifnum_to_use = -1;
 
-static DECLARE_RWSEM(register_sem);
-
 /* Parameters to ipmi_set_timeout */
 #define IPMI_SET_TIMEOUT_NO_HB                 0
 #define IPMI_SET_TIMEOUT_HB_IF_NECESSARY       1
@@ -193,11 +200,9 @@ static int set_param_int(const char *val, struct kernel_param *kp)
        if (endp == val)
                return -EINVAL;
 
-       down_read(&register_sem);
        *((int *)kp->arg) = l;
        if (watchdog_user)
                rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
-       up_read(&register_sem);
 
        return rv;
 }
@@ -226,17 +231,15 @@ static int set_param_str(const char *val, struct kernel_param *kp)
 
        s = strstrip(valcp);
 
-       down_read(&register_sem);
        rv = fn(s, NULL);
        if (rv)
-               goto out_unlock;
+               goto out;
 
        check_parms();
        if (watchdog_user)
                rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
 
- out_unlock:
-       up_read(&register_sem);
+ out:
        return rv;
 }
 
@@ -319,9 +322,12 @@ static unsigned char ipmi_version_minor;
 /* If a pretimeout occurs, this is used to allow only one panic to happen. */
 static atomic_t preop_panic_excl = ATOMIC_INIT(-1);
 
-static int ipmi_heartbeat(void);
-static void panic_halt_ipmi_heartbeat(void);
+#ifdef HAVE_DIE_NMI
+static int testing_nmi;
+static int nmi_handler_registered;
+#endif
 
+static int ipmi_heartbeat(void);
 
 /* We use a mutex to make sure that only one thing can send a set
    timeout at one time, because we only have one copy of the data.
@@ -360,6 +366,9 @@ static int i_ipmi_set_timeout(struct ipmi_smi_msg  *smi_msg,
        int                               hbnow = 0;
 
 
+       /* These can be cleared as we are setting the timeout. */
+       pretimeout_since_last_heartbeat = 0;
+
        data[0] = 0;
        WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS);
 
@@ -434,31 +443,75 @@ static int ipmi_set_timeout(int do_heartbeat)
 
        wait_for_completion(&set_timeout_wait);
 
+       mutex_unlock(&set_timeout_lock);
+
        if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB)
            || ((send_heartbeat_now)
                && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY)))
-       {
                rv = ipmi_heartbeat();
-       }
-       mutex_unlock(&set_timeout_lock);
 
 out:
        return rv;
 }
 
-static void dummy_smi_free(struct ipmi_smi_msg *msg)
+static atomic_t panic_done_count = ATOMIC_INIT(0);
+
+static void panic_smi_free(struct ipmi_smi_msg *msg)
 {
+       atomic_dec(&panic_done_count);
 }
-static void dummy_recv_free(struct ipmi_recv_msg *msg)
+static void panic_recv_free(struct ipmi_recv_msg *msg)
 {
+       atomic_dec(&panic_done_count);
+}
+
+static struct ipmi_smi_msg panic_halt_heartbeat_smi_msg =
+{
+       .done = panic_smi_free
+};
+static struct ipmi_recv_msg panic_halt_heartbeat_recv_msg =
+{
+       .done = panic_recv_free
+};
+
+static void panic_halt_ipmi_heartbeat(void)
+{
+       struct kernel_ipmi_msg             msg;
+       struct ipmi_system_interface_addr addr;
+       int rv;
+
+       /* Don't reset the timer if we have the timer turned off, that
+           re-enables the watchdog. */
+       if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE)
+               return;
+
+       addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
+       addr.channel = IPMI_BMC_CHANNEL;
+       addr.lun = 0;
+
+       msg.netfn = 0x06;
+       msg.cmd = IPMI_WDOG_RESET_TIMER;
+       msg.data = NULL;
+       msg.data_len = 0;
+       rv = ipmi_request_supply_msgs(watchdog_user,
+                                     (struct ipmi_addr *) &addr,
+                                     0,
+                                     &msg,
+                                     NULL,
+                                     &panic_halt_heartbeat_smi_msg,
+                                     &panic_halt_heartbeat_recv_msg,
+                                     1);
+       if (!rv)
+               atomic_add(2, &panic_done_count);
 }
+
 static struct ipmi_smi_msg panic_halt_smi_msg =
 {
-       .done = dummy_smi_free
+       .done = panic_smi_free
 };
 static struct ipmi_recv_msg panic_halt_recv_msg =
 {
-       .done = dummy_recv_free
+       .done = panic_recv_free
 };
 
 /* Special call, doesn't claim any locks.  This is only to be called
@@ -470,13 +523,21 @@ static void panic_halt_ipmi_set_timeout(void)
        int send_heartbeat_now;
        int rv;
 
+       /* Wait for the messages to be free. */
+       while (atomic_read(&panic_done_count) != 0)
+               ipmi_poll_interface(watchdog_user);
        rv = i_ipmi_set_timeout(&panic_halt_smi_msg,
                                &panic_halt_recv_msg,
                                &send_heartbeat_now);
        if (!rv) {
+               atomic_add(2, &panic_done_count);
                if (send_heartbeat_now)
                        panic_halt_ipmi_heartbeat();
-       }
+       } else
+               printk(KERN_WARNING PFX
+                      "Unable to extend the watchdog timeout.");
+       while (atomic_read(&panic_done_count) != 0)
+               ipmi_poll_interface(watchdog_user);
 }
 
 /* We use a semaphore to make sure that only one thing can send a
@@ -505,24 +566,14 @@ static struct ipmi_recv_msg heartbeat_recv_msg =
        .done = heartbeat_free_recv
 };
  
-static struct ipmi_smi_msg panic_halt_heartbeat_smi_msg =
-{
-       .done = dummy_smi_free
-};
-static struct ipmi_recv_msg panic_halt_heartbeat_recv_msg =
-{
-       .done = dummy_recv_free
-};
 static int ipmi_heartbeat(void)
 {
        struct kernel_ipmi_msg            msg;
        int                               rv;
        struct ipmi_system_interface_addr addr;
 
-       if (ipmi_ignore_heartbeat) {
+       if (ipmi_ignore_heartbeat)
                return 0;
-       }
 
        if (ipmi_start_timer_on_heartbeat) {
                ipmi_start_timer_on_heartbeat = 0;
@@ -533,7 +584,6 @@ static int ipmi_heartbeat(void)
                   We don't want to set the action, though, we want to
                   leave that alone (thus it can't be combined with the
                   above operation. */
-               pretimeout_since_last_heartbeat = 0;
                return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
        }
 
@@ -586,35 +636,6 @@ static int ipmi_heartbeat(void)
        return rv;
 }
 
-static void panic_halt_ipmi_heartbeat(void)
-{
-       struct kernel_ipmi_msg             msg;
-       struct ipmi_system_interface_addr addr;
-
-
-       /* Don't reset the timer if we have the timer turned off, that
-           re-enables the watchdog. */
-       if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE)
-               return;
-
-       addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
-       addr.channel = IPMI_BMC_CHANNEL;
-       addr.lun = 0;
-
-       msg.netfn = 0x06;
-       msg.cmd = IPMI_WDOG_RESET_TIMER;
-       msg.data = NULL;
-       msg.data_len = 0;
-       ipmi_request_supply_msgs(watchdog_user,
-                                (struct ipmi_addr *) &addr,
-                                0,
-                                &msg,
-                                NULL,
-                                &panic_halt_heartbeat_smi_msg,
-                                &panic_halt_heartbeat_recv_msg,
-                                1);
-}
-
 static struct watchdog_info ident =
 {
        .options        = 0,    /* WDIOF_SETTIMEOUT, */
@@ -895,7 +916,6 @@ static void ipmi_register_watchdog(int ipmi_intf)
 {
        int rv = -EBUSY;
 
-       down_write(&register_sem);
        if (watchdog_user)
                goto out;
 
@@ -921,15 +941,56 @@ static void ipmi_register_watchdog(int ipmi_intf)
                printk(KERN_CRIT PFX "Unable to register misc device\n");
        }
 
- out:
-       up_write(&register_sem);
+#ifdef HAVE_DIE_NMI
+       if (nmi_handler_registered) {
+               int old_pretimeout = pretimeout;
+               int old_timeout = timeout;
+               int old_preop_val = preop_val;
+
+               /* Set the pretimeout to go off in a second and give
+                  ourselves plenty of time to stop the timer. */
+               ipmi_watchdog_state = WDOG_TIMEOUT_RESET;
+               preop_val = WDOG_PREOP_NONE; /* Make sure nothing happens */
+               pretimeout = 99;
+               timeout = 100;
+
+               testing_nmi = 1;
+
+               rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB);
+               if (rv) {
+                       printk(KERN_WARNING PFX "Error starting timer to"
+                              " test NMI: 0x%x.  The NMI pretimeout will"
+                              " likely not work\n", rv);
+                       rv = 0;
+                       goto out_restore;
+               }
+
+               msleep(1500);
 
+               if (testing_nmi != 2) {
+                       printk(KERN_WARNING PFX "IPMI NMI didn't seem to"
+                              " occur.  The NMI pretimeout will"
+                              " likely not work\n");
+               }
+       out_restore:
+               testing_nmi = 0;
+               preop_val = old_preop_val;
+               pretimeout = old_pretimeout;
+               timeout = old_timeout;
+       }
+#endif
+
+ out:
        if ((start_now) && (rv == 0)) {
                /* Run from startup, so start the timer now. */
                start_now = 0; /* Disable this function after first startup. */
                ipmi_watchdog_state = action_val;
                ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB);
                printk(KERN_INFO PFX "Starting now!\n");
+       } else {
+               /* Stop the timer now. */
+               ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
+               ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB);
        }
 }
 
@@ -937,8 +998,6 @@ static void ipmi_unregister_watchdog(int ipmi_intf)
 {
        int rv;
 
-       down_write(&register_sem);
-
        if (!watchdog_user)
                goto out;
 
@@ -963,20 +1022,44 @@ static void ipmi_unregister_watchdog(int ipmi_intf)
        watchdog_user = NULL;
 
  out:
-       up_write(&register_sem);
+       return;
 }
 
-#ifdef HAVE_NMI_HANDLER
+#ifdef HAVE_DIE_NMI
 static int
-ipmi_nmi(void *dev_id, int cpu, int handled)
+ipmi_nmi(struct notifier_block *self, unsigned long val, void *data)
 {
+       struct die_args *args = data;
+
+       if (val != DIE_NMI)
+               return NOTIFY_OK;
+
+       /* Hack, if it's a memory or I/O error, ignore it. */
+       if (args->err & 0xc0)
+               return NOTIFY_OK;
+
+       /*
+        * If we get here, it's an NMI that's not a memory or I/O
+        * error.  We can't truly tell if it's from IPMI or not
+        * without sending a message, and sending a message is almost
+        * impossible because of locking.
+        */
+
+       if (testing_nmi) {
+               testing_nmi = 2;
+               return NOTIFY_STOP;
+       }
+
         /* If we are not expecting a timeout, ignore it. */
        if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE)
-               return NOTIFY_DONE;
+               return NOTIFY_OK;
+
+       if (preaction_val != WDOG_PRETIMEOUT_NMI)
+               return NOTIFY_OK;
 
        /* If no one else handled the NMI, we assume it was the IPMI
            watchdog. */
-       if ((!handled) && (preop_val == WDOG_PREOP_PANIC)) {
+       if (preop_val == WDOG_PREOP_PANIC) {
                /* On some machines, the heartbeat will give
                   an error and not work unless we re-enable
                   the timer.   So do so. */
@@ -985,18 +1068,12 @@ ipmi_nmi(void *dev_id, int cpu, int handled)
                        panic(PFX "pre-timeout");
        }
 
-       return NOTIFY_DONE;
+       return NOTIFY_STOP;
 }
 
-static struct nmi_handler ipmi_nmi_handler =
-{
-       .link     = LIST_HEAD_INIT(ipmi_nmi_handler.link),
-       .dev_name = "ipmi_watchdog",
-       .dev_id   = NULL,
-       .handler  = ipmi_nmi,
-       .priority = 0, /* Call us last. */
+static struct notifier_block ipmi_nmi_handler = {
+       .notifier_call = ipmi_nmi
 };
-int nmi_handler_registered;
 #endif
 
 static int wdog_reboot_handler(struct notifier_block *this,
@@ -1009,7 +1086,7 @@ static int wdog_reboot_handler(struct notifier_block *this,
                /* Make sure we only do this once. */
                reboot_event_handled = 1;
 
-               if (code == SYS_DOWN || code == SYS_HALT) {
+               if (code == SYS_POWER_OFF || code == SYS_HALT) {
                        /* Disable the WDT if we are shutting down. */
                        ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
                        panic_halt_ipmi_set_timeout();
@@ -1113,7 +1190,7 @@ static int preaction_op(const char *inval, char *outval)
                preaction_val = WDOG_PRETIMEOUT_NONE;
        else if (strcmp(inval, "pre_smi") == 0)
                preaction_val = WDOG_PRETIMEOUT_SMI;
-#ifdef HAVE_NMI_HANDLER
+#ifdef HAVE_DIE_NMI
        else if (strcmp(inval, "pre_nmi") == 0)
                preaction_val = WDOG_PRETIMEOUT_NMI;
 #endif
@@ -1147,7 +1224,7 @@ static int preop_op(const char *inval, char *outval)
 
 static void check_parms(void)
 {
-#ifdef HAVE_NMI_HANDLER
+#ifdef HAVE_DIE_NMI
        int do_nmi = 0;
        int rv;
 
@@ -1160,20 +1237,9 @@ static void check_parms(void)
                        preop_op("preop_none", NULL);
                        do_nmi = 0;
                }
-#ifdef CONFIG_X86_LOCAL_APIC
-               if (nmi_watchdog == NMI_IO_APIC) {
-                       printk(KERN_WARNING PFX "nmi_watchdog is set to IO APIC"
-                              " mode (value is %d), that is incompatible"
-                              " with using NMI in the IPMI watchdog."
-                              " Disabling IPMI nmi pretimeout.\n",
-                              nmi_watchdog);
-                       preaction_val = WDOG_PRETIMEOUT_NONE;
-                       do_nmi = 0;
-               }
-#endif
        }
        if (do_nmi && !nmi_handler_registered) {
-               rv = request_nmi(&ipmi_nmi_handler);
+               rv = register_die_notifier(&ipmi_nmi_handler);
                if (rv) {
                        printk(KERN_WARNING PFX
                               "Can't register nmi handler\n");
@@ -1181,7 +1247,7 @@ static void check_parms(void)
                } else
                        nmi_handler_registered = 1;
        } else if (!do_nmi && nmi_handler_registered) {
-               release_nmi(&ipmi_nmi_handler);
+               unregister_die_notifier(&ipmi_nmi_handler);
                nmi_handler_registered = 0;
        }
 #endif
@@ -1217,9 +1283,9 @@ static int __init ipmi_wdog_init(void)
 
        rv = ipmi_smi_watcher_register(&smi_watcher);
        if (rv) {
-#ifdef HAVE_NMI_HANDLER
-               if (preaction_val == WDOG_PRETIMEOUT_NMI)
-                       release_nmi(&ipmi_nmi_handler);
+#ifdef HAVE_DIE_NMI
+               if (nmi_handler_registered)
+                       unregister_die_notifier(&ipmi_nmi_handler);
 #endif
                atomic_notifier_chain_unregister(&panic_notifier_list,
                                                 &wdog_panic_notifier);
@@ -1238,9 +1304,9 @@ static void __exit ipmi_wdog_exit(void)
        ipmi_smi_watcher_unregister(&smi_watcher);
        ipmi_unregister_watchdog(watchdog_ifnum);
 
-#ifdef HAVE_NMI_HANDLER
+#ifdef HAVE_DIE_NMI
        if (nmi_handler_registered)
-               release_nmi(&ipmi_nmi_handler);
+               unregister_die_notifier(&ipmi_nmi_handler);
 #endif
 
        atomic_notifier_chain_unregister(&panic_notifier_list,
index 77a7a4a06620e239b9c72f7b6f726f2908732aa0..85d596a3c18c35b7248b4ee98fcaba65c60abcf0 100644 (file)
@@ -1529,7 +1529,7 @@ static int __devinit reset_card(struct pci_dev *pdev,
        portcount = inw(base + 0x2);
        if (!inw(base + 0xe) & 0x1 || (portcount != 0 && portcount != 4 &&
                                portcount != 8 && portcount != 16)) {
-               dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.",
+               dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.\n",
                        card + 1);
                retval = -EIO;
                goto end;
@@ -1622,7 +1622,9 @@ static int __devinit load_firmware(struct pci_dev *pdev,
 
                if ((status = inw(base + 0x4)) != 0) {
                        dev_warn(&pdev->dev, "Card%d rejected load header:\n"
-                               "Address:0x%x\nCount:0x%x\nStatus:0x%x\n",
+                               KERN_WARNING "Address:0x%x\n"
+                               KERN_WARNING "Count:0x%x\n"
+                               KERN_WARNING "Status:0x%x\n",
                                index + 1, frame->addr, frame->count, status);
                        goto errrelfw;
                }
@@ -1666,7 +1668,9 @@ static int __devinit load_firmware(struct pci_dev *pdev,
 
                if ((status = inw(base + 0x4)) != 0) {
                        dev_warn(&pdev->dev, "Card%d rejected verify header:\n"
-                               "Address:0x%x\nCount:0x%x\nStatus: 0x%x\n",
+                               KERN_WARNING "Address:0x%x\n"
+                               KERN_WARNING "Count:0x%x\n"
+                               KERN_WARNING "Status: 0x%x\n",
                                index + 1, frame->addr, frame->count, status);
                        goto errrelfw;
                }
index 212276affa1f5c887233cdd3c14e987a6941fd22..fc54d234507ace68d0470122f8c3dba967b977e5 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/sysrq.h>
 #include <linux/input.h>
 #include <linux/reboot.h>
+#include <linux/notifier.h>
 
 extern void ctrl_alt_del(void);
 
@@ -81,7 +82,8 @@ void compute_shiftstate(void);
 typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value,
                            char up_flag);
 static k_handler_fn K_HANDLERS;
-static k_handler_fn *k_handler[16] = { K_HANDLERS };
+k_handler_fn *k_handler[16] = { K_HANDLERS };
+EXPORT_SYMBOL_GPL(k_handler);
 
 #define FN_HANDLERS\
        fn_null,        fn_enter,       fn_show_ptregs, fn_show_mem,\
@@ -127,7 +129,7 @@ int shift_state = 0;
  */
 
 static struct input_handler kbd_handler;
-static unsigned long key_down[NBITS(KEY_MAX)];         /* keyboard key bitmap */
+static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */
 static unsigned char shift_down[NR_SHIFT];             /* shift state counters.. */
 static int dead_key_next;
 static int npadch = -1;                                        /* -1 or number assembled on pad */
@@ -159,6 +161,23 @@ static int sysrq_alt_use;
 #endif
 static int sysrq_alt;
 
+/*
+ * Notifier list for console keyboard events
+ */
+static ATOMIC_NOTIFIER_HEAD(keyboard_notifier_list);
+
+int register_keyboard_notifier(struct notifier_block *nb)
+{
+       return atomic_notifier_chain_register(&keyboard_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(register_keyboard_notifier);
+
+int unregister_keyboard_notifier(struct notifier_block *nb)
+{
+       return atomic_notifier_chain_unregister(&keyboard_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(unregister_keyboard_notifier);
+
 /*
  * Translation of scancodes to keycodes. We set them on only the first
  * keyboard in the list that accepts the scancode and keycode.
@@ -1130,6 +1149,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
        unsigned char type, raw_mode;
        struct tty_struct *tty;
        int shift_final;
+       struct keyboard_notifier_param param = { .vc = vc, .value = keycode, .down = down };
 
        tty = vc->vc_tty;
 
@@ -1217,10 +1237,11 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
                return;
        }
 
-       shift_final = (shift_state | kbd->slockstate) ^ kbd->lockstate;
+       param.shift = shift_final = (shift_state | kbd->slockstate) ^ kbd->lockstate;
        key_map = key_maps[shift_final];
 
-       if (!key_map) {
+       if (atomic_notifier_call_chain(&keyboard_notifier_list, KBD_KEYCODE, &param) == NOTIFY_STOP || !key_map) {
+               atomic_notifier_call_chain(&keyboard_notifier_list, KBD_UNBOUND_KEYCODE, &param);
                compute_shiftstate();
                kbd->slockstate = 0;
                return;
@@ -1237,6 +1258,9 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
        type = KTYP(keysym);
 
        if (type < 0xf0) {
+               param.value = keysym;
+               if (atomic_notifier_call_chain(&keyboard_notifier_list, KBD_UNICODE, &param) == NOTIFY_STOP)
+                       return;
                if (down && !raw_mode)
                        to_utf8(vc, keysym);
                return;
@@ -1244,9 +1268,6 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
 
        type -= 0xf0;
 
-       if (raw_mode && type != KT_SPEC && type != KT_SHIFT)
-               return;
-
        if (type == KT_LETTER) {
                type = KT_LATIN;
                if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
@@ -1255,9 +1276,18 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
                                keysym = key_map[keycode];
                }
        }
+       param.value = keysym;
+
+       if (atomic_notifier_call_chain(&keyboard_notifier_list, KBD_KEYSYM, &param) == NOTIFY_STOP)
+               return;
+
+       if (raw_mode && type != KT_SPEC && type != KT_SHIFT)
+               return;
 
        (*k_handler[type])(vc, keysym & 0xff, !down);
 
+       atomic_notifier_call_chain(&keyboard_notifier_list, KBD_POST_KEYSYM, &param);
+
        if (type != KT_SLOCK)
                kbd->slockstate = 0;
 }
@@ -1347,12 +1377,12 @@ static void kbd_start(struct input_handle *handle)
 static const struct input_device_id kbd_ids[] = {
        {
                 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
-                .evbit = { BIT(EV_KEY) },
+                .evbit = { BIT_MASK(EV_KEY) },
         },
 
        {
                 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
-                .evbit = { BIT(EV_SND) },
+                .evbit = { BIT_MASK(EV_SND) },
         },
 
        { },    /* Terminating entry */
index ed76f0a127fd759c1679a908681c25fcdfc15064..2fc255a21486321acc7c70fb40c40e814bf10918 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
+#include <linux/completion.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -142,7 +143,7 @@ struct moxa_port {
        struct tty_struct *tty;
        int cflag;
        wait_queue_head_t open_wait;
-       wait_queue_head_t close_wait;
+       struct completion close_wait;
 
        struct timer_list emptyTimer;
 
@@ -166,7 +167,6 @@ struct moxa_port {
 
 #define WAKEUP_CHARS           256
 
-static int verbose = 0;
 static int ttymajor = MOXAMAJOR;
 /* Variables for insmod */
 #ifdef MODULE
@@ -184,7 +184,6 @@ module_param_array(baseaddr, int, NULL, 0);
 module_param_array(numports, int, NULL, 0);
 #endif
 module_param(ttymajor, int, 0);
-module_param(verbose, bool, 0644);
 
 /*
  * static functions:
@@ -208,13 +207,13 @@ static int moxa_tiocmget(struct tty_struct *tty, struct file *file);
 static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
                         unsigned int set, unsigned int clear);
 static void moxa_poll(unsigned long);
-static void set_tty_param(struct tty_struct *);
-static int block_till_ready(struct tty_struct *, struct file *,
+static void moxa_set_tty_param(struct tty_struct *);
+static int moxa_block_till_ready(struct tty_struct *, struct file *,
                            struct moxa_port *);
-static void setup_empty_event(struct tty_struct *);
-static void check_xmit_empty(unsigned long);
-static void shut_down(struct moxa_port *);
-static void receive_data(struct moxa_port *);
+static void moxa_setup_empty_event(struct tty_struct *);
+static void moxa_check_xmit_empty(unsigned long);
+static void moxa_shut_down(struct moxa_port *);
+static void moxa_receive_data(struct moxa_port *);
 /*
  * moxa board interface functions:
  */
@@ -283,8 +282,10 @@ static int __devinit moxa_pci_probe(struct pci_dev *pdev,
        int retval;
 
        retval = pci_enable_device(pdev);
-       if (retval)
+       if (retval) {
+               dev_err(&pdev->dev, "can't enable pci device\n");
                goto err;
+       }
 
        for (i = 0; i < MAX_BOARDS; i++)
                if (moxa_boards[i].basemem == NULL)
@@ -292,16 +293,17 @@ static int __devinit moxa_pci_probe(struct pci_dev *pdev,
 
        retval = -ENODEV;
        if (i >= MAX_BOARDS) {
-               if (verbose)
-                       printk("More than %d MOXA Intellio family boards "
+               dev_warn(&pdev->dev, "more than %u MOXA Intellio family boards "
                                "found. Board is ignored.\n", MAX_BOARDS);
                goto err;
        }
 
        board = &moxa_boards[i];
        board->basemem = pci_iomap(pdev, 2, 0x4000);
-       if (board->basemem == NULL)
+       if (board->basemem == NULL) {
+               dev_err(&pdev->dev, "can't remap io space 2\n");
                goto err;
+       }
 
        board->boardType = board_type;
        switch (board_type) {
@@ -347,7 +349,8 @@ static int __init moxa_init(void)
        int i, numBoards, retval = 0;
        struct moxa_port *ch;
 
-       printk(KERN_INFO "MOXA Intellio family driver version %s\n", MOXA_VERSION);
+       printk(KERN_INFO "MOXA Intellio family driver version %s\n",
+                       MOXA_VERSION);
        moxaDriver = alloc_tty_driver(MAX_PORTS + 1);
        if (!moxaDriver)
                return -ENOMEM;
@@ -372,13 +375,13 @@ static int __init moxa_init(void)
                ch->closing_wait = 30 * HZ;
                ch->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
                init_waitqueue_head(&ch->open_wait);
-               init_waitqueue_head(&ch->close_wait);
+               init_completion(&ch->close_wait);
 
-               setup_timer(&ch->emptyTimer, check_xmit_empty,
+               setup_timer(&ch->emptyTimer, moxa_check_xmit_empty,
                                (unsigned long)ch);
        }
 
-       printk("Tty devices major number = %d\n", ttymajor);
+       pr_debug("Moxa tty devices major number = %d\n", ttymajor);
 
        if (tty_register_driver(moxaDriver)) {
                printk(KERN_ERR "Couldn't install MOXA Smartio family driver !\n");
@@ -400,11 +403,10 @@ static int __init moxa_init(void)
                                moxa_boards[numBoards].numPorts = moxa_isa_boards[i].numPorts;
                        moxa_boards[numBoards].busType = MOXA_BUS_TYPE_ISA;
                        moxa_boards[numBoards].baseAddr = moxa_isa_boards[i].baseAddr;
-                       if (verbose)
-                               printk("Board %2d: %s board(baseAddr=%lx)\n",
-                                      numBoards + 1,
-                                      moxa_brdname[moxa_boards[numBoards].boardType - 1],
-                                      moxa_boards[numBoards].baseAddr);
+                       pr_debug("Moxa board %2d: %s board(baseAddr=%lx)\n",
+                              numBoards + 1,
+                              moxa_brdname[moxa_boards[numBoards].boardType-1],
+                              moxa_boards[numBoards].baseAddr);
                        numBoards++;
                }
        }
@@ -413,14 +415,13 @@ static int __init moxa_init(void)
        for (i = 0; i < MAX_BOARDS; i++) {
                if ((type[i] == MOXA_BOARD_C218_ISA) ||
                    (type[i] == MOXA_BOARD_C320_ISA)) {
-                       if (verbose)
-                               printk("Board %2d: %s board(baseAddr=%lx)\n",
-                                      numBoards + 1,
-                                      moxa_brdname[type[i] - 1],
-                                      (unsigned long) baseaddr[i]);
+                       pr_debug("Moxa board %2d: %s board(baseAddr=%lx)\n",
+                              numBoards + 1, moxa_brdname[type[i] - 1],
+                              (unsigned long)baseaddr[i]);
                        if (numBoards >= MAX_BOARDS) {
-                               if (verbose)
-                                       printk("More than %d MOXA Intellio family boards found. Board is ignored.", MAX_BOARDS);
+                               printk(KERN_WARNING "More than %d MOXA "
+                                       "Intellio family boards found. Board "
+                                       "is ignored.\n", MAX_BOARDS);
                                continue;
                        }
                        moxa_boards[numBoards].boardType = type[i];
@@ -456,16 +457,14 @@ static void __exit moxa_exit(void)
 {
        int i;
 
-       if (verbose)
-               printk("Unloading module moxa ...\n");
-
        del_timer_sync(&moxaTimer);
 
        for (i = 0; i < MAX_PORTS; i++)
                del_timer_sync(&moxa_ports[i].emptyTimer);
 
        if (tty_unregister_driver(moxaDriver))
-               printk("Couldn't unregister MOXA Intellio family serial driver\n");
+               printk(KERN_ERR "Couldn't unregister MOXA Intellio family "
+                               "serial driver\n");
        put_tty_driver(moxaDriver);
 
 #ifdef CONFIG_PCI
@@ -475,9 +474,6 @@ static void __exit moxa_exit(void)
        for (i = 0; i < MAX_BOARDS; i++)
                if (moxa_boards[i].basemem)
                        iounmap(moxa_boards[i].basemem);
-
-       if (verbose)
-               printk("Done\n");
 }
 
 module_init(moxa_init);
@@ -504,12 +500,12 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
        ch->tty = tty;
        if (!(ch->asyncflags & ASYNC_INITIALIZED)) {
                ch->statusflags = 0;
-               set_tty_param(tty);
+               moxa_set_tty_param(tty);
                MoxaPortLineCtrl(ch->port, 1, 1);
                MoxaPortEnable(ch->port);
                ch->asyncflags |= ASYNC_INITIALIZED;
        }
-       retval = block_till_ready(tty, filp, ch);
+       retval = moxa_block_till_ready(tty, filp, ch);
 
        moxa_unthrottle(tty);
 
@@ -532,9 +528,7 @@ static void moxa_close(struct tty_struct *tty, struct file *filp)
                return;
        }
        if (!MoxaPortIsValid(port)) {
-#ifdef SERIAL_DEBUG_CLOSE
-               printk("Invalid portno in moxa_close\n");
-#endif
+               pr_debug("Invalid portno in moxa_close\n");
                tty->driver_data = NULL;
                return;
        }
@@ -547,13 +541,13 @@ static void moxa_close(struct tty_struct *tty, struct file *filp)
        ch = (struct moxa_port *) tty->driver_data;
 
        if ((tty->count == 1) && (ch->count != 1)) {
-               printk("moxa_close: bad serial port count; tty->count is 1, "
-                      "ch->count is %d\n", ch->count);
+               printk(KERN_WARNING "moxa_close: bad serial port count; "
+                       "tty->count is 1, ch->count is %d\n", ch->count);
                ch->count = 1;
        }
        if (--ch->count < 0) {
-               printk("moxa_close: bad serial port count, device=%s\n",
-                      tty->name);
+               printk(KERN_WARNING "moxa_close: bad serial port count, "
+                       "device=%s\n", tty->name);
                ch->count = 0;
        }
        if (ch->count) {
@@ -563,11 +557,11 @@ static void moxa_close(struct tty_struct *tty, struct file *filp)
 
        ch->cflag = tty->termios->c_cflag;
        if (ch->asyncflags & ASYNC_INITIALIZED) {
-               setup_empty_event(tty);
+               moxa_setup_empty_event(tty);
                tty_wait_until_sent(tty, 30 * HZ);      /* 30 seconds timeout */
                del_timer_sync(&moxa_ports[ch->port].emptyTimer);
        }
-       shut_down(ch);
+       moxa_shut_down(ch);
        MoxaPortFlushData(port, 2);
 
        if (tty->driver->flush_buffer)
@@ -584,7 +578,7 @@ static void moxa_close(struct tty_struct *tty, struct file *filp)
                wake_up_interruptible(&ch->open_wait);
        }
        ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
-       wake_up_interruptible(&ch->close_wait);
+       complete_all(&ch->close_wait);
 }
 
 static int moxa_write(struct tty_struct *tty,
@@ -653,7 +647,7 @@ static int moxa_chars_in_buffer(struct tty_struct *tty)
                 * in tty_ioctl.c, etc.
                 */
                if (!(ch->statusflags & EMPTYWAIT))
-                       setup_empty_event(tty);
+                       moxa_setup_empty_event(tty);
        }
        return (chars);
 }
@@ -751,7 +745,7 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
                retval = tty_check_change(tty);
                if (retval)
                        return (retval);
-               setup_empty_event(tty);
+               moxa_setup_empty_event(tty);
                tty_wait_until_sent(tty, 0);
                if (!arg)
                        MoxaPortSendBreak(ch->port, 0);
@@ -760,7 +754,7 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
                retval = tty_check_change(tty);
                if (retval)
                        return (retval);
-               setup_empty_event(tty);
+               moxa_setup_empty_event(tty);
                tty_wait_until_sent(tty, 0);
                MoxaPortSendBreak(ch->port, arg);
                return (0);
@@ -809,7 +803,7 @@ static void moxa_set_termios(struct tty_struct *tty,
 
        if (ch == NULL)
                return;
-       set_tty_param(tty);
+       moxa_set_tty_param(tty);
        if (!(old_termios->c_cflag & CLOCAL) &&
            (tty->termios->c_cflag & CLOCAL))
                wake_up_interruptible(&ch->open_wait);
@@ -845,7 +839,7 @@ static void moxa_hangup(struct tty_struct *tty)
        struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
 
        moxa_flush_buffer(tty);
-       shut_down(ch);
+       moxa_shut_down(ch);
        ch->event = 0;
        ch->count = 0;
        ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
@@ -875,7 +869,7 @@ static void moxa_poll(unsigned long ignored)
                                continue;
                        if (!(ch->statusflags & THROTTLE) &&
                            (MoxaPortRxQueue(ch->port) > 0))
-                               receive_data(ch);
+                               moxa_receive_data(ch);
                        if ((tp = ch->tty) == 0)
                                continue;
                        if (ch->statusflags & LOWWAIT) {
@@ -909,7 +903,7 @@ static void moxa_poll(unsigned long ignored)
 
 /******************************************************************************/
 
-static void set_tty_param(struct tty_struct *tty)
+static void moxa_set_tty_param(struct tty_struct *tty)
 {
        register struct ktermios *ts;
        struct moxa_port *ch;
@@ -934,7 +928,7 @@ static void set_tty_param(struct tty_struct *tty)
        MoxaPortSetTermio(ch->port, ts, tty_get_baud_rate(tty));
 }
 
-static int block_till_ready(struct tty_struct *tty, struct file *filp,
+static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
                            struct moxa_port *ch)
 {
        DECLARE_WAITQUEUE(wait,current);
@@ -948,7 +942,7 @@ static int block_till_ready(struct tty_struct *tty, struct file *filp,
         */
        if (tty_hung_up_p(filp) || (ch->asyncflags & ASYNC_CLOSING)) {
                if (ch->asyncflags & ASYNC_CLOSING)
-                       interruptible_sleep_on(&ch->close_wait);
+                       wait_for_completion_interruptible(&ch->close_wait);
 #ifdef SERIAL_DO_RESTART
                if (ch->asyncflags & ASYNC_HUP_NOTIFY)
                        return (-EAGAIN);
@@ -971,10 +965,8 @@ static int block_till_ready(struct tty_struct *tty, struct file *filp,
         */
        retval = 0;
        add_wait_queue(&ch->open_wait, &wait);
-#ifdef SERIAL_DEBUG_OPEN
-       printk("block_til_ready before block: ttys%d, count = %d\n",
-              ch->line, ch->count);
-#endif
+       pr_debug("block_til_ready before block: ttys%d, count = %d\n",
+               ch->port, ch->count);
        spin_lock_irqsave(&moxa_lock, flags);
        if (!tty_hung_up_p(filp))
                ch->count--;
@@ -1013,10 +1005,8 @@ static int block_till_ready(struct tty_struct *tty, struct file *filp,
                ch->count++;
        ch->blocked_open--;
        spin_unlock_irqrestore(&moxa_lock, flags);
-#ifdef SERIAL_DEBUG_OPEN
-       printk("block_til_ready after blocking: ttys%d, count = %d\n",
-              ch->line, ch->count);
-#endif
+       pr_debug("block_til_ready after blocking: ttys%d, count = %d\n",
+               ch->port, ch->count);
        if (retval)
                return (retval);
        /* FIXME: review to see if we need to use set_bit on these */
@@ -1024,7 +1014,7 @@ static int block_till_ready(struct tty_struct *tty, struct file *filp,
        return 0;
 }
 
-static void setup_empty_event(struct tty_struct *tty)
+static void moxa_setup_empty_event(struct tty_struct *tty)
 {
        struct moxa_port *ch = tty->driver_data;
        unsigned long flags;
@@ -1035,24 +1025,24 @@ static void setup_empty_event(struct tty_struct *tty)
        spin_unlock_irqrestore(&moxa_lock, flags);
 }
 
-static void check_xmit_empty(unsigned long data)
+static void moxa_check_xmit_empty(unsigned long data)
 {
        struct moxa_port *ch;
 
        ch = (struct moxa_port *) data;
-       del_timer_sync(&moxa_ports[ch->port].emptyTimer);
        if (ch->tty && (ch->statusflags & EMPTYWAIT)) {
                if (MoxaPortTxQueue(ch->port) == 0) {
                        ch->statusflags &= ~EMPTYWAIT;
                        tty_wakeup(ch->tty);
                        return;
                }
-               mod_timer(&moxa_ports[ch->port].emptyTimer, jiffies + HZ);
+               mod_timer(&moxa_ports[ch->port].emptyTimer,
+                               round_jiffies(jiffies + HZ));
        } else
                ch->statusflags &= ~EMPTYWAIT;
 }
 
-static void shut_down(struct moxa_port *ch)
+static void moxa_shut_down(struct moxa_port *ch)
 {
        struct tty_struct *tp;
 
@@ -1072,7 +1062,7 @@ static void shut_down(struct moxa_port *ch)
        ch->asyncflags &= ~ASYNC_INITIALIZED;
 }
 
-static void receive_data(struct moxa_port *ch)
+static void moxa_receive_data(struct moxa_port *ch)
 {
        struct tty_struct *tp;
        struct ktermios *ts;
@@ -1406,8 +1396,8 @@ static struct mon_str moxaLog;
 static int moxaFuncTout = HZ / 2;
 
 static void moxafunc(void __iomem *, int, ushort);
-static void wait_finish(void __iomem *);
-static void low_water_check(void __iomem *);
+static void moxa_wait_finish(void __iomem *);
+static void moxa_low_water_check(void __iomem *);
 static int moxaloadbios(int, unsigned char __user *, int);
 static int moxafindcard(int);
 static int moxaload320b(int, unsigned char __user *, int);
@@ -1473,7 +1463,7 @@ void MoxaPortFlushData(int port, int mode)
        moxafunc(ofsAddr, FC_FlushQueue, mode);
        if (mode != 1) {
                moxa_ports[port].lowChkFlag = 0;
-               low_water_check(ofsAddr);
+               moxa_low_water_check(ofsAddr);
        }
 }
 
@@ -1654,7 +1644,7 @@ int MoxaDriverPoll(void)
                                if (moxa_ports[p].lowChkFlag) {
                                        moxa_ports[p].lowChkFlag = 0;
                                        ofsAddr = moxa_ports[p].tableAddr;
-                                       low_water_check(ofsAddr);
+                                       moxa_low_water_check(ofsAddr);
                                }
                        }
                }
@@ -2081,7 +2071,7 @@ int MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud)
                writeb(termio->c_cc[VSTART], ofsAddr + FuncArg);
                writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1);
                writeb(FC_SetXonXoff, ofsAddr + FuncCode);
-               wait_finish(ofsAddr);
+               moxa_wait_finish(ofsAddr);
 
        }
        return (0);
@@ -2480,10 +2470,10 @@ static void moxafunc(void __iomem *ofsAddr, int cmd, ushort arg)
 
        writew(arg, ofsAddr + FuncArg);
        writew(cmd, ofsAddr + FuncCode);
-       wait_finish(ofsAddr);
+       moxa_wait_finish(ofsAddr);
 }
 
-static void wait_finish(void __iomem *ofsAddr)
+static void moxa_wait_finish(void __iomem *ofsAddr)
 {
        unsigned long i, j;
 
@@ -2496,7 +2486,7 @@ static void wait_finish(void __iomem *ofsAddr)
        }
 }
 
-static void low_water_check(void __iomem *ofsAddr)
+static void moxa_low_water_check(void __iomem *ofsAddr)
 {
        int len;
        ushort rptr, wptr, mask;
index 2aee3fef0416cc6d689b428371761d12504afd01..fd0abef7ee0867dfb86ccc0958e0a1c64402e947 100644 (file)
 #include <linux/mm.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
+#include <linux/bitops.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/bitops.h>
 #include <asm/uaccess.h>
 
 #include "mxser.h"
@@ -383,7 +383,6 @@ static int mxser_init(void);
 
 /* static void   mxser_poll(unsigned long); */
 static int mxser_get_ISA_conf(int, struct mxser_hwconf *);
-static int mxser_get_PCI_conf(int, int, int, struct mxser_hwconf *);
 static void mxser_do_softint(struct work_struct *);
 static int mxser_open(struct tty_struct *, struct file *);
 static void mxser_close(struct tty_struct *, struct file *);
@@ -422,7 +421,7 @@ static void mxser_wait_until_sent(struct tty_struct *tty, int timeout);
 static void mxser_startrx(struct tty_struct *tty);
 static void mxser_stoprx(struct tty_struct *tty);
 
-
+#ifdef CONFIG_PCI
 static int CheckIsMoxaMust(int io)
 {
        u8 oldmcr, hwid;
@@ -445,6 +444,7 @@ static int CheckIsMoxaMust(int io)
        }
        return MOXA_OTHER_UART;
 }
+#endif
 
 /* above is modified by Victor Yu. 08-15-2002 */
 
@@ -1938,14 +1938,6 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id)
                                inb(info->base + UART_MSR);
                                continue;
                        }
-                       /* above add by Victor Yu. 09-13-2002 */
-                       /*
-                          if (info->tty->flip.count < TTY_FLIPBUF_SIZE / 4) {
-                          info->IER |= MOXA_MUST_RECV_ISR;
-                          outb(info->IER, info->base + UART_IER);
-                          }
-                        */
-
 
                        /* mask by Victor Yu. 09-13-2002
                           if ( !info->tty ||
@@ -2599,19 +2591,8 @@ static int mxser_change_speed(struct mxser_struct *info, struct ktermios *old_te
                info->IER |= UART_IER_MSI;
                if ((info->type == PORT_16550A) || (info->IsMoxaMustChipFlag)) {
                        info->MCR |= UART_MCR_AFE;
-                       /* status = mxser_get_msr(info->base, 0, info->port); */
-/*
-       save_flags(flags);
-       cli();
-       status = inb(baseaddr + UART_MSR);
-       restore_flags(flags);
-*/
-                       /* mxser_check_modem_status(info, status); */
                } else {
-                       /* status = mxser_get_msr(info->base, 0, info->port); */
-                       /* MX_LOCK(&info->slock); */
                        status = inb(info->base + UART_MSR);
-                       /* MX_UNLOCK(&info->slock); */
                        if (info->tty->hw_stopped) {
                                if (status & UART_MSR_CTS) {
                                        info->tty->hw_stopped = 0;
index 6a563932ba191f31efbec7e1f4d088dc1ef44fb3..081c84c7b5489ae9b3e80fb2730d8622dc552790 100644 (file)
@@ -2,7 +2,7 @@
  *          mxser.c  -- MOXA Smartio/Industio family multiport serial driver.
  *
  *      Copyright (C) 1999-2006  Moxa Technologies (support@moxa.com.tw).
- *     Copyright (C) 2006       Jiri Slaby <jirislaby@gmail.com>
+ *     Copyright (C) 2006-2007  Jiri Slaby <jirislaby@gmail.com>
  *
  *      This code is loosely based on the 1.8 moxa driver which is based on
  *     Linux serial driver, written by Linus Torvalds, Theodore T'so and
 #include <linux/mm.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
+#include <linux/bitops.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/bitops.h>
 #include <asm/uaccess.h>
 
 #include "mxser_new.h"
 
-#define        MXSER_VERSION   "2.0.1"         /* 1.9.15 */
+#define        MXSER_VERSION   "2.0.2"         /* 1.10 */
 #define        MXSERMAJOR       174
 #define        MXSERCUMAJOR     175
 
 #define UART_MCR_AFE           0x20
 #define UART_LSR_SPECIAL       0x1E
 
+#define PCI_DEVICE_ID_CB108    0x1080
+#define PCI_DEVICE_ID_CB114    0x1142
+#define PCI_DEVICE_ID_CB134I   0x1341
+#define PCI_DEVICE_ID_CP138U   0x1380
+#define PCI_DEVICE_ID_POS104UL 0x1044
+
 
 #define C168_ASIC_ID    1
 #define C104_ASIC_ID    2
@@ -107,71 +113,63 @@ struct mxser_cardinfo {
 };
 
 static const struct mxser_cardinfo mxser_cards[] = {
-       { 8, "C168 series", },                  /* C168-ISA */
-       { 4, "C104 series", },                  /* C104-ISA */
-       { 4, "CI-104J series", },               /* CI104J */
-       { 8, "C168H/PCI series", },             /* C168-PCI */
-       { 4, "C104H/PCI series", },             /* C104-PCI */
-       { 4, "C102 series", MXSER_HAS2 },       /* C102-ISA */
-       { 4, "CI-132 series", MXSER_HAS2 },     /* CI132 */
-       { 4, "CI-134 series", },                /* CI134 */
-       { 2, "CP-132 series", },                /* CP132 */
-       { 4, "CP-114 series", },                /* CP114 */
-       { 4, "CT-114 series", },                /* CT114 */
-       { 2, "CP-102 series", MXSER_HIGHBAUD }, /* CP102 */
-       { 4, "CP-104U series", },               /* CP104U */
-       { 8, "CP-168U series", },               /* CP168U */
-       { 2, "CP-132U series", },               /* CP132U */
-       { 4, "CP-134U series", },               /* CP134U */
-       { 4, "CP-104JU series", },              /* CP104JU */
+/* 0*/ { 8, "C168 series", },
+       { 4, "C104 series", },
+       { 4, "CI-104J series", },
+       { 8, "C168H/PCI series", },
+       { 4, "C104H/PCI series", },
+/* 5*/ { 4, "C102 series", MXSER_HAS2 },       /* C102-ISA */
+       { 4, "CI-132 series", MXSER_HAS2 },
+       { 4, "CI-134 series", },
+       { 2, "CP-132 series", },
+       { 4, "CP-114 series", },
+/*10*/ { 4, "CT-114 series", },
+       { 2, "CP-102 series", MXSER_HIGHBAUD },
+       { 4, "CP-104U series", },
+       { 8, "CP-168U series", },
+       { 2, "CP-132U series", },
+/*15*/ { 4, "CP-134U series", },
+       { 4, "CP-104JU series", },
        { 8, "Moxa UC7000 Serial", },           /* RC7000 */
-       { 8, "CP-118U series", },               /* CP118U */
-       { 2, "CP-102UL series", },              /* CP102UL */
-       { 2, "CP-102U series", },               /* CP102U */
-       { 8, "CP-118EL series", },              /* CP118EL */
-       { 8, "CP-168EL series", },              /* CP168EL */
-       { 4, "CP-104EL series", }               /* CP104EL */
+       { 8, "CP-118U series", },
+       { 2, "CP-102UL series", },
+/*20*/ { 2, "CP-102U series", },
+       { 8, "CP-118EL series", },
+       { 8, "CP-168EL series", },
+       { 4, "CP-104EL series", },
+       { 8, "CB-108 series", },
+/*25*/ { 4, "CB-114 series", },
+       { 4, "CB-134I series", },
+       { 8, "CP-138U series", },
+       { 4, "POS-104UL series", }
 };
 
 /* driver_data correspond to the lines in the structure above
    see also ISA probe function before you change something */
 static struct pci_device_id mxser_pcibrds[] = {
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C168),
-               .driver_data = 3 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C104),
-               .driver_data = 4 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP132),
-               .driver_data = 8 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP114),
-               .driver_data = 9 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CT114),
-               .driver_data = 10 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102),
-               .driver_data = 11 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104U),
-               .driver_data = 12 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP168U),
-               .driver_data = 13 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP132U),
-               .driver_data = 14 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP134U),
-               .driver_data = 15 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104JU),
-               .driver_data = 16 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_RC7000),
-               .driver_data = 17 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP118U),
-               .driver_data = 18 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102UL),
-               .driver_data = 19 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102U),
-               .driver_data = 20 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP118EL),
-               .driver_data = 21 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP168EL),
-               .driver_data = 22 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104EL),
-               .driver_data = 23 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C168),   .driver_data = 3 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C104),   .driver_data = 4 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132),  .driver_data = 8 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP114),  .driver_data = 9 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CT114),  .driver_data = 10 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102),  .driver_data = 11 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104U), .driver_data = 12 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP168U), .driver_data = 13 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132U), .driver_data = 14 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP134U), .driver_data = 15 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104JU),.driver_data = 16 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_RC7000), .driver_data = 17 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118U), .driver_data = 18 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102UL),.driver_data = 19 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102U), .driver_data = 20 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118EL),.driver_data = 21 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP168EL),.driver_data = 22 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104EL),.driver_data = 23 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB108),       .driver_data = 24 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB114),       .driver_data = 25 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB134I),      .driver_data = 26 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP138U),      .driver_data = 27 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_POS104UL),    .driver_data = 28 },
        { }
 };
 MODULE_DEVICE_TABLE(pci, mxser_pcibrds);
index 038056911934c3b60a10a70553702ff33cb070b6..596c7173997b577d1216d479604435053da4f92f 100644 (file)
@@ -437,7 +437,7 @@ static inline void finish_erasing(struct tty_struct *tty)
  *     @c: character input
  *     @tty: terminal device
  *
- *     Perform erase and neccessary output when an erase character is
+ *     Perform erase and necessary output when an erase character is
  *     present in the stream from the driver layer. Handles the complexities
  *     of UTF-8 multibyte symbols.
  */
@@ -657,7 +657,7 @@ static inline void n_tty_receive_overrun(struct tty_struct *tty)
  *     @c: character
  *
  *     Process a parity error and queue the right data to indicate
- *     the error case if neccessary. Locking as per n_tty_receive_buf.
+ *     the error case if necessary. Locking as per n_tty_receive_buf.
  */
 static inline void n_tty_receive_parity_error(struct tty_struct *tty,
                                              unsigned char c)
index 73de77105fea9c9a58c8ed704fab7626b2bfb2d1..706ff34728f19382be4215e25e3052bd2b1ba371 100644 (file)
@@ -318,7 +318,7 @@ int pty_limit = NR_UNIX98_PTY_DEFAULT;
 static int pty_limit_min = 0;
 static int pty_limit_max = NR_UNIX98_PTY_MAX;
 
-ctl_table pty_table[] = {
+static struct ctl_table pty_table[] = {
        {
                .ctl_name       = PTY_MAX,
                .procname       = "max",
@@ -340,6 +340,27 @@ ctl_table pty_table[] = {
        }
 };
 
+static struct ctl_table pty_kern_table[] = {
+       {
+               .ctl_name       = KERN_PTY,
+               .procname       = "pty",
+               .mode           = 0555,
+               .child          = pty_table,
+       },
+       {}
+};
+
+static struct ctl_table pty_root_table[] = {
+       {
+               .ctl_name       = CTL_KERN,
+               .procname       = "kernel",
+               .mode           = 0555,
+               .child          = pty_kern_table,
+       },
+       {}
+};
+
+
 static int pty_unix98_ioctl(struct tty_struct *tty, struct file *file,
                            unsigned int cmd, unsigned long arg)
 {
@@ -404,6 +425,7 @@ static void __init unix98_pty_init(void)
                panic("Couldn't register Unix98 pts driver");
 
        pty_table[1].data = &ptm_driver->refcount;
+       register_sysctl_table(pty_root_table);
 }
 #else
 static inline void unix98_pty_init(void) { }
index af274e5a25ee5ec57533eff3a4e869feac831924..1756b1f7cb7252b8a596ff25767c1d9155fab5f4 100644 (file)
@@ -649,7 +649,7 @@ EXPORT_SYMBOL_GPL(add_input_randomness);
 
 void add_interrupt_randomness(int irq)
 {
-       if (irq >= NR_IRQS || irq_timer_state[irq] == 0)
+       if (irq >= NR_IRQS || irq_timer_state[irq] == NULL)
                return;
 
        DEBUG_ENT("irq event %d\n", irq);
index 56cbba7b6ec098a7cbc1e770098e348ad3e736b1..d83419c3857e92baa4d28a8a53806b4b465484a4 100644 (file)
@@ -84,6 +84,7 @@
 #include <linux/mutex.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
+#include <linux/completion.h>
 #include <linux/wait.h>
 #include <linux/pci.h>
 #include <asm/uaccess.h>
@@ -548,8 +549,8 @@ static void rp_handle_port(struct r_port *info)
 static void rp_do_poll(unsigned long dummy)
 {
        CONTROLLER_t *ctlp;
-       int ctrl, aiop, ch, line, i;
-       unsigned int xmitmask;
+       int ctrl, aiop, ch, line;
+       unsigned int xmitmask, i;
        unsigned int CtlMask;
        unsigned char AiopMask;
        Word_t bit;
@@ -562,7 +563,7 @@ static void rp_do_poll(unsigned long dummy)
                /*  Get a ptr to the board's control struct */
                ctlp = sCtlNumToCtlPtr(ctrl);
 
-               /*  Get the interupt status from the board */
+               /*  Get the interrupt status from the board */
 #ifdef CONFIG_PCI
                if (ctlp->BusType == isPCI)
                        CtlMask = sPCIGetControllerIntStatus(ctlp);
@@ -650,7 +651,7 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
        info->closing_wait = 3000;
        info->close_delay = 50;
        init_waitqueue_head(&info->open_wait);
-       init_waitqueue_head(&info->close_wait);
+       init_completion(&info->close_wait);
        info->flags &= ~ROCKET_MODE_MASK;
        switch (pc104[board][line]) {
        case 422:
@@ -699,8 +700,8 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
        spin_lock_init(&info->slock);
        mutex_init(&info->write_mtx);
        rp_table[line] = info;
-       if (pci_dev)
-               tty_register_device(rocket_driver, line, &pci_dev->dev);
+       tty_register_device(rocket_driver, line, pci_dev ? &pci_dev->dev :
+                       NULL);
 }
 
 /*
@@ -878,7 +879,8 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
        if (tty_hung_up_p(filp))
                return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
        if (info->flags & ROCKET_CLOSING) {
-               interruptible_sleep_on(&info->close_wait);
+               if (wait_for_completion_interruptible(&info->close_wait))
+                       return -ERESTARTSYS;
                return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
        }
 
@@ -983,8 +985,10 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
                return -ENOMEM;
 
        if (info->flags & ROCKET_CLOSING) {
-               interruptible_sleep_on(&info->close_wait);
+               retval = wait_for_completion_interruptible(&info->close_wait);
                free_page(page);
+               if (retval)
+                       return retval;
                return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
        }
 
@@ -1176,7 +1180,7 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
        }
        info->flags &= ~(ROCKET_INITIALIZED | ROCKET_CLOSING | ROCKET_NORMAL_ACTIVE);
        tty->closing = 0;
-       wake_up_interruptible(&info->close_wait);
+       complete_all(&info->close_wait);
        atomic_dec(&rp_num_ports_open);
 
 #ifdef ROCKET_DEBUG_OPEN
@@ -1869,8 +1873,6 @@ static __init int register_PCI(int i, struct pci_dev *dev)
        int fast_clock = 0;
        int altChanRingIndicator = 0;
        int ports_per_aiop = 8;
-       int ret;
-       unsigned int class_rev;
        WordIO_t ConfigIO = 0;
        ByteIO_t UPCIRingInd = 0;
 
@@ -1878,12 +1880,6 @@ static __init int register_PCI(int i, struct pci_dev *dev)
                return 0;
 
        rcktpt_io_addr[i] = pci_resource_start(dev, 0);
-       ret = pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
-
-       if (ret) {
-               printk(KERN_INFO "  Error during register_PCI(), unable to read config dword \n");
-               return 0;
-       }
 
        rcktpt_type[i] = ROCKET_TYPE_NORMAL;
        rocketModel[i].loadrm2 = 0;
@@ -2037,8 +2033,9 @@ static __init int register_PCI(int i, struct pci_dev *dev)
                ports_per_aiop = 6;
                str = "6-port";
 
-               /*  If class_rev is 1, the rocketmodem flash must be loaded.  If it is 2 it is a "socketed" version. */
-               if ((class_rev & 0xFF) == 1) {
+               /*  If revision is 1, the rocketmodem flash must be loaded.
+                *  If it is 2 it is a "socketed" version. */
+               if (dev->revision == 1) {
                        rcktpt_type[i] = ROCKET_TYPE_MODEMII;
                        rocketModel[i].loadrm2 = 1;
                } else {
@@ -2053,7 +2050,7 @@ static __init int register_PCI(int i, struct pci_dev *dev)
                max_num_aiops = 1;
                ports_per_aiop = 4;
                str = "4-port";
-               if ((class_rev & 0xFF) == 1) {
+               if (dev->revision == 1) {
                        rcktpt_type[i] = ROCKET_TYPE_MODEMII;
                        rocketModel[i].loadrm2 = 1;
                } else {
@@ -2362,26 +2359,14 @@ static const struct tty_operations rocket_ops = {
  */
 static int __init rp_init(void)
 {
-       int retval, pci_boards_found, isa_boards_found, i;
+       int ret = -ENOMEM, pci_boards_found, isa_boards_found, i;
 
        printk(KERN_INFO "RocketPort device driver module, version %s, %s\n",
               ROCKET_VERSION, ROCKET_DATE);
 
        rocket_driver = alloc_tty_driver(MAX_RP_PORTS);
        if (!rocket_driver)
-               return -ENOMEM;
-
-       /*
-        * Initialize the array of pointers to our own internal state
-        * structures.
-        */
-       memset(rp_table, 0, sizeof (rp_table));
-       memset(xmit_flags, 0, sizeof (xmit_flags));
-
-       for (i = 0; i < MAX_RP_PORTS; i++)
-               lineNumbers[i] = 0;
-       nextLineNumber = 0;
-       memset(rocketModel, 0, sizeof (rocketModel));
+               goto err;
 
        /*
         *  If board 1 is non-zero, there is at least one ISA configured.  If controller is 
@@ -2396,8 +2381,11 @@ static int __init rp_init(void)
 
        /*  If an ISA card is configured, reserve the 4 byte IO space for the Mudbac controller */
        if (controller && (!request_region(controller, 4, "Comtrol RocketPort"))) {
-               printk(KERN_INFO "Unable to reserve IO region for first configured ISA RocketPort controller 0x%lx.  Driver exiting \n", controller);
-               return -EBUSY;
+               printk(KERN_ERR "Unable to reserve IO region for first "
+                       "configured ISA RocketPort controller 0x%lx.  "
+                       "Driver exiting\n", controller);
+               ret = -EBUSY;
+               goto err_tty;
        }
 
        /*  Store ISA variable retrieved from command line or .conf file. */
@@ -2434,15 +2422,14 @@ static int __init rp_init(void)
        rocket_driver->init_termios.c_ispeed = 9600;
        rocket_driver->init_termios.c_ospeed = 9600;
 #ifdef ROCKET_SOFT_FLOW
-       rocket_driver->flags |= TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
+       rocket_driver->flags |= TTY_DRIVER_REAL_RAW;
 #endif
        tty_set_operations(rocket_driver, &rocket_ops);
 
-       retval = tty_register_driver(rocket_driver);
-       if (retval < 0) {
-               printk(KERN_INFO "Couldn't install tty RocketPort driver (error %d)\n", -retval);
-               put_tty_driver(rocket_driver);
-               return -1;
+       ret = tty_register_driver(rocket_driver);
+       if (ret < 0) {
+               printk(KERN_ERR "Couldn't install tty RocketPort driver\n");
+               goto err_tty;
        }
 
 #ifdef ROCKET_DEBUG_OPEN
@@ -2469,14 +2456,18 @@ static int __init rp_init(void)
        max_board = pci_boards_found + isa_boards_found;
 
        if (max_board == 0) {
-               printk(KERN_INFO "No rocketport ports found; unloading driver.\n");
-               del_timer_sync(&rocket_timer);
-               tty_unregister_driver(rocket_driver);
-               put_tty_driver(rocket_driver);
-               return -ENXIO;
+               printk(KERN_ERR "No rocketport ports found; unloading driver\n");
+               ret = -ENXIO;
+               goto err_ttyu;
        }
 
        return 0;
+err_ttyu:
+       tty_unregister_driver(rocket_driver);
+err_tty:
+       put_tty_driver(rocket_driver);
+err:
+       return ret;
 }
 
 
@@ -2491,10 +2482,14 @@ static void rp_cleanup_module(void)
        if (retval)
                printk(KERN_INFO "Error %d while trying to unregister "
                       "rocketport driver\n", -retval);
-       put_tty_driver(rocket_driver);
 
        for (i = 0; i < MAX_RP_PORTS; i++)
-               kfree(rp_table[i]);
+               if (rp_table[i]) {
+                       tty_unregister_device(rocket_driver, i);
+                       kfree(rp_table[i]);
+               }
+
+       put_tty_driver(rocket_driver);
 
        for (i = 0; i < NUM_BOARDS; i++) {
                if (rcktpt_io_addr[i] <= 0 || is_PCI[i])
index b4c53dfa7951290f48be4b5e28e685d91a0b8558..55b8f2d71a9617d3be3c3d932b34002636d52afe 100644 (file)
@@ -1163,13 +1163,8 @@ struct r_port {
        int read_status_mask;
        int cps;
 
-#ifdef DECLARE_WAITQUEUE
        wait_queue_head_t open_wait;
-       wait_queue_head_t close_wait;
-#else
-       struct wait_queue *open_wait;
-       struct wait_queue *close_wait;
-#endif
+       struct completion close_wait;
        spinlock_t slock;
        struct mutex write_mtx;
 };
index 859858561ab6705e5f398117dc5e83e8866df77c..877e53dcb9968a2215816b10c4351fb5e2ba4224 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Copyright (C) 2005 Narayanan R S <nars@kadamba.org>
  *
- * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
+ * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
  *
  * Copyright (C) 2001 Michael Ashley <m.ashley@unsw.edu.au>
  *
@@ -1178,9 +1178,9 @@ static int __devinit sonypi_create_input_devices(void)
        jog_dev->id.bustype = BUS_ISA;
        jog_dev->id.vendor = PCI_VENDOR_ID_SONY;
 
-       jog_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-       jog_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_MIDDLE);
-       jog_dev->relbit[0] = BIT(REL_WHEEL);
+       jog_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+       jog_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_MIDDLE);
+       jog_dev->relbit[0] = BIT_MASK(REL_WHEEL);
 
        sonypi_device.input_key_dev = key_dev = input_allocate_device();
        if (!key_dev) {
@@ -1193,7 +1193,7 @@ static int __devinit sonypi_create_input_devices(void)
        key_dev->id.vendor = PCI_VENDOR_ID_SONY;
 
        /* Initialize the Input Drivers: special keys */
-       key_dev->evbit[0] = BIT(EV_KEY);
+       key_dev->evbit[0] = BIT_MASK(EV_KEY);
        for (i = 0; sonypi_inputkeys[i].sonypiev; i++)
                if (sonypi_inputkeys[i].inputev)
                        set_bit(sonypi_inputkeys[i].inputev, key_dev->keybit);
index 85a23283dff55144b594ae86b6a87100814fdf66..a6e1c9ba12174d769e1389d5329b70676e5e3b16 100644 (file)
@@ -1467,7 +1467,7 @@ static int sx_open(struct tty_struct *tty, struct file *filp)
 
        line = tty->index;
        sx_dprintk(SX_DEBUG_OPEN, "%d: opening line %d. tty=%p ctty=%p, "
-                       "np=%d)\n", current->pid, line, tty,
+                       "np=%d)\n", task_pid_nr(current), line, tty,
                        current->signal->tty, sx_nports);
 
        if ((line < 0) || (line >= SX_NPORTS) || (line >= sx_nports))
index 78d14935f2b8c4b1dbb4678f0d918858c6a15832..de60e1ea4fb3830e01524b73381738d7e98485b6 100644 (file)
@@ -251,7 +251,7 @@ static void send_sig_all(int sig)
        struct task_struct *p;
 
        for_each_process(p) {
-               if (p->mm && !is_init(p))
+               if (p->mm && !is_global_init(p))
                        /* Not swapper, init nor kernel thread */
                        force_sig(sig, p);
        }
index 9c867cf6de6456293314eb1675e697c87a9f64d2..f36fecd3fd264a67cf7d66b2fd8e74369a38f406 100644 (file)
 #include <linux/selection.h>
 
 #include <linux/kmod.h>
+#include <linux/nsproxy.h>
 
 #undef TTY_DEBUG_HANGUP
 
@@ -942,7 +943,7 @@ EXPORT_SYMBOL_GPL(tty_ldisc_deref);
  *     @tty: terminal to activate ldisc on
  *
  *     Set the TTY_LDISC flag when the line discipline can be called
- *     again. Do neccessary wakeups for existing sleepers.
+ *     again. Do necessary wakeups for existing sleepers.
  *
  *     Note: nobody should set this bit except via this function. Clearing
  *     directly is allowed.
@@ -1503,7 +1504,7 @@ EXPORT_SYMBOL(tty_hangup);
  *
  *     The user has asked via system call for the terminal to be hung up.
  *     We do this synchronously so that when the syscall returns the process
- *     is complete. That guarantee is neccessary for security reasons.
+ *     is complete. That guarantee is necessary for security reasons.
  */
 
 void tty_vhangup(struct tty_struct * tty)
@@ -1690,7 +1691,7 @@ EXPORT_SYMBOL(stop_tty);
  *     @tty: tty to start
  *
  *     Start a tty that has been stopped if at all possible. Perform
- *     any neccessary wakeups and propagate the TIOCPKT status. If this
+ *     any necessary wakeups and propagate the TIOCPKT status. If this
  *     is the tty was previous stopped and is being started then the
  *     driver start method is invoked and the line discipline woken.
  *
@@ -2876,7 +2877,7 @@ static int tty_fasync(int fd, struct file * filp, int on)
  *     @tty: tty to fake input into
  *     @p: pointer to character
  *
- *     Fake input to a tty device. Does the neccessary locking and
+ *     Fake input to a tty device. Does the necessary locking and
  *     input management.
  *
  *     FIXME: does not honour flow control ??
@@ -3107,7 +3108,7 @@ static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
         */
        if (tty == real_tty && current->signal->tty != real_tty)
                return -ENOTTY;
-       return put_user(pid_nr(real_tty->pgrp), p);
+       return put_user(pid_vnr(real_tty->pgrp), p);
 }
 
 /**
@@ -3141,7 +3142,7 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
        if (pgrp_nr < 0)
                return -EINVAL;
        rcu_read_lock();
-       pgrp = find_pid(pgrp_nr);
+       pgrp = find_vpid(pgrp_nr);
        retval = -ESRCH;
        if (!pgrp)
                goto out_unlock;
@@ -3178,7 +3179,7 @@ static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t _
                return -ENOTTY;
        if (!real_tty->session)
                return -ENOTTY;
-       return put_user(pid_nr(real_tty->session), p);
+       return put_user(pid_vnr(real_tty->session), p);
 }
 
 /**
@@ -3528,8 +3529,8 @@ void __do_SAK(struct tty_struct *tty)
        /* Kill the entire session */
        do_each_pid_task(session, PIDTYPE_SID, p) {
                printk(KERN_NOTICE "SAK: killed process %d"
-                       " (%s): process_session(p)==tty->session\n",
-                       p->pid, p->comm);
+                       " (%s): task_session_nr(p)==tty->session\n",
+                       task_pid_nr(p), p->comm);
                send_sig(SIGKILL, p, 1);
        } while_each_pid_task(session, PIDTYPE_SID, p);
        /* Now kill any processes that happen to have the
@@ -3538,8 +3539,8 @@ void __do_SAK(struct tty_struct *tty)
        do_each_thread(g, p) {
                if (p->signal->tty == tty) {
                        printk(KERN_NOTICE "SAK: killed process %d"
-                           " (%s): process_session(p)==tty->session\n",
-                           p->pid, p->comm);
+                           " (%s): task_session_nr(p)==tty->session\n",
+                           task_pid_nr(p), p->comm);
                        send_sig(SIGKILL, p, 1);
                        continue;
                }
@@ -3559,7 +3560,7 @@ void __do_SAK(struct tty_struct *tty)
                                    filp->private_data == tty) {
                                        printk(KERN_NOTICE "SAK: killed process %d"
                                            " (%s): fd#%d opened to the tty\n",
-                                           p->pid, p->comm, i);
+                                           task_pid_nr(p), p->comm, i);
                                        force_sig(SIGKILL, p);
                                        break;
                                }
index 745d552620bfc21229d286a8bc40827fd7811d3b..7a003504c265f73ee5f99aaffb140d97d1853991 100644 (file)
@@ -228,7 +228,8 @@ EXPORT_SYMBOL(tty_termios_input_baud_rate);
  *     and will all go away once this is done.
  */
 
-void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, speed_t obaud)
+void tty_termios_encode_baud_rate(struct ktermios *termios,
+                                 speed_t ibaud, speed_t obaud)
 {
        int i = 0;
        int ifound = -1, ofound = -1;
@@ -263,11 +264,15 @@ void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, speed
         */
 
        do {
-               if (obaud - oclose >= baud_table[i] && obaud + oclose <= baud_table[i]) {
+               if (obaud - oclose <= baud_table[i] &&
+                   obaud + oclose >= baud_table[i]) {
                        termios->c_cflag |= baud_bits[i];
                        ofound = i;
                }
-               if (ibaud - iclose >= baud_table[i] && ibaud + iclose <= baud_table[i]) {
+               if (ibaud - iclose <= baud_table[i] &&
+                   ibaud + iclose >= baud_table[i]) {
+                       /* For the case input == output don't set IBAUD bits
+                          if the user didn't do so */
                        if (ofound == i && !ibinput)
                                ifound  = i;
 #ifdef IBSHIFT
@@ -439,7 +444,7 @@ static void change_termios(struct tty_struct * tty, struct ktermios * new_termio
  *     @arg: user data
  *     @opt: option information
  *
- *     Helper function to prepare termios data and run neccessary other
+ *     Helper function to prepare termios data and run necessary other
  *     functions before using change_termios to do the actual changes.
  *
  *     Locking:
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
new file mode 100644 (file)
index 0000000..100e8a2
--- /dev/null
@@ -0,0 +1,225 @@
+/*D:300
+ * The Guest console driver
+ *
+ * Writing console drivers is one of the few remaining Dark Arts in Linux.
+ * Fortunately for us, the path of virtual consoles has been well-trodden by
+ * the PowerPC folks, who wrote "hvc_console.c" to generically support any
+ * virtual console.  We use that infrastructure which only requires us to write
+ * the basic put_chars and get_chars functions and call the right register
+ * functions.
+ :*/
+
+/*M:002 The console can be flooded: while the Guest is processing input the
+ * Host can send more.  Buffering in the Host could alleviate this, but it is a
+ * difficult problem in general. :*/
+/* Copyright (C) 2006, 2007 Rusty Russell, 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/err.h>
+#include <linux/init.h>
+#include <linux/virtio.h>
+#include <linux/virtio_console.h>
+#include "hvc_console.h"
+
+/*D:340 These represent our input and output console queues, and the virtio
+ * operations for them. */
+static struct virtqueue *in_vq, *out_vq;
+static struct virtio_device *vdev;
+
+/* This is our input buffer, and how much data is left in it. */
+static unsigned int in_len;
+static char *in, *inbuf;
+
+/* The operations for our console. */
+static struct hv_ops virtio_cons;
+
+/*D:310 The put_chars() callback is pretty straightforward.
+ *
+ * We turn the characters into a scatter-gather list, add it to the output
+ * queue and then kick the Host.  Then we sit here waiting for it to finish:
+ * inefficient in theory, but in practice implementations will do it
+ * immediately (lguest's Launcher does). */
+static int put_chars(u32 vtermno, const char *buf, int count)
+{
+       struct scatterlist sg[1];
+       unsigned int len;
+
+       /* This is a convenient routine to initialize a single-elem sg list */
+       sg_init_one(sg, buf, count);
+
+       /* add_buf wants a token to identify this buffer: we hand it any
+        * non-NULL pointer, since there's only ever one buffer. */
+       if (out_vq->vq_ops->add_buf(out_vq, sg, 1, 0, (void *)1) == 0) {
+               /* Tell Host to go! */
+               out_vq->vq_ops->kick(out_vq);
+               /* Chill out until it's done with the buffer. */
+               while (!out_vq->vq_ops->get_buf(out_vq, &len))
+                       cpu_relax();
+       }
+
+       /* We're expected to return the amount of data we wrote: all of it. */
+       return count;
+}
+
+/* Create a scatter-gather list representing our input buffer and put it in the
+ * queue. */
+static void add_inbuf(void)
+{
+       struct scatterlist sg[1];
+       sg_init_one(sg, inbuf, PAGE_SIZE);
+
+       /* We should always be able to add one buffer to an empty queue. */
+       if (in_vq->vq_ops->add_buf(in_vq, sg, 0, 1, inbuf) != 0)
+               BUG();
+       in_vq->vq_ops->kick(in_vq);
+}
+
+/*D:350 get_chars() is the callback from the hvc_console infrastructure when
+ * an interrupt is received.
+ *
+ * Most of the code deals with the fact that the hvc_console() infrastructure
+ * only asks us for 16 bytes at a time.  We keep in_offset and in_used fields
+ * for partially-filled buffers. */
+static int get_chars(u32 vtermno, char *buf, int count)
+{
+       /* If we don't have an input queue yet, we can't get input. */
+       BUG_ON(!in_vq);
+
+       /* No buffer?  Try to get one. */
+       if (!in_len) {
+               in = in_vq->vq_ops->get_buf(in_vq, &in_len);
+               if (!in)
+                       return 0;
+       }
+
+       /* You want more than we have to give?  Well, try wanting less! */
+       if (in_len < count)
+               count = in_len;
+
+       /* Copy across to their buffer and increment offset. */
+       memcpy(buf, in, count);
+       in += count;
+       in_len -= count;
+
+       /* Finished?  Re-register buffer so Host will use it again. */
+       if (in_len == 0)
+               add_inbuf();
+
+       return count;
+}
+/*:*/
+
+/*D:320 Console drivers are initialized very early so boot messages can go out,
+ * so we do things slightly differently from the generic virtio initialization
+ * of the net and block drivers.
+ *
+ * At this stage, the console is output-only.  It's too early to set up a
+ * virtqueue, so we let the drivers do some boutique early-output thing. */
+int __init virtio_cons_early_init(int (*put_chars)(u32, const char *, int))
+{
+       virtio_cons.put_chars = put_chars;
+       return hvc_instantiate(0, 0, &virtio_cons);
+}
+
+/*D:370 Once we're further in boot, we get probed like any other virtio device.
+ * At this stage we set up the output virtqueue.
+ *
+ * To set up and manage our virtual console, we call hvc_alloc().  Since we
+ * never remove the console device we never need this pointer again.
+ *
+ * Finally we put our input buffer in the input queue, ready to receive. */
+static int virtcons_probe(struct virtio_device *dev)
+{
+       int err;
+       struct hvc_struct *hvc;
+
+       vdev = dev;
+
+       /* This is the scratch page we use to receive console input */
+       inbuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+       if (!inbuf) {
+               err = -ENOMEM;
+               goto fail;
+       }
+
+       /* Find the input queue. */
+       /* FIXME: This is why we want to wean off hvc: we do nothing
+        * when input comes in. */
+       in_vq = vdev->config->find_vq(vdev, NULL);
+       if (IS_ERR(in_vq)) {
+               err = PTR_ERR(in_vq);
+               goto free;
+       }
+
+       out_vq = vdev->config->find_vq(vdev, NULL);
+       if (IS_ERR(out_vq)) {
+               err = PTR_ERR(out_vq);
+               goto free_in_vq;
+       }
+
+       /* Start using the new console output. */
+       virtio_cons.get_chars = get_chars;
+       virtio_cons.put_chars = put_chars;
+
+       /* The first argument of hvc_alloc() is the virtual console number, so
+        * we use zero.  The second argument is the interrupt number; we
+        * currently leave this as zero: it would be better not to use the
+        * hvc mechanism and fix this (FIXME!).
+        *
+        * The third argument is a "struct hv_ops" containing the put_chars()
+        * and get_chars() pointers.  The final argument is the output buffer
+        * size: we can do any size, so we put PAGE_SIZE here. */
+       hvc = hvc_alloc(0, 0, &virtio_cons, PAGE_SIZE);
+       if (IS_ERR(hvc)) {
+               err = PTR_ERR(hvc);
+               goto free_out_vq;
+       }
+
+       /* Register the input buffer the first time. */
+       add_inbuf();
+       return 0;
+
+free_out_vq:
+       vdev->config->del_vq(out_vq);
+free_in_vq:
+       vdev->config->del_vq(in_vq);
+free:
+       kfree(inbuf);
+fail:
+       return err;
+}
+
+static struct virtio_device_id id_table[] = {
+       { VIRTIO_ID_CONSOLE, VIRTIO_DEV_ANY_ID },
+       { 0 },
+};
+
+static struct virtio_driver virtio_console = {
+       .driver.name =  KBUILD_MODNAME,
+       .driver.owner = THIS_MODULE,
+       .id_table =     id_table,
+       .probe =        virtcons_probe,
+};
+
+static int __init init(void)
+{
+       return register_virtio_driver(&virtio_console);
+}
+module_init(init);
+
+MODULE_DEVICE_TABLE(virtio, id_table);
+MODULE_DESCRIPTION("Virtio console driver");
+MODULE_LICENSE("GPL");
index 645ad9808982526cf8f7ae4fdf682e2a433ed72e..7a5badfb7d846e00d85dbbd2c082461264b7a660 100644 (file)
@@ -99,6 +99,7 @@
 #include <linux/pm.h>
 #include <linux/font.h>
 #include <linux/bitops.h>
+#include <linux/notifier.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
@@ -158,11 +159,7 @@ static void blank_screen_t(unsigned long dummy);
 static void set_palette(struct vc_data *vc);
 
 static int printable;          /* Is console ready for printing? */
-#ifdef CONFIG_VT_UNICODE
-int default_utf8 = 1;
-#else
-int default_utf8;
-#endif
+int default_utf8 = true;
 module_param(default_utf8, int, S_IRUGO | S_IWUSR);
 
 /*
@@ -226,6 +223,35 @@ enum {
        blank_vesa_wait,
 };
 
+/*
+ * Notifier list for console events.
+ */
+static ATOMIC_NOTIFIER_HEAD(vt_notifier_list);
+
+int register_vt_notifier(struct notifier_block *nb)
+{
+       return atomic_notifier_chain_register(&vt_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(register_vt_notifier);
+
+int unregister_vt_notifier(struct notifier_block *nb)
+{
+       return atomic_notifier_chain_unregister(&vt_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(unregister_vt_notifier);
+
+static void notify_write(struct vc_data *vc, unsigned int unicode)
+{
+       struct vt_notifier_param param = { .vc = vc, unicode = unicode };
+       atomic_notifier_call_chain(&vt_notifier_list, VT_WRITE, &param);
+}
+
+static void notify_update(struct vc_data *vc)
+{
+       struct vt_notifier_param param = { .vc = vc };
+       atomic_notifier_call_chain(&vt_notifier_list, VT_UPDATE, &param);
+}
+
 /*
  *     Low-Level Functions
  */
@@ -722,6 +748,7 @@ int vc_allocate(unsigned int currcons)      /* return 0 on success */
                return -ENXIO;
        if (!vc_cons[currcons].d) {
            struct vc_data *vc;
+           struct vt_notifier_param param;
 
            /* prevent users from taking too much memory */
            if (currcons >= MAX_NR_USER_CONSOLES && !capable(CAP_SYS_RESOURCE))
@@ -733,7 +760,7 @@ int vc_allocate(unsigned int currcons)      /* return 0 on success */
            /* although the numbers above are not valid since long ago, the
               point is still up-to-date and the comment still has its value
               even if only as a historical artifact.  --mj, July 1998 */
-           vc = kzalloc(sizeof(struct vc_data), GFP_KERNEL);
+           param.vc = vc = kzalloc(sizeof(struct vc_data), GFP_KERNEL);
            if (!vc)
                return -ENOMEM;
            vc_cons[currcons].d = vc;
@@ -750,6 +777,7 @@ int vc_allocate(unsigned int currcons)      /* return 0 on success */
            }
            vc->vc_kmalloced = 1;
            vc_init(vc, vc->vc_rows, vc->vc_cols, 1);
+           atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, &param);
        }
        return 0;
 }
@@ -911,6 +939,8 @@ void vc_deallocate(unsigned int currcons)
 
        if (vc_cons_allocated(currcons)) {
                struct vc_data *vc = vc_cons[currcons].d;
+               struct vt_notifier_param param = { .vc = vc };
+               atomic_notifier_call_chain(&vt_notifier_list, VT_DEALLOCATE, &param);
                vc->vc_sw->con_deinit(vc);
                put_pid(vc->vt_pid);
                module_put(vc->vc_sw->owner);
@@ -1023,6 +1053,7 @@ static void lf(struct vc_data *vc)
                vc->vc_pos += vc->vc_size_row;
        }
        vc->vc_need_wrap = 0;
+       notify_write(vc, '\n');
 }
 
 static void ri(struct vc_data *vc)
@@ -1043,6 +1074,7 @@ static inline void cr(struct vc_data *vc)
 {
        vc->vc_pos -= vc->vc_x << 1;
        vc->vc_need_wrap = vc->vc_x = 0;
+       notify_write(vc, '\r');
 }
 
 static inline void bs(struct vc_data *vc)
@@ -1051,6 +1083,7 @@ static inline void bs(struct vc_data *vc)
                vc->vc_pos -= 2;
                vc->vc_x--;
                vc->vc_need_wrap = 0;
+               notify_write(vc, '\b');
        }
 }
 
@@ -1597,6 +1630,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
                                break;
                }
                vc->vc_pos += (vc->vc_x << 1);
+               notify_write(vc, '\t');
                return;
        case 10: case 11: case 12:
                lf(vc);
@@ -2256,6 +2290,7 @@ rescan_last_byte:
                                tc = conv_uni_to_pc(vc, ' '); /* A space is printed in the second column */
                                if (tc < 0) tc = ' ';
                        }
+                       notify_write(vc, c);
 
                        if (inverse) {
                                FLUSH
@@ -2278,6 +2313,7 @@ rescan_last_byte:
        release_console_sem();
 
 out:
+       notify_update(vc);
        return n;
 #undef FLUSH
 }
@@ -2321,6 +2357,7 @@ static void console_callback(struct work_struct *ignored)
                do_blank_screen(0);
                blank_timer_expired = 0;
        }
+       notify_update(vc_cons[fg_console].d);
 
        release_console_sem();
 }
@@ -2422,6 +2459,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
                                continue;
                }
                scr_writew((vc->vc_attr << 8) + c, (unsigned short *)vc->vc_pos);
+               notify_write(vc, c);
                cnt++;
                if (myx == vc->vc_cols - 1) {
                        vc->vc_need_wrap = 1;
@@ -2440,6 +2478,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
                }
        }
        set_cursor(vc);
+       notify_update(vc);
 
 quit:
        clear_bit(0, &printing);
diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
new file mode 100644 (file)
index 0000000..3bed412
--- /dev/null
@@ -0,0 +1,20 @@
+
+config CPU_IDLE
+       bool "CPU idle PM support"
+       help
+         CPU idle is a generic framework for supporting software-controlled
+         idle processor power management.  It includes modular cross-platform
+         governors that can be swapped during runtime.
+
+         If you're using a mobile platform that supports CPU idle PM (e.g.
+         an ACPI-capable notebook), you should say Y here.
+
+config CPU_IDLE_GOV_LADDER
+       bool
+       depends on CPU_IDLE
+       default y
+
+config CPU_IDLE_GOV_MENU
+       bool
+       depends on CPU_IDLE && NO_HZ
+       default y
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
new file mode 100644 (file)
index 0000000..5634f88
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for cpuidle.
+#
+
+obj-y += cpuidle.o driver.o governor.o sysfs.o governors/
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
new file mode 100644 (file)
index 0000000..fdf4106
--- /dev/null
@@ -0,0 +1,295 @@
+/*
+ * cpuidle.c - core cpuidle infrastructure
+ *
+ * (C) 2006-2007 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ *               Shaohua Li <shaohua.li@intel.com>
+ *               Adam Belay <abelay@novell.com>
+ *
+ * This code is licenced under the GPL.
+ */
+
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/notifier.h>
+#include <linux/latency.h>
+#include <linux/cpu.h>
+#include <linux/cpuidle.h>
+
+#include "cpuidle.h"
+
+DEFINE_PER_CPU(struct cpuidle_device *, cpuidle_devices);
+EXPORT_PER_CPU_SYMBOL_GPL(cpuidle_devices);
+
+DEFINE_MUTEX(cpuidle_lock);
+LIST_HEAD(cpuidle_detected_devices);
+static void (*pm_idle_old)(void);
+
+static int enabled_devices;
+
+/**
+ * cpuidle_idle_call - the main idle loop
+ *
+ * NOTE: no locks or semaphores should be used here
+ */
+static void cpuidle_idle_call(void)
+{
+       struct cpuidle_device *dev = __get_cpu_var(cpuidle_devices);
+       struct cpuidle_state *target_state;
+       int next_state;
+
+       /* check if the device is ready */
+       if (!dev || !dev->enabled) {
+               if (pm_idle_old)
+                       pm_idle_old();
+               else
+                       local_irq_enable();
+               return;
+       }
+
+       /* ask the governor for the next state */
+       next_state = cpuidle_curr_governor->select(dev);
+       if (need_resched())
+               return;
+       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;
+       target_state->time += dev->last_residency;
+       target_state->usage++;
+
+       /* give the governor an opportunity to reflect on the outcome */
+       if (cpuidle_curr_governor->reflect)
+               cpuidle_curr_governor->reflect(dev);
+}
+
+/**
+ * cpuidle_install_idle_handler - installs the cpuidle idle loop handler
+ */
+void cpuidle_install_idle_handler(void)
+{
+       if (enabled_devices && (pm_idle != cpuidle_idle_call)) {
+               /* Make sure all changes finished before we switch to new idle */
+               smp_wmb();
+               pm_idle = cpuidle_idle_call;
+       }
+}
+
+/**
+ * cpuidle_uninstall_idle_handler - uninstalls the cpuidle idle loop handler
+ */
+void cpuidle_uninstall_idle_handler(void)
+{
+       if (enabled_devices && (pm_idle != pm_idle_old)) {
+               pm_idle = pm_idle_old;
+               cpu_idle_wait();
+       }
+}
+
+/**
+ * cpuidle_pause_and_lock - temporarily disables CPUIDLE
+ */
+void cpuidle_pause_and_lock(void)
+{
+       mutex_lock(&cpuidle_lock);
+       cpuidle_uninstall_idle_handler();
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_pause_and_lock);
+
+/**
+ * cpuidle_resume_and_unlock - resumes CPUIDLE operation
+ */
+void cpuidle_resume_and_unlock(void)
+{
+       cpuidle_install_idle_handler();
+       mutex_unlock(&cpuidle_lock);
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_resume_and_unlock);
+
+/**
+ * cpuidle_enable_device - enables idle PM for a CPU
+ * @dev: the CPU
+ *
+ * This function must be called between cpuidle_pause_and_lock and
+ * cpuidle_resume_and_unlock when used externally.
+ */
+int cpuidle_enable_device(struct cpuidle_device *dev)
+{
+       int ret, i;
+
+       if (dev->enabled)
+               return 0;
+       if (!cpuidle_curr_driver || !cpuidle_curr_governor)
+               return -EIO;
+       if (!dev->state_count)
+               return -EINVAL;
+
+       if ((ret = cpuidle_add_state_sysfs(dev)))
+               return ret;
+
+       if (cpuidle_curr_governor->enable &&
+           (ret = cpuidle_curr_governor->enable(dev)))
+               goto fail_sysfs;
+
+       for (i = 0; i < dev->state_count; i++) {
+               dev->states[i].usage = 0;
+               dev->states[i].time = 0;
+       }
+       dev->last_residency = 0;
+       dev->last_state = NULL;
+
+       smp_wmb();
+
+       dev->enabled = 1;
+
+       enabled_devices++;
+       return 0;
+
+fail_sysfs:
+       cpuidle_remove_state_sysfs(dev);
+
+       return ret;
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_enable_device);
+
+/**
+ * cpuidle_disable_device - disables idle PM for a CPU
+ * @dev: the CPU
+ *
+ * This function must be called between cpuidle_pause_and_lock and
+ * cpuidle_resume_and_unlock when used externally.
+ */
+void cpuidle_disable_device(struct cpuidle_device *dev)
+{
+       if (!dev->enabled)
+               return;
+       if (!cpuidle_curr_driver || !cpuidle_curr_governor)
+               return;
+
+       dev->enabled = 0;
+
+       if (cpuidle_curr_governor->disable)
+               cpuidle_curr_governor->disable(dev);
+
+       cpuidle_remove_state_sysfs(dev);
+       enabled_devices--;
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_disable_device);
+
+/**
+ * cpuidle_register_device - registers a CPU's idle PM feature
+ * @dev: the cpu
+ */
+int cpuidle_register_device(struct cpuidle_device *dev)
+{
+       int ret;
+       struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu);
+
+       if (!sys_dev)
+               return -EINVAL;
+       if (!try_module_get(cpuidle_curr_driver->owner))
+               return -EINVAL;
+
+       init_completion(&dev->kobj_unregister);
+
+       mutex_lock(&cpuidle_lock);
+
+       per_cpu(cpuidle_devices, dev->cpu) = dev;
+       list_add(&dev->device_list, &cpuidle_detected_devices);
+       if ((ret = cpuidle_add_sysfs(sys_dev))) {
+               mutex_unlock(&cpuidle_lock);
+               module_put(cpuidle_curr_driver->owner);
+               return ret;
+       }
+
+       cpuidle_enable_device(dev);
+       cpuidle_install_idle_handler();
+
+       mutex_unlock(&cpuidle_lock);
+
+       return 0;
+
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_register_device);
+
+/**
+ * cpuidle_unregister_device - unregisters a CPU's idle PM feature
+ * @dev: the cpu
+ */
+void cpuidle_unregister_device(struct cpuidle_device *dev)
+{
+       struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu);
+
+       cpuidle_pause_and_lock();
+
+       cpuidle_disable_device(dev);
+
+       cpuidle_remove_sysfs(sys_dev);
+       list_del(&dev->device_list);
+       wait_for_completion(&dev->kobj_unregister);
+       per_cpu(cpuidle_devices, dev->cpu) = NULL;
+
+       cpuidle_resume_and_unlock();
+
+       module_put(cpuidle_curr_driver->owner);
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_unregister_device);
+
+#ifdef CONFIG_SMP
+
+static void smp_callback(void *v)
+{
+       /* we already woke the CPU up, nothing more to do */
+}
+
+/*
+ * This function gets called when a part of the kernel has a new latency
+ * requirement.  This means we need to get all processors out of their C-state,
+ * and then recalculate a new suitable C-state. Just do a cross-cpu IPI; that
+ * wakes them all right up.
+ */
+static int cpuidle_latency_notify(struct notifier_block *b,
+               unsigned long l, void *v)
+{
+       smp_call_function(smp_callback, NULL, 0, 1);
+       return NOTIFY_OK;
+}
+
+static struct notifier_block cpuidle_latency_notifier = {
+       .notifier_call = cpuidle_latency_notify,
+};
+
+#define latency_notifier_init(x) do { register_latency_notifier(x); } while (0)
+
+#else /* CONFIG_SMP */
+
+#define latency_notifier_init(x) do { } while (0)
+
+#endif /* CONFIG_SMP */
+
+/**
+ * cpuidle_init - core initializer
+ */
+static int __init cpuidle_init(void)
+{
+       int ret;
+
+       pm_idle_old = pm_idle;
+
+       ret = cpuidle_add_class_sysfs(&cpu_sysdev_class);
+       if (ret)
+               return ret;
+
+       latency_notifier_init(&cpuidle_latency_notifier);
+
+       return 0;
+}
+
+core_initcall(cpuidle_init);
diff --git a/drivers/cpuidle/cpuidle.h b/drivers/cpuidle/cpuidle.h
new file mode 100644 (file)
index 0000000..9476ba3
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * cpuidle.h - The internal header file
+ */
+
+#ifndef __DRIVER_CPUIDLE_H
+#define __DRIVER_CPUIDLE_H
+
+#include <linux/sysdev.h>
+
+/* For internal use only */
+extern struct cpuidle_governor *cpuidle_curr_governor;
+extern struct cpuidle_driver *cpuidle_curr_driver;
+extern struct list_head cpuidle_governors;
+extern struct list_head cpuidle_detected_devices;
+extern struct mutex cpuidle_lock;
+extern spinlock_t cpuidle_driver_lock;
+
+/* idle loop */
+extern void cpuidle_install_idle_handler(void);
+extern void cpuidle_uninstall_idle_handler(void);
+
+/* governors */
+extern int cpuidle_switch_governor(struct cpuidle_governor *gov);
+
+/* sysfs */
+extern int cpuidle_add_class_sysfs(struct sysdev_class *cls);
+extern void cpuidle_remove_class_sysfs(struct sysdev_class *cls);
+extern int cpuidle_add_state_sysfs(struct cpuidle_device *device);
+extern void cpuidle_remove_state_sysfs(struct cpuidle_device *device);
+extern int cpuidle_add_sysfs(struct sys_device *sysdev);
+extern void cpuidle_remove_sysfs(struct sys_device *sysdev);
+
+#endif /* __DRIVER_CPUIDLE_H */
diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c
new file mode 100644 (file)
index 0000000..2257004
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * driver.c - driver support
+ *
+ * (C) 2006-2007 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ *               Shaohua Li <shaohua.li@intel.com>
+ *               Adam Belay <abelay@novell.com>
+ *
+ * This code is licenced under the GPL.
+ */
+
+#include <linux/mutex.h>
+#include <linux/module.h>
+#include <linux/cpuidle.h>
+
+#include "cpuidle.h"
+
+struct cpuidle_driver *cpuidle_curr_driver;
+DEFINE_SPINLOCK(cpuidle_driver_lock);
+
+/**
+ * cpuidle_register_driver - registers a driver
+ * @drv: the driver
+ */
+int cpuidle_register_driver(struct cpuidle_driver *drv)
+{
+       if (!drv)
+               return -EINVAL;
+
+       spin_lock(&cpuidle_driver_lock);
+       if (cpuidle_curr_driver) {
+               spin_unlock(&cpuidle_driver_lock);
+               return -EBUSY;
+       }
+       cpuidle_curr_driver = drv;
+       spin_unlock(&cpuidle_driver_lock);
+
+       return 0;
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_register_driver);
+
+/**
+ * cpuidle_unregister_driver - unregisters a driver
+ * @drv: the driver
+ */
+void cpuidle_unregister_driver(struct cpuidle_driver *drv)
+{
+       if (!drv)
+               return;
+
+       spin_lock(&cpuidle_driver_lock);
+       cpuidle_curr_driver = NULL;
+       spin_unlock(&cpuidle_driver_lock);
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_unregister_driver);
diff --git a/drivers/cpuidle/governor.c b/drivers/cpuidle/governor.c
new file mode 100644 (file)
index 0000000..bb699cb
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * governor.c - governor support
+ *
+ * (C) 2006-2007 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ *               Shaohua Li <shaohua.li@intel.com>
+ *               Adam Belay <abelay@novell.com>
+ *
+ * This code is licenced under the GPL.
+ */
+
+#include <linux/mutex.h>
+#include <linux/module.h>
+#include <linux/cpuidle.h>
+
+#include "cpuidle.h"
+
+LIST_HEAD(cpuidle_governors);
+struct cpuidle_governor *cpuidle_curr_governor;
+
+/**
+ * __cpuidle_find_governor - finds a governor of the specified name
+ * @str: the name
+ *
+ * Must be called with cpuidle_lock aquired.
+ */
+static struct cpuidle_governor * __cpuidle_find_governor(const char *str)
+{
+       struct cpuidle_governor *gov;
+
+       list_for_each_entry(gov, &cpuidle_governors, governor_list)
+               if (!strnicmp(str, gov->name, CPUIDLE_NAME_LEN))
+                       return gov;
+
+       return NULL;
+}
+
+/**
+ * cpuidle_switch_governor - changes the governor
+ * @gov: the new target governor
+ *
+ * NOTE: "gov" can be NULL to specify disabled
+ * Must be called with cpuidle_lock aquired.
+ */
+int cpuidle_switch_governor(struct cpuidle_governor *gov)
+{
+       struct cpuidle_device *dev;
+
+       if (gov == cpuidle_curr_governor)
+               return 0;
+
+       cpuidle_uninstall_idle_handler();
+
+       if (cpuidle_curr_governor) {
+               list_for_each_entry(dev, &cpuidle_detected_devices, device_list)
+                       cpuidle_disable_device(dev);
+               module_put(cpuidle_curr_governor->owner);
+       }
+
+       cpuidle_curr_governor = gov;
+
+       if (gov) {
+               if (!try_module_get(cpuidle_curr_governor->owner))
+                       return -EINVAL;
+               list_for_each_entry(dev, &cpuidle_detected_devices, device_list)
+                       cpuidle_enable_device(dev);
+               cpuidle_install_idle_handler();
+               printk(KERN_INFO "cpuidle: using governor %s\n", gov->name);
+       }
+
+       return 0;
+}
+
+/**
+ * cpuidle_register_governor - registers a governor
+ * @gov: the governor
+ */
+int cpuidle_register_governor(struct cpuidle_governor *gov)
+{
+       int ret = -EEXIST;
+
+       if (!gov || !gov->select)
+               return -EINVAL;
+
+       mutex_lock(&cpuidle_lock);
+       if (__cpuidle_find_governor(gov->name) == NULL) {
+               ret = 0;
+               list_add_tail(&gov->governor_list, &cpuidle_governors);
+               if (!cpuidle_curr_governor ||
+                   cpuidle_curr_governor->rating < gov->rating)
+                       cpuidle_switch_governor(gov);
+       }
+       mutex_unlock(&cpuidle_lock);
+
+       return ret;
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_register_governor);
+
+/**
+ * cpuidle_replace_governor - find a replacement governor
+ * @exclude_rating: the rating that will be skipped while looking for
+ * new governor.
+ */
+static struct cpuidle_governor *cpuidle_replace_governor(int exclude_rating)
+{
+       struct cpuidle_governor *gov;
+       struct cpuidle_governor *ret_gov = NULL;
+       unsigned int max_rating = 0;
+
+       list_for_each_entry(gov, &cpuidle_governors, governor_list) {
+               if (gov->rating == exclude_rating)
+                       continue;
+               if (gov->rating > max_rating) {
+                       max_rating = gov->rating;
+                       ret_gov = gov;
+               }
+       }
+
+       return ret_gov;
+}
+
+/**
+ * cpuidle_unregister_governor - unregisters a governor
+ * @gov: the governor
+ */
+void cpuidle_unregister_governor(struct cpuidle_governor *gov)
+{
+       if (!gov)
+               return;
+
+       mutex_lock(&cpuidle_lock);
+       if (gov == cpuidle_curr_governor) {
+               struct cpuidle_governor *new_gov;
+               new_gov = cpuidle_replace_governor(gov->rating);
+               cpuidle_switch_governor(new_gov);
+       }
+       list_del(&gov->governor_list);
+       mutex_unlock(&cpuidle_lock);
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_unregister_governor);
diff --git a/drivers/cpuidle/governors/Makefile b/drivers/cpuidle/governors/Makefile
new file mode 100644 (file)
index 0000000..1b51272
--- /dev/null
@@ -0,0 +1,6 @@
+#
+# Makefile for cpuidle governors.
+#
+
+obj-$(CONFIG_CPU_IDLE_GOV_LADDER) += ladder.o
+obj-$(CONFIG_CPU_IDLE_GOV_MENU) += menu.o
diff --git a/drivers/cpuidle/governors/ladder.c b/drivers/cpuidle/governors/ladder.c
new file mode 100644 (file)
index 0000000..eb666ec
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * ladder.c - the residency ladder algorithm
+ *
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *  Copyright (C) 2004, 2005 Dominik Brodowski <linux@brodo.de>
+ *
+ * (C) 2006-2007 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ *               Shaohua Li <shaohua.li@intel.com>
+ *               Adam Belay <abelay@novell.com>
+ *
+ * This code is licenced under the GPL.
+ */
+
+#include <linux/kernel.h>
+#include <linux/cpuidle.h>
+#include <linux/latency.h>
+#include <linux/moduleparam.h>
+#include <linux/jiffies.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#define PROMOTION_COUNT 4
+#define DEMOTION_COUNT 1
+
+struct ladder_device_state {
+       struct {
+               u32 promotion_count;
+               u32 demotion_count;
+               u32 promotion_time;
+               u32 demotion_time;
+       } threshold;
+       struct {
+               int promotion_count;
+               int demotion_count;
+       } stats;
+};
+
+struct ladder_device {
+       struct ladder_device_state states[CPUIDLE_STATE_MAX];
+       int last_state_idx;
+};
+
+static DEFINE_PER_CPU(struct ladder_device, ladder_devices);
+
+/**
+ * ladder_do_selection - prepares private data for a state change
+ * @ldev: the ladder device
+ * @old_idx: the current state index
+ * @new_idx: the new target state index
+ */
+static inline void ladder_do_selection(struct ladder_device *ldev,
+                                      int old_idx, int new_idx)
+{
+       ldev->states[old_idx].stats.promotion_count = 0;
+       ldev->states[old_idx].stats.demotion_count = 0;
+       ldev->last_state_idx = new_idx;
+}
+
+/**
+ * ladder_select_state - selects the next state to enter
+ * @dev: the CPU
+ */
+static int ladder_select_state(struct cpuidle_device *dev)
+{
+       struct ladder_device *ldev = &__get_cpu_var(ladder_devices);
+       struct ladder_device_state *last_state;
+       int last_residency, last_idx = ldev->last_state_idx;
+
+       if (unlikely(!ldev))
+               return 0;
+
+       last_state = &ldev->states[last_idx];
+
+       if (dev->states[last_idx].flags & CPUIDLE_FLAG_TIME_VALID)
+               last_residency = cpuidle_get_last_residency(dev) - dev->states[last_idx].exit_latency;
+       else
+               last_residency = last_state->threshold.promotion_time + 1;
+
+       /* consider promotion */
+       if (last_idx < dev->state_count - 1 &&
+           last_residency > last_state->threshold.promotion_time &&
+           dev->states[last_idx + 1].exit_latency <= system_latency_constraint()) {
+               last_state->stats.promotion_count++;
+               last_state->stats.demotion_count = 0;
+               if (last_state->stats.promotion_count >= last_state->threshold.promotion_count) {
+                       ladder_do_selection(ldev, last_idx, last_idx + 1);
+                       return last_idx + 1;
+               }
+       }
+
+       /* consider demotion */
+       if (last_idx > 0 &&
+           last_residency < last_state->threshold.demotion_time) {
+               last_state->stats.demotion_count++;
+               last_state->stats.promotion_count = 0;
+               if (last_state->stats.demotion_count >= last_state->threshold.demotion_count) {
+                       ladder_do_selection(ldev, last_idx, last_idx - 1);
+                       return last_idx - 1;
+               }
+       }
+
+       /* otherwise remain at the current state */
+       return last_idx;
+}
+
+/**
+ * ladder_enable_device - setup for the governor
+ * @dev: the CPU
+ */
+static int ladder_enable_device(struct cpuidle_device *dev)
+{
+       int i;
+       struct ladder_device *ldev = &per_cpu(ladder_devices, dev->cpu);
+       struct ladder_device_state *lstate;
+       struct cpuidle_state *state;
+
+       ldev->last_state_idx = 0;
+
+       for (i = 0; i < dev->state_count; i++) {
+               state = &dev->states[i];
+               lstate = &ldev->states[i];
+
+               lstate->stats.promotion_count = 0;
+               lstate->stats.demotion_count = 0;
+
+               lstate->threshold.promotion_count = PROMOTION_COUNT;
+               lstate->threshold.demotion_count = DEMOTION_COUNT;
+
+               if (i < dev->state_count - 1)
+                       lstate->threshold.promotion_time = state->exit_latency;
+               if (i > 0)
+                       lstate->threshold.demotion_time = state->exit_latency;
+       }
+
+       return 0;
+}
+
+static struct cpuidle_governor ladder_governor = {
+       .name =         "ladder",
+       .rating =       10,
+       .enable =       ladder_enable_device,
+       .select =       ladder_select_state,
+       .owner =        THIS_MODULE,
+};
+
+/**
+ * init_ladder - initializes the governor
+ */
+static int __init init_ladder(void)
+{
+       return cpuidle_register_governor(&ladder_governor);
+}
+
+/**
+ * exit_ladder - exits the governor
+ */
+static void __exit exit_ladder(void)
+{
+       cpuidle_unregister_governor(&ladder_governor);
+}
+
+MODULE_LICENSE("GPL");
+module_init(init_ladder);
+module_exit(exit_ladder);
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
new file mode 100644 (file)
index 0000000..299d45c
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * menu.c - the menu idle governor
+ *
+ * Copyright (C) 2006-2007 Adam Belay <abelay@novell.com>
+ *
+ * This code is licenced under the GPL.
+ */
+
+#include <linux/kernel.h>
+#include <linux/cpuidle.h>
+#include <linux/latency.h>
+#include <linux/time.h>
+#include <linux/ktime.h>
+#include <linux/hrtimer.h>
+#include <linux/tick.h>
+
+#define BREAK_FUZZ     4       /* 4 us */
+
+struct menu_device {
+       int             last_state_idx;
+
+       unsigned int    expected_us;
+       unsigned int    predicted_us;
+       unsigned int    last_measured_us;
+       unsigned int    elapsed_us;
+};
+
+static DEFINE_PER_CPU(struct menu_device, menu_devices);
+
+/**
+ * menu_select - selects the next idle state to enter
+ * @dev: the CPU
+ */
+static int menu_select(struct cpuidle_device *dev)
+{
+       struct menu_device *data = &__get_cpu_var(menu_devices);
+       int i;
+
+       /* determine the expected residency time */
+       data->expected_us =
+               (u32) ktime_to_ns(tick_nohz_get_sleep_length()) / 1000;
+
+       /* find the deepest idle state that satisfies our constraints */
+       for (i = 1; i < dev->state_count; i++) {
+               struct cpuidle_state *s = &dev->states[i];
+
+               if (s->target_residency > data->expected_us)
+                       break;
+               if (s->target_residency > data->predicted_us)
+                       break;
+               if (s->exit_latency > system_latency_constraint())
+                       break;
+       }
+
+       data->last_state_idx = i - 1;
+       return i - 1;
+}
+
+/**
+ * menu_reflect - attempts to guess what happened after entry
+ * @dev: the CPU
+ *
+ * NOTE: it's important to be fast here because this operation will add to
+ *       the overall exit latency.
+ */
+static void menu_reflect(struct cpuidle_device *dev)
+{
+       struct menu_device *data = &__get_cpu_var(menu_devices);
+       int last_idx = data->last_state_idx;
+       unsigned int measured_us =
+               cpuidle_get_last_residency(dev) + data->elapsed_us;
+       struct cpuidle_state *target = &dev->states[last_idx];
+
+       /*
+        * Ugh, this idle state doesn't support residency measurements, so we
+        * are basically lost in the dark.  As a compromise, assume we slept
+        * for one full standard timer tick.  However, be aware that this
+        * could potentially result in a suboptimal state transition.
+        */
+       if (!(target->flags & CPUIDLE_FLAG_TIME_VALID))
+               measured_us = USEC_PER_SEC / HZ;
+
+       /* Predict time remaining until next break event */
+       if (measured_us + BREAK_FUZZ < data->expected_us - target->exit_latency) {
+               data->predicted_us = max(measured_us, data->last_measured_us);
+               data->last_measured_us = measured_us;
+               data->elapsed_us = 0;
+       } else {
+               if (data->elapsed_us < data->elapsed_us + measured_us)
+                       data->elapsed_us = measured_us;
+               else
+                       data->elapsed_us = -1;
+               data->predicted_us = max(measured_us, data->last_measured_us);
+       }
+}
+
+/**
+ * menu_enable_device - scans a CPU's states and does setup
+ * @dev: the CPU
+ */
+static int menu_enable_device(struct cpuidle_device *dev)
+{
+       struct menu_device *data = &per_cpu(menu_devices, dev->cpu);
+
+       memset(data, 0, sizeof(struct menu_device));
+
+       return 0;
+}
+
+static struct cpuidle_governor menu_governor = {
+       .name =         "menu",
+       .rating =       20,
+       .enable =       menu_enable_device,
+       .select =       menu_select,
+       .reflect =      menu_reflect,
+       .owner =        THIS_MODULE,
+};
+
+/**
+ * init_menu - initializes the governor
+ */
+static int __init init_menu(void)
+{
+       return cpuidle_register_governor(&menu_governor);
+}
+
+/**
+ * exit_menu - exits the governor
+ */
+static void __exit exit_menu(void)
+{
+       cpuidle_unregister_governor(&menu_governor);
+}
+
+MODULE_LICENSE("GPL");
+module_init(init_menu);
+module_exit(exit_menu);
diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c
new file mode 100644 (file)
index 0000000..0f3515e
--- /dev/null
@@ -0,0 +1,361 @@
+/*
+ * sysfs.c - sysfs support
+ *
+ * (C) 2006-2007 Shaohua Li <shaohua.li@intel.com>
+ *
+ * This code is licenced under the GPL.
+ */
+
+#include <linux/kernel.h>
+#include <linux/cpuidle.h>
+#include <linux/sysfs.h>
+#include <linux/cpu.h>
+
+#include "cpuidle.h"
+
+static unsigned int sysfs_switch;
+static int __init cpuidle_sysfs_setup(char *unused)
+{
+       sysfs_switch = 1;
+       return 1;
+}
+__setup("cpuidle_sysfs_switch", cpuidle_sysfs_setup);
+
+static ssize_t show_available_governors(struct sys_device *dev, char *buf)
+{
+       ssize_t i = 0;
+       struct cpuidle_governor *tmp;
+
+       mutex_lock(&cpuidle_lock);
+       list_for_each_entry(tmp, &cpuidle_governors, governor_list) {
+               if (i >= (ssize_t) ((PAGE_SIZE/sizeof(char)) - CPUIDLE_NAME_LEN - 2))
+                       goto out;
+               i += scnprintf(&buf[i], CPUIDLE_NAME_LEN, "%s ", tmp->name);
+       }
+
+out:
+       i+= sprintf(&buf[i], "\n");
+       mutex_unlock(&cpuidle_lock);
+       return i;
+}
+
+static ssize_t show_current_driver(struct sys_device *dev, char *buf)
+{
+       ssize_t ret;
+
+       spin_lock(&cpuidle_driver_lock);
+       if (cpuidle_curr_driver)
+               ret = sprintf(buf, "%s\n", cpuidle_curr_driver->name);
+       else
+               ret = sprintf(buf, "none\n");
+       spin_unlock(&cpuidle_driver_lock);
+
+       return ret;
+}
+
+static ssize_t show_current_governor(struct sys_device *dev, char *buf)
+{
+       ssize_t ret;
+
+       mutex_lock(&cpuidle_lock);
+       if (cpuidle_curr_governor)
+               ret = sprintf(buf, "%s\n", cpuidle_curr_governor->name);
+       else
+               ret = sprintf(buf, "none\n");
+       mutex_unlock(&cpuidle_lock);
+
+       return ret;
+}
+
+static ssize_t store_current_governor(struct sys_device *dev,
+       const char *buf, size_t count)
+{
+       char gov_name[CPUIDLE_NAME_LEN];
+       int ret = -EINVAL;
+       size_t len = count;
+       struct cpuidle_governor *gov;
+
+       if (!len || len >= sizeof(gov_name))
+               return -EINVAL;
+
+       memcpy(gov_name, buf, len);
+       gov_name[len] = '\0';
+       if (gov_name[len - 1] == '\n')
+               gov_name[--len] = '\0';
+
+       mutex_lock(&cpuidle_lock);
+
+       list_for_each_entry(gov, &cpuidle_governors, governor_list) {
+               if (strlen(gov->name) == len && !strcmp(gov->name, gov_name)) {
+                       ret = cpuidle_switch_governor(gov);
+                       break;
+               }
+       }
+
+       mutex_unlock(&cpuidle_lock);
+
+       if (ret)
+               return ret;
+       else
+               return count;
+}
+
+static SYSDEV_ATTR(current_driver, 0444, show_current_driver, NULL);
+static SYSDEV_ATTR(current_governor_ro, 0444, show_current_governor, NULL);
+
+static struct attribute *cpuclass_default_attrs[] = {
+       &attr_current_driver.attr,
+       &attr_current_governor_ro.attr,
+       NULL
+};
+
+static SYSDEV_ATTR(available_governors, 0444, show_available_governors, NULL);
+static SYSDEV_ATTR(current_governor, 0644, show_current_governor,
+       store_current_governor);
+
+static struct attribute *cpuclass_switch_attrs[] = {
+       &attr_available_governors.attr,
+       &attr_current_driver.attr,
+       &attr_current_governor.attr,
+       NULL
+};
+
+static struct attribute_group cpuclass_attr_group = {
+       .attrs = cpuclass_default_attrs,
+       .name = "cpuidle",
+};
+
+/**
+ * cpuidle_add_class_sysfs - add CPU global sysfs attributes
+ */
+int cpuidle_add_class_sysfs(struct sysdev_class *cls)
+{
+       if (sysfs_switch)
+               cpuclass_attr_group.attrs = cpuclass_switch_attrs;
+
+       return sysfs_create_group(&cls->kset.kobj, &cpuclass_attr_group);
+}
+
+/**
+ * cpuidle_remove_class_sysfs - remove CPU global sysfs attributes
+ */
+void cpuidle_remove_class_sysfs(struct sysdev_class *cls)
+{
+       sysfs_remove_group(&cls->kset.kobj, &cpuclass_attr_group);
+}
+
+struct cpuidle_attr {
+       struct attribute attr;
+       ssize_t (*show)(struct cpuidle_device *, char *);
+       ssize_t (*store)(struct cpuidle_device *, const char *, size_t count);
+};
+
+#define define_one_ro(_name, show) \
+       static struct cpuidle_attr attr_##_name = __ATTR(_name, 0444, show, NULL)
+#define define_one_rw(_name, show, store) \
+       static struct cpuidle_attr attr_##_name = __ATTR(_name, 0644, show, store)
+
+#define kobj_to_cpuidledev(k) container_of(k, struct cpuidle_device, kobj)
+#define attr_to_cpuidleattr(a) container_of(a, struct cpuidle_attr, attr)
+static ssize_t cpuidle_show(struct kobject * kobj, struct attribute * attr ,char * buf)
+{
+       int ret = -EIO;
+       struct cpuidle_device *dev = kobj_to_cpuidledev(kobj);
+       struct cpuidle_attr * cattr = attr_to_cpuidleattr(attr);
+
+       if (cattr->show) {
+               mutex_lock(&cpuidle_lock);
+               ret = cattr->show(dev, buf);
+               mutex_unlock(&cpuidle_lock);
+       }
+       return ret;
+}
+
+static ssize_t cpuidle_store(struct kobject * kobj, struct attribute * attr,
+                    const char * buf, size_t count)
+{
+       int ret = -EIO;
+       struct cpuidle_device *dev = kobj_to_cpuidledev(kobj);
+       struct cpuidle_attr * cattr = attr_to_cpuidleattr(attr);
+
+       if (cattr->store) {
+               mutex_lock(&cpuidle_lock);
+               ret = cattr->store(dev, buf, count);
+               mutex_unlock(&cpuidle_lock);
+       }
+       return ret;
+}
+
+static struct sysfs_ops cpuidle_sysfs_ops = {
+       .show = cpuidle_show,
+       .store = cpuidle_store,
+};
+
+static void cpuidle_sysfs_release(struct kobject *kobj)
+{
+       struct cpuidle_device *dev = kobj_to_cpuidledev(kobj);
+
+       complete(&dev->kobj_unregister);
+}
+
+static struct kobj_type ktype_cpuidle = {
+       .sysfs_ops = &cpuidle_sysfs_ops,
+       .release = cpuidle_sysfs_release,
+};
+
+struct cpuidle_state_attr {
+       struct attribute attr;
+       ssize_t (*show)(struct cpuidle_state *, char *);
+       ssize_t (*store)(struct cpuidle_state *, const char *, size_t);
+};
+
+#define define_one_state_ro(_name, show) \
+static struct cpuidle_state_attr attr_##_name = __ATTR(_name, 0444, show, NULL)
+
+#define define_show_state_function(_name) \
+static ssize_t show_state_##_name(struct cpuidle_state *state, char *buf) \
+{ \
+       return sprintf(buf, "%u\n", state->_name);\
+}
+
+static ssize_t show_state_name(struct cpuidle_state *state, char *buf)
+{
+       return sprintf(buf, "%s\n", state->name);
+}
+
+define_show_state_function(exit_latency)
+define_show_state_function(power_usage)
+define_show_state_function(usage)
+define_show_state_function(time)
+define_one_state_ro(name, show_state_name);
+define_one_state_ro(latency, show_state_exit_latency);
+define_one_state_ro(power, show_state_power_usage);
+define_one_state_ro(usage, show_state_usage);
+define_one_state_ro(time, show_state_time);
+
+static struct attribute *cpuidle_state_default_attrs[] = {
+       &attr_name.attr,
+       &attr_latency.attr,
+       &attr_power.attr,
+       &attr_usage.attr,
+       &attr_time.attr,
+       NULL
+};
+
+#define kobj_to_state_obj(k) container_of(k, struct cpuidle_state_kobj, kobj)
+#define kobj_to_state(k) (kobj_to_state_obj(k)->state)
+#define attr_to_stateattr(a) container_of(a, struct cpuidle_state_attr, attr)
+static ssize_t cpuidle_state_show(struct kobject * kobj,
+       struct attribute * attr ,char * buf)
+{
+       int ret = -EIO;
+       struct cpuidle_state *state = kobj_to_state(kobj);
+       struct cpuidle_state_attr * cattr = attr_to_stateattr(attr);
+
+       if (cattr->show)
+               ret = cattr->show(state, buf);
+
+       return ret;
+}
+
+static struct sysfs_ops cpuidle_state_sysfs_ops = {
+       .show = cpuidle_state_show,
+};
+
+static void cpuidle_state_sysfs_release(struct kobject *kobj)
+{
+       struct cpuidle_state_kobj *state_obj = kobj_to_state_obj(kobj);
+
+       complete(&state_obj->kobj_unregister);
+}
+
+static struct kobj_type ktype_state_cpuidle = {
+       .sysfs_ops = &cpuidle_state_sysfs_ops,
+       .default_attrs = cpuidle_state_default_attrs,
+       .release = cpuidle_state_sysfs_release,
+};
+
+static void inline cpuidle_free_state_kobj(struct cpuidle_device *device, int i)
+{
+       kobject_unregister(&device->kobjs[i]->kobj);
+       wait_for_completion(&device->kobjs[i]->kobj_unregister);
+       kfree(device->kobjs[i]);
+       device->kobjs[i] = NULL;
+}
+
+/**
+ * cpuidle_add_driver_sysfs - adds driver-specific sysfs attributes
+ * @device: the target device
+ */
+int cpuidle_add_state_sysfs(struct cpuidle_device *device)
+{
+       int i, ret = -ENOMEM;
+       struct cpuidle_state_kobj *kobj;
+
+       /* state statistics */
+       for (i = 0; i < device->state_count; i++) {
+               kobj = kzalloc(sizeof(struct cpuidle_state_kobj), GFP_KERNEL);
+               if (!kobj)
+                       goto error_state;
+               kobj->state = &device->states[i];
+               init_completion(&kobj->kobj_unregister);
+
+               kobj->kobj.parent = &device->kobj;
+               kobj->kobj.ktype = &ktype_state_cpuidle;
+               kobject_set_name(&kobj->kobj, "state%d", i);
+               ret = kobject_register(&kobj->kobj);
+               if (ret) {
+                       kfree(kobj);
+                       goto error_state;
+               }
+               device->kobjs[i] = kobj;
+       }
+
+       return 0;
+
+error_state:
+       for (i = i - 1; i >= 0; i--)
+               cpuidle_free_state_kobj(device, i);
+       return ret;
+}
+
+/**
+ * cpuidle_remove_driver_sysfs - removes driver-specific sysfs attributes
+ * @device: the target device
+ */
+void cpuidle_remove_state_sysfs(struct cpuidle_device *device)
+{
+       int i;
+
+       for (i = 0; i < device->state_count; i++)
+               cpuidle_free_state_kobj(device, i);
+}
+
+/**
+ * cpuidle_add_sysfs - creates a sysfs instance for the target device
+ * @sysdev: the target device
+ */
+int cpuidle_add_sysfs(struct sys_device *sysdev)
+{
+       int cpu = sysdev->id;
+       struct cpuidle_device *dev;
+
+       dev = per_cpu(cpuidle_devices, cpu);
+       dev->kobj.parent = &sysdev->kobj;
+       dev->kobj.ktype = &ktype_cpuidle;
+       kobject_set_name(&dev->kobj, "%s", "cpuidle");
+       return kobject_register(&dev->kobj);
+}
+
+/**
+ * cpuidle_remove_sysfs - deletes a sysfs instance on the target device
+ * @sysdev: the target device
+ */
+void cpuidle_remove_sysfs(struct sys_device *sysdev)
+{
+       int cpu = sysdev->id;
+       struct cpuidle_device *dev;
+
+       dev = per_cpu(cpuidle_devices, cpu);
+       kobject_unregister(&dev->kobj);
+}
index f7276bf2fe7eaa05051efc507e47387c9c8eda02..f204c39fb412e2c25469ffbe41dc7e483d65096d 100644 (file)
@@ -34,7 +34,7 @@
 #include "ioatdma_registers.h"
 #include "ioatdma_hw.h"
 
-MODULE_VERSION("1.24");
+MODULE_VERSION(IOAT_DMA_VERSION);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Intel Corporation");
 
@@ -55,9 +55,7 @@ struct ioat_device {
 
 static int __devinit ioat_probe(struct pci_dev *pdev,
                                const struct pci_device_id *id);
-#ifdef IOAT_DMA_REMOVE
 static void __devexit ioat_remove(struct pci_dev *pdev);
-#endif
 
 static int ioat_dca_enabled = 1;
 module_param(ioat_dca_enabled, int, 0644);
@@ -73,7 +71,7 @@ static int ioat_setup_functionality(struct pci_dev *pdev, void __iomem *iobase)
        switch (version) {
        case IOAT_VER_1_2:
                device->dma = ioat_dma_probe(pdev, iobase);
-               if (ioat_dca_enabled)
+               if (device->dma && ioat_dca_enabled)
                        device->dca = ioat_dca_init(pdev, iobase);
                break;
        default:
@@ -87,27 +85,25 @@ static void ioat_shutdown_functionality(struct pci_dev *pdev)
 {
        struct ioat_device *device = pci_get_drvdata(pdev);
 
-       if (device->dma) {
-               ioat_dma_remove(device->dma);
-               device->dma = NULL;
-       }
-
+       dev_err(&pdev->dev, "Removing dma and dca services\n");
        if (device->dca) {
                unregister_dca_provider(device->dca);
                free_dca_provider(device->dca);
                device->dca = NULL;
        }
 
+       if (device->dma) {
+               ioat_dma_remove(device->dma);
+               device->dma = NULL;
+       }
 }
 
-static struct pci_driver ioat_pci_drv = {
+static struct pci_driver ioat_pci_driver = {
        .name           = "ioatdma",
        .id_table       = ioat_pci_tbl,
        .probe          = ioat_probe,
        .shutdown       = ioat_shutdown_functionality,
-#ifdef IOAT_DMA_REMOVE
        .remove         = __devexit_p(ioat_remove),
-#endif
 };
 
 static int __devinit ioat_probe(struct pci_dev *pdev,
@@ -122,7 +118,7 @@ static int __devinit ioat_probe(struct pci_dev *pdev,
        if (err)
                goto err_enable_device;
 
-       err = pci_request_regions(pdev, ioat_pci_drv.name);
+       err = pci_request_regions(pdev, ioat_pci_driver.name);
        if (err)
                goto err_request_regions;
 
@@ -176,13 +172,11 @@ err_enable_device:
        return err;
 }
 
-#ifdef IOAT_DMA_REMOVE
 /*
  * It is unsafe to remove this module: if removed while a requested
  * dma is outstanding, esp. from tcp, it is possible to hang while
- * waiting for something that will never finish, thus hanging at
- * least one cpu.  However, if you're feeling lucky and need to do
- * some testing, this usually works just fine.
+ * waiting for something that will never finish.  However, if you're
+ * feeling lucky, this usually works just fine.
  */
 static void __devexit ioat_remove(struct pci_dev *pdev)
 {
@@ -191,21 +185,16 @@ static void __devexit ioat_remove(struct pci_dev *pdev)
        ioat_shutdown_functionality(pdev);
 
        kfree(device);
-
-       iounmap(device->iobase);
-       pci_release_regions(pdev);
-       pci_disable_device(pdev);
 }
-#endif
 
 static int __init ioat_init_module(void)
 {
-       return pci_register_driver(&ioat_pci_drv);
+       return pci_register_driver(&ioat_pci_driver);
 }
 module_init(ioat_init_module);
 
 static void __exit ioat_exit_module(void)
 {
-       pci_unregister_driver(&ioat_pci_drv);
+       pci_unregister_driver(&ioat_pci_driver);
 }
 module_exit(ioat_exit_module);
index 2ae04c30edebba365cc956ad81e9d5d64deb7c06..ba985715b80306fe568018c59ffe016a1404db24 100644 (file)
@@ -65,7 +65,7 @@ static inline u16 dcaid_from_pcidev(struct pci_dev *pci)
        return (pci->bus->number << 8) | pci->devfn;
 }
 
-static int dca_enabled_in_bios(void)
+static int dca_enabled_in_bios(struct pci_dev *pdev)
 {
        /* CPUID level 9 returns DCA configuration */
        /* Bit 0 indicates DCA enabled by the BIOS */
@@ -75,17 +75,17 @@ static int dca_enabled_in_bios(void)
        cpuid_level_9 = cpuid_eax(9);
        res = test_bit(0, &cpuid_level_9);
        if (!res)
-               printk(KERN_ERR "ioat dma: DCA is disabled in BIOS\n");
+               dev_err(&pdev->dev, "DCA is disabled in BIOS\n");
 
        return res;
 }
 
-static int system_has_dca_enabled(void)
+static int system_has_dca_enabled(struct pci_dev *pdev)
 {
        if (boot_cpu_has(X86_FEATURE_DCA))
-               return dca_enabled_in_bios();
+               return dca_enabled_in_bios(pdev);
 
-       printk(KERN_ERR "ioat dma: boot cpu doesn't have X86_FEATURE_DCA\n");
+       dev_err(&pdev->dev, "boot cpu doesn't have X86_FEATURE_DCA\n");
        return 0;
 }
 
@@ -208,7 +208,7 @@ struct dca_provider *ioat_dca_init(struct pci_dev *pdev, void __iomem *iobase)
        int i;
        int err;
 
-       if (!system_has_dca_enabled())
+       if (!system_has_dca_enabled(pdev))
                return NULL;
 
        /* I/OAT v1 systems must have a known tag_map to support DCA */
index 66c5bb53211bceef2f3494a9a43fc4f9d4b6724e..7e4a785c2dff6fdb5d1640e9b0499974f27f8cc5 100644 (file)
 /* internal functions */
 static void ioat_dma_start_null_desc(struct ioat_dma_chan *ioat_chan);
 static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan);
+static struct ioat_desc_sw *
+ioat_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan);
 
-static struct ioat_dma_chan *ioat_lookup_chan_by_index(struct ioatdma_device *device,
-                                                      int index)
+static inline struct ioat_dma_chan *ioat_lookup_chan_by_index(
+                                               struct ioatdma_device *device,
+                                               int index)
 {
        return device->idx[index];
 }
@@ -148,57 +151,102 @@ static void ioat_set_src(dma_addr_t addr,
                         struct dma_async_tx_descriptor *tx,
                         int index)
 {
-       struct ioat_desc_sw *iter, *desc = tx_to_ioat_desc(tx);
-       struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan);
-
-       pci_unmap_addr_set(desc, src, addr);
-
-       list_for_each_entry(iter, &desc->async_tx.tx_list, node) {
-               iter->hw->src_addr = addr;
-               addr += ioat_chan->xfercap;
-       }
-
+       tx_to_ioat_desc(tx)->src = addr;
 }
 
 static void ioat_set_dest(dma_addr_t addr,
                          struct dma_async_tx_descriptor *tx,
                          int index)
 {
-       struct ioat_desc_sw *iter, *desc = tx_to_ioat_desc(tx);
-       struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan);
-
-       pci_unmap_addr_set(desc, dst, addr);
-
-       list_for_each_entry(iter, &desc->async_tx.tx_list, node) {
-               iter->hw->dst_addr = addr;
-               addr += ioat_chan->xfercap;
-       }
+       tx_to_ioat_desc(tx)->dst = addr;
 }
 
 static dma_cookie_t ioat_tx_submit(struct dma_async_tx_descriptor *tx)
 {
        struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan);
-       struct ioat_desc_sw *desc = tx_to_ioat_desc(tx);
+       struct ioat_desc_sw *first = tx_to_ioat_desc(tx);
+       struct ioat_desc_sw *prev, *new;
+       struct ioat_dma_descriptor *hw;
        int append = 0;
        dma_cookie_t cookie;
-       struct ioat_desc_sw *group_start;
+       LIST_HEAD(new_chain);
+       u32 copy;
+       size_t len;
+       dma_addr_t src, dst;
+       int orig_ack;
+       unsigned int desc_count = 0;
+
+       /* src and dest and len are stored in the initial descriptor */
+       len = first->len;
+       src = first->src;
+       dst = first->dst;
+       orig_ack = first->async_tx.ack;
+       new = first;
 
-       group_start = list_entry(desc->async_tx.tx_list.next,
-                                struct ioat_desc_sw, node);
        spin_lock_bh(&ioat_chan->desc_lock);
+       prev = to_ioat_desc(ioat_chan->used_desc.prev);
+       prefetch(prev->hw);
+       do {
+               copy = min((u32) len, ioat_chan->xfercap);
+
+               new->async_tx.ack = 1;
+
+               hw = new->hw;
+               hw->size = copy;
+               hw->ctl = 0;
+               hw->src_addr = src;
+               hw->dst_addr = dst;
+               hw->next = 0;
+
+               /* chain together the physical address list for the HW */
+               wmb();
+               prev->hw->next = (u64) new->async_tx.phys;
+
+               len -= copy;
+               dst += copy;
+               src += copy;
+
+               list_add_tail(&new->node, &new_chain);
+               desc_count++;
+               prev = new;
+       } while (len && (new = ioat_dma_get_next_descriptor(ioat_chan)));
+
+       hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
+       if (new->async_tx.callback) {
+               hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN;
+               if (first != new) {
+                       /* move callback into to last desc */
+                       new->async_tx.callback = first->async_tx.callback;
+                       new->async_tx.callback_param
+                                       = first->async_tx.callback_param;
+                       first->async_tx.callback = NULL;
+                       first->async_tx.callback_param = NULL;
+               }
+       }
+
+       new->tx_cnt = desc_count;
+       new->async_tx.ack = orig_ack; /* client is in control of this ack */
+
+       /* store the original values for use in later cleanup */
+       if (new != first) {
+               new->src = first->src;
+               new->dst = first->dst;
+               new->len = first->len;
+       }
+
        /* cookie incr and addition to used_list must be atomic */
        cookie = ioat_chan->common.cookie;
        cookie++;
        if (cookie < 0)
                cookie = 1;
-       ioat_chan->common.cookie = desc->async_tx.cookie = cookie;
+       ioat_chan->common.cookie = new->async_tx.cookie = cookie;
 
        /* write address into NextDescriptor field of last desc in chain */
        to_ioat_desc(ioat_chan->used_desc.prev)->hw->next =
-                                               group_start->async_tx.phys;
-       list_splice_init(&desc->async_tx.tx_list, ioat_chan->used_desc.prev);
+                                                       first->async_tx.phys;
+       __list_splice(&new_chain, ioat_chan->used_desc.prev);
 
-       ioat_chan->pending += desc->tx_cnt;
+       ioat_chan->pending += desc_count;
        if (ioat_chan->pending >= 4) {
                append = 1;
                ioat_chan->pending = 0;
@@ -267,7 +315,7 @@ static int ioat_dma_alloc_chan_resources(struct dma_chan *chan)
        chanerr = readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET);
        if (chanerr) {
                dev_err(&ioat_chan->device->pdev->dev,
-                       "ioatdma: CHANERR = %x, clearing\n", chanerr);
+                       "CHANERR = %x, clearing\n", chanerr);
                writel(chanerr, ioat_chan->reg_base + IOAT_CHANERR_OFFSET);
        }
 
@@ -276,7 +324,7 @@ static int ioat_dma_alloc_chan_resources(struct dma_chan *chan)
                desc = ioat_dma_alloc_descriptor(ioat_chan, GFP_KERNEL);
                if (!desc) {
                        dev_err(&ioat_chan->device->pdev->dev,
-                               "ioatdma: Only %d initial descriptors\n", i);
+                               "Only %d initial descriptors\n", i);
                        break;
                }
                list_add_tail(&desc->node, &tmp_list);
@@ -342,12 +390,13 @@ static void ioat_dma_free_chan_resources(struct dma_chan *chan)
        /* one is ok since we left it on there on purpose */
        if (in_use_descs > 1)
                dev_err(&ioat_chan->device->pdev->dev,
-                       "ioatdma: Freeing %d in use descriptors!\n",
+                       "Freeing %d in use descriptors!\n",
                        in_use_descs - 1);
 
        ioat_chan->last_completion = ioat_chan->completion_addr = 0;
        ioat_chan->pending = 0;
 }
+
 /**
  * ioat_dma_get_next_descriptor - return the next available descriptor
  * @ioat_chan: IOAT DMA channel handle
@@ -356,8 +405,8 @@ static void ioat_dma_free_chan_resources(struct dma_chan *chan)
  * channel's desc_lock held.  Allocates more descriptors if the channel
  * has run out.
  */
-static struct ioat_desc_sw *ioat_dma_get_next_descriptor(
-                                               struct ioat_dma_chan *ioat_chan)
+static struct ioat_desc_sw *
+ioat_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan)
 {
        struct ioat_desc_sw *new = NULL;
 
@@ -382,51 +431,11 @@ static struct dma_async_tx_descriptor *ioat_dma_prep_memcpy(
                                                int int_en)
 {
        struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
-       struct ioat_desc_sw *first, *prev, *new;
-       LIST_HEAD(new_chain);
-       u32 copy;
-       size_t orig_len;
-       int desc_count = 0;
-
-       if (!len)
-               return NULL;
-
-       orig_len = len;
-
-       first = NULL;
-       prev = NULL;
+       struct ioat_desc_sw *new;
 
        spin_lock_bh(&ioat_chan->desc_lock);
-       while (len) {
-               new = ioat_dma_get_next_descriptor(ioat_chan);
-               copy = min((u32) len, ioat_chan->xfercap);
-
-               new->hw->size = copy;
-               new->hw->ctl = 0;
-               new->async_tx.cookie = 0;
-               new->async_tx.ack = 1;
-
-               /* chain together the physical address list for the HW */
-               if (!first)
-                       first = new;
-               else
-                       prev->hw->next = (u64) new->async_tx.phys;
-
-               prev = new;
-               len  -= copy;
-               list_add_tail(&new->node, &new_chain);
-               desc_count++;
-       }
-
-       list_splice(&new_chain, &new->async_tx.tx_list);
-
-       new->hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
-       new->hw->next = 0;
-       new->tx_cnt = desc_count;
-       new->async_tx.ack = 0; /* client is in control of this ack */
-       new->async_tx.cookie = -EBUSY;
-
-       pci_unmap_len_set(new, len, orig_len);
+       new = ioat_dma_get_next_descriptor(ioat_chan);
+       new->len = len;
        spin_unlock_bh(&ioat_chan->desc_lock);
 
        return new ? &new->async_tx : NULL;
@@ -464,7 +473,7 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan)
 
        prefetch(ioat_chan->completion_virt);
 
-       if (!spin_trylock(&ioat_chan->cleanup_lock))
+       if (!spin_trylock_bh(&ioat_chan->cleanup_lock))
                return;
 
        /* The completion writeback can happen at any time,
@@ -474,22 +483,25 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan)
 
 #if (BITS_PER_LONG == 64)
        phys_complete =
-       ioat_chan->completion_virt->full & IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR;
+               ioat_chan->completion_virt->full
+               & IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR;
 #else
-       phys_complete = ioat_chan->completion_virt->low & IOAT_LOW_COMPLETION_MASK;
+       phys_complete =
+               ioat_chan->completion_virt->low & IOAT_LOW_COMPLETION_MASK;
 #endif
 
-       if ((ioat_chan->completion_virt->full & IOAT_CHANSTS_DMA_TRANSFER_STATUS) ==
+       if ((ioat_chan->completion_virt->full
+               & IOAT_CHANSTS_DMA_TRANSFER_STATUS) ==
                                IOAT_CHANSTS_DMA_TRANSFER_STATUS_HALTED) {
                dev_err(&ioat_chan->device->pdev->dev,
-                       "ioatdma: Channel halted, chanerr = %x\n",
+                       "Channel halted, chanerr = %x\n",
                        readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET));
 
                /* TODO do something to salvage the situation */
        }
 
        if (phys_complete == ioat_chan->last_completion) {
-               spin_unlock(&ioat_chan->cleanup_lock);
+               spin_unlock_bh(&ioat_chan->cleanup_lock);
                return;
        }
 
@@ -517,6 +529,11 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan)
                                        pci_unmap_addr(desc, src),
                                        pci_unmap_len(desc, len),
                                        PCI_DMA_TODEVICE);
+                       if (desc->async_tx.callback) {
+                               desc->async_tx.callback(
+                                               desc->async_tx.callback_param);
+                               desc->async_tx.callback = NULL;
+                       }
                }
 
                if (desc->async_tx.phys != phys_complete) {
@@ -548,7 +565,7 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan)
        if (cookie != 0)
                ioat_chan->completed_cookie = cookie;
 
-       spin_unlock(&ioat_chan->cleanup_lock);
+       spin_unlock_bh(&ioat_chan->cleanup_lock);
 }
 
 static void ioat_dma_dependency_added(struct dma_chan *chan)
@@ -613,8 +630,13 @@ static void ioat_dma_start_null_desc(struct ioat_dma_chan *ioat_chan)
        spin_lock_bh(&ioat_chan->desc_lock);
 
        desc = ioat_dma_get_next_descriptor(ioat_chan);
-       desc->hw->ctl = IOAT_DMA_DESCRIPTOR_NUL;
+       desc->hw->ctl = IOAT_DMA_DESCRIPTOR_NUL
+                               | IOAT_DMA_DESCRIPTOR_CTL_INT_GN
+                               | IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
        desc->hw->next = 0;
+       desc->hw->size = 0;
+       desc->hw->src_addr = 0;
+       desc->hw->dst_addr = 0;
        desc->async_tx.ack = 1;
 
        list_add_tail(&desc->node, &ioat_chan->used_desc);
@@ -633,6 +655,12 @@ static void ioat_dma_start_null_desc(struct ioat_dma_chan *ioat_chan)
  */
 #define IOAT_TEST_SIZE 2000
 
+static void ioat_dma_test_callback(void *dma_async_param)
+{
+       printk(KERN_ERR "ioatdma: ioat_dma_test_callback(%p)\n",
+                       dma_async_param);
+}
+
 /**
  * ioat_dma_self_test - Perform a IOAT transaction to verify the HW works.
  * @device: device to be tested
@@ -643,7 +671,7 @@ static int ioat_dma_self_test(struct ioatdma_device *device)
        u8 *src;
        u8 *dest;
        struct dma_chan *dma_chan;
-       struct dma_async_tx_descriptor *tx;
+       struct dma_async_tx_descriptor *tx = NULL;
        dma_addr_t addr;
        dma_cookie_t cookie;
        int err = 0;
@@ -673,6 +701,13 @@ static int ioat_dma_self_test(struct ioatdma_device *device)
        }
 
        tx = ioat_dma_prep_memcpy(dma_chan, IOAT_TEST_SIZE, 0);
+       if (!tx) {
+               dev_err(&device->pdev->dev,
+                       "Self-test prep failed, disabling\n");
+               err = -ENODEV;
+               goto free_resources;
+       }
+
        async_tx_ack(tx);
        addr = dma_map_single(dma_chan->device->dev, src, IOAT_TEST_SIZE,
                        DMA_TO_DEVICE);
@@ -680,19 +715,27 @@ static int ioat_dma_self_test(struct ioatdma_device *device)
        addr = dma_map_single(dma_chan->device->dev, dest, IOAT_TEST_SIZE,
                        DMA_FROM_DEVICE);
        ioat_set_dest(addr, tx, 0);
+       tx->callback = ioat_dma_test_callback;
+       tx->callback_param = (void *)0x8086;
        cookie = ioat_tx_submit(tx);
+       if (cookie < 0) {
+               dev_err(&device->pdev->dev,
+                       "Self-test setup failed, disabling\n");
+               err = -ENODEV;
+               goto free_resources;
+       }
        ioat_dma_memcpy_issue_pending(dma_chan);
        msleep(1);
 
        if (ioat_dma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) {
                dev_err(&device->pdev->dev,
-                       "ioatdma: Self-test copy timed out, disabling\n");
+                       "Self-test copy timed out, disabling\n");
                err = -ENODEV;
                goto free_resources;
        }
        if (memcmp(src, dest, IOAT_TEST_SIZE)) {
                dev_err(&device->pdev->dev,
-                       "ioatdma: Self-test copy failed compare, disabling\n");
+                       "Self-test copy failed compare, disabling\n");
                err = -ENODEV;
                goto free_resources;
        }
@@ -730,6 +773,9 @@ static int ioat_dma_setup_interrupts(struct ioatdma_device *device)
                goto msi;
        if (!strcmp(ioat_interrupt_style, "intx"))
                goto intx;
+       dev_err(&device->pdev->dev, "invalid ioat_interrupt_style %s\n",
+               ioat_interrupt_style);
+       goto err_no_irq;
 
 msix:
        /* The number of MSI-X vectors should equal the number of channels */
@@ -906,9 +952,9 @@ struct ioatdma_device *ioat_dma_probe(struct pci_dev *pdev,
        device->common.device_dependency_added = ioat_dma_dependency_added;
        device->common.dev = &pdev->dev;
        dev_err(&device->pdev->dev,
-               "ioatdma: Intel(R) I/OAT DMA Engine found,"
-               " %d channels, device version 0x%02x\n",
-               device->common.chancnt, device->version);
+               "Intel(R) I/OAT DMA Engine found,"
+               " %d channels, device version 0x%02x, driver version %s\n",
+               device->common.chancnt, device->version, IOAT_DMA_VERSION);
 
        err = ioat_dma_setup_interrupts(device);
        if (err)
@@ -931,9 +977,8 @@ err_completion_pool:
 err_dma_pool:
        kfree(device);
 err_kzalloc:
-       iounmap(iobase);
        dev_err(&device->pdev->dev,
-               "ioatdma: Intel(R) I/OAT DMA Engine initialization failed\n");
+               "Intel(R) I/OAT DMA Engine initialization failed\n");
        return NULL;
 }
 
@@ -942,13 +987,17 @@ void ioat_dma_remove(struct ioatdma_device *device)
        struct dma_chan *chan, *_chan;
        struct ioat_dma_chan *ioat_chan;
 
-       dma_async_device_unregister(&device->common);
-
        ioat_dma_remove_interrupts(device);
 
+       dma_async_device_unregister(&device->common);
+
        pci_pool_destroy(device->dma_pool);
        pci_pool_destroy(device->completion_pool);
 
+       iounmap(device->reg_base);
+       pci_release_regions(device->pdev);
+       pci_disable_device(device->pdev);
+
        list_for_each_entry_safe(chan, _chan,
                                 &device->common.channels, device_node) {
                ioat_chan = to_ioat_chan(chan);
index 2a319e124ece8c492a74b99f9e070079a0664635..5f9881e7b0ed25bc2722ac67c3f2b2cd10a1ed4d 100644 (file)
@@ -28,6 +28,8 @@
 #include <linux/cache.h>
 #include <linux/pci_ids.h>
 
+#define IOAT_DMA_VERSION "1.26"
+
 enum ioat_interrupt {
        none = 0,
        msix_multi_vector = 1,
@@ -122,9 +124,9 @@ struct ioat_desc_sw {
        struct ioat_dma_descriptor *hw;
        struct list_head node;
        int tx_cnt;
-       DECLARE_PCI_UNMAP_LEN(len)
-       DECLARE_PCI_UNMAP_ADDR(src)
-       DECLARE_PCI_UNMAP_ADDR(dst)
+       size_t len;
+       dma_addr_t src;
+       dma_addr_t dst;
        struct dma_async_tx_descriptor async_tx;
 };
 
index e80af67664cc72829fbd0caad82a7ba50c60c5c2..2d23e304f5ec1083b9850e46fe817c74b4e78d00 100644 (file)
@@ -94,8 +94,6 @@ extern int edac_debug_level;
 
 #endif                         /* !CONFIG_EDAC_DEBUG */
 
-#define BIT(x) (1 << (x))
-
 #define PCI_VEND_DEV(vend, dev) PCI_VENDOR_ID_ ## vend, \
        PCI_DEVICE_ID_ ## vend ## _ ## dev
 
index e66cdd42a392f5eadeb84bfc20038e3818b835f0..9007d0677220cf3aef8a524608d345452820ba6b 100644 (file)
@@ -270,6 +270,7 @@ static void __devexit pasemi_edac_remove(struct pci_dev *pdev)
 
 static const struct pci_device_id pasemi_edac_pci_tbl[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa00a) },
+       { }
 };
 
 MODULE_DEVICE_TABLE(pci, pasemi_edac_pci_tbl);
index 2f307c4df33563217ae7acbb85ae4c89224b866c..67588326ae56e2a9810207415e15c09141fc0622 100644 (file)
@@ -606,7 +606,7 @@ static int
 at_context_queue_packet(struct context *ctx, struct fw_packet *packet)
 {
        struct fw_ohci *ohci = ctx->ohci;
-       dma_addr_t d_bus, payload_bus;
+       dma_addr_t d_bus, uninitialized_var(payload_bus);
        struct driver_data *driver_data;
        struct descriptor *d, *last;
        __le32 *header;
@@ -1459,7 +1459,7 @@ ohci_allocate_iso_context(struct fw_card *card, int type, size_t header_size)
        /* FIXME: We need a fallback for pre 1.1 OHCI. */
        if (callback == handle_ir_dualbuffer_packet &&
            ohci->version < OHCI_VERSION_1_1)
-               return ERR_PTR(-EINVAL);
+               return ERR_PTR(-ENOSYS);
 
        spin_lock_irqsave(&ohci->lock, flags);
        index = ffs(*mask) - 1;
@@ -1778,7 +1778,7 @@ ohci_queue_iso(struct fw_iso_context *base,
                                                         buffer, payload);
        else
                /* FIXME: Implement fallback for OHCI 1.0 controllers. */
-               return -EINVAL;
+               return -ENOSYS;
 }
 
 static const struct fw_card_driver ohci_driver = {
@@ -1898,7 +1898,12 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
        ohci->version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff;
        fw_notify("Added fw-ohci device %s, OHCI version %x.%x\n",
                  dev->dev.bus_id, ohci->version >> 16, ohci->version & 0xff);
-
+       if (ohci->version < OHCI_VERSION_1_1) {
+               fw_notify("    Isochronous I/O is not yet implemented for "
+                         "OHCI 1.0 chips.\n");
+               fw_notify("    Cameras, audio devices etc. won't work on "
+                         "this controller with this driver version.\n");
+       }
        return 0;
 
  fail_self_id:
index 9959b799dbe2f100351be40f5b44e564669e2ffb..c00d4a9b39e5861980d884823e9d46d41c18a61f 100644 (file)
@@ -228,7 +228,7 @@ fw_fill_request(struct fw_packet *packet, int tcode, int tlabel,
  *
  * @param card the card from which to send the request
  * @param tcode the tcode for this transaction.  Do not use
- *   TCODE_LOCK_REQUEST directly, insted use TCODE_LOCK_MASK_SWAP
+ *   TCODE_LOCK_REQUEST directly, instead use TCODE_LOCK_MASK_SWAP
  *   etc. to specify tcode and ext_tcode.
  * @param node_id the destination node ID (bus ID and PHY ID concatenated)
  * @param generation the generation for which node_id is valid
index dcdba0f1b32c835cdcd37d0d2cb975442ab31348..87bc3417de2745c62de30ddc88c9fc8cc6e5a8e1 100644 (file)
@@ -17,7 +17,6 @@
 #define _DCDBAS_H_
 
 #include <linux/device.h>
-#include <linux/input.h>
 #include <linux/sysfs.h>
 #include <linux/types.h>
 
index a702e2f6da7d953892a468574e8348e23397e735..1ca6f4635eeb3e0474abada594892ac5683ce7ba 100644 (file)
@@ -113,13 +113,13 @@ static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t
 
        if (count > HID_MIN_BUFFER_SIZE) {
                printk(KERN_WARNING "hidraw: pid %d passed too large report\n",
-                               current->pid);
+                               task_pid_nr(current));
                return -EINVAL;
        }
 
        if (count < 2) {
                printk(KERN_WARNING "hidraw: pid %d passed too short report\n",
-                               current->pid);
+                               task_pid_nr(current));
                return -EINVAL;
        }
 
index 22329feb3b5ae63d7b65a3e561f263da7935342d..4c210e16b1b4d5b0ef8f4a17e7a2e79be5061136 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: hid-ff.c,v 1.2 2002/04/18 22:02:47 jdeneux Exp $
- *
  *  Force feedback support for hid devices.
  *  Not all hid devices use the same protocol. For example, some use PID,
  *  other use their own proprietary procotol.
index b76b02f7b52de04a11e17d2a17e0e80b850d9922..775a1ef28a297fc3035f484845917b55ba6c5b29 100644 (file)
@@ -274,8 +274,11 @@ static int usb_kbd_probe(struct usb_interface *iface,
 
        input_set_drvdata(input_dev, kbd);
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
-       input_dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL) | BIT(LED_COMPOSE) | BIT(LED_KANA);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_LED) |
+               BIT_MASK(EV_REP);
+       input_dev->ledbit[0] = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) |
+               BIT_MASK(LED_SCROLLL) | BIT_MASK(LED_COMPOSE) |
+               BIT_MASK(LED_KANA);
 
        for (i = 0; i < 255; i++)
                set_bit(usb_kbd_keycode[i], input_dev->keybit);
index 5345c73bcf622a2918df1982ba24749e2dfd0c68..f8ad6910d3d920ccec4f8cf66dcd6b737cbf958f 100644 (file)
@@ -173,11 +173,13 @@ static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_i
        usb_to_input_id(dev, &input_dev->id);
        input_dev->dev.parent = &intf->dev;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-       input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
-       input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
-       input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA);
-       input_dev->relbit[0] |= BIT(REL_WHEEL);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+       input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+               BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
+       input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
+       input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_SIDE) |
+               BIT_MASK(BTN_EXTRA);
+       input_dev->relbit[0] |= BIT_MASK(REL_WHEEL);
 
        input_set_drvdata(input_dev, mouse);
 
index aa875ca50d9bc1282771fe180907d6555d424c6b..3e63c148677095dc38ce5e67dab90355a40fda8d 100644 (file)
@@ -1651,7 +1651,7 @@ static int adm1026_detect(struct i2c_adapter *adapter, int address,
                break;
        default :
                dev_err(&adapter->dev, ": Internal error, invalid "
-                       "kind (%d)!", kind);
+                       "kind (%d)!\n", kind);
                err = -EFAULT;
                goto exitfree;
        }
index 4879125b4cdc1963534928181aed8088a30f3900..1001d2e122a262eafa72bb80857260bcc1659472 100644 (file)
@@ -1099,7 +1099,7 @@ static int applesmc_create_accelerometer(void)
        idev->name = "applesmc";
        idev->id.bustype = BUS_HOST;
        idev->dev.parent = &pdev->dev;
-       idev->evbit[0] = BIT(EV_ABS);
+       idev->evbit[0] = BIT_MASK(EV_ABS);
        input_set_abs_params(idev, ABS_X,
                        -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
        input_set_abs_params(idev, ABS_Y,
index 6f66551d9e51ab00f787dfe5c2d5d9182affd4bc..5c82ec7f8bbda7fea7ec8a1f81c14add4a25c6d8 100644 (file)
@@ -150,7 +150,7 @@ static struct coretemp_data *coretemp_update_device(struct device *dev)
 static int __devinit coretemp_probe(struct platform_device *pdev)
 {
        struct coretemp_data *data;
-       struct cpuinfo_x86 *c = &(cpu_data)[pdev->id];
+       struct cpuinfo_x86 *c = &cpu_data(pdev->id);
        int err;
        u32 eax, edx;
 
@@ -359,7 +359,7 @@ static int __init coretemp_init(void)
        struct pdev_entry *p, *n;
 
        /* quick check if we run Intel */
-       if (cpu_data[0].x86_vendor != X86_VENDOR_INTEL)
+       if (cpu_data(0).x86_vendor != X86_VENDOR_INTEL)
                goto exit;
 
        err = platform_driver_register(&coretemp_driver);
@@ -367,7 +367,7 @@ static int __init coretemp_init(void)
                goto exit;
 
        for_each_online_cpu(i) {
-               struct cpuinfo_x86 *c = &(cpu_data)[i];
+               struct cpuinfo_x86 *c = &cpu_data(i);
 
                /* check if family 6, models e, f, 16 */
                if ((c->cpuid_level < 0) || (c->x86 != 0x6) ||
index a3b56c816e11d3924c98698f6978802c27e6fc29..2d39d8fc2389fbc904fbc1c93632981efa7d1be5 100644 (file)
@@ -2,7 +2,7 @@
     gl520sm.c - Part of lm_sensors, Linux kernel modules for hardware
                 monitoring
     Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>,
-                              Kyösti Mälkki <kmalkki@cc.hut.fi>
+                              Kyösti Mälkki <kmalkki@cc.hut.fi>
     Copyright (c) 2005        Maarten Deprez <maartendeprez@users.sourceforge.net>
 
     This program is free software; you can redistribute it and/or modify
@@ -805,7 +805,7 @@ static void __exit sensors_gl520sm_exit(void)
 
 
 MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, "
-       "Kyösti Mälkki <kmalkki@cc.hut.fi>, "
+       "Kyösti Mälkki <kmalkki@cc.hut.fi>, "
        "Maarten Deprez <maartendeprez@users.sourceforge.net>");
 MODULE_DESCRIPTION("GL520SM driver");
 MODULE_LICENSE("GPL");
index 8a7ae03aeee4e5aa1adb629ce77055b10c2a1f77..bab5fd2e4dfdafd4442fa13bdd90f3a3f2022d39 100644 (file)
@@ -574,7 +574,7 @@ static int __init hdaps_init(void)
        idev = hdaps_idev->input;
        idev->name = "hdaps";
        idev->dev.parent = &pdev->dev;
-       idev->evbit[0] = BIT(EV_ABS);
+       idev->evbit[0] = BIT_MASK(EV_ABS);
        input_set_abs_params(idev, ABS_X,
                        -256, 256, HDAPS_INPUT_FUZZ, HDAPS_INPUT_FLAT);
        input_set_abs_params(idev, ABS_Y,
index f17e771e42f8aa6c699a21e429b0a1d557fbb048..3330667280b9aa5d5b3d9a7852934041a384bf8c 100644 (file)
@@ -200,7 +200,7 @@ static u8 find_vrm(u8 eff_family, u8 eff_model, u8 eff_stepping, u8 vendor)
 
 u8 vid_which_vrm(void)
 {
-       struct cpuinfo_x86 *c = cpu_data;
+       struct cpuinfo_x86 *c = &cpu_data(0);
        u32 eax;
        u8 eff_family, eff_model, eff_stepping, vrm_ret;
 
index f207434730de66f472d7e6203e4eb31b1752827d..650b07d5b902f997d3f887e0bc9c8ff978d5a911 100644 (file)
@@ -533,7 +533,7 @@ static void lm63_init_client(struct i2c_client *client)
 
        /* Start converting if needed */
        if (data->config & 0x40) { /* standby */
-               dev_dbg(&client->dev, "Switching to operational mode");
+               dev_dbg(&client->dev, "Switching to operational mode\n");
                data->config &= 0xA7;
                i2c_smbus_write_byte_data(client, LM63_REG_CONFIG1,
                                          data->config);
index 860b71ccbb86bde3e27dcc549303d8ea95ee76b8..7e2d9787babc4b5776ea262a84473f0d36824331 100644 (file)
@@ -3,7 +3,7 @@
                for hardware monitoring
 
     Copyright (C) 1998 - 2001 Frodo Looijaard <frodol@dds.nl>,
-                       Kyösti Mälkki <kmalkki@cc.hut.fi>, and
+                       Kyösti Mälkki <kmalkki@cc.hut.fi>, and
                        Mark D. Studebaker <mdsxyz123@yahoo.com>
     Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with
     the help of Jean Delvare <khali@linux-fr.org>
index 8f63dada6019347eb9ee40bb4f6ff8c8177ef738..2635bba1e3fc96f75fa2c7561f59c06486601ef6 100644 (file)
@@ -3,7 +3,7 @@
                for hardware monitoring
 
     Copyright (c) 1998 - 2002  Frodo Looijaard <frodol@dds.nl>,
-                       Kyösti Mälkki <kmalkki@cc.hut.fi>,
+                       Kyösti Mälkki <kmalkki@cc.hut.fi>,
                        Mark Studebaker <mdsxyz123@yahoo.com>,
                        and Bob Dougherty <bobd@stanford.edu>
     (Some conversion-factor data were contributed by Jonathan Teh Soon Yew
@@ -866,7 +866,7 @@ static void __exit sm_via686a_exit(void)
        }
 }
 
-MODULE_AUTHOR("Kyösti Mälkki <kmalkki@cc.hut.fi>, "
+MODULE_AUTHOR("Kyösti Mälkki <kmalkki@cc.hut.fi>, "
              "Mark Studebaker <mdsxyz123@yahoo.com> "
              "and Bob Dougherty <bobd@stanford.edu>");
 MODULE_DESCRIPTION("VIA 686A Sensor device");
index e69416465e6dbbe6fae9295d6fcde620568e26da..7dfcc8dd316dcadceb4362b13aaf877f9e0e7d79 100644 (file)
@@ -795,7 +795,7 @@ static ssize_t set_pwm_auto_point_pwm(struct device *dev,
 
        if ((val < 0) || (val > 255)) {
                dev_err(dev, "pwm value %ld is out of range. "
-                       "Choose a value between 0 and 255." , val);
+                       "Choose a value between 0 and 255.\n" , val);
                return -EINVAL;
        }
 
index b6f2ebf9f9cf54e4648c8772856bbd4f0952d0a7..a9c01a6f00571d0f39b9a0d6e2dbf3e483e54c5e 100644 (file)
@@ -1096,7 +1096,7 @@ static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind)
        if (kind == w83791d) {
                client_name = "w83791d";
        } else {
-               dev_err(dev, "w83791d: Internal error: unknown kind (%d)?!?",
+               dev_err(dev, "w83791d: Internal error: unknown kind (%d)?!?\n",
                        kind);
                goto error1;
        }
index f836198b705c231ef9d7eda88b92079365c9bdc8..007449d3e16ee4d5804a2ccf70759a56e8c4dcf1 100644 (file)
@@ -1385,8 +1385,8 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind)
        if (kind == w83792d) {
                client_name = "w83792d";
        } else {
-               dev_err(dev, "w83792d: Internal error: unknown"
-                                         " kind (%d)?!?", kind);
+               dev_err(dev, "w83792d: Internal error: unknown kind (%d)?!?\n",
+                       kind);
                goto ERROR1;
        }
 
index 7f0a0a62cf60fc2d9524a4c3bd113767c98f4c59..a37cb6b8593cf715c957d49a400d01209ff69187 100644 (file)
@@ -18,7 +18,7 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.               */
 /* ------------------------------------------------------------------------- */
 
-/* With some changes from Frodo Looijaard <frodol@dds.nl>, Kyösti Mälkki
+/* With some changes from Frodo Looijaard <frodol@dds.nl>, Kyösti Mälkki
    <kmalkki@cc.hut.fi> and Jean Delvare <khali@linux-fr.org> */
 
 #include <linux/kernel.h>
index 36fdf971f08092f1997268046d039aec98fe912d..2a16211f12e55dfe2aca3ca77848a694b05d652c 100644 (file)
@@ -350,7 +350,7 @@ static int pca_init(struct i2c_algo_pca_data *adap)
        pca_outw(adap, I2C_PCA_ADR, own << 1);
 
        pca_set_con(adap, I2C_PCA_CON_ENSIO | clock);
-       udelay(500); /* 500 µs for oscilator to stabilise */
+       udelay(500); /* 500 Âµs for oscilator to stabilise */
 
        return 0;
 }
index ecb2c2d7d540241745e27137f45da6b1cf52c081..ab2e6f3498b4a585cafcb84952bfa0113e27d123 100644 (file)
@@ -19,7 +19,7 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.               */
 /* ------------------------------------------------------------------------- */
 
-/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and 
+/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and
    Frodo Looijaard <frodol@dds.nl> ,and also from Martin Bailey
    <mbailey@littlefeet-inc.com> */
 
index de95c75efb41e71d2796107331913adb0f0a0d61..c466c6cfc2e53512c402f2eae138c625a1fb1e69 100644 (file)
@@ -278,7 +278,7 @@ config I2C_IXP2000
        depends on ARCH_IXP2000
        select I2C_ALGOBIT
        help
-         Say Y here if you have an Intel IXP2000(2400, 2800, 2850) based 
+         Say Y here if you have an Intel IXP2000 (2400, 2800, 2850) based 
          system and are using GPIO lines for an I2C bus.
 
          This support is also available as a module. If so, the module
@@ -293,8 +293,8 @@ config I2C_POWERMAC
        default y
        help
          This exposes the various PowerMac i2c interfaces to the linux i2c
-         layer and to userland. It is used by various drivers on the powemac
-         platform, thus should generally be enabled.
+         layer and to userland. It is used by various drivers on the PowerMac
+         platform, and should generally be enabled.
 
          This support is also available as a module.  If so, the module
          will be called i2c-powermac.
@@ -438,12 +438,12 @@ config I2C_SIMTEC
        tristate "Simtec Generic I2C interface"
        select I2C_ALGOBIT
        help
-         If you say yes to this option, support will be inclyded for
+         If you say yes to this option, support will be included for
          the Simtec Generic I2C interface. This driver is for the
          simple I2C bus used on newer Simtec products for general
          I2C, such as DDC on the Simtec BBD2016A.
 
-         This driver can also be build as a module. If so, the module
+         This driver can also be built as a module. If so, the module
          will be called i2c-simtec.
 
 config SCx200_I2C
index 804f0a551c055fd9447f6b75d6b364d19a89567e..b7a9977b025f31a492d632f8b57cb49930f05466 100644 (file)
@@ -19,7 +19,7 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.               */
 /* ------------------------------------------------------------------------- */
 
-/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
+/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
    Frodo Looijaard <frodol@dds.nl> */
 
 /* Partialy rewriten by Oleg I. Vdovikin for mmapped support of
index 9832f773651ddfba8324bce580ff4d6e5a6c8001..f9972f9651e45f3497386cae1d16a55686066eab 100644 (file)
@@ -7,7 +7,7 @@
     Copyright (c) 1999-2004 Geert Uytterhoeven <geert@linux-m68k.org>
 
     Based on i2c Support for Via Technologies 82C586B South Bridge
-    Copyright (c) 1998, 1999 Kyösti Mälkki <kmalkki@cc.hut.fi>
+    Copyright (c) 1998, 1999 Kyösti Mälkki <kmalkki@cc.hut.fi>
 
     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
index e08bacadd6bc2ae7adc0445341d8996eff6ddee5..9b43ff7270d0213db406e034ec486e78af984336 100644 (file)
@@ -18,7 +18,7 @@
  *     Copyright 1995-97 Simon G. Vogl
  *                1998-99 Hans Berglund
  *
- *     With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> 
+ *     With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi>
  *     and even Frodo Looijaard <frodol@dds.nl>
  *
  * This program is free software; you can redistribute  it and/or modify it
index e471e3bfdc1e08872dcc9d4dd23e1e81a5d422cd..89a30028ddb6e40d9cd00402936460e196a32f9b 100644 (file)
@@ -8,7 +8,7 @@
  * Tony Lindgren <tony@atomide.com> and Imre Deak <imre.deak@nokia.com>
  * Copyright (C) 2005 Nokia Corporation
  *
- * Cleaned up by Juha Yrjölä <juha.yrjola@nokia.com>
+ * Cleaned up by Juha Yrjölä <juha.yrjola@nokia.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
index 49a95e2887bc39221d63dd9c1511d54004cb3af2..c6faf9bdad18d1ddda022243a4de7cc29d83f185 100644 (file)
@@ -7,7 +7,7 @@
    Copyright (C) 1995-2000 Simon G. Vogl
    With some changes from:
    Frodo Looijaard <frodol@dds.nl>
-   Kyösti Mälkki <kmalkki@cc.hut.fi>
+   Kyösti Mälkki <kmalkki@cc.hut.fi>
    
    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
index 039a07fde908f679851fb990e1e6ad04667002fd..59ba2086d2f92ffd5aa9c3c866b362ff6232ed3f 100644 (file)
@@ -7,7 +7,7 @@
    Copyright (C) 1995-2000 Simon G. Vogl
    With some changes from:
    Frodo Looijaard <frodol@dds.nl>
-   Kyösti Mälkki <kmalkki@cc.hut.fi>
+   Kyösti Mälkki <kmalkki@cc.hut.fi>
    
    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
index 17cecf1ea79767ed701e49a3d974ccfb48fe84f3..be99c02ecac57e84c5616a073ea7821dd2809fdf 100644 (file)
@@ -591,18 +591,18 @@ static int pmcmsptwi_master_xfer(struct i2c_adapter *adap,
        if (msg->flags & I2C_M_TEN)
                pmcmsptwi_set_twi_config(&oldcfg, data);
 
-       dev_dbg(&adap->dev, "I2C %s of %d bytes ",
-               (msg->flags & I2C_M_RD) ? "read" : "write", msg->len);
+       dev_dbg(&adap->dev, "I2C %s of %d bytes %s\n",
+               (msg->flags & I2C_M_RD) ? "read" : "write", msg->len,
+               (ret == MSP_TWI_XFER_OK) ? "succeeded" : "failed");
+
        if (ret != MSP_TWI_XFER_OK) {
                /*
                 * TODO: We could potentially loop and retry in the case
                 * of MSP_TWI_XFER_TIMEOUT.
                 */
-               dev_dbg(&adap->dev, "failed\n");
                return -1;
        }
 
-       dev_dbg(&adap->dev, "succeeded\n");
        return 0;
 }
 
index 17376feb1acc6b95c29196ac538515b9a58ead4d..f8d0dff0de7eab4d77e06ae33794b510fb39817d 100644 (file)
@@ -575,7 +575,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev)
        else {
                freq_mhz = PNX_DEFAULT_FREQ;
                dev_info(&pdev->dev, "Setting bus frequency to default value: "
-                      "%d MHz", freq_mhz);
+                      "%d MHz\n", freq_mhz);
        }
 
        i2c_pnx->adapter->algo = &pnx_algorithm;
index 00fad11733ad09f4ea92370a2722d832ef426023..6426a61f8d4df16e19427cfca375d4313e1e09f4 100644 (file)
@@ -85,7 +85,7 @@ struct bits {
        const char *set;
        const char *unset;
 };
-#define BIT(m, s, u)   { .mask = m, .set = s, .unset = u }
+#define PXA_BIT(m, s, u)       { .mask = m, .set = s, .unset = u }
 
 static inline void
 decode_bits(const char *prefix, const struct bits *bits, int num, u32 val)
@@ -100,17 +100,17 @@ decode_bits(const char *prefix, const struct bits *bits, int num, u32 val)
 }
 
 static const struct bits isr_bits[] = {
-       BIT(ISR_RWM,    "RX",           "TX"),
-       BIT(ISR_ACKNAK, "NAK",          "ACK"),
-       BIT(ISR_UB,     "Bsy",          "Rdy"),
-       BIT(ISR_IBB,    "BusBsy",       "BusRdy"),
-       BIT(ISR_SSD,    "SlaveStop",    NULL),
-       BIT(ISR_ALD,    "ALD",          NULL),
-       BIT(ISR_ITE,    "TxEmpty",      NULL),
-       BIT(ISR_IRF,    "RxFull",       NULL),
-       BIT(ISR_GCAD,   "GenCall",      NULL),
-       BIT(ISR_SAD,    "SlaveAddr",    NULL),
-       BIT(ISR_BED,    "BusErr",       NULL),
+       PXA_BIT(ISR_RWM,        "RX",           "TX"),
+       PXA_BIT(ISR_ACKNAK,     "NAK",          "ACK"),
+       PXA_BIT(ISR_UB,         "Bsy",          "Rdy"),
+       PXA_BIT(ISR_IBB,        "BusBsy",       "BusRdy"),
+       PXA_BIT(ISR_SSD,        "SlaveStop",    NULL),
+       PXA_BIT(ISR_ALD,        "ALD",          NULL),
+       PXA_BIT(ISR_ITE,        "TxEmpty",      NULL),
+       PXA_BIT(ISR_IRF,        "RxFull",       NULL),
+       PXA_BIT(ISR_GCAD,       "GenCall",      NULL),
+       PXA_BIT(ISR_SAD,        "SlaveAddr",    NULL),
+       PXA_BIT(ISR_BED,        "BusErr",       NULL),
 };
 
 static void decode_ISR(unsigned int val)
@@ -120,21 +120,21 @@ static void decode_ISR(unsigned int val)
 }
 
 static const struct bits icr_bits[] = {
-       BIT(ICR_START,  "START",        NULL),
-       BIT(ICR_STOP,   "STOP",         NULL),
-       BIT(ICR_ACKNAK, "ACKNAK",       NULL),
-       BIT(ICR_TB,     "TB",           NULL),
-       BIT(ICR_MA,     "MA",           NULL),
-       BIT(ICR_SCLE,   "SCLE",         "scle"),
-       BIT(ICR_IUE,    "IUE",          "iue"),
-       BIT(ICR_GCD,    "GCD",          NULL),
-       BIT(ICR_ITEIE,  "ITEIE",        NULL),
-       BIT(ICR_IRFIE,  "IRFIE",        NULL),
-       BIT(ICR_BEIE,   "BEIE",         NULL),
-       BIT(ICR_SSDIE,  "SSDIE",        NULL),
-       BIT(ICR_ALDIE,  "ALDIE",        NULL),
-       BIT(ICR_SADIE,  "SADIE",        NULL),
-       BIT(ICR_UR,     "UR",           "ur"),
+       PXA_BIT(ICR_START,  "START",    NULL),
+       PXA_BIT(ICR_STOP,   "STOP",     NULL),
+       PXA_BIT(ICR_ACKNAK, "ACKNAK",   NULL),
+       PXA_BIT(ICR_TB,     "TB",       NULL),
+       PXA_BIT(ICR_MA,     "MA",       NULL),
+       PXA_BIT(ICR_SCLE,   "SCLE",     "scle"),
+       PXA_BIT(ICR_IUE,    "IUE",      "iue"),
+       PXA_BIT(ICR_GCD,    "GCD",      NULL),
+       PXA_BIT(ICR_ITEIE,  "ITEIE",    NULL),
+       PXA_BIT(ICR_IRFIE,  "IRFIE",    NULL),
+       PXA_BIT(ICR_BEIE,   "BEIE",     NULL),
+       PXA_BIT(ICR_SSDIE,  "SSDIE",    NULL),
+       PXA_BIT(ICR_ALDIE,  "ALDIE",    NULL),
+       PXA_BIT(ICR_SADIE,  "SADIE",    NULL),
+       PXA_BIT(ICR_UR,     "UR",               "ur"),
 };
 
 static void decode_ICR(unsigned int val)
index 81520868797b84e8f3915a8c23360660c7291022..61716f6b14dcd2435c1b65f0fe27e05fc4f090cb 100644 (file)
@@ -4,7 +4,7 @@
 
     i2c Support for Via Technologies 82C586B South Bridge
 
-    Copyright (c) 1998, 1999 Kyösti Mälkki <kmalkki@cc.hut.fi>
+    Copyright (c) 1998, 1999 Kyösti Mälkki <kmalkki@cc.hut.fi>
 
     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
@@ -176,7 +176,7 @@ static void __exit i2c_vt586b_exit(void)
 }
 
 
-MODULE_AUTHOR("Kyösti Mälkki <kmalkki@cc.hut.fi>");
+MODULE_AUTHOR("Kyösti Mälkki <kmalkki@cc.hut.fi>");
 MODULE_DESCRIPTION("i2c for Via vt82c586b southbridge");
 MODULE_LICENSE("GPL");
 
index edc275002f8087a2501251a37dc2c29e5b637838..c9ce77f13c0ed366e03704d2fc81d22142fe0ae8 100644 (file)
@@ -2,7 +2,7 @@
     i2c-viapro.c - Part of lm_sensors, Linux kernel modules for hardware
               monitoring
     Copyright (c) 1998 - 2002  Frodo Looijaard <frodol@dds.nl>,
-    Philip Edelbrock <phil@netroedge.com>, Kyösti Mälkki <kmalkki@cc.hut.fi>,
+    Philip Edelbrock <phil@netroedge.com>, Kyösti Mälkki <kmalkki@cc.hut.fi>,
     Mark D. Studebaker <mdsxyz123@yahoo.com>
     Copyright (C) 2005 - 2007  Jean Delvare <khali@linux-fr.org>
 
index 66436bae11acbcde6aa1074ea4ba3513073e5376..2dea0123a958577ad87a3095c159edf177d7050e 100644 (file)
@@ -1195,7 +1195,7 @@ static int menelaus_probe(struct i2c_client *client)
                err = request_irq(client->irq, menelaus_irq, IRQF_DISABLED,
                                  DRIVER_NAME, menelaus);
                if (err) {
-                       dev_dbg(&client->dev,  "can't get IRQ %d, err %d",
+                       dev_dbg(&client->dev,  "can't get IRQ %d, err %d\n",
                                        client->irq, err);
                        goto fail1;
                }
index e73d58c43f386a349856cdb95f2935510c2a79fe..1a4e8dc03b365dfb2e5b99fd3e56d617bbe4b113 100644 (file)
@@ -17,7 +17,7 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.               */
 /* ------------------------------------------------------------------------- */
 
-/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi>.
+/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi>.
    All SMBus-related things are written by Frodo Looijaard <frodol@dds.nl>
    SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> and
    Jean Delvare <khali@linux-fr.org> */
index 6d9fd92763f46bf853bacbf091c92be3d1294c92..6eaece96524eac2c9e7d709559c4c99f4eb8a2a1 100644 (file)
@@ -1056,6 +1056,9 @@ endif
 config BLK_DEV_IDEDMA
        def_bool BLK_DEV_IDEDMA_PCI || BLK_DEV_IDEDMA_PMAC || BLK_DEV_IDEDMA_ICS || BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
 
+config IDE_ARCH_OBSOLETE_INIT
+       def_bool ALPHA || (ARM && !ARCH_L7200) || BLACKFIN || X86 || IA64 || M32R || MIPS || PARISC || PPC || (SUPERH64 && BLK_DEV_IDEPCI) || SPARC
+
 endif
 
 config BLK_DEV_HD_ONLY
index f7449d04114a1b1e984917e35fb23755424abaf3..48db6167bb90f6005927590431ba56a231061cd3 100644 (file)
@@ -45,7 +45,7 @@ bastide_register(unsigned int base, unsigned int aux, int irq,
        hw.io_ports[IDE_CONTROL_OFFSET] = aux + (6 * 0x20);
        hw.irq = irq;
 
-       ide_register_hw(&hw, 0, hwif);
+       ide_register_hw(&hw, NULL, 0, hwif);
 
        return 0;
 }
index e4875cef78bbad6e229eb1fd5315f60ab4b32a7e..410a0d13e35e847ad8695a7e8585cbb3d322e72b 100644 (file)
@@ -316,27 +316,29 @@ static int icside_dma_end(ide_drive_t *drive)
 
        drive->waiting_for_dma = 0;
 
-       disable_dma(hwif->hw.dma);
+       disable_dma(state->dev->dma);
 
        /* Teardown mappings after DMA has completed. */
        dma_unmap_sg(state->dev, hwif->sg_table, hwif->sg_nents,
                     hwif->sg_dma_direction);
 
-       return get_dma_residue(hwif->hw.dma) != 0;
+       return get_dma_residue(state->dev->dma) != 0;
 }
 
 static void icside_dma_start(ide_drive_t *drive)
 {
        ide_hwif_t *hwif = HWIF(drive);
+       struct icside_state *state = hwif->hwif_data;
 
        /* We can not enable DMA on both channels simultaneously. */
-       BUG_ON(dma_channel_active(hwif->hw.dma));
-       enable_dma(hwif->hw.dma);
+       BUG_ON(dma_channel_active(state->dev->dma));
+       enable_dma(state->dev->dma);
 }
 
 static int icside_dma_setup(ide_drive_t *drive)
 {
        ide_hwif_t *hwif = HWIF(drive);
+       struct icside_state *state = hwif->hwif_data;
        struct request *rq = hwif->hwgroup->rq;
        unsigned int dma_mode;
 
@@ -348,7 +350,7 @@ static int icside_dma_setup(ide_drive_t *drive)
        /*
         * We can not enable DMA on both channels.
         */
-       BUG_ON(dma_channel_active(hwif->hw.dma));
+       BUG_ON(dma_channel_active(state->dev->dma));
 
        icside_build_sglist(drive, rq);
 
@@ -365,14 +367,14 @@ static int icside_dma_setup(ide_drive_t *drive)
        /*
         * Select the correct timing for this drive.
         */
-       set_dma_speed(hwif->hw.dma, drive->drive_data);
+       set_dma_speed(state->dev->dma, drive->drive_data);
 
        /*
         * Tell the DMA engine about the SG table and
         * data direction.
         */
-       set_dma_sg(hwif->hw.dma, hwif->sg_table, hwif->sg_nents);
-       set_dma_mode(hwif->hw.dma, dma_mode);
+       set_dma_sg(state->dev->dma, hwif->sg_table, hwif->sg_nents);
+       set_dma_mode(state->dev->dma, dma_mode);
 
        drive->waiting_for_dma = 1;
 
@@ -415,7 +417,6 @@ static void icside_dma_lost_irq(ide_drive_t *drive)
 
 static void icside_dma_init(ide_hwif_t *hwif)
 {
-       hwif->atapi_dma         = 1;
        hwif->mwdma_mask        = 7; /* MW0..2 */
        hwif->swdma_mask        = 7; /* SW0..2 */
 
@@ -439,40 +440,16 @@ static void icside_dma_init(ide_hwif_t *hwif)
 #define icside_dma_init(hwif)  (0)
 #endif
 
-static ide_hwif_t *icside_find_hwif(unsigned long dataport)
-{
-       ide_hwif_t *hwif;
-       int index;
-
-       for (index = 0; index < MAX_HWIFS; ++index) {
-               hwif = &ide_hwifs[index];
-               if (hwif->io_ports[IDE_DATA_OFFSET] == dataport)
-                       goto found;
-       }
-
-       for (index = 0; index < MAX_HWIFS; ++index) {
-               hwif = &ide_hwifs[index];
-               if (!hwif->io_ports[IDE_DATA_OFFSET])
-                       goto found;
-       }
-
-       hwif = NULL;
-found:
-       return hwif;
-}
-
 static ide_hwif_t *
 icside_setup(void __iomem *base, struct cardinfo *info, struct expansion_card *ec)
 {
        unsigned long port = (unsigned long)base + info->dataoffset;
        ide_hwif_t *hwif;
 
-       hwif = icside_find_hwif(port);
+       hwif = ide_find_port(port);
        if (hwif) {
                int i;
 
-               memset(&hwif->hw, 0, sizeof(hw_regs_t));
-
                /*
                 * Ensure we're using MMIO
                 */
@@ -480,13 +457,10 @@ icside_setup(void __iomem *base, struct cardinfo *info, struct expansion_card *e
                hwif->mmio = 1;
 
                for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
-                       hwif->hw.io_ports[i] = port;
                        hwif->io_ports[i] = port;
                        port += 1 << info->stepping;
                }
-               hwif->hw.io_ports[IDE_CONTROL_OFFSET] = (unsigned long)base + info->ctrloffset;
                hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)base + info->ctrloffset;
-               hwif->hw.irq  = ec->irq;
                hwif->irq     = ec->irq;
                hwif->noprobe = 0;
                hwif->chipset = ide_acorn;
@@ -501,6 +475,7 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec)
 {
        ide_hwif_t *hwif;
        void __iomem *base;
+       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 
        base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0);
        if (!base)
@@ -524,9 +499,9 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec)
 
        state->hwif[0] = hwif;
 
-       probe_hwif_init(hwif);
+       idx[0] = hwif->index;
 
-       ide_proc_register_port(hwif);
+       ide_device_add(idx);
 
        return 0;
 }
@@ -538,6 +513,7 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
        void __iomem *ioc_base, *easi_base;
        unsigned int sel = 0;
        int ret;
+       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 
        ioc_base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
        if (!ioc_base) {
@@ -593,7 +569,6 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
        hwif->serialized  = 1;
        hwif->config_data = (unsigned long)ioc_base;
        hwif->select_data = sel;
-       hwif->hw.dma      = ec->dma;
 
        mate->maskproc    = icside_maskproc;
        mate->channel     = 1;
@@ -602,18 +577,16 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
        mate->serialized  = 1;
        mate->config_data = (unsigned long)ioc_base;
        mate->select_data = sel | 1;
-       mate->hw.dma      = ec->dma;
 
        if (ec->dma != NO_DMA && !request_dma(ec->dma, hwif->name)) {
                icside_dma_init(hwif);
                icside_dma_init(mate);
        }
 
-       probe_hwif_init(hwif);
-       probe_hwif_init(mate);
+       idx[0] = hwif->index;
+       idx[1] = mate->index;
 
-       ide_proc_register_port(hwif);
-       ide_proc_register_port(mate);
+       ide_device_add(idx);
 
        return 0;
 
index bce2bec81413eafa8f9358bb81efc3306ca7ad83..8957cbadf5c2a8c5870800a54ebd1d4b6eebae70 100644 (file)
@@ -31,5 +31,5 @@ void __init ide_arm_init(void)
        memset(&hw, 0, sizeof(hw));
        ide_std_init_ports(&hw, IDE_ARM_IO, IDE_ARM_IO + 0x206);
        hw.irq = IDE_ARM_IRQ;
-       ide_register_hw(&hw, 1, NULL);
+       ide_register_hw(&hw, NULL, 1, NULL);
 }
index 83811af11610d91a371825ca5e937af6ec327927..0775a3afef4862d5e5b2b5646443cbcfdec1448c 100644 (file)
 
 #include <asm/ecard.h>
 
-/*
- * Something like this really should be in generic code, but isn't.
- */
 static ide_hwif_t *
 rapide_locate_hwif(void __iomem *base, void __iomem *ctrl, unsigned int sz, int irq)
 {
        unsigned long port = (unsigned long)base;
-       ide_hwif_t *hwif;
-       int index, i;
-
-       for (index = 0; index < MAX_HWIFS; ++index) {
-               hwif = ide_hwifs + index;
-               if (hwif->io_ports[IDE_DATA_OFFSET] == port)
-                       goto found;
-       }
-
-       for (index = 0; index < MAX_HWIFS; ++index) {
-               hwif = ide_hwifs + index;
-               if (hwif->io_ports[IDE_DATA_OFFSET] == 0)
-                       goto found;
-       }
+       ide_hwif_t *hwif = ide_find_port(port);
+       int i;
 
-       return NULL;
+       if (hwif == NULL)
+               goto out;
 
- found:
        for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
-               hwif->hw.io_ports[i] = port;
                hwif->io_ports[i] = port;
                port += sz;
        }
-       hwif->hw.io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
        hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
-       hwif->hw.irq = hwif->irq = irq;
+       hwif->irq = irq;
        hwif->mmio = 1;
        default_hwif_mmiops(hwif);
-
+out:
        return hwif;
 }
 
@@ -58,6 +41,7 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id)
        ide_hwif_t *hwif;
        void __iomem *base;
        int ret;
+       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 
        ret = ecard_request_resources(ec);
        if (ret)
@@ -74,8 +58,11 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id)
                hwif->hwif_data = base;
                hwif->gendev.parent = &ec->dev;
                hwif->noprobe = 0;
-               probe_hwif_init(hwif);
-               ide_proc_register_port(hwif);
+
+               idx[0] = hwif->index;
+
+               ide_device_add(idx);
+
                ecard_set_drvdata(ec, hwif);
                goto out;
        }
index 06c75f18eb8826e931336ab2b3929f29c312ef91..e196aefa2070c2f2c54e79498cfc1dcf5e19e419 100644 (file)
@@ -782,7 +782,7 @@ init_e100_ide (void)
                                ide_offsets,
                                0, 0, cris_ide_ack_intr,
                                ide_default_irq(0));
-               ide_register_hw(&hw, 1, &hwif);
+               ide_register_hw(&hw, NULL, 1, &hwif);
                hwif->mmio = 1;
                hwif->chipset = ide_etrax100;
                hwif->set_pio_mode = &cris_set_pio_mode;
@@ -805,6 +805,7 @@ init_e100_ide (void)
                hwif->dma_host_on = &cris_dma_on;
                hwif->dma_off_quietly = &cris_dma_off;
                hwif->cbl = ATA_CBL_PATA40;
+               hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA;
                hwif->pio_mask = ATA_PIO4,
                hwif->drives[0].autotune = 1;
                hwif->drives[1].autotune = 1;
@@ -934,11 +935,11 @@ static int cris_ide_build_dmatable (ide_drive_t *drive)
                 * than two possibly non-adjacent physical 4kB pages.
                 */
                /* group sequential buffers into one large buffer */
-               addr = page_to_phys(sg->page) + sg->offset;
+               addr = sg_phys(sg);
                size = sg_dma_len(sg);
                while (--i) {
                        sg = sg_next(sg);
-                       if ((addr + size) != page_to_phys(sg->page) + sg->offset)
+                       if ((addr + size) != sg_phys(sg))
                                break;
                        size += sg_dma_len(sg);
                }
index 6d26ad7360d52c35dd01ab897dafe24b8fd2dacd..4a49b5c59acb3949fa87656814678956b7855e17 100644 (file)
@@ -68,7 +68,6 @@ static inline void hw_setup(hw_regs_t *hw)
                hw->io_ports[i] = CONFIG_H8300_IDE_BASE + H8300_IDE_GAP*i;
        hw->io_ports[IDE_CONTROL_OFFSET] = CONFIG_H8300_IDE_ALT;
        hw->irq = EXT_IRQ0 + CONFIG_H8300_IDE_IRQ;
-       hw->dma = NO_DMA;
        hw->chipset = ide_generic;
 }
 
@@ -101,7 +100,7 @@ void __init h8300_ide_init(void)
        hw_setup(&hw);
 
        /* register if */
-       idx = ide_register_hw(&hw, 1, &hwif);
+       idx = ide_register_hw(&hw, NULL, 1, &hwif);
        if (idx == -1) {
                printk(KERN_ERR "ide-h8300: IDE I/F register failed\n");
                return;
index 1d5f6823101c26c2e73980c6705878956e68be85..89df48fdc69d7b6109098153813524862fe4bff1 100644 (file)
@@ -350,7 +350,7 @@ static int taskfile_load_raw(ide_drive_t *drive,
 
        memset(&args, 0, sizeof(ide_task_t));
        args.command_type = IDE_DRIVE_TASK_NO_DATA;
-       args.data_phase   = TASKFILE_IN;
+       args.data_phase   = TASKFILE_NO_DATA;
        args.handler      = &task_no_data_intr;
 
        /* convert gtf to IDE Taskfile */
index ca843522f91dc914e26f656e5011116f5f2b5ca0..57a5f63d6ae3ed46be61de6660ddd4a96f9034d8 100644 (file)
  *                       Reformat to match kernel tabbing style.
  *                       Add CDROM_GET_UPC ioctl.
  * 3.10  Apr 10, 1996 -- Fix compilation error with STANDARD_ATAPI.
- * 3.11  Apr 29, 1996 -- Patch from Heiko Eissfeldt <heiko@colossus.escape.de>
+ * 3.11  Apr 29, 1996 -- Patch from Heiko Eißfeldt <heiko@colossus.escape.de>
  *                       to remove redundant verify_area calls.
  * 3.12  May  7, 1996 -- Rudimentary changer support.  Based on patches
  *                        from Gerhard Zuber <zuber@berlin.snafu.de>.
  *                     - Minimize the TOC reading - only do it when we
  *                       know a media change has occurred.
  *                     - Moved all the CDROMREADx ioctls to the Uniform layer.
- *                     - Heiko Eissfeldt <heiko@colossus.escape.de> supplied
+ *                     - Heiko Eißfeldt <heiko@colossus.escape.de> supplied
  *                       some fixes for CDI.
  *                     - CD-ROM leaving door locked fix from Andries
  *                       Brouwer <Andries.Brouwer@cwi.nl>
@@ -2341,7 +2341,7 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
                   If we get an error for the regular case, we assume
                   a CDI without additional audio tracks. In this case
                   the readable TOC is empty (CDI tracks are not included)
-                  and only holds the Leadout entry. Heiko Eißfeldt */
+                  and only holds the Leadout entry. Heiko Eißfeldt */
                ntracks = 0;
                stat = cdrom_read_tocentry(drive, CDROM_LEADOUT, 1, 0,
                                           (char *)&toc->hdr,
index 92177ca48b4de7edb5e828339059fcb05e854490..00123d99527ab72c28ce29fd5d2f08b558211e78 100644 (file)
@@ -169,7 +169,7 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
 
        nsectors.all            = (u16) rq->nr_sectors;
 
-       if (hwif->no_lba48_dma && lba48 && dma) {
+       if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && lba48 && dma) {
                if (block + rq->nr_sectors > 1ULL << 28)
                        dma = 0;
                else
@@ -593,28 +593,12 @@ static int smart_enable(ide_drive_t *drive)
        return ide_raw_taskfile(drive, &args, NULL);
 }
 
-static int get_smart_values(ide_drive_t *drive, u8 *buf)
+static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd)
 {
        ide_task_t args;
 
        memset(&args, 0, sizeof(ide_task_t));
-       args.tfRegister[IDE_FEATURE_OFFSET]     = SMART_READ_VALUES;
-       args.tfRegister[IDE_NSECTOR_OFFSET]     = 0x01;
-       args.tfRegister[IDE_LCYL_OFFSET]        = SMART_LCYL_PASS;
-       args.tfRegister[IDE_HCYL_OFFSET]        = SMART_HCYL_PASS;
-       args.tfRegister[IDE_COMMAND_OFFSET]     = WIN_SMART;
-       args.command_type                       = IDE_DRIVE_TASK_IN;
-       args.data_phase                         = TASKFILE_IN;
-       args.handler                            = &task_in_intr;
-       (void) smart_enable(drive);
-       return ide_raw_taskfile(drive, &args, buf);
-}
-
-static int get_smart_thresholds(ide_drive_t *drive, u8 *buf)
-{
-       ide_task_t args;
-       memset(&args, 0, sizeof(ide_task_t));
-       args.tfRegister[IDE_FEATURE_OFFSET]     = SMART_READ_THRESHOLDS;
+       args.tfRegister[IDE_FEATURE_OFFSET]     = sub_cmd;
        args.tfRegister[IDE_NSECTOR_OFFSET]     = 0x01;
        args.tfRegister[IDE_LCYL_OFFSET]        = SMART_LCYL_PASS;
        args.tfRegister[IDE_HCYL_OFFSET]        = SMART_HCYL_PASS;
@@ -656,7 +640,7 @@ static int proc_idedisk_read_smart_thresholds
        ide_drive_t     *drive = (ide_drive_t *)data;
        int             len = 0, i = 0;
 
-       if (!get_smart_thresholds(drive, page)) {
+       if (get_smart_data(drive, page, SMART_READ_THRESHOLDS) == 0) {
                unsigned short *val = (unsigned short *) page;
                char *out = ((char *)val) + (SECTOR_WORDS * 4);
                page = out;
@@ -675,7 +659,7 @@ static int proc_idedisk_read_smart_values
        ide_drive_t     *drive = (ide_drive_t *)data;
        int             len = 0, i = 0;
 
-       if (!get_smart_values(drive, page)) {
+       if (get_smart_data(drive, page, SMART_READ_VALUES) == 0) {
                unsigned short *val = (unsigned short *) page;
                char *out = ((char *)val) + (SECTOR_WORDS * 4);
                page = out;
@@ -856,7 +840,7 @@ static int set_lba_addressing(ide_drive_t *drive, int arg)
 
        drive->addressing =  0;
 
-       if (HWIF(drive)->no_lba48)
+       if (drive->hwif->host_flags & IDE_HFLAG_NO_LBA48)
                return 0;
 
        if (!idedisk_supports_lba48(drive->id))
@@ -889,6 +873,7 @@ static inline void idedisk_add_settings(ide_drive_t *drive) { ; }
 
 static void idedisk_setup (ide_drive_t *drive)
 {
+       ide_hwif_t *hwif = drive->hwif;
        struct hd_driveid *id = drive->id;
        unsigned long long capacity;
 
@@ -909,7 +894,6 @@ static void idedisk_setup (ide_drive_t *drive)
        (void)set_lba_addressing(drive, 1);
 
        if (drive->addressing == 1) {
-               ide_hwif_t *hwif = HWIF(drive);
                int max_s = 2048;
 
                if (max_s > hwif->rqsize)
@@ -932,7 +916,7 @@ static void idedisk_setup (ide_drive_t *drive)
                drive->capacity64 = 1ULL << 28;
        }
 
-       if (drive->hwif->no_lba48_dma && drive->addressing) {
+       if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && drive->addressing) {
                if (drive->capacity64 > 1ULL << 28) {
                        printk(KERN_INFO "%s: cannot use LBA48 DMA - PIO mode will"
                                         " be used for accessing sectors > %u\n",
index bc57ce6bf0b3064ecdc76f9b55895e68988201f3..428f7a8a00b628715d86d7f9c27007db33952d3d 100644 (file)
@@ -338,8 +338,10 @@ static int config_drive_for_dma (ide_drive_t *drive)
        ide_hwif_t *hwif = drive->hwif;
        struct hd_driveid *id = drive->id;
 
-       if (drive->media != ide_disk && hwif->atapi_dma == 0)
-               return 0;
+       if (drive->media != ide_disk) {
+               if (hwif->host_flags & IDE_HFLAG_NO_ATAPI_DMA)
+                       return -1;
+       }
 
        /*
         * Enable DMA on any drive that has
@@ -726,8 +728,10 @@ u8 ide_find_dma_mode(ide_drive_t *drive, u8 req_mode)
        int x, i;
        u8 mode = 0;
 
-       if (drive->media != ide_disk && hwif->atapi_dma == 0)
-               return 0;
+       if (drive->media != ide_disk) {
+               if (hwif->host_flags & IDE_HFLAG_NO_ATAPI_DMA)
+                       return 0;
+       }
 
        for (i = 0; i < ARRAY_SIZE(xfer_mode_bases); i++) {
                if (req_mode < xfer_mode_bases[i])
@@ -897,10 +901,7 @@ void ide_dma_timeout (ide_drive_t *drive)
 
 EXPORT_SYMBOL(ide_dma_timeout);
 
-/*
- * Needed for allowing full modular support of ide-driver
- */
-static int ide_release_dma_engine(ide_hwif_t *hwif)
+static void ide_release_dma_engine(ide_hwif_t *hwif)
 {
        if (hwif->dmatable_cpu) {
                pci_free_consistent(hwif->pci_dev,
@@ -909,7 +910,6 @@ static int ide_release_dma_engine(ide_hwif_t *hwif)
                                    hwif->dmatable_dma);
                hwif->dmatable_cpu = NULL;
        }
-       return 1;
 }
 
 static int ide_release_iomio_dma(ide_hwif_t *hwif)
@@ -952,12 +952,6 @@ static int ide_mapped_mmio_dma(ide_hwif_t *hwif, unsigned long base, unsigned in
 {
        printk(KERN_INFO "    %s: MMIO-DMA ", hwif->name);
 
-       hwif->dma_base = base;
-
-       if(hwif->mate)
-               hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base : base;
-       else
-               hwif->dma_master = base;
        return 0;
 }
 
@@ -971,8 +965,6 @@ static int ide_iomio_dma(ide_hwif_t *hwif, unsigned long base, unsigned int port
                return 1;
        }
 
-       hwif->dma_base = base;
-
        if (hwif->cds->extra) {
                hwif->extra_base = base + (hwif->channel ? 8 : 16);
 
@@ -987,10 +979,6 @@ static int ide_iomio_dma(ide_hwif_t *hwif, unsigned long base, unsigned int port
                }
        }
 
-       if(hwif->mate)
-               hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base:base;
-       else
-               hwif->dma_master = base;
        return 0;
 }
 
@@ -1002,12 +990,9 @@ static int ide_dma_iobase(ide_hwif_t *hwif, unsigned long base, unsigned int por
        return ide_iomio_dma(hwif, base, ports);
 }
 
-/*
- * This can be called for a dynamically installed interface. Don't __init it
- */
-void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_ports)
+void ide_setup_dma(ide_hwif_t *hwif, unsigned long base, unsigned num_ports)
 {
-       if (ide_dma_iobase(hwif, dma_base, num_ports))
+       if (ide_dma_iobase(hwif, base, num_ports))
                return;
 
        if (ide_allocate_dma_engine(hwif)) {
@@ -1015,6 +1000,13 @@ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_p
                return;
        }
 
+       hwif->dma_base = base;
+
+       if (hwif->mate)
+               hwif->dma_master = hwif->channel ? hwif->mate->dma_base : base;
+       else
+               hwif->dma_master = base;
+
        if (!(hwif->dma_command))
                hwif->dma_command       = hwif->dma_base;
        if (!(hwif->dma_vendor1))
index ec835e37e729f59ba33aab5b4054e47951b07356..c89f0d3058e934767bc1c2a3b8b7e2231b43a587 100644 (file)
 #include <linux/device.h>
 #include <linux/kmod.h>
 #include <linux/scatterlist.h>
+#include <linux/bitops.h>
 
 #include <asm/byteorder.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
-#include <asm/bitops.h>
 
 static int __ide_end_request(ide_drive_t *drive, struct request *rq,
-                            int uptodate, unsigned int nr_bytes)
+                            int uptodate, unsigned int nr_bytes, int dequeue)
 {
        int ret = 1;
 
@@ -80,9 +80,11 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq,
 
        if (!end_that_request_chunk(rq, uptodate, nr_bytes)) {
                add_disk_randomness(rq->rq_disk);
-               if (!list_empty(&rq->queuelist))
-                       blkdev_dequeue_request(rq);
-               HWGROUP(drive)->rq = NULL;
+               if (dequeue) {
+                       if (!list_empty(&rq->queuelist))
+                               blkdev_dequeue_request(rq);
+                       HWGROUP(drive)->rq = NULL;
+               }
                end_that_request_last(rq, uptodate);
                ret = 0;
        }
@@ -122,7 +124,7 @@ int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors)
                        nr_bytes = rq->hard_cur_sectors << 9;
        }
 
-       ret = __ide_end_request(drive, rq, uptodate, nr_bytes);
+       ret = __ide_end_request(drive, rq, uptodate, nr_bytes, 1);
 
        spin_unlock_irqrestore(&ide_lock, flags);
        return ret;
@@ -255,39 +257,13 @@ int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq,
                             int uptodate, int nr_sectors)
 {
        unsigned long flags;
-       int ret = 1;
+       int ret;
 
        spin_lock_irqsave(&ide_lock, flags);
-
        BUG_ON(!blk_rq_started(rq));
-
-       /*
-        * if failfast is set on a request, override number of sectors and
-        * complete the whole request right now
-        */
-       if (blk_noretry_request(rq) && end_io_error(uptodate))
-               nr_sectors = rq->hard_nr_sectors;
-
-       if (!blk_fs_request(rq) && end_io_error(uptodate) && !rq->errors)
-               rq->errors = -EIO;
-
-       /*
-        * decide whether to reenable DMA -- 3 is a random magic for now,
-        * if we DMA timeout more than 3 times, just stay in PIO
-        */
-       if (drive->state == DMA_PIO_RETRY && drive->retry_pio <= 3) {
-               drive->state = 0;
-               HWGROUP(drive)->hwif->ide_dma_on(drive);
-       }
-
-       if (!end_that_request_first(rq, uptodate, nr_sectors)) {
-               add_disk_randomness(rq->rq_disk);
-               if (blk_rq_tagged(rq))
-                       blk_queue_end_tag(drive->queue, rq);
-               end_that_request_last(rq, uptodate);
-               ret = 0;
-       }
+       ret = __ide_end_request(drive, rq, uptodate, nr_sectors << 9, 0);
        spin_unlock_irqrestore(&ide_lock, flags);
+
        return ret;
 }
 EXPORT_SYMBOL_GPL(ide_end_dequeued_request);
@@ -484,7 +460,8 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8
                }
        }
 
-       if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ && hwif->err_stops_fifo == 0)
+       if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ &&
+           (hwif->host_flags & IDE_HFLAG_ERROR_STOPS_FIFO) == 0)
                try_to_flush_leftover_data(drive);
 
        if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) {
@@ -799,7 +776,20 @@ static ide_startstop_t do_special (ide_drive_t *drive)
                s->b.set_tune = 0;
 
                if (set_pio_mode_abuse(drive->hwif, req_pio)) {
-                       if (hwif->set_pio_mode)
+
+                       if (hwif->set_pio_mode == NULL)
+                               return ide_stopped;
+
+                       /*
+                        * take ide_lock for drive->[no_]unmask/[no_]io_32bit
+                        */
+                       if (req_pio == 8 || req_pio == 9) {
+                               unsigned long flags;
+
+                               spin_lock_irqsave(&ide_lock, flags);
+                               hwif->set_pio_mode(drive, req_pio);
+                               spin_unlock_irqrestore(&ide_lock, flags);
+                       } else
                                hwif->set_pio_mode(drive, req_pio);
                } else {
                        int keep_dma = drive->using_dma;
index d4d790f91f91afc7e7156b442143caa46d32f932..95168833d0691a82c896197a7a4d01beae361479 100644 (file)
@@ -693,35 +693,16 @@ static u8 ide_auto_reduce_xfer (ide_drive_t *drive)
 }
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 
-/*
- * Update the 
- */
-int ide_driveid_update (ide_drive_t *drive)
+int ide_driveid_update(ide_drive_t *drive)
 {
-       ide_hwif_t *hwif        = HWIF(drive);
+       ide_hwif_t *hwif = drive->hwif;
        struct hd_driveid *id;
-#if 0
-       id = kmalloc(SECTOR_WORDS*4, GFP_ATOMIC);
-       if (!id)
-               return 0;
-
-       taskfile_lib_get_identify(drive, (char *)&id);
+       unsigned long timeout, flags;
 
-       ide_fix_driveid(id);
-       if (id) {
-               drive->id->dma_ultra = id->dma_ultra;
-               drive->id->dma_mword = id->dma_mword;
-               drive->id->dma_1word = id->dma_1word;
-               /* anything more ? */
-               kfree(id);
-       }
-       return 1;
-#else
        /*
         * Re-read drive->id for possible DMA mode
         * change (copied from ide-probe.c)
         */
-       unsigned long timeout, flags;
 
        SELECT_MASK(drive, 1);
        if (IDE_CONTROL_REG)
@@ -763,7 +744,6 @@ int ide_driveid_update (ide_drive_t *drive)
        }
 
        return 1;
-#endif
 }
 
 int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
index 2b8009c50e91363c1316c3a8bbfad6208e823942..e245521af7b55d3aa9ae97c381c2234213183179 100644 (file)
@@ -40,9 +40,8 @@ static int idepnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id
        ide_std_init_ports(&hw, pnp_port_start(dev, 0),
                                pnp_port_start(dev, 1));
        hw.irq = pnp_irq(dev, 0);
-       hw.dma = NO_DMA;
 
-       index = ide_register_hw(&hw, 1, &hwif);
+       index = ide_register_hw(&hw, NULL, 1, &hwif);
 
        if (index != -1) {
                printk(KERN_INFO "ide%d: generic PnP IDE interface\n", index);
index 3c945d64d8458c01dbdc6e2e35a7cc69a9203494..6a6f2e066b4679b7c1a2ff16704af8a67bbc7673 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/spinlock.h>
 #include <linux/kmod.h>
 #include <linux/pci.h>
+#include <linux/scatterlist.h>
 
 #include <asm/byteorder.h>
 #include <asm/irq.h>
@@ -717,7 +718,7 @@ EXPORT_SYMBOL_GPL(ide_undecoded_slave);
  * This routine only knows how to look for drive units 0 and 1
  * on an interface, so any setting of MAX_DRIVES > 2 won't work here.
  */
-static void probe_hwif(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif))
+static void probe_hwif(ide_hwif_t *hwif)
 {
        unsigned long flags;
        unsigned int irqd;
@@ -819,8 +820,8 @@ static void probe_hwif(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif))
                return;
        }
 
-       if (fixup)
-               fixup(hwif);
+       if (hwif->fixup)
+               hwif->fixup(hwif);
 
        for (unit = 0; unit < MAX_DRIVES; ++unit) {
                ide_drive_t *drive = &hwif->drives[unit];
@@ -859,10 +860,11 @@ static void probe_hwif(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif))
 }
 
 static int hwif_init(ide_hwif_t *hwif);
+static void hwif_register_devices(ide_hwif_t *hwif);
 
-int probe_hwif_init_with_fixup(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif))
+static int probe_hwif_init(ide_hwif_t *hwif)
 {
-       probe_hwif(hwif, fixup);
+       probe_hwif(hwif);
 
        if (!hwif_init(hwif)) {
                printk(KERN_INFO "%s: failed to initialize IDE interface\n",
@@ -870,34 +872,12 @@ int probe_hwif_init_with_fixup(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif)
                return -1;
        }
 
-       if (hwif->present) {
-               u16 unit = 0;
-               int ret;
+       if (hwif->present)
+               hwif_register_devices(hwif);
 
-               for (unit = 0; unit < MAX_DRIVES; ++unit) {
-                       ide_drive_t *drive = &hwif->drives[unit];
-                       /* For now don't attach absent drives, we may
-                          want them on default or a new "empty" class
-                          for hotplug reprobing ? */
-                       if (drive->present) {
-                               ret = device_register(&drive->gendev);
-                               if (ret < 0)
-                                       printk(KERN_WARNING "IDE: %s: "
-                                               "device_register error: %d\n",
-                                               __FUNCTION__, ret);
-                       }
-               }
-       }
        return 0;
 }
 
-int probe_hwif_init(ide_hwif_t *hwif)
-{
-       return probe_hwif_init_with_fixup(hwif, NULL);
-}
-
-EXPORT_SYMBOL(probe_hwif_init);
-
 #if MAX_HWIFS > 1
 /*
  * save_match() is used to simplify logic in init_irq() below.
@@ -951,7 +931,8 @@ static int ide_init_queue(ide_drive_t *drive)
        blk_queue_segment_boundary(q, 0xffff);
 
        if (!hwif->rqsize) {
-               if (hwif->no_lba48 || hwif->no_lba48_dma)
+               if ((hwif->host_flags & IDE_HFLAG_NO_LBA48) ||
+                   (hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA))
                        hwif->rqsize = 256;
                else
                        hwif->rqsize = 65536;
@@ -1337,12 +1318,14 @@ static int hwif_init(ide_hwif_t *hwif)
        if (!hwif->sg_max_nents)
                hwif->sg_max_nents = PRD_ENTRIES;
 
-       hwif->sg_table = kzalloc(sizeof(struct scatterlist)*hwif->sg_max_nents,
+       hwif->sg_table = kmalloc(sizeof(struct scatterlist)*hwif->sg_max_nents,
                                 GFP_KERNEL);
        if (!hwif->sg_table) {
                printk(KERN_ERR "%s: unable to allocate SG table.\n", hwif->name);
                goto out;
        }
+
+       sg_init_table(hwif->sg_table, hwif->sg_max_nents);
        
        if (init_irq(hwif) == 0)
                goto done;
@@ -1378,6 +1361,24 @@ out:
        return 0;
 }
 
+static void hwif_register_devices(ide_hwif_t *hwif)
+{
+       unsigned int i;
+
+       for (i = 0; i < MAX_DRIVES; i++) {
+               ide_drive_t *drive = &hwif->drives[i];
+
+               if (drive->present) {
+                       int ret = device_register(&drive->gendev);
+
+                       if (ret < 0)
+                               printk(KERN_WARNING "IDE: %s: "
+                                       "device_register error: %d\n",
+                                       __FUNCTION__, ret);
+               }
+       }
+}
+
 int ideprobe_init (void)
 {
        unsigned int index;
@@ -1389,27 +1390,18 @@ int ideprobe_init (void)
 
        for (index = 0; index < MAX_HWIFS; ++index)
                if (probe[index])
-                       probe_hwif(&ide_hwifs[index], NULL);
+                       probe_hwif(&ide_hwifs[index]);
        for (index = 0; index < MAX_HWIFS; ++index)
                if (probe[index])
                        hwif_init(&ide_hwifs[index]);
        for (index = 0; index < MAX_HWIFS; ++index) {
                if (probe[index]) {
                        ide_hwif_t *hwif = &ide_hwifs[index];
-                       int unit;
                        if (!hwif->present)
                                continue;
                        if (hwif->chipset == ide_unknown || hwif->chipset == ide_forced)
                                hwif->chipset = ide_generic;
-                       for (unit = 0; unit < MAX_DRIVES; ++unit)
-                               if (hwif->drives[unit].present) {
-                                       int ret = device_register(
-                                               &hwif->drives[unit].gendev);
-                                       if (ret < 0)
-                                               printk(KERN_WARNING "IDE: %s: "
-                                                       "device_register error: %d\n",
-                                                       __FUNCTION__, ret);
-                               }
+                       hwif_register_devices(hwif);
                }
        }
        for (index = 0; index < MAX_HWIFS; ++index)
@@ -1419,3 +1411,22 @@ int ideprobe_init (void)
 }
 
 EXPORT_SYMBOL_GPL(ideprobe_init);
+
+int ide_device_add(u8 idx[4])
+{
+       int i, rc = 0;
+
+       for (i = 0; i < 4; i++) {
+               if (idx[i] != 0xff)
+                       rc |= probe_hwif_init(&ide_hwifs[idx[i]]);
+       }
+
+       for (i = 0; i < 4; i++) {
+               if (idx[i] != 0xff)
+                       ide_proc_register_port(&ide_hwifs[idx[i]]);
+       }
+
+       return rc;
+}
+
+EXPORT_SYMBOL_GPL(ide_device_add);
index fc1d8ae6a80381d08937faf4dc5d2fd687d33c7c..a4007d30da520c091491f4ca6e9923b9cc83d232 100644 (file)
@@ -804,8 +804,6 @@ void ide_proc_register_port(ide_hwif_t *hwif)
        create_proc_ide_drives(hwif);
 }
 
-EXPORT_SYMBOL_GPL(ide_proc_register_port);
-
 #ifdef CONFIG_BLK_DEV_IDEPCI
 void ide_pci_create_host_proc(const char *name, get_info_t *get_info)
 {
index 1fa57947bca0777a3b173aa8011edfb251edded3..7b9181b5469d3be9d3e8e0929c5a0c2d4122c8d5 100644 (file)
@@ -565,7 +565,7 @@ typedef struct os_dat_s {
  *     The following parameter is used to select the point in the internal
  *     tape fifo in which we will start to refill the buffer. Decreasing
  *     the following parameter will improve the system's latency and
- *     interactive response, while using a high value might improve sytem
+ *     interactive response, while using a high value might improve system
  *     throughput.
  */
 #define IDETAPE_FIFO_THRESHOLD                 2
@@ -621,7 +621,6 @@ typedef struct os_dat_s {
  */
 #define USE_IOTRACE    0
 #if USE_IOTRACE
-#include <linux/io_trace.h>
 #define IO_IDETAPE_FIFO        500
 #endif
 
index 2a3c8d498343ff417f398d1fb4b93e8678dbf82f..d066546f2831e8cab14800c4602f406e39c21302 100644 (file)
@@ -8,23 +8,6 @@
  *  Copyright (C) 2003-2004    Bartlomiej Zolnierkiewicz
  *
  *  The big the bad and the ugly.
- *
- *  Problems to be fixed because of BH interface or the lack therefore.
- *
- *  Fill me in stupid !!!
- *
- *  HOST:
- *     General refers to the Controller and Driver "pair".
- *  DATA HANDLER:
- *     Under the context of Linux it generally refers to an interrupt handler.
- *     However, it correctly describes the 'HOST'
- *  DATA BLOCK:
- *     The amount of data needed to be transfered as predefined in the
- *     setup of the device.
- *  STORAGE ATOMIC:
- *     The 'DATA BLOCK' associated to the 'DATA HANDLER', and can be as
- *     small as a single sector or as large as the entire command block
- *     request.
  */
 
 #include <linux/module.h>
@@ -278,7 +261,7 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
                hwif->cursg = sg;
        }
 
-       page = cursg->page;
+       page = sg_page(cursg);
        offset = cursg->offset + hwif->cursg_ofs * SECTOR_SIZE;
 
        /* get the current page and offset */
@@ -695,9 +678,6 @@ int ide_wait_cmd (ide_drive_t *drive, u8 cmd, u8 nsect, u8 feature, u8 sectors,
        return ide_do_drive_cmd(drive, &rq, ide_wait);
 }
 
-/*
- * FIXME : this needs to map into at taskfile. <andre@linux-ide.org>
- */
 int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
 {
        int err = 0;
@@ -761,9 +741,6 @@ static int ide_wait_cmd_task(ide_drive_t *drive, u8 *buf)
        return ide_do_drive_cmd(drive, &rq, ide_wait);
 }
 
-/*
- * FIXME : this needs to map into at taskfile. <andre@linux-ide.org>
- */
 int ide_task_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
 {
        void __user *p = (void __user *)arg;
@@ -860,9 +837,14 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
                case TASKFILE_OUT_DMA:
                case TASKFILE_IN_DMAQ:
                case TASKFILE_IN_DMA:
-                       hwif->dma_setup(drive);
-                       hwif->dma_exec_cmd(drive, taskfile->command);
-                       hwif->dma_start(drive);
+                       if (!drive->using_dma)
+                               break;
+
+                       if (!hwif->dma_setup(drive)) {
+                               hwif->dma_exec_cmd(drive, taskfile->command);
+                               hwif->dma_start(drive);
+                               return ide_started;
+                       }
                        break;
 
                default:
@@ -876,7 +858,8 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
                                return task->prehandler(drive, task->rq);
                        }
                        ide_execute_command(drive, taskfile->command, task->handler, WAIT_WORSTCASE, NULL);
+                       return ide_started;
        }
 
-       return ide_started;
+       return ide_stopped;
 }
index 5b090662683ed25031b69e10593fc8582951c941..674a65c1a1308986743237c46792a6c7661d1c7c 100644 (file)
@@ -134,8 +134,6 @@ static void init_hwif_data(ide_hwif_t *hwif, unsigned int index)
 
        hwif->bus_state = BUSSTATE_ON;
 
-       hwif->atapi_dma = 0;            /* disable all atapi dma */ 
-
        init_completion(&hwif->gendev_rel_comp);
 
        default_hwif_iops(hwif);
@@ -170,7 +168,6 @@ static void init_hwif_default(ide_hwif_t *hwif, unsigned int index)
 
        ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, &hwif->irq);
 
-       memcpy(&hwif->hw, &hw, sizeof(hw));
        memcpy(hwif->io_ports, hw.io_ports, sizeof(hw.io_ports));
 
        hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
@@ -216,7 +213,7 @@ static void __init init_ide_data (void)
                init_hwif_data(hwif, index);
                init_hwif_default(hwif, index);
 #if !defined(CONFIG_PPC32) || !defined(CONFIG_PCI)
-               hwif->irq = hwif->hw.irq =
+               hwif->irq =
                        ide_init_default_irq(hwif->io_ports[IDE_DATA_OFFSET]);
 #endif
        }
@@ -267,6 +264,30 @@ static int ide_system_bus_speed(void)
        return system_bus_speed;
 }
 
+ide_hwif_t * ide_find_port(unsigned long base)
+{
+       ide_hwif_t *hwif;
+       int i;
+
+       for (i = 0; i < MAX_HWIFS; i++) {
+               hwif = &ide_hwifs[i];
+               if (hwif->io_ports[IDE_DATA_OFFSET] == base)
+                       goto found;
+       }
+
+       for (i = 0; i < MAX_HWIFS; i++) {
+               hwif = &ide_hwifs[i];
+               if (hwif->io_ports[IDE_DATA_OFFSET] == 0)
+                       goto found;
+       }
+
+       hwif = NULL;
+found:
+       return hwif;
+}
+
+EXPORT_SYMBOL_GPL(ide_find_port);
+
 static struct resource* hwif_request_region(ide_hwif_t *hwif,
                                            unsigned long addr, int num)
 {
@@ -379,7 +400,6 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
 
        hwif->pio_mask                  = tmp_hwif->pio_mask;
 
-       hwif->atapi_dma                 = tmp_hwif->atapi_dma;
        hwif->ultra_mask                = tmp_hwif->ultra_mask;
        hwif->mwdma_mask                = tmp_hwif->mwdma_mask;
        hwif->swdma_mask                = tmp_hwif->swdma_mask;
@@ -394,6 +414,8 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
        hwif->cds                       = tmp_hwif->cds;
 #endif
 
+       hwif->fixup                     = tmp_hwif->fixup;
+
        hwif->set_pio_mode              = tmp_hwif->set_pio_mode;
        hwif->set_dma_mode              = tmp_hwif->set_dma_mode;
        hwif->mdma_filter               = tmp_hwif->mdma_filter;
@@ -440,7 +462,6 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
 
        hwif->mmio                      = tmp_hwif->mmio;
        hwif->rqsize                    = tmp_hwif->rqsize;
-       hwif->no_lba48                  = tmp_hwif->no_lba48;
 
 #ifndef CONFIG_BLK_DEV_IDECS
        hwif->irq                       = tmp_hwif->irq;
@@ -656,7 +677,6 @@ void ide_setup_ports (      hw_regs_t *hw,
                }
        }
        hw->irq = irq;
-       hw->dma = NO_DMA;
        hw->ack_intr = ack_intr;
 /*
  *     hw->iops = iops;
@@ -664,11 +684,11 @@ void ide_setup_ports (    hw_regs_t *hw,
 }
 
 /**
- *     ide_register_hw_with_fixup      -       register IDE interface
+ *     ide_register_hw         -       register IDE interface
  *     @hw: hardware registers
+ *     @fixup: fixup function
  *     @initializing: set while initializing built-in drivers
  *     @hwifp: pointer to returned hwif
- *     @fixup: fixup function
  *
  *     Register an IDE interface, specifying exactly the registers etc.
  *     Set init=1 iff calling before probes have taken place.
@@ -676,9 +696,8 @@ void ide_setup_ports (      hw_regs_t *hw,
  *     Returns -1 on error.
  */
 
-int ide_register_hw_with_fixup(hw_regs_t *hw, int initializing,
-                              ide_hwif_t **hwifp,
-                              void(*fixup)(ide_hwif_t *hwif))
+int ide_register_hw(hw_regs_t *hw, void (*fixup)(ide_hwif_t *),
+                   int initializing, ide_hwif_t **hwifp)
 {
        int index, retry = 1;
        ide_hwif_t *hwif;
@@ -686,7 +705,7 @@ int ide_register_hw_with_fixup(hw_regs_t *hw, int initializing,
        do {
                for (index = 0; index < MAX_HWIFS; ++index) {
                        hwif = &ide_hwifs[index];
-                       if (hwif->hw.io_ports[IDE_DATA_OFFSET] == hw->io_ports[IDE_DATA_OFFSET])
+                       if (hwif->io_ports[IDE_DATA_OFFSET] == hw->io_ports[IDE_DATA_OFFSET])
                                goto found;
                }
                for (index = 0; index < MAX_HWIFS; ++index) {
@@ -694,7 +713,7 @@ int ide_register_hw_with_fixup(hw_regs_t *hw, int initializing,
                        if (hwif->hold)
                                continue;
                        if ((!hwif->present && !hwif->mate && !initializing) ||
-                           (!hwif->hw.io_ports[IDE_DATA_OFFSET] && initializing))
+                           (!hwif->io_ports[IDE_DATA_OFFSET] && initializing))
                                goto found;
                }
                for (index = 0; index < MAX_HWIFS; index++)
@@ -710,16 +729,18 @@ found:
        }
        if (hwif->present)
                return -1;
-       memcpy(&hwif->hw, hw, sizeof(*hw));
-       memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports));
+       memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports));
        hwif->irq = hw->irq;
        hwif->noprobe = 0;
+       hwif->fixup = fixup;
        hwif->chipset = hw->chipset;
        hwif->gendev.parent = hw->dev;
+       hwif->ack_intr = hw->ack_intr;
+
+       if (initializing == 0) {
+               u8 idx[4] = { index, 0xff, 0xff, 0xff };
 
-       if (!initializing) {
-               probe_hwif_init_with_fixup(hwif, fixup);
-               ide_proc_register_port(hwif);
+               ide_device_add(idx);
        }
 
        if (hwifp)
@@ -728,13 +749,6 @@ found:
        return (initializing || hwif->present) ? index : -1;
 }
 
-EXPORT_SYMBOL(ide_register_hw_with_fixup);
-
-int ide_register_hw(hw_regs_t *hw, int initializing, ide_hwif_t **hwifp)
-{
-       return ide_register_hw_with_fixup(hw, initializing, hwifp, NULL);
-}
-
 EXPORT_SYMBOL(ide_register_hw);
 
 /*
@@ -1050,7 +1064,7 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device
                        ide_init_hwif_ports(&hw, (unsigned long) args[0],
                                            (unsigned long) args[1], NULL);
                        hw.irq = args[2];
-                       if (ide_register_hw(&hw, 0, NULL) == -1)
+                       if (ide_register_hw(&hw, NULL, 0, NULL) == -1)
                                return -EIO;
                        return 0;
                }
@@ -1401,6 +1415,9 @@ static int __init ide_setup(char *s)
                        "reset", "minus6", "ata66", "minus8", "minus9",
                        "minus10", "four", "qd65xx", "ht6560b", "cmd640_vlb",
                        "dtc2278", "umc8672", "ali14xx", NULL };
+
+               hw_regs_t hwregs;
+
                hw = s[3] - '0';
                hwif = &ide_hwifs[hw];
                i = match_parm(&s[4], ide_words, vals, 3);
@@ -1510,9 +1527,9 @@ static int __init ide_setup(char *s)
                        case 2: /* base,ctl */
                                vals[2] = 0;    /* default irq = probe for it */
                        case 3: /* base,ctl,irq */
-                               hwif->hw.irq = vals[2];
-                               ide_init_hwif_ports(&hwif->hw, (unsigned long) vals[0], (unsigned long) vals[1], &hwif->irq);
-                               memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
+                               memset(&hwregs, 0, sizeof(hwregs));
+                               ide_init_hwif_ports(&hwregs, vals[0], vals[1], &hwif->irq);
+                               memcpy(hwif->io_ports, hwregs.io_ports, sizeof(hwif->io_ports));
                                hwif->irq      = vals[2];
                                hwif->noprobe  = 0;
                                hwif->chipset  = ide_forced;
index 2f0ef9b440335d9e1f6654c54424a4faa30b145a..10311ecc674a4440511de0b4b27d0601d3718a45 100644 (file)
@@ -102,6 +102,8 @@ static void outReg (u8 data, u8 reg)
        outb_p(data, dataPort);
 }
 
+static DEFINE_SPINLOCK(ali14xx_lock);
+
 /*
  * Set PIO mode for the specified drive.
  * This function computes timing parameters
@@ -129,14 +131,14 @@ static void ali14xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
 
        /* stuff timing parameters into controller registers */
        driveNum = (HWIF(drive)->index << 1) + drive->select.b.unit;
-       spin_lock_irqsave(&ide_lock, flags);
+       spin_lock_irqsave(&ali14xx_lock, flags);
        outb_p(regOn, basePort);
        outReg(param1, regTab[driveNum].reg1);
        outReg(param2, regTab[driveNum].reg2);
        outReg(param3, regTab[driveNum].reg3);
        outReg(param4, regTab[driveNum].reg4);
        outb_p(regOff, basePort);
-       spin_unlock_irqrestore(&ide_lock, flags);
+       spin_unlock_irqrestore(&ali14xx_lock, flags);
 }
 
 /*
@@ -193,6 +195,7 @@ static int __init initRegisters (void) {
 static int __init ali14xx_probe(void)
 {
        ide_hwif_t *hwif, *mate;
+       static u8 idx[4] = { 0, 1, 0xff, 0xff };
 
        printk(KERN_DEBUG "ali14xx: base=0x%03x, regOn=0x%02x.\n",
                          basePort, regOn);
@@ -217,11 +220,7 @@ static int __init ali14xx_probe(void)
        mate->mate = hwif;
        mate->channel = 1;
 
-       probe_hwif_init(hwif);
-       probe_hwif_init(mate);
-
-       ide_proc_register_port(hwif);
-       ide_proc_register_port(mate);
+       ide_device_add(idx);
 
        return 0;
 }
index 101aee1711c489c7985bc1d730e3ca6fb1452c29..4a0be251a05fd84ddaa606c2b1161c2c99d93a59 100644 (file)
@@ -212,8 +212,8 @@ fail_base2:
 //                                             xsurf_iops,
                                                IRQ_AMIGA_PORTS);
                        }       
-                       
-                       index = ide_register_hw(&hw, 1, &hwif);
+
+                       index = ide_register_hw(&hw, NULL, 1, &hwif);
                        if (index != -1) {
                                hwif->mmio = 1;
                                printk("ide%d: ", index);
index f165212548673729f412bbfb031aea67ba20c49c..24a845d45bd29b369001979b9b24cede2c6bda05 100644 (file)
@@ -67,20 +67,24 @@ static void sub22 (char b, char c)
        }
 }
 
+static DEFINE_SPINLOCK(dtc2278_lock);
+
 static void dtc2278_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
        unsigned long flags;
 
        if (pio >= 3) {
-               spin_lock_irqsave(&ide_lock, flags);
+               spin_lock_irqsave(&dtc2278_lock, flags);
                /*
                 * This enables PIO mode4 (3?) on the first interface
                 */
                sub22(1,0xc3);
                sub22(0,0xa0);
-               spin_unlock_irqrestore(&ide_lock, flags);
+               spin_unlock_irqrestore(&dtc2278_lock, flags);
        } else {
                /* we don't know how to set it back again.. */
+               /* Actually we do - there is a data sheet available for the
+                  Winbond but does anyone actually care */
        }
 
        /*
@@ -94,6 +98,7 @@ static int __init dtc2278_probe(void)
 {
        unsigned long flags;
        ide_hwif_t *hwif, *mate;
+       static u8 idx[4] = { 0, 1, 0xff, 0xff };
 
        hwif = &ide_hwifs[0];
        mate = &ide_hwifs[1];
@@ -129,16 +134,13 @@ static int __init dtc2278_probe(void)
 
        mate->serialized = 1;
        mate->chipset = ide_dtc2278;
+       mate->pio_mask = ATA_PIO4;
        mate->drives[0].no_unmask = 1;
        mate->drives[1].no_unmask = 1;
        mate->mate = hwif;
        mate->channel = 1;
 
-       probe_hwif_init(hwif);
-       probe_hwif_init(mate);
-
-       ide_proc_register_port(hwif);
-       ide_proc_register_port(mate);
+       ide_device_add(idx);
 
        return 0;
 }
index f0829b83e970db20c5f7a500eee860bf1aa484a2..7d7936f1b9007b06c50bfe477f1171ef49a33150 100644 (file)
@@ -72,7 +72,7 @@ void __init falconide_init(void)
                        0, 0, NULL,
 //                     falconide_iops,
                        IRQ_MFP_IDE);
-       index = ide_register_hw(&hw, 1, NULL);
+       index = ide_register_hw(&hw, NULL, 1, NULL);
 
        if (index != -1)
            printk("ide%d: Falcon IDE interface\n", index);
index 0830a021bbb609d4b103dc037239a0f2ec5bc934..53331ee1e957c9a71c651a2eeb3c5ae2aaa191bf 100644 (file)
@@ -165,7 +165,7 @@ found:
 //                     &gayle_iops,
                        IRQ_AMIGA_PORTS);
 
-       index = ide_register_hw(&hw, 1, &hwif);
+       index = ide_register_hw(&hw, NULL, 1, &hwif);
        if (index != -1) {
            hwif->mmio = 1;
            switch (i) {
index 2e5a9cc5c0f7ab1a48a2b26bef35ca12922f4837..a4245d13f11b83d2dced3d1f82d33f0caa6c34e7 100644 (file)
@@ -247,6 +247,8 @@ static u8 ht_pio2timings(ide_drive_t *drive, const u8 pio)
        }
 }
 
+static DEFINE_SPINLOCK(ht6560b_lock);
+
 /*
  *  Enable/Disable so called prefetch mode
  */
@@ -254,9 +256,9 @@ static void ht_set_prefetch(ide_drive_t *drive, u8 state)
 {
        unsigned long flags;
        int t = HT_PREFETCH_MODE << 8;
-       
-       spin_lock_irqsave(&ide_lock, flags);
-       
+
+       spin_lock_irqsave(&ht6560b_lock, flags);
+
        /*
         *  Prefetch mode and unmask irq seems to conflict
         */
@@ -268,9 +270,9 @@ static void ht_set_prefetch(ide_drive_t *drive, u8 state)
                drive->drive_data &= ~t;  /* disable prefetch mode */
                drive->no_unmask = 0;
        }
-       
-       spin_unlock_irqrestore(&ide_lock, flags);
-       
+
+       spin_unlock_irqrestore(&ht6560b_lock, flags);
+
 #ifdef DEBUG
        printk("ht6560b: drive %s prefetch mode %sabled\n", drive->name, (state ? "en" : "dis"));
 #endif
@@ -287,16 +289,14 @@ static void ht6560b_set_pio_mode(ide_drive_t *drive, const u8 pio)
                ht_set_prefetch(drive, pio & 1);
                return;
        }
-       
+
        timing = ht_pio2timings(drive, pio);
-       
-       spin_lock_irqsave(&ide_lock, flags);
-       
+
+       spin_lock_irqsave(&ht6560b_lock, flags);
        drive->drive_data &= 0xff00;
        drive->drive_data |= timing;
-       
-       spin_unlock_irqrestore(&ide_lock, flags);
-       
+       spin_unlock_irqrestore(&ht6560b_lock, flags);
+
 #ifdef DEBUG
        printk("ht6560b: drive %s tuned to pio mode %#x timing=%#x\n", drive->name, pio, timing);
 #endif
@@ -311,6 +311,7 @@ MODULE_PARM_DESC(probe, "probe for HT6560B chipset");
 int __init ht6560b_init(void)
 {
        ide_hwif_t *hwif, *mate;
+       static u8 idx[4] = { 0, 1, 0xff, 0xff };
        int t;
 
        if (probe_ht6560b == 0)
@@ -359,11 +360,7 @@ int __init ht6560b_init(void)
        mate->drives[0].drive_data = t;
        mate->drives[1].drive_data = t;
 
-       probe_hwif_init(hwif);
-       probe_hwif_init(mate);
-
-       ide_proc_register_port(hwif);
-       ide_proc_register_port(mate);
+       ide_device_add(idx);
 
        return 0;
 
index e8e360c2619d1eea7365ae2bd5645716834c97f5..03715c05866408b1d14773e365d265d74b7194c4 100644 (file)
@@ -153,7 +153,7 @@ static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq
     hw.irq = irq;
     hw.chipset = ide_pci;
     hw.dev = &handle->dev;
-    return ide_register_hw_with_fixup(&hw, 0, NULL, ide_undecoded_slave);
+    return ide_register_hw(&hw, &ide_undecoded_slave, 0, NULL);
 }
 
 /*======================================================================
index b992b2b91fe2ba684dadbc7345ffb96d4161f8bc..7bb79f53dac804e708ef6a49e110804d903f993d 100644 (file)
@@ -33,39 +33,24 @@ static ide_hwif_t *__devinit plat_ide_locate_hwif(void __iomem *base,
            int mmio)
 {
        unsigned long port = (unsigned long)base;
-       ide_hwif_t *hwif;
-       int index, i;
-
-       for (index = 0; index < MAX_HWIFS; ++index) {
-               hwif = ide_hwifs + index;
-               if (hwif->io_ports[IDE_DATA_OFFSET] == port)
-                       goto found;
-       }
-
-       for (index = 0; index < MAX_HWIFS; ++index) {
-               hwif = ide_hwifs + index;
-               if (hwif->io_ports[IDE_DATA_OFFSET] == 0)
-                       goto found;
-       }
+       ide_hwif_t *hwif = ide_find_port(port);
+       int i;
 
-       return NULL;
-
-found:
+       if (hwif == NULL)
+               goto out;
 
-       hwif->hw.io_ports[IDE_DATA_OFFSET] = port;
+       hwif->io_ports[IDE_DATA_OFFSET] = port;
 
        port += (1 << pdata->ioport_shift);
        for (i = IDE_ERROR_OFFSET; i <= IDE_STATUS_OFFSET;
             i++, port += (1 << pdata->ioport_shift))
-               hwif->hw.io_ports[i] = port;
+               hwif->io_ports[i] = port;
 
-       hwif->hw.io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
+       hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
 
-       memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports));
-       hwif->hw.irq = hwif->irq = irq;
+       hwif->irq = irq;
 
-       hwif->hw.dma = NO_DMA;
-       hwif->chipset = hwif->hw.chipset = ide_generic;
+       hwif->chipset = ide_generic;
 
        if (mmio) {
                hwif->mmio = 1;
@@ -73,8 +58,8 @@ found:
        }
 
        hwif_prop.hwif = hwif;
-       hwif_prop.index = index;
-
+       hwif_prop.index = hwif->index;
+out:
        return hwif;
 }
 
@@ -83,6 +68,7 @@ static int __devinit plat_ide_probe(struct platform_device *pdev)
        struct resource *res_base, *res_alt, *res_irq;
        ide_hwif_t *hwif;
        struct pata_platform_info *pdata;
+       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
        int ret = 0;
        int mmio = 0;
 
@@ -130,10 +116,11 @@ static int __devinit plat_ide_probe(struct platform_device *pdev)
        hwif->gendev.parent = &pdev->dev;
        hwif->noprobe = 0;
 
-       probe_hwif_init(hwif);
+       idx[0] = hwif->index;
+
+       ide_device_add(idx);
 
        platform_set_drvdata(pdev, hwif);
-       ide_proc_register_port(hwif);
 
        return 0;
 
index b557c45a5a9dc614e7aa556e07554f5b3623457a..e87cd2f16430a6555e4f7e88fca5ee1e17d0e3e0 100644 (file)
@@ -93,21 +93,21 @@ void macide_init(void)
                                0, 0, macide_ack_intr,
 //                             quadra_ide_iops,
                                IRQ_NUBUS_F);
-               index = ide_register_hw(&hw, 1, &hwif);
+               index = ide_register_hw(&hw, NULL, 1, &hwif);
                break;
        case MAC_IDE_PB:
                ide_setup_ports(&hw, IDE_BASE, macide_offsets,
                                0, 0, macide_ack_intr,
 //                             macide_pb_iops,
                                IRQ_NUBUS_C);
-               index = ide_register_hw(&hw, 1, &hwif);
+               index = ide_register_hw(&hw, NULL, 1, &hwif);
                break;
        case MAC_IDE_BABOON:
                ide_setup_ports(&hw, BABOON_BASE, macide_offsets,
                                0, 0, NULL,
 //                             macide_baboon_iops,
                                IRQ_BABOON_1);
-               index = ide_register_hw(&hw, 1, &hwif);
+               index = ide_register_hw(&hw, NULL, 1, &hwif);
                if (index == -1) break;
                if (macintosh_config->ident == MAC_MODEL_PB190) {
 
index e628a983ce3395706cdf905c52a37eab15abc9d9..a73db1bd482d6ecbdcf023f72aba169e61595f4b 100644 (file)
@@ -89,9 +89,8 @@ void q40_ide_setup_ports ( hw_regs_t *hw,
                else
                        hw->io_ports[i] = Q40_ISA_IO_B(base + offsets[i]);
        }
-       
+
        hw->irq = irq;
-       hw->dma = NO_DMA;
        hw->ack_intr = ack_intr;
 /*
  *     hw->iops = iops;
@@ -102,7 +101,7 @@ void q40_ide_setup_ports ( hw_regs_t *hw,
 
 /* 
  * the static array is needed to have the name reported in /proc/ioports,
- * hwif->name unfortunately isn´t available yet
+ * hwif->name unfortunately isn't available yet
  */
 static const char *q40_ide_names[Q40IDE_NUM_HWIFS]={
        "ide0", "ide1"
@@ -142,7 +141,7 @@ void q40ide_init(void)
                        0, NULL,
 //                     m68kide_iops,
                        q40ide_default_irq(pcide_bases[i]));
-       index = ide_register_hw(&hw, 1, &hwif);
+       index = ide_register_hw(&hw, NULL, 1, &hwif);
        // **FIXME**
        if (index != -1)
                hwif->mmio = 1;
index 0c81d2d0b9418a2a2f7db1ca85a119b1038b41b9..912e73853faa1b3fa2082031cd6687e95be94dde 100644 (file)
 
 static int timings[4]={-1,-1,-1,-1}; /* stores current timing for each timer */
 
-static void qd_write_reg (u8 content, unsigned long reg)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&ide_lock, flags);
-       outb(content,reg);
-       spin_unlock_irqrestore(&ide_lock, flags);
-}
-
-static u8 __init qd_read_reg (unsigned long reg)
-{
-       unsigned long flags;
-       u8 read;
-
-       spin_lock_irqsave(&ide_lock, flags);
-       read = inb(reg);
-       spin_unlock_irqrestore(&ide_lock, flags);
-       return read;
-}
-
 /*
  * qd_select:
  *
@@ -121,7 +101,7 @@ static void qd_select (ide_drive_t *drive)
                        (QD_TIMREG(drive) & 0x02);
 
        if (timings[index] != QD_TIMING(drive))
-               qd_write_reg(timings[index] = QD_TIMING(drive), QD_TIMREG(drive));
+               outb(timings[index] = QD_TIMING(drive), QD_TIMREG(drive));
 }
 
 /*
@@ -284,7 +264,7 @@ static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio)
        }
 
        if (!HWIF(drive)->channel && drive->media != ide_disk) {
-               qd_write_reg(0x5f, QD_CONTROL_PORT);
+               outb(0x5f, QD_CONTROL_PORT);
                printk(KERN_WARNING "%s: ATAPI: disabled read-ahead FIFO "
                        "and post-write buffer on %s.\n",
                        drive->name, HWIF(drive)->name);
@@ -301,16 +281,15 @@ static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio)
 
 static int __init qd_testreg(int port)
 {
-       u8 savereg;
-       u8 readreg;
        unsigned long flags;
+       u8 savereg, readreg;
 
-       spin_lock_irqsave(&ide_lock, flags);
+       local_irq_save(flags);
        savereg = inb_p(port);
        outb_p(QD_TESTVAL, port);       /* safe value */
        readreg = inb_p(port);
        outb(savereg, port);
-       spin_unlock_irqrestore(&ide_lock, flags);
+       local_irq_restore(flags);
 
        if (savereg == QD_TESTVAL) {
                printk(KERN_ERR "Outch ! the probe for qd65xx isn't reliable !\n");
@@ -364,13 +343,13 @@ static void __exit qd_unsetup(ide_hwif_t *hwif)
 
        if (set_pio_mode == (void *)qd6500_set_pio_mode) {
                // will do it for both
-               qd_write_reg(QD6500_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
+               outb(QD6500_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
        } else if (set_pio_mode == (void *)qd6580_set_pio_mode) {
                if (QD_CONTROL(hwif) & QD_CONTR_SEC_DISABLED) {
-                       qd_write_reg(QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
-                       qd_write_reg(QD6580_DEF_DATA2, QD_TIMREG(&hwif->drives[1]));
+                       outb(QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
+                       outb(QD6580_DEF_DATA2, QD_TIMREG(&hwif->drives[1]));
                } else {
-                       qd_write_reg(hwif->channel ? QD6580_DEF_DATA2 : QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
+                       outb(hwif->channel ? QD6580_DEF_DATA2 : QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
                }
        } else {
                printk(KERN_WARNING "Unknown qd65xx tuning fonction !\n");
@@ -389,10 +368,11 @@ static void __exit qd_unsetup(ide_hwif_t *hwif)
 static int __init qd_probe(int base)
 {
        ide_hwif_t *hwif;
+       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
        u8 config;
        u8 unit;
 
-       config = qd_read_reg(QD_CONFIG_PORT);
+       config = inb(QD_CONFIG_PORT);
 
        if (! ((config & QD_CONFIG_BASEPORT) >> 1 == (base == 0xb0)) )
                return 1;
@@ -419,9 +399,9 @@ static int __init qd_probe(int base)
 
                hwif->set_pio_mode = &qd6500_set_pio_mode;
 
-               probe_hwif_init(hwif);
+               idx[0] = unit;
 
-               ide_proc_register_port(hwif);
+               ide_device_add(idx);
 
                return 1;
        }
@@ -436,7 +416,7 @@ static int __init qd_probe(int base)
 
                /* qd6580 found */
 
-               control = qd_read_reg(QD_CONTROL_PORT);
+               control = inb(QD_CONTROL_PORT);
 
                printk(KERN_NOTICE "qd6580 at %#x\n", base);
                printk(KERN_DEBUG "qd6580: config=%#x, control=%#x, ID3=%u\n",
@@ -453,11 +433,11 @@ static int __init qd_probe(int base)
 
                        hwif->set_pio_mode = &qd6580_set_pio_mode;
 
-                       probe_hwif_init(hwif);
+                       idx[0] = unit;
 
-                       qd_write_reg(QD_DEF_CONTR,QD_CONTROL_PORT);
+                       ide_device_add(idx);
 
-                       ide_proc_register_port(hwif);
+                       outb(QD_DEF_CONTR, QD_CONTROL_PORT);
 
                        return 1;
                } else {
@@ -474,19 +454,17 @@ static int __init qd_probe(int base)
 
                        hwif->set_pio_mode = &qd6580_set_pio_mode;
 
-                       probe_hwif_init(hwif);
-
                        qd_setup(mate, base, config | (control << 8),
                                 QD6580_DEF_DATA2, QD6580_DEF_DATA2);
 
                        mate->set_pio_mode = &qd6580_set_pio_mode;
 
-                       probe_hwif_init(mate);
+                       idx[0] = 0;
+                       idx[1] = 1;
 
-                       qd_write_reg(QD_DEF_CONTR,QD_CONTROL_PORT);
+                       ide_device_add(idx);
 
-                       ide_proc_register_port(hwif);
-                       ide_proc_register_port(mate);
+                       outb(QD_DEF_CONTR, QD_CONTROL_PORT);
 
                        return 0; /* no other qd65xx possible */
                }
index 1151c92dd5318dfc8681771143322f7d1e4e3480..79577b916874d085fa96dbf2c2036301e129ef11 100644 (file)
@@ -124,8 +124,9 @@ static void umc_set_pio_mode(ide_drive_t *drive, const u8 pio)
 
 static int __init umc8672_probe(void)
 {
-       unsigned long flags;
        ide_hwif_t *hwif, *mate;
+       unsigned long flags;
+       static u8 idx[4] = { 0, 1, 0xff, 0xff };
 
        if (!request_region(0x108, 2, "umc8672")) {
                printk(KERN_ERR "umc8672: ports 0x108-0x109 already in use.\n");
@@ -158,11 +159,7 @@ static int __init umc8672_probe(void)
        mate->mate = hwif;
        mate->channel = 1;
 
-       probe_hwif_init(hwif);
-       probe_hwif_init(mate);
-
-       ide_proc_register_port(hwif);
-       ide_proc_register_port(mate);
+       ide_device_add(idx);
 
        return 0;
 }
index 47c035a550e343e9a3515055f52bfa5cd35ca47e..a4ce3ba15d61a0164fc3ee1535060e1121186b8e 100644 (file)
@@ -276,8 +276,7 @@ static int auide_build_dmatable(ide_drive_t *drive)
 
                        if (iswrite) {
                                if(!put_source_flags(ahwif->tx_chan, 
-                                                    (void*)(page_address(sg->page) 
-                                                            + sg->offset), 
+                                                    (void*) sg_virt(sg),
                                                     tc, flags)) { 
                                        printk(KERN_ERR "%s failed %d\n", 
                                               __FUNCTION__, __LINE__);
@@ -285,8 +284,7 @@ static int auide_build_dmatable(ide_drive_t *drive)
                        } else 
                        {
                                if(!put_dest_flags(ahwif->rx_chan, 
-                                                  (void*)(page_address(sg->page) 
-                                                          + sg->offset), 
+                                                  (void*) sg_virt(sg),
                                                   tc, flags)) { 
                                        printk(KERN_ERR "%s failed %d\n", 
                                               __FUNCTION__, __LINE__);
@@ -601,8 +599,9 @@ static int au_ide_probe(struct device *dev)
        _auide_hwif *ahwif = &auide_hwif;
        ide_hwif_t *hwif;
        struct resource *res;
-       hw_regs_t *hw;
        int ret = 0;
+       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+       hw_regs_t hw;
 
 #if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
        char *mode = "MWDMA2";
@@ -644,12 +643,12 @@ static int au_ide_probe(struct device *dev)
        /* FIXME:  This might possibly break PCMCIA IDE devices */
 
        hwif                            = &ide_hwifs[pdev->id];
-       hw                              = &hwif->hw;
-       hwif->irq = hw->irq             = ahwif->irq;
+       hwif->irq                       = ahwif->irq;
        hwif->chipset                   = ide_au1xxx;
 
-       auide_setup_ports(hw, ahwif);
-       memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports));
+       memset(&hw, 0, sizeof(hw));
+       auide_setup_ports(&hw, ahwif);
+       memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports));
 
        hwif->ultra_mask                = 0x0;  /* Disable Ultra DMA */
 #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
@@ -699,9 +698,6 @@ static int au_ide_probe(struct device *dev)
        hwif->dma_host_on               = &auide_dma_host_on;
        hwif->dma_lost_irq              = &auide_dma_lost_irq;
        hwif->ide_dma_on                = &auide_dma_on;
-
-       hwif->atapi_dma                 = 1;
-
 #else /* !CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
        hwif->channel                   = 0;
        hwif->hold                      = 1;
@@ -709,8 +705,10 @@ static int au_ide_probe(struct device *dev)
        hwif->config_data               = 0;    /* no chipset-specific code */
 
        hwif->drives[0].autotune        = 1;    /* 1=autotune, 2=noautotune, 0=default */
+       hwif->drives[1].autotune        = 1;
 #endif
-       hwif->drives[0].no_io_32bit     = 1;   
+       hwif->drives[0].no_io_32bit     = 1;
+       hwif->drives[1].no_io_32bit     = 1;
 
        auide_hwif.hwif                 = hwif;
        hwif->hwif_data                 = &auide_hwif;
@@ -720,9 +718,9 @@ static int au_ide_probe(struct device *dev)
        dbdma_init_done = 1;
 #endif
 
-       probe_hwif_init(hwif);
+       idx[0] = hwif->index;
 
-       ide_proc_register_port(hwif);
+       ide_device_add(idx);
 
        dev_set_drvdata(dev, hwif);
 
index c2e29571b0075d3647d2978f24c281cf4d0e7d0f..521edd41b572b0e9c00a82d218c9ec91acb72046 100644 (file)
@@ -71,6 +71,7 @@ static int __devinit swarm_ide_probe(struct device *dev)
        u8 __iomem *base;
        phys_t offset, size;
        int i;
+       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 
        if (!SIBYTE_HAVE_IDE)
                return -ENODEV;
@@ -119,18 +120,15 @@ static int __devinit swarm_ide_probe(struct device *dev)
        hwif->noprobe = 0;
 
        for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
-               hwif->hw.io_ports[i] =
+               hwif->io_ports[i] =
                                (unsigned long)(base + ((0x1f0 + i) << 5));
-       hwif->hw.io_ports[IDE_CONTROL_OFFSET] =
+       hwif->io_ports[IDE_CONTROL_OFFSET] =
                                (unsigned long)(base + (0x3f6 << 5));
-       hwif->hw.irq = K_INT_GB_IDE;
+       hwif->irq = K_INT_GB_IDE;
 
-       memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
-       hwif->irq = hwif->hw.irq;
+       idx[0] = hwif->index;
 
-       probe_hwif_init(hwif);
-
-       ide_proc_register_port(hwif);
+       ide_device_add(idx);
 
        dev_set_drvdata(dev, hwif);
 
index 3a4c2c26a77e1da218de133db363f7c84e92a53b..19ec421f7b9f4c2f4871c74069c9dd0fa9db46e2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/pci/aec62xx.c             Version 0.25    Aug 1, 2007
+ * linux/drivers/ide/pci/aec62xx.c             Version 0.27    Sep 16, 2007
  *
  * Copyright (C) 1999-2002     Andre Hedrick <andre@linux-ide.org>
  * Copyright (C) 2007          MontaVista Software, Inc. <source@mvista.com>
@@ -141,19 +141,6 @@ static void aec_set_pio_mode(ide_drive_t *drive, const u8 pio)
        drive->hwif->set_dma_mode(drive, pio + XFER_PIO_0);
 }
 
-static void aec62xx_dma_lost_irq (ide_drive_t *drive)
-{
-       switch (HWIF(drive)->pci_dev->device) {
-               case PCI_DEVICE_ID_ARTOP_ATP860:
-               case PCI_DEVICE_ID_ARTOP_ATP860R:
-               case PCI_DEVICE_ID_ARTOP_ATP865:
-               case PCI_DEVICE_ID_ARTOP_ATP865R:
-                       printk(" AEC62XX time out ");
-               default:
-                       break;
-       }
-}
-
 static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const char *name)
 {
        int bus_speed = system_bus_clock();
@@ -184,34 +171,21 @@ static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const ch
 static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif)
 {
        struct pci_dev *dev     = hwif->pci_dev;
-       u8 reg54 = 0,  mask     = hwif->channel ? 0xf0 : 0x0f;
-       unsigned long flags;
 
        hwif->set_pio_mode = &aec_set_pio_mode;
 
-       if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) {
-               if(hwif->mate)
-                       hwif->mate->serialized = hwif->serialized = 1;
+       if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF)
                hwif->set_dma_mode = &aec6210_set_mode;
-       else
+       else
                hwif->set_dma_mode = &aec6260_set_mode;
 
-       hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
-
        if (hwif->dma_base == 0)
                return;
 
-       hwif->ultra_mask = hwif->cds->udma_mask;
-       hwif->mwdma_mask = 0x07;
-
-       hwif->dma_lost_irq      = &aec62xx_dma_lost_irq;
+       if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF)
+               return;
 
-       if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) {
-               spin_lock_irqsave(&ide_lock, flags);
-               pci_read_config_byte (dev, 0x54, &reg54);
-               pci_write_config_byte(dev, 0x54, (reg54 & ~mask));
-               spin_unlock_irqrestore(&ide_lock, flags);
-       } else if (hwif->cbl != ATA_CBL_PATA40_SHORT) {
+       if (hwif->cbl != ATA_CBL_PATA40_SHORT) {
                u8 ata66 = 0, mask = hwif->channel ? 0x02 : 0x01;
 
                pci_read_config_byte(hwif->pci_dev, 0x49, &ata66);
@@ -220,73 +194,53 @@ static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif)
        }
 }
 
-static int __devinit init_setup_aec62xx(struct pci_dev *dev, ide_pci_device_t *d)
-{
-       return ide_setup_pci_device(dev, d);
-}
-
-static int __devinit init_setup_aec6x80(struct pci_dev *dev, ide_pci_device_t *d)
-{
-       unsigned long dma_base = pci_resource_start(dev, 4);
-
-       if (inb(dma_base + 2) & 0x10) {
-               d->name = (dev->device == PCI_DEVICE_ID_ARTOP_ATP865R) ?
-                         "AEC6880R" : "AEC6880";
-               d->udma_mask = 0x7f; /* udma0-6 */
-       }
-
-       return ide_setup_pci_device(dev, d);
-}
-
-static ide_pci_device_t aec62xx_chipsets[] __devinitdata = {
+static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
        {       /* 0 */
                .name           = "AEC6210",
-               .init_setup     = init_setup_aec62xx,
                .init_chipset   = init_chipset_aec62xx,
                .init_hwif      = init_hwif_aec62xx,
-               .autodma        = AUTODMA,
                .enablebits     = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
-               .bootable       = OFF_BOARD,
+               .host_flags     = IDE_HFLAG_SERIALIZE |
+                                 IDE_HFLAG_NO_ATAPI_DMA |
+                                 IDE_HFLAG_OFF_BOARD,
                .pio_mask       = ATA_PIO4,
-               .udma_mask      = 0x07, /* udma0-2 */
+               .mwdma_mask     = ATA_MWDMA2,
+               .udma_mask      = ATA_UDMA2,
        },{     /* 1 */
                .name           = "AEC6260",
-               .init_setup     = init_setup_aec62xx,
                .init_chipset   = init_chipset_aec62xx,
                .init_hwif      = init_hwif_aec62xx,
-               .autodma        = NOAUTODMA,
-               .bootable       = OFF_BOARD,
+               .host_flags     = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_NO_AUTODMA |
+                                 IDE_HFLAG_OFF_BOARD,
                .pio_mask       = ATA_PIO4,
-               .udma_mask      = 0x1f, /* udma0-4 */
+               .mwdma_mask     = ATA_MWDMA2,
+               .udma_mask      = ATA_UDMA4,
        },{     /* 2 */
                .name           = "AEC6260R",
-               .init_setup     = init_setup_aec62xx,
                .init_chipset   = init_chipset_aec62xx,
                .init_hwif      = init_hwif_aec62xx,
-               .autodma        = AUTODMA,
                .enablebits     = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
-               .bootable       = NEVER_BOARD,
+               .host_flags     = IDE_HFLAG_NO_ATAPI_DMA,
                .pio_mask       = ATA_PIO4,
-               .udma_mask      = 0x1f, /* udma0-4 */
+               .mwdma_mask     = ATA_MWDMA2,
+               .udma_mask      = ATA_UDMA4,
        },{     /* 3 */
                .name           = "AEC6280",
-               .init_setup     = init_setup_aec6x80,
                .init_chipset   = init_chipset_aec62xx,
                .init_hwif      = init_hwif_aec62xx,
-               .autodma        = AUTODMA,
-               .bootable       = OFF_BOARD,
+               .host_flags     = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,
                .pio_mask       = ATA_PIO4,
-               .udma_mask      = 0x3f, /* udma0-5 */
+               .mwdma_mask     = ATA_MWDMA2,
+               .udma_mask      = ATA_UDMA5,
        },{     /* 4 */
                .name           = "AEC6280R",
-               .init_setup     = init_setup_aec6x80,
                .init_chipset   = init_chipset_aec62xx,
                .init_hwif      = init_hwif_aec62xx,
-               .autodma        = AUTODMA,
                .enablebits     = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
-               .bootable       = OFF_BOARD,
+               .host_flags     = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,
                .pio_mask       = ATA_PIO4,
-               .udma_mask      = 0x3f, /* udma0-5 */
+               .mwdma_mask     = ATA_MWDMA2,
+               .udma_mask      = ATA_UDMA5,
        }
 };
 
@@ -299,14 +253,26 @@ static ide_pci_device_t aec62xx_chipsets[] __devinitdata = {
  *     finds a device matching our IDE device tables.
  *
  *     NOTE: since we're going to modify the 'name' field for AEC-6[26]80[R]
- *     chips, pass a local copy of 'struct pci_device_id' down the call chain.
+ *     chips, pass a local copy of 'struct ide_port_info' down the call chain.
  */
+
 static int __devinit aec62xx_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       ide_pci_device_t d = aec62xx_chipsets[id->driver_data];
+       struct ide_port_info d;
+       u8 idx = id->driver_data;
+
+       d = aec62xx_chipsets[idx];
+
+       if (idx == 3 || idx == 4) {
+               unsigned long dma_base = pci_resource_start(dev, 4);
+
+               if (inb(dma_base + 2) & 0x10) {
+                       d.name = (idx == 4) ? "AEC6880R" : "AEC6880";
+                       d.udma_mask = ATA_UDMA6;
+               }
+       }
 
-       return d.init_setup(dev, &d);
+       return ide_setup_pci_device(dev, &d);
 }
 
 static const struct pci_device_id aec62xx_pci_tbl[] = {
index 31d4e50647d5881bbc3b274e0d9e0f59b9338554..a607dd31a64c58a9e23b7677d0702fb24cacd64e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/pci/alim15x3.c            Version 0.26    Jul 14 2007
+ * linux/drivers/ide/pci/alim15x3.c            Version 0.29    Sep 16 2007
  *
  *  Copyright (C) 1998-2000 Michel Aubry, Maintainer
  *  Copyright (C) 1998-2000 Andrzej Krzysztofowicz, Maintainer
@@ -492,6 +492,13 @@ static unsigned int __devinit init_chipset_ali15x3 (struct pci_dev *dev, const c
                 * clear bit 7
                 */
                pci_write_config_byte(dev, 0x4b, tmpbyte & 0x7F);
+               /*
+                * check m1533, 0x5e, bit 1~4 == 1001 => & 00011110 = 00010010
+                */
+               if (m5229_revision >= 0x20 && isa_dev) {
+                       pci_read_config_byte(isa_dev, 0x5e, &tmpbyte);
+                       chip_is_1543c_e = ((tmpbyte & 0x1e) == 0x12) ? 1: 0;
+               }
                goto out;
        }
 
@@ -537,7 +544,30 @@ static unsigned int __devinit init_chipset_ali15x3 (struct pci_dev *dev, const c
                        pci_write_config_byte(isa_dev, 0x79, tmpbyte | 0x02);
                }
        }
+
 out:
+       /*
+        * CD_ROM DMA on (m5229, 0x53, bit0)
+        *      Enable this bit even if we want to use PIO.
+        * PIO FIFO off (m5229, 0x53, bit1)
+        *      The hardware will use 0x54h and 0x55h to control PIO FIFO.
+        *      (Not on later devices it seems)
+        *
+        *      0x53 changes meaning on later revs - we must no touch
+        *      bit 1 on them.  Need to check if 0x20 is the right break.
+        */
+       if (m5229_revision >= 0x20) {
+               pci_read_config_byte(dev, 0x53, &tmpbyte);
+
+               if (m5229_revision <= 0x20)
+                       tmpbyte = (tmpbyte & (~0x02)) | 0x01;
+               else if (m5229_revision == 0xc7 || m5229_revision == 0xc8)
+                       tmpbyte |= 0x03;
+               else
+                       tmpbyte |= 0x01;
+
+               pci_write_config_byte(dev, 0x53, tmpbyte);
+       }
        pci_dev_put(north);
        pci_dev_put(isa_dev);
        local_irq_restore(flags);
@@ -616,36 +646,8 @@ static u8 __devinit ata66_ali15x3(ide_hwif_t *hwif)
                        if ((tmpbyte & (1 << hwif->channel)) == 0)
                                cbl = ATA_CBL_PATA80;
                }
-       } else {
-               /*
-                * check m1533, 0x5e, bit 1~4 == 1001 => & 00011110 = 00010010
-                */
-               pci_read_config_byte(isa_dev, 0x5e, &tmpbyte);
-               chip_is_1543c_e = ((tmpbyte & 0x1e) == 0x12) ? 1: 0;
        }
 
-       /*
-        * CD_ROM DMA on (m5229, 0x53, bit0)
-        *      Enable this bit even if we want to use PIO
-        * PIO FIFO off (m5229, 0x53, bit1)
-        *      The hardware will use 0x54h and 0x55h to control PIO FIFO
-        *      (Not on later devices it seems)
-        *
-        *      0x53 changes meaning on later revs - we must no touch
-        *      bit 1 on them. Need to check if 0x20 is the right break
-        */
-        
-       pci_read_config_byte(dev, 0x53, &tmpbyte);
-       
-       if(m5229_revision <= 0x20)
-               tmpbyte = (tmpbyte & (~0x02)) | 0x01;
-       else if (m5229_revision == 0xc7 || m5229_revision == 0xc8)
-               tmpbyte |= 0x03;
-       else
-               tmpbyte |= 0x01;
-
-       pci_write_config_byte(dev, 0x53, tmpbyte);
-
        local_irq_restore(flags);
 
        return cbl;
@@ -664,35 +666,8 @@ static void __devinit init_hwif_common_ali15x3 (ide_hwif_t *hwif)
        hwif->set_dma_mode = &ali_set_dma_mode;
        hwif->udma_filter = &ali_udma_filter;
 
-       /* don't use LBA48 DMA on ALi devices before rev 0xC5 */
-       hwif->no_lba48_dma = (m5229_revision <= 0xC4) ? 1 : 0;
-
-       if (!hwif->dma_base) {
-               hwif->drives[0].autotune = 1;
-               hwif->drives[1].autotune = 1;
+       if (hwif->dma_base == 0)
                return;
-       }
-
-       /*
-        * check in ->init_dma guarantees m5229_revision >= 0x20 here
-        */
-
-       if (m5229_revision > 0x20)
-               hwif->atapi_dma = 1;
-
-       if (m5229_revision <= 0x20)
-               hwif->ultra_mask = 0x00; /* no udma */
-       else if (m5229_revision < 0xC2)
-               hwif->ultra_mask = 0x07; /* udma0-2 */
-       else if (m5229_revision == 0xC2 || m5229_revision == 0xC3)
-               hwif->ultra_mask = 0x1f; /* udma0-4 */
-       else if (m5229_revision == 0xC4)
-               hwif->ultra_mask = 0x3f; /* udma0-5 */
-       else
-               hwif->ultra_mask = 0x7f; /* udma0-6 */
-
-       hwif->mwdma_mask = 0x07;
-       hwif->swdma_mask = 0x07;
 
        hwif->dma_setup = &ali15x3_dma_setup;
 
@@ -771,14 +746,15 @@ static void __devinit init_dma_ali15x3 (ide_hwif_t *hwif, unsigned long dmabase)
        ide_setup_dma(hwif, dmabase, 8);
 }
 
-static ide_pci_device_t ali15x3_chipset __devinitdata = {
+static const struct ide_port_info ali15x3_chipset __devinitdata = {
        .name           = "ALI15X3",
        .init_chipset   = init_chipset_ali15x3,
        .init_hwif      = init_hwif_ali15x3,
        .init_dma       = init_dma_ali15x3,
-       .autodma        = AUTODMA,
-       .bootable       = ON_BOARD,
+       .host_flags     = IDE_HFLAG_BOOTABLE,
        .pio_mask       = ATA_PIO5,
+       .swdma_mask     = ATA_SWDMA2,
+       .mwdma_mask     = ATA_MWDMA2,
 };
 
 /**
@@ -796,15 +772,34 @@ static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_dev
                { },
        };
 
-       ide_pci_device_t *d = &ali15x3_chipset;
+       struct ide_port_info d = ali15x3_chipset;
+       u8 rev = dev->revision;
 
        if (pci_dev_present(ati_rs100))
                printk(KERN_WARNING "alim15x3: ATI Radeon IGP Northbridge is not yet fully tested.\n");
 
+       /* don't use LBA48 DMA on ALi devices before rev 0xC5 */
+       if (rev <= 0xC4)
+               d.host_flags |= IDE_HFLAG_NO_LBA48_DMA;
+
+       if (rev >= 0x20) {
+               if (rev == 0x20)
+                       d.host_flags |= IDE_HFLAG_NO_ATAPI_DMA;
+
+               if (rev < 0xC2)
+                       d.udma_mask = ATA_UDMA2;
+               else if (rev == 0xC2 || rev == 0xC3)
+                       d.udma_mask = ATA_UDMA4;
+               else if (rev == 0xC4)
+                       d.udma_mask = ATA_UDMA5;
+               else
+                       d.udma_mask = ATA_UDMA6;
+       }
+
 #if defined(CONFIG_SPARC64)
-       d->init_hwif = init_hwif_common_ali15x3;
+       d.init_hwif = init_hwif_common_ali15x3;
 #endif /* CONFIG_SPARC64 */
-       return ide_setup_pci_device(dev, d);
+       return ide_setup_pci_device(dev, &d);
 }
 
 
index 3bf3d931eea1b84b6c5ce127a7620ba28eb1367d..8d4125ec252c102fd982158aeac8dd6e5cb4b4cc 100644 (file)
@@ -77,7 +77,7 @@ static struct amd_ide_chip {
 };
 
 static struct amd_ide_chip *amd_config;
-static ide_pci_device_t *amd_chipset;
+static const struct ide_port_info *amd_chipset;
 static unsigned int amd_80w;
 static unsigned int amd_clock;
 
@@ -233,7 +233,6 @@ static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, const ch
  * Print the boot message.
  */
 
-       pci_read_config_byte(dev, PCI_REVISION_ID, &t);
        printk(KERN_INFO "%s: %s (rev %02x) UDMA%s controller\n",
                amd_chipset->name, pci_name(dev), dev->revision,
                amd_dma[fls(amd_config->udma_mask) - 1]);
@@ -243,29 +242,18 @@ static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, const ch
 
 static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
 {
-       int i;
-
        if (hwif->irq == 0) /* 0 is bogus but will do for now */
                hwif->irq = pci_get_legacy_ide_irq(hwif->pci_dev, hwif->channel);
 
        hwif->set_pio_mode = &amd_set_pio_mode;
        hwif->set_dma_mode = &amd_set_drive;
 
-       for (i = 0; i < 2; i++) {
-               hwif->drives[i].io_32bit = 1;
-               hwif->drives[i].unmask = 1;
-               hwif->drives[i].autotune = 1;
-       }
-
        if (!hwif->dma_base)
                return;
 
-        hwif->atapi_dma = 1;
-
        hwif->ultra_mask = amd_config->udma_mask;
-       hwif->mwdma_mask = 0x07;
-       if ((amd_config->flags & AMD_BAD_SWDMA) == 0)
-               hwif->swdma_mask = 0x07;
+       if (amd_config->flags & AMD_BAD_SWDMA)
+               hwif->swdma_mask = 0x00;
 
        if (hwif->cbl != ATA_CBL_PATA40_SHORT) {
                if ((amd_80w >> hwif->channel) & 1)
@@ -275,18 +263,24 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
        }
 }
 
+#define IDE_HFLAGS_AMD \
+       (IDE_HFLAG_PIO_NO_BLACKLIST | \
+        IDE_HFLAG_PIO_NO_DOWNGRADE | \
+        IDE_HFLAG_POST_SET_MODE | \
+        IDE_HFLAG_IO_32BIT | \
+        IDE_HFLAG_UNMASK_IRQS | \
+        IDE_HFLAG_BOOTABLE)
+
 #define DECLARE_AMD_DEV(name_str)                                      \
        {                                                               \
                .name           = name_str,                             \
                .init_chipset   = init_chipset_amd74xx,                 \
                .init_hwif      = init_hwif_amd74xx,                    \
-               .autodma        = AUTODMA,                              \
                .enablebits     = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, \
-               .bootable       = ON_BOARD,                             \
-               .host_flags     = IDE_HFLAG_PIO_NO_BLACKLIST            \
-                               | IDE_HFLAG_PIO_NO_DOWNGRADE            \
-                               | IDE_HFLAG_POST_SET_MODE,              \
+               .host_flags     = IDE_HFLAGS_AMD,                       \
                .pio_mask       = ATA_PIO5,                             \
+               .swdma_mask     = ATA_SWDMA2,                           \
+               .mwdma_mask     = ATA_MWDMA2,                           \
        }
 
 #define DECLARE_NV_DEV(name_str)                                       \
@@ -294,16 +288,14 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
                .name           = name_str,                             \
                .init_chipset   = init_chipset_amd74xx,                 \
                .init_hwif      = init_hwif_amd74xx,                    \
-               .autodma        = AUTODMA,                              \
                .enablebits     = {{0x50,0x02,0x02}, {0x50,0x01,0x01}}, \
-               .bootable       = ON_BOARD,                             \
-               .host_flags     = IDE_HFLAG_PIO_NO_BLACKLIST            \
-                               | IDE_HFLAG_PIO_NO_DOWNGRADE            \
-                               | IDE_HFLAG_POST_SET_MODE,              \
+               .host_flags     = IDE_HFLAGS_AMD,                       \
                .pio_mask       = ATA_PIO5,                             \
+               .swdma_mask     = ATA_SWDMA2,                           \
+               .mwdma_mask     = ATA_MWDMA2,                           \
        }
 
-static ide_pci_device_t amd74xx_chipsets[] __devinitdata = {
+static const struct ide_port_info amd74xx_chipsets[] __devinitdata = {
        /*  0 */ DECLARE_AMD_DEV("AMD7401"),
        /*  1 */ DECLARE_AMD_DEV("AMD7409"),
        /*  2 */ DECLARE_AMD_DEV("AMD7411"),
index 446900da1329a6af1eb92e70f66959386947ad4c..ef8e0164ef7a019e560608741d3b880ed6a12452 100644 (file)
@@ -172,21 +172,12 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif)
        u8 ch = hwif->channel;
        struct pci_dev *pdev = hwif->pci_dev;
 
-       if (!hwif->irq)
-               hwif->irq = ch ? 15 : 14;
-
        hwif->set_pio_mode = &atiixp_set_pio_mode;
        hwif->set_dma_mode = &atiixp_set_dma_mode;
-       hwif->drives[0].autotune = 1;
-       hwif->drives[1].autotune = 1;
 
        if (!hwif->dma_base)
                return;
 
-       hwif->atapi_dma = 1;
-       hwif->ultra_mask = 0x3f;
-       hwif->mwdma_mask = 0x07;
-
        pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ch, &udma_mode);
 
        if ((udma_mode & 0x07) >= 0x04 || (udma_mode & 0x70) >= 0x40)
@@ -198,23 +189,24 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif)
        hwif->dma_host_off = &atiixp_dma_host_off;
 }
 
-
-static ide_pci_device_t atiixp_pci_info[] __devinitdata = {
+static const struct ide_port_info atiixp_pci_info[] __devinitdata = {
        {       /* 0 */
                .name           = "ATIIXP",
                .init_hwif      = init_hwif_atiixp,
-               .autodma        = AUTODMA,
                .enablebits     = {{0x48,0x01,0x00}, {0x48,0x08,0x00}},
-               .bootable       = ON_BOARD,
+               .host_flags     = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE,
                .pio_mask       = ATA_PIO4,
+               .mwdma_mask     = ATA_MWDMA2,
+               .udma_mask      = ATA_UDMA5,
        },{     /* 1 */
                .name           = "SB600_PATA",
                .init_hwif      = init_hwif_atiixp,
-               .autodma        = AUTODMA,
                .enablebits     = {{0x48,0x01,0x00}, {0x00,0x00,0x00}},
-               .bootable       = ON_BOARD,
-               .host_flags     = IDE_HFLAG_SINGLE,
+               .host_flags     = IDE_HFLAG_SINGLE | IDE_HFLAG_LEGACY_IRQS |
+                                 IDE_HFLAG_BOOTABLE,
                .pio_mask       = ATA_PIO4,
+               .mwdma_mask     = ATA_MWDMA2,
+               .udma_mask      = ATA_UDMA5,
        },
 };
 
index f369645e4d1645ce91651df6742c78302fc3752b..4aa48104e0c1c5cb3e7d787efa2983ccd4e4899f 100644 (file)
@@ -185,6 +185,8 @@ static u8 recovery_counts[4] = {16, 16, 16, 16}; /* Recovery count (encoded) */
 
 #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
 
+static DEFINE_SPINLOCK(cmd640_lock);
+
 /*
  * These are initialized to point at the devices we control
  */
@@ -258,12 +260,12 @@ static u8 get_cmd640_reg_vlb (u16 reg)
 
 static u8 get_cmd640_reg(u16 reg)
 {
-       u8 b;
        unsigned long flags;
+       u8 b;
 
-       spin_lock_irqsave(&ide_lock, flags);
+       spin_lock_irqsave(&cmd640_lock, flags);
        b = __get_cmd640_reg(reg);
-       spin_unlock_irqrestore(&ide_lock, flags);
+       spin_unlock_irqrestore(&cmd640_lock, flags);
        return b;
 }
 
@@ -271,9 +273,9 @@ static void put_cmd640_reg(u16 reg, u8 val)
 {
        unsigned long flags;
 
-       spin_lock_irqsave(&ide_lock, flags);
+       spin_lock_irqsave(&cmd640_lock, flags);
        __put_cmd640_reg(reg,val);
-       spin_unlock_irqrestore(&ide_lock, flags);
+       spin_unlock_irqrestore(&cmd640_lock, flags);
 }
 
 static int __init match_pci_cmd640_device (void)
@@ -351,7 +353,7 @@ static int __init secondary_port_responding (void)
 {
        unsigned long flags;
 
-       spin_lock_irqsave(&ide_lock, flags);
+       spin_lock_irqsave(&cmd640_lock, flags);
 
        outb_p(0x0a, 0x170 + IDE_SELECT_OFFSET);        /* select drive0 */
        udelay(100);
@@ -359,11 +361,11 @@ static int __init secondary_port_responding (void)
                outb_p(0x1a, 0x170 + IDE_SELECT_OFFSET); /* select drive1 */
                udelay(100);
                if ((inb_p(0x170 + IDE_SELECT_OFFSET) & 0x1f) != 0x1a) {
-                       spin_unlock_irqrestore(&ide_lock, flags);
+                       spin_unlock_irqrestore(&cmd640_lock, flags);
                        return 0; /* nothing responded */
                }
        }
-       spin_unlock_irqrestore(&ide_lock, flags);
+       spin_unlock_irqrestore(&cmd640_lock, flags);
        return 1; /* success */
 }
 
@@ -440,11 +442,11 @@ static void __init setup_device_ptrs (void)
 static void set_prefetch_mode (unsigned int index, int mode)
 {
        ide_drive_t *drive = cmd_drives[index];
+       unsigned long flags;
        int reg = prefetch_regs[index];
        u8 b;
-       unsigned long flags;
 
-       spin_lock_irqsave(&ide_lock, flags);
+       spin_lock_irqsave(&cmd640_lock, flags);
        b = __get_cmd640_reg(reg);
        if (mode) {     /* want prefetch on? */
 #if CMD640_PREFETCH_MASKS
@@ -460,7 +462,7 @@ static void set_prefetch_mode (unsigned int index, int mode)
                b |= prefetch_masks[index];     /* disable prefetch */
        }
        __put_cmd640_reg(reg, b);
-       spin_unlock_irqrestore(&ide_lock, flags);
+       spin_unlock_irqrestore(&cmd640_lock, flags);
 }
 
 /*
@@ -561,7 +563,7 @@ static void program_drive_counts (unsigned int index)
        /*
         * Now that everything is ready, program the new timings
         */
-       spin_lock_irqsave(&ide_lock, flags);
+       spin_lock_irqsave(&cmd640_lock, flags);
        /*
         * Program the address_setup clocks into ARTTIM reg,
         * and then the active/recovery counts into the DRWTIM reg
@@ -570,7 +572,7 @@ static void program_drive_counts (unsigned int index)
        setup_count |= __get_cmd640_reg(arttim_regs[index]) & 0x3f;
        __put_cmd640_reg(arttim_regs[index], setup_count);
        __put_cmd640_reg(drwtim_regs[index], pack_nibbles(active_count, recovery_count));
-       spin_unlock_irqrestore(&ide_lock, flags);
+       spin_unlock_irqrestore(&cmd640_lock, flags);
 }
 
 /*
@@ -670,20 +672,20 @@ static void cmd640_set_pio_mode(ide_drive_t *drive, const u8 pio)
 
 static int pci_conf1(void)
 {
-       u32 tmp;
        unsigned long flags;
+       u32 tmp;
 
-       spin_lock_irqsave(&ide_lock, flags);
+       spin_lock_irqsave(&cmd640_lock, flags);
        outb(0x01, 0xCFB);
        tmp = inl(0xCF8);
        outl(0x80000000, 0xCF8);
        if (inl(0xCF8) == 0x80000000) {
                outl(tmp, 0xCF8);
-               spin_unlock_irqrestore(&ide_lock, flags);
+               spin_unlock_irqrestore(&cmd640_lock, flags);
                return 1;
        }
        outl(tmp, 0xCF8);
-       spin_unlock_irqrestore(&ide_lock, flags);
+       spin_unlock_irqrestore(&cmd640_lock, flags);
        return 0;
 }
 
@@ -691,15 +693,15 @@ static int pci_conf2(void)
 {
        unsigned long flags;
 
-       spin_lock_irqsave(&ide_lock, flags);
+       spin_lock_irqsave(&cmd640_lock, flags);
        outb(0x00, 0xCFB);
        outb(0x00, 0xCF8);
        outb(0x00, 0xCFA);
        if (inb(0xCF8) == 0x00 && inb(0xCF8) == 0x00) {
-               spin_unlock_irqrestore(&ide_lock, flags);
+               spin_unlock_irqrestore(&cmd640_lock, flags);
                return 1;
        }
-       spin_unlock_irqrestore(&ide_lock, flags);
+       spin_unlock_irqrestore(&cmd640_lock, flags);
        return 0;
 }
 
index f3d3bde8daba7596436de42b00df10de31fd32df..ea0143ef5fe5aee02df0e09442f790f5f68a6fcd 100644 (file)
@@ -439,11 +439,8 @@ static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const cha
        u8 mrdmode = 0;
 
        if (dev->device == PCI_DEVICE_ID_CMD_646) {
-               u8 rev = 0;
 
-               pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
-
-               switch (rev) {
+               switch (dev->revision) {
                case 0x07:
                case 0x05:
                        printk("%s: UltraDMA capable\n", name);
@@ -505,22 +502,13 @@ static u8 __devinit ata66_cmd64x(ide_hwif_t *hwif)
 static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
 {
        struct pci_dev *dev     = hwif->pci_dev;
-       u8 rev                  = 0;
-
-       pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
 
        hwif->set_pio_mode = &cmd64x_set_pio_mode;
        hwif->set_dma_mode = &cmd64x_set_dma_mode;
 
-       hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
-
        if (!hwif->dma_base)
                return;
 
-       hwif->atapi_dma  = 1;
-       hwif->mwdma_mask = 0x07;
-       hwif->ultra_mask = hwif->cds->udma_mask;
-
        /*
         * UltraDMA only supported on PCI646U and PCI646U2, which
         * correspond to revisions 0x03, 0x05 and 0x07 respectively.
@@ -533,7 +521,7 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
         *
         * So we only do UltraDMA on revision 0x05 and 0x07 chipsets.
         */
-       if (dev->device == PCI_DEVICE_ID_CMD_646 && rev < 5)
+       if (dev->device == PCI_DEVICE_ID_CMD_646 && dev->revision < 5)
                hwif->ultra_mask = 0x00;
 
        if (hwif->cbl != ATA_CBL_PATA40_SHORT)
@@ -547,11 +535,10 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
                hwif->ide_dma_test_irq  = &cmd648_ide_dma_test_irq;
                break;
        case PCI_DEVICE_ID_CMD_646:
-               hwif->chipset = ide_cmd646;
-               if (rev == 0x01) {
+               if (dev->revision == 0x01) {
                        hwif->ide_dma_end = &cmd646_1_ide_dma_end;
                        break;
-               } else if (rev >= 0x03)
+               } else if (dev->revision >= 0x03)
                        goto alt_irq_bits;
                /* fall thru */
        default:
@@ -561,80 +548,62 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
        }
 }
 
-static int __devinit init_setup_cmd64x(struct pci_dev *dev, ide_pci_device_t *d)
-{
-       return ide_setup_pci_device(dev, d);
-}
-
-static int __devinit init_setup_cmd646(struct pci_dev *dev, ide_pci_device_t *d)
-{
-       /*
-        * The original PCI0646 didn't have the primary channel enable bit,
-        * it appeared starting with PCI0646U (i.e. revision ID 3).
-        */
-       if (dev->revision < 3)
-               d->enablebits[0].reg = 0;
-
-       return ide_setup_pci_device(dev, d);
-}
-
-static ide_pci_device_t cmd64x_chipsets[] __devinitdata = {
+static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
        {       /* 0 */
                .name           = "CMD643",
-               .init_setup     = init_setup_cmd64x,
                .init_chipset   = init_chipset_cmd64x,
                .init_hwif      = init_hwif_cmd64x,
-               .autodma        = AUTODMA,
                .enablebits     = {{0x00,0x00,0x00}, {0x51,0x08,0x08}},
-               .bootable       = ON_BOARD,
-               .host_flags     = IDE_HFLAG_ABUSE_PREFETCH,
+               .host_flags     = IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE,
                .pio_mask       = ATA_PIO5,
+               .mwdma_mask     = ATA_MWDMA2,
                .udma_mask      = 0x00, /* no udma */
        },{     /* 1 */
                .name           = "CMD646",
-               .init_setup     = init_setup_cmd646,
                .init_chipset   = init_chipset_cmd64x,
                .init_hwif      = init_hwif_cmd64x,
-               .autodma        = AUTODMA,
                .enablebits     = {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
-               .bootable       = ON_BOARD,
-               .host_flags     = IDE_HFLAG_ABUSE_PREFETCH,
+               .host_flags     = IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE,
                .pio_mask       = ATA_PIO5,
-               .udma_mask      = 0x07, /* udma0-2 */
+               .mwdma_mask     = ATA_MWDMA2,
+               .udma_mask      = ATA_UDMA2,
        },{     /* 2 */
                .name           = "CMD648",
-               .init_setup     = init_setup_cmd64x,
                .init_chipset   = init_chipset_cmd64x,
                .init_hwif      = init_hwif_cmd64x,
-               .autodma        = AUTODMA,
                .enablebits     = {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
-               .bootable       = ON_BOARD,
-               .host_flags     = IDE_HFLAG_ABUSE_PREFETCH,
+               .chipset        = ide_cmd646,
+               .host_flags     = IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE,
                .pio_mask       = ATA_PIO5,
-               .udma_mask      = 0x1f, /* udma0-4 */
+               .mwdma_mask     = ATA_MWDMA2,
+               .udma_mask      = ATA_UDMA4,
        },{     /* 3 */
                .name           = "CMD649",
-               .init_setup     = init_setup_cmd64x,
                .init_chipset   = init_chipset_cmd64x,
                .init_hwif      = init_hwif_cmd64x,
-               .autodma        = AUTODMA,
                .enablebits     = {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
-               .bootable       = ON_BOARD,
-               .host_flags     = IDE_HFLAG_ABUSE_PREFETCH,
+               .host_flags     = IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE,
                .pio_mask       = ATA_PIO5,
-               .udma_mask      = 0x3f, /* udma0-5 */
+               .mwdma_mask     = ATA_MWDMA2,
+               .udma_mask      = ATA_UDMA5,
        }
 };
 
-/*
- * We may have to modify enablebits for PCI0646, so we'd better pass
- * a local copy of the ide_pci_device_t structure down the call chain...
- */
 static int __devinit cmd64x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       ide_pci_device_t d = cmd64x_chipsets[id->driver_data];
+       struct ide_port_info d;
+       u8 idx = id->driver_data;
+
+       d = cmd64x_chipsets[idx];
+
+       /*
+        * The original PCI0646 didn't have the primary channel enable bit,
+        * it appeared starting with PCI0646U (i.e. revision ID 3).
+        */
+       if (idx == 1 && dev->revision < 3)
+               d.enablebits[0].reg = 0;
 
-       return d.init_setup(dev, &d);
+       return ide_setup_pci_device(dev, &d);
 }
 
 static const struct pci_device_id cmd64x_pci_tbl[] = {
index a8bf4940ca9c3941461b1c6c4bdc2c73a793d8fe..0466462fd21b9a7ce82b9ab6789d0aa7648ff273 100644 (file)
@@ -105,18 +105,6 @@ static void cs5520_set_dma_mode(ide_drive_t *drive, const u8 speed)
        cs5520_set_pio_mode(drive, 0);
 }
 
-/*
- *     We provide a callback for our nonstandard DMA location
- */
-
-static void __devinit cs5520_init_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwif_t *hwif)
-{
-       unsigned long bmide = pci_resource_start(dev, 2);       /* Not the usual 4 */
-       if(hwif->mate && hwif->mate->dma_base)  /* Second channel at primary + 8 */
-               bmide += 8;
-       ide_setup_dma(hwif, bmide, 8);
-}
-
 /*
  *     We wrap the DMA activate to set the vdma flag. This is needed
  *     so that the IDE DMA layer issues PIO not DMA commands over the
@@ -125,6 +113,7 @@ static void __devinit cs5520_init_setup_dma(struct pci_dev *dev, ide_pci_device_
  
 static int cs5520_dma_on(ide_drive_t *drive)
 {
+       /* ATAPI is harder so leave it for now */
        drive->vdma = 1;
        return 0;
 }
@@ -134,33 +123,25 @@ static void __devinit init_hwif_cs5520(ide_hwif_t *hwif)
        hwif->set_pio_mode = &cs5520_set_pio_mode;
        hwif->set_dma_mode = &cs5520_set_dma_mode;
 
-       if (hwif->dma_base == 0) {
-               hwif->drives[1].autotune = hwif->drives[0].autotune = 1;
+       if (hwif->dma_base == 0)
                return;
-       }
 
        hwif->ide_dma_on = &cs5520_dma_on;
-
-       /* ATAPI is harder so leave it for now */
-       hwif->atapi_dma = 0;
-       hwif->ultra_mask = 0;
-       hwif->swdma_mask = 0;
-       hwif->mwdma_mask = 0;
 }
 
 #define DECLARE_CS_DEV(name_str)                               \
        {                                                       \
                .name           = name_str,                     \
-               .init_setup_dma = cs5520_init_setup_dma,        \
                .init_hwif      = init_hwif_cs5520,             \
-               .autodma        = AUTODMA,                      \
-               .bootable       = ON_BOARD,                     \
                .host_flags     = IDE_HFLAG_ISA_PORTS |         \
-                                 IDE_HFLAG_VDMA,               \
+                                 IDE_HFLAG_CS5520 |            \
+                                 IDE_HFLAG_VDMA |              \
+                                 IDE_HFLAG_NO_ATAPI_DMA |      \
+                                 IDE_HFLAG_BOOTABLE,           \
                .pio_mask       = ATA_PIO4,                     \
        }
 
-static ide_pci_device_t cyrix_chipsets[] __devinitdata = {
+static const struct ide_port_info cyrix_chipsets[] __devinitdata = {
        /* 0 */ DECLARE_CS_DEV("Cyrix 5510"),
        /* 1 */ DECLARE_CS_DEV("Cyrix 5520")
 };
@@ -173,9 +154,8 @@ static ide_pci_device_t cyrix_chipsets[] __devinitdata = {
  
 static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       ide_hwif_t *hwif = NULL, *mate = NULL;
-       ata_index_t index;
-       ide_pci_device_t *d = &cyrix_chipsets[id->driver_data];
+       const struct ide_port_info *d = &cyrix_chipsets[id->driver_data];
+       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 
        ide_setup_pci_noise(dev, d);
 
@@ -191,29 +171,14 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic
                return -ENODEV;
        }
 
-       index.all = 0xf0f0;
-
        /*
         *      Now the chipset is configured we can let the core
         *      do all the device setup for us
         */
 
-       ide_pci_setup_ports(dev, d, 14, &index);
-
-       if ((index.b.low & 0xf0) != 0xf0)
-               hwif = &ide_hwifs[index.b.low];
-       if ((index.b.high & 0xf0) != 0xf0)
-               mate = &ide_hwifs[index.b.high];
-
-       if (hwif)
-               probe_hwif_init(hwif);
-       if (mate)
-               probe_hwif_init(mate);
+       ide_pci_setup_ports(dev, d, 14, &idx[0]);
 
-       if (hwif)
-               ide_proc_register_port(hwif);
-       if (mate)
-               ide_proc_register_port(mate);
+       ide_device_add(idx);
 
        return 0;
 }
index 0d23b8aabe9ca4989a453a274ef313c4750f2aca..599408952bd4cbae54410f3de2e306eda9c101b4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/pci/cs5530.c              Version 0.76    Aug 3 2007
+ * linux/drivers/ide/pci/cs5530.c              Version 0.77    Sep 24 2007
  *
  * Copyright (C) 2000                  Andre Hedrick <andre@linux-ide.org>
  * Copyright (C) 2000                  Mark Lord <mlord@pobox.com>
@@ -146,7 +146,6 @@ static void cs5530_set_dma_mode(ide_drive_t *drive, const u8 mode)
 static unsigned int __devinit init_chipset_cs5530 (struct pci_dev *dev, const char *name)
 {
        struct pci_dev *master_0 = NULL, *cs5530_0 = NULL;
-       unsigned long flags;
 
        if (pci_resource_start(dev, 4) == 0)
                return -EFAULT;
@@ -171,9 +170,6 @@ static unsigned int __devinit init_chipset_cs5530 (struct pci_dev *dev, const ch
                goto out;
        }
 
-       spin_lock_irqsave(&ide_lock, flags);
-               /* all CPUs (there should only be one CPU with this chipset) */
-
        /*
         * Enable BusMaster and MemoryWriteAndInvalidate for the cs5530:
         * -->  OR 0x14 into 16-bit PCI COMMAND reg of function 0 of the cs5530
@@ -224,8 +220,6 @@ static unsigned int __devinit init_chipset_cs5530 (struct pci_dev *dev, const ch
        pci_write_config_byte(master_0, 0x42, 0x00);
        pci_write_config_byte(master_0, 0x43, 0xc1);
 
-       spin_unlock_irqrestore(&ide_lock, flags);
-
 out:
        pci_dev_put(master_0);
        pci_dev_put(cs5530_0);
@@ -245,9 +239,6 @@ static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif)
        unsigned long basereg;
        u32 d0_timings;
 
-       if (hwif->mate)
-               hwif->serialized = hwif->mate->serialized = 1;
-
        hwif->set_pio_mode = &cs5530_set_pio_mode;
        hwif->set_dma_mode = &cs5530_set_dma_mode;
 
@@ -258,27 +249,22 @@ static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif)
        if (CS5530_BAD_PIO(inl(basereg + 8)))
                outl(cs5530_pio_timings[(d0_timings >> 31) & 1][0], basereg + 8);
 
-       hwif->drives[0].autotune = 1;
-       hwif->drives[1].autotune = 1;
-
        if (hwif->dma_base == 0)
                return;
 
-       hwif->atapi_dma = 1;
-       hwif->ultra_mask = 0x07;
-       hwif->mwdma_mask = 0x07;
-
        hwif->udma_filter = cs5530_udma_filter;
 }
 
-static ide_pci_device_t cs5530_chipset __devinitdata = {
+static const struct ide_port_info cs5530_chipset __devinitdata = {
        .name           = "CS5530",
        .init_chipset   = init_chipset_cs5530,
        .init_hwif      = init_hwif_cs5530,
-       .autodma        = AUTODMA,
-       .bootable       = ON_BOARD,
+       .host_flags     = IDE_HFLAG_SERIALIZE |
+                         IDE_HFLAG_POST_SET_MODE |
+                         IDE_HFLAG_BOOTABLE,
        .pio_mask       = ATA_PIO4,
-       .host_flags     = IDE_HFLAG_POST_SET_MODE,
+       .mwdma_mask     = ATA_MWDMA2,
+       .udma_mask      = ATA_UDMA2,
 };
 
 static int __devinit cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id)
index e4891a16afeff3f076700c1d9d506b657a747d71..9094916e37803c61a02306f0d402653a771a2fc7 100644 (file)
@@ -84,7 +84,7 @@ static void cs5535_set_speed(ide_drive_t *drive, const u8 speed)
 
        /* Set the PIO timings */
        if ((speed & XFER_MODE) == XFER_PIO) {
-               ide_drive_t *pair = &drive->hwif->drives[drive->dn ^ 1];
+               ide_drive_t *pair = ide_get_paired_drive(drive);
                u8 cmd, pioa;
 
                cmd = pioa = speed - XFER_PIO_0;
@@ -180,25 +180,20 @@ static void __devinit init_hwif_cs5535(ide_hwif_t *hwif)
        hwif->set_pio_mode = &cs5535_set_pio_mode;
        hwif->set_dma_mode = &cs5535_set_dma_mode;
 
-       hwif->drives[1].autotune = hwif->drives[0].autotune = 1;
-
        if (hwif->dma_base == 0)
                return;
 
-       hwif->atapi_dma = 1;
-       hwif->ultra_mask = 0x1F;
-       hwif->mwdma_mask = 0x07;
-
        hwif->cbl = cs5535_cable_detect(hwif->pci_dev);
 }
 
-static ide_pci_device_t cs5535_chipset __devinitdata = {
+static const struct ide_port_info cs5535_chipset __devinitdata = {
        .name           = "CS5535",
        .init_hwif      = init_hwif_cs5535,
-       .autodma        = AUTODMA,
-       .bootable       = ON_BOARD,
-       .host_flags     = IDE_HFLAG_SINGLE | IDE_HFLAG_POST_SET_MODE,
+       .host_flags     = IDE_HFLAG_SINGLE | IDE_HFLAG_POST_SET_MODE |
+                         IDE_HFLAG_BOOTABLE,
        .pio_mask       = ATA_PIO4,
+       .mwdma_mask     = ATA_MWDMA2,
+       .udma_mask      = ATA_UDMA4,
 };
 
 static int __devinit cs5535_init_one(struct pci_dev *dev,
index c498ecfd7fcb35d9f813fa510adff7b39ecfc909..3ef4fc10fe2cf596e463634d19c8fe01c842458b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/pci/cy82c693.c            Version 0.40    Sep. 10, 2002
+ * linux/drivers/ide/pci/cy82c693.c            Version 0.41    Aug 27, 2007
  *
  *  Copyright (C) 1998-2000 Andreas S. Krebs (akrebs@altavista.net), Maintainer
  *  Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>, Integrator
@@ -428,18 +428,10 @@ static unsigned int __devinit init_chipset_cy82c693(struct pci_dev *dev, const c
  */
 static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif)
 {
-       hwif->chipset = ide_cy82c693;
        hwif->set_pio_mode = &cy82c693_set_pio_mode;
 
-       if (!hwif->dma_base) {
-               hwif->drives[0].autotune = 1;
-               hwif->drives[1].autotune = 1;
+       if (hwif->dma_base == 0)
                return;
-       }
-
-       hwif->atapi_dma = 1;
-       hwif->mwdma_mask = 0x04;
-       hwif->swdma_mask = 0x04;
 
        hwif->ide_dma_on = &cy82c693_ide_dma_on;
 }
@@ -456,15 +448,17 @@ static void __devinit init_iops_cy82c693(ide_hwif_t *hwif)
        }
 }
 
-static ide_pci_device_t cy82c693_chipset __devinitdata = {
+static const struct ide_port_info cy82c693_chipset __devinitdata = {
        .name           = "CY82C693",
        .init_chipset   = init_chipset_cy82c693,
        .init_iops      = init_iops_cy82c693,
        .init_hwif      = init_hwif_cy82c693,
-       .autodma        = AUTODMA,
-       .bootable       = ON_BOARD,
-       .host_flags     = IDE_HFLAG_SINGLE | IDE_HFLAG_TRUST_BIOS_FOR_DMA,
+       .chipset        = ide_cy82c693,
+       .host_flags     = IDE_HFLAG_SINGLE | IDE_HFLAG_TRUST_BIOS_FOR_DMA |
+                         IDE_HFLAG_BOOTABLE,
        .pio_mask       = ATA_PIO4,
+       .swdma_mask     = ATA_SWDMA2_ONLY,
+       .mwdma_mask     = ATA_MWDMA2_ONLY,
 };
 
 static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_device_id *id)
index 46f4a888c03711c341eddaeea2be7933e3bcbf57..83829081640a6f84727f18260a169477e8d3d257 100644 (file)
@@ -80,7 +80,7 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
        hw.irq = dev->irq;
        hw.chipset = ide_pci;           /* this enables IRQ sharing */
 
-       rc = ide_register_hw_with_fixup(&hw, 0, &hwif, ide_undecoded_slave);
+       rc = ide_register_hw(&hw, &ide_undecoded_slave, 0, &hwif);
        if (rc < 0) {
                printk(KERN_ERR "delkin_cb: ide_register_hw failed (%d)\n", rc);
                pci_disable_device(dev);
index cce6311b02df73660eb3bb697ab11c7a377bc556..f44d70852c3cc9c18efcb4bae6b75ba3294f2762 100644 (file)
@@ -54,130 +54,61 @@ __setup("all-generic-ide", ide_generic_all_on);
 module_param_named(all_generic_ide, ide_generic_all, bool, 0444);
 MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers.");
 
-static void __devinit init_hwif_generic (ide_hwif_t *hwif)
-{
-       switch(hwif->pci_dev->device) {
-               case PCI_DEVICE_ID_UMC_UM8673F:
-               case PCI_DEVICE_ID_UMC_UM8886A:
-               case PCI_DEVICE_ID_UMC_UM8886BF:
-                       hwif->irq = hwif->channel ? 15 : 14;
-                       break;
-               default:
-                       break;
+#define IDE_HFLAGS_UMC (IDE_HFLAG_NO_DMA | IDE_HFLAG_FORCE_LEGACY_IRQS)
+
+#define DECLARE_GENERIC_PCI_DEV(name_str, extra_flags) \
+       { \
+               .name           = name_str, \
+               .host_flags     = IDE_HFLAG_TRUST_BIOS_FOR_DMA | \
+                                 extra_flags | \
+                                 IDE_HFLAG_BOOTABLE, \
+               .swdma_mask     = ATA_SWDMA2, \
+               .mwdma_mask     = ATA_MWDMA2, \
+               .udma_mask      = ATA_UDMA6, \
        }
 
-       if (!(hwif->dma_base))
-               return;
-
-       hwif->atapi_dma = 1;
-       hwif->ultra_mask = 0x7f;
-       hwif->mwdma_mask = 0x07;
-       hwif->swdma_mask = 0x07;
-}
-
-#if 0
-       /* Logic to add back later on */
-
-       if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
-               ide_pci_device_t *unknown = unknown_chipset;
-               init_setup_unknown(dev, unknown);
-               return 1;
-       }
-       return 0;
-#endif 
+static const struct ide_port_info generic_chipsets[] __devinitdata = {
+       /*  0 */ DECLARE_GENERIC_PCI_DEV("Unknown",     0),
 
-static ide_pci_device_t generic_chipsets[] __devinitdata = {
-       {       /* 0 */
-               .name           = "Unknown",
-               .init_hwif      = init_hwif_generic,
-               .autodma        = AUTODMA,
-               .bootable       = ON_BOARD,
-               .host_flags     = IDE_HFLAG_TRUST_BIOS_FOR_DMA,
-       },{     /* 1 */
+       {       /* 1 */
                .name           = "NS87410",
-               .init_hwif      = init_hwif_generic,
-               .autodma        = AUTODMA,
                .enablebits     = {{0x43,0x08,0x08}, {0x47,0x08,0x08}},
-               .bootable       = ON_BOARD,
-               .host_flags     = IDE_HFLAG_TRUST_BIOS_FOR_DMA,
-        },{    /* 2 */
-               .name           = "SAMURAI",
-               .init_hwif      = init_hwif_generic,
-               .autodma        = AUTODMA,
-               .bootable       = ON_BOARD,
-               .host_flags     = IDE_HFLAG_TRUST_BIOS_FOR_DMA,
-       },{     /* 3 */
-               .name           = "HT6565",
-               .init_hwif      = init_hwif_generic,
-               .autodma        = AUTODMA,
-               .bootable       = ON_BOARD,
-               .host_flags     = IDE_HFLAG_TRUST_BIOS_FOR_DMA,
-       },{     /* 4 */
-               .name           = "UM8673F",
-               .init_hwif      = init_hwif_generic,
-               .autodma        = NODMA,
-               .bootable       = ON_BOARD,
-               .host_flags     = IDE_HFLAG_TRUST_BIOS_FOR_DMA,
-       },{     /* 5 */
-               .name           = "UM8886A",
-               .init_hwif      = init_hwif_generic,
-               .autodma        = NODMA,
-               .bootable       = ON_BOARD,
-               .host_flags     = IDE_HFLAG_TRUST_BIOS_FOR_DMA,
-       },{     /* 6 */
-               .name           = "UM8886BF",
-               .init_hwif      = init_hwif_generic,
-               .autodma        = NODMA,
-               .bootable       = ON_BOARD,
-               .host_flags     = IDE_HFLAG_TRUST_BIOS_FOR_DMA,
-       },{     /* 7 */
-               .name           = "HINT_IDE",
-               .init_hwif      = init_hwif_generic,
-               .autodma        = AUTODMA,
-               .bootable       = ON_BOARD,
-               .host_flags     = IDE_HFLAG_TRUST_BIOS_FOR_DMA,
-       },{     /* 8 */
-               .name           = "VIA_IDE",
-               .init_hwif      = init_hwif_generic,
-               .autodma        = NOAUTODMA,
-               .bootable       = ON_BOARD,
-               .host_flags     = IDE_HFLAG_TRUST_BIOS_FOR_DMA,
-       },{     /* 9 */
-               .name           = "OPTI621V",
-               .init_hwif      = init_hwif_generic,
-               .autodma        = NOAUTODMA,
-               .bootable       = ON_BOARD,
-               .host_flags     = IDE_HFLAG_TRUST_BIOS_FOR_DMA,
-       },{     /* 10 */
+               .host_flags     = IDE_HFLAG_TRUST_BIOS_FOR_DMA |
+                                 IDE_HFLAG_BOOTABLE,
+               .swdma_mask     = ATA_SWDMA2,
+               .mwdma_mask     = ATA_MWDMA2,
+               .udma_mask      = ATA_UDMA6,
+       },
+
+       /*  2 */ DECLARE_GENERIC_PCI_DEV("SAMURAI",     0),
+       /*  3 */ DECLARE_GENERIC_PCI_DEV("HT6565",      0),
+       /*  4 */ DECLARE_GENERIC_PCI_DEV("UM8673F",     IDE_HFLAGS_UMC),
+       /*  5 */ DECLARE_GENERIC_PCI_DEV("UM8886A",     IDE_HFLAGS_UMC),
+       /*  6 */ DECLARE_GENERIC_PCI_DEV("UM8886BF",    IDE_HFLAGS_UMC),
+       /*  7 */ DECLARE_GENERIC_PCI_DEV("HINT_IDE",    0),
+       /*  8 */ DECLARE_GENERIC_PCI_DEV("VIA_IDE",     IDE_HFLAG_NO_AUTODMA),
+       /*  9 */ DECLARE_GENERIC_PCI_DEV("OPTI621V",    IDE_HFLAG_NO_AUTODMA),
+
+       {       /* 10 */
                .name           = "VIA8237SATA",
-               .init_hwif      = init_hwif_generic,
-               .autodma        = AUTODMA,
-               .bootable       = OFF_BOARD,
-               .host_flags     = IDE_HFLAG_TRUST_BIOS_FOR_DMA,
-       },{     /* 11 */
-               .name           = "Piccolo0102",
-               .init_hwif      = init_hwif_generic,
-               .autodma        = NOAUTODMA,
-               .bootable       = ON_BOARD,
-               .host_flags     = IDE_HFLAG_TRUST_BIOS_FOR_DMA,
-       },{     /* 12 */
-               .name           = "Piccolo0103",
-               .init_hwif      = init_hwif_generic,
-               .autodma        = NOAUTODMA,
-               .bootable       = ON_BOARD,
-               .host_flags     = IDE_HFLAG_TRUST_BIOS_FOR_DMA,
-       },{     /* 13 */
-               .name           = "Piccolo0105",
-               .init_hwif      = init_hwif_generic,
-               .autodma        = NOAUTODMA,
-               .bootable       = ON_BOARD,
-               .host_flags     = IDE_HFLAG_TRUST_BIOS_FOR_DMA,
-       },{     /* 14 */
+               .host_flags     = IDE_HFLAG_TRUST_BIOS_FOR_DMA |
+                                 IDE_HFLAG_OFF_BOARD,
+               .swdma_mask     = ATA_SWDMA2,
+               .mwdma_mask     = ATA_MWDMA2,
+               .udma_mask      = ATA_UDMA6,
+       },
+
+       /* 11 */ DECLARE_GENERIC_PCI_DEV("Piccolo0102", IDE_HFLAG_NO_AUTODMA),
+       /* 12 */ DECLARE_GENERIC_PCI_DEV("Piccolo0103", IDE_HFLAG_NO_AUTODMA),
+       /* 13 */ DECLARE_GENERIC_PCI_DEV("Piccolo0105", IDE_HFLAG_NO_AUTODMA),
+
+       {       /* 14 */
                .name           = "Revolution",
-               .init_hwif      = init_hwif_generic,
-               .autodma        = AUTODMA,
-               .bootable       = OFF_BOARD,
-               .host_flags     = IDE_HFLAG_TRUST_BIOS_FOR_DMA,
+               .host_flags     = IDE_HFLAG_TRUST_BIOS_FOR_DMA |
+                                 IDE_HFLAG_OFF_BOARD,
+               .swdma_mask     = ATA_SWDMA2,
+               .mwdma_mask     = ATA_MWDMA2,
+               .udma_mask      = ATA_UDMA6,
        }
 };
 
@@ -192,7 +123,7 @@ static ide_pci_device_t generic_chipsets[] __devinitdata = {
  
 static int __devinit generic_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       ide_pci_device_t *d = &generic_chipsets[id->driver_data];
+       const struct ide_port_info *d = &generic_chipsets[id->driver_data];
        int ret = -ENODEV;
 
        /* Don't use the generic entry unless instructed to do so */
index 44ac0e2f7a09cdd8f3fca871ec13712c94c8c619..ae6307fae4f9311b35ba24b7727e5c21b05c6b54 100644 (file)
@@ -125,49 +125,45 @@ static unsigned int __devinit init_chipset_hpt34x(struct pci_dev *dev, const cha
 
 static void __devinit init_hwif_hpt34x(ide_hwif_t *hwif)
 {
-       u16 pcicmd = 0;
-
        hwif->set_pio_mode = &hpt34x_set_pio_mode;
        hwif->set_dma_mode = &hpt34x_set_mode;
+}
 
-       hwif->drives[0].autotune = 1;
-       hwif->drives[1].autotune = 1;
-
-       pci_read_config_word(hwif->pci_dev, PCI_COMMAND, &pcicmd);
-
-       if (!hwif->dma_base)
-               return;
-
+static const struct ide_port_info hpt34x_chipsets[] __devinitdata = {
+       { /* 0 */
+               .name           = "HPT343",
+               .init_chipset   = init_chipset_hpt34x,
+               .init_hwif      = init_hwif_hpt34x,
+               .extra          = 16,
+               .host_flags     = IDE_HFLAG_NO_ATAPI_DMA |
+                                 IDE_HFLAG_NO_AUTODMA,
+               .pio_mask       = ATA_PIO5,
+       },
+       { /* 1 */
+               .name           = "HPT345",
+               .init_chipset   = init_chipset_hpt34x,
+               .init_hwif      = init_hwif_hpt34x,
+               .extra          = 16,
+               .host_flags     = IDE_HFLAG_NO_ATAPI_DMA |
+                                 IDE_HFLAG_NO_AUTODMA |
+                                 IDE_HFLAG_OFF_BOARD,
+               .pio_mask       = ATA_PIO5,
 #ifdef CONFIG_HPT34X_AUTODMA
-       if ((pcicmd & PCI_COMMAND_MEMORY) == 0)
-               return;
-
-       hwif->ultra_mask = 0x07;
-       hwif->mwdma_mask = 0x07;
-       hwif->swdma_mask = 0x07;
+               .swdma_mask     = ATA_SWDMA2,
+               .mwdma_mask     = ATA_MWDMA2,
+               .udma_mask      = ATA_UDMA2,
 #endif
-}
-
-static ide_pci_device_t hpt34x_chipset __devinitdata = {
-       .name           = "HPT34X",
-       .init_chipset   = init_chipset_hpt34x,
-       .init_hwif      = init_hwif_hpt34x,
-       .autodma        = NOAUTODMA,
-       .bootable       = NEVER_BOARD,
-       .extra          = 16,
-       .pio_mask       = ATA_PIO5,
+       }
 };
 
 static int __devinit hpt34x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       ide_pci_device_t *d = &hpt34x_chipset;
-       static char *chipset_names[] = {"HPT343", "HPT345"};
+       const struct ide_port_info *d;
        u16 pcicmd = 0;
 
        pci_read_config_word(dev, PCI_COMMAND, &pcicmd);
 
-       d->name = chipset_names[(pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0];
-       d->bootable = (pcicmd & PCI_COMMAND_MEMORY) ? OFF_BOARD : NEVER_BOARD;
+       d = &hpt34x_chipsets[(pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0];
 
        return ide_setup_pci_device(dev, d);
 }
index fcb21ddab2cc6d69415147a9fcb742f33b8e02a4..612b795241bfc5bf5741de77b633c81e6b416563 100644 (file)
@@ -1,9 +1,10 @@
 /*
- * linux/drivers/ide/pci/hpt366.c              Version 1.14    Oct 1, 2007
+ * linux/drivers/ide/pci/hpt366.c              Version 1.20    Oct 1, 2007
  *
  * Copyright (C) 1999-2003             Andre Hedrick <andre@linux-ide.org>
  * 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.
  *
  * Thanks to HighPoint Technologies for their assistance, and hardware.
@@ -393,8 +394,9 @@ enum ata_clock {
  */
 
 struct hpt_info {
+       char *chip_name;        /* Chip name */
        u8 chip_type;           /* Chip type */
-       u8 max_ultra;           /* Max. UltraDMA mode allowed */
+       u8 udma_mask;           /* Allowed UltraDMA modes mask. */
        u8 dpll_clk;            /* DPLL clock in MHz */
        u8 pci_clk;             /* PCI  clock in MHz */
        u32 **settings;         /* Chipset settings table */
@@ -432,78 +434,89 @@ static u32 *hpt37x_settings[NUM_ATA_CLOCKS] = {
 };
 
 static struct hpt_info hpt36x __devinitdata = {
+       .chip_name      = "HPT36x",
        .chip_type      = HPT36x,
-       .max_ultra      = HPT366_ALLOW_ATA66_3 ? (HPT366_ALLOW_ATA66_4 ? 4 : 3) : 2,
+       .udma_mask      = HPT366_ALLOW_ATA66_3 ? (HPT366_ALLOW_ATA66_4 ? ATA_UDMA4 : ATA_UDMA3) : ATA_UDMA2,
        .dpll_clk       = 0,    /* no DPLL */
        .settings       = hpt36x_settings
 };
 
 static struct hpt_info hpt370 __devinitdata = {
+       .chip_name      = "HPT370",
        .chip_type      = HPT370,
-       .max_ultra      = HPT370_ALLOW_ATA100_5 ? 5 : 4,
+       .udma_mask      = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4,
        .dpll_clk       = 48,
        .settings       = hpt37x_settings
 };
 
 static struct hpt_info hpt370a __devinitdata = {
+       .chip_name      = "HPT370A",
        .chip_type      = HPT370A,
-       .max_ultra      = HPT370_ALLOW_ATA100_5 ? 5 : 4,
+       .udma_mask      = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4,
        .dpll_clk       = 48,
        .settings       = hpt37x_settings
 };
 
 static struct hpt_info hpt374 __devinitdata = {
+       .chip_name      = "HPT374",
        .chip_type      = HPT374,
-       .max_ultra      = 5,
+       .udma_mask      = ATA_UDMA5,
        .dpll_clk       = 48,
        .settings       = hpt37x_settings
 };
 
 static struct hpt_info hpt372 __devinitdata = {
+       .chip_name      = "HPT372",
        .chip_type      = HPT372,
-       .max_ultra      = HPT372_ALLOW_ATA133_6 ? 6 : 5,
+       .udma_mask      = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
        .dpll_clk       = 55,
        .settings       = hpt37x_settings
 };
 
 static struct hpt_info hpt372a __devinitdata = {
+       .chip_name      = "HPT372A",
        .chip_type      = HPT372A,
-       .max_ultra      = HPT372_ALLOW_ATA133_6 ? 6 : 5,
+       .udma_mask      = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
        .dpll_clk       = 66,
        .settings       = hpt37x_settings
 };
 
 static struct hpt_info hpt302 __devinitdata = {
+       .chip_name      = "HPT302",
        .chip_type      = HPT302,
-       .max_ultra      = HPT372_ALLOW_ATA133_6 ? 6 : 5,
+       .udma_mask      = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
        .dpll_clk       = 66,
        .settings       = hpt37x_settings
 };
 
 static struct hpt_info hpt371 __devinitdata = {
+       .chip_name      = "HPT371",
        .chip_type      = HPT371,
-       .max_ultra      = HPT371_ALLOW_ATA133_6 ? 6 : 5,
+       .udma_mask      = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
        .dpll_clk       = 66,
        .settings       = hpt37x_settings
 };
 
 static struct hpt_info hpt372n __devinitdata = {
+       .chip_name      = "HPT372N",
        .chip_type      = HPT372N,
-       .max_ultra      = HPT372_ALLOW_ATA133_6 ? 6 : 5,
+       .udma_mask      = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
        .dpll_clk       = 77,
        .settings       = hpt37x_settings
 };
 
 static struct hpt_info hpt302n __devinitdata = {
+       .chip_name      = "HPT302N",
        .chip_type      = HPT302N,
-       .max_ultra      = HPT302_ALLOW_ATA133_6 ? 6 : 5,
+       .udma_mask      = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
        .dpll_clk       = 77,
        .settings       = hpt37x_settings
 };
 
 static struct hpt_info hpt371n __devinitdata = {
+       .chip_name      = "HPT371N",
        .chip_type      = HPT371N,
-       .max_ultra      = HPT371_ALLOW_ATA133_6 ? 6 : 5,
+       .udma_mask      = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
        .dpll_clk       = 77,
        .settings       = hpt37x_settings
 };
@@ -676,12 +689,11 @@ static int hpt3xx_quirkproc(ide_drive_t *drive)
 
 static void hpt3xx_intrproc(ide_drive_t *drive)
 {
-       ide_hwif_t *hwif = HWIF(drive);
-
        if (drive->quirk_list)
                return;
+
        /* drives in the quirk_list may not like intr setups/cleanups */
-       hwif->OUTB(drive->ctl | 2, IDE_CONTROL_REG);
+       outb(drive->ctl | 2, IDE_CONTROL_REG);
 }
 
 static void hpt3xx_maskproc(ide_drive_t *drive, int mask)
@@ -709,8 +721,8 @@ static void hpt3xx_maskproc(ide_drive_t *drive, int mask)
                                enable_irq (hwif->irq);
                }
        } else
-               hwif->OUTB(mask ? (drive->ctl | 2) : (drive->ctl & ~2),
-                          IDE_CONTROL_REG);
+               outb(mask ? (drive->ctl | 2) : (drive->ctl & ~2),
+                    IDE_CONTROL_REG);
 }
 
 /*
@@ -750,9 +762,9 @@ static void hpt370_irq_timeout(ide_drive_t *drive)
        printk(KERN_DEBUG "%s: %d bytes in FIFO\n", drive->name, bfifo & 0x1ff);
 
        /* get DMA command mode */
-       dma_cmd = hwif->INB(hwif->dma_command);
+       dma_cmd = inb(hwif->dma_command);
        /* stop DMA */
-       hwif->OUTB(dma_cmd & ~0x1, hwif->dma_command);
+       outb(dma_cmd & ~0x1, hwif->dma_command);
        hpt370_clear_engine(drive);
 }
 
@@ -767,12 +779,12 @@ static void hpt370_ide_dma_start(ide_drive_t *drive)
 static int hpt370_ide_dma_end(ide_drive_t *drive)
 {
        ide_hwif_t *hwif        = HWIF(drive);
-       u8  dma_stat            = hwif->INB(hwif->dma_status);
+       u8  dma_stat            = inb(hwif->dma_status);
 
        if (dma_stat & 0x01) {
                /* wait a little */
                udelay(20);
-               dma_stat = hwif->INB(hwif->dma_status);
+               dma_stat = inb(hwif->dma_status);
                if (dma_stat & 0x01)
                        hpt370_irq_timeout(drive);
        }
@@ -833,34 +845,32 @@ static int hpt374_ide_dma_end(ide_drive_t *drive)
 
 static void hpt3xxn_set_clock(ide_hwif_t *hwif, u8 mode)
 {
-       u8 scr2 = hwif->INB(hwif->dma_master + 0x7b);
+       u8 scr2 = inb(hwif->dma_master + 0x7b);
 
        if ((scr2 & 0x7f) == mode)
                return;
 
        /* Tristate the bus */
-       hwif->OUTB(0x80, hwif->dma_master + 0x73);
-       hwif->OUTB(0x80, hwif->dma_master + 0x77);
+       outb(0x80, hwif->dma_master + 0x73);
+       outb(0x80, hwif->dma_master + 0x77);
 
        /* Switch clock and reset channels */
-       hwif->OUTB(mode, hwif->dma_master + 0x7b);
-       hwif->OUTB(0xc0, hwif->dma_master + 0x79);
+       outb(mode, hwif->dma_master + 0x7b);
+       outb(0xc0, hwif->dma_master + 0x79);
 
        /*
         * Reset the state machines.
         * NOTE: avoid accidentally enabling the disabled channels.
         */
-       hwif->OUTB(hwif->INB(hwif->dma_master + 0x70) | 0x32,
-                  hwif->dma_master + 0x70);
-       hwif->OUTB(hwif->INB(hwif->dma_master + 0x74) | 0x32,
-                  hwif->dma_master + 0x74);
+       outb(inb(hwif->dma_master + 0x70) | 0x32, hwif->dma_master + 0x70);
+       outb(inb(hwif->dma_master + 0x74) | 0x32, hwif->dma_master + 0x74);
 
        /* Complete reset */
-       hwif->OUTB(0x00, hwif->dma_master + 0x79);
+       outb(0x00, hwif->dma_master + 0x79);
 
        /* Reconnect channels to bus */
-       hwif->OUTB(0x00, hwif->dma_master + 0x73);
-       hwif->OUTB(0x00, hwif->dma_master + 0x77);
+       outb(0x00, hwif->dma_master + 0x73);
+       outb(0x00, hwif->dma_master + 0x77);
 }
 
 /**
@@ -1139,7 +1149,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
                  * Select 66 MHz DPLL clock only if UltraATA/133 mode is
                  * supported/enabled, use 50 MHz DPLL clock otherwise...
                  */
-               if (info->max_ultra == 6) {
+               if (info->udma_mask == ATA_UDMA6) {
                        dpll_clk = 66;
                        clock = ATA_CLOCK_66MHZ;
                } else if (dpll_clk) {  /* HPT36x chips don't have DPLL */
@@ -1291,14 +1301,9 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
        if (new_mcr != old_mcr)
                pci_write_config_byte(dev, hwif->select_data + 1, new_mcr);
 
-       hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
-
        if (hwif->dma_base == 0)
                return;
 
-       hwif->ultra_mask = hwif->cds->udma_mask;
-       hwif->mwdma_mask = 0x07;
-
        /*
         * The HPT37x uses the CBLID pins as outputs for MA15/MA16
         * address lines to access an external EEPROM.  To read valid
@@ -1354,7 +1359,7 @@ static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase)
        u8 dma_new      = 0, dma_old    = 0;
        unsigned long flags;
 
-       dma_old = hwif->INB(dmabase + 2);
+       dma_old = inb(dmabase + 2);
 
        local_irq_save(flags);
 
@@ -1365,60 +1370,26 @@ static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase)
        if (masterdma & 0x30)   dma_new |= 0x20;
        if ( slavedma & 0x30)   dma_new |= 0x40;
        if (dma_new != dma_old)
-               hwif->OUTB(dma_new, dmabase + 2);
+               outb(dma_new, dmabase + 2);
 
        local_irq_restore(flags);
 
        ide_setup_dma(hwif, dmabase, 8);
 }
 
-static int __devinit init_setup_hpt374(struct pci_dev *dev, ide_pci_device_t *d)
+static void __devinit hpt374_init(struct pci_dev *dev, struct pci_dev *dev2)
 {
-       struct pci_dev *dev2;
-
-       if (PCI_FUNC(dev->devfn) & 1)
-               return -ENODEV;
-
-       pci_set_drvdata(dev, &hpt374);
-
-       if ((dev2 = pci_get_slot(dev->bus, dev->devfn + 1)) != NULL) {
-               int ret;
-
-               pci_set_drvdata(dev2, &hpt374);
-
-               if (dev2->irq != dev->irq) {
-                       /* FIXME: we need a core pci_set_interrupt() */
-                       dev2->irq = dev->irq;
-                       printk(KERN_WARNING "%s: PCI config space interrupt "
-                              "fixed.\n", d->name);
-               }
-               ret = ide_setup_pci_devices(dev, dev2, d);
-               if (ret < 0)
-                       pci_dev_put(dev2);
-               return ret;
+       if (dev2->irq != dev->irq) {
+               /* FIXME: we need a core pci_set_interrupt() */
+               dev2->irq = dev->irq;
+               printk(KERN_INFO "HPT374: PCI config space interrupt fixed\n");
        }
-       return ide_setup_pci_device(dev, d);
-}
-
-static int __devinit init_setup_hpt372n(struct pci_dev *dev, ide_pci_device_t *d)
-{
-       pci_set_drvdata(dev, &hpt372n);
-
-       return ide_setup_pci_device(dev, d);
 }
 
-static int __devinit init_setup_hpt371(struct pci_dev *dev, ide_pci_device_t *d)
+static void __devinit hpt371_init(struct pci_dev *dev)
 {
-       struct hpt_info *info;
        u8 mcr1 = 0;
 
-       if (dev->revision > 1) {
-               d->name = "HPT371N";
-
-               info = &hpt371n;
-       } else
-               info = &hpt371;
-
        /*
         * HPT371 chips physically have only one channel, the secondary one,
         * but the primary channel registers do exist!  Go figure...
@@ -1428,194 +1399,102 @@ static int __devinit init_setup_hpt371(struct pci_dev *dev, ide_pci_device_t *d)
        pci_read_config_byte(dev, 0x50, &mcr1);
        if (mcr1 & 0x04)
                pci_write_config_byte(dev, 0x50, mcr1 & ~0x04);
-
-       pci_set_drvdata(dev, info);
-
-       return ide_setup_pci_device(dev, d);
 }
 
-static int __devinit init_setup_hpt372a(struct pci_dev *dev, ide_pci_device_t *d)
+static int __devinit hpt36x_init(struct pci_dev *dev, struct pci_dev *dev2)
 {
-       struct hpt_info *info;
-
-       if (dev->revision > 1) {
-               d->name = "HPT372N";
+       u8 mcr1 = 0, pin1 = 0, pin2 = 0;
 
-               info = &hpt372n;
-       } else
-               info = &hpt372a;
-       pci_set_drvdata(dev, info);
-
-       return ide_setup_pci_device(dev, d);
-}
-
-static int __devinit init_setup_hpt302(struct pci_dev *dev, ide_pci_device_t *d)
-{
-       struct hpt_info *info;
+       /*
+        * Now we'll have to force both channels enabled if
+        * at least one of them has been enabled by BIOS...
+        */
+       pci_read_config_byte(dev, 0x50, &mcr1);
+       if (mcr1 & 0x30)
+               pci_write_config_byte(dev, 0x50, mcr1 | 0x30);
 
-       if (dev->revision > 1) {
-               d->name = "HPT302N";
+       pci_read_config_byte(dev,  PCI_INTERRUPT_PIN, &pin1);
+       pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin2);
 
-               info = &hpt302n;
-       } else
-               info = &hpt302;
-       pci_set_drvdata(dev, info);
+       if (pin1 != pin2 && dev->irq == dev2->irq) {
+               printk(KERN_INFO "HPT36x: onboard version of chipset, "
+                                "pin1=%d pin2=%d\n", pin1, pin2);
+               return 1;
+       }
 
-       return ide_setup_pci_device(dev, d);
+       return 0;
 }
 
-static int __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d)
-{
-       struct pci_dev *dev2;
-       u8 rev = dev->revision;
-       static char   *chipset_names[] = { "HPT366", "HPT366",  "HPT368",
-                                          "HPT370", "HPT370A", "HPT372",
-                                          "HPT372N" };
-       static struct hpt_info *info[] = { &hpt36x,  &hpt36x,  &hpt36x,
-                                          &hpt370,  &hpt370a, &hpt372,
-                                          &hpt372n  };
-
-       if (PCI_FUNC(dev->devfn) & 1)
-               return -ENODEV;
-
-       switch (rev) {
-       case 0:
-       case 1:
-       case 2:
+static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
+       {       /* 0 */
+               .name           = "HPT36x",
+               .init_chipset   = init_chipset_hpt366,
+               .init_hwif      = init_hwif_hpt366,
+               .init_dma       = init_dma_hpt366,
                /*
                 * HPT36x chips have one channel per function and have
                 * both channel enable bits located differently and visible
                 * to both functions -- really stupid design decision... :-(
                 * Bit 4 is for the primary channel, bit 5 for the secondary.
                 */
-               d->host_flags |= IDE_HFLAG_SINGLE;
-               d->enablebits[0].mask = d->enablebits[0].val = 0x10;
-
-               d->udma_mask = HPT366_ALLOW_ATA66_3 ? (HPT366_ALLOW_ATA66_4 ?
-                              ATA_UDMA4 : ATA_UDMA3) : ATA_UDMA2;
-               break;
-       case 3:
-       case 4:
-               d->udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4;
-               break;
-       default:
-               rev = 6;
-               /* fall thru */
-       case 5:
-       case 6:
-               d->udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5;
-               break;
-       }
-
-       d->name = chipset_names[rev];
-
-       pci_set_drvdata(dev, info[rev]);
-
-       if (rev > 2)
-               goto init_single;
-
-       if ((dev2 = pci_get_slot(dev->bus, dev->devfn + 1)) != NULL) {
-               u8  mcr1 = 0, pin1 = 0, pin2 = 0;
-               int ret;
-
-               pci_set_drvdata(dev2, info[rev]);
-
-               /*
-                * Now we'll have to force both channels enabled if
-                * at least one of them has been enabled by BIOS...
-                */
-               pci_read_config_byte(dev, 0x50, &mcr1);
-               if (mcr1 & 0x30)
-                       pci_write_config_byte(dev, 0x50, mcr1 | 0x30);
-
-               pci_read_config_byte(dev,  PCI_INTERRUPT_PIN, &pin1);
-               pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin2);
-               if (pin1 != pin2 && dev->irq == dev2->irq) {
-                       d->bootable = ON_BOARD;
-                       printk("%s: onboard version of chipset, pin1=%d pin2=%d\n",
-                              d->name, pin1, pin2);
-               }
-               ret = ide_setup_pci_devices(dev, dev2, d);
-               if (ret < 0)
-                       pci_dev_put(dev2);
-               return ret;
-       }
-init_single:
-       return ide_setup_pci_device(dev, d);
-}
-
-static ide_pci_device_t hpt366_chipsets[] __devinitdata = {
-       {       /* 0 */
-               .name           = "HPT366",
-               .init_setup     = init_setup_hpt366,
-               .init_chipset   = init_chipset_hpt366,
-               .init_hwif      = init_hwif_hpt366,
-               .init_dma       = init_dma_hpt366,
-               .autodma        = AUTODMA,
-               .enablebits     = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
-               .bootable       = OFF_BOARD,
+               .enablebits     = {{0x50,0x10,0x10}, {0x54,0x04,0x04}},
                .extra          = 240,
+               .host_flags     = IDE_HFLAG_SINGLE |
+                                 IDE_HFLAG_NO_ATAPI_DMA |
+                                 IDE_HFLAG_OFF_BOARD,
                .pio_mask       = ATA_PIO4,
+               .mwdma_mask     = ATA_MWDMA2,
        },{     /* 1 */
                .name           = "HPT372A",
-               .init_setup     = init_setup_hpt372a,
                .init_chipset   = init_chipset_hpt366,
                .init_hwif      = init_hwif_hpt366,
                .init_dma       = init_dma_hpt366,
-               .autodma        = AUTODMA,
                .enablebits     = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
-               .udma_mask      = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
-               .bootable       = OFF_BOARD,
                .extra          = 240,
+               .host_flags     = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,
                .pio_mask       = ATA_PIO4,
+               .mwdma_mask     = ATA_MWDMA2,
        },{     /* 2 */
                .name           = "HPT302",
-               .init_setup     = init_setup_hpt302,
                .init_chipset   = init_chipset_hpt366,
                .init_hwif      = init_hwif_hpt366,
                .init_dma       = init_dma_hpt366,
-               .autodma        = AUTODMA,
                .enablebits     = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
-               .udma_mask      = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
-               .bootable       = OFF_BOARD,
                .extra          = 240,
+               .host_flags     = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,
                .pio_mask       = ATA_PIO4,
+               .mwdma_mask     = ATA_MWDMA2,
        },{     /* 3 */
                .name           = "HPT371",
-               .init_setup     = init_setup_hpt371,
                .init_chipset   = init_chipset_hpt366,
                .init_hwif      = init_hwif_hpt366,
                .init_dma       = init_dma_hpt366,
-               .autodma        = AUTODMA,
                .enablebits     = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
-               .udma_mask      = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
-               .bootable       = OFF_BOARD,
                .extra          = 240,
+               .host_flags     = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,
                .pio_mask       = ATA_PIO4,
+               .mwdma_mask     = ATA_MWDMA2,
        },{     /* 4 */
                .name           = "HPT374",
-               .init_setup     = init_setup_hpt374,
                .init_chipset   = init_chipset_hpt366,
                .init_hwif      = init_hwif_hpt366,
                .init_dma       = init_dma_hpt366,
-               .autodma        = AUTODMA,
                .enablebits     = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
                .udma_mask      = ATA_UDMA5,
-               .bootable       = OFF_BOARD,
                .extra          = 240,
+               .host_flags     = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,
                .pio_mask       = ATA_PIO4,
+               .mwdma_mask     = ATA_MWDMA2,
        },{     /* 5 */
                .name           = "HPT372N",
-               .init_setup     = init_setup_hpt372n,
                .init_chipset   = init_chipset_hpt366,
                .init_hwif      = init_hwif_hpt366,
                .init_dma       = init_dma_hpt366,
-               .autodma        = AUTODMA,
                .enablebits     = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
-               .udma_mask      = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
-               .bootable       = OFF_BOARD,
                .extra          = 240,
+               .host_flags     = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,
                .pio_mask       = ATA_PIO4,
+               .mwdma_mask     = ATA_MWDMA2,
        }
 };
 
@@ -1626,16 +1505,77 @@ static ide_pci_device_t hpt366_chipsets[] __devinitdata = {
  *
  *     Called when the PCI registration layer (or the IDE initialization)
  *     finds a device matching our IDE device tables.
- *
- *     NOTE: since we'll have to modify some fields of the ide_pci_device_t
- *     structure depending on the chip's revision, we'd better pass a local
- *     copy down the call chain...
  */
 static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       ide_pci_device_t d = hpt366_chipsets[id->driver_data];
+       struct hpt_info *info = NULL;
+       struct pci_dev *dev2 = NULL;
+       struct ide_port_info d;
+       u8 idx = id->driver_data;
+       u8 rev = dev->revision;
+
+       if ((idx == 0 || idx == 4) && (PCI_FUNC(dev->devfn) & 1))
+               return -ENODEV;
+
+       switch (idx) {
+       case 0:
+               if (rev < 3)
+                       info = &hpt36x;
+               else {
+                       static struct hpt_info *hpt37x_info[] =
+                               { &hpt370, &hpt370a, &hpt372, &hpt372n };
+
+                       info = hpt37x_info[min_t(u8, rev, 6) - 3];
+                       idx++;
+               }
+               break;
+       case 1:
+               info = (rev > 1) ? &hpt372n : &hpt372a;
+               break;
+       case 2:
+               info = (rev > 1) ? &hpt302n : &hpt302;
+               break;
+       case 3:
+               hpt371_init(dev);
+               info = (rev > 1) ? &hpt371n : &hpt371;
+               break;
+       case 4:
+               info = &hpt374;
+               break;
+       case 5:
+               info = &hpt372n;
+               break;
+       }
+
+       d = hpt366_chipsets[idx];
+
+       d.name = info->chip_name;
+       d.udma_mask = info->udma_mask;
+
+       pci_set_drvdata(dev, info);
+
+       if (info == &hpt36x || info == &hpt374)
+               dev2 = pci_get_slot(dev->bus, dev->devfn + 1);
+
+       if (dev2) {
+               int ret;
+
+               pci_set_drvdata(dev2, info);
+
+               if (info == &hpt374)
+                       hpt374_init(dev, dev2);
+               else {
+                       if (hpt36x_init(dev, dev2))
+                               d.host_flags |= IDE_HFLAG_BOOTABLE;
+               }
+
+               ret = ide_setup_pci_devices(dev, dev2, &d);
+               if (ret < 0)
+                       pci_dev_put(dev2);
+               return ret;
+       }
 
-       return d.init_setup(dev, &d);
+       return ide_setup_pci_device(dev, &d);
 }
 
 static const struct pci_device_id hpt366_pci_tbl[] = {
index 24a71d03744a35bb88d3e68f30c15a4a972ebd93..90b52ed37bfc365de2a6041eac56280b5d1ba44e 100644 (file)
@@ -170,17 +170,9 @@ static void __devinit init_hwif_it8213(ide_hwif_t *hwif)
        hwif->set_dma_mode = &it8213_set_dma_mode;
        hwif->set_pio_mode = &it8213_set_pio_mode;
 
-       hwif->drives[0].autotune = 1;
-       hwif->drives[1].autotune = 1;
-
        if (!hwif->dma_base)
                return;
 
-       hwif->atapi_dma = 1;
-       hwif->ultra_mask = 0x7f;
-       hwif->mwdma_mask = 0x06;
-       hwif->swdma_mask = 0x04;
-
        pci_read_config_byte(hwif->pci_dev, 0x42, &reg42h);
 
        if (hwif->cbl != ATA_CBL_PATA40_SHORT)
@@ -192,14 +184,16 @@ static void __devinit init_hwif_it8213(ide_hwif_t *hwif)
        {                                               \
                .name           = name_str,             \
                .init_hwif      = init_hwif_it8213,     \
-               .autodma        = AUTODMA,              \
                .enablebits     = {{0x41,0x80,0x80}}, \
-               .bootable       = ON_BOARD,             \
-               .host_flags     = IDE_HFLAG_SINGLE,     \
+               .host_flags     = IDE_HFLAG_SINGLE |    \
+                                 IDE_HFLAG_BOOTABLE,   \
                .pio_mask       = ATA_PIO4,             \
+               .swdma_mask     = ATA_SWDMA2_ONLY,      \
+               .mwdma_mask     = ATA_MWDMA12_ONLY,     \
+               .udma_mask      = ATA_UDMA6,            \
        }
 
-static ide_pci_device_t it8213_chipsets[] __devinitdata = {
+static const struct ide_port_info it8213_chipsets[] __devinitdata = {
        /* 0 */ DECLARE_ITE_DEV("IT8213"),
 };
 
index f3391a8698ac65fed5d55afd258e18f65a1048a5..5c99754353194478890a3ae073bddcdd509e07f5 100644 (file)
@@ -95,7 +95,7 @@ struct it821x_dev
 
 /*
  *     We allow users to force the card into non raid mode without
- *     flashing the alternative BIOS. This is also neccessary right now
+ *     flashing the alternative BIOS. This is also necessary right now
  *     for embedded platforms that cannot run a PC BIOS but are using this
  *     device.
  */
@@ -544,12 +544,10 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
 
        ide_set_hwifdata(hwif, idev);
 
-       hwif->atapi_dma = 1;
-
        pci_read_config_byte(hwif->pci_dev, 0x50, &conf);
-       if(conf & 1) {
+       if (conf & 1) {
                idev->smart = 1;
-               hwif->atapi_dma = 0;
+               hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA;
                /* Long I/O's although allowed in LBA48 space cause the
                   onboard firmware to enter the twighlight zone */
                hwif->rqsize = 256;
@@ -566,14 +564,14 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
 
        /*
         *      Not in the docs but according to the reference driver
-        *      this is neccessary.
+        *      this is necessary.
         */
 
        pci_read_config_byte(hwif->pci_dev, 0x08, &conf);
-       if(conf == 0x10) {
+       if (conf == 0x10) {
                idev->timing10 = 1;
-               hwif->atapi_dma = 0;
-               if(!idev->smart)
+               hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA;
+               if (idev->smart == 0)
                        printk(KERN_WARNING "it821x: Revision 0x10, workarounds activated.\n");
        }
 
@@ -587,14 +585,11 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
        } else
                hwif->host_flags |= IDE_HFLAG_NO_SET_MODE;
 
-       hwif->drives[0].autotune = 1;
-       hwif->drives[1].autotune = 1;
-
        if (hwif->dma_base == 0)
                return;
 
-       hwif->ultra_mask = 0x7f;
-       hwif->mwdma_mask = 0x07;
+       hwif->ultra_mask = ATA_UDMA6;
+       hwif->mwdma_mask = ATA_MWDMA2;
 
        if (hwif->cbl != ATA_CBL_PATA40_SHORT)
                hwif->cbl = ata66_it821x(hwif);
@@ -638,13 +633,12 @@ static unsigned int __devinit init_chipset_it821x(struct pci_dev *dev, const cha
                .name           = name_str,             \
                .init_chipset   = init_chipset_it821x,  \
                .init_hwif      = init_hwif_it821x,     \
-               .autodma        = AUTODMA,              \
-               .bootable       = ON_BOARD,             \
                .fixup          = it821x_fixups,        \
+               .host_flags     = IDE_HFLAG_BOOTABLE,   \
                .pio_mask       = ATA_PIO4,             \
        }
 
-static ide_pci_device_t it821x_chipsets[] __devinitdata = {
+static const struct ide_port_info it821x_chipsets[] __devinitdata = {
        /* 0 */ DECLARE_ITE_DEV("IT8212"),
 };
 
index bb893ffcc987f646e5ad651249cb44388a9fb542..bdf64d99770805313647814c848cedc5d43ff600 100644 (file)
@@ -111,27 +111,21 @@ static void __devinit init_hwif_jmicron(ide_hwif_t *hwif)
        hwif->set_pio_mode = &jmicron_set_pio_mode;
        hwif->set_dma_mode = &jmicron_set_dma_mode;
 
-       hwif->drives[0].autotune = 1;
-       hwif->drives[1].autotune = 1;
-
        if (hwif->dma_base == 0)
                return;
 
-       hwif->atapi_dma = 1;
-       hwif->ultra_mask = 0x7f;
-       hwif->mwdma_mask = 0x07;
-
        if (hwif->cbl != ATA_CBL_PATA40_SHORT)
                hwif->cbl = ata66_jmicron(hwif);
 }
 
-static ide_pci_device_t jmicron_chipset __devinitdata = {
+static const struct ide_port_info jmicron_chipset __devinitdata = {
        .name           = "JMB",
        .init_hwif      = init_hwif_jmicron,
-       .autodma        = AUTODMA,
-       .bootable       = ON_BOARD,
+       .host_flags     = IDE_HFLAG_BOOTABLE,
        .enablebits     = { { 0x40, 0x01, 0x01 }, { 0x40, 0x10, 0x10 } },
        .pio_mask       = ATA_PIO5,
+       .mwdma_mask     = ATA_MWDMA2,
+       .udma_mask      = ATA_UDMA6,
 };
 
 /**
index a8cd50ab62fb5ed2216d52a0e7e0f3320cc28b73..d4df4642dbb5ff83e136b26126816fcc3ca09fff 100644 (file)
@@ -260,15 +260,15 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
        hwif->ide_dma_end = &ns87415_ide_dma_end;
 }
 
-static ide_pci_device_t ns87415_chipset __devinitdata = {
+static const struct ide_port_info ns87415_chipset __devinitdata = {
        .name           = "NS87415",
 #ifdef CONFIG_SUPERIO
        .init_iops      = init_iops_ns87415,
 #endif
        .init_hwif      = init_hwif_ns87415,
-       .autodma        = AUTODMA,
-       .bootable       = ON_BOARD,
-       .host_flags     = IDE_HFLAG_TRUST_BIOS_FOR_DMA,
+       .host_flags     = IDE_HFLAG_TRUST_BIOS_FOR_DMA |
+                         IDE_HFLAG_NO_ATAPI_DMA |
+                         IDE_HFLAG_BOOTABLE,
 };
 
 static int __devinit ns87415_init_one(struct pci_dev *dev, const struct pci_device_id *id)
index 250662ea18ad837b608a6272249cb638c4f8fabb..8953d9c3926fe3ea909563562374f3599d9568e6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/ide/pci/opti621.c            Version 0.7     Sept 10, 2002
+ *  linux/drivers/ide/pci/opti621.c            Version 0.9     Sep 24, 2007
  *
  *  Copyright (C) 1996-1998  Linus Torvalds & authors (see below)
  */
@@ -57,9 +57,6 @@
  * There is a 25/33MHz switch in configuration
  * register, but driver is written for use at any frequency which get
  * (use idebus=xx to select PCI bus speed).
- * Use hda=autotune and hdb=autotune for automatical tune of the PIO modes.
- * If you get strange results, do not use this and set PIO manually
- * by hdparm.
  *
  * Version 0.1, Nov 8, 1996
  * by Jaromir Koutek, for 2.1.8. 
@@ -136,6 +133,8 @@ static int reg_base;
 #define PIO_NOT_EXIST 254
 #define PIO_DONT_KNOW 255
 
+static DEFINE_SPINLOCK(opti621_lock);
+
 /* there are stored pio numbers from other calls of opti621_set_pio_mode */
 static void compute_pios(ide_drive_t *drive, const u8 pio)
 /* Store values into drive->drive_data
@@ -281,7 +280,7 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio)
                second.recovery_time, drdy);
 #endif
 
-       spin_lock_irqsave(&ide_lock, flags);
+       spin_lock_irqsave(&opti621_lock, flags);
 
        reg_base = hwif->io_ports[IDE_DATA_OFFSET];
 
@@ -320,7 +319,7 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio)
        /*  and read prefetch for both drives */
        write_reg(misc, MISC_REG);
 
-       spin_unlock_irqrestore(&ide_lock, flags);
+       spin_unlock_irqrestore(&opti621_lock, flags);
 }
 
 /*
@@ -332,32 +331,27 @@ static void __devinit init_hwif_opti621 (ide_hwif_t *hwif)
        hwif->drives[1].drive_data = PIO_DONT_KNOW;
 
        hwif->set_pio_mode = &opti621_set_pio_mode;
-
-       if (!(hwif->dma_base))
-               return;
-
-       hwif->atapi_dma = 1;
-       hwif->mwdma_mask = 0x07;
-       hwif->swdma_mask = 0x07;
 }
 
-static ide_pci_device_t opti621_chipsets[] __devinitdata = {
+static const struct ide_port_info opti621_chipsets[] __devinitdata = {
        {       /* 0 */
                .name           = "OPTI621",
                .init_hwif      = init_hwif_opti621,
-               .autodma        = AUTODMA,
                .enablebits     = {{0x45,0x80,0x00}, {0x40,0x08,0x00}},
-               .bootable       = ON_BOARD,
+               .host_flags     = IDE_HFLAG_TRUST_BIOS_FOR_DMA |
+                                 IDE_HFLAG_BOOTABLE,
                .pio_mask       = ATA_PIO3,
-               .host_flags     = IDE_HFLAG_TRUST_BIOS_FOR_DMA,
+               .swdma_mask     = ATA_SWDMA2,
+               .mwdma_mask     = ATA_MWDMA2,
        },{     /* 1 */
                .name           = "OPTI621X",
                .init_hwif      = init_hwif_opti621,
-               .autodma        = AUTODMA,
                .enablebits     = {{0x45,0x80,0x00}, {0x40,0x08,0x00}},
-               .bootable       = ON_BOARD,
+               .host_flags     = IDE_HFLAG_TRUST_BIOS_FOR_DMA |
+                                 IDE_HFLAG_BOOTABLE,
                .pio_mask       = ATA_PIO3,
-               .host_flags     = IDE_HFLAG_TRUST_BIOS_FOR_DMA,
+               .swdma_mask     = ATA_SWDMA2,
+               .mwdma_mask     = ATA_MWDMA2,
        }
 };
 
index 8704b6f33312636034d0a6a33cbdffe1df3fea62..4234efeba606750d9b4d7e4cc5ad95aaea57faba 100644 (file)
@@ -332,16 +332,12 @@ static long __devinit detect_pll_input_clock(unsigned long dma_base)
 static void __devinit apple_kiwi_init(struct pci_dev *pdev)
 {
        struct device_node *np = pci_device_to_OF_node(pdev);
-       unsigned int class_rev = 0;
        u8 conf;
 
        if (np == NULL || !of_device_is_compatible(np, "kiwi-root"))
                return;
 
-       pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev);
-       class_rev &= 0xff;
-
-       if (class_rev >= 0x03) {
+       if (pdev->revision >= 0x03) {
                /* Setup chip magic config stuff (from darwin) */
                pci_read_config_byte (pdev, 0x40, &conf);
                pci_write_config_byte(pdev, 0x40, (conf | 0x01));
@@ -475,32 +471,76 @@ static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif)
        hwif->quirkproc = &pdcnew_quirkproc;
        hwif->resetproc = &pdcnew_reset;
 
-       hwif->err_stops_fifo = 1;
-
-       hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
-
        if (hwif->dma_base == 0)
                return;
 
-       hwif->atapi_dma  = 1;
-
-       hwif->ultra_mask = hwif->cds->udma_mask;
-       hwif->mwdma_mask = 0x07;
-
        if (hwif->cbl != ATA_CBL_PATA40_SHORT)
                hwif->cbl = pdcnew_cable_detect(hwif);
 }
 
-static int __devinit init_setup_pdcnew(struct pci_dev *dev, ide_pci_device_t *d)
+static struct pci_dev * __devinit pdc20270_get_dev2(struct pci_dev *dev)
 {
-       return ide_setup_pci_device(dev, d);
+       struct pci_dev *dev2;
+
+       dev2 = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn) + 2,
+                                               PCI_FUNC(dev->devfn)));
+       if (dev2 &&
+           dev2->vendor == dev->vendor &&
+           dev2->device == dev->device) {
+
+               if (dev2->irq != dev->irq) {
+                       dev2->irq = dev->irq;
+                       printk(KERN_INFO "PDC20270: PCI config space "
+                                        "interrupt fixed\n");
+               }
+
+               return dev2;
+       }
+
+       return NULL;
 }
 
-static int __devinit init_setup_pdc20270(struct pci_dev *dev, ide_pci_device_t *d)
+#define DECLARE_PDCNEW_DEV(name_str, udma) \
+       { \
+               .name           = name_str, \
+               .init_chipset   = init_chipset_pdcnew, \
+               .init_hwif      = init_hwif_pdc202new, \
+               .host_flags     = IDE_HFLAG_POST_SET_MODE | \
+                                 IDE_HFLAG_ERROR_STOPS_FIFO | \
+                                 IDE_HFLAG_OFF_BOARD, \
+               .pio_mask       = ATA_PIO4, \
+               .mwdma_mask     = ATA_MWDMA2, \
+               .udma_mask      = udma, \
+       }
+
+static const struct ide_port_info pdcnew_chipsets[] __devinitdata = {
+       /* 0 */ DECLARE_PDCNEW_DEV("PDC20268", ATA_UDMA5),
+       /* 1 */ DECLARE_PDCNEW_DEV("PDC20269", ATA_UDMA6),
+       /* 2 */ DECLARE_PDCNEW_DEV("PDC20270", ATA_UDMA5),
+       /* 3 */ DECLARE_PDCNEW_DEV("PDC20271", ATA_UDMA6),
+       /* 4 */ DECLARE_PDCNEW_DEV("PDC20275", ATA_UDMA6),
+       /* 5 */ DECLARE_PDCNEW_DEV("PDC20276", ATA_UDMA6),
+       /* 6 */ DECLARE_PDCNEW_DEV("PDC20277", ATA_UDMA6),
+};
+
+/**
+ *     pdc202new_init_one      -       called when a pdc202xx is found
+ *     @dev: the pdc202new device
+ *     @id: the matching pci id
+ *
+ *     Called when the PCI registration layer (or the IDE initialization)
+ *     finds a device matching our IDE device tables.
+ */
+static int __devinit pdc202new_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
+       const struct ide_port_info *d;
        struct pci_dev *bridge = dev->bus->self;
+       u8 idx = id->driver_data;
+
+       d = &pdcnew_chipsets[idx];
 
-       if (bridge != NULL &&
+       if (idx == 2 && bridge &&
            bridge->vendor == PCI_VENDOR_ID_DEC &&
            bridge->device == PCI_DEVICE_ID_DEC_21150) {
                struct pci_dev *dev2;
@@ -508,133 +548,26 @@ static int __devinit init_setup_pdc20270(struct pci_dev *dev, ide_pci_device_t *
                if (PCI_SLOT(dev->devfn) & 2)
                        return -ENODEV;
 
-               dev2 = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn) + 2,
-                                                       PCI_FUNC(dev->devfn)));
-               if (dev2 != NULL &&
-                   dev2->vendor == dev->vendor &&
-                   dev2->device == dev->device) {
-                       int ret;
-
-                       if (dev2->irq != dev->irq) {
-                               dev2->irq = dev->irq;
+               dev2 = pdc20270_get_dev2(dev);
 
-                               printk(KERN_WARNING "%s: PCI config space "
-                                      "interrupt fixed.\n", d->name);
-                       }
-
-                       ret = ide_setup_pci_devices(dev, dev2, d);
+               if (dev2) {
+                       int ret = ide_setup_pci_devices(dev, dev2, d);
                        if (ret < 0)
                                pci_dev_put(dev2);
                        return ret;
                }
        }
-       return ide_setup_pci_device(dev, d);
-}
 
-static int __devinit init_setup_pdc20276(struct pci_dev *dev, ide_pci_device_t *d)
-{
-       struct pci_dev *bridge = dev->bus->self;
-
-       if (bridge != NULL &&
+       if (idx == 5 && bridge &&
            bridge->vendor == PCI_VENDOR_ID_INTEL &&
-          (bridge->device == PCI_DEVICE_ID_INTEL_I960 ||
-           bridge->device == PCI_DEVICE_ID_INTEL_I960RM)) {
-
-               printk(KERN_INFO "%s: attached to I2O RAID controller, "
-                                "skipping.\n", d->name);
+           (bridge->device == PCI_DEVICE_ID_INTEL_I960 ||
+            bridge->device == PCI_DEVICE_ID_INTEL_I960RM)) {
+               printk(KERN_INFO "PDC20276: attached to I2O RAID controller, "
+                                "skipping\n");
                return -ENODEV;
        }
-       return ide_setup_pci_device(dev, d);
-}
-
-static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
-       {       /* 0 */
-               .name           = "PDC20268",
-               .init_setup     = init_setup_pdcnew,
-               .init_chipset   = init_chipset_pdcnew,
-               .init_hwif      = init_hwif_pdc202new,
-               .autodma        = AUTODMA,
-               .bootable       = OFF_BOARD,
-               .pio_mask       = ATA_PIO4,
-               .udma_mask      = 0x3f, /* udma0-5 */
-               .host_flags     = IDE_HFLAG_POST_SET_MODE,
-       },{     /* 1 */
-               .name           = "PDC20269",
-               .init_setup     = init_setup_pdcnew,
-               .init_chipset   = init_chipset_pdcnew,
-               .init_hwif      = init_hwif_pdc202new,
-               .autodma        = AUTODMA,
-               .bootable       = OFF_BOARD,
-               .pio_mask       = ATA_PIO4,
-               .udma_mask      = 0x7f, /* udma0-6*/
-               .host_flags     = IDE_HFLAG_POST_SET_MODE,
-       },{     /* 2 */
-               .name           = "PDC20270",
-               .init_setup     = init_setup_pdc20270,
-               .init_chipset   = init_chipset_pdcnew,
-               .init_hwif      = init_hwif_pdc202new,
-               .autodma        = AUTODMA,
-               .bootable       = OFF_BOARD,
-               .pio_mask       = ATA_PIO4,
-               .udma_mask      = 0x3f, /* udma0-5 */
-               .host_flags     = IDE_HFLAG_POST_SET_MODE,
-       },{     /* 3 */
-               .name           = "PDC20271",
-               .init_setup     = init_setup_pdcnew,
-               .init_chipset   = init_chipset_pdcnew,
-               .init_hwif      = init_hwif_pdc202new,
-               .autodma        = AUTODMA,
-               .bootable       = OFF_BOARD,
-               .pio_mask       = ATA_PIO4,
-               .udma_mask      = 0x7f, /* udma0-6*/
-               .host_flags     = IDE_HFLAG_POST_SET_MODE,
-       },{     /* 4 */
-               .name           = "PDC20275",
-               .init_setup     = init_setup_pdcnew,
-               .init_chipset   = init_chipset_pdcnew,
-               .init_hwif      = init_hwif_pdc202new,
-               .autodma        = AUTODMA,
-               .bootable       = OFF_BOARD,
-               .pio_mask       = ATA_PIO4,
-               .udma_mask      = 0x7f, /* udma0-6*/
-               .host_flags     = IDE_HFLAG_POST_SET_MODE,
-       },{     /* 5 */
-               .name           = "PDC20276",
-               .init_setup     = init_setup_pdc20276,
-               .init_chipset   = init_chipset_pdcnew,
-               .init_hwif      = init_hwif_pdc202new,
-               .autodma        = AUTODMA,
-               .bootable       = OFF_BOARD,
-               .pio_mask       = ATA_PIO4,
-               .udma_mask      = 0x7f, /* udma0-6*/
-               .host_flags     = IDE_HFLAG_POST_SET_MODE,
-       },{     /* 6 */
-               .name           = "PDC20277",
-               .init_setup     = init_setup_pdcnew,
-               .init_chipset   = init_chipset_pdcnew,
-               .init_hwif      = init_hwif_pdc202new,
-               .autodma        = AUTODMA,
-               .bootable       = OFF_BOARD,
-               .pio_mask       = ATA_PIO4,
-               .udma_mask      = 0x7f, /* udma0-6*/
-               .host_flags     = IDE_HFLAG_POST_SET_MODE,
-       }
-};
 
-/**
- *     pdc202new_init_one      -       called when a pdc202xx is found
- *     @dev: the pdc202new device
- *     @id: the matching pci id
- *
- *     Called when the PCI registration layer (or the IDE initialization)
- *     finds a device matching our IDE device tables.
- */
-static int __devinit pdc202new_init_one(struct pci_dev *dev, const struct pci_device_id *id)
-{
-       ide_pci_device_t *d = &pdcnew_chipsets[id->driver_data];
-
-       return d->init_setup(dev, d);
+       return ide_setup_pci_device(dev, d);
 }
 
 static const struct pci_device_id pdc202new_pci_tbl[] = {
index e1d2337a9f1d563af10b1a4253495997d6a7adac..e09742e2ba592607e31dd3356099fabf8fae5ea8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/ide/pci/pdc202xx_old.c       Version 0.51    Jul 27, 2007
+ *  linux/drivers/ide/pci/pdc202xx_old.c       Version 0.52    Aug 27, 2007
  *
  *  Copyright (C) 1998-2002            Andre Hedrick <andre@linux-ide.org>
  *  Copyright (C) 2006-2007            MontaVista Software, Inc.
@@ -97,9 +97,6 @@ static void pdc202xx_set_mode(ide_drive_t *drive, const u8 speed)
                case XFER_MW_DMA_2:     TB = 0x60; TC = 0x03; break;
                case XFER_MW_DMA_1:     TB = 0x60; TC = 0x04; break;
                case XFER_MW_DMA_0:     TB = 0xE0; TC = 0x0F; break;
-               case XFER_SW_DMA_2:     TB = 0x60; TC = 0x05; break;
-               case XFER_SW_DMA_1:     TB = 0x80; TC = 0x06; break;
-               case XFER_SW_DMA_0:     TB = 0xC0; TC = 0x0B; break;
                case XFER_PIO_4:        TA = 0x01; TB = 0x04; break;
                case XFER_PIO_3:        TA = 0x02; TB = 0x06; break;
                case XFER_PIO_2:        TA = 0x03; TB = 0x08; break;
@@ -305,13 +302,6 @@ static unsigned int __devinit init_chipset_pdc202xx(struct pci_dev *dev,
 
 static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif)
 {
-       struct pci_dev *dev = hwif->pci_dev;
-
-       /* PDC20265 has problems with large LBA48 requests */
-       if ((dev->device == PCI_DEVICE_ID_PROMISE_20267) ||
-           (dev->device == PCI_DEVICE_ID_PROMISE_20265))
-               hwif->rqsize = 256;
-
        hwif->set_pio_mode = &pdc202xx_set_pio_mode;
        hwif->set_dma_mode = &pdc202xx_set_mode;
 
@@ -320,18 +310,9 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif)
        if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246)
                hwif->resetproc = &pdc202xx_reset;
 
-       hwif->err_stops_fifo = 1;
-
-       hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
-
        if (hwif->dma_base == 0)
                return;
 
-       hwif->ultra_mask = hwif->cds->udma_mask;
-       hwif->mwdma_mask = 0x07;
-       hwif->swdma_mask = 0x07;
-       hwif->atapi_dma = 1;
-
        hwif->dma_lost_irq = &pdc202xx_dma_lost_irq;
        hwif->dma_timeout = &pdc202xx_dma_timeout;
 
@@ -377,8 +358,8 @@ static void __devinit init_dma_pdc202xx(ide_hwif_t *hwif, unsigned long dmabase)
        ide_setup_dma(hwif, dmabase, 8);
 }
 
-static int __devinit init_setup_pdc202ata4(struct pci_dev *dev,
-                                          ide_pci_device_t *d)
+static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev,
+                                          const char *name)
 {
        if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) {
                u8 irq = 0, irq2 = 0;
@@ -388,90 +369,45 @@ static int __devinit init_setup_pdc202ata4(struct pci_dev *dev,
                if (irq != irq2) {
                        pci_write_config_byte(dev,
                                (PCI_INTERRUPT_LINE)|0x80, irq);     /* 0xbc */
-                       printk(KERN_INFO "%s: pci-config space interrupt "
-                               "mirror fixed.\n", d->name);
+                       printk(KERN_INFO "%s: PCI config space interrupt "
+                                        "mirror fixed\n", name);
                }
        }
-       return ide_setup_pci_device(dev, d);
 }
 
-static int __devinit init_setup_pdc20265(struct pci_dev *dev,
-                                        ide_pci_device_t *d)
-{
-       if ((dev->bus->self) &&
-           (dev->bus->self->vendor == PCI_VENDOR_ID_INTEL) &&
-           ((dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960) ||
-            (dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960RM))) {
-               printk(KERN_INFO "ide: Skipping Promise PDC20265 "
-                       "attached to I2O RAID controller.\n");
-               return -ENODEV;
+#define DECLARE_PDC2026X_DEV(name_str, udma, extra_flags) \
+       { \
+               .name           = name_str, \
+               .init_chipset   = init_chipset_pdc202xx, \
+               .init_hwif      = init_hwif_pdc202xx, \
+               .init_dma       = init_dma_pdc202xx, \
+               .extra          = 48, \
+               .host_flags     = IDE_HFLAG_ERROR_STOPS_FIFO | \
+                                 extra_flags | \
+                                 IDE_HFLAG_OFF_BOARD, \
+               .pio_mask       = ATA_PIO4, \
+               .mwdma_mask     = ATA_MWDMA2, \
+               .udma_mask      = udma, \
        }
-       return ide_setup_pci_device(dev, d);
-}
 
-static int __devinit init_setup_pdc202xx(struct pci_dev *dev,
-                                        ide_pci_device_t *d)
-{
-       return ide_setup_pci_device(dev, d);
-}
-
-static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = {
+static const struct ide_port_info pdc202xx_chipsets[] __devinitdata = {
        {       /* 0 */
                .name           = "PDC20246",
-               .init_setup     = init_setup_pdc202ata4,
                .init_chipset   = init_chipset_pdc202xx,
                .init_hwif      = init_hwif_pdc202xx,
                .init_dma       = init_dma_pdc202xx,
-               .autodma        = AUTODMA,
-               .bootable       = OFF_BOARD,
                .extra          = 16,
+               .host_flags     = IDE_HFLAG_ERROR_STOPS_FIFO |
+                                 IDE_HFLAG_OFF_BOARD,
                .pio_mask       = ATA_PIO4,
-               .udma_mask      = 0x07, /* udma0-2 */
-       },{     /* 1 */
-               .name           = "PDC20262",
-               .init_setup     = init_setup_pdc202ata4,
-               .init_chipset   = init_chipset_pdc202xx,
-               .init_hwif      = init_hwif_pdc202xx,
-               .init_dma       = init_dma_pdc202xx,
-               .autodma        = AUTODMA,
-               .bootable       = OFF_BOARD,
-               .extra          = 48,
-               .pio_mask       = ATA_PIO4,
-               .udma_mask      = 0x1f, /* udma0-4 */
-       },{     /* 2 */
-               .name           = "PDC20263",
-               .init_setup     = init_setup_pdc202ata4,
-               .init_chipset   = init_chipset_pdc202xx,
-               .init_hwif      = init_hwif_pdc202xx,
-               .init_dma       = init_dma_pdc202xx,
-               .autodma        = AUTODMA,
-               .bootable       = OFF_BOARD,
-               .extra          = 48,
-               .pio_mask       = ATA_PIO4,
-               .udma_mask      = 0x1f, /* udma0-4 */
-       },{     /* 3 */
-               .name           = "PDC20265",
-               .init_setup     = init_setup_pdc20265,
-               .init_chipset   = init_chipset_pdc202xx,
-               .init_hwif      = init_hwif_pdc202xx,
-               .init_dma       = init_dma_pdc202xx,
-               .autodma        = AUTODMA,
-               .bootable       = OFF_BOARD,
-               .extra          = 48,
-               .pio_mask       = ATA_PIO4,
-               .udma_mask      = 0x3f, /* udma0-5 */
-       },{     /* 4 */
-               .name           = "PDC20267",
-               .init_setup     = init_setup_pdc202xx,
-               .init_chipset   = init_chipset_pdc202xx,
-               .init_hwif      = init_hwif_pdc202xx,
-               .init_dma       = init_dma_pdc202xx,
-               .autodma        = AUTODMA,
-               .bootable       = OFF_BOARD,
-               .extra          = 48,
-               .pio_mask       = ATA_PIO4,
-               .udma_mask      = 0x3f, /* udma0-5 */
-       }
+               .mwdma_mask     = ATA_MWDMA2,
+               .udma_mask      = ATA_UDMA2,
+       },
+
+       /* 1 */ DECLARE_PDC2026X_DEV("PDC20262", ATA_UDMA4, 0),
+       /* 2 */ DECLARE_PDC2026X_DEV("PDC20263", ATA_UDMA4, 0),
+       /* 3 */ DECLARE_PDC2026X_DEV("PDC20265", ATA_UDMA5, IDE_HFLAG_RQSIZE_256),
+       /* 4 */ DECLARE_PDC2026X_DEV("PDC20267", ATA_UDMA5, IDE_HFLAG_RQSIZE_256),
 };
 
 /**
@@ -485,9 +421,28 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = {
  
 static int __devinit pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       ide_pci_device_t *d = &pdc202xx_chipsets[id->driver_data];
+       const struct ide_port_info *d;
+       u8 idx = id->driver_data;
+
+       d = &pdc202xx_chipsets[idx];
+
+       if (idx < 3)
+               pdc202ata4_fixup_irq(dev, d->name);
+
+       if (idx == 3) {
+               struct pci_dev *bridge = dev->bus->self;
 
-       return d->init_setup(dev, d);
+               if (bridge &&
+                   bridge->vendor == PCI_VENDOR_ID_INTEL &&
+                   (bridge->device == PCI_DEVICE_ID_INTEL_I960 ||
+                    bridge->device == PCI_DEVICE_ID_INTEL_I960RM)) {
+                       printk(KERN_INFO "ide: Skipping Promise PDC20265 "
+                               "attached to I2O RAID controller\n");
+                       return -ENODEV;
+               }
+       }
+
+       return ide_setup_pci_device(dev, d);
 }
 
 static const struct pci_device_id pdc202xx_pci_tbl[] = {
index a8dd0c0add351890dadfc5659ff2270d3f8b3b5a..9329d4a810e50fe4a25b45c5f9b6e8b26640e6c6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/ide/pci/piix.c       Version 0.53    Aug 9, 2007
+ *  linux/drivers/ide/pci/piix.c       Version 0.54    Sep 5, 2007
  *
  *  Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer
  *  Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
@@ -254,53 +254,20 @@ static void piix_set_dma_mode(ide_drive_t *drive, const u8 speed)
 }
 
 /**
- *     piix_is_ichx    -       check if ICHx
- *     @dev: PCI device to check
- *
- *     returns 1 if ICHx, 0 otherwise.
- */
-static int piix_is_ichx(struct pci_dev *dev)
-{
-        switch (dev->device) {
-               case PCI_DEVICE_ID_INTEL_82801EB_1:
-               case PCI_DEVICE_ID_INTEL_82801AA_1:
-               case PCI_DEVICE_ID_INTEL_82801AB_1:
-               case PCI_DEVICE_ID_INTEL_82801BA_8:
-               case PCI_DEVICE_ID_INTEL_82801BA_9:
-               case PCI_DEVICE_ID_INTEL_82801CA_10:
-               case PCI_DEVICE_ID_INTEL_82801CA_11:
-               case PCI_DEVICE_ID_INTEL_82801DB_1:
-               case PCI_DEVICE_ID_INTEL_82801DB_10:
-               case PCI_DEVICE_ID_INTEL_82801DB_11:
-               case PCI_DEVICE_ID_INTEL_82801EB_11:
-               case PCI_DEVICE_ID_INTEL_82801E_11:
-               case PCI_DEVICE_ID_INTEL_ESB_2:
-               case PCI_DEVICE_ID_INTEL_ICH6_19:
-               case PCI_DEVICE_ID_INTEL_ICH7_21:
-               case PCI_DEVICE_ID_INTEL_ESB2_18:
-               case PCI_DEVICE_ID_INTEL_ICH8_6:
-                       return 1;
-       }
-
-       return 0;
-}
-
-/**
- *     init_chipset_piix       -       set up the PIIX chipset
+ *     init_chipset_ich        -       set up the ICH chipset
  *     @dev: PCI device to set up
  *     @name: Name of the device
  *
- *     Initialize the PCI device as required. For the PIIX this turns
- *     out to be nice and simple
+ *     Initialize the PCI device as required.  For the ICH this turns
+ *     out to be nice and simple.
  */
 
-static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_ich(struct pci_dev *dev, const char *name)
 {
-       if (piix_is_ichx(dev)) {
-               unsigned int extra = 0;
-               pci_read_config_dword(dev, 0x54, &extra);
-               pci_write_config_dword(dev, 0x54, extra|0x400);
-       }
+       u32 extra = 0;
+
+       pci_read_config_dword(dev, 0x54, &extra);
+       pci_write_config_dword(dev, 0x54, extra | 0x400);
 
        return 0;
 }
@@ -318,9 +285,9 @@ static void piix_dma_clear_irq(ide_drive_t *drive)
        u8 dma_stat;
 
        /* clear the INTR & ERROR bits */
-       dma_stat = hwif->INB(hwif->dma_status);
+       dma_stat = inb(hwif->dma_status);
        /* Should we force the bit as well ? */
-       hwif->OUTB(dma_stat, hwif->dma_status);
+       outb(dma_stat, hwif->dma_status);
 }
 
 struct ich_laptop {
@@ -374,35 +341,12 @@ static u8 __devinit piix_cable_detect(ide_hwif_t *hwif)
 
 static void __devinit init_hwif_piix(ide_hwif_t *hwif)
 {
-#ifndef CONFIG_IA64
-       if (!hwif->irq)
-               hwif->irq = hwif->channel ? 15 : 14;
-#endif /* CONFIG_IA64 */
-
-       if (hwif->pci_dev->device == PCI_DEVICE_ID_INTEL_82371MX) {
-               /* This is a painful system best to let it self tune for now */
-               return;
-       }
-
        hwif->set_pio_mode = &piix_set_pio_mode;
        hwif->set_dma_mode = &piix_set_dma_mode;
 
-       hwif->drives[0].autotune = 1;
-       hwif->drives[1].autotune = 1;
-
        if (!hwif->dma_base)
                return;
 
-       /* ICHx need to clear the bmdma status for all interrupts */
-       if (piix_is_ichx(hwif->pci_dev))
-               hwif->ide_dma_clear_irq = &piix_dma_clear_irq;
-
-       hwif->atapi_dma = 1;
-
-       hwif->ultra_mask = hwif->cds->udma_mask;
-       hwif->mwdma_mask = 0x06;
-       hwif->swdma_mask = 0x04;
-
        if (hwif->ultra_mask & 0x78) {
                if (hwif->cbl != ATA_CBL_PATA40_SHORT)
                        hwif->cbl = piix_cable_detect(hwif);
@@ -412,21 +356,49 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif)
                hwif->ultra_mask = hwif->mwdma_mask = hwif->swdma_mask = 0;
 }
 
+static void __devinit init_hwif_ich(ide_hwif_t *hwif)
+{
+       init_hwif_piix(hwif);
+
+       /* ICHx need to clear the BMDMA status for all interrupts */
+       if (hwif->dma_base)
+               hwif->ide_dma_clear_irq = &piix_dma_clear_irq;
+}
+
+#ifndef CONFIG_IA64
+ #define IDE_HFLAGS_PIIX (IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE)
+#else
+ #define IDE_HFLAGS_PIIX IDE_HFLAG_BOOTABLE
+#endif
+
 #define DECLARE_PIIX_DEV(name_str, udma) \
        {                                               \
                .name           = name_str,             \
-               .init_chipset   = init_chipset_piix,    \
                .init_hwif      = init_hwif_piix,       \
-               .autodma        = AUTODMA,              \
                .enablebits     = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \
-               .bootable       = ON_BOARD,             \
+               .host_flags     = IDE_HFLAGS_PIIX,      \
                .pio_mask       = ATA_PIO4,             \
+               .swdma_mask     = ATA_SWDMA2_ONLY,      \
+               .mwdma_mask     = ATA_MWDMA12_ONLY,     \
                .udma_mask      = udma,                 \
        }
 
-static ide_pci_device_t piix_pci_info[] __devinitdata = {
-       /*  0 */ DECLARE_PIIX_DEV("PIIXa", 0x00),       /* no udma */
-       /*  1 */ DECLARE_PIIX_DEV("PIIXb", 0x00),       /* no udma */
+#define DECLARE_ICH_DEV(name_str, udma) \
+       { \
+               .name           = name_str, \
+               .init_chipset   = init_chipset_ich, \
+               .init_hwif      = init_hwif_ich, \
+               .enablebits     = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \
+               .host_flags     = IDE_HFLAGS_PIIX, \
+               .pio_mask       = ATA_PIO4, \
+               .swdma_mask     = ATA_SWDMA2_ONLY, \
+               .mwdma_mask     = ATA_MWDMA12_ONLY, \
+               .udma_mask      = udma, \
+       }
+
+static const struct ide_port_info piix_pci_info[] __devinitdata = {
+       /*  0 */ DECLARE_PIIX_DEV("PIIXa",      0x00),  /* no udma */
+       /*  1 */ DECLARE_PIIX_DEV("PIIXb",      0x00),  /* no udma */
 
        /*  2 */
        {       /*
@@ -435,36 +407,35 @@ static ide_pci_device_t piix_pci_info[] __devinitdata = {
                 * of the bit 14 of the IDETIM register at offset 0x6c
                 */
                .name           = "MPIIX",
-               .init_hwif      = init_hwif_piix,
-               .autodma        = NODMA,
                .enablebits     = {{0x6d,0xc0,0x80}, {0x6d,0xc0,0xc0}},
-               .bootable       = ON_BOARD,
-               .host_flags     = IDE_HFLAG_ISA_PORTS,
+               .host_flags     = IDE_HFLAG_ISA_PORTS | IDE_HFLAG_NO_DMA |
+                                 IDE_HFLAGS_PIIX,
                .pio_mask       = ATA_PIO4,
+               /* This is a painful system best to let it self tune for now */
        },
 
-       /*  3 */ DECLARE_PIIX_DEV("PIIX3", 0x00),       /* no udma */
-       /*  4 */ DECLARE_PIIX_DEV("PIIX4", 0x07),       /* udma0-2 */
-       /*  5 */ DECLARE_PIIX_DEV("ICH0",  0x07),       /* udma0-2 */
-       /*  6 */ DECLARE_PIIX_DEV("PIIX4", 0x07),       /* udma0-2 */
-       /*  7 */ DECLARE_PIIX_DEV("ICH",   0x1f),       /* udma0-4 */
-       /*  8 */ DECLARE_PIIX_DEV("PIIX4", 0x1f),       /* udma0-4 */
-       /*  9 */ DECLARE_PIIX_DEV("PIIX4", 0x07),       /* udma0-2 */
-       /* 10 */ DECLARE_PIIX_DEV("ICH2",  0x3f),       /* udma0-5 */
-       /* 11 */ DECLARE_PIIX_DEV("ICH2M", 0x3f),       /* udma0-5 */
-       /* 12 */ DECLARE_PIIX_DEV("ICH3M", 0x3f),       /* udma0-5 */
-       /* 13 */ DECLARE_PIIX_DEV("ICH3",  0x3f),       /* udma0-5 */
-       /* 14 */ DECLARE_PIIX_DEV("ICH4",  0x3f),       /* udma0-5 */
-       /* 15 */ DECLARE_PIIX_DEV("ICH5",  0x3f),       /* udma0-5 */
-       /* 16 */ DECLARE_PIIX_DEV("C-ICH", 0x3f),       /* udma0-5 */
-       /* 17 */ DECLARE_PIIX_DEV("ICH4",  0x3f),       /* udma0-5 */
-       /* 18 */ DECLARE_PIIX_DEV("ICH5-SATA", 0x3f),   /* udma0-5 */
-       /* 19 */ DECLARE_PIIX_DEV("ICH5",  0x3f),       /* udma0-5 */
-       /* 20 */ DECLARE_PIIX_DEV("ICH6",  0x3f),       /* udma0-5 */
-       /* 21 */ DECLARE_PIIX_DEV("ICH7",  0x3f),       /* udma0-5 */
-       /* 22 */ DECLARE_PIIX_DEV("ICH4",  0x3f),       /* udma0-5 */
-       /* 23 */ DECLARE_PIIX_DEV("ESB2",  0x3f),       /* udma0-5 */
-       /* 24 */ DECLARE_PIIX_DEV("ICH8M", 0x3f),       /* udma0-5 */
+       /*  3 */ DECLARE_PIIX_DEV("PIIX3",      0x00),  /* no udma */
+       /*  4 */ DECLARE_PIIX_DEV("PIIX4",      ATA_UDMA2),
+       /*  5 */ DECLARE_ICH_DEV("ICH0",        ATA_UDMA2),
+       /*  6 */ DECLARE_PIIX_DEV("PIIX4",      ATA_UDMA2),
+       /*  7 */ DECLARE_ICH_DEV("ICH",         ATA_UDMA4),
+       /*  8 */ DECLARE_PIIX_DEV("PIIX4",      ATA_UDMA4),
+       /*  9 */ DECLARE_PIIX_DEV("PIIX4",      ATA_UDMA2),
+       /* 10 */ DECLARE_ICH_DEV("ICH2",        ATA_UDMA5),
+       /* 11 */ DECLARE_ICH_DEV("ICH2M",       ATA_UDMA5),
+       /* 12 */ DECLARE_ICH_DEV("ICH3M",       ATA_UDMA5),
+       /* 13 */ DECLARE_ICH_DEV("ICH3",        ATA_UDMA5),
+       /* 14 */ DECLARE_ICH_DEV("ICH4",        ATA_UDMA5),
+       /* 15 */ DECLARE_ICH_DEV("ICH5",        ATA_UDMA5),
+       /* 16 */ DECLARE_ICH_DEV("C-ICH",       ATA_UDMA5),
+       /* 17 */ DECLARE_ICH_DEV("ICH4",        ATA_UDMA5),
+       /* 18 */ DECLARE_ICH_DEV("ICH5-SATA",   ATA_UDMA5),
+       /* 19 */ DECLARE_ICH_DEV("ICH5",        ATA_UDMA5),
+       /* 20 */ DECLARE_ICH_DEV("ICH6",        ATA_UDMA5),
+       /* 21 */ DECLARE_ICH_DEV("ICH7",        ATA_UDMA5),
+       /* 22 */ DECLARE_ICH_DEV("ICH4",        ATA_UDMA5),
+       /* 23 */ DECLARE_ICH_DEV("ESB2",        ATA_UDMA5),
+       /* 24 */ DECLARE_ICH_DEV("ICH8M",       ATA_UDMA5),
 };
 
 /**
@@ -478,9 +449,7 @@ static ide_pci_device_t piix_pci_info[] __devinitdata = {
  
 static int __devinit piix_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       ide_pci_device_t *d = &piix_pci_info[id->driver_data];
-
-       return ide_setup_pci_device(dev, d);
+       return ide_setup_pci_device(dev, &piix_pci_info[id->driver_data]);
 }
 
 /**
index 3f506e8d44e3a89b59864198f97db21f7d015cdd..6b10ae260fa29e148ae6f9f874400ce1d0997381 100644 (file)
@@ -35,13 +35,13 @@ static void __devinit init_hwif_rz1000 (ide_hwif_t *hwif)
        u16 reg;
        struct pci_dev *dev = hwif->pci_dev;
 
-       hwif->chipset = ide_rz1000;
        if (!pci_read_config_word (dev, 0x40, &reg) &&
            !pci_write_config_word(dev, 0x40, reg & 0xdfff)) {
                printk(KERN_INFO "%s: disabled chipset read-ahead "
                        "(buggy RZ1000/RZ1001)\n", hwif->name);
        } else {
-               hwif->serialized = 1;
+               if (hwif->mate)
+                       hwif->mate->serialized = hwif->serialized = 1;
                hwif->drives[0].no_unmask = 1;
                hwif->drives[1].no_unmask = 1;
                printk(KERN_INFO "%s: serialized, disabled unmasking "
@@ -49,11 +49,11 @@ static void __devinit init_hwif_rz1000 (ide_hwif_t *hwif)
        }
 }
 
-static ide_pci_device_t rz1000_chipset __devinitdata = {
+static const struct ide_port_info rz1000_chipset __devinitdata = {
        .name           = "RZ100x",
        .init_hwif      = init_hwif_rz1000,
-       .autodma        = NODMA,
-       .bootable       = ON_BOARD,
+       .chipset        = ide_rz1000,
+       .host_flags     = IDE_HFLAG_NO_DMA | IDE_HFLAG_BOOTABLE,
 };
 
 static int __devinit rz1000_init_one(struct pci_dev *dev, const struct pci_device_id *id)
index 54c5c98a2e2655f32b32b4b0fa3335f8ac3df1c7..d2c8b5524f283df712581463e0c80a59b99fa0dc 100644 (file)
@@ -362,33 +362,26 @@ static int sc1200_resume (struct pci_dev *dev)
  */
 static void __devinit init_hwif_sc1200 (ide_hwif_t *hwif)
 {
-       if (hwif->mate)
-               hwif->serialized = hwif->mate->serialized = 1;
-
        hwif->set_pio_mode = &sc1200_set_pio_mode;
        hwif->set_dma_mode = &sc1200_set_dma_mode;
 
-       hwif->drives[0].autotune = 1;
-       hwif->drives[1].autotune = 1;
-
        if (hwif->dma_base == 0)
                return;
 
        hwif->udma_filter = sc1200_udma_filter;
        hwif->ide_dma_end   = &sc1200_ide_dma_end;
-
-        hwif->atapi_dma = 1;
-        hwif->ultra_mask = 0x07;
-        hwif->mwdma_mask = 0x07;
 }
 
-static ide_pci_device_t sc1200_chipset __devinitdata = {
+static const struct ide_port_info sc1200_chipset __devinitdata = {
        .name           = "SC1200",
        .init_hwif      = init_hwif_sc1200,
-       .autodma        = AUTODMA,
-       .bootable       = ON_BOARD,
-       .host_flags     = IDE_HFLAG_ABUSE_DMA_MODES | IDE_HFLAG_POST_SET_MODE,
+       .host_flags     = IDE_HFLAG_SERIALIZE |
+                         IDE_HFLAG_POST_SET_MODE |
+                         IDE_HFLAG_ABUSE_DMA_MODES |
+                         IDE_HFLAG_BOOTABLE,
        .pio_mask       = ATA_PIO4,
+       .mwdma_mask     = ATA_MWDMA2,
+       .udma_mask      = ATA_UDMA2,
 };
 
 static int __devinit sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id)
index bd4c1d3070e4961c7fee4cb20337a0d1ff8a729e..ebb7132b9b848c6c87f92cbe9dc6b92450980c8f 100644 (file)
@@ -472,7 +472,7 @@ static u8 scc_udma_filter(ide_drive_t *drive)
        if ((drive->media != ide_disk) && (mask & 0xE0)) {
                printk(KERN_INFO "%s: limit %s to UDMA4\n",
                       SCC_PATA_NAME, drive->name);
-               mask = 0x1F;
+               mask = ATA_UDMA4;
        }
 
        return mask;
@@ -538,12 +538,13 @@ static int setup_mmio_scc (struct pci_dev *dev, const char *name)
 /**
  *     init_setup_scc  -       set up an SCC PATA Controller
  *     @dev: PCI device
- *     @d: IDE PCI device
+ *     @d: IDE port info
  *
  *     Perform the initial set up for this device.
  */
 
-static int __devinit init_setup_scc(struct pci_dev *dev, ide_pci_device_t *d)
+static int __devinit init_setup_scc(struct pci_dev *dev,
+                                   const struct ide_port_info *d)
 {
        unsigned long ctl_base;
        unsigned long dma_base;
@@ -683,17 +684,10 @@ static void __devinit init_hwif_scc(ide_hwif_t *hwif)
        hwif->ide_dma_test_irq = scc_dma_test_irq;
        hwif->udma_filter = scc_udma_filter;
 
-       hwif->drives[0].autotune = IDE_TUNE_AUTO;
-       hwif->drives[1].autotune = IDE_TUNE_AUTO;
-
-       if (in_be32((void __iomem *)(hwif->config_data + 0xff0)) & CCKCTRL_ATACLKOEN) {
-               hwif->ultra_mask = 0x7f; /* 133MHz */
-       } else {
-               hwif->ultra_mask = 0x3f; /* 100MHz */
-       }
-       hwif->mwdma_mask = 0x00;
-       hwif->swdma_mask = 0x00;
-       hwif->atapi_dma = 1;
+       if (in_be32((void __iomem *)(hwif->config_data + 0xff0)) & CCKCTRL_ATACLKOEN)
+               hwif->ultra_mask = ATA_UDMA6; /* 133MHz */
+       else
+               hwif->ultra_mask = ATA_UDMA5; /* 100MHz */
 
        /* we support 80c cable only. */
        hwif->cbl = ATA_CBL_PATA80;
@@ -702,16 +696,14 @@ static void __devinit init_hwif_scc(ide_hwif_t *hwif)
 #define DECLARE_SCC_DEV(name_str)                      \
   {                                                    \
       .name            = name_str,                     \
-      .init_setup      = init_setup_scc,               \
       .init_iops       = init_iops_scc,                \
       .init_hwif       = init_hwif_scc,                \
-      .autodma = AUTODMA,                              \
-      .bootable        = ON_BOARD,                             \
-      .host_flags      = IDE_HFLAG_SINGLE,             \
+      .host_flags      = IDE_HFLAG_SINGLE |            \
+                         IDE_HFLAG_BOOTABLE,           \
       .pio_mask                = ATA_PIO4,                     \
   }
 
-static ide_pci_device_t scc_chipsets[] __devinitdata = {
+static const struct ide_port_info scc_chipsets[] __devinitdata = {
        /* 0 */ DECLARE_SCC_DEV("sccIDE"),
 };
 
@@ -726,8 +718,7 @@ static ide_pci_device_t scc_chipsets[] __devinitdata = {
 
 static int __devinit scc_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       ide_pci_device_t *d = &scc_chipsets[id->driver_data];
-       return d->init_setup(dev, d);
+       return init_setup_scc(dev, &scc_chipsets[id->driver_data]);
 }
 
 /**
index d3ffc52e22aff340ee55e71c4a6a9fda91472e10..a7280311357b3e539aae503165ed0b9e69603f71 100644 (file)
@@ -158,13 +158,6 @@ static void svwks_set_dma_mode(ide_drive_t *drive, const u8 speed)
 
        u8 ultra_enable  = 0, ultra_timing = 0, dma_timing = 0;
 
-       /* If we are about to put a disk into UDMA mode we screwed up.
-          Our code assumes we never _ever_ do this on an OSB4 */
-          
-       if(dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4 &&
-               drive->media == ide_disk && speed >= XFER_UDMA_0)
-                       BUG();
-
        pci_read_config_byte(dev, (0x56|hwif->channel), &ultra_timing);
        pci_read_config_byte(dev, 0x54, &ultra_enable);
 
@@ -360,23 +353,10 @@ static u8 __devinit ata66_svwks(ide_hwif_t *hwif)
 
 static void __devinit init_hwif_svwks (ide_hwif_t *hwif)
 {
-       if (!hwif->irq)
-               hwif->irq = hwif->channel ? 15 : 14;
-
        hwif->set_pio_mode = &svwks_set_pio_mode;
        hwif->set_dma_mode = &svwks_set_dma_mode;
        hwif->udma_filter = &svwks_udma_filter;
 
-       hwif->atapi_dma = 1;
-
-       if (hwif->pci_dev->device != PCI_DEVICE_ID_SERVERWORKS_OSB4IDE)
-               hwif->ultra_mask = 0x3f;
-
-       hwif->mwdma_mask = 0x07;
-
-       hwif->drives[0].autotune = 1;
-       hwif->drives[1].autotune = 1;
-
        if (!hwif->dma_base)
                return;
 
@@ -386,72 +366,49 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif)
        }
 }
 
-static int __devinit init_setup_svwks (struct pci_dev *dev, ide_pci_device_t *d)
-{
-       return ide_setup_pci_device(dev, d);
-}
-
-static int __devinit init_setup_csb6 (struct pci_dev *dev, ide_pci_device_t *d)
-{
-       if (!(PCI_FUNC(dev->devfn) & 1)) {
-               d->bootable = NEVER_BOARD;
-               if (dev->resource[0].start == 0x01f1)
-                       d->bootable = ON_BOARD;
-       }
-
-       if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE ||
-           dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2) &&
-           (!(PCI_FUNC(dev->devfn) & 1)))
-               d->host_flags |= IDE_HFLAG_SINGLE;
-       else
-               d->host_flags &= ~IDE_HFLAG_SINGLE;
-
-       return ide_setup_pci_device(dev, d);
-}
-
-static ide_pci_device_t serverworks_chipsets[] __devinitdata = {
+static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
        {       /* 0 */
                .name           = "SvrWks OSB4",
-               .init_setup     = init_setup_svwks,
                .init_chipset   = init_chipset_svwks,
                .init_hwif      = init_hwif_svwks,
-               .autodma        = AUTODMA,
-               .bootable       = ON_BOARD,
+               .host_flags     = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE,
                .pio_mask       = ATA_PIO4,
+               .mwdma_mask     = ATA_MWDMA2,
+               .udma_mask      = 0x00, /* UDMA is problematic on OSB4 */
        },{     /* 1 */
                .name           = "SvrWks CSB5",
-               .init_setup     = init_setup_svwks,
                .init_chipset   = init_chipset_svwks,
                .init_hwif      = init_hwif_svwks,
-               .autodma        = AUTODMA,
-               .bootable       = ON_BOARD,
+               .host_flags     = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE,
                .pio_mask       = ATA_PIO4,
+               .mwdma_mask     = ATA_MWDMA2,
+               .udma_mask      = ATA_UDMA5,
        },{     /* 2 */
                .name           = "SvrWks CSB6",
-               .init_setup     = init_setup_csb6,
                .init_chipset   = init_chipset_svwks,
                .init_hwif      = init_hwif_svwks,
-               .autodma        = AUTODMA,
-               .bootable       = ON_BOARD,
+               .host_flags     = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE,
                .pio_mask       = ATA_PIO4,
+               .mwdma_mask     = ATA_MWDMA2,
+               .udma_mask      = ATA_UDMA5,
        },{     /* 3 */
                .name           = "SvrWks CSB6",
-               .init_setup     = init_setup_csb6,
                .init_chipset   = init_chipset_svwks,
                .init_hwif      = init_hwif_svwks,
-               .autodma        = AUTODMA,
-               .bootable       = ON_BOARD,
-               .host_flags     = IDE_HFLAG_SINGLE,
+               .host_flags     = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_SINGLE |
+                                 IDE_HFLAG_BOOTABLE,
                .pio_mask       = ATA_PIO4,
+               .mwdma_mask     = ATA_MWDMA2,
+               .udma_mask      = ATA_UDMA5,
        },{     /* 4 */
                .name           = "SvrWks HT1000",
-               .init_setup     = init_setup_svwks,
                .init_chipset   = init_chipset_svwks,
                .init_hwif      = init_hwif_svwks,
-               .autodma        = AUTODMA,
-               .bootable       = ON_BOARD,
-               .host_flags     = IDE_HFLAG_SINGLE,
+               .host_flags     = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_SINGLE |
+                                 IDE_HFLAG_BOOTABLE,
                .pio_mask       = ATA_PIO4,
+               .mwdma_mask     = ATA_MWDMA2,
+               .udma_mask      = ATA_UDMA5,
        }
 };
 
@@ -466,9 +423,21 @@ static ide_pci_device_t serverworks_chipsets[] __devinitdata = {
  
 static int __devinit svwks_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       ide_pci_device_t *d = &serverworks_chipsets[id->driver_data];
+       struct ide_port_info d;
+       u8 idx = id->driver_data;
+
+       d = serverworks_chipsets[idx];
+
+       if (idx == 2 || idx == 3) {
+               if ((PCI_FUNC(dev->devfn) & 1) == 0) {
+                       if (pci_resource_start(dev, 0) != 0x01f1)
+                               d.host_flags &= ~IDE_HFLAG_BOOTABLE;
+                       d.host_flags |= IDE_HFLAG_SINGLE;
+               } else
+                       d.host_flags &= ~IDE_HFLAG_SINGLE;
+       }
 
-       return d->init_setup(dev, d);
+       return ide_setup_pci_device(dev, &d);
 }
 
 static const struct pci_device_id svwks_pci_tbl[] = {
index 9a9474f534e5e8a7676236c8c8c67d87e187f7d8..de820aa58cd0e47057b9a8028d9fd3b8c1bfe515 100644 (file)
@@ -592,8 +592,7 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
        if (hwif->dma_base == 0)
                return;
 
-       hwif->atapi_dma = 1;
-       hwif->mwdma_mask = 0x04;
+       hwif->mwdma_mask = ATA_MWDMA2_ONLY;
 
        hwif->dma_setup = &sgiioc4_ide_dma_setup;
        hwif->dma_start = &sgiioc4_ide_dma_start;
@@ -615,6 +614,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
        void __iomem *virt_base;
        ide_hwif_t *hwif;
        int h;
+       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 
        /*
         * Find an empty HWIF; if none available, return -ENOMEM.
@@ -655,10 +655,12 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
        }
 
        if (hwif->io_ports[IDE_DATA_OFFSET] != cmd_base) {
+               hw_regs_t hw;
+
                /* Initialize the IO registers */
-               sgiioc4_init_hwif_ports(&hwif->hw, cmd_base, ctl, irqport);
-               memcpy(hwif->io_ports, hwif->hw.io_ports,
-                      sizeof (hwif->io_ports));
+               memset(&hw, 0, sizeof(hw));
+               sgiioc4_init_hwif_ports(&hw, cmd_base, ctl, irqport);
+               memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports));
                hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
        }
 
@@ -680,11 +682,10 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
 
        ide_init_sgiioc4(hwif);
 
-       if (probe_hwif_init(hwif))
-               return -EIO;
+       idx[0] = hwif->index;
 
-       /* Create /proc/ide entries */
-       ide_proc_register_port(hwif);
+       if (ide_device_add(idx))
+               return -EIO;
 
        return 0;
 }
@@ -692,14 +693,12 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
 static unsigned int __devinit
 pci_init_sgiioc4(struct pci_dev *dev)
 {
-       unsigned int class_rev;
        int ret;
 
-       pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
-       class_rev &= 0xff;
        printk(KERN_INFO "%s: IDE controller at PCI slot %s, revision %d\n",
-                        DRV_NAME, pci_name(dev), class_rev);
-       if (class_rev < IOC4_SUPPORTED_FIRMWARE_REV) {
+                        DRV_NAME, pci_name(dev), dev->revision);
+
+       if (dev->revision < IOC4_SUPPORTED_FIRMWARE_REV) {
                printk(KERN_ERR "Skipping %s IDE controller in slot %s: "
                                "firmware is obsolete - please upgrade to "
                                "revision46 or higher\n",
index 85d0afd00e660e828744d88808d829e6eda1c431..6d99441c605be1836843c514de2a780b8dcee804 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/pci/siimage.c             Version 1.16    Jul 13 2007
+ * linux/drivers/ide/pci/siimage.c             Version 1.18    Oct 18 2007
  *
  * Copyright (C) 2001-2002     Andre Hedrick <andre@linux-ide.org>
  * Copyright (C) 2003          Red Hat <alan@redhat.com>
@@ -26,7 +26,7 @@
  *
  *     If you have strange problems with nVidia chipset systems please
  *     see the SI support documentation and update your system BIOS
- *     if neccessary
+ *     if necessary
  *
  *  The Dell DRAC4 has some interesting features including effectively hot
  *  unplugging/replugging the virtual CD interface when the DRAC is reset.
@@ -57,8 +57,8 @@
  
 static int pdev_is_sata(struct pci_dev *pdev)
 {
-       switch(pdev->device)
-       {
+#ifdef CONFIG_BLK_DEV_IDE_SATA
+       switch(pdev->device) {
                case PCI_DEVICE_ID_SII_3112:
                case PCI_DEVICE_ID_SII_1210SA:
                        return 1;
@@ -66,9 +66,10 @@ static int pdev_is_sata(struct pci_dev *pdev)
                        return 0;
        }
        BUG();
+#endif
        return 0;
 }
+
 /**
  *     is_sata                 -       check if hwif is SATA
  *     @hwif:  interface to check
@@ -136,7 +137,7 @@ static inline unsigned long siimage_seldev(ide_drive_t *drive, int r)
  *     SI3112 SATA controller life is a bit simpler.
  */
 
-static u8 sil_udma_filter(ide_drive_t *drive)
+static u8 sil_pata_udma_filter(ide_drive_t *drive)
 {
        ide_hwif_t *hwif = drive->hwif;
        unsigned long base = (unsigned long) hwif->hwif_data;
@@ -147,23 +148,23 @@ static u8 sil_udma_filter(ide_drive_t *drive)
        else
                pci_read_config_byte(hwif->pci_dev, 0x8A, &scsc);
 
-       if (is_sata(hwif)) {
-               mask = strstr(drive->id->model, "Maxtor") ? 0x3f : 0x7f;
-               goto out;
-       }
-
        if ((scsc & 0x30) == 0x10)      /* 133 */
-               mask = 0x7f;
+               mask = ATA_UDMA6;
        else if ((scsc & 0x30) == 0x20) /* 2xPCI */
-               mask = 0x7f;
+               mask = ATA_UDMA6;
        else if ((scsc & 0x30) == 0x00) /* 100 */
-               mask = 0x3f;
+               mask = ATA_UDMA5;
        else    /* Disabled ? */
                BUG();
-out:
+
        return mask;
 }
 
+static u8 sil_sata_udma_filter(ide_drive_t *drive)
+{
+       return strstr(drive->id->model, "Maxtor") ? ATA_UDMA5 : ATA_UDMA6;
+}
+
 /**
  *     sil_set_pio_mode        -       set host controller for PIO mode
  *     @drive: drive
@@ -180,7 +181,7 @@ static void sil_set_pio_mode(ide_drive_t *drive, u8 pio)
        const u16 data_speed[]  = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 };
 
        ide_hwif_t *hwif        = HWIF(drive);
-       ide_drive_t *pair       = &hwif->drives[drive->dn ^ 1];
+       ide_drive_t *pair       = ide_get_paired_drive(drive);
        u32 speedt              = 0;
        u16 speedp              = 0;
        unsigned long addr      = siimage_seldev(drive, 0x04);
@@ -340,10 +341,11 @@ static int siimage_io_ide_dma_test_irq (ide_drive_t *drive)
 static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive)
 {
        ide_hwif_t *hwif        = HWIF(drive);
-       unsigned long base      = (unsigned long)hwif->hwif_data;
        unsigned long addr      = siimage_selreg(hwif, 0x1);
 
        if (SATA_ERROR_REG) {
+               unsigned long base = (unsigned long)hwif->hwif_data;
+
                u32 ext_stat = readl((void __iomem *)(base + 0x10));
                u8 watchdog = 0;
                if (ext_stat & ((hwif->channel) ? 0x40 : 0x10)) {
@@ -376,7 +378,7 @@ static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive)
 }
 
 /**
- *     siimage_busproc         -       bus isolation ioctl
+ *     sil_sata_busproc        -       bus isolation IOCTL
  *     @drive: drive to isolate/restore
  *     @state: bus state to set
  *
@@ -384,8 +386,8 @@ static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive)
  *     SATA controller the work required is quite limited, we 
  *     just have to clean up the statistics
  */
-static int siimage_busproc (ide_drive_t * drive, int state)
+
+static int sil_sata_busproc(ide_drive_t * drive, int state)
 {
        ide_hwif_t *hwif        = HWIF(drive);
        u32 stat_config         = 0;
@@ -417,14 +419,14 @@ static int siimage_busproc (ide_drive_t * drive, int state)
 }
 
 /**
- *     siimage_reset_poll      -       wait for sata reset
+ *     sil_sata_reset_poll     -       wait for SATA reset
  *     @drive: drive we are resetting
  *
  *     Poll the SATA phy and see whether it has come back from the dead
  *     yet.
  */
-static int siimage_reset_poll (ide_drive_t *drive)
+
+static int sil_sata_reset_poll(ide_drive_t *drive)
 {
        if (SATA_STATUS_REG) {
                ide_hwif_t *hwif        = HWIF(drive);
@@ -436,27 +438,22 @@ static int siimage_reset_poll (ide_drive_t *drive)
                        HWGROUP(drive)->polling = 0;
                        return ide_started;
                }
-               return 0;
-       } else {
-               return 0;
        }
+
+       return 0;
 }
 
 /**
- *     siimage_pre_reset       -       reset hook
+ *     sil_sata_pre_reset      -       reset hook
  *     @drive: IDE device being reset
  *
  *     For the SATA devices we need to handle recalibration/geometry
  *     differently
  */
-static void siimage_pre_reset (ide_drive_t *drive)
-{
-       if (drive->media != ide_disk)
-               return;
 
-       if (is_sata(HWIF(drive)))
-       {
+static void sil_sata_pre_reset(ide_drive_t *drive)
+{
+       if (drive->media == ide_disk) {
                drive->special.b.set_geometry = 0;
                drive->special.b.recalibrate = 0;
        }
@@ -502,7 +499,6 @@ static void siimage_reset (ide_drive_t *drive)
                        drive->failures++;
                }
        }
-
 }
 
 /**
@@ -640,13 +636,9 @@ static unsigned int setup_mmio_siimage (struct pci_dev *dev, const char *name)
 
 static unsigned int __devinit init_chipset_siimage(struct pci_dev *dev, const char *name)
 {
-       u32 class_rev   = 0;
-       u8 tmpbyte      = 0;
-       u8 BA5_EN       = 0;
+       u8 rev = dev->revision, tmpbyte = 0, BA5_EN = 0;
 
-        pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
-        class_rev &= 0xff;
-       pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (class_rev) ? 1 : 255); 
+       pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, rev ? 1 : 255);
 
        pci_read_config_byte(dev, 0x8A, &BA5_EN);
        if ((BA5_EN & 0x01) || (pci_resource_start(dev, 5))) {
@@ -762,16 +754,11 @@ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif)
                hwif->sata_misc[SATA_IEN_OFFSET]        = base + 0x148;
        }
 
-       hw.irq                          = hwif->pci_dev->irq;
-
-       memcpy(&hwif->hw, &hw, sizeof(hw));
-       memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports));
+       memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports));
 
-       hwif->irq                       = hw.irq;
+       hwif->irq = dev->irq;
 
-               base = (unsigned long) addr;
-
-       hwif->dma_base                  = base + (ch ? 0x08 : 0x00);
+       hwif->dma_base = (unsigned long)addr + (ch ? 0x08 : 0x00);
 
        hwif->mmio = 1;
 }
@@ -825,19 +812,14 @@ static void __devinit siimage_fixup(ide_hwif_t *hwif)
 
 static void __devinit init_iops_siimage(ide_hwif_t *hwif)
 {
-       struct pci_dev *dev     = hwif->pci_dev;
-       u32 class_rev           = 0;
-
-       pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
-       class_rev &= 0xff;
-       
        hwif->hwif_data = NULL;
 
        /* Pessimal until we finish probing */
        hwif->rqsize = 15;
 
-       if (pci_get_drvdata(dev) == NULL)
+       if (pci_get_drvdata(hwif->pci_dev) == NULL)
                return;
+
        init_mmio_iops_siimage(hwif);
 }
 
@@ -873,34 +855,32 @@ static u8 __devinit ata66_siimage(ide_hwif_t *hwif)
 
 static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
 {
+       u8 sata = is_sata(hwif);
+
        hwif->resetproc = &siimage_reset;
        hwif->set_pio_mode = &sil_set_pio_mode;
        hwif->set_dma_mode = &sil_set_dma_mode;
-       hwif->reset_poll = &siimage_reset_poll;
-       hwif->pre_reset = &siimage_pre_reset;
-       hwif->udma_filter = &sil_udma_filter;
 
-       if(is_sata(hwif)) {
+       if (sata) {
                static int first = 1;
 
-               hwif->busproc   = &siimage_busproc;
+               hwif->busproc = &sil_sata_busproc;
+               hwif->reset_poll = &sil_sata_reset_poll;
+               hwif->pre_reset = &sil_sata_pre_reset;
+               hwif->udma_filter = &sil_sata_udma_filter;
 
                if (first) {
                        printk(KERN_INFO "siimage: For full SATA support you should use the libata sata_sil module.\n");
                        first = 0;
                }
-       }
-
-       hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
+       } else
+               hwif->udma_filter = &sil_pata_udma_filter;
 
        if (hwif->dma_base == 0)
                return;
 
-       hwif->ultra_mask = 0x7f;
-       hwif->mwdma_mask = 0x07;
-
-       if (!is_sata(hwif))
-               hwif->atapi_dma = 1;
+       if (sata)
+               hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA;
 
        if (hwif->cbl != ATA_CBL_PATA40_SHORT)
                hwif->cbl = ata66_siimage(hwif);
@@ -919,12 +899,13 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
                .init_iops      = init_iops_siimage,    \
                .init_hwif      = init_hwif_siimage,    \
                .fixup          = siimage_fixup,        \
-               .autodma        = AUTODMA,              \
-               .bootable       = ON_BOARD,             \
+               .host_flags     = IDE_HFLAG_BOOTABLE,   \
                .pio_mask       = ATA_PIO4,             \
+               .mwdma_mask     = ATA_MWDMA2,           \
+               .udma_mask      = ATA_UDMA6,            \
        }
 
-static ide_pci_device_t siimage_chipsets[] __devinitdata = {
+static const struct ide_port_info siimage_chipsets[] __devinitdata = {
        /* 0 */ DECLARE_SII_DEV("SiI680"),
        /* 1 */ DECLARE_SII_DEV("SiI3112 Serial ATA"),
        /* 2 */ DECLARE_SII_DEV("Adaptec AAR-1210SA")
index 5a54e2e20b3ce8e4e22b613f8ca94b6f3994e65a..6b7bb53acefdc68d1928bd0bd85eb3d0c3e4a5c3 100644 (file)
@@ -264,7 +264,7 @@ static void sis_ata133_program_timings(ide_drive_t *drive, const u8 mode)
        if (mode >= XFER_MW_DMA_0) {
                t1 &= ~0x04;    /* disable UDMA */
                idx = mode - XFER_MW_DMA_0 + 5;
-       }
+       } else
                idx = mode - XFER_PIO_0;
        t1 |= ini_time_value[clk][idx] << 12;
        t1 |= act_time_value[clk][idx] << 16;
@@ -564,38 +564,30 @@ static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif)
 {
        u8 udma_rates[] = { 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x7f, 0x7f };
 
-       if (!hwif->irq)
-               hwif->irq = hwif->channel ? 15 : 14;
-
        hwif->set_pio_mode = &sis_set_pio_mode;
        hwif->set_dma_mode = &sis_set_dma_mode;
 
        if (chipset_family >= ATA_133)
                hwif->udma_filter = sis5513_ata133_udma_filter;
 
-       hwif->drives[0].autotune = 1;
-       hwif->drives[1].autotune = 1;
-
        if (hwif->dma_base == 0)
                return;
 
-       hwif->atapi_dma = 1;
-
        hwif->ultra_mask = udma_rates[chipset_family];
-       hwif->mwdma_mask = 0x07;
 
        if (hwif->cbl != ATA_CBL_PATA40_SHORT)
                hwif->cbl = ata66_sis5513(hwif);
 }
 
-static ide_pci_device_t sis5513_chipset __devinitdata = {
+static const struct ide_port_info sis5513_chipset __devinitdata = {
        .name           = "SIS5513",
        .init_chipset   = init_chipset_sis5513,
        .init_hwif      = init_hwif_sis5513,
-       .autodma        = NOAUTODMA,
        .enablebits     = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
-       .bootable       = ON_BOARD,
+       .host_flags     = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_NO_AUTODMA |
+                         IDE_HFLAG_BOOTABLE,
        .pio_mask       = ATA_PIO4,
+       .mwdma_mask     = ATA_MWDMA2,
 };
 
 static int __devinit sis5513_init_one(struct pci_dev *dev, const struct pci_device_id *id)
index 771efb8884c8d37eec36e5fb79a7fb1a416246c2..147d783f7529e681fb1d69645942d00780bd42e0 100644 (file)
@@ -361,19 +361,6 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
        hwif->selectproc        = &sl82c105_selectproc;
        hwif->resetproc         = &sl82c105_resetproc;
 
-       /*
-        * We support 32-bit I/O on this interface, and
-        * it doesn't have problems with interrupts.
-        */
-       hwif->drives[0].io_32bit = hwif->drives[1].io_32bit = 1;
-       hwif->drives[0].unmask   = hwif->drives[1].unmask   = 1;
-
-       /*
-        * We always autotune PIO,  this is done before DMA is checked,
-        * so there's no risk of accidentally disabling DMA
-        */
-       hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
-
        if (!hwif->dma_base)
                return;
 
@@ -388,8 +375,7 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
                return;
        }
 
-       hwif->atapi_dma  = 1;
-       hwif->mwdma_mask = 0x07;
+       hwif->mwdma_mask = ATA_MWDMA2;
 
        hwif->ide_dma_on                = &sl82c105_ide_dma_on;
        hwif->dma_off_quietly           = &sl82c105_dma_off_quietly;
@@ -401,13 +387,15 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
                hwif->serialized = hwif->mate->serialized = 1;
 }
 
-static ide_pci_device_t sl82c105_chipset __devinitdata = {
+static const struct ide_port_info sl82c105_chipset __devinitdata = {
        .name           = "W82C105",
        .init_chipset   = init_chipset_sl82c105,
        .init_hwif      = init_hwif_sl82c105,
-       .autodma        = NOAUTODMA,
        .enablebits     = {{0x40,0x01,0x01}, {0x40,0x10,0x10}},
-       .bootable       = ON_BOARD,
+       .host_flags     = IDE_HFLAG_IO_32BIT |
+                         IDE_HFLAG_UNMASK_IRQS |
+                         IDE_HFLAG_NO_AUTODMA |
+                         IDE_HFLAG_BOOTABLE,
        .pio_mask       = ATA_PIO5,
 };
 
index fa8df6d43832b11ebd0686f1d51a52ab6253db07..eb4445b229ed431602bff6bfe7e65d94b8ac53d7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/ide/pci/slc90e66.c   Version 0.18    Aug 9, 2007
+ *  linux/drivers/ide/pci/slc90e66.c   Version 0.19    Sep 24, 2007
  *
  *  Copyright (C) 2000-2002 Andre Hedrick <andre@linux-ide.org>
  *  Copyright (C) 2006-2007 MontaVista Software, Inc. <source@mvista.com>
@@ -21,6 +21,8 @@
 
 #include <asm/io.h>
 
+static DEFINE_SPINLOCK(slc90e66_lock);
+
 static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
        ide_hwif_t *hwif        = HWIF(drive);
@@ -40,7 +42,7 @@ static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio)
                                        { 2, 1 },
                                        { 2, 3 }, };
 
-       spin_lock_irqsave(&ide_lock, flags);
+       spin_lock_irqsave(&slc90e66_lock, flags);
        pci_read_config_word(dev, master_port, &master_data);
 
        if (pio > 1)
@@ -71,7 +73,7 @@ static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio)
        pci_write_config_word(dev, master_port, master_data);
        if (is_slave)
                pci_write_config_byte(dev, slave_port, slave_data);
-       spin_unlock_irqrestore(&ide_lock, flags);
+       spin_unlock_irqrestore(&slc90e66_lock, flags);
 }
 
 static void slc90e66_set_dma_mode(ide_drive_t *drive, const u8 speed)
@@ -133,37 +135,28 @@ static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif)
        u8 reg47 = 0;
        u8 mask = hwif->channel ? 0x01 : 0x02;  /* bit0:Primary */
 
-       if (!hwif->irq)
-               hwif->irq = hwif->channel ? 15 : 14;
-
        hwif->set_pio_mode = &slc90e66_set_pio_mode;
        hwif->set_dma_mode = &slc90e66_set_dma_mode;
 
        pci_read_config_byte(hwif->pci_dev, 0x47, &reg47);
 
-       hwif->drives[0].autotune = 1;
-       hwif->drives[1].autotune = 1;
-
        if (hwif->dma_base == 0)
                return;
 
-       hwif->atapi_dma = 1;
-       hwif->ultra_mask = 0x1f;
-       hwif->mwdma_mask = 0x06;
-       hwif->swdma_mask = 0x04;
-
        if (hwif->cbl != ATA_CBL_PATA40_SHORT)
                /* bit[0(1)]: 0:80, 1:40 */
                hwif->cbl = (reg47 & mask) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
 }
 
-static ide_pci_device_t slc90e66_chipset __devinitdata = {
+static const struct ide_port_info slc90e66_chipset __devinitdata = {
        .name           = "SLC90E66",
        .init_hwif      = init_hwif_slc90e66,
-       .autodma        = AUTODMA,
        .enablebits     = {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
-       .bootable       = ON_BOARD,
+       .host_flags     = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE,
        .pio_mask       = ATA_PIO4,
+       .swdma_mask     = ATA_SWDMA2_ONLY,
+       .mwdma_mask     = ATA_MWDMA12_ONLY,
+       .udma_mask      = ATA_UDMA4,
 };
 
 static int __devinit slc90e66_init_one(struct pci_dev *dev, const struct pci_device_id *id)
index de62db576adcf50647d815c8cfc0f66b88dc6b89..a66ebd14664e66149bce9ada527692a7acd7977b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * drivers/ide/pci/tc86c001.c  Version 1.00    Dec 12, 2006
+ * drivers/ide/pci/tc86c001.c  Version 1.01    Sep 5, 2007
  *
  * Copyright (C) 2002 Toshiba Corporation
  * Copyright (C) 2005-2006 MontaVista Software, Inc. <source@mvista.com>
@@ -17,7 +17,7 @@ static void tc86c001_set_mode(ide_drive_t *drive, const u8 speed)
 {
        ide_hwif_t *hwif        = HWIF(drive);
        unsigned long scr_port  = hwif->config_data + (drive->dn ? 0x02 : 0x00);
-       u16 mode, scr           = hwif->INW(scr_port);
+       u16 mode, scr           = inw(scr_port);
 
        switch (speed) {
                case XFER_UDMA_4:       mode = 0x00c0; break;
@@ -65,7 +65,7 @@ static int tc86c001_timer_expiry(ide_drive_t *drive)
        ide_hwif_t *hwif        = HWIF(drive);
        ide_expiry_t *expiry    = ide_get_hwifdata(hwif);
        ide_hwgroup_t *hwgroup  = HWGROUP(drive);
-       u8 dma_stat             = hwif->INB(hwif->dma_status);
+       u8 dma_stat             = inb(hwif->dma_status);
 
        /* Restore a higher level driver's expiry handler first. */
        hwgroup->expiry = expiry;
@@ -73,7 +73,7 @@ static int tc86c001_timer_expiry(ide_drive_t *drive)
        if ((dma_stat & 5) == 1) {      /* DMA active and no interrupt */
                unsigned long sc_base   = hwif->config_data;
                unsigned long twcr_port = sc_base + (drive->dn ? 0x06 : 0x04);
-               u8 dma_cmd              = hwif->INB(hwif->dma_command);
+               u8 dma_cmd              = inb(hwif->dma_command);
 
                printk(KERN_WARNING "%s: DMA interrupt possibly stuck, "
                       "attempting recovery...\n", drive->name);
@@ -135,7 +135,7 @@ static int tc86c001_busproc(ide_drive_t *drive, int state)
        u16 scr1;
 
        /* System Control 1 Register bit 11 (ATA Hard Reset) read */
-       scr1 = hwif->INW(sc_base + 0x00);
+       scr1 = inw(sc_base + 0x00);
 
        switch (state) {
                case BUSSTATE_ON:
@@ -165,7 +165,7 @@ static int tc86c001_busproc(ide_drive_t *drive, int state)
 static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)
 {
        unsigned long sc_base   = pci_resource_start(hwif->pci_dev, 5);
-       u16 scr1                = hwif->INW(sc_base + 0x00);;
+       u16 scr1                = inw(sc_base + 0x00);
 
        /* System Control 1 Register bit 15 (Soft Reset) set */
        outw(scr1 |  0x8000, sc_base + 0x00);
@@ -184,8 +184,6 @@ static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)
 
        hwif->busproc   = &tc86c001_busproc;
 
-       hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
-
        if (!hwif->dma_base)
                return;
 
@@ -198,10 +196,6 @@ static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)
        /* Sector Count Register limit */
        hwif->rqsize     = 0xffff;
 
-       hwif->atapi_dma  = 1;
-       hwif->ultra_mask = 0x1f;
-       hwif->mwdma_mask = 0x07;
-
        hwif->dma_start         = &tc86c001_dma_start;
 
        if (hwif->cbl != ATA_CBL_PATA40_SHORT) {
@@ -209,7 +203,7 @@ static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)
                 * System Control  1 Register bit 13 (PDIAGN):
                 * 0=80-pin cable, 1=40-pin cable
                 */
-               scr1 = hwif->INW(sc_base + 0x00);
+               scr1 = inw(sc_base + 0x00);
                hwif->cbl = (scr1 & 0x2000) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
        }
 }
@@ -224,14 +218,14 @@ static unsigned int __devinit init_chipset_tc86c001(struct pci_dev *dev,
        return err;
 }
 
-static ide_pci_device_t tc86c001_chipset __devinitdata = {
+static const struct ide_port_info tc86c001_chipset __devinitdata = {
        .name           = "TC86C001",
        .init_chipset   = init_chipset_tc86c001,
        .init_hwif      = init_hwif_tc86c001,
-       .autodma        = AUTODMA,
-       .bootable       = OFF_BOARD,
-       .host_flags     = IDE_HFLAG_SINGLE,
+       .host_flags     = IDE_HFLAG_SINGLE | IDE_HFLAG_OFF_BOARD,
        .pio_mask       = ATA_PIO4,
+       .mwdma_mask     = ATA_MWDMA2,
+       .udma_mask      = ATA_UDMA4,
 };
 
 static int __devinit tc86c001_init_one(struct pci_dev *dev,
index 4075c907f05cf4bea497cb017786919c56979ba9..a227c41d23a3110e0efaaec5cebe40ac7718cc2b 100644 (file)
@@ -100,22 +100,16 @@ static void __devinit init_hwif_triflex(ide_hwif_t *hwif)
 {
        hwif->set_pio_mode = &triflex_set_pio_mode;
        hwif->set_dma_mode = &triflex_set_mode;
-
-       if (hwif->dma_base == 0)
-               return;
-
-       hwif->atapi_dma  = 1;
-       hwif->mwdma_mask = 0x07;
-       hwif->swdma_mask = 0x07;
 }
 
-static ide_pci_device_t triflex_device __devinitdata = {
+static const struct ide_port_info triflex_device __devinitdata = {
        .name           = "TRIFLEX",
        .init_hwif      = init_hwif_triflex,
-       .autodma        = AUTODMA,
        .enablebits     = {{0x80, 0x01, 0x01}, {0x80, 0x02, 0x02}},
-       .bootable       = ON_BOARD,
+       .host_flags     = IDE_HFLAG_BOOTABLE,
        .pio_mask       = ATA_PIO4,
+       .swdma_mask     = ATA_SWDMA2,
+       .mwdma_mask     = ATA_MWDMA2,
 };
 
 static int __devinit triflex_init_one(struct pci_dev *dev, 
index e3d943ada7b0d5be11743c2f426eb10de88f6174..5011ba22e36c4e23a73a39ca98700ef2c31de738 100644 (file)
@@ -250,8 +250,6 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
        u8 reg = 0;
        struct pci_dev *dev = hwif->pci_dev;
 
-       hwif->no_lba48 = 1;
-       hwif->chipset = ide_trm290;
        cfgbase = pci_resource_start(dev, 4);
        if ((dev->class & 5) && cfgbase) {
                hwif->config_data = cfgbase;
@@ -321,14 +319,17 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
 #endif
 }
 
-static ide_pci_device_t trm290_chipset __devinitdata = {
+static const struct ide_port_info trm290_chipset __devinitdata = {
        .name           = "TRM290",
        .init_hwif      = init_hwif_trm290,
-       .autodma        = NOAUTODMA,
-       .bootable       = ON_BOARD,
+       .chipset        = ide_trm290,
+       .host_flags     = IDE_HFLAG_NO_ATAPI_DMA |
 #if 0 /* play it safe for now */
-       .host_flags     = IDE_HFLAG_TRUST_BIOS_FOR_DMA,
+                         IDE_HFLAG_TRUST_BIOS_FOR_DMA |
 #endif
+                         IDE_HFLAG_NO_AUTODMA |
+                         IDE_HFLAG_BOOTABLE |
+                         IDE_HFLAG_NO_LBA48,
 };
 
 static int __devinit trm290_init_one(struct pci_dev *dev, const struct pci_device_id *id)
index b25fb65b240e10cc0e9d07cf7cb525f1bbaa084e..a0d3c16b68ec4fdba9d4d54d9a2bcb6e7181860e 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *
- * Version 3.49
+ * Version 3.50
  *
  * VIA IDE driver for Linux. Supported southbridges:
  *
@@ -422,67 +422,40 @@ static u8 __devinit via82cxxx_cable_detect(ide_hwif_t *hwif)
 
 static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
 {
-       struct via82cxxx_dev *vdev = pci_get_drvdata(hwif->pci_dev);
-       int i;
-
        hwif->set_pio_mode = &via_set_pio_mode;
        hwif->set_dma_mode = &via_set_drive;
 
-#ifdef CONFIG_PPC_CHRP
-       if(machine_is(chrp) && _chrp_type == _CHRP_Pegasos) {
-               hwif->irq = hwif->channel ? 15 : 14;
-       }
-#endif
-
-       for (i = 0; i < 2; i++) {
-               hwif->drives[i].io_32bit = 1;
-               hwif->drives[i].unmask = (vdev->via_config->flags & VIA_NO_UNMASK) ? 0 : 1;
-               hwif->drives[i].autotune = 1;
-       }
-
        if (!hwif->dma_base)
                return;
 
-       hwif->atapi_dma = 1;
-
-       hwif->ultra_mask = vdev->via_config->udma_mask;
-       hwif->mwdma_mask = 0x07;
-       hwif->swdma_mask = 0x07;
-
        if (hwif->cbl != ATA_CBL_PATA40_SHORT)
                hwif->cbl = via82cxxx_cable_detect(hwif);
 }
 
-static ide_pci_device_t via82cxxx_chipsets[] __devinitdata = {
-       {       /* 0 */
-               .name           = "VP_IDE",
-               .init_chipset   = init_chipset_via82cxxx,
-               .init_hwif      = init_hwif_via82cxxx,
-               .autodma        = NOAUTODMA,
-               .enablebits     = {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
-               .bootable       = ON_BOARD,
-               .host_flags     = IDE_HFLAG_PIO_NO_BLACKLIST
-                               | IDE_HFLAG_PIO_NO_DOWNGRADE
-                               | IDE_HFLAG_POST_SET_MODE,
-               .pio_mask       = ATA_PIO5,
-       },{     /* 1 */
-               .name           = "VP_IDE",
-               .init_chipset   = init_chipset_via82cxxx,
-               .init_hwif      = init_hwif_via82cxxx,
-               .autodma        = AUTODMA,
-               .enablebits     = {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
-               .bootable       = ON_BOARD,
-               .host_flags     = IDE_HFLAG_PIO_NO_BLACKLIST
-                               | IDE_HFLAG_PIO_NO_DOWNGRADE
-                               | IDE_HFLAG_POST_SET_MODE,
-               .pio_mask       = ATA_PIO5,
-       }
+static const struct ide_port_info via82cxxx_chipset __devinitdata = {
+       .name           = "VP_IDE",
+       .init_chipset   = init_chipset_via82cxxx,
+       .init_hwif      = init_hwif_via82cxxx,
+       .enablebits     = { { 0x40, 0x02, 0x02 }, { 0x40, 0x01, 0x01 } },
+       .host_flags     = IDE_HFLAG_PIO_NO_BLACKLIST |
+                         IDE_HFLAG_PIO_NO_DOWNGRADE |
+                         IDE_HFLAG_POST_SET_MODE |
+                         IDE_HFLAG_IO_32BIT |
+                         IDE_HFLAG_BOOTABLE,
+       .pio_mask       = ATA_PIO5,
+       .swdma_mask     = ATA_SWDMA2,
+       .mwdma_mask     = ATA_MWDMA2,
 };
 
 static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
        struct pci_dev *isa = NULL;
        struct via_isa_bridge *via_config;
+       u8 idx = id->driver_data;
+       struct ide_port_info d;
+
+       d = via82cxxx_chipset;
+
        /*
         * Find the ISA bridge and check we know what it is.
         */
@@ -492,7 +465,23 @@ static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_i
                printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, disabling DMA.\n");
                return -ENODEV;
        }
-       return ide_setup_pci_device(dev, &via82cxxx_chipsets[id->driver_data]);
+
+       if (idx == 0)
+               d.host_flags |= IDE_HFLAG_NO_AUTODMA;
+       else
+               d.enablebits[1].reg = d.enablebits[0].reg = 0;
+
+       if ((via_config->flags & VIA_NO_UNMASK) == 0)
+               d.host_flags |= IDE_HFLAG_UNMASK_IRQS;
+
+#ifdef CONFIG_PPC_CHRP
+       if (machine_is(chrp) && _chrp_type == _CHRP_Pegasos)
+               d.host_flags |= IDE_HFLAG_FORCE_LEGACY_IRQS;
+#endif
+
+       d.udma_mask = via_config->udma_mask;
+
+       return ide_setup_pci_device(dev, &d);
 }
 
 static const struct pci_device_id via_pci_tbl[] = {
index df2e92034f5d3719658008a1ec1e3eeee059ba85..5f0da35ab5ad0a3ef977ab67c8145c0733f47245 100644 (file)
@@ -316,8 +316,8 @@ m8xx_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port,
 
        ide_hwifs[data_port].pio_mask = ATA_PIO4;
        ide_hwifs[data_port].set_pio_mode = m8xx_ide_set_pio_mode;
+       ide_hwifs[data_port].ack_intr = (ide_ack_intr_t *)ide_interrupt_ack;
 
-       hw->ack_intr = (ide_ack_intr_t *) ide_interrupt_ack;
        /* Enable Harddisk Interrupt,
         * and make it edge sensitive
         */
@@ -402,8 +402,8 @@ void m8xx_ide_init_hwif_ports (hw_regs_t *hw,
 
        ide_hwifs[data_port].pio_mask = ATA_PIO4;
        ide_hwifs[data_port].set_pio_mode = m8xx_ide_set_pio_mode;
+       ide_hwifs[data_port].ack_intr = (ide_ack_intr_t *)ide_interrupt_ack;
 
-       hw->ack_intr = (ide_ack_intr_t *) ide_interrupt_ack;
        /* Enable Harddisk Interrupt,
         * and make it edge sensitive
         */
index 1d25a3433008699dca36c172d610fff87d278033..816b5311dad647febb4577991f53102c4e537d1b 100644 (file)
@@ -1039,6 +1039,8 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
 {
        struct device_node *np = pmif->node;
        const int *bidp;
+       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+       hw_regs_t hw;
 
        pmif->cable_80 = 0;
        pmif->broken_dma = pmif->broken_dma_warn = 0;
@@ -1124,8 +1126,9 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
        /* Tell common code _not_ to mess with resources */
        hwif->mmio = 1;
        hwif->hwif_data = pmif;
-       pmac_ide_init_hwif_ports(&hwif->hw, pmif->regbase, 0, &hwif->irq);
-       memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
+       memset(&hw, 0, sizeof(hw));
+       pmac_ide_init_hwif_ports(&hw, pmif->regbase, 0, &hwif->irq);
+       memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports));
        hwif->chipset = ide_pmac;
        hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET] || pmif->mediabay;
        hwif->hold = pmif->mediabay;
@@ -1163,10 +1166,9 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
                pmac_ide_setup_dma(pmif, hwif);
 #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
 
-       /* We probe the hwif now */
-       probe_hwif_init(hwif);
+       idx[0] = hwif->index;
 
-       ide_proc_register_port(hwif);
+       ide_device_add(idx);
 
        return 0;
 }
@@ -1780,7 +1782,6 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
        hwif->dma_timeout = &ide_dma_timeout;
        hwif->dma_lost_irq = &pmac_ide_dma_lost_irq;
 
-       hwif->atapi_dma = 1;
        switch(pmif->kind) {
                case controller_sh_ata6:
                        hwif->ultra_mask = pmif->cable_80 ? 0x7f : 0x07;
index 3d101f73f9108399ba093e7a0ae4e3fdfdc6331b..02d14bf85ab2112b11a589e8fad9c73d428686bb 100644 (file)
@@ -147,14 +147,15 @@ static int ide_setup_pci_baseregs (struct pci_dev *dev, const char *name)
 #ifdef CONFIG_BLK_DEV_IDEDMA_PCI
 /**
  *     ide_get_or_set_dma_base         -       setup BMIBA
- *     @hwif: Interface
+ *     @d: IDE port info
+ *     @hwif: IDE interface
  *
  *     Fetch the DMA Bus-Master-I/O-Base-Address (BMIBA) from PCI space.
  *     Where a device has a partner that is already in DMA mode we check
  *     and enforce IDE simplex rules.
  */
 
-static unsigned long ide_get_or_set_dma_base (ide_hwif_t *hwif)
+static unsigned long ide_get_or_set_dma_base(const struct ide_port_info *d, ide_hwif_t *hwif)
 {
        unsigned long   dma_base = 0;
        struct pci_dev  *dev = hwif->pci_dev;
@@ -165,14 +166,15 @@ static unsigned long ide_get_or_set_dma_base (ide_hwif_t *hwif)
        if (hwif->mate && hwif->mate->dma_base) {
                dma_base = hwif->mate->dma_base - (hwif->channel ? 0 : 8);
        } else {
-               dma_base = pci_resource_start(dev, 4);
-               if (!dma_base) {
-                       printk(KERN_ERR "%s: dma_base is invalid\n",
-                                       hwif->cds->name);
-               }
+               u8 baridx = (d->host_flags & IDE_HFLAG_CS5520) ? 2 : 4;
+
+               dma_base = pci_resource_start(dev, baridx);
+
+               if (dma_base == 0)
+                       printk(KERN_ERR "%s: DMA base is invalid\n", d->name);
        }
 
-       if (dma_base) {
+       if ((d->host_flags & IDE_HFLAG_CS5520) == 0 && dma_base) {
                u8 simplex_stat = 0;
                dma_base += hwif->channel ? 8 : 0;
 
@@ -183,13 +185,13 @@ static unsigned long ide_get_or_set_dma_base (ide_hwif_t *hwif)
                        case PCI_DEVICE_ID_CMD_643:
                        case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE:
                        case PCI_DEVICE_ID_REVOLUTION:
-                               simplex_stat = hwif->INB(dma_base + 2);
-                               hwif->OUTB((simplex_stat&0x60),(dma_base + 2));
-                               simplex_stat = hwif->INB(dma_base + 2);
+                               simplex_stat = inb(dma_base + 2);
+                               outb(simplex_stat & 0x60, dma_base + 2);
+                               simplex_stat = inb(dma_base + 2);
                                if (simplex_stat & 0x80) {
                                        printk(KERN_INFO "%s: simplex device: "
-                                               "DMA forced\n",
-                                               hwif->cds->name);
+                                                        "DMA forced\n",
+                                                        d->name);
                                }
                                break;
                        default:
@@ -212,8 +214,8 @@ static unsigned long ide_get_or_set_dma_base (ide_hwif_t *hwif)
  */
                                        if (hwif->mate && hwif->mate->dma_base) {
                                                printk(KERN_INFO "%s: simplex device: "
-                                                       "DMA disabled\n",
-                                                       hwif->cds->name);
+                                                                "DMA disabled\n",
+                                                                d->name);
                                                dma_base = 0;
                                        }
                                }
@@ -223,10 +225,11 @@ static unsigned long ide_get_or_set_dma_base (ide_hwif_t *hwif)
 }
 #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
 
-void ide_setup_pci_noise (struct pci_dev *dev, ide_pci_device_t *d)
+void ide_setup_pci_noise(struct pci_dev *dev, const struct ide_port_info *d)
 {
-       printk(KERN_INFO "%s: IDE controller at PCI slot %s\n",
-                        d->name, pci_name(dev));
+       printk(KERN_INFO "%s: IDE controller (0x%04x:0x%04x rev 0x%02x) at "
+                        " PCI slot %s\n", d->name, dev->vendor, dev->device,
+                        dev->revision, pci_name(dev));
 }
 
 EXPORT_SYMBOL_GPL(ide_setup_pci_noise);
@@ -235,15 +238,15 @@ EXPORT_SYMBOL_GPL(ide_setup_pci_noise);
 /**
  *     ide_pci_enable  -       do PCI enables
  *     @dev: PCI device
- *     @d: IDE pci device data
+ *     @d: IDE port info
  *
  *     Enable the IDE PCI device. We attempt to enable the device in full
  *     but if that fails then we only need BAR4 so we will enable that.
  *     
  *     Returns zero on success or an error code
  */
-static int ide_pci_enable(struct pci_dev *dev, ide_pci_device_t *d)
+
+static int ide_pci_enable(struct pci_dev *dev, const struct ide_port_info *d)
 {
        int ret;
 
@@ -258,9 +261,9 @@ static int ide_pci_enable(struct pci_dev *dev, ide_pci_device_t *d)
        }
 
        /*
-        * assume all devices can do 32-bit dma for now. we can add a
-        * dma mask field to the ide_pci_device_t if we need it (or let
-        * lower level driver set the dma mask)
+        * assume all devices can do 32-bit DMA for now, we can add
+        * a DMA mask field to the struct ide_port_info if we need it
+        * (or let lower level driver set the DMA mask)
         */
        ret = pci_set_dma_mask(dev, DMA_32BIT_MASK);
        if (ret < 0) {
@@ -282,13 +285,13 @@ out:
 /**
  *     ide_pci_configure       -       configure an unconfigured device
  *     @dev: PCI device
- *     @d: IDE pci device data
+ *     @d: IDE port info
  *
  *     Enable and configure the PCI device we have been passed.
  *     Returns zero on success or an error code.
  */
-static int ide_pci_configure(struct pci_dev *dev, ide_pci_device_t *d)
+
+static int ide_pci_configure(struct pci_dev *dev, const struct ide_port_info *d)
 {
        u16 pcicmd = 0;
        /*
@@ -316,15 +319,15 @@ static int ide_pci_configure(struct pci_dev *dev, ide_pci_device_t *d)
 
 /**
  *     ide_pci_check_iomem     -       check a register is I/O
- *     @dev: pci device
- *     @d: ide_pci_device
- *     @bar: bar number
+ *     @dev: PCI device
+ *     @d: IDE port info
+ *     @bar: BAR number
  *
  *     Checks if a BAR is configured and points to MMIO space. If so
  *     print an error and return an error code. Otherwise return 0
  */
-static int ide_pci_check_iomem(struct pci_dev *dev, ide_pci_device_t *d, int bar)
+
+static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info *d, int bar)
 {
        ulong flags = pci_resource_flags(dev, bar);
        
@@ -346,7 +349,7 @@ static int ide_pci_check_iomem(struct pci_dev *dev, ide_pci_device_t *d, int bar
 /**
  *     ide_hwif_configure      -       configure an IDE interface
  *     @dev: PCI device holding interface
- *     @d: IDE pci data
+ *     @d: IDE port info
  *     @mate: Paired interface if any
  *
  *     Perform the initial set up for the hardware interface structure. This
@@ -355,11 +358,12 @@ static int ide_pci_check_iomem(struct pci_dev *dev, ide_pci_device_t *d, int bar
  *
  *     Returns the new hardware interface structure, or NULL on a failure
  */
-static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, ide_pci_device_t *d, ide_hwif_t *mate, int port, int irq)
+
+static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, const struct ide_port_info *d, ide_hwif_t *mate, int port, int irq)
 {
        unsigned long ctl = 0, base = 0;
        ide_hwif_t *hwif;
+       u8 bootable = (d->host_flags & IDE_HFLAG_BOOTABLE) ? 1 : 0;
 
        if ((d->host_flags & IDE_HFLAG_ISA_PORTS) == 0) {
                /*  Possibly we should fail if these checks report true */
@@ -380,23 +384,24 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, ide_pci_device_t *d,
                ctl = port ? 0x374 : 0x3f4;
                base = port ? 0x170 : 0x1f0;
        }
-       if ((hwif = ide_match_hwif(base, d->bootable, d->name)) == NULL)
+       if ((hwif = ide_match_hwif(base, bootable, d->name)) == NULL)
                return NULL;    /* no room in ide_hwifs[] */
        if (hwif->io_ports[IDE_DATA_OFFSET] != base ||
            hwif->io_ports[IDE_CONTROL_OFFSET] != (ctl | 2)) {
-               memset(&hwif->hw, 0, sizeof(hwif->hw));
-#ifndef IDE_ARCH_OBSOLETE_INIT
-               ide_std_init_ports(&hwif->hw, base, (ctl | 2));
-               hwif->hw.io_ports[IDE_IRQ_OFFSET] = 0;
+               hw_regs_t hw;
+
+               memset(&hw, 0, sizeof(hw));
+#ifndef CONFIG_IDE_ARCH_OBSOLETE_INIT
+               ide_std_init_ports(&hw, base, ctl | 2);
 #else
-               ide_init_hwif_ports(&hwif->hw, base, (ctl | 2), NULL);
+               ide_init_hwif_ports(&hw, base, ctl | 2, NULL);
 #endif
-               memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
+               memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports));
                hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
        }
-       hwif->chipset = ide_pci;
+       hwif->chipset = d->chipset ? d->chipset : ide_pci;
        hwif->pci_dev = dev;
-       hwif->cds = (struct ide_pci_device_s *) d;
+       hwif->cds = d;
        hwif->channel = port;
 
        if (!hwif->irq)
@@ -411,28 +416,25 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, ide_pci_device_t *d,
 /**
  *     ide_hwif_setup_dma      -       configure DMA interface
  *     @dev: PCI device
- *     @d: IDE pci data
- *     @hwif: Hardware interface we are configuring
+ *     @d: IDE port info
+ *     @hwif: IDE interface
  *
  *     Set up the DMA base for the interface. Enable the master bits as
  *     necessary and attempt to bring the device DMA into a ready to use
  *     state
  */
-#ifndef CONFIG_BLK_DEV_IDEDMA_PCI
-static void ide_hwif_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwif_t *hwif)
-{
-}
-#else
-static void ide_hwif_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwif_t *hwif)
+
+static void ide_hwif_setup_dma(struct pci_dev *dev, const struct ide_port_info *d, ide_hwif_t *hwif)
 {
+#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
        u16 pcicmd;
+
        pci_read_config_word(dev, PCI_COMMAND, &pcicmd);
 
-       if ((d->autodma == AUTODMA) ||
+       if ((d->host_flags & IDE_HFLAG_NO_AUTODMA) == 0 ||
            ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE &&
             (dev->class & 0x80))) {
-               unsigned long dma_base = ide_get_or_set_dma_base(hwif);
+               unsigned long dma_base = ide_get_or_set_dma_base(d, hwif);
                if (dma_base && !(pcicmd & PCI_COMMAND_MASTER)) {
                        /*
                         * Set up BM-DMA capability
@@ -456,13 +458,13 @@ static void ide_hwif_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwi
                                "(BIOS)\n", hwif->name, d->name);
                }
        }
-}
 #endif /* CONFIG_BLK_DEV_IDEDMA_PCI*/
+}
 
 /**
  *     ide_setup_pci_controller        -       set up IDE PCI
  *     @dev: PCI device
- *     @d: IDE PCI data
+ *     @d: IDE port info
  *     @noisy: verbose flag
  *     @config: returned as 1 if we configured the hardware
  *
@@ -470,11 +472,10 @@ static void ide_hwif_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwi
  *     up the PCI side of the device, checks that the device is enabled
  *     and enables it if need be
  */
-static int ide_setup_pci_controller(struct pci_dev *dev, ide_pci_device_t *d, int noisy, int *config)
+
+static int ide_setup_pci_controller(struct pci_dev *dev, const struct ide_port_info *d, int noisy, int *config)
 {
        int ret;
-       u32 class_rev;
        u16 pcicmd;
 
        if (noisy)
@@ -497,10 +498,6 @@ static int ide_setup_pci_controller(struct pci_dev *dev, ide_pci_device_t *d, in
                printk(KERN_INFO "%s: device enabled (Linux)\n", d->name);
        }
 
-       pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
-       class_rev &= 0xff;
-       if (noisy)
-               printk(KERN_INFO "%s: chipset revision %d\n", d->name, class_rev);
 out:
        return ret;
 }
@@ -508,9 +505,9 @@ out:
 /**
  *     ide_pci_setup_ports     -       configure ports/devices on PCI IDE
  *     @dev: PCI device
- *     @d: IDE pci device info
+ *     @d: IDE port info
  *     @pciirq: IRQ line
- *     @index: ata index to update
+ *     @idx: ATA index table to update
  *
  *     Scan the interfaces attached to this device and do any
  *     necessary per port setup. Attach the devices and ask the
@@ -520,26 +517,25 @@ out:
  *     but is also used directly as a helper function by some controllers
  *     where the chipset setup is not the default PCI IDE one.
  */
-void ide_pci_setup_ports(struct pci_dev *dev, ide_pci_device_t *d, int pciirq, ata_index_t *index)
+
+void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, int pciirq, u8 *idx)
 {
        int channels = (d->host_flags & IDE_HFLAG_SINGLE) ? 1 : 2, port;
-       int at_least_one_hwif_enabled = 0;
        ide_hwif_t *hwif, *mate = NULL;
        u8 tmp;
 
-       index->all = 0xf0f0;
-
        /*
         * Set up the IDE ports
         */
-        
+
        for (port = 0; port < channels; ++port) {
-               ide_pci_enablebit_t *e = &(d->enablebits[port]);
-       
+               const ide_pci_enablebit_t *e = &(d->enablebits[port]);
+
                if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) ||
-                   (tmp & e->mask) != e->val))
+                   (tmp & e->mask) != e->val)) {
+                       printk(KERN_INFO "%s: IDE port disabled\n", d->name);
                        continue;       /* port not enabled */
+               }
 
                if ((hwif = ide_hwif_configure(dev, d, mate, port, pciirq)) == NULL)
                        continue;
@@ -547,27 +543,49 @@ void ide_pci_setup_ports(struct pci_dev *dev, ide_pci_device_t *d, int pciirq, a
                /* setup proper ancestral information */
                hwif->gendev.parent = &dev->dev;
 
-               if (hwif->channel) {
-                       index->b.high = hwif->index;
-               } else {
-                       index->b.low = hwif->index;
-               }
+               *(idx + port) = hwif->index;
 
                
                if (d->init_iops)
                        d->init_iops(hwif);
 
-               if (d->autodma == NODMA)
-                       goto bypass_legacy_dma;
-
-               if(d->init_setup_dma)
-                       d->init_setup_dma(dev, d, hwif);
-               else
+               if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0)
                        ide_hwif_setup_dma(dev, d, hwif);
-bypass_legacy_dma:
+
+               if ((!hwif->irq && (d->host_flags & IDE_HFLAG_LEGACY_IRQS)) ||
+                   (d->host_flags & IDE_HFLAG_FORCE_LEGACY_IRQS))
+                       hwif->irq = port ? 15 : 14;
+
+               hwif->fixup = d->fixup;
+
                hwif->host_flags = d->host_flags;
                hwif->pio_mask = d->pio_mask;
 
+               if ((d->host_flags & IDE_HFLAG_SERIALIZE) && hwif->mate)
+                       hwif->mate->serialized = hwif->serialized = 1;
+
+               if (d->host_flags & IDE_HFLAG_IO_32BIT) {
+                       hwif->drives[0].io_32bit = 1;
+                       hwif->drives[1].io_32bit = 1;
+               }
+
+               if (d->host_flags & IDE_HFLAG_UNMASK_IRQS) {
+                       hwif->drives[0].unmask = 1;
+                       hwif->drives[1].unmask = 1;
+               }
+
+               if (hwif->dma_base) {
+                       hwif->swdma_mask = d->swdma_mask;
+                       hwif->mwdma_mask = d->mwdma_mask;
+                       hwif->ultra_mask = d->udma_mask;
+               }
+
+               hwif->drives[0].autotune = 1;
+               hwif->drives[1].autotune = 1;
+
+               if (d->host_flags & IDE_HFLAG_RQSIZE_256)
+                       hwif->rqsize = 256;
+
                if (d->init_hwif)
                        /* Call chipset-specific routine
                         * for each enabled hwif
@@ -575,10 +593,7 @@ bypass_legacy_dma:
                        d->init_hwif(hwif);
 
                mate = hwif;
-               at_least_one_hwif_enabled = 1;
        }
-       if (!at_least_one_hwif_enabled)
-               printk(KERN_INFO "%s: neither IDE port enabled (BIOS)\n", d->name);
 }
 
 EXPORT_SYMBOL_GPL(ide_pci_setup_ports);
@@ -590,13 +605,13 @@ EXPORT_SYMBOL_GPL(ide_pci_setup_ports);
  *
  * One thing that is not standardized is the location of the
  * primary/secondary interface "enable/disable" bits.  For chipsets that
- * we "know" about, this information is in the ide_pci_device_t struct;
+ * we "know" about, this information is in the struct ide_port_info;
  * for all other chipsets, we just assume both interfaces are enabled.
  */
-static int do_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t *d,
-                                  ata_index_t *index, u8 noisy)
+static int do_ide_setup_pci_device(struct pci_dev *dev,
+                                  const struct ide_port_info *d,
+                                  u8 *idx, u8 noisy)
 {
-       static ata_index_t ata_index = { .b = { .low = 0xff, .high = 0xff } };
        int tried_config = 0;
        int pciirq, ret;
 
@@ -646,51 +661,35 @@ static int do_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t *d,
 
        /* FIXME: silent failure can happen */
 
-       *index = ata_index;
-       ide_pci_setup_ports(dev, d, pciirq, index);
+       ide_pci_setup_ports(dev, d, pciirq, idx);
 out:
        return ret;
 }
 
-int ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t *d)
+int ide_setup_pci_device(struct pci_dev *dev, const struct ide_port_info *d)
 {
-       ide_hwif_t *hwif = NULL, *mate = NULL;
-       ata_index_t index_list;
+       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
        int ret;
 
-       ret = do_ide_setup_pci_device(dev, d, &index_list, 1);
-       if (ret < 0)
-               goto out;
-
-       if ((index_list.b.low & 0xf0) != 0xf0)
-               hwif = &ide_hwifs[index_list.b.low];
-       if ((index_list.b.high & 0xf0) != 0xf0)
-               mate = &ide_hwifs[index_list.b.high];
+       ret = do_ide_setup_pci_device(dev, d, &idx[0], 1);
 
-       if (hwif)
-               probe_hwif_init_with_fixup(hwif, d->fixup);
-       if (mate)
-               probe_hwif_init_with_fixup(mate, d->fixup);
+       if (ret >= 0)
+               ide_device_add(idx);
 
-       if (hwif)
-               ide_proc_register_port(hwif);
-       if (mate)
-               ide_proc_register_port(mate);
-out:
        return ret;
 }
 
 EXPORT_SYMBOL_GPL(ide_setup_pci_device);
 
 int ide_setup_pci_devices(struct pci_dev *dev1, struct pci_dev *dev2,
-                         ide_pci_device_t *d)
+                         const struct ide_port_info *d)
 {
        struct pci_dev *pdev[] = { dev1, dev2 };
-       ata_index_t index_list[2];
        int ret, i;
+       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 
        for (i = 0; i < 2; i++) {
-               ret = do_ide_setup_pci_device(pdev[i], d, index_list + i, !i);
+               ret = do_ide_setup_pci_device(pdev[i], d, &idx[i*2], !i);
                /*
                 * FIXME: Mom, mom, they stole me the helper function to undo
                 * do_ide_setup_pci_device() on the first device!
@@ -699,25 +698,7 @@ int ide_setup_pci_devices(struct pci_dev *dev1, struct pci_dev *dev2,
                        goto out;
        }
 
-       for (i = 0; i < 2; i++) {
-               u8 idx[2] = { index_list[i].b.low, index_list[i].b.high };
-               int j;
-
-               for (j = 0; j < 2; j++) {
-                       if ((idx[j] & 0xf0) != 0xf0)
-                               probe_hwif_init(ide_hwifs + idx[j]);
-               }
-       }
-
-       for (i = 0; i < 2; i++) {
-               u8 idx[2] = { index_list[i].b.low, index_list[i].b.high };
-               int j;
-
-               for (j = 0; j < 2; j++) {
-                       if ((idx[j] & 0xf0) != 0xf0)
-                               ide_proc_register_port(ide_hwifs + idx[j]);
-               }
-       }
+       ide_device_add(idx);
 out:
        return ret;
 }
@@ -742,9 +723,6 @@ static LIST_HEAD(ide_pci_drivers);
  *     hands the controllers off to the core PCI code to do the rest of
  *     the work.
  *
- *     The driver_data of the driver table must point to an ide_pci_device_t
- *     describing the interface.
- *
  *     Returns are the same as for pci_register_driver
  */
 
index 45d6055819227367fb318e472b1ee2de990b458f..3051e312fdc824733d837529461b13b27cbf587f 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 
 #include "dma.h"
 
@@ -111,7 +111,7 @@ int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes,
                unsigned long va =
                    (unsigned long)dma->kvirt + (i << PAGE_SHIFT);
 
-               dma->sglist[i].page = vmalloc_to_page((void *)va);
+               sg_set_page(&dma->sglist[i], vmalloc_to_page((void *)va));
                dma->sglist[i].length = PAGE_SIZE;
        }
 
index 1b353b964b33fff6c5cfe609c9acc1b6be09f20b..d5dfe11aa5c6ded52e40b6c65c353c22db827b39 100644 (file)
@@ -1466,7 +1466,7 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb,
                cmd->dma_size = sgpnt[0].length;
                cmd->dma_type = CMD_DMA_PAGE;
                cmd->cmd_dma = dma_map_page(hi->host->device.parent,
-                                           sgpnt[0].page, sgpnt[0].offset,
+                                           sg_page(&sgpnt[0]), sgpnt[0].offset,
                                            cmd->dma_size, cmd->dma_dir);
 
                orb->data_descriptor_lo = cmd->cmd_dma;
index 93644f82592c426074a9beba068b4e23d4910b79..0751697ef984a87e7f688238a10760127fd7383f 100644 (file)
@@ -114,13 +114,16 @@ struct rdma_id_private {
 
        struct rdma_bind_list   *bind_list;
        struct hlist_node       node;
-       struct list_head        list;
-       struct list_head        listen_list;
+       struct list_head        list; /* listen_any_list or cma_device.list */
+       struct list_head        listen_list; /* per device listens */
        struct cma_device       *cma_dev;
        struct list_head        mc_list;
 
+       int                     internal_id;
        enum cma_state          state;
        spinlock_t              lock;
+       struct mutex            qp_mutex;
+
        struct completion       comp;
        atomic_t                refcount;
        wait_queue_head_t       wait_remove;
@@ -389,6 +392,7 @@ struct rdma_cm_id *rdma_create_id(rdma_cm_event_handler event_handler,
        id_priv->id.event_handler = event_handler;
        id_priv->id.ps = ps;
        spin_lock_init(&id_priv->lock);
+       mutex_init(&id_priv->qp_mutex);
        init_completion(&id_priv->comp);
        atomic_set(&id_priv->refcount, 1);
        init_waitqueue_head(&id_priv->wait_remove);
@@ -474,61 +478,86 @@ EXPORT_SYMBOL(rdma_create_qp);
 
 void rdma_destroy_qp(struct rdma_cm_id *id)
 {
-       ib_destroy_qp(id->qp);
+       struct rdma_id_private *id_priv;
+
+       id_priv = container_of(id, struct rdma_id_private, id);
+       mutex_lock(&id_priv->qp_mutex);
+       ib_destroy_qp(id_priv->id.qp);
+       id_priv->id.qp = NULL;
+       mutex_unlock(&id_priv->qp_mutex);
 }
 EXPORT_SYMBOL(rdma_destroy_qp);
 
-static int cma_modify_qp_rtr(struct rdma_cm_id *id)
+static int cma_modify_qp_rtr(struct rdma_id_private *id_priv)
 {
        struct ib_qp_attr qp_attr;
        int qp_attr_mask, ret;
 
-       if (!id->qp)
-               return 0;
+       mutex_lock(&id_priv->qp_mutex);
+       if (!id_priv->id.qp) {
+               ret = 0;
+               goto out;
+       }
 
        /* Need to update QP attributes from default values. */
        qp_attr.qp_state = IB_QPS_INIT;
-       ret = rdma_init_qp_attr(id, &qp_attr, &qp_attr_mask);
+       ret = rdma_init_qp_attr(&id_priv->id, &qp_attr, &qp_attr_mask);
        if (ret)
-               return ret;
+               goto out;
 
-       ret = ib_modify_qp(id->qp, &qp_attr, qp_attr_mask);
+       ret = ib_modify_qp(id_priv->id.qp, &qp_attr, qp_attr_mask);
        if (ret)
-               return ret;
+               goto out;
 
        qp_attr.qp_state = IB_QPS_RTR;
-       ret = rdma_init_qp_attr(id, &qp_attr, &qp_attr_mask);
+       ret = rdma_init_qp_attr(&id_priv->id, &qp_attr, &qp_attr_mask);
        if (ret)
-               return ret;
+               goto out;
 
-       return ib_modify_qp(id->qp, &qp_attr, qp_attr_mask);
+       ret = ib_modify_qp(id_priv->id.qp, &qp_attr, qp_attr_mask);
+out:
+       mutex_unlock(&id_priv->qp_mutex);
+       return ret;
 }
 
-static int cma_modify_qp_rts(struct rdma_cm_id *id)
+static int cma_modify_qp_rts(struct rdma_id_private *id_priv)
 {
        struct ib_qp_attr qp_attr;
        int qp_attr_mask, ret;
 
-       if (!id->qp)
-               return 0;
+       mutex_lock(&id_priv->qp_mutex);
+       if (!id_priv->id.qp) {
+               ret = 0;
+               goto out;
+       }
 
        qp_attr.qp_state = IB_QPS_RTS;
-       ret = rdma_init_qp_attr(id, &qp_attr, &qp_attr_mask);
+       ret = rdma_init_qp_attr(&id_priv->id, &qp_attr, &qp_attr_mask);
        if (ret)
-               return ret;
+               goto out;
 
-       return ib_modify_qp(id->qp, &qp_attr, qp_attr_mask);
+       ret = ib_modify_qp(id_priv->id.qp, &qp_attr, qp_attr_mask);
+out:
+       mutex_unlock(&id_priv->qp_mutex);
+       return ret;
 }
 
-static int cma_modify_qp_err(struct rdma_cm_id *id)
+static int cma_modify_qp_err(struct rdma_id_private *id_priv)
 {
        struct ib_qp_attr qp_attr;
+       int ret;
 
-       if (!id->qp)
-               return 0;
+       mutex_lock(&id_priv->qp_mutex);
+       if (!id_priv->id.qp) {
+               ret = 0;
+               goto out;
+       }
 
        qp_attr.qp_state = IB_QPS_ERR;
-       return ib_modify_qp(id->qp, &qp_attr, IB_QP_STATE);
+       ret = ib_modify_qp(id_priv->id.qp, &qp_attr, IB_QP_STATE);
+out:
+       mutex_unlock(&id_priv->qp_mutex);
+       return ret;
 }
 
 static int cma_ib_init_qp_attr(struct rdma_id_private *id_priv,
@@ -717,50 +746,27 @@ static void cma_cancel_route(struct rdma_id_private *id_priv)
        }
 }
 
-static inline int cma_internal_listen(struct rdma_id_private *id_priv)
-{
-       return (id_priv->state == CMA_LISTEN) && id_priv->cma_dev &&
-              cma_any_addr(&id_priv->id.route.addr.src_addr);
-}
-
-static void cma_destroy_listen(struct rdma_id_private *id_priv)
-{
-       cma_exch(id_priv, CMA_DESTROYING);
-
-       if (id_priv->cma_dev) {
-               switch (rdma_node_get_transport(id_priv->id.device->node_type)) {
-               case RDMA_TRANSPORT_IB:
-                       if (id_priv->cm_id.ib && !IS_ERR(id_priv->cm_id.ib))
-                               ib_destroy_cm_id(id_priv->cm_id.ib);
-                       break;
-               case RDMA_TRANSPORT_IWARP:
-                       if (id_priv->cm_id.iw && !IS_ERR(id_priv->cm_id.iw))
-                               iw_destroy_cm_id(id_priv->cm_id.iw);
-                       break;
-               default:
-                       break;
-               }
-               cma_detach_from_dev(id_priv);
-       }
-       list_del(&id_priv->listen_list);
-
-       cma_deref_id(id_priv);
-       wait_for_completion(&id_priv->comp);
-
-       kfree(id_priv);
-}
-
 static void cma_cancel_listens(struct rdma_id_private *id_priv)
 {
        struct rdma_id_private *dev_id_priv;
 
+       /*
+        * Remove from listen_any_list to prevent added devices from spawning
+        * additional listen requests.
+        */
        mutex_lock(&lock);
        list_del(&id_priv->list);
 
        while (!list_empty(&id_priv->listen_list)) {
                dev_id_priv = list_entry(id_priv->listen_list.next,
                                         struct rdma_id_private, listen_list);
-               cma_destroy_listen(dev_id_priv);
+               /* sync with device removal to avoid duplicate destruction */
+               list_del_init(&dev_id_priv->list);
+               list_del(&dev_id_priv->listen_list);
+               mutex_unlock(&lock);
+
+               rdma_destroy_id(&dev_id_priv->id);
+               mutex_lock(&lock);
        }
        mutex_unlock(&lock);
 }
@@ -848,6 +854,9 @@ void rdma_destroy_id(struct rdma_cm_id *id)
        cma_deref_id(id_priv);
        wait_for_completion(&id_priv->comp);
 
+       if (id_priv->internal_id)
+               cma_deref_id(id_priv->id.context);
+
        kfree(id_priv->id.route.path_rec);
        kfree(id_priv);
 }
@@ -857,11 +866,11 @@ static int cma_rep_recv(struct rdma_id_private *id_priv)
 {
        int ret;
 
-       ret = cma_modify_qp_rtr(&id_priv->id);
+       ret = cma_modify_qp_rtr(id_priv);
        if (ret)
                goto reject;
 
-       ret = cma_modify_qp_rts(&id_priv->id);
+       ret = cma_modify_qp_rts(id_priv);
        if (ret)
                goto reject;
 
@@ -871,7 +880,7 @@ static int cma_rep_recv(struct rdma_id_private *id_priv)
 
        return 0;
 reject:
-       cma_modify_qp_err(&id_priv->id);
+       cma_modify_qp_err(id_priv);
        ib_send_cm_rej(id_priv->cm_id.ib, IB_CM_REJ_CONSUMER_DEFINED,
                       NULL, 0, NULL, 0);
        return ret;
@@ -947,7 +956,7 @@ static int cma_ib_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event)
                /* ignore event */
                goto out;
        case IB_CM_REJ_RECEIVED:
-               cma_modify_qp_err(&id_priv->id);
+               cma_modify_qp_err(id_priv);
                event.status = ib_event->param.rej_rcvd.reason;
                event.event = RDMA_CM_EVENT_REJECTED;
                event.param.conn.private_data = ib_event->private_data;
@@ -1404,14 +1413,13 @@ static void cma_listen_on_dev(struct rdma_id_private *id_priv,
 
        cma_attach_to_dev(dev_id_priv, cma_dev);
        list_add_tail(&dev_id_priv->listen_list, &id_priv->listen_list);
+       atomic_inc(&id_priv->refcount);
+       dev_id_priv->internal_id = 1;
 
        ret = rdma_listen(id, id_priv->backlog);
        if (ret)
-               goto err;
-
-       return;
-err:
-       cma_destroy_listen(dev_id_priv);
+               printk(KERN_WARNING "RDMA CMA: cma_listen_on_dev, error %d, "
+                      "listening on device %s", ret, cma_dev->device->name);
 }
 
 static void cma_listen_on_all(struct rdma_id_private *id_priv)
@@ -2264,7 +2272,7 @@ static int cma_connect_iw(struct rdma_id_private *id_priv,
        sin = (struct sockaddr_in*) &id_priv->id.route.addr.dst_addr;
        cm_id->remote_addr = *sin;
 
-       ret = cma_modify_qp_rtr(&id_priv->id);
+       ret = cma_modify_qp_rtr(id_priv);
        if (ret)
                goto out;
 
@@ -2331,7 +2339,7 @@ static int cma_accept_ib(struct rdma_id_private *id_priv,
        int qp_attr_mask, ret;
 
        if (id_priv->id.qp) {
-               ret = cma_modify_qp_rtr(&id_priv->id);
+               ret = cma_modify_qp_rtr(id_priv);
                if (ret)
                        goto out;
 
@@ -2370,7 +2378,7 @@ static int cma_accept_iw(struct rdma_id_private *id_priv,
        struct iw_cm_conn_param iw_param;
        int ret;
 
-       ret = cma_modify_qp_rtr(&id_priv->id);
+       ret = cma_modify_qp_rtr(id_priv);
        if (ret)
                return ret;
 
@@ -2442,7 +2450,7 @@ int rdma_accept(struct rdma_cm_id *id, struct rdma_conn_param *conn_param)
 
        return 0;
 reject:
-       cma_modify_qp_err(id);
+       cma_modify_qp_err(id_priv);
        rdma_reject(id, NULL, 0);
        return ret;
 }
@@ -2512,7 +2520,7 @@ int rdma_disconnect(struct rdma_cm_id *id)
 
        switch (rdma_node_get_transport(id->device->node_type)) {
        case RDMA_TRANSPORT_IB:
-               ret = cma_modify_qp_err(id);
+               ret = cma_modify_qp_err(id_priv);
                if (ret)
                        goto out;
                /* Initiate or respond to a disconnect. */
@@ -2543,9 +2551,11 @@ static int cma_ib_mc_handler(int status, struct ib_sa_multicast *multicast)
            cma_disable_remove(id_priv, CMA_ADDR_RESOLVED))
                return 0;
 
+       mutex_lock(&id_priv->qp_mutex);
        if (!status && id_priv->id.qp)
                status = ib_attach_mcast(id_priv->id.qp, &multicast->rec.mgid,
                                         multicast->rec.mlid);
+       mutex_unlock(&id_priv->qp_mutex);
 
        memset(&event, 0, sizeof event);
        event.status = status;
@@ -2757,16 +2767,12 @@ static void cma_process_remove(struct cma_device *cma_dev)
                id_priv = list_entry(cma_dev->id_list.next,
                                     struct rdma_id_private, list);
 
-               if (cma_internal_listen(id_priv)) {
-                       cma_destroy_listen(id_priv);
-                       continue;
-               }
-
+               list_del(&id_priv->listen_list);
                list_del_init(&id_priv->list);
                atomic_inc(&id_priv->refcount);
                mutex_unlock(&lock);
 
-               ret = cma_remove_id_dev(id_priv);
+               ret = id_priv->internal_id ? 1 : cma_remove_id_dev(id_priv);
                cma_deref_id(id_priv);
                if (ret)
                        rdma_destroy_id(&id_priv->id);
@@ -2797,11 +2803,12 @@ static void cma_remove_one(struct ib_device *device)
 
 static int cma_init(void)
 {
-       int ret, low, high;
+       int ret, low, high, remaining;
 
        get_random_bytes(&next_port, sizeof next_port);
        inet_get_local_port_range(&low, &high);
-       next_port = ((unsigned int) next_port % (high - low)) + low;
+       remaining = (high - low) + 1;
+       next_port = ((unsigned int) next_port % remaining) + low;
 
        cma_wq = create_singlethread_workqueue("rdma_cm");
        if (!cma_wq)
index 2f54e29dc7a64b3771e6fec854d7f4699b355e17..14159ff29408c717fcf77c3940458f59dadc11c8 100644 (file)
@@ -55,9 +55,11 @@ static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int d
                ib_dma_unmap_sg(dev, chunk->page_list,
                                chunk->nents, DMA_BIDIRECTIONAL);
                for (i = 0; i < chunk->nents; ++i) {
+                       struct page *page = sg_page(&chunk->page_list[i]);
+
                        if (umem->writable && dirty)
-                               set_page_dirty_lock(chunk->page_list[i].page);
-                       put_page(chunk->page_list[i].page);
+                               set_page_dirty_lock(page);
+                       put_page(page);
                }
 
                kfree(chunk);
@@ -164,11 +166,12 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
                        }
 
                        chunk->nents = min_t(int, ret, IB_UMEM_MAX_PAGE_CHUNK);
+                       sg_init_table(chunk->page_list, chunk->nents);
                        for (i = 0; i < chunk->nents; ++i) {
                                if (vma_list &&
                                    !is_vm_hugetlb_page(vma_list[i + off]))
                                        umem->hugetlb = 0;
-                               chunk->page_list[i].page   = page_list[i + off];
+                               sg_set_page(&chunk->page_list[i], page_list[i + off]);
                                chunk->page_list[i].offset = 0;
                                chunk->page_list[i].length = PAGE_SIZE;
                        }
@@ -179,7 +182,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
                                                    DMA_BIDIRECTIONAL);
                        if (chunk->nmap <= 0) {
                                for (i = 0; i < chunk->nents; ++i)
-                                       put_page(chunk->page_list[i].page);
+                                       put_page(sg_page(&chunk->page_list[i]));
                                kfree(chunk);
 
                                ret = -ENOMEM;
index 01d70084aebe8c0737dc685c0bf3c4db3a57b4ec..495c803fb11dfb9a8c117eda7a71490c4a5b3726 100644 (file)
@@ -147,8 +147,12 @@ static struct ib_uobject *__idr_get_uobj(struct idr *idr, int id,
 
        spin_lock(&ib_uverbs_idr_lock);
        uobj = idr_find(idr, id);
-       if (uobj)
-               kref_get(&uobj->ref);
+       if (uobj) {
+               if (uobj->context == context)
+                       kref_get(&uobj->ref);
+               else
+                       uobj = NULL;
+       }
        spin_unlock(&ib_uverbs_idr_lock);
 
        return uobj;
index 3f2d68cff764a945311bcc8cdb89e3cf3658a7d4..2d660ae189e544b54b3895cc4f0fc2f7d58312ea 100644 (file)
@@ -323,7 +323,6 @@ extern int ehca_static_rate;
 extern int ehca_port_act_time;
 extern int ehca_use_hp_mr;
 extern int ehca_scaling_code;
-extern int ehca_mr_largepage;
 
 struct ipzu_queue_resp {
        u32 qe_size;      /* queue entry size */
index 4aa3ffa6a19fe425345e1bcd800dad2d6cc3d459..15806d1404612d1b34c849080ef4fb2d26627b94 100644 (file)
@@ -77,6 +77,7 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props)
        }
 
        memset(props, 0, sizeof(struct ib_device_attr));
+       props->page_size_cap   = shca->hca_cap_mr_pgsize;
        props->fw_ver          = rblock->hw_ver;
        props->max_mr_size     = rblock->max_mr_size;
        props->vendor_id       = rblock->vendor_id >> 8;
index a3409fdb307c88d3de45e37c633bd66a3910c797..c6cd38c5321fb2a11c553bd7754a9dad88b58a44 100644 (file)
@@ -65,7 +65,7 @@ int ehca_port_act_time = 30;
 int ehca_poll_all_eqs  = 1;
 int ehca_static_rate   = -1;
 int ehca_scaling_code  = 0;
-int ehca_mr_largepage  = 0;
+int ehca_mr_largepage  = 1;
 
 module_param_named(open_aqp1,     ehca_open_aqp1,     int, S_IRUGO);
 module_param_named(debug_level,   ehca_debug_level,   int, S_IRUGO);
@@ -260,13 +260,20 @@ static struct cap_descr {
        { HCA_CAP_MINI_QP, "HCA_CAP_MINI_QP" },
 };
 
-int ehca_sense_attributes(struct ehca_shca *shca)
+static int ehca_sense_attributes(struct ehca_shca *shca)
 {
        int i, ret = 0;
        u64 h_ret;
        struct hipz_query_hca *rblock;
        struct hipz_query_port *port;
 
+       static const u32 pgsize_map[] = {
+               HCA_CAP_MR_PGSIZE_4K,  0x1000,
+               HCA_CAP_MR_PGSIZE_64K, 0x10000,
+               HCA_CAP_MR_PGSIZE_1M,  0x100000,
+               HCA_CAP_MR_PGSIZE_16M, 0x1000000,
+       };
+
        rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
        if (!rblock) {
                ehca_gen_err("Cannot allocate rblock memory.");
@@ -329,8 +336,15 @@ int ehca_sense_attributes(struct ehca_shca *shca)
                if (EHCA_BMASK_GET(hca_cap_descr[i].mask, shca->hca_cap))
                        ehca_gen_dbg("   %s", hca_cap_descr[i].descr);
 
-       shca->hca_cap_mr_pgsize = rblock->memory_page_size_supported;
+       /* translate supported MR page sizes; always support 4K */
+       shca->hca_cap_mr_pgsize = EHCA_PAGESIZE;
+       if (ehca_mr_largepage) { /* support extra sizes only if enabled */
+               for (i = 0; i < ARRAY_SIZE(pgsize_map); i += 2)
+                       if (rblock->memory_page_size_supported & pgsize_map[i])
+                               shca->hca_cap_mr_pgsize |= pgsize_map[i + 1];
+       }
 
+       /* query max MTU from first port -- it's the same for all ports */
        port = (struct hipz_query_port *)rblock;
        h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port);
        if (h_ret != H_SUCCESS) {
@@ -579,12 +593,12 @@ static ssize_t  ehca_show_##name(struct device *dev,                       \
                                                                           \
        rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);                      \
        if (!rblock) {                                                     \
-               dev_err(dev, "Can't allocate rblock memory.");             \
+               dev_err(dev, "Can't allocate rblock memory.\n");           \
                return 0;                                                  \
        }                                                                  \
                                                                           \
        if (hipz_h_query_hca(shca->ipz_hca_handle, rblock) != H_SUCCESS) { \
-               dev_err(dev, "Can't query device properties");             \
+               dev_err(dev, "Can't query device properties\n");           \
                ehca_free_fw_ctrlblock(rblock);                            \
                return 0;                                                  \
        }                                                                  \
index da88738265edd23893b136540148a29db3902f09..e239bbf54da14ff3d79b49912bb745018a1407f2 100644 (file)
@@ -72,24 +72,14 @@ enum ehca_mr_pgsize {
 
 static u32 ehca_encode_hwpage_size(u32 pgsize)
 {
-       u32 idx = 0;
-       pgsize >>= 12;
-       /*
-        * map mr page size into hw code:
-        * 0, 1, 2, 3 for 4K, 64K, 1M, 64M
-        */
-       while (!(pgsize & 1)) {
-               idx++;
-               pgsize >>= 4;
-       }
-       return idx;
+       int log = ilog2(pgsize);
+       WARN_ON(log < 12 || log > 24 || log & 3);
+       return (log - 12) / 4;
 }
 
 static u64 ehca_get_max_hwpage_size(struct ehca_shca *shca)
 {
-       if (shca->hca_cap_mr_pgsize & HCA_CAP_MR_PGSIZE_16M)
-               return EHCA_MR_PGSIZE16M;
-       return EHCA_MR_PGSIZE4K;
+       return 1UL << ilog2(shca->hca_cap_mr_pgsize);
 }
 
 static struct ehca_mr *ehca_mr_new(void)
@@ -259,7 +249,7 @@ struct ib_mr *ehca_reg_phys_mr(struct ib_pd *pd,
                pginfo.u.phy.num_phys_buf = num_phys_buf;
                pginfo.u.phy.phys_buf_array = phys_buf_array;
                pginfo.next_hwpage =
-                       ((u64)iova_start & ~(hw_pgsize - 1)) / hw_pgsize;
+                       ((u64)iova_start & ~PAGE_MASK) / hw_pgsize;
 
                ret = ehca_reg_mr(shca, e_mr, iova_start, size, mr_access_flags,
                                  e_pd, &pginfo, &e_mr->ib.ib_mr.lkey,
@@ -296,7 +286,7 @@ struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
                container_of(pd->device, struct ehca_shca, ib_device);
        struct ehca_pd *e_pd = container_of(pd, struct ehca_pd, ib_pd);
        struct ehca_mr_pginfo pginfo;
-       int ret;
+       int ret, page_shift;
        u32 num_kpages;
        u32 num_hwpages;
        u64 hwpage_size;
@@ -351,19 +341,20 @@ struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
        /* determine number of MR pages */
        num_kpages = NUM_CHUNKS((virt % PAGE_SIZE) + length, PAGE_SIZE);
        /* select proper hw_pgsize */
-       if (ehca_mr_largepage &&
-           (shca->hca_cap_mr_pgsize & HCA_CAP_MR_PGSIZE_16M)) {
-               int page_shift = PAGE_SHIFT;
-               if (e_mr->umem->hugetlb) {
-                       /* determine page_shift, clamp between 4K and 16M */
-                       page_shift = (fls64(length - 1) + 3) & ~3;
-                       page_shift = min(max(page_shift, EHCA_MR_PGSHIFT4K),
-                                        EHCA_MR_PGSHIFT16M);
-               }
-               hwpage_size = 1UL << page_shift;
-       } else
-               hwpage_size = EHCA_MR_PGSIZE4K; /* ehca1 only supports 4k */
-       ehca_dbg(pd->device, "hwpage_size=%lx", hwpage_size);
+       page_shift = PAGE_SHIFT;
+       if (e_mr->umem->hugetlb) {
+               /* determine page_shift, clamp between 4K and 16M */
+               page_shift = (fls64(length - 1) + 3) & ~3;
+               page_shift = min(max(page_shift, EHCA_MR_PGSHIFT4K),
+                                EHCA_MR_PGSHIFT16M);
+       }
+       hwpage_size = 1UL << page_shift;
+
+       /* now that we have the desired page size, shift until it's
+        * supported, too. 4K is always supported, so this terminates.
+        */
+       while (!(hwpage_size & shca->hca_cap_mr_pgsize))
+               hwpage_size >>= 4;
 
 reg_user_mr_fallback:
        num_hwpages = NUM_CHUNKS((virt % hwpage_size) + length, hwpage_size);
@@ -547,7 +538,7 @@ int ehca_rereg_phys_mr(struct ib_mr *mr,
                pginfo.u.phy.num_phys_buf = num_phys_buf;
                pginfo.u.phy.phys_buf_array = phys_buf_array;
                pginfo.next_hwpage =
-                       ((u64)iova_start & ~(hw_pgsize - 1)) / hw_pgsize;
+                       ((u64)iova_start & ~PAGE_MASK) / hw_pgsize;
        }
        if (mr_rereg_mask & IB_MR_REREG_ACCESS)
                new_acl = mr_access_flags;
@@ -809,8 +800,9 @@ struct ib_fmr *ehca_alloc_fmr(struct ib_pd *pd,
                ib_fmr = ERR_PTR(-EINVAL);
                goto alloc_fmr_exit0;
        }
-       hw_pgsize = ehca_get_max_hwpage_size(shca);
-       if ((1 << fmr_attr->page_shift) != hw_pgsize) {
+
+       hw_pgsize = 1 << fmr_attr->page_shift;
+       if (!(hw_pgsize & shca->hca_cap_mr_pgsize)) {
                ehca_err(pd->device, "unsupported fmr_attr->page_shift=%x",
                         fmr_attr->page_shift);
                ib_fmr = ERR_PTR(-EINVAL);
@@ -826,6 +818,7 @@ struct ib_fmr *ehca_alloc_fmr(struct ib_pd *pd,
 
        /* register MR on HCA */
        memset(&pginfo, 0, sizeof(pginfo));
+       pginfo.hwpage_size = hw_pgsize;
        /*
         * pginfo.num_hwpages==0, ie register_rpages() will not be called
         * but deferred to map_phys_fmr()
@@ -1776,7 +1769,7 @@ static int ehca_set_pagebuf_user1(struct ehca_mr_pginfo *pginfo,
        list_for_each_entry_continue(
                chunk, (&(pginfo->u.usr.region->chunk_list)), list) {
                for (i = pginfo->u.usr.next_nmap; i < chunk->nmap; ) {
-                       pgaddr = page_to_pfn(chunk->page_list[i].page)
+                       pgaddr = page_to_pfn(sg_page(&chunk->page_list[i]))
                                << PAGE_SHIFT ;
                        *kpage = phys_to_abs(pgaddr +
                                             (pginfo->next_hwpage *
@@ -1832,7 +1825,7 @@ static int ehca_check_kpages_per_ate(struct scatterlist *page_list,
 {
        int t;
        for (t = start_idx; t <= end_idx; t++) {
-               u64 pgaddr = page_to_pfn(page_list[t].page) << PAGE_SHIFT;
+               u64 pgaddr = page_to_pfn(sg_page(&page_list[t])) << PAGE_SHIFT;
                ehca_gen_dbg("chunk_page=%lx value=%016lx", pgaddr,
                             *(u64 *)abs_to_virt(phys_to_abs(pgaddr)));
                if (pgaddr - PAGE_SIZE != *prev_pgaddr) {
@@ -1867,7 +1860,7 @@ static int ehca_set_pagebuf_user2(struct ehca_mr_pginfo *pginfo,
                chunk, (&(pginfo->u.usr.region->chunk_list)), list) {
                for (i = pginfo->u.usr.next_nmap; i < chunk->nmap; ) {
                        if (nr_kpages == kpages_per_hwpage) {
-                               pgaddr = ( page_to_pfn(chunk->page_list[i].page)
+                               pgaddr = ( page_to_pfn(sg_page(&chunk->page_list[i]))
                                           << PAGE_SHIFT );
                                *kpage = phys_to_abs(pgaddr);
                                if ( !(*kpage) ) {
index e2bd62be11e71ba735af508731181cf14b2c9d1b..de182648b2823404ebfc6188f1a68508e9972c00 100644 (file)
@@ -451,7 +451,6 @@ static struct ehca_qp *internal_create_qp(
                has_srq = 1;
                parms.ext_type = EQPT_SRQBASE;
                parms.srq_qpn = my_srq->real_qp_num;
-               parms.srq_token = my_srq->token;
        }
 
        if (is_llqp && has_srq) {
@@ -583,6 +582,9 @@ static struct ehca_qp *internal_create_qp(
                goto create_qp_exit1;
        }
 
+       if (has_srq)
+               parms.srq_token = my_qp->token;
+
        parms.servicetype = ibqptype2servicetype(qp_type);
        if (parms.servicetype < 0) {
                ret = -EINVAL;
index 22709a4f8fc89304672b12de18f29d8f2a981871..e90a0ea538a05b75b3fe0ca06edcda968bb4d364 100644 (file)
@@ -108,7 +108,7 @@ static int ipath_map_sg(struct ib_device *dev, struct scatterlist *sgl,
        BUG_ON(!valid_dma_direction(direction));
 
        for_each_sg(sgl, sg, nents, i) {
-               addr = (u64) page_address(sg->page);
+               addr = (u64) page_address(sg_page(sg));
                /* TODO: handle highmem pages */
                if (!addr) {
                        ret = 0;
@@ -127,7 +127,7 @@ static void ipath_unmap_sg(struct ib_device *dev,
 
 static u64 ipath_sg_dma_address(struct ib_device *dev, struct scatterlist *sg)
 {
-       u64 addr = (u64) page_address(sg->page);
+       u64 addr = (u64) page_address(sg_page(sg));
 
        if (addr)
                addr += sg->offset;
index e442470a23755ff87947434abc21ff39a2d54158..db4ba92f79fcd60736a8bd3d1e1752caa0ab3f5d 100644 (file)
@@ -225,7 +225,7 @@ struct ib_mr *ipath_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
                for (i = 0; i < chunk->nents; i++) {
                        void *vaddr;
 
-                       vaddr = page_address(chunk->page_list[i].page);
+                       vaddr = page_address(sg_page(&chunk->page_list[i]));
                        if (!vaddr) {
                                ret = ERR_PTR(-EINVAL);
                                goto bail;
index 31a480e5b0d03064e0597765e16ae62791402d33..6b3322486b5e2e66a0e2de0db16914f185f6f298 100644 (file)
@@ -63,6 +63,10 @@ struct mlx4_ib_sqp {
        u8                      header_buf[MLX4_IB_UD_HEADER_SIZE];
 };
 
+enum {
+       MLX4_IB_MIN_SQ_STRIDE = 6
+};
+
 static const __be32 mlx4_ib_opcode[] = {
        [IB_WR_SEND]                    = __constant_cpu_to_be32(MLX4_OPCODE_SEND),
        [IB_WR_SEND_WITH_IMM]           = __constant_cpu_to_be32(MLX4_OPCODE_SEND_IMM),
@@ -285,9 +289,17 @@ static int set_kernel_sq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
        return 0;
 }
 
-static int set_user_sq_size(struct mlx4_ib_qp *qp,
+static int set_user_sq_size(struct mlx4_ib_dev *dev,
+                           struct mlx4_ib_qp *qp,
                            struct mlx4_ib_create_qp *ucmd)
 {
+       /* Sanity check SQ size before proceeding */
+       if ((1 << ucmd->log_sq_bb_count) > dev->dev->caps.max_wqes       ||
+           ucmd->log_sq_stride >
+               ilog2(roundup_pow_of_two(dev->dev->caps.max_sq_desc_sz)) ||
+           ucmd->log_sq_stride < MLX4_IB_MIN_SQ_STRIDE)
+               return -EINVAL;
+
        qp->sq.wqe_cnt   = 1 << ucmd->log_sq_bb_count;
        qp->sq.wqe_shift = ucmd->log_sq_stride;
 
@@ -330,7 +342,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
 
                qp->sq_no_prefetch = ucmd.sq_no_prefetch;
 
-               err = set_user_sq_size(qp, &ucmd);
+               err = set_user_sq_size(dev, qp, &ucmd);
                if (err)
                        goto err;
 
index be6e1e03bdab131d421974353b1d251bded7d12b..6bd9f1393349c1d8e92e1c23bda605e14fa46846 100644 (file)
@@ -204,16 +204,11 @@ static void dump_cqe(struct mthca_dev *dev, void *cqe_ptr)
 static inline void update_cons_index(struct mthca_dev *dev, struct mthca_cq *cq,
                                     int incr)
 {
-       __be32 doorbell[2];
-
        if (mthca_is_memfree(dev)) {
                *cq->set_ci_db = cpu_to_be32(cq->cons_index);
                wmb();
        } else {
-               doorbell[0] = cpu_to_be32(MTHCA_TAVOR_CQ_DB_INC_CI | cq->cqn);
-               doorbell[1] = cpu_to_be32(incr - 1);
-
-               mthca_write64(doorbell,
+               mthca_write64(MTHCA_TAVOR_CQ_DB_INC_CI | cq->cqn, incr - 1,
                              dev->kar + MTHCA_CQ_DOORBELL,
                              MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
                /*
@@ -731,17 +726,12 @@ repoll:
 
 int mthca_tavor_arm_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags)
 {
-       __be32 doorbell[2];
+       u32 dbhi = ((flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED ?
+                   MTHCA_TAVOR_CQ_DB_REQ_NOT_SOL :
+                   MTHCA_TAVOR_CQ_DB_REQ_NOT) |
+               to_mcq(cq)->cqn;
 
-       doorbell[0] = cpu_to_be32(((flags & IB_CQ_SOLICITED_MASK) ==
-                                  IB_CQ_SOLICITED ?
-                                  MTHCA_TAVOR_CQ_DB_REQ_NOT_SOL :
-                                  MTHCA_TAVOR_CQ_DB_REQ_NOT)      |
-                                 to_mcq(cq)->cqn);
-       doorbell[1] = (__force __be32) 0xffffffff;
-
-       mthca_write64(doorbell,
-                     to_mdev(cq->device)->kar + MTHCA_CQ_DOORBELL,
+       mthca_write64(dbhi, 0xffffffff, to_mdev(cq->device)->kar + MTHCA_CQ_DOORBELL,
                      MTHCA_GET_DOORBELL_LOCK(&to_mdev(cq->device)->doorbell_lock));
 
        return 0;
@@ -750,19 +740,16 @@ int mthca_tavor_arm_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags)
 int mthca_arbel_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags)
 {
        struct mthca_cq *cq = to_mcq(ibcq);
-       __be32 doorbell[2];
-       u32 sn;
-       __be32 ci;
-
-       sn = cq->arm_sn & 3;
-       ci = cpu_to_be32(cq->cons_index);
+       __be32 db_rec[2];
+       u32 dbhi;
+       u32 sn = cq->arm_sn & 3;
 
-       doorbell[0] = ci;
-       doorbell[1] = cpu_to_be32((cq->cqn << 8) | (2 << 5) | (sn << 3) |
-                                 ((flags & IB_CQ_SOLICITED_MASK) ==
-                                  IB_CQ_SOLICITED ? 1 : 2));
+       db_rec[0] = cpu_to_be32(cq->cons_index);
+       db_rec[1] = cpu_to_be32((cq->cqn << 8) | (2 << 5) | (sn << 3) |
+                               ((flags & IB_CQ_SOLICITED_MASK) ==
+                                IB_CQ_SOLICITED ? 1 : 2));
 
-       mthca_write_db_rec(doorbell, cq->arm_db);
+       mthca_write_db_rec(db_rec, cq->arm_db);
 
        /*
         * Make sure that the doorbell record in host memory is
@@ -770,14 +757,12 @@ int mthca_arbel_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags)
         */
        wmb();
 
-       doorbell[0] = cpu_to_be32((sn << 28)                       |
-                                 ((flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED ?
-                                  MTHCA_ARBEL_CQ_DB_REQ_NOT_SOL :
-                                  MTHCA_ARBEL_CQ_DB_REQ_NOT)      |
-                                 cq->cqn);
-       doorbell[1] = ci;
+       dbhi = (sn << 28) |
+               ((flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED ?
+                MTHCA_ARBEL_CQ_DB_REQ_NOT_SOL :
+                MTHCA_ARBEL_CQ_DB_REQ_NOT) | cq->cqn;
 
-       mthca_write64(doorbell,
+       mthca_write64(dbhi, cq->cons_index,
                      to_mdev(ibcq->device)->kar + MTHCA_CQ_DOORBELL,
                      MTHCA_GET_DOORBELL_LOCK(&to_mdev(ibcq->device)->doorbell_lock));
 
index dd9a44d170c9e951e60517b6a3c0c77b03163b04..b374dc395be1af1f95c668bbbea524aeeea311db 100644 (file)
@@ -58,10 +58,10 @@ static inline void mthca_write64_raw(__be64 val, void __iomem *dest)
        __raw_writeq((__force u64) val, dest);
 }
 
-static inline void mthca_write64(__be32 val[2], void __iomem *dest,
+static inline void mthca_write64(u32 hi, u32 lo, void __iomem *dest,
                                 spinlock_t *doorbell_lock)
 {
-       __raw_writeq(*(u64 *) val, dest);
+       __raw_writeq((__force u64) cpu_to_be64((u64) hi << 32 | lo), dest);
 }
 
 static inline void mthca_write_db_rec(__be32 val[2], __be32 *db)
@@ -87,14 +87,17 @@ static inline void mthca_write64_raw(__be64 val, void __iomem *dest)
        __raw_writel(((__force u32 *) &val)[1], dest + 4);
 }
 
-static inline void mthca_write64(__be32 val[2], void __iomem *dest,
+static inline void mthca_write64(u32 hi, u32 lo, void __iomem *dest,
                                 spinlock_t *doorbell_lock)
 {
        unsigned long flags;
 
+       hi = (__force u32) cpu_to_be32(hi);
+       lo = (__force u32) cpu_to_be32(lo);
+
        spin_lock_irqsave(doorbell_lock, flags);
-       __raw_writel((__force u32) val[0], dest);
-       __raw_writel((__force u32) val[1], dest + 4);
+       __raw_writel(hi, dest);
+       __raw_writel(lo, dest + 4);
        spin_unlock_irqrestore(doorbell_lock, flags);
 }
 
index 8592b26dc4e1b051d5fe7704e285371145c7587e..b29de51b7f350affcafbfd49aabb8f06805f6784 100644 (file)
@@ -173,11 +173,6 @@ static inline u64 async_mask(struct mthca_dev *dev)
 
 static inline void tavor_set_eq_ci(struct mthca_dev *dev, struct mthca_eq *eq, u32 ci)
 {
-       __be32 doorbell[2];
-
-       doorbell[0] = cpu_to_be32(MTHCA_EQ_DB_SET_CI | eq->eqn);
-       doorbell[1] = cpu_to_be32(ci & (eq->nent - 1));
-
        /*
         * This barrier makes sure that all updates to ownership bits
         * done by set_eqe_hw() hit memory before the consumer index
@@ -187,7 +182,7 @@ static inline void tavor_set_eq_ci(struct mthca_dev *dev, struct mthca_eq *eq, u
         * having set_eqe_hw() overwrite the owner field.
         */
        wmb();
-       mthca_write64(doorbell,
+       mthca_write64(MTHCA_EQ_DB_SET_CI | eq->eqn, ci & (eq->nent - 1),
                      dev->kar + MTHCA_EQ_DOORBELL,
                      MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
 }
@@ -212,12 +207,7 @@ static inline void set_eq_ci(struct mthca_dev *dev, struct mthca_eq *eq, u32 ci)
 
 static inline void tavor_eq_req_not(struct mthca_dev *dev, int eqn)
 {
-       __be32 doorbell[2];
-
-       doorbell[0] = cpu_to_be32(MTHCA_EQ_DB_REQ_NOT | eqn);
-       doorbell[1] = 0;
-
-       mthca_write64(doorbell,
+       mthca_write64(MTHCA_EQ_DB_REQ_NOT | eqn, 0,
                      dev->kar + MTHCA_EQ_DOORBELL,
                      MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
 }
@@ -230,12 +220,7 @@ static inline void arbel_eq_req_not(struct mthca_dev *dev, u32 eqn_mask)
 static inline void disarm_cq(struct mthca_dev *dev, int eqn, int cqn)
 {
        if (!mthca_is_memfree(dev)) {
-               __be32 doorbell[2];
-
-               doorbell[0] = cpu_to_be32(MTHCA_EQ_DB_DISARM_CQ | eqn);
-               doorbell[1] = cpu_to_be32(cqn);
-
-               mthca_write64(doorbell,
+               mthca_write64(MTHCA_EQ_DB_DISARM_CQ | eqn, cqn,
                              dev->kar + MTHCA_EQ_DOORBELL,
                              MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
        }
index e61f3e626980e582959b3cfa0f1bd31a141a3db1..007b38157fc49b81d8363ba9908597d75f8522ff 100644 (file)
@@ -71,7 +71,7 @@ static void mthca_free_icm_pages(struct mthca_dev *dev, struct mthca_icm_chunk *
                             PCI_DMA_BIDIRECTIONAL);
 
        for (i = 0; i < chunk->npages; ++i)
-               __free_pages(chunk->mem[i].page,
+               __free_pages(sg_page(&chunk->mem[i]),
                             get_order(chunk->mem[i].length));
 }
 
@@ -81,7 +81,7 @@ static void mthca_free_icm_coherent(struct mthca_dev *dev, struct mthca_icm_chun
 
        for (i = 0; i < chunk->npages; ++i) {
                dma_free_coherent(&dev->pdev->dev, chunk->mem[i].length,
-                                 lowmem_page_address(chunk->mem[i].page),
+                                 lowmem_page_address(sg_page(&chunk->mem[i])),
                                  sg_dma_address(&chunk->mem[i]));
        }
 }
@@ -107,10 +107,13 @@ void mthca_free_icm(struct mthca_dev *dev, struct mthca_icm *icm, int coherent)
 
 static int mthca_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_mask)
 {
-       mem->page = alloc_pages(gfp_mask, order);
-       if (!mem->page)
+       struct page *page;
+
+       page = alloc_pages(gfp_mask, order);
+       if (!page)
                return -ENOMEM;
 
+       sg_set_page(mem, page);
        mem->length = PAGE_SIZE << order;
        mem->offset = 0;
        return 0;
@@ -157,6 +160,7 @@ struct mthca_icm *mthca_alloc_icm(struct mthca_dev *dev, int npages,
                        if (!chunk)
                                goto fail;
 
+                       sg_init_table(chunk->mem, MTHCA_ICM_CHUNK_LEN);
                        chunk->npages = 0;
                        chunk->nsg    = 0;
                        list_add_tail(&chunk->list, &icm->chunk_list);
@@ -304,7 +308,7 @@ void *mthca_table_find(struct mthca_icm_table *table, int obj, dma_addr_t *dma_h
                         * so if we found the page, dma_handle has already
                         * been assigned to. */
                        if (chunk->mem[i].length > offset) {
-                               page = chunk->mem[i].page;
+                               page = sg_page(&chunk->mem[i]);
                                goto out;
                        }
                        offset -= chunk->mem[i].length;
@@ -445,6 +449,7 @@ static u64 mthca_uarc_virt(struct mthca_dev *dev, struct mthca_uar *uar, int pag
 int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
                      struct mthca_user_db_table *db_tab, int index, u64 uaddr)
 {
+       struct page *pages[1];
        int ret = 0;
        u8 status;
        int i;
@@ -472,16 +477,17 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
        }
 
        ret = get_user_pages(current, current->mm, uaddr & PAGE_MASK, 1, 1, 0,
-                            &db_tab->page[i].mem.page, NULL);
+                            pages, NULL);
        if (ret < 0)
                goto out;
 
+       sg_set_page(&db_tab->page[i].mem, pages[0]);
        db_tab->page[i].mem.length = MTHCA_ICM_PAGE_SIZE;
        db_tab->page[i].mem.offset = uaddr & ~PAGE_MASK;
 
        ret = pci_map_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
        if (ret < 0) {
-               put_page(db_tab->page[i].mem.page);
+               put_page(pages[0]);
                goto out;
        }
 
@@ -491,7 +497,7 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
                ret = -EINVAL;
        if (ret) {
                pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
-               put_page(db_tab->page[i].mem.page);
+               put_page(sg_page(&db_tab->page[i].mem));
                goto out;
        }
 
@@ -557,7 +563,7 @@ void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar,
                if (db_tab->page[i].uvirt) {
                        mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, uar, i), 1, &status);
                        pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
-                       put_page(db_tab->page[i].mem.page);
+                       put_page(sg_page(&db_tab->page[i].mem));
                }
        }
 
index df01b2026a644657b288e5304d17dbd22517c8bf..0e5461c65731db15ec38a16bc670ca331f69b4b7 100644 (file)
@@ -1799,15 +1799,11 @@ int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 
 out:
        if (likely(nreq)) {
-               __be32 doorbell[2];
-
-               doorbell[0] = cpu_to_be32(((qp->sq.next_ind << qp->sq.wqe_shift) +
-                                          qp->send_wqe_offset) | f0 | op0);
-               doorbell[1] = cpu_to_be32((qp->qpn << 8) | size0);
-
                wmb();
 
-               mthca_write64(doorbell,
+               mthca_write64(((qp->sq.next_ind << qp->sq.wqe_shift) +
+                              qp->send_wqe_offset) | f0 | op0,
+                             (qp->qpn << 8) | size0,
                              dev->kar + MTHCA_SEND_DOORBELL,
                              MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
                /*
@@ -1829,7 +1825,6 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
 {
        struct mthca_dev *dev = to_mdev(ibqp->device);
        struct mthca_qp *qp = to_mqp(ibqp);
-       __be32 doorbell[2];
        unsigned long flags;
        int err = 0;
        int nreq;
@@ -1907,13 +1902,10 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
                if (unlikely(nreq == MTHCA_TAVOR_MAX_WQES_PER_RECV_DB)) {
                        nreq = 0;
 
-                       doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0);
-                       doorbell[1] = cpu_to_be32(qp->qpn << 8);
-
                        wmb();
 
-                       mthca_write64(doorbell,
-                                     dev->kar + MTHCA_RECEIVE_DOORBELL,
+                       mthca_write64((qp->rq.next_ind << qp->rq.wqe_shift) | size0,
+                                     qp->qpn << 8, dev->kar + MTHCA_RECEIVE_DOORBELL,
                                      MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
 
                        qp->rq.next_ind = ind;
@@ -1923,13 +1915,10 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
 
 out:
        if (likely(nreq)) {
-               doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0);
-               doorbell[1] = cpu_to_be32((qp->qpn << 8) | nreq);
-
                wmb();
 
-               mthca_write64(doorbell,
-                             dev->kar + MTHCA_RECEIVE_DOORBELL,
+               mthca_write64((qp->rq.next_ind << qp->rq.wqe_shift) | size0,
+                             qp->qpn << 8 | nreq, dev->kar + MTHCA_RECEIVE_DOORBELL,
                              MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
        }
 
@@ -1951,7 +1940,7 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 {
        struct mthca_dev *dev = to_mdev(ibqp->device);
        struct mthca_qp *qp = to_mqp(ibqp);
-       __be32 doorbell[2];
+       u32 dbhi;
        void *wqe;
        void *prev_wqe;
        unsigned long flags;
@@ -1981,10 +1970,8 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
                if (unlikely(nreq == MTHCA_ARBEL_MAX_WQES_PER_SEND_DB)) {
                        nreq = 0;
 
-                       doorbell[0] = cpu_to_be32((MTHCA_ARBEL_MAX_WQES_PER_SEND_DB << 24) |
-                                                 ((qp->sq.head & 0xffff) << 8) |
-                                                 f0 | op0);
-                       doorbell[1] = cpu_to_be32((qp->qpn << 8) | size0);
+                       dbhi = (MTHCA_ARBEL_MAX_WQES_PER_SEND_DB << 24) |
+                               ((qp->sq.head & 0xffff) << 8) | f0 | op0;
 
                        qp->sq.head += MTHCA_ARBEL_MAX_WQES_PER_SEND_DB;
 
@@ -2000,7 +1987,8 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
                         * write MMIO send doorbell.
                         */
                        wmb();
-                       mthca_write64(doorbell,
+
+                       mthca_write64(dbhi, (qp->qpn << 8) | size0,
                                      dev->kar + MTHCA_SEND_DOORBELL,
                                      MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
                }
@@ -2154,10 +2142,7 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 
 out:
        if (likely(nreq)) {
-               doorbell[0] = cpu_to_be32((nreq << 24)                  |
-                                         ((qp->sq.head & 0xffff) << 8) |
-                                         f0 | op0);
-               doorbell[1] = cpu_to_be32((qp->qpn << 8) | size0);
+               dbhi = (nreq << 24) | ((qp->sq.head & 0xffff) << 8) | f0 | op0;
 
                qp->sq.head += nreq;
 
@@ -2173,8 +2158,8 @@ out:
                 * write MMIO send doorbell.
                 */
                wmb();
-               mthca_write64(doorbell,
-                             dev->kar + MTHCA_SEND_DOORBELL,
+
+               mthca_write64(dbhi, (qp->qpn << 8) | size0, dev->kar + MTHCA_SEND_DOORBELL,
                              MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
        }
 
index 3f58c11a62b77f2618714e682ad8aea7bddf710a..553d681f6813a709a2d8e2a5601c8e1dc98bc902 100644 (file)
@@ -491,7 +491,6 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
 {
        struct mthca_dev *dev = to_mdev(ibsrq->device);
        struct mthca_srq *srq = to_msrq(ibsrq);
-       __be32 doorbell[2];
        unsigned long flags;
        int err = 0;
        int first_ind;
@@ -563,16 +562,13 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
                if (unlikely(nreq == MTHCA_TAVOR_MAX_WQES_PER_RECV_DB)) {
                        nreq = 0;
 
-                       doorbell[0] = cpu_to_be32(first_ind << srq->wqe_shift);
-                       doorbell[1] = cpu_to_be32(srq->srqn << 8);
-
                        /*
                         * Make sure that descriptors are written
                         * before doorbell is rung.
                         */
                        wmb();
 
-                       mthca_write64(doorbell,
+                       mthca_write64(first_ind << srq->wqe_shift, srq->srqn << 8,
                                      dev->kar + MTHCA_RECEIVE_DOORBELL,
                                      MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
 
@@ -581,16 +577,13 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
        }
 
        if (likely(nreq)) {
-               doorbell[0] = cpu_to_be32(first_ind << srq->wqe_shift);
-               doorbell[1] = cpu_to_be32((srq->srqn << 8) | nreq);
-
                /*
                 * Make sure that descriptors are written before
                 * doorbell is rung.
                 */
                wmb();
 
-               mthca_write64(doorbell,
+               mthca_write64(first_ind << srq->wqe_shift, (srq->srqn << 8) | nreq,
                              dev->kar + MTHCA_RECEIVE_DOORBELL,
                              MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
        }
index 1b3327ad6bc477332c622b069e55f9d8f7b7f542..eb7edab0e836041f444061889ddf3acf4ad7786c 100644 (file)
@@ -84,9 +84,8 @@ enum {
        IPOIB_MCAST_RUN           = 6,
        IPOIB_STOP_REAPER         = 7,
        IPOIB_MCAST_STARTED       = 8,
-       IPOIB_FLAG_NETIF_STOPPED  = 9,
-       IPOIB_FLAG_ADMIN_CM       = 10,
-       IPOIB_FLAG_UMCAST         = 11,
+       IPOIB_FLAG_ADMIN_CM       = 9,
+       IPOIB_FLAG_UMCAST         = 10,
 
        IPOIB_MAX_BACKOFF_SECONDS = 16,
 
@@ -98,9 +97,9 @@ enum {
 
 #define        IPOIB_OP_RECV   (1ul << 31)
 #ifdef CONFIG_INFINIBAND_IPOIB_CM
-#define        IPOIB_CM_OP_SRQ (1ul << 30)
+#define        IPOIB_OP_CM     (1ul << 30)
 #else
-#define        IPOIB_CM_OP_SRQ (0)
+#define        IPOIB_OP_CM     (0)
 #endif
 
 /* structs */
@@ -197,7 +196,6 @@ struct ipoib_cm_rx {
 
 struct ipoib_cm_tx {
        struct ib_cm_id     *id;
-       struct ib_cq        *cq;
        struct ib_qp        *qp;
        struct list_head     list;
        struct net_device   *dev;
@@ -294,6 +292,7 @@ struct ipoib_dev_priv {
        unsigned             tx_tail;
        struct ib_sge        tx_sge;
        struct ib_send_wr    tx_wr;
+       unsigned             tx_outstanding;
 
        struct ib_wc ibwc[IPOIB_NUM_WC];
 
@@ -504,6 +503,7 @@ void ipoib_cm_destroy_tx(struct ipoib_cm_tx *tx);
 void ipoib_cm_skb_too_long(struct net_device* dev, struct sk_buff *skb,
                           unsigned int mtu);
 void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc);
+void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ib_wc *wc);
 #else
 
 struct ipoib_cm_tx;
@@ -592,6 +592,9 @@ static inline void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *w
 {
 }
 
+static inline void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ib_wc *wc)
+{
+}
 #endif
 
 #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
index 0a0dcb8fdfd1ac2ca54ec326974341a6ff187baa..87610772a97944448ee2965e0ae5b9a5f787abb7 100644 (file)
@@ -87,7 +87,7 @@ static int ipoib_cm_post_receive(struct net_device *dev, int id)
        struct ib_recv_wr *bad_wr;
        int i, ret;
 
-       priv->cm.rx_wr.wr_id = id | IPOIB_CM_OP_SRQ;
+       priv->cm.rx_wr.wr_id = id | IPOIB_OP_CM | IPOIB_OP_RECV;
 
        for (i = 0; i < IPOIB_CM_RX_SG; ++i)
                priv->cm.rx_sge[i].addr = priv->cm.srq_ring[id].mapping[i];
@@ -401,7 +401,7 @@ static void skb_put_frags(struct sk_buff *skb, unsigned int hdr_space,
 void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
 {
        struct ipoib_dev_priv *priv = netdev_priv(dev);
-       unsigned int wr_id = wc->wr_id & ~IPOIB_CM_OP_SRQ;
+       unsigned int wr_id = wc->wr_id & ~(IPOIB_OP_CM | IPOIB_OP_RECV);
        struct sk_buff *skb, *newskb;
        struct ipoib_cm_rx *p;
        unsigned long flags;
@@ -412,7 +412,7 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
                       wr_id, wc->status);
 
        if (unlikely(wr_id >= ipoib_recvq_size)) {
-               if (wr_id == (IPOIB_CM_RX_DRAIN_WRID & ~IPOIB_CM_OP_SRQ)) {
+               if (wr_id == (IPOIB_CM_RX_DRAIN_WRID & ~(IPOIB_OP_CM | IPOIB_OP_RECV))) {
                        spin_lock_irqsave(&priv->lock, flags);
                        list_splice_init(&priv->cm.rx_drain_list, &priv->cm.rx_reap_list);
                        ipoib_cm_start_rx_drain(priv);
@@ -434,7 +434,7 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
                goto repost;
        }
 
-       if (!likely(wr_id & IPOIB_CM_RX_UPDATE_MASK)) {
+       if (unlikely(!(wr_id & IPOIB_CM_RX_UPDATE_MASK))) {
                p = wc->qp->qp_context;
                if (p && time_after_eq(jiffies, p->jiffies + IPOIB_CM_RX_UPDATE_TIME)) {
                        spin_lock_irqsave(&priv->lock, flags);
@@ -498,7 +498,7 @@ static inline int post_send(struct ipoib_dev_priv *priv,
        priv->tx_sge.addr             = addr;
        priv->tx_sge.length           = len;
 
-       priv->tx_wr.wr_id             = wr_id;
+       priv->tx_wr.wr_id             = wr_id | IPOIB_OP_CM;
 
        return ib_post_send(tx->qp, &priv->tx_wr, &bad_wr);
 }
@@ -549,20 +549,19 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_
                dev->trans_start = jiffies;
                ++tx->tx_head;
 
-               if (tx->tx_head - tx->tx_tail == ipoib_sendq_size) {
+               if (++priv->tx_outstanding == ipoib_sendq_size) {
                        ipoib_dbg(priv, "TX ring 0x%x full, stopping kernel net queue\n",
                                  tx->qp->qp_num);
                        netif_stop_queue(dev);
-                       set_bit(IPOIB_FLAG_NETIF_STOPPED, &tx->flags);
                }
        }
 }
 
-static void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ipoib_cm_tx *tx,
-                                 struct ib_wc *wc)
+void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ib_wc *wc)
 {
        struct ipoib_dev_priv *priv = netdev_priv(dev);
-       unsigned int wr_id = wc->wr_id;
+       struct ipoib_cm_tx *tx = wc->qp->qp_context;
+       unsigned int wr_id = wc->wr_id & ~IPOIB_OP_CM;
        struct ipoib_tx_buf *tx_req;
        unsigned long flags;
 
@@ -587,11 +586,10 @@ static void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ipoib_cm_tx *tx
 
        spin_lock_irqsave(&priv->tx_lock, flags);
        ++tx->tx_tail;
-       if (unlikely(test_bit(IPOIB_FLAG_NETIF_STOPPED, &tx->flags)) &&
-           tx->tx_head - tx->tx_tail <= ipoib_sendq_size >> 1) {
-               clear_bit(IPOIB_FLAG_NETIF_STOPPED, &tx->flags);
+       if (unlikely(--priv->tx_outstanding == ipoib_sendq_size >> 1) &&
+           netif_queue_stopped(dev) &&
+           test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))
                netif_wake_queue(dev);
-       }
 
        if (wc->status != IB_WC_SUCCESS &&
            wc->status != IB_WC_WR_FLUSH_ERR) {
@@ -614,11 +612,6 @@ static void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ipoib_cm_tx *tx
                        tx->neigh = NULL;
                }
 
-               /* queue would be re-started anyway when TX is destroyed,
-                * but it makes sense to do it ASAP here. */
-               if (test_and_clear_bit(IPOIB_FLAG_NETIF_STOPPED, &tx->flags))
-                       netif_wake_queue(dev);
-
                if (test_and_clear_bit(IPOIB_FLAG_INITIALIZED, &tx->flags)) {
                        list_move(&tx->list, &priv->cm.reap_list);
                        queue_work(ipoib_workqueue, &priv->cm.reap_task);
@@ -632,19 +625,6 @@ static void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ipoib_cm_tx *tx
        spin_unlock_irqrestore(&priv->tx_lock, flags);
 }
 
-static void ipoib_cm_tx_completion(struct ib_cq *cq, void *tx_ptr)
-{
-       struct ipoib_cm_tx *tx = tx_ptr;
-       int n, i;
-
-       ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
-       do {
-               n = ib_poll_cq(cq, IPOIB_NUM_WC, tx->ibwc);
-               for (i = 0; i < n; ++i)
-                       ipoib_cm_handle_tx_wc(tx->dev, tx, tx->ibwc + i);
-       } while (n == IPOIB_NUM_WC);
-}
-
 int ipoib_cm_dev_open(struct net_device *dev)
 {
        struct ipoib_dev_priv *priv = netdev_priv(dev);
@@ -807,17 +787,18 @@ static int ipoib_cm_rep_handler(struct ib_cm_id *cm_id, struct ib_cm_event *even
        return 0;
 }
 
-static struct ib_qp *ipoib_cm_create_tx_qp(struct net_device *dev, struct ib_cq *cq)
+static struct ib_qp *ipoib_cm_create_tx_qp(struct net_device *dev, struct ipoib_cm_tx *tx)
 {
        struct ipoib_dev_priv *priv = netdev_priv(dev);
        struct ib_qp_init_attr attr = {
-               .send_cq                = cq,
+               .send_cq                = priv->cq,
                .recv_cq                = priv->cq,
                .srq                    = priv->cm.srq,
                .cap.max_send_wr        = ipoib_sendq_size,
                .cap.max_send_sge       = 1,
                .sq_sig_type            = IB_SIGNAL_ALL_WR,
                .qp_type                = IB_QPT_RC,
+               .qp_context             = tx
         };
 
        return ib_create_qp(priv->pd, &attr);
@@ -899,21 +880,7 @@ static int ipoib_cm_tx_init(struct ipoib_cm_tx *p, u32 qpn,
                goto err_tx;
        }
 
-       p->cq = ib_create_cq(priv->ca, ipoib_cm_tx_completion, NULL, p,
-                            ipoib_sendq_size + 1, 0);
-       if (IS_ERR(p->cq)) {
-               ret = PTR_ERR(p->cq);
-               ipoib_warn(priv, "failed to allocate tx cq: %d\n", ret);
-               goto err_cq;
-       }
-
-       ret = ib_req_notify_cq(p->cq, IB_CQ_NEXT_COMP);
-       if (ret) {
-               ipoib_warn(priv, "failed to request completion notification: %d\n", ret);
-               goto err_req_notify;
-       }
-
-       p->qp = ipoib_cm_create_tx_qp(p->dev, p->cq);
+       p->qp = ipoib_cm_create_tx_qp(p->dev, p);
        if (IS_ERR(p->qp)) {
                ret = PTR_ERR(p->qp);
                ipoib_warn(priv, "failed to allocate tx qp: %d\n", ret);
@@ -950,12 +917,8 @@ err_modify:
 err_id:
        p->id = NULL;
        ib_destroy_qp(p->qp);
-err_req_notify:
 err_qp:
        p->qp = NULL;
-       ib_destroy_cq(p->cq);
-err_cq:
-       p->cq = NULL;
 err_tx:
        return ret;
 }
@@ -964,6 +927,8 @@ static void ipoib_cm_tx_destroy(struct ipoib_cm_tx *p)
 {
        struct ipoib_dev_priv *priv = netdev_priv(p->dev);
        struct ipoib_tx_buf *tx_req;
+       unsigned long flags;
+       unsigned long begin;
 
        ipoib_dbg(priv, "Destroy active connection 0x%x head 0x%x tail 0x%x\n",
                  p->qp ? p->qp->qp_num : 0, p->tx_head, p->tx_tail);
@@ -971,27 +936,40 @@ static void ipoib_cm_tx_destroy(struct ipoib_cm_tx *p)
        if (p->id)
                ib_destroy_cm_id(p->id);
 
-       if (p->qp)
-               ib_destroy_qp(p->qp);
-
-       if (p->cq)
-               ib_destroy_cq(p->cq);
-
-       if (test_bit(IPOIB_FLAG_NETIF_STOPPED, &p->flags))
-               netif_wake_queue(p->dev);
-
        if (p->tx_ring) {
+               /* Wait for all sends to complete */
+               begin = jiffies;
                while ((int) p->tx_tail - (int) p->tx_head < 0) {
-                       tx_req = &p->tx_ring[p->tx_tail & (ipoib_sendq_size - 1)];
-                       ib_dma_unmap_single(priv->ca, tx_req->mapping, tx_req->skb->len,
-                                        DMA_TO_DEVICE);
-                       dev_kfree_skb_any(tx_req->skb);
-                       ++p->tx_tail;
+                       if (time_after(jiffies, begin + 5 * HZ)) {
+                               ipoib_warn(priv, "timing out; %d sends not completed\n",
+                                          p->tx_head - p->tx_tail);
+                               goto timeout;
+                       }
+
+                       msleep(1);
                }
+       }
 
-               kfree(p->tx_ring);
+timeout:
+
+       while ((int) p->tx_tail - (int) p->tx_head < 0) {
+               tx_req = &p->tx_ring[p->tx_tail & (ipoib_sendq_size - 1)];
+               ib_dma_unmap_single(priv->ca, tx_req->mapping, tx_req->skb->len,
+                                   DMA_TO_DEVICE);
+               dev_kfree_skb_any(tx_req->skb);
+               ++p->tx_tail;
+               spin_lock_irqsave(&priv->tx_lock, flags);
+               if (unlikely(--priv->tx_outstanding == ipoib_sendq_size >> 1) &&
+                   netif_queue_stopped(p->dev) &&
+                   test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))
+                       netif_wake_queue(p->dev);
+               spin_unlock_irqrestore(&priv->tx_lock, flags);
        }
 
+       if (p->qp)
+               ib_destroy_qp(p->qp);
+
+       kfree(p->tx_ring);
        kfree(p);
 }
 
index 1a77e79f6b432748accdbb9a813f9a257aa4c1c6..5063dd509ad2338077c0b2fae061f8d6f68754be 100644 (file)
@@ -267,11 +267,10 @@ static void ipoib_ib_handle_tx_wc(struct net_device *dev, struct ib_wc *wc)
 
        spin_lock_irqsave(&priv->tx_lock, flags);
        ++priv->tx_tail;
-       if (unlikely(test_bit(IPOIB_FLAG_NETIF_STOPPED, &priv->flags)) &&
-           priv->tx_head - priv->tx_tail <= ipoib_sendq_size >> 1) {
-               clear_bit(IPOIB_FLAG_NETIF_STOPPED, &priv->flags);
+       if (unlikely(--priv->tx_outstanding == ipoib_sendq_size >> 1) &&
+           netif_queue_stopped(dev) &&
+           test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))
                netif_wake_queue(dev);
-       }
        spin_unlock_irqrestore(&priv->tx_lock, flags);
 
        if (wc->status != IB_WC_SUCCESS &&
@@ -301,14 +300,18 @@ poll_more:
                for (i = 0; i < n; i++) {
                        struct ib_wc *wc = priv->ibwc + i;
 
-                       if (wc->wr_id & IPOIB_CM_OP_SRQ) {
-                               ++done;
-                               ipoib_cm_handle_rx_wc(dev, wc);
-                       } else if (wc->wr_id & IPOIB_OP_RECV) {
+                       if (wc->wr_id & IPOIB_OP_RECV) {
                                ++done;
-                               ipoib_ib_handle_rx_wc(dev, wc);
-                       } else
-                               ipoib_ib_handle_tx_wc(dev, wc);
+                               if (wc->wr_id & IPOIB_OP_CM)
+                                       ipoib_cm_handle_rx_wc(dev, wc);
+                               else
+                                       ipoib_ib_handle_rx_wc(dev, wc);
+                       } else {
+                               if (wc->wr_id & IPOIB_OP_CM)
+                                       ipoib_cm_handle_tx_wc(dev, wc);
+                               else
+                                       ipoib_ib_handle_tx_wc(dev, wc);
+                       }
                }
 
                if (n != t)
@@ -401,10 +404,9 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb,
                address->last_send = priv->tx_head;
                ++priv->tx_head;
 
-               if (priv->tx_head - priv->tx_tail == ipoib_sendq_size) {
+               if (++priv->tx_outstanding == ipoib_sendq_size) {
                        ipoib_dbg(priv, "TX ring full, stopping kernel net queue\n");
                        netif_stop_queue(dev);
-                       set_bit(IPOIB_FLAG_NETIF_STOPPED, &priv->flags);
                }
        }
 }
@@ -436,7 +438,8 @@ void ipoib_reap_ah(struct work_struct *work)
        __ipoib_reap_ah(dev);
 
        if (!test_bit(IPOIB_STOP_REAPER, &priv->flags))
-               queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task, HZ);
+               queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task,
+                                  round_jiffies_relative(HZ));
 }
 
 int ipoib_ib_dev_open(struct net_device *dev)
@@ -472,7 +475,8 @@ int ipoib_ib_dev_open(struct net_device *dev)
        }
 
        clear_bit(IPOIB_STOP_REAPER, &priv->flags);
-       queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task, HZ);
+       queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task,
+                          round_jiffies_relative(HZ));
 
        set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);
 
@@ -561,12 +565,17 @@ void ipoib_drain_cq(struct net_device *dev)
                        if (priv->ibwc[i].status == IB_WC_SUCCESS)
                                priv->ibwc[i].status = IB_WC_WR_FLUSH_ERR;
 
-                       if (priv->ibwc[i].wr_id & IPOIB_CM_OP_SRQ)
-                               ipoib_cm_handle_rx_wc(dev, priv->ibwc + i);
-                       else if (priv->ibwc[i].wr_id & IPOIB_OP_RECV)
-                               ipoib_ib_handle_rx_wc(dev, priv->ibwc + i);
-                       else
-                               ipoib_ib_handle_tx_wc(dev, priv->ibwc + i);
+                       if (priv->ibwc[i].wr_id & IPOIB_OP_RECV) {
+                               if (priv->ibwc[i].wr_id & IPOIB_OP_CM)
+                                       ipoib_cm_handle_rx_wc(dev, priv->ibwc + i);
+                               else
+                                       ipoib_ib_handle_rx_wc(dev, priv->ibwc + i);
+                       } else {
+                               if (priv->ibwc[i].wr_id & IPOIB_OP_CM)
+                                       ipoib_cm_handle_tx_wc(dev, priv->ibwc + i);
+                               else
+                                       ipoib_ib_handle_tx_wc(dev, priv->ibwc + i);
+                       }
                }
        } while (n == IPOIB_NUM_WC);
 }
@@ -612,6 +621,7 @@ int ipoib_ib_dev_stop(struct net_device *dev, int flush)
                                                    DMA_TO_DEVICE);
                                dev_kfree_skb_any(tx_req->skb);
                                ++priv->tx_tail;
+                               --priv->tx_outstanding;
                        }
 
                        for (i = 0; i < ipoib_recvq_size; ++i) {
index 362610d870e4328935f8be02f4ffaa0faae96ea6..a03a65ebcf0c0a95d31903b17d448be3dd26ed85 100644 (file)
@@ -148,8 +148,6 @@ static int ipoib_stop(struct net_device *dev)
 
        netif_stop_queue(dev);
 
-       clear_bit(IPOIB_FLAG_NETIF_STOPPED, &priv->flags);
-
        /*
         * Now flush workqueue to make sure a scheduled task doesn't
         * bring our internal state back up.
@@ -902,7 +900,7 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port)
                goto out_rx_ring_cleanup;
        }
 
-       /* priv->tx_head & tx_tail are already 0 */
+       /* priv->tx_head, tx_tail & tx_outstanding are already 0 */
 
        if (ipoib_ib_dev_init(dev, ca, port))
                goto out_tx_ring_cleanup;
index f3529b6f0a337261e3eb275f5b0c48693a747054..d68798061795187551a0873503a5fa256ecedf0a 100644 (file)
@@ -131,7 +131,7 @@ static int iser_start_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask,
 
                p = mem;
                for_each_sg(sgl, sg, data->size, i) {
-                       from = kmap_atomic(sg->page, KM_USER0);
+                       from = kmap_atomic(sg_page(sg), KM_USER0);
                        memcpy(p,
                               from + sg->offset,
                               sg->length);
@@ -191,7 +191,7 @@ void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask,
 
                p = mem;
                for_each_sg(sgl, sg, sg_size, i) {
-                       to = kmap_atomic(sg->page, KM_SOFTIRQ0);
+                       to = kmap_atomic(sg_page(sg), KM_SOFTIRQ0);
                        memcpy(to + sg->offset,
                               p,
                               sg->length);
@@ -300,7 +300,7 @@ static unsigned int iser_data_buf_aligned_len(struct iser_data_buf *data,
        for_each_sg(sgl, sg, data->dma_nents, i) {
                /* iser_dbg("Checking sg iobuf [%d]: phys=0x%08lX "
                   "offset: %ld sz: %ld\n", i,
-                  (unsigned long)page_to_phys(sg->page),
+                  (unsigned long)sg_phys(sg),
                   (unsigned long)sg->offset,
                   (unsigned long)sg->length); */
                end_addr = ib_sg_dma_address(ibdev, sg) +
@@ -336,7 +336,7 @@ static void iser_data_buf_dump(struct iser_data_buf *data,
                iser_err("sg[%d] dma_addr:0x%lX page:0x%p "
                         "off:0x%x sz:0x%x dma_len:0x%x\n",
                         i, (unsigned long)ib_sg_dma_address(ibdev, sg),
-                        sg->page, sg->offset,
+                        sg_page(sg), sg->offset,
                         sg->length, ib_sg_dma_len(ibdev, sg));
 }
 
index 1d62c8b88e121307427a491a204a023c9510c3d5..e5b4e9bfbdc5b044b968a70579f13eea513a12c6 100644 (file)
@@ -495,7 +495,7 @@ static unsigned int evdev_poll(struct file *file, poll_table *wait)
 #ifdef CONFIG_COMPAT
 
 #define BITS_PER_LONG_COMPAT (sizeof(compat_long_t) * 8)
-#define NBITS_COMPAT(x) ((((x) - 1) / BITS_PER_LONG_COMPAT) + 1)
+#define BITS_TO_LONGS_COMPAT(x) ((((x) - 1) / BITS_PER_LONG_COMPAT) + 1)
 
 #ifdef __BIG_ENDIAN
 static int bits_to_user(unsigned long *bits, unsigned int maxbit,
@@ -504,7 +504,7 @@ static int bits_to_user(unsigned long *bits, unsigned int maxbit,
        int len, i;
 
        if (compat) {
-               len = NBITS_COMPAT(maxbit) * sizeof(compat_long_t);
+               len = BITS_TO_LONGS_COMPAT(maxbit) * sizeof(compat_long_t);
                if (len > maxlen)
                        len = maxlen;
 
@@ -515,7 +515,7 @@ static int bits_to_user(unsigned long *bits, unsigned int maxbit,
                                         sizeof(compat_long_t)))
                                return -EFAULT;
        } else {
-               len = NBITS(maxbit) * sizeof(long);
+               len = BITS_TO_LONGS(maxbit) * sizeof(long);
                if (len > maxlen)
                        len = maxlen;
 
@@ -530,8 +530,8 @@ static int bits_to_user(unsigned long *bits, unsigned int maxbit,
                        unsigned int maxlen, void __user *p, int compat)
 {
        int len = compat ?
-                       NBITS_COMPAT(maxbit) * sizeof(compat_long_t) :
-                       NBITS(maxbit) * sizeof(long);
+                       BITS_TO_LONGS_COMPAT(maxbit) * sizeof(compat_long_t) :
+                       BITS_TO_LONGS(maxbit) * sizeof(long);
 
        if (len > maxlen)
                len = maxlen;
@@ -545,7 +545,7 @@ static int bits_to_user(unsigned long *bits, unsigned int maxbit,
 static int bits_to_user(unsigned long *bits, unsigned int maxbit,
                        unsigned int maxlen, void __user *p, int compat)
 {
-       int len = NBITS(maxbit) * sizeof(long);
+       int len = BITS_TO_LONGS(maxbit) * sizeof(long);
 
        if (len > maxlen)
                len = maxlen;
index ed3d2da0c48534e30473b2888a3d613b8a2273ca..3089d738232530d1bc873a00bd8eb1a255104483 100644 (file)
@@ -24,7 +24,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  *
  * Should you need to contact me, the author, you can do so by
- * e-mail - mail your message to <deneux@ifrance.com>
+ * e-mail - mail your message to <johann.deneux@gmail.com>
  */
 
 #include <linux/types.h>
index 20896d5e5f0e640389161dbecde47c1d3b21992e..bfc6061f1554fdf72c20d0e9d22631921f6fc052 100644 (file)
@@ -136,7 +136,8 @@ static int gameport_measure_speed(struct gameport *gameport)
        }
 
        gameport_close(gameport);
-       return (cpu_data[raw_smp_processor_id()].loops_per_jiffy * (unsigned long)HZ / (1000 / 50)) / (tx < 1 ? 1 : tx);
+       return (cpu_data(raw_smp_processor_id()).loops_per_jiffy *
+               (unsigned long)HZ / (1000 / 50)) / (tx < 1 ? 1 : tx);
 
 #else
 
@@ -448,9 +449,8 @@ static int gameport_thread(void *nothing)
        set_freezable();
        do {
                gameport_handle_event();
-               wait_event_interruptible(gameport_wait,
+               wait_event_freezable(gameport_wait,
                        kthread_should_stop() || !list_empty(&gameport_event_list));
-               try_to_freeze();
        } while (!kthread_should_stop());
 
        printk(KERN_DEBUG "gameport: kgameportd exiting\n");
index 2f2b020cd6294109da6e757e2968c12bca97aaef..307c7b5c2b33a59fa33825523cca639af4f4ccd2 100644 (file)
@@ -584,10 +584,10 @@ static int input_default_setkeycode(struct input_dev *dev,
 
 
 #define MATCH_BIT(bit, max) \
-               for (i = 0; i < NBITS(max); i++) \
+               for (i = 0; i < BITS_TO_LONGS(max); i++) \
                        if ((id->bit[i] & dev->bit[i]) != id->bit[i]) \
                                break; \
-               if (i != NBITS(max)) \
+               if (i != BITS_TO_LONGS(max)) \
                        continue;
 
 static const struct input_device_id *input_match_device(const struct input_device_id *id,
@@ -698,7 +698,7 @@ static void input_seq_print_bitmap(struct seq_file *seq, const char *name,
 {
        int i;
 
-       for (i = NBITS(max) - 1; i > 0; i--)
+       for (i = BITS_TO_LONGS(max) - 1; i > 0; i--)
                if (bitmap[i])
                        break;
 
@@ -892,7 +892,7 @@ static int input_print_modalias_bits(char *buf, int size,
 
        len += snprintf(buf, max(size, 0), "%c", name);
        for (i = min_bit; i < max_bit; i++)
-               if (bm[LONG(i)] & BIT(i))
+               if (bm[BIT_WORD(i)] & BIT_MASK(i))
                        len += snprintf(buf + len, max(size - len, 0), "%X,", i);
        return len;
 }
@@ -991,7 +991,7 @@ static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap,
        int i;
        int len = 0;
 
-       for (i = NBITS(max) - 1; i > 0; i--)
+       for (i = BITS_TO_LONGS(max) - 1; i > 0; i--)
                if (bitmap[i])
                        break;
 
index 2b201f9aa02405fce891b9aee53c757307609a28..22b2789ef58ad17e30299f5fcbc7f5587d11dba9 100644 (file)
@@ -844,8 +844,8 @@ static const struct input_device_id joydev_blacklist[] = {
        {
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
                                INPUT_DEVICE_ID_MATCH_KEYBIT,
-               .evbit = { BIT(EV_KEY) },
-               .keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) },
+               .evbit = { BIT_MASK(EV_KEY) },
+               .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
        },      /* Avoid itouchpads, touchscreens and tablets */
        { }     /* Terminating entry */
 };
@@ -854,20 +854,20 @@ static const struct input_device_id joydev_ids[] = {
        {
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
                                INPUT_DEVICE_ID_MATCH_ABSBIT,
-               .evbit = { BIT(EV_ABS) },
-               .absbit = { BIT(ABS_X) },
+               .evbit = { BIT_MASK(EV_ABS) },
+               .absbit = { BIT_MASK(ABS_X) },
        },
        {
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
                                INPUT_DEVICE_ID_MATCH_ABSBIT,
-               .evbit = { BIT(EV_ABS) },
-               .absbit = { BIT(ABS_WHEEL) },
+               .evbit = { BIT_MASK(EV_ABS) },
+               .absbit = { BIT_MASK(ABS_WHEEL) },
        },
        {
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
                                INPUT_DEVICE_ID_MATCH_ABSBIT,
-               .evbit = { BIT(EV_ABS) },
-               .absbit = { BIT(ABS_THROTTLE) },
+               .evbit = { BIT_MASK(EV_ABS) },
+               .absbit = { BIT_MASK(ABS_THROTTLE) },
        },
        { }     /* Terminating entry */
 };
index ff701ab10d74f71e0ffcee5f953fc2428d3ef817..52ba16f487c793a36acc464dc4c0e3cc80e77fbc 100644 (file)
@@ -326,14 +326,19 @@ static int a3d_connect(struct gameport *gameport, struct gameport_driver *drv)
 
                a3d->length = 33;
 
-               input_dev->evbit[0] |= BIT(EV_ABS) | BIT(EV_KEY) | BIT(EV_REL);
-               input_dev->relbit[0] |= BIT(REL_X) | BIT(REL_Y);
-               input_dev->absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_THROTTLE) | BIT(ABS_RUDDER)
-                                       | BIT(ABS_HAT0X) | BIT(ABS_HAT0Y) | BIT(ABS_HAT1X) | BIT(ABS_HAT1Y);
-               input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_RIGHT) | BIT(BTN_LEFT) | BIT(BTN_MIDDLE)
-                                                       | BIT(BTN_SIDE) | BIT(BTN_EXTRA);
-               input_dev->keybit[LONG(BTN_JOYSTICK)] |= BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP)
-                                                       | BIT(BTN_PINKIE);
+               input_dev->evbit[0] |= BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY) |
+                       BIT_MASK(EV_REL);
+               input_dev->relbit[0] |= BIT_MASK(REL_X) | BIT_MASK(REL_Y);
+               input_dev->absbit[0] |= BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
+                       BIT_MASK(ABS_THROTTLE) | BIT_MASK(ABS_RUDDER) |
+                       BIT_MASK(ABS_HAT0X) | BIT_MASK(ABS_HAT0Y) |
+                       BIT_MASK(ABS_HAT1X) | BIT_MASK(ABS_HAT1Y);
+               input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_RIGHT) |
+                       BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) |
+                       BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA);
+               input_dev->keybit[BIT_WORD(BTN_JOYSTICK)] |=
+                       BIT_MASK(BTN_TRIGGER) | BIT_MASK(BTN_THUMB) |
+                       BIT_MASK(BTN_TOP) | BIT_MASK(BTN_PINKIE);
 
                a3d_read(a3d, data);
 
@@ -348,9 +353,10 @@ static int a3d_connect(struct gameport *gameport, struct gameport_driver *drv)
        } else {
                a3d->length = 29;
 
-               input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_REL);
-               input_dev->relbit[0] |= BIT(REL_X) | BIT(REL_Y);
-               input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_RIGHT) | BIT(BTN_LEFT) | BIT(BTN_MIDDLE);
+               input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+               input_dev->relbit[0] |= BIT_MASK(REL_X) | BIT_MASK(REL_Y);
+               input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_RIGHT) |
+                       BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE);
 
                a3d_read(a3d, data);
 
index 28140c4a110df399c713d7ad337dfd177885455e..d1ca8a14950f62f914e9d4f9f81ae34a7eabadfe 100644 (file)
@@ -431,7 +431,7 @@ static int adi_init_input(struct adi *adi, struct adi_port *port, int half)
        input_dev->open = adi_open;
        input_dev->close = adi_close;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
        for (i = 0; i < adi->axes10 + adi->axes8 + (adi->hats + (adi->pad != -1)) * 2; i++)
                set_bit(adi->abs[i], input_dev->absbit);
index b0f5541ec3e6849725955c655cbb4c5ea1f6559c..5cf9f3610e67f3924b4a8eb71fcc9d9156b93bb3 100644 (file)
@@ -137,9 +137,10 @@ static int __init amijoy_init(void)
                amijoy_dev[i]->open = amijoy_open;
                amijoy_dev[i]->close = amijoy_close;
 
-               amijoy_dev[i]->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-               amijoy_dev[i]->absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
-               amijoy_dev[i]->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+               amijoy_dev[i]->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+               amijoy_dev[i]->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y);
+               amijoy_dev[i]->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
+                       BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
                for (j = 0; j < 2; j++) {
                        amijoy_dev[i]->absmin[ABS_X + j] = -1;
                        amijoy_dev[i]->absmax[ABS_X + j] = 1;
index bdd157c1ebf8929b763a9d56815ce209c5d906f2..15739880afc6af31829f8a3058c701efa0976207 100644 (file)
@@ -456,7 +456,7 @@ static int analog_init_device(struct analog_port *port, struct analog *analog, i
        input_dev->open = analog_open;
        input_dev->close = analog_close;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
        for (i = j = 0; i < 4; i++)
                if (analog->mask & (1 << i)) {
index d3352a849b85f592b08df3140af53c0b594c0366..55646a6d89f586de8f35616a947b41c84bd854c2 100644 (file)
@@ -218,7 +218,7 @@ static int cobra_connect(struct gameport *gameport, struct gameport_driver *drv)
                input_dev->open = cobra_open;
                input_dev->close = cobra_close;
 
-               input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+               input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
                input_set_abs_params(input_dev, ABS_X, -1, 1, 0, 0);
                input_set_abs_params(input_dev, ABS_Y, -1, 1, 0, 0);
                for (j = 0; cobra_btn[j]; j++)
index b069ee18e35312078ec3cff1d6910d102dd851a7..a6ca9d5e252f089f9118efd6f0d01693920b4973 100644 (file)
@@ -4,7 +4,7 @@
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  *
  *  Based on the work of:
- *     Andree Borrmann         Mats Sjövall
+ *     Andree Borrmann         Mats Sjövall
  */
 
 /*
@@ -631,7 +631,7 @@ static struct db9 __init *db9_probe(int parport, int mode)
                input_dev->open = db9_open;
                input_dev->close = db9_close;
 
-               input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+               input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
                for (j = 0; j < db9_mode->n_buttons; j++)
                        set_bit(db9_mode->buttons[j], input_dev->keybit);
                for (j = 0; j < db9_mode->n_axis; j++) {
index 1a452e0e5f25788e37c972998912245747ec1657..df2a9d02ca6c1f32d8bf31fc24270883f912aa17 100644 (file)
@@ -653,12 +653,12 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type)
        input_dev->close = gc_close;
 
        if (pad_type != GC_SNESMOUSE) {
-               input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+               input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
                for (i = 0; i < 2; i++)
                        input_set_abs_params(input_dev, ABS_X + i, -1, 1, 0, 0);
        } else
-               input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+               input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
 
        gc->pads[0] |= gc_status_bit[idx];
        gc->pads[pad_type] |= gc_status_bit[idx];
index d514aebf75541fc871b56b510f1c4410bef2990c..1f6302c0eb3fd8e47c5f8e5a5edfdd95836d5fe8 100644 (file)
@@ -315,7 +315,7 @@ static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv)
        input_dev->open = gf2k_open;
        input_dev->close = gf2k_close;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
        for (i = 0; i < gf2k_axes[gf2k->id]; i++)
                set_bit(gf2k_abs[i], input_dev->absbit);
index 73eb5ab6f140caa4bc8b9dd5eb34346335f1b1c2..fd3853ab1aad4db5499cea82c62872d720c16edc 100644 (file)
@@ -370,7 +370,7 @@ static int grip_connect(struct gameport *gameport, struct gameport_driver *drv)
                input_dev->open = grip_open;
                input_dev->close = grip_close;
 
-               input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+               input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
                for (j = 0; (t = grip_abs[grip->mode[i]][j]) >= 0; j++) {
 
index 4ed3a3eadf1964eaad388e4f603720910e675811..c57e21d68c003e2970949744120b3384b8fe98e6 100644 (file)
@@ -606,7 +606,7 @@ static int register_slot(int slot, struct grip_mp *grip)
        input_dev->open = grip_open;
        input_dev->close = grip_close;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
        for (j = 0; (t = grip_abs[port->mode][j]) >= 0; j++)
                input_set_abs_params(input_dev, t, -1, 1, 0, 0);
index d4e8073caf27a98a603a33a9eb0323f7e300701d..aa6bfb3fb8cd2b135201e97b7ee7dc99d6263660 100644 (file)
@@ -238,7 +238,7 @@ static int guillemot_connect(struct gameport *gameport, struct gameport_driver *
        input_dev->open = guillemot_open;
        input_dev->close = guillemot_close;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
        for (i = 0; (t = guillemot->type->abs[i]) >= 0; i++)
                input_set_abs_params(input_dev, t, 0, 255, 0, 0);
index 17ae42bf9ffd8b810deee67d4868a09df273cfcc..74daff49ab6e1e146415a13c6103ef2e30ba8bb1 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Makefile for the I-Force driver
 #
-# By Johann Deneux <deneux@ifrance.com>
+# By Johann Deneux <johann.deneux@gmail.com>
 #
 
 # Goal definition
index 682244b1c0422610e9475020d83f67cb7fff51e4..6f826b37d9aa6274e470ed07493e42c2f95bcf8a 100644 (file)
@@ -389,7 +389,8 @@ int iforce_init_device(struct iforce *iforce)
  * Set input device bitfields and ranges.
  */
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_FF_STATUS);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) |
+               BIT_MASK(EV_FF_STATUS);
 
        for (i = 0; iforce->type->btn[i] >= 0; i++)
                set_bit(iforce->type->btn[i], input_dev->keybit);
index 40a853ac21c795c2e3db467be967f203a91f1d0b..a964a7cfd210cdc29b4fac6fcd9ee4c2c230d60b 100644 (file)
 #define FF_CORE_IS_PLAYED      3       /* Effect is currently being played */
 #define FF_CORE_SHOULD_PLAY    4       /* User wants the effect to be played */
 #define FF_CORE_UPDATE         5       /* Effect is being updated */
-#define FF_MODCORE_MAX         5
+#define FF_MODCORE_CNT         6
 
 struct iforce_core_effect {
        /* Information about where modifiers are stored in the device's memory */
        struct resource mod1_chunk;
        struct resource mod2_chunk;
-       unsigned long flags[NBITS(FF_MODCORE_MAX)];
+       unsigned long flags[BITS_TO_LONGS(FF_MODCORE_CNT)];
 };
 
 #define FF_CMD_EFFECT          0x010e
index 1aec1e9d7c5942f2b58d090778a08516ccee79b4..bc8ea95dfd0e8328736097ec4b1b132256d978ca 100644 (file)
@@ -269,7 +269,7 @@ static int interact_connect(struct gameport *gameport, struct gameport_driver *d
        input_dev->open = interact_open;
        input_dev->close = interact_close;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
        for (i = 0; (t = interact_type[interact->type].abs[i]) >= 0; i++) {
                set_bit(t, input_dev->absbit);
index b35604ee43aecd4318a4fb126a4c0d40a9db7279..54e676948ebb1caa777dee0195f942fb876478e3 100644 (file)
@@ -170,7 +170,7 @@ static int magellan_connect(struct serio *serio, struct serio_driver *drv)
        input_dev->id.version = 0x0100;
        input_dev->dev.parent = &serio->dev;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
        for (i = 0; i < 9; i++)
                set_bit(magellan_buttons[i], input_dev->keybit);
index 2adf73f63c94dd7898d7ef1091a4c5842bb832c4..7b4865fdee54cdcf48998cff18dc7bdd4316a9c0 100644 (file)
@@ -758,7 +758,7 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv)
                input_dev->open = sw_open;
                input_dev->close = sw_close;
 
-               input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+               input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
                for (j = 0; (bits = sw_bit[sw->type][j]); j++) {
                        code = sw_abs[sw->type][j];
index abb7c4cf54ad50d07fe3bcff57d7eceea86f18d4..d4087fd496563367bea2c7894c1e4a71c8477853 100644 (file)
@@ -228,18 +228,23 @@ static int spaceball_connect(struct serio *serio, struct serio_driver *drv)
        input_dev->id.version = 0x0100;
        input_dev->dev.parent = &serio->dev;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
        switch (id) {
                case SPACEBALL_4000FLX:
                case SPACEBALL_4000FLX_L:
-                       input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_9);
-                       input_dev->keybit[LONG(BTN_A)] |= BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_MODE);
+                       input_dev->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_9);
+                       input_dev->keybit[BIT_WORD(BTN_A)] |= BIT_MASK(BTN_A) |
+                               BIT_MASK(BTN_B) | BIT_MASK(BTN_C) |
+                               BIT_MASK(BTN_MODE);
                default:
-                       input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4)
-                               | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7) | BIT(BTN_8);
+                       input_dev->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_2) |
+                               BIT_MASK(BTN_3) | BIT_MASK(BTN_4) |
+                               BIT_MASK(BTN_5) | BIT_MASK(BTN_6) |
+                               BIT_MASK(BTN_7) | BIT_MASK(BTN_8);
                case SPACEBALL_3003C:
-                       input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_1) | BIT(BTN_8);
+                       input_dev->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_1) |
+                               BIT_MASK(BTN_8);
        }
 
        for (i = 0; i < 3; i++) {
index c4937f1e837c192dd41ab252d933ac81308e8e4b..f7ce4004f4ba1baf036766e5af0f90d7ef14c8e1 100644 (file)
@@ -185,7 +185,7 @@ static int spaceorb_connect(struct serio *serio, struct serio_driver *drv)
        input_dev->id.version = 0x0100;
        input_dev->dev.parent = &serio->dev;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
        for (i = 0; i < 6; i++)
                set_bit(spaceorb_buttons[i], input_dev->keybit);
index 8581ee991d4e8e90cff96d8dee1fcfc3f038855d..baa10b2f7ba1c74843b8d8bbf2060e3649b045f7 100644 (file)
@@ -156,10 +156,11 @@ static int stinger_connect(struct serio *serio, struct serio_driver *drv)
        input_dev->id.version = 0x0100;
        input_dev->dev.parent = &serio->dev;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-       input_dev->keybit[LONG(BTN_A)] = BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_X) |
-                                        BIT(BTN_Y) | BIT(BTN_Z) | BIT(BTN_TL) | BIT(BTN_TR) |
-                                        BIT(BTN_START) | BIT(BTN_SELECT);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+       input_dev->keybit[BIT_WORD(BTN_A)] = BIT_MASK(BTN_A) | BIT_MASK(BTN_B) |
+               BIT_MASK(BTN_C) | BIT_MASK(BTN_X) | BIT_MASK(BTN_Y) |
+               BIT_MASK(BTN_Z) | BIT_MASK(BTN_TL) | BIT_MASK(BTN_TR) |
+               BIT_MASK(BTN_START) | BIT_MASK(BTN_SELECT);
        input_set_abs_params(input_dev, ABS_X, -64, 64, 0, 4);
        input_set_abs_params(input_dev, ABS_Y, -64, 64, 0, 4);
 
index 3b36ee04f7261848e87c0c61c45b9e517e1bf218..0feeb8acb532a297a819d5713a3aa2bce3490af8 100644 (file)
@@ -333,7 +333,7 @@ static int tmdc_setup_port(struct tmdc *tmdc, int idx, unsigned char *data)
        input_dev->open = tmdc_open;
        input_dev->close = tmdc_close;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
        for (i = 0; i < port->absc && i < TMDC_ABS; i++)
                if (port->abs[i] >= 0)
index 8381c6f143735f69af27b714cfcd7d79d2a37ed7..bbebd4e2ad7f35845770540f5c3a74f74fd3de1a 100644 (file)
@@ -229,7 +229,7 @@ static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs)
                input_dev->open = tgfx_open;
                input_dev->close = tgfx_close;
 
-               input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+               input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
                input_set_abs_params(input_dev, ABS_X, -1, 1, 0, 0);
                input_set_abs_params(input_dev, ABS_Y, -1, 1, 0, 0);
 
index c91504ec38ebf012423b46db735d90174697580a..1085c841fec48ca932263e898b0e759ca363fb62 100644 (file)
@@ -207,7 +207,7 @@ static int twidjoy_connect(struct serio *serio, struct serio_driver *drv)
        input_dev->id.version = 0x0100;
        input_dev->dev.parent = &serio->dev;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
        input_set_abs_params(input_dev, ABS_X, -50, 50, 4, 4);
        input_set_abs_params(input_dev, ABS_Y, -50, 50, 4, 4);
 
index 4e85f72eefd7075b4a6a7c9ae339c64a8dec6d4d..e928b6e3724a528b632f1a3af472073eaf888419 100644 (file)
@@ -162,9 +162,11 @@ static int warrior_connect(struct serio *serio, struct serio_driver *drv)
        input_dev->id.version = 0x0100;
        input_dev->dev.parent = &serio->dev;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);
-       input_dev->keybit[LONG(BTN_TRIGGER)] = BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP) | BIT(BTN_TOP2);
-       input_dev->relbit[0] = BIT(REL_DIAL);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) |
+               BIT_MASK(EV_ABS);
+       input_dev->keybit[BIT_WORD(BTN_TRIGGER)] = BIT_MASK(BTN_TRIGGER) |
+               BIT_MASK(BTN_THUMB) | BIT_MASK(BTN_TOP) | BIT_MASK(BTN_TOP2);
+       input_dev->relbit[0] = BIT_MASK(REL_DIAL);
        input_set_abs_params(input_dev, ABS_X, -64, 64, 0, 8);
        input_set_abs_params(input_dev, ABS_Y, -64, 64, 0, 8);
        input_set_abs_params(input_dev, ABS_THROTTLE, -112, 112, 0, 0);
index 623629a69b03e9be1b2a000a98cff8ccede174ef..6dd375825a1403226c9c727da6d3fc460ed17b6f 100644 (file)
@@ -658,7 +658,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
        input_dev->open = xpad_open;
        input_dev->close = xpad_close;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
        /* set up buttons */
        for (i = 0; xpad_btn[i] >= 0; i++)
index 63d6ead6b877051baf18392140cd9e23a2df9f68..72abc196ce66580000b25e0800e5b4908fc03383 100644 (file)
@@ -125,7 +125,7 @@ static int __devinit aaedkbd_probe(struct platform_device *pdev)
        input_dev->id.version = 0x0100;
        input_dev->dev.parent = &pdev->dev;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
        input_dev->keycode = aaedkbd->keycode;
        input_dev->keycodesize = sizeof(unsigned char);
        input_dev->keycodemax = ARRAY_SIZE(aaedkbd_keycode);
index c67e84ec2d6a506b94696c1739dd9d9a76752181..81bf7562aca0d94c65c7ec75278c240055692916 100644 (file)
@@ -209,7 +209,7 @@ static int __init amikbd_init(void)
        amikbd_dev->id.product = 0x0001;
        amikbd_dev->id.version = 0x0100;
 
-       amikbd_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+       amikbd_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
 
        for (i = 0; i < 0x78; i++)
                set_bit(i, amikbd_dev->keybit);
index a1800151b6ce8dc045005138154b065055afe171..4e92100c56a8dddcc342c40c5c2867e46e6c0fcf 100644 (file)
@@ -237,7 +237,7 @@ static int __init atakbd_init(void)
        atakbd_dev->id.product = 0x0001;
        atakbd_dev->id.version = 0x0100;
 
-       atakbd_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+       atakbd_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
        atakbd_dev->keycode = atakbd_keycode;
        atakbd_dev->keycodesize = sizeof(unsigned char);
        atakbd_dev->keycodemax = ARRAY_SIZE(atakbd_keycode);
index 41fc3d03b6eb495759cb93fbb7611e2acf76b712..b39c5b31e6201155ece9d224ab7e013ed9cb157f 100644 (file)
@@ -900,27 +900,32 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd)
 
        input_set_drvdata(input_dev, atkbd);
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_MSC);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) |
+               BIT_MASK(EV_MSC);
 
        if (atkbd->write) {
-               input_dev->evbit[0] |= BIT(EV_LED);
-               input_dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
+               input_dev->evbit[0] |= BIT_MASK(EV_LED);
+               input_dev->ledbit[0] = BIT_MASK(LED_NUML) |
+                       BIT_MASK(LED_CAPSL) | BIT_MASK(LED_SCROLLL);
        }
 
        if (atkbd->extra)
-               input_dev->ledbit[0] |= BIT(LED_COMPOSE) | BIT(LED_SUSPEND) |
-                                       BIT(LED_SLEEP) | BIT(LED_MUTE) | BIT(LED_MISC);
+               input_dev->ledbit[0] |= BIT_MASK(LED_COMPOSE) |
+                       BIT_MASK(LED_SUSPEND) | BIT_MASK(LED_SLEEP) |
+                       BIT_MASK(LED_MUTE) | BIT_MASK(LED_MISC);
 
        if (!atkbd->softrepeat) {
                input_dev->rep[REP_DELAY] = 250;
                input_dev->rep[REP_PERIOD] = 33;
        }
 
-       input_dev->mscbit[0] = atkbd->softraw ? BIT(MSC_SCAN) : BIT(MSC_RAW) | BIT(MSC_SCAN);
+       input_dev->mscbit[0] = atkbd->softraw ? BIT_MASK(MSC_SCAN) :
+               BIT_MASK(MSC_RAW) | BIT_MASK(MSC_SCAN);
 
        if (atkbd->scroll) {
-               input_dev->evbit[0] |= BIT(EV_REL);
-               input_dev->relbit[0] = BIT(REL_WHEEL) | BIT(REL_HWHEEL);
+               input_dev->evbit[0] |= BIT_MASK(EV_REL);
+               input_dev->relbit[0] = BIT_MASK(REL_WHEEL) |
+                       BIT_MASK(REL_HWHEEL);
                set_bit(BTN_MIDDLE, input_dev->keybit);
        }
 
index a67b29b089ef6b6b2506be658af3f64eebe07810..e5f4da9283406920945cee029758f3d0f8fbab94 100644 (file)
@@ -256,7 +256,6 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev)
                printk(KERN_ERR DRV_NAME
                        ": unable to claim irq %d; error %d\n",
                        bf54x_kpad->irq, error);
-               error = -EBUSY;
                goto out2;
        }
 
index 6578bfff644bdc5099f0da31d9876c451af4fa27..790fed368aae0ea144ddb053b6c20276d6717792 100644 (file)
@@ -325,7 +325,8 @@ static int __init corgikbd_probe(struct platform_device *pdev)
        input_dev->id.version = 0x0100;
        input_dev->dev.parent = &pdev->dev;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) |
+               BIT_MASK(EV_PWR) | BIT_MASK(EV_SW);
        input_dev->keycode = corgikbd->keycode;
        input_dev->keycodesize = sizeof(unsigned char);
        input_dev->keycodemax = ARRAY_SIZE(corgikbd_keycode);
index e2a3293bc67ed37b66949747de99d0e3d4d1dfd9..3eddf52a0bba5cabbe76a1f41cedee7c5fbf8ffc 100644 (file)
@@ -62,7 +62,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, input);
 
-       input->evbit[0] = BIT(EV_KEY);
+       input->evbit[0] = BIT_MASK(EV_KEY);
 
        input->name = pdev->name;
        input->phys = "gpio-keys/input0";
index cdd254f2e6c7970a93819d7966fead2454c56613..adbf29f0169d81f1f5a740243ade99756fc798cb 100644 (file)
@@ -323,8 +323,9 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv)
                goto bail2;
        }
 
-       kbd->dev->evbit[0]      = BIT(EV_KEY) | BIT(EV_REP);
-       kbd->dev->ledbit[0]     = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
+       kbd->dev->evbit[0]      = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
+       kbd->dev->ledbit[0]     = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) |
+               BIT_MASK(LED_SCROLLL);
        kbd->dev->keycodemax    = HIL_KEYCODES_SET1_TBLSIZE;
        kbd->dev->keycodesize   = sizeof(hil_kbd_set1[0]);
        kbd->dev->keycode       = hil_kbd_set1;
index 499b6974457f7039366941e1a4ae299fd0580d8b..50d80ecf0b80915ee81d2ab5c59b01be9cb1c4b7 100644 (file)
@@ -266,8 +266,9 @@ hil_keyb_init(void)
                if (hphilkeyb_keycode[i] != KEY_RESERVED)
                        set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit);
 
-       hil_dev.dev->evbit[0]   = BIT(EV_KEY) | BIT(EV_REP);
-       hil_dev.dev->ledbit[0]  = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
+       hil_dev.dev->evbit[0]   = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
+       hil_dev.dev->ledbit[0]  = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) |
+               BIT_MASK(LED_SCROLLL);
        hil_dev.dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE;
        hil_dev.dev->keycodesize= sizeof(hphilkeyb_keycode[0]);
        hil_dev.dev->keycode    = hphilkeyb_keycode;
index 7a41b271f222cfb5bdf5b68cd6946e27d6c88bf8..5a0ca18d6755827b77d776af407364b1a8b2d30d 100644 (file)
@@ -233,7 +233,7 @@ static int locomokbd_probe(struct locomo_dev *dev)
        input_dev->id.version = 0x0100;
        input_dev->dev.parent = &dev->dev;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
        input_dev->keycode = locomokbd->keycode;
        input_dev->keycodesize = sizeof(unsigned char);
        input_dev->keycodemax = ARRAY_SIZE(locomokbd_keycode);
index b97a41e3ee56cef949835fdc9135f597aefa7850..48d1cab0aa1c7284dcc795391d1759303f39db7c 100644 (file)
@@ -106,7 +106,7 @@ static int nkbd_connect(struct serio *serio, struct serio_driver *drv)
        input_dev->id.version = 0x0100;
        input_dev->dev.parent = &serio->dev;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
        input_dev->keycode = nkbd->keycode;
        input_dev->keycodesize = sizeof(unsigned char);
        input_dev->keycodemax = ARRAY_SIZE(nkbd_keycode);
index 76f1969552c5e453c93a3db263e1d7d834c66061..babc913d5492b617b388ee3eb7781ce0facd535e 100644 (file)
@@ -4,7 +4,7 @@
  * OMAP Keypad Driver
  *
  * Copyright (C) 2003 Nokia Corporation
- * Written by Timo Teräs <ext-timo.teras@nokia.com>
+ * Written by Timo Teräs <ext-timo.teras@nokia.com>
  *
  * Added support for H2 & H3 Keypad
  * Copyright (C) 2004 Texas Instruments
@@ -481,6 +481,6 @@ static void __exit omap_kp_exit(void)
 module_init(omap_kp_init);
 module_exit(omap_kp_exit);
 
-MODULE_AUTHOR("Timo Teräs");
+MODULE_AUTHOR("Timo Teräs");
 MODULE_DESCRIPTION("OMAP Keypad Driver");
 MODULE_LICENSE("GPL");
index b7061aa38816d13b1a9469706cb34e9b4c3d5d88..bdd64ee4c5c8fa5187cfce8cb3f718dd7b5f4a3c 100644 (file)
@@ -183,8 +183,9 @@ static int __devinit pxakbd_probe(struct platform_device *pdev)
        input_dev->close = pxakbd_close;
        input_dev->dev.parent = &pdev->dev;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_REL);
-       input_dev->relbit[LONG(REL_WHEEL)] = BIT(REL_WHEEL);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) |
+               BIT_MASK(EV_REL);
+       input_dev->relbit[BIT_WORD(REL_WHEEL)] = BIT_MASK(REL_WHEEL);
        for (row = 0; row < pdata->nr_rows; row++) {
                for (col = 0; col < pdata->nr_cols; col++) {
                        int code = pdata->keycodes[row][col];
index 41b80385476c82fd67a170a12dae1eb5f6e2f34e..410d78a774d03c2eab0ce95a1fd608f73df09436 100644 (file)
@@ -381,7 +381,8 @@ static int __init spitzkbd_probe(struct platform_device *dev)
        input_dev->id.product = 0x0001;
        input_dev->id.version = 0x0100;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) |
+               BIT_MASK(EV_PWR) | BIT_MASK(EV_SW);
        input_dev->keycode = spitzkbd->keycode;
        input_dev->keycodesize = sizeof(unsigned char);
        input_dev->keycodemax = ARRAY_SIZE(spitzkbd_keycode);
index b44b0684d5439e7e18ce620f5fe65a6962997261..7437219370b1a22e0695003d7318f596e60350d1 100644 (file)
@@ -110,7 +110,7 @@ static int skbd_connect(struct serio *serio, struct serio_driver *drv)
        input_dev->id.version = 0x0100;
        input_dev->dev.parent = &serio->dev;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
        input_dev->keycode = skbd->keycode;
        input_dev->keycodesize = sizeof(unsigned char);
        input_dev->keycodemax = ARRAY_SIZE(skbd_keycode);
index 1d4e39624cfecf08d1a4ef4f6a81fce8da3b5112..be0f5d19d0238590f2ffd219a5ef602e505fcb3c 100644 (file)
@@ -277,9 +277,11 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv)
 
        input_dev->event = sunkbd_event;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_SND) | BIT(EV_REP);
-       input_dev->ledbit[0] = BIT(LED_CAPSL) | BIT(LED_COMPOSE) | BIT(LED_SCROLLL) | BIT(LED_NUML);
-       input_dev->sndbit[0] = BIT(SND_CLICK) | BIT(SND_BELL);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_LED) |
+               BIT_MASK(EV_SND) | BIT_MASK(EV_REP);
+       input_dev->ledbit[0] = BIT_MASK(LED_CAPSL) | BIT_MASK(LED_COMPOSE) |
+               BIT_MASK(LED_SCROLLL) | BIT_MASK(LED_NUML);
+       input_dev->sndbit[0] = BIT_MASK(SND_CLICK) | BIT_MASK(SND_BELL);
 
        input_dev->keycode = sunkbd->keycode;
        input_dev->keycodesize = sizeof(unsigned char);
index f3a56eb58ed1fa05d6abf0c572cf34aef4019095..152a2c0705080f6432fcfb2f4fb4e27c7fa4d47e 100644 (file)
@@ -110,7 +110,7 @@ static int xtkbd_connect(struct serio *serio, struct serio_driver *drv)
        input_dev->id.version = 0x0100;
        input_dev->dev.parent = &serio->dev;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
        input_dev->keycode = xtkbd->keycode;
        input_dev->keycodesize = sizeof(unsigned char);
        input_dev->keycodemax = ARRAY_SIZE(xtkbd_keycode);
index 7acc6351bb44c9156c7afd93aa7671e4959a4a2a..8f5c7b90187de92b11a3ca005d04c532d934048d 100644 (file)
@@ -70,9 +70,9 @@ config INPUT_WISTRON_BTNS
        select LEDS_CLASS
        select CHECK_SIGNATURE
        help
-         Say Y here for support of Winstron laptop button interface, used on
+         Say Y here for support of Wistron laptop button interfaces, used on
          laptops of various brands, including Acer and Fujitsu-Siemens. If
-         available, mail and wifi leds will be controlable via /sys/class/leds.
+         available, mail and wifi LEDs will be controllable via /sys/class/leds.
 
          To compile this driver as a module, choose M here: the module will
          be called wistron_btns.
index 471aab206443bd8641d03e561aa58565ce5b3cb4..3a7937481ad8730d654835d4014557a364c70a3f 100644 (file)
@@ -662,10 +662,10 @@ static void ati_remote_input_init(struct ati_remote *ati_remote)
        struct input_dev *idev = ati_remote->idev;
        int i;
 
-       idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-       idev->keybit[LONG(BTN_MOUSE)] = ( BIT(BTN_LEFT) | BIT(BTN_RIGHT) |
-                                         BIT(BTN_SIDE) | BIT(BTN_EXTRA) );
-       idev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+       idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+       idev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+               BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA);
+       idev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
        for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++)
                if (ati_remote_tbl[i].type == EV_KEY)
                        set_bit(ati_remote_tbl[i].code, idev->keybit);
index 1031543e5c3f3e1f71e4e15bcae5ae600aa0f087..f2709b82485c181067b8a8fccab942a83bd425ed 100644 (file)
@@ -346,9 +346,10 @@ static int ati_remote2_input_init(struct ati_remote2 *ar2)
        ar2->idev = idev;
        input_set_drvdata(idev, ar2);
 
-       idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_REL);
-       idev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT);
-       idev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+       idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | BIT_MASK(EV_REL);
+       idev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+               BIT_MASK(BTN_RIGHT);
+       idev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
        for (i = 0; ati_remote2_key_table[i].key_code != KEY_RESERVED; i++)
                set_bit(ati_remote2_key_table[i].key_code, idev->keybit);
 
index e43e92fd9e2311f8a15c01f52b2eb769b003cb7c..4e3ad657ed8033b7ab917a1e4c886296b3722849 100644 (file)
@@ -81,7 +81,7 @@ static int atlas_acpi_button_add(struct acpi_device *device)
        input_dev->name = "Atlas ACPI button driver";
        input_dev->phys = "ASIM0000/atlas/input0";
        input_dev->id.bustype = BUS_HOST;
-       input_dev->evbit[LONG(EV_KEY)] = BIT(EV_KEY);
+       input_dev->evbit[BIT_WORD(EV_KEY)] = BIT_MASK(EV_KEY);
 
        set_bit(KEY_F1, input_dev->keybit);
        set_bit(KEY_F2, input_dev->keybit);
index 064b07936019c1f6465eb6aa1c1391666734a653..1aef97ed5e84575cc43225fd020038e28659f599 100644 (file)
@@ -104,7 +104,7 @@ static int __devinit cobalt_buttons_probe(struct platform_device *pdev)
        input->id.bustype = BUS_HOST;
        input->cdev.dev = &pdev->dev;
 
-       input->evbit[0] = BIT(EV_KEY);
+       input->evbit[0] = BIT_MASK(EV_KEY);
        for (i = 0; i < ARRAY_SIZE(buttons_map); i++) {
                set_bit(buttons_map[i].keycode, input->keybit);
                buttons_map[i].count = 0;
index e759944041abd7c3a92b0849df88e34e59a47b92..d2ade7443b7db832ba756992f16117ee19b63799 100644 (file)
@@ -109,8 +109,8 @@ static int __devinit ixp4xx_spkr_probe(struct platform_device *dev)
        input_dev->id.version = 0x0100;
        input_dev->dev.parent = &dev->dev;
 
-       input_dev->evbit[0] = BIT(EV_SND);
-       input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+       input_dev->evbit[0] = BIT_MASK(EV_SND);
+       input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
        input_dev->event = ixp4xx_spkr_event;
 
        err = request_irq(IRQ_IXP4XX_TIMER2, &ixp4xx_spkr_interrupt,
index 1bffc9fa98c270f3c8898a70a423602867846d9e..fd74347047dde8315cec4457caaf560b00e02b2a 100644 (file)
@@ -497,7 +497,7 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic
        usb_to_input_id(udev, &input_dev->id);
        input_dev->dev.parent = &interface->dev;
 
-       input_dev->evbit[0] = BIT(EV_KEY);              /* We will only report KEY events. */
+       input_dev->evbit[0] = BIT_MASK(EV_KEY);         /* We will only report KEY events. */
        for (i = 0; i < ARRAY_SIZE(keyspan_key_table); i++)
                if (keyspan_key_table[i] != KEY_RESERVED)
                        set_bit(keyspan_key_table[i], input_dev->keybit);
index e9f26e766b4d84606a5d0d79dc3f255a825773e9..0c64d9bb718ecf9250b84137fa581d1c552339a0 100644 (file)
@@ -65,8 +65,8 @@ static int __devinit m68kspkr_probe(struct platform_device *dev)
        input_dev->id.version = 0x0100;
        input_dev->dev.parent = &dev->dev;
 
-       input_dev->evbit[0] = BIT(EV_SND);
-       input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+       input_dev->evbit[0] = BIT_MASK(EV_SND);
+       input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
        input_dev->event = m68kspkr_event;
 
        err = input_register_device(input_dev);
index c19f77fbaf2a9ffb7646f03bfcb8493797830f93..4941a9e61e902967a410404f0b67171bdbdb51d5 100644 (file)
@@ -86,8 +86,8 @@ static int __devinit pcspkr_probe(struct platform_device *dev)
        pcspkr_dev->id.version = 0x0100;
        pcspkr_dev->dev.parent = &dev->dev;
 
-       pcspkr_dev->evbit[0] = BIT(EV_SND);
-       pcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+       pcspkr_dev->evbit[0] = BIT_MASK(EV_SND);
+       pcspkr_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
        pcspkr_dev->event = pcspkr_event;
 
        err = input_register_device(pcspkr_dev);
index 448a470d28f264d4ee6f666438d162a17225f694..7a7b8c7b96333b441bf9746b42e75d7a31f359d5 100644 (file)
@@ -363,10 +363,11 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
 
        input_dev->event = powermate_input_event;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_MSC);
-       input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0);
-       input_dev->relbit[LONG(REL_DIAL)] = BIT(REL_DIAL);
-       input_dev->mscbit[LONG(MSC_PULSELED)] = BIT(MSC_PULSELED);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) |
+               BIT_MASK(EV_MSC);
+       input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
+       input_dev->relbit[BIT_WORD(REL_DIAL)] = BIT_MASK(REL_DIAL);
+       input_dev->mscbit[BIT_WORD(MSC_PULSELED)] = BIT_MASK(MSC_PULSELED);
 
        /* get a handle to the interrupt data pipe */
        pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
index e36ec1d92be895a4279e12f88d7654d2eddc466d..a3637d870880a22a8d92befb7e75aa9272096c1d 100644 (file)
@@ -115,8 +115,8 @@ static int __devinit sparcspkr_probe(struct device *dev)
        input_dev->id.version = 0x0100;
        input_dev->dev.parent = dev;
 
-       input_dev->evbit[0] = BIT(EV_SND);
-       input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+       input_dev->evbit[0] = BIT_MASK(EV_SND);
+       input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
 
        input_dev->event = state->event;
 
index ab15880fd5663ab63cd0bbbc085dbea617eb7410..46279ef2b649b7f523006eeffa1bfd14e0173f77 100644 (file)
@@ -945,7 +945,7 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
        /* input_dev->event = input_ev; TODO */
 
        /* register available key events */
-       input_dev->evbit[0] = BIT(EV_KEY);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY);
        for (i = 0; i < 256; i++) {
                int k = map_p1k_to_key(i);
                if (k >= 0) {
index 64d70a9b714c9d84572f5c39d5f98b7a60f9d5b9..2b5ed119c9a90e9b5d66245eebfe9fcc1e11a197 100644 (file)
@@ -455,24 +455,25 @@ int alps_init(struct psmouse *psmouse)
        if (alps_hw_init(psmouse, &version))
                goto init_fail;
 
-       dev1->evbit[LONG(EV_KEY)] |= BIT(EV_KEY);
-       dev1->keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH);
-       dev1->keybit[LONG(BTN_TOOL_FINGER)] |= BIT(BTN_TOOL_FINGER);
-       dev1->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+       dev1->evbit[BIT_WORD(EV_KEY)] |= BIT_MASK(EV_KEY);
+       dev1->keybit[BIT_WORD(BTN_TOUCH)] |= BIT_MASK(BTN_TOUCH);
+       dev1->keybit[BIT_WORD(BTN_TOOL_FINGER)] |= BIT_MASK(BTN_TOOL_FINGER);
+       dev1->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) |
+               BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
 
-       dev1->evbit[LONG(EV_ABS)] |= BIT(EV_ABS);
+       dev1->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS);
        input_set_abs_params(dev1, ABS_X, 0, 1023, 0, 0);
        input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0);
        input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0);
 
        if (priv->i->flags & ALPS_WHEEL) {
-               dev1->evbit[LONG(EV_REL)] |= BIT(EV_REL);
-               dev1->relbit[LONG(REL_WHEEL)] |= BIT(REL_WHEEL);
+               dev1->evbit[BIT_WORD(EV_REL)] |= BIT_MASK(EV_REL);
+               dev1->relbit[BIT_WORD(REL_WHEEL)] |= BIT_MASK(REL_WHEEL);
        }
 
        if (priv->i->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
-               dev1->keybit[LONG(BTN_FORWARD)] |= BIT(BTN_FORWARD);
-               dev1->keybit[LONG(BTN_BACK)] |= BIT(BTN_BACK);
+               dev1->keybit[BIT_WORD(BTN_FORWARD)] |= BIT_MASK(BTN_FORWARD);
+               dev1->keybit[BIT_WORD(BTN_BACK)] |= BIT_MASK(BTN_BACK);
        }
 
        snprintf(priv->phys, sizeof(priv->phys), "%s/input1", psmouse->ps2dev.serio->phys);
@@ -483,9 +484,10 @@ int alps_init(struct psmouse *psmouse)
        dev2->id.product = PSMOUSE_ALPS;
        dev2->id.version = 0x0000;
 
-       dev2->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-       dev2->relbit[LONG(REL_X)] |= BIT(REL_X) | BIT(REL_Y);
-       dev2->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+       dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+       dev2->relbit[BIT_WORD(REL_X)] |= BIT_MASK(REL_X) | BIT_MASK(REL_Y);
+       dev2->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) |
+               BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
 
        if (input_register_device(priv->dev2))
                goto init_fail;
index 239a0e16d91abf215904584e72b3985c746e770b..a185ac78a42ca441a193229f2bd04ccf7cfd8079 100644 (file)
@@ -111,9 +111,10 @@ static int __init amimouse_init(void)
        amimouse_dev->id.product = 0x0002;
        amimouse_dev->id.version = 0x0100;
 
-       amimouse_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-       amimouse_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
-       amimouse_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+       amimouse_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+       amimouse_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
+       amimouse_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
+               BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
        amimouse_dev->open = amimouse_open;
        amimouse_dev->close = amimouse_close;
 
index 0117817bf538c5ce36511965b08134b550aa5c3a..f132702d137d1c3810ef01b3080dd33301ef1b87 100644 (file)
@@ -504,25 +504,22 @@ static void atp_complete(struct urb* urb)
                memset(dev->xy_acc, 0, sizeof(dev->xy_acc));
        }
 
-       /* Geyser 3 will continue to send packets continually after
+       input_report_key(dev->input, BTN_LEFT, key);
+       input_sync(dev->input);
+
+       /* Many Geysers will continue to send packets continually after
           the first touch unless reinitialised. Do so if it's been
           idle for a while in order to avoid waking the kernel up
           several hundred times a second */
 
-       if (atp_is_geyser_3(dev)) {
-               if (!x && !y && !key) {
-                       dev->idlecount++;
-                       if (dev->idlecount == 10) {
-                               dev->valid = 0;
-                               schedule_work(&dev->work);
-                       }
+       if (!x && !y && !key) {
+               dev->idlecount++;
+               if (dev->idlecount == 10) {
+                       dev->valid = 0;
+                       schedule_work(&dev->work);
                }
-               else
-                       dev->idlecount = 0;
-       }
-
-       input_report_key(dev->input, BTN_LEFT, key);
-       input_sync(dev->input);
+       } else
+               dev->idlecount = 0;
 
 exit:
        retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
index c8c7244b48a1bae505aab6b5e70f48657ad30dbb..98a3561d4b054f21633433b4f12d6e1367a94f44 100644 (file)
@@ -137,9 +137,10 @@ static int __init atamouse_init(void)
        atamouse_dev->id.product = 0x0002;
        atamouse_dev->id.version = 0x0100;
 
-       atamouse_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-       atamouse_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
-       atamouse_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+       atamouse_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+       atamouse_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
+       atamouse_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
+               BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
        atamouse_dev->open = atamouse_open;
        atamouse_dev->close = atamouse_close;
 
index 449bf4dcbbcc726cc7546edbbeb122078d039a1c..27f88fbb7136c0a40f6257db82266f105fee0a7e 100644 (file)
@@ -298,12 +298,12 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
        idd = ptr->idd + 1;
        txt = "unknown";
        if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) {
-               ptr->dev->evbit[0] = BIT(EV_REL);
+               ptr->dev->evbit[0] = BIT_MASK(EV_REL);
                txt = "relative";
        }
 
        if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_ABS) {
-               ptr->dev->evbit[0] = BIT(EV_ABS);
+               ptr->dev->evbit[0] = BIT_MASK(EV_ABS);
                txt = "absolute";
        }
        if (!ptr->dev->evbit[0])
@@ -311,7 +311,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
 
        ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd);
        if (ptr->nbtn)
-               ptr->dev->evbit[0] |= BIT(EV_KEY);
+               ptr->dev->evbit[0] |= BIT_MASK(EV_KEY);
 
        naxsets = HIL_IDD_NUM_AXSETS(*idd);
        ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd);
index 79b624fe8994ff2d513b91a984840df869704e80..655a392174322605a37cf6d2fda29f3cf02c1d32 100644 (file)
@@ -163,9 +163,10 @@ static int __init inport_init(void)
        inport_dev->id.product = 0x0001;
        inport_dev->id.version = 0x0100;
 
-       inport_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-       inport_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
-       inport_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+       inport_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+       inport_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
+               BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
+       inport_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
 
        inport_dev->open  = inport_open;
        inport_dev->close = inport_close;
index d7de4c53b3d8cb8cd853c14ae382f5f47f2fda83..9ec57d80186e43b7f776ec3b9aed0c7c385ce625 100644 (file)
@@ -270,9 +270,10 @@ static int lifebook_create_relative_device(struct psmouse *psmouse)
        dev2->id.version = 0x0000;
        dev2->dev.parent = &psmouse->ps2dev.serio->dev;
 
-       dev2->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-       dev2->relbit[LONG(REL_X)] = BIT(REL_X) | BIT(REL_Y);
-       dev2->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT);
+       dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+       dev2->relbit[BIT_WORD(REL_X)] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
+       dev2->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
+               BIT_MASK(BTN_RIGHT);
 
        error = input_register_device(priv->dev2);
        if (error)
@@ -295,9 +296,9 @@ int lifebook_init(struct psmouse *psmouse)
        if (lifebook_absolute_mode(psmouse))
                return -1;
 
-       dev1->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
+       dev1->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
        dev1->relbit[0] = 0;
-       dev1->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+       dev1->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
        input_set_abs_params(dev1, ABS_X, 0, max_coord, 0, 0);
        input_set_abs_params(dev1, ABS_Y, 0, max_coord, 0, 0);
 
index 26c3b2e2ca94a3eff06a3ef800f59f78a19f5c58..b23a4f3ea5cdcf48d5e09cf789ba610940a3f68f 100644 (file)
@@ -156,9 +156,10 @@ static int __init logibm_init(void)
        logibm_dev->id.product = 0x0001;
        logibm_dev->id.version = 0x0100;
 
-       logibm_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-       logibm_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
-       logibm_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+       logibm_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+       logibm_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
+               BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
+       logibm_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
 
        logibm_dev->open  = logibm_open;
        logibm_dev->close = logibm_close;
index 05d992e514f0bd5452dc0a6f0c9161b01a01c753..8991ab0b4fe3b3caed329b0a32aea07d29c6d303 100644 (file)
@@ -144,9 +144,9 @@ static int __init pc110pad_init(void)
        pc110pad_dev->id.product = 0x0001;
        pc110pad_dev->id.version = 0x0100;
 
-       pc110pad_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-       pc110pad_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
-       pc110pad_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+       pc110pad_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+       pc110pad_dev->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y);
+       pc110pad_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 
        pc110pad_dev->absmax[ABS_X] = 0x1ff;
        pc110pad_dev->absmax[ABS_Y] = 0x0ff;
index 0735257565329aa590096f1f9bc8fd0ab49e665b..21a9c0b69a1f461befa62691f0a35baaa99641a6 100644 (file)
@@ -906,7 +906,7 @@ static void psmouse_activate(struct psmouse *psmouse)
 
 /*
  * psmouse_deactivate() puts the mouse into poll mode so that we don't get motion
- * reports from it unless we explicitely request it.
+ * reports from it unless we explicitly request it.
  */
 
 static void psmouse_deactivate(struct psmouse *psmouse)
@@ -1115,9 +1115,10 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, const struct psmouse
 
        input_dev->dev.parent = &psmouse->ps2dev.serio->dev;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-       input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
-       input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+       input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+               BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
+       input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
 
        psmouse->set_rate = psmouse_set_rate;
        psmouse->set_resolution = psmouse_set_resolution;
index 355efd0423e7df49cd5cbbf35b26eb3da774adf5..18a48636ba4a96f88c8b7f253fd9aaf894e593b6 100644 (file)
@@ -78,9 +78,10 @@ static int __init rpcmouse_init(void)
        rpcmouse_dev->id.product = 0x0001;
        rpcmouse_dev->id.version = 0x0100;
 
-       rpcmouse_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-       rpcmouse_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
-       rpcmouse_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+       rpcmouse_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+       rpcmouse_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
+               BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
+       rpcmouse_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
 
        rpcmouse_lastx = (short) iomd_readl(IOMD_MOUSEX);
        rpcmouse_lasty = (short) iomd_readl(IOMD_MOUSEY);
index 77b8ee2b9651750728fe47409042ab0710057cc1..ed917bfd086aa13dbafc56bf19a971ee906307e3 100644 (file)
@@ -268,9 +268,10 @@ static int sermouse_connect(struct serio *serio, struct serio_driver *drv)
        input_dev->id.version = 0x0100;
        input_dev->dev.parent = &serio->dev;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-       input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT);
-       input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+       input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+               BIT_MASK(BTN_RIGHT);
+       input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
 
        if (c & 0x01) set_bit(BTN_MIDDLE, input_dev->keybit);
        if (c & 0x02) set_bit(BTN_SIDE, input_dev->keybit);
index 7b977fd23571737ee3e49cb70ee4174e4c083376..3fadb2accac0264baa3dc2790241fd5e4ae1783a 100644 (file)
@@ -85,7 +85,7 @@ int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties)
                return -ENODEV;
 
        if (set_properties) {
-               dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+               dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
                set_bit(BTN_TOUCH, dev->keybit);
                input_set_abs_params(dev, ABS_X, 0, TOUCHKIT_MAX_XC, 0, 0);
                input_set_abs_params(dev, ABS_Y, 0, TOUCHKIT_MAX_YC, 0, 0);
index 4a321576f34518181b1d3b04a201746956d32561..404eedd5ffa2b7e039db5c7508971450e7ae1a4c 100644 (file)
@@ -330,7 +330,7 @@ vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse)
 
        /*
         * Check for Power-On-Reset packets. These are sent out
-        * after plugging the mouse in, or when explicitely
+        * after plugging the mouse in, or when explicitly
         * requested by sending 'T'.
         *
         * [0]: 1       0       1       0       R3      R2      R1      R0
index 79146d6ed2ab2d392988d196d64d4f9d6c0e92bf..78c3ea75da2a056b2799045c6c2329f5834a8705 100644 (file)
@@ -998,34 +998,36 @@ static const struct input_device_id mousedev_ids[] = {
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
                                INPUT_DEVICE_ID_MATCH_KEYBIT |
                                INPUT_DEVICE_ID_MATCH_RELBIT,
-               .evbit = { BIT(EV_KEY) | BIT(EV_REL) },
-               .keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) },
-               .relbit = { BIT(REL_X) | BIT(REL_Y) },
+               .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) },
+               .keybit = { [BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) },
+               .relbit = { BIT_MASK(REL_X) | BIT_MASK(REL_Y) },
        },      /* A mouse like device, at least one button,
                   two relative axes */
        {
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
                                INPUT_DEVICE_ID_MATCH_RELBIT,
-               .evbit = { BIT(EV_KEY) | BIT(EV_REL) },
-               .relbit = { BIT(REL_WHEEL) },
+               .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) },
+               .relbit = { BIT_MASK(REL_WHEEL) },
        },      /* A separate scrollwheel */
        {
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
                                INPUT_DEVICE_ID_MATCH_KEYBIT |
                                INPUT_DEVICE_ID_MATCH_ABSBIT,
-               .evbit = { BIT(EV_KEY) | BIT(EV_ABS) },
-               .keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) },
-               .absbit = { BIT(ABS_X) | BIT(ABS_Y) },
+               .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) },
+               .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
+               .absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) },
        },      /* A tablet like device, at least touch detection,
                   two absolute axes */
        {
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
                                INPUT_DEVICE_ID_MATCH_KEYBIT |
                                INPUT_DEVICE_ID_MATCH_ABSBIT,
-               .evbit = { BIT(EV_KEY) | BIT(EV_ABS) },
-               .keybit = { [LONG(BTN_TOOL_FINGER)] = BIT(BTN_TOOL_FINGER) },
-               .absbit = { BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) |
-                               BIT(ABS_TOOL_WIDTH) },
+               .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) },
+               .keybit = { [BIT_WORD(BTN_TOOL_FINGER)] =
+                               BIT_MASK(BTN_TOOL_FINGER) },
+               .absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
+                               BIT_MASK(ABS_PRESSURE) |
+                               BIT_MASK(ABS_TOOL_WIDTH) },
        },      /* A touchpad */
 
        { },    /* Terminating entry */
index 11dafc0ee9942145b937a85bbebe27578ed073c6..1a0cea3c52945fca48aa363d2f636030d715ca77 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/err.h>
 #include <linux/rcupdate.h>
 #include <linux/platform_device.h>
+#include <linux/i8042.h>
 
 #include <asm/io.h>
 
@@ -208,7 +209,7 @@ static int __i8042_command(unsigned char *param, int command)
        return 0;
 }
 
-static int i8042_command(unsigned char *param, int command)
+int i8042_command(unsigned char *param, int command)
 {
        unsigned long flags;
        int retval;
@@ -219,6 +220,7 @@ static int i8042_command(unsigned char *param, int command)
 
        return retval;
 }
+EXPORT_SYMBOL(i8042_command);
 
 /*
  * i8042_kbd_write() sends a byte out through the keyboard interface.
index b3eb7a72d96114653799339dce4d9040391f4abd..dd22d91f8b39bd1c16abf0a755096fb7af44147f 100644 (file)
 #define I8042_CTR_AUXDIS       0x20
 #define I8042_CTR_XLATE                0x40
 
-/*
- * Commands.
- */
-
-#define I8042_CMD_CTL_RCTR     0x0120
-#define I8042_CMD_CTL_WCTR     0x1060
-#define I8042_CMD_CTL_TEST     0x01aa
-
-#define I8042_CMD_KBD_DISABLE  0x00ad
-#define I8042_CMD_KBD_ENABLE   0x00ae
-#define I8042_CMD_KBD_TEST     0x01ab
-#define I8042_CMD_KBD_LOOP     0x11d2
-
-#define I8042_CMD_AUX_DISABLE  0x00a7
-#define I8042_CMD_AUX_ENABLE   0x00a8
-#define I8042_CMD_AUX_TEST     0x01a9
-#define I8042_CMD_AUX_SEND     0x10d4
-#define I8042_CMD_AUX_LOOP     0x11d3
-
-#define I8042_CMD_MUX_PFX      0x0090
-#define I8042_CMD_MUX_SEND     0x1090
-
 /*
  * Return codes.
  */
index b3bc15acd3f5604979874f4311c5f56daf8fd1eb..7f5293828fbff2e5325c612a93f3ff449cdfa958 100644 (file)
@@ -387,9 +387,8 @@ static int serio_thread(void *nothing)
        set_freezable();
        do {
                serio_handle_event();
-               wait_event_interruptible(serio_wait,
+               wait_event_freezable(serio_wait,
                        kthread_should_stop() || !list_empty(&serio_event_list));
-               try_to_freeze();
        } while (!kthread_should_stop());
 
        printk(KERN_DEBUG "serio: kseriod exiting\n");
index dd2310458c46a87aafaf0d2873a54f535dde0781..b973d0ef6d16ae6d332838204a57a20bf184d575 100644 (file)
@@ -192,10 +192,14 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
        input_dev->open = usb_acecad_open;
        input_dev->close = usb_acecad_close;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-       input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
-       input_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
-       input_dev->keybit[LONG(BTN_DIGI)] = BIT(BTN_TOOL_PEN) |BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+       input_dev->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
+               BIT_MASK(ABS_PRESSURE);
+       input_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
+               BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
+       input_dev->keybit[BIT_WORD(BTN_DIGI)] = BIT_MASK(BTN_TOOL_PEN) |
+               BIT_MASK(BTN_TOUCH) | BIT_MASK(BTN_STYLUS) |
+               BIT_MASK(BTN_STYLUS2);
 
        switch (id->driver_info) {
                case 0:
index b2ca10f2fe0e48b74d8cf22739f8623561a09c7c..d2c6da264722576ddee43d1041ed641fe25af422 100644 (file)
@@ -573,10 +573,12 @@ static void gtco_setup_caps(struct input_dev *inputdev)
        struct gtco *device = input_get_drvdata(inputdev);
 
        /* Which events */
-       inputdev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC);
+       inputdev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) |
+               BIT_MASK(EV_MSC);
 
        /* Misc event menu block */
-       inputdev->mscbit[0] = BIT(MSC_SCAN)|BIT(MSC_SERIAL)|BIT(MSC_RAW) ;
+       inputdev->mscbit[0] = BIT_MASK(MSC_SCAN) | BIT_MASK(MSC_SERIAL) |
+               BIT_MASK(MSC_RAW);
 
        /* Absolute values based on HID report info */
        input_set_abs_params(inputdev, ABS_X, device->min_X, device->max_X,
index 91e6d00d4a43ffdc4a8a26e21ea1ca9bd6e9df90..1182fc133167ac203e2d5e52cc71201ce4108c24 100644 (file)
@@ -153,10 +153,13 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i
        input_dev->open = kbtab_open;
        input_dev->close = kbtab_close;
 
-       input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC);
-       input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
-       input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH);
-       input_dev->mscbit[0] |= BIT(MSC_SERIAL);
+       input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) |
+               BIT_MASK(EV_MSC);
+       input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) |
+               BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
+       input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) |
+               BIT_MASK(BTN_TOUCH);
+       input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL);
        input_set_abs_params(input_dev, ABS_X, 0, 0x2000, 4, 0);
        input_set_abs_params(input_dev, ABS_Y, 0, 0x1750, 4, 0);
        input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0xff, 0, 0);
index 064e123c9b766170be132d2bb894b535d168b961..d64b1ea136b35c1a79ee18ca658f717e27f408f2 100644 (file)
@@ -140,48 +140,58 @@ static void wacom_close(struct input_dev *dev)
 
 void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 {
-       input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_1) | BIT(BTN_5);
+       input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_1) |
+               BIT_MASK(BTN_5);
        input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);
 }
 
 void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 {
-       input_dev->evbit[0] |= BIT(EV_MSC);
-       input_dev->mscbit[0] |= BIT(MSC_SERIAL);
-       input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER);
-       input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_4);
+       input_dev->evbit[0] |= BIT_MASK(EV_MSC);
+       input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL);
+       input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER);
+       input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_0) |
+               BIT_MASK(BTN_4);
 }
 
 void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 {
-       input_dev->evbit[0] |= BIT(EV_REL);
-       input_dev->relbit[0] |= BIT(REL_WHEEL);
-       input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
-       input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2);
+       input_dev->evbit[0] |= BIT_MASK(EV_REL);
+       input_dev->relbit[0] |= BIT_MASK(REL_WHEEL);
+       input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) |
+               BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
+       input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) |
+               BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_STYLUS2);
        input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0);
 }
 
 void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 {
-       input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER);
-       input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3);
+       input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER);
+       input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_0) |
+               BIT_MASK(BTN_1) | BIT_MASK(BTN_2) | BIT_MASK(BTN_3);
        input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0);
 }
 
 void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 {
-       input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7);
+       input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_4) |
+               BIT_MASK(BTN_5) | BIT_MASK(BTN_6) | BIT_MASK(BTN_7);
        input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0);
 }
 
 void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 {
-       input_dev->evbit[0] |= BIT(EV_MSC) | BIT(EV_REL);
-       input_dev->mscbit[0] |= BIT(MSC_SERIAL);
-       input_dev->relbit[0] |= BIT(REL_WHEEL);
-       input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA);
-       input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOOL_BRUSH)
-               | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2);
+       input_dev->evbit[0] |= BIT_MASK(EV_MSC) | BIT_MASK(EV_REL);
+       input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL);
+       input_dev->relbit[0] |= BIT_MASK(REL_WHEEL);
+       input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) |
+               BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE) |
+               BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA);
+       input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) |
+               BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_TOOL_BRUSH) |
+               BIT_MASK(BTN_TOOL_PENCIL) | BIT_MASK(BTN_TOOL_AIRBRUSH) |
+               BIT_MASK(BTN_TOOL_LENS) | BIT_MASK(BTN_STYLUS2);
        input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0);
        input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0);
        input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0);
@@ -192,12 +202,13 @@ void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 
 void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 {
-       input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER);
+       input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_STYLUS2) |
+               BIT_MASK(BTN_TOOL_RUBBER);
 }
 
 void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 {
-       input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER);
+       input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER);
 }
 
 static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
@@ -243,12 +254,13 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
        input_dev->open = wacom_open;
        input_dev->close = wacom_close;
 
-       input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS);
-       input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS);
+       input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+       input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) |
+               BIT_MASK(BTN_TOUCH) | BIT_MASK(BTN_STYLUS);
        input_set_abs_params(input_dev, ABS_X, 0, wacom_wac->features->x_max, 4, 0);
        input_set_abs_params(input_dev, ABS_Y, 0, wacom_wac->features->y_max, 4, 0);
        input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom_wac->features->pressure_max, 0, 0);
-       input_dev->absbit[LONG(ABS_MISC)] |= BIT(ABS_MISC);
+       input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC);
 
        wacom_init_input_dev(input_dev, wacom_wac);
 
index e3e0baa1a158b4e907a5cb5e2f3aedc4654722e3..fa8442b6241c11a343b7fe1413b8e2202c0c60c4 100644 (file)
@@ -202,6 +202,7 @@ config TOUCHSCREEN_USB_COMPOSITE
          - DMC TSC-10/25
          - IRTOUCHSYSTEMS/UNITOP
          - IdealTEK URTC1000
+         - GoTop Super_Q2/GogoPen/PenPower tablets
 
          Have a look at <http://linux.chapter7.ch/touchkit/> for
          a usage description and the required user-space stuff.
@@ -259,4 +260,9 @@ config TOUCHSCREEN_USB_GENERAL_TOUCH
        bool "GeneralTouch Touchscreen device support" if EMBEDDED
        depends on TOUCHSCREEN_USB_COMPOSITE
 
+config TOUCHSCREEN_USB_GOTOP
+       default y
+       bool "GoTop Super_Q2/GogoPen/PenPower tablet device support" if EMBEDDED
+       depends on TOUCHSCREEN_USB_COMPOSITE
+
 endif
index 51ae4fb7d123b2882380f1ec78531949c70c59a9..f59aecf5ec1565fe4959308edc8cc034c3a0a9a3 100644 (file)
@@ -917,8 +917,8 @@ static int __devinit ads7846_probe(struct spi_device *spi)
        input_dev->phys = ts->phys;
        input_dev->dev.parent = &spi->dev;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-       input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+       input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
        input_set_abs_params(input_dev, ABS_X,
                        pdata->x_min ? : 0,
                        pdata->x_max ? : MAX_12BIT,
index e6a31d118786c67c76913f7270e2761eecd69a8a..b1b2e07bf080b3cb348726e3c7a3aff935ad7725 100644 (file)
@@ -302,8 +302,8 @@ static int __init corgits_probe(struct platform_device *pdev)
        input_dev->id.version = 0x0100;
        input_dev->dev.parent = &pdev->dev;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-       input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+       input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
        input_set_abs_params(input_dev, ABS_X, X_AXIS_MIN, X_AXIS_MAX, 0, 0);
        input_set_abs_params(input_dev, ABS_Y, Y_AXIS_MIN, Y_AXIS_MAX, 0, 0);
        input_set_abs_params(input_dev, ABS_PRESSURE, PRESSURE_MIN, PRESSURE_MAX, 0, 0);
index 557d781719f12b631c6dd940b109c91be04cef9b..d20689cdbd5d63665601e9e00baca7ffd08eb42d 100644 (file)
@@ -320,8 +320,8 @@ static int elo_connect(struct serio *serio, struct serio_driver *drv)
        input_dev->id.version = 0x0100;
        input_dev->dev.parent = &serio->dev;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-       input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+       input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 
        serio_set_drvdata(serio, elo);
        err = serio_open(serio, drv);
index daf7a4afc9352e08afe3e04637a18bd8698382eb..80b21800355f10d255a8e8f06fdad8a3b37270fa 100644 (file)
@@ -122,8 +122,8 @@ static int fujitsu_connect(struct serio *serio, struct serio_driver *drv)
        input_dev->id.vendor = SERIO_FUJITSU;
        input_dev->id.product = 0;
        input_dev->id.version = 0x0100;
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-       input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+       input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 
        input_set_abs_params(input_dev, ABS_X, 0, 4096, 0, 0);
        input_set_abs_params(input_dev, ABS_Y, 0, 4096, 0, 0);
index 39d602600d7cfe1e7a89d5f9f4f23652d8ad90d9..a48a15868c4ade3b1067a97f955d819df739c831 100644 (file)
@@ -137,8 +137,8 @@ static int gunze_connect(struct serio *serio, struct serio_driver *drv)
        input_dev->id.product = 0x0051;
        input_dev->id.version = 0x0100;
        input_dev->dev.parent = &serio->dev;
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-       input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+       input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
        input_set_abs_params(input_dev, ABS_X, 24, 1000, 0, 0);
        input_set_abs_params(input_dev, ABS_Y, 24, 1000, 0, 0);
 
index 09ed7803cb8fcd07143bd3c1dfb3d571fb0efb58..2ae6c6016a8665d79eb4f6dd63d76a3675230f30 100644 (file)
@@ -373,8 +373,9 @@ static int h3600ts_connect(struct serio *serio, struct serio_driver *drv)
 
        input_dev->event = h3600ts_event;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_LED) | BIT(EV_PWR);
-       input_dev->ledbit[0] = BIT(LED_SLEEP);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) |
+               BIT_MASK(EV_LED) | BIT_MASK(EV_PWR);
+       input_dev->ledbit[0] = BIT_MASK(LED_SLEEP);
        input_set_abs_params(input_dev, ABS_X, 60, 985, 0, 0);
        input_set_abs_params(input_dev, ABS_Y, 35, 1024, 0, 0);
 
index 1a15475aedfcc269d5bbfc033c15db3025a3dd5b..c38d4e0f95c6a093e7bf009fcb662160b97a3a8e 100644 (file)
@@ -81,8 +81,8 @@ static int __init hp680_ts_init(void)
        if (!hp680_ts_dev)
                return -ENOMEM;
 
-       hp680_ts_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
-       hp680_ts_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+       hp680_ts_dev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
+       hp680_ts_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 
        input_set_abs_params(hp680_ts_dev, ABS_X,
                HP680_TS_ABS_X_MIN, HP680_TS_ABS_X_MAX, 0, 0);
index 44140feeffc503428a54399b591f1628f3842010..80a65886870624300be79bfb008f4add780d68e4 100644 (file)
@@ -186,8 +186,8 @@ static int __init mk712_init(void)
        mk712_dev->open    = mk712_open;
        mk712_dev->close   = mk712_close;
 
-       mk712_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-       mk712_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+       mk712_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+       mk712_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
        input_set_abs_params(mk712_dev, ABS_X, 0, 0xfff, 88, 0);
        input_set_abs_params(mk712_dev, ABS_Y, 0, 0xfff, 88, 0);
 
index 4ec3b1f940c8f424560f4d5ebcc1bb060ce44162..9077228418b7028242caa03cc99292ee8f2c62cd 100644 (file)
@@ -151,8 +151,8 @@ static int mtouch_connect(struct serio *serio, struct serio_driver *drv)
        input_dev->id.product = 0;
        input_dev->id.version = 0x0100;
        input_dev->dev.parent = &serio->dev;
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-       input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+       input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
        input_set_abs_params(mtouch->dev, ABS_X, MTOUCH_MIN_XC, MTOUCH_MAX_XC, 0, 0);
        input_set_abs_params(mtouch->dev, ABS_Y, MTOUCH_MIN_YC, MTOUCH_MAX_YC, 0, 0);
 
index f2c0d3c7149cacc684a3cb30f20ba159dbd1ac00..c7f9cebebbb6dbe5376e53407b44d4c41370aee8 100644 (file)
@@ -113,8 +113,8 @@ static int pm_connect(struct serio *serio, struct serio_driver *drv)
        input_dev->id.version = 0x0100;
        input_dev->dev.parent = &serio->dev;
 
-        input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-        input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+        input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+        input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
         input_set_abs_params(pm->dev, ABS_X, 0, 0x3ff, 0, 0);
         input_set_abs_params(pm->dev, ABS_Y, 0, 0x3ff, 0, 0);
 
index 3def7bb1df44641c569880e64f389613e2ad3425..3a5c142c2a78a6fd6b0e55cbf79c5c57bf236999 100644 (file)
@@ -125,8 +125,8 @@ static int tr_connect(struct serio *serio, struct serio_driver *drv)
        input_dev->id.product = 0;
        input_dev->id.version = 0x0100;
        input_dev->dev.parent = &serio->dev;
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-       input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+       input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
        input_set_abs_params(tr->dev, ABS_X, TR_MIN_XC, TR_MAX_XC, 0, 0);
        input_set_abs_params(tr->dev, ABS_Y, TR_MIN_YC, TR_MAX_YC, 0, 0);
 
index ac4bdcf186660a8c040ea5604648a59438061808..763a656a59f8270929f2366f710147ef2339e43e 100644 (file)
@@ -132,8 +132,8 @@ static int tw_connect(struct serio *serio, struct serio_driver *drv)
        input_dev->id.product = 0;
        input_dev->id.version = 0x0100;
        input_dev->dev.parent = &serio->dev;
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-       input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+       input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
        input_set_abs_params(tw->dev, ABS_X, TW_MIN_XC, TW_MAX_XC, 0, 0);
        input_set_abs_params(tw->dev, ABS_Y, TW_MIN_YC, TW_MAX_YC, 0, 0);
 
index 86aed64ec0fb9dd54c5ed3ec1b134f62a2615d6e..7549939b9535634de87ddb09a829b186758303e0 100644 (file)
@@ -333,10 +333,9 @@ static int ucb1400_ts_thread(void *_ucb)
                        timeout = msecs_to_jiffies(10);
                }
 
-               wait_event_interruptible_timeout(ucb->ts_wait,
+               wait_event_freezable_timeout(ucb->ts_wait,
                        ucb->irq_pending || ucb->ts_restart || kthread_should_stop(),
                        timeout);
-               try_to_freeze();
        }
 
        /* Send the "pen off" if we are stopping with the pen still active */
@@ -518,7 +517,7 @@ static int ucb1400_ts_probe(struct device *dev)
        idev->id.product        = id;
        idev->open              = ucb1400_ts_open;
        idev->close             = ucb1400_ts_close;
-       idev->evbit[0]          = BIT(EV_ABS);
+       idev->evbit[0]          = BIT_MASK(EV_ABS);
 
        ucb1400_adc_enable(ucb);
        x_res = ucb1400_ts_read_xres(ucb);
index 9fb3d5c309998162c5f14d40c6587e95c95395a5..19055e7381f8423b52e14763c43281b7672ccb09 100644 (file)
@@ -11,8 +11,9 @@
  *  - DMC TSC-10/25
  *  - IRTOUCHSYSTEMS/UNITOP
  *  - IdealTEK URTC1000
+ *  - GoTop Super_Q2/GogoPen/PenPower tablets
  *
- * Copyright (C) 2004-2006 by Daniel Ritz <daniel.ritz@gmx.ch>
+ * Copyright (C) 2004-2007 by Daniel Ritz <daniel.ritz@gmx.ch>
  * Copyright (C) by Todd E. Johnson (mtouchusb.c)
  *
  * This program is free software; you can redistribute it and/or
@@ -115,6 +116,7 @@ enum {
        DEVTYPE_IRTOUCH,
        DEVTYPE_IDEALTEK,
        DEVTYPE_GENERAL_TOUCH,
+       DEVTYPE_GOTOP,
 };
 
 static struct usb_device_id usbtouch_devices[] = {
@@ -168,6 +170,12 @@ static struct usb_device_id usbtouch_devices[] = {
        {USB_DEVICE(0x0dfc, 0x0001), .driver_info = DEVTYPE_GENERAL_TOUCH},
 #endif
 
+#ifdef CONFIG_TOUCHSCREEN_USB_GOTOP
+       {USB_DEVICE(0x08f2, 0x007f), .driver_info = DEVTYPE_GOTOP},
+       {USB_DEVICE(0x08f2, 0x00ce), .driver_info = DEVTYPE_GOTOP},
+       {USB_DEVICE(0x08f2, 0x00f4), .driver_info = DEVTYPE_GOTOP},
+#endif
+
        {}
 };
 
@@ -500,6 +508,20 @@ static int general_touch_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
 }
 #endif
 
+/*****************************************************************************
+ * GoTop Part
+ */
+#ifdef CONFIG_TOUCHSCREEN_USB_GOTOP
+static int gotop_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+{
+       dev->x = ((pkt[1] & 0x38) << 4) | pkt[2];
+       dev->y = ((pkt[1] & 0x07) << 7) | pkt[3];
+       dev->touch = pkt[0] & 0x01;
+       return 1;
+}
+#endif
+
+
 /*****************************************************************************
  * the different device descriptors
  */
@@ -623,9 +645,19 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
                .max_yc         = 0x0500,
                .rept_size      = 7,
                .read_data      = general_touch_read_data,
-       }
+       },
 #endif
 
+#ifdef CONFIG_TOUCHSCREEN_USB_GOTOP
+       [DEVTYPE_GOTOP] = {
+               .min_xc         = 0x0,
+               .max_xc         = 0x03ff,
+               .min_yc         = 0x0,
+               .max_yc         = 0x03ff,
+               .rept_size      = 4,
+               .read_data      = gotop_read_data,
+       },
+#endif
 };
 
 
@@ -868,8 +900,8 @@ static int usbtouch_probe(struct usb_interface *intf,
        input_dev->open = usbtouch_open;
        input_dev->close = usbtouch_close;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-       input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+       input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
        input_set_abs_params(input_dev, ABS_X, type->min_xc, type->max_xc, 0, 0);
        input_set_abs_params(input_dev, ABS_Y, type->min_yc, type->max_yc, 0, 0);
        if (type->max_press)
index 09ea50dd3459d536a6a4f9414f6a56a8be3f2758..819ea85576a39be065e75ff71f721b25d14809fd 100644 (file)
@@ -126,7 +126,7 @@ act2000_isa_enable_irq(act2000_card * card)
 
 /*
  * Install interrupt handler, enable irq on card.
- * If irq is -1, choose next free irq, else irq is given explicitely.
+ * If irq is -1, choose next free irq, else irq is given explicitly.
  */
 int
 act2000_isa_config_irq(act2000_card * card, short irq)
index 6df336bdd5716881766c7c9039272c1f2b3a1b89..acd417197d03dd6f46078bff2eff31fb05bf5414 100644 (file)
@@ -534,7 +534,8 @@ int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src,
                        n = RBUFSIZE - tail;
                if (!n) {
                        dev_err(inbuf->cs->dev,
-                               "buffer overflow (%u bytes lost)", bytesleft);
+                               "buffer overflow (%u bytes lost)\n",
+                               bytesleft);
                        break;
                }
                if (n > bytesleft)
index 7a69a18d07e245f4a15cc10631262a37c568d67c..4484a6417235ec3c87de9cbe36313a7b015bfac2 100644 (file)
@@ -321,12 +321,15 @@ void b1_reset_ctr(struct capi_ctr *ctrl)
        avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
        avmcard *card = cinfo->card;
        unsigned int port = card->port;
+       unsigned long flags;
 
        b1_reset(port);
        b1_reset(port);
 
        memset(cinfo->version, 0, sizeof(cinfo->version));
+       spin_lock_irqsave(&card->lock, flags);
        capilib_release(&cinfo->ncci_head);
+       spin_unlock_irqrestore(&card->lock, flags);
        capi_ctr_reseted(ctrl);
 }
 
@@ -361,9 +364,8 @@ void b1_release_appl(struct capi_ctr *ctrl, u16 appl)
        unsigned int port = card->port;
        unsigned long flags;
 
-       capilib_release_appl(&cinfo->ncci_head, appl);
-
        spin_lock_irqsave(&card->lock, flags);
+       capilib_release_appl(&cinfo->ncci_head, appl);
        b1_put_byte(port, SEND_RELEASE);
        b1_put_word(port, appl);
        spin_unlock_irqrestore(&card->lock, flags);
@@ -380,27 +382,27 @@ u16 b1_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
        u8 subcmd = CAPIMSG_SUBCOMMAND(skb->data);
        u16 dlen, retval;
 
+       spin_lock_irqsave(&card->lock, flags);
        if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) {
                retval = capilib_data_b3_req(&cinfo->ncci_head,
                                             CAPIMSG_APPID(skb->data),
                                             CAPIMSG_NCCI(skb->data),
                                             CAPIMSG_MSGID(skb->data));
-               if (retval != CAPI_NOERROR) 
+               if (retval != CAPI_NOERROR) {
+                       spin_unlock_irqrestore(&card->lock, flags);
                        return retval;
+               }
 
                dlen = CAPIMSG_DATALEN(skb->data);
 
-               spin_lock_irqsave(&card->lock, flags);
                b1_put_byte(port, SEND_DATA_B3_REQ);
                b1_put_slice(port, skb->data, len);
                b1_put_slice(port, skb->data + len, dlen);
-               spin_unlock_irqrestore(&card->lock, flags);
        } else {
-               spin_lock_irqsave(&card->lock, flags);
                b1_put_byte(port, SEND_MESSAGE);
                b1_put_slice(port, skb->data, len);
-               spin_unlock_irqrestore(&card->lock, flags);
        }
+       spin_unlock_irqrestore(&card->lock, flags);
 
        dev_kfree_skb_any(skb);
        return CAPI_NOERROR;
@@ -534,17 +536,17 @@ irqreturn_t b1_interrupt(int interrupt, void *devptr)
 
                ApplId = (unsigned) b1_get_word(card->port);
                MsgLen = b1_get_slice(card->port, card->msgbuf);
-               spin_unlock_irqrestore(&card->lock, flags);
                if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) {
                        printk(KERN_ERR "%s: incoming packet dropped\n",
                                        card->name);
+                       spin_unlock_irqrestore(&card->lock, flags);
                } else {
                        memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
                        if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF)
                                capilib_data_b3_conf(&cinfo->ncci_head, ApplId,
                                                     CAPIMSG_NCCI(skb->data),
                                                     CAPIMSG_MSGID(skb->data));
-
+                       spin_unlock_irqrestore(&card->lock, flags);
                        capi_ctr_handle_message(ctrl, ApplId, skb);
                }
                break;
@@ -554,21 +556,17 @@ irqreturn_t b1_interrupt(int interrupt, void *devptr)
                ApplId = b1_get_word(card->port);
                NCCI = b1_get_word(card->port);
                WindowSize = b1_get_word(card->port);
-               spin_unlock_irqrestore(&card->lock, flags);
-
                capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize);
-
+               spin_unlock_irqrestore(&card->lock, flags);
                break;
 
        case RECEIVE_FREE_NCCI:
 
                ApplId = b1_get_word(card->port);
                NCCI = b1_get_word(card->port);
-               spin_unlock_irqrestore(&card->lock, flags);
-
                if (NCCI != 0xffffffff)
                        capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI);
-              
+               spin_unlock_irqrestore(&card->lock, flags);
                break;
 
        case RECEIVE_START:
index 428872b653e9b0cd0c1c06d33ff7d6cf834344c6..669f6f67449c46f26416a27c82939ad734256306 100644 (file)
@@ -486,11 +486,13 @@ static void b1dma_handle_rx(avmcard *card)
                                        card->name);
                } else {
                        memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
-                       if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF)
+                       if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF) {
+                               spin_lock(&card->lock);
                                capilib_data_b3_conf(&cinfo->ncci_head, ApplId,
-                                                    CAPIMSG_NCCI(skb->data),
-                                                    CAPIMSG_MSGID(skb->data));
-
+                                       CAPIMSG_NCCI(skb->data),
+                                       CAPIMSG_MSGID(skb->data));
+                               spin_unlock(&card->lock);
+                       }
                        capi_ctr_handle_message(ctrl, ApplId, skb);
                }
                break;
@@ -500,9 +502,9 @@ static void b1dma_handle_rx(avmcard *card)
                ApplId = _get_word(&p);
                NCCI = _get_word(&p);
                WindowSize = _get_word(&p);
-
+               spin_lock(&card->lock);
                capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize);
-
+               spin_unlock(&card->lock);
                break;
 
        case RECEIVE_FREE_NCCI:
@@ -510,9 +512,11 @@ static void b1dma_handle_rx(avmcard *card)
                ApplId = _get_word(&p);
                NCCI = _get_word(&p);
 
-               if (NCCI != 0xffffffff)
+               if (NCCI != 0xffffffff) {
+                       spin_lock(&card->lock);
                        capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI);
-
+                       spin_unlock(&card->lock);
+               }
                break;
 
        case RECEIVE_START:
@@ -751,10 +755,10 @@ void b1dma_reset_ctr(struct capi_ctr *ctrl)
 
        spin_lock_irqsave(&card->lock, flags);
        b1dma_reset(card);
-       spin_unlock_irqrestore(&card->lock, flags);
 
        memset(cinfo->version, 0, sizeof(cinfo->version));
        capilib_release(&cinfo->ncci_head);
+       spin_unlock_irqrestore(&card->lock, flags);
        capi_ctr_reseted(ctrl);
 }
 
@@ -803,8 +807,11 @@ void b1dma_release_appl(struct capi_ctr *ctrl, u16 appl)
        avmcard *card = cinfo->card;
        struct sk_buff *skb;
        void *p;
+       unsigned long flags;
 
+       spin_lock_irqsave(&card->lock, flags);
        capilib_release_appl(&cinfo->ncci_head, appl);
+       spin_unlock_irqrestore(&card->lock, flags);
 
        skb = alloc_skb(7, GFP_ATOMIC);
        if (!skb) {
@@ -832,10 +839,13 @@ u16 b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
        u16 retval = CAPI_NOERROR;
 
        if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
+               unsigned long flags;
+               spin_lock_irqsave(&card->lock, flags);
                retval = capilib_data_b3_req(&cinfo->ncci_head,
                                             CAPIMSG_APPID(skb->data),
                                             CAPIMSG_NCCI(skb->data),
                                             CAPIMSG_MSGID(skb->data));
+               spin_unlock_irqrestore(&card->lock, flags);
        }
        if (retval == CAPI_NOERROR) 
                b1dma_queue_tx(card, skb);
index d58f927e766a4a95f9c942be039e6ae3071be210..4bbbbe688077558f1793c746e0f95380d8b65f17 100644 (file)
@@ -678,7 +678,9 @@ static irqreturn_t c4_handle_interrupt(avmcard *card)
                 for (i=0; i < card->nr_controllers; i++) {
                        avmctrl_info *cinfo = &card->ctrlinfo[i];
                        memset(cinfo->version, 0, sizeof(cinfo->version));
+                       spin_lock_irqsave(&card->lock, flags);
                        capilib_release(&cinfo->ncci_head);
+                       spin_unlock_irqrestore(&card->lock, flags);
                        capi_ctr_reseted(&cinfo->capi_ctrl);
                }
                card->nlogcontr = 0;
@@ -727,6 +729,7 @@ static void c4_send_init(avmcard *card)
 {
        struct sk_buff *skb;
        void *p;
+       unsigned long flags;
 
        skb = alloc_skb(15, GFP_ATOMIC);
        if (!skb) {
@@ -744,12 +747,15 @@ static void c4_send_init(avmcard *card)
        skb_put(skb, (u8 *)p - (u8 *)skb->data);
 
        skb_queue_tail(&card->dma->send_queue, skb);
+       spin_lock_irqsave(&card->lock, flags);
        c4_dispatch_tx(card);
+       spin_unlock_irqrestore(&card->lock, flags);
 }
 
 static int queue_sendconfigword(avmcard *card, u32 val)
 {
        struct sk_buff *skb;
+       unsigned long flags;
        void *p;
 
        skb = alloc_skb(3+4, GFP_ATOMIC);
@@ -766,7 +772,9 @@ static int queue_sendconfigword(avmcard *card, u32 val)
        skb_put(skb, (u8 *)p - (u8 *)skb->data);
 
        skb_queue_tail(&card->dma->send_queue, skb);
+       spin_lock_irqsave(&card->lock, flags);
        c4_dispatch_tx(card);
+       spin_unlock_irqrestore(&card->lock, flags);
        return 0;
 }
 
@@ -986,7 +994,9 @@ static void c4_release_appl(struct capi_ctr *ctrl, u16 appl)
        struct sk_buff *skb;
        void *p;
 
+       spin_lock_irqsave(&card->lock, flags);
        capilib_release_appl(&cinfo->ncci_head, appl);
+       spin_unlock_irqrestore(&card->lock, flags);
 
        if (ctrl->cnr == card->cardnr) {
                skb = alloc_skb(7, GFP_ATOMIC);
@@ -1019,7 +1029,8 @@ static u16 c4_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
        u16 retval = CAPI_NOERROR;
        unsigned long flags;
 
-       if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
+       spin_lock_irqsave(&card->lock, flags);
+       if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
                retval = capilib_data_b3_req(&cinfo->ncci_head,
                                             CAPIMSG_APPID(skb->data),
                                             CAPIMSG_NCCI(skb->data),
@@ -1027,10 +1038,9 @@ static u16 c4_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
        }
        if (retval == CAPI_NOERROR) {
                skb_queue_tail(&card->dma->send_queue, skb);
-               spin_lock_irqsave(&card->lock, flags);
                c4_dispatch_tx(card);
-               spin_unlock_irqrestore(&card->lock, flags);
        }
+       spin_unlock_irqrestore(&card->lock, flags);
        return retval;
 }
 
index c925020fe9b7874732383d8605994d30096f3c10..6130724e46e775a98e9f37621d9aa4533eb2c553 100644 (file)
@@ -180,8 +180,8 @@ static irqreturn_t t1isa_interrupt(int interrupt, void *devptr)
 
                        ApplId = (unsigned) b1_get_word(card->port);
                        MsgLen = t1_get_slice(card->port, card->msgbuf);
-                       spin_unlock_irqrestore(&card->lock, flags);
                        if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) {
+                               spin_unlock_irqrestore(&card->lock, flags);
                                printk(KERN_ERR "%s: incoming packet dropped\n",
                                                card->name);
                        } else {
@@ -190,7 +190,7 @@ static irqreturn_t t1isa_interrupt(int interrupt, void *devptr)
                                        capilib_data_b3_conf(&cinfo->ncci_head, ApplId,
                                                             CAPIMSG_NCCI(skb->data),
                                                             CAPIMSG_MSGID(skb->data));
-
+                               spin_unlock_irqrestore(&card->lock, flags);
                                capi_ctr_handle_message(ctrl, ApplId, skb);
                        }
                        break;
@@ -200,21 +200,17 @@ static irqreturn_t t1isa_interrupt(int interrupt, void *devptr)
                        ApplId = b1_get_word(card->port);
                        NCCI = b1_get_word(card->port);
                        WindowSize = b1_get_word(card->port);
-                       spin_unlock_irqrestore(&card->lock, flags);
-
                        capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize);
-
+                       spin_unlock_irqrestore(&card->lock, flags);
                        break;
 
                case RECEIVE_FREE_NCCI:
 
                        ApplId = b1_get_word(card->port);
                        NCCI = b1_get_word(card->port);
-                       spin_unlock_irqrestore(&card->lock, flags);
-
                        if (NCCI != 0xffffffff)
                                capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI);
-
+                       spin_unlock_irqrestore(&card->lock, flags);
                        break;
 
                case RECEIVE_START:
@@ -333,13 +329,16 @@ static void t1isa_reset_ctr(struct capi_ctr *ctrl)
        avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
        avmcard *card = cinfo->card;
        unsigned int port = card->port;
+       unsigned long flags;
 
        t1_disable_irq(port);
        b1_reset(port);
        b1_reset(port);
 
        memset(cinfo->version, 0, sizeof(cinfo->version));
+       spin_lock_irqsave(&card->lock, flags);
        capilib_release(&cinfo->ncci_head);
+       spin_unlock_irqrestore(&card->lock, flags);
        capi_ctr_reseted(ctrl);
 }
 
@@ -466,29 +465,26 @@ static u16 t1isa_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
        u8 subcmd = CAPIMSG_SUBCOMMAND(skb->data);
        u16 dlen, retval;
 
+       spin_lock_irqsave(&card->lock, flags);
        if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) {
                retval = capilib_data_b3_req(&cinfo->ncci_head,
                                             CAPIMSG_APPID(skb->data),
                                             CAPIMSG_NCCI(skb->data),
                                             CAPIMSG_MSGID(skb->data));
-               if (retval != CAPI_NOERROR) 
+               if (retval != CAPI_NOERROR) {
+                       spin_unlock_irqrestore(&card->lock, flags);
                        return retval;
-
+               }
                dlen = CAPIMSG_DATALEN(skb->data);
 
-               spin_lock_irqsave(&card->lock, flags);
                b1_put_byte(port, SEND_DATA_B3_REQ);
                t1_put_slice(port, skb->data, len);
                t1_put_slice(port, skb->data + len, dlen);
-               spin_unlock_irqrestore(&card->lock, flags);
        } else {
-
-               spin_lock_irqsave(&card->lock, flags);
                b1_put_byte(port, SEND_MESSAGE);
                t1_put_slice(port, skb->data, len);
-               spin_unlock_irqrestore(&card->lock, flags);
        }
-
+       spin_unlock_irqrestore(&card->lock, flags);
        dev_kfree_skb_any(skb);
        return CAPI_NOERROR;
 }
index 82edc1c1db7a685127498fcfecffc46db5e594dc..4d425c644d413b7d4080ea36dd0bdb1b0f694b6d 100644 (file)
@@ -321,7 +321,7 @@ void sendf(APPL * appl, word command, dword Id, word Number, byte * format, ...)
                                  DBG_BLK((((char *)(long)GET_DWORD(&msg.info.data_b3_ind.Data)) + i,
                                        ((dlength - i) < 256) ? (dlength - i) : 256))
                                  if (!(myDriverDebugHandle.dbgMask & DL_PRV0))
-                                         break; /* not more if not explicitely requested */
+                                         break; /* not more if not explicitly requested */
                                }
                        }
                        break;
@@ -965,7 +965,7 @@ static u16 diva_send_message(struct capi_ctr *ctrl,
                                        ((GET_WORD(&msg->info.data_b3_req.Data_Length) - j) <
                                          256) ? (GET_WORD(&msg->info.data_b3_req.Data_Length) - j) : 256))
                                if (!(myDriverDebugHandle.dbgMask & DL_PRV0))
-                                       break;  /* not more if not explicitely requested */
+                                       break;  /* not more if not explicitly requested */
                        }
                }
 #endif
index 3b19caeba25880971a708213519ab734dc5ce343..c0d7036404a5920a7404a1d7c8acd9bc591df93d 100644 (file)
@@ -767,7 +767,7 @@ Amd7930_init(struct IsdnCardState *cs)
                 /* read */
                 if (*ptr++ >= 0x100) {
                        if (cmd < 8)
-                                /* setzt Register zurück */
+                                /* reset register */
                                 rByteAMD(cs, cmd);
                        else {
                                wByteAMD(cs, 0x00, cmd);
index b73027ff50e88784747325f3367ae1aaf26f3bce..39f421ed8de82d199e5856dd262c7f4ee4882036 100644 (file)
 static const char *enternow_pci_rev = "$Revision: 1.1.4.5 $";
 
 
-/* für PowerISDN PCI */
+/* for PowerISDN PCI */
 #define TJ_AMD_IRQ                                              0x20
 #define TJ_LED1                                                 0x40
 #define TJ_LED2                                                 0x80
 
 
-/* Das Fenster zum AMD...
- * Ab Adresse hw.njet.base + TJ_AMD_PORT werden vom AMD jeweils 8 Bit in
- * den TigerJet i/o-Raum gemappt
- * -> 0x01 des AMD bei hw.njet.base + 0C4 */
+/* The window to [the] AMD [chip]...
+ * From address hw.njet.base + TJ_AMD_PORT onwards, the AMD
+ * maps [consecutive/multiple] 8 bits into the TigerJet I/O space
+ * -> 0x01 of the AMD at hw.njet.base + 0C4 */
 #define TJ_AMD_PORT                                             0xC0
 
 
@@ -96,11 +96,11 @@ static const char *enternow_pci_rev = "$Revision: 1.1.4.5 $";
 static unsigned char
 ReadByteAmd7930(struct IsdnCardState *cs, unsigned char offset)
 {
-       /* direktes Register */
+       /* direct register */
        if(offset < 8)
                return (inb(cs->hw.njet.isac + 4*offset));
 
-       /* indirektes Register */
+       /* indirect register */
        else {
                outb(offset, cs->hw.njet.isac + 4*AMD_CR);
                return(inb(cs->hw.njet.isac + 4*AMD_DR));
@@ -111,11 +111,11 @@ ReadByteAmd7930(struct IsdnCardState *cs, unsigned char offset)
 static void
 WriteByteAmd7930(struct IsdnCardState *cs, unsigned char offset, unsigned char value)
 {
-       /* direktes Register */
+       /* direct register */
        if(offset < 8)
                outb(value, cs->hw.njet.isac + 4*offset);
 
-       /* indirektes Register */
+       /* indirect register */
        else {
                outb(offset, cs->hw.njet.isac + 4*AMD_CR);
                outb(value, cs->hw.njet.isac + 4*AMD_DR);
index 077080aca79973366d8c13ccce686f4ec0d226f1..fba8b624ffcf19538c8a9821e227351502a11f6a 100644 (file)
@@ -1,6 +1,6 @@
 /* $Id: hfc_pci.c,v 1.48.2.4 2004/02/11 13:21:33 keil Exp $
  *
- * low level driver for CCD´s hfc-pci based cards
+ * low level driver for CCD's hfc-pci based cards
  *
  * Author       Werner Cornelius
  *              based on existing driver for CCD hfc ISA cards
index 268dced6c34a9e33c24bf508ce2b083c9414f6c1..c69a77a80062f970bc289c543a9eded80e35aa73 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * isdnhdlc.c  --  General purpose ISDN HDLC decoder.
  *
- *Copyright (C) 2002   Wolfgang Mües      <wolfgang@iksw-muees.de>
+ *Copyright (C) 2002   Wolfgang Mües      <wolfgang@iksw-muees.de>
  *             2001    Frode Isaksen      <fisaksen@bewan.com>
  *              2001   Kai Germaschewski  <kai.germaschewski@gmx.de>
  *
@@ -27,7 +27,7 @@
 
 /*-------------------------------------------------------------------*/
 
-MODULE_AUTHOR("Wolfgang Mües <wolfgang@iksw-muees.de>, "
+MODULE_AUTHOR("Wolfgang Mües <wolfgang@iksw-muees.de>, "
              "Frode Isaksen <fisaksen@bewan.com>, "
              "Kai Germaschewski <kai.germaschewski@gmx.de>");
 MODULE_DESCRIPTION("General purpose ISDN HDLC decoder");
index 45167d2f8fb0a303aacdcf9ada1eb36352ca168a..cf0a95a24015dbd1e32f19e71b35b5f3f8cf669d 100644 (file)
@@ -5,7 +5,7 @@
  * Neccessary because some ISDN devices don't have HDLC
  * controllers. Also included: a bit reversal table.
  *
- *Copyright (C) 2002    Wolfgang Mües      <wolfgang@iksw-muees.de>
+ *Copyright (C) 2002    Wolfgang Mües      <wolfgang@iksw-muees.de>
  *             2001    Frode Isaksen      <fisaksen@bewan.com>
  *              2001   Kai Germaschewski  <kai.germaschewski@gmx.de>
  *
index 43d61d1bc5b629103e365a5eb2405aff9743e14f..70840a710acfe1938323f8436a07652892486310 100644 (file)
@@ -304,7 +304,7 @@ initjade(struct IsdnCardState *cs)
        cs->BC_Write_Reg(cs, 1, jade_HDLC_IMR,  0x00);
        /* Setup host access to hdlc controller */
        jade_write_indirect(cs, jade_HDLCCNTRACCESS, (jadeINDIRECT_HAH1|jadeINDIRECT_HAH2));
-       /* Unmask HDLC int (don´t forget DSP int later on)*/
+       /* Unmask HDLC int (don't forget DSP int later on)*/
        cs->BC_Write_Reg(cs, -1,jade_INT, (jadeINT_HDLC1|jadeINT_HDLC2));
 
        /* once again TRANSPARENT */    
index 7b55e151f1b009fb78f402680dbf75849db10d8c..ac5a91ccde8102b18a3ae39a7a309e6137f9b978 100644 (file)
@@ -15,9 +15,9 @@
 
 /*
  *        Documentation:
- *        - "Common ISDN API - Perfil Português - Versão 2.1",
+ *        - "Common ISDN API - Perfil Português - Versão 2.1",
  *           Telecom Portugal, Fev 1992.
- *        - "Common ISDN API - Especificação de protocolos para 
+ *        - "Common ISDN API - Especificação de protocolos para
  *           acesso aos canais B", Inesc, Jan 1994.
  */
 
diff --git a/drivers/isdn/sc/debug.h b/drivers/isdn/sc/debug.h
deleted file mode 100644 (file)
index e9db96e..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/* $Id: debug.h,v 1.2.8.1 2001/09/23 22:24:59 kai Exp $
- *
- * Copyright (C) 1996  SpellCaster Telecommunications Inc.
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * For more information, please contact gpl-info@spellcast.com or write:
- *
- *     SpellCaster Telecommunications Inc.
- *     5621 Finch Avenue East, Unit #3
- *     Scarborough, Ontario  Canada
- *     M1B 2T9
- *     +1 (416) 297-8565
- *     +1 (416) 297-6433 Facsimile
- */
-
-#define REQUEST_IRQ(a,b,c,d,e) request_irq(a,b,c,d,e)
-#define FREE_IRQ(a,b) free_irq(a,b)
index 5286e0c810a9f4c26254e9638a049bf2d38c501f..4766e5b77378369aa09f9d73084e83728d76a9f3 100644 (file)
@@ -14,4 +14,3 @@
 #include <linux/timer.h>
 #include <linux/wait.h>
 #include <linux/isdnif.h>
-#include "debug.h"
index 0bf76344a0d54fcbd00752fc65d2a1b4f390332f..d09c854cfac7f819721cc91c5624c1bbc6a67c2a 100644 (file)
@@ -404,7 +404,7 @@ static void __exit sc_exit(void)
                /*
                 * Release the IRQ
                 */
-               FREE_IRQ(sc_adapter[i]->interrupt, NULL);
+               free_irq(sc_adapter[i]->interrupt, NULL);
 
                /*
                 * Reset for a clean start
index 8749fa4ffcee955725e9f8992104c086522828a2..656920636cb2f6dafba5ffbd0dc41c7c177e601e 100644 (file)
@@ -47,4 +47,8 @@ config KVM_AMD
          Provides support for KVM on AMD processors equipped with the AMD-V
          (SVM) extensions.
 
+# OK, it's a little counter-intuitive to do this, but it puts it neatly under
+# the virtualization menu.
+source drivers/lguest/Kconfig
+
 endif # VIRTUALIZATION
index af2d288c881d32500a5f753cb6453432ce3b6c15..07ae280e8fe5c279f7077b1e95650949002e44d7 100644 (file)
@@ -198,21 +198,15 @@ static void vcpu_put(struct kvm_vcpu *vcpu)
 
 static void ack_flush(void *_completed)
 {
-       atomic_t *completed = _completed;
-
-       atomic_inc(completed);
 }
 
 void kvm_flush_remote_tlbs(struct kvm *kvm)
 {
-       int i, cpu, needed;
+       int i, cpu;
        cpumask_t cpus;
        struct kvm_vcpu *vcpu;
-       atomic_t completed;
 
-       atomic_set(&completed, 0);
        cpus_clear(cpus);
-       needed = 0;
        for (i = 0; i < KVM_MAX_VCPUS; ++i) {
                vcpu = kvm->vcpus[i];
                if (!vcpu)
@@ -221,23 +215,9 @@ void kvm_flush_remote_tlbs(struct kvm *kvm)
                        continue;
                cpu = vcpu->cpu;
                if (cpu != -1 && cpu != raw_smp_processor_id())
-                       if (!cpu_isset(cpu, cpus)) {
-                               cpu_set(cpu, cpus);
-                               ++needed;
-                       }
-       }
-
-       /*
-        * We really want smp_call_function_mask() here.  But that's not
-        * available, so ipi all cpus in parallel and wait for them
-        * to complete.
-        */
-       for (cpu = first_cpu(cpus); cpu != NR_CPUS; cpu = next_cpu(cpu, cpus))
-               smp_call_function_single(cpu, ack_flush, &completed, 1, 0);
-       while (atomic_read(&completed) != needed) {
-               cpu_relax();
-               barrier();
+                       cpu_set(cpu, cpus);
        }
+       smp_call_function_mask(cpus, ack_flush, NULL, 1);
 }
 
 int kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id)
@@ -2054,12 +2034,21 @@ again:
 
        kvm_x86_ops->run(vcpu, kvm_run);
 
-       kvm_guest_exit();
        vcpu->guest_mode = 0;
        local_irq_enable();
 
        ++vcpu->stat.exits;
 
+       /*
+        * We must have an instruction between local_irq_enable() and
+        * kvm_guest_exit(), so the timer interrupt isn't delayed by
+        * the interrupt shadow.  The stat.exits increment will do nicely.
+        * But we need to prevent reordering, hence this barrier():
+        */
+       barrier();
+
+       kvm_guest_exit();
+
        preempt_enable();
 
        /*
index a190587cf6a52d5806ec48c54e44cfc5c7cd18f4..238fcad3ceceee4fc32f8ebc2396ed455b4107ae 100644 (file)
@@ -494,12 +494,19 @@ static void apic_send_ipi(struct kvm_lapic *apic)
 
 static u32 apic_get_tmcct(struct kvm_lapic *apic)
 {
-       u32 counter_passed;
-       ktime_t passed, now = apic->timer.dev.base->get_time();
-       u32 tmcct = apic_get_reg(apic, APIC_TMICT);
+       u64 counter_passed;
+       ktime_t passed, now;
+       u32 tmcct;
 
        ASSERT(apic != NULL);
 
+       now = apic->timer.dev.base->get_time();
+       tmcct = apic_get_reg(apic, APIC_TMICT);
+
+       /* if initial count is 0, current count should also be 0 */
+       if (tmcct == 0)
+               return 0;
+
        if (unlikely(ktime_to_ns(now) <=
                ktime_to_ns(apic->timer.last_update))) {
                /* Wrap around */
@@ -514,15 +521,24 @@ static u32 apic_get_tmcct(struct kvm_lapic *apic)
 
        counter_passed = div64_64(ktime_to_ns(passed),
                                  (APIC_BUS_CYCLE_NS * apic->timer.divide_count));
-       tmcct -= counter_passed;
 
-       if (tmcct <= 0) {
-               if (unlikely(!apic_lvtt_period(apic)))
+       if (counter_passed > tmcct) {
+               if (unlikely(!apic_lvtt_period(apic))) {
+                       /* one-shot timers stick at 0 until reset */
                        tmcct = 0;
-               else
-                       do {
-                               tmcct += apic_get_reg(apic, APIC_TMICT);
-                       } while (tmcct <= 0);
+               } else {
+                       /*
+                        * periodic timers reset to APIC_TMICT when they
+                        * hit 0. The while loop simulates this happening N
+                        * times. (counter_passed %= tmcct) would also work,
+                        * but might be slower or not work on 32-bit??
+                        */
+                       while (counter_passed > tmcct)
+                               counter_passed -= tmcct;
+                       tmcct -= counter_passed;
+               }
+       } else {
+               tmcct -= counter_passed;
        }
 
        return tmcct;
@@ -853,7 +869,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu)
                apic_set_reg(apic, APIC_ISR + 0x10 * i, 0);
                apic_set_reg(apic, APIC_TMR + 0x10 * i, 0);
        }
-       apic->timer.divide_count = 0;
+       update_divide_count(apic);
        atomic_set(&apic->timer.pending, 0);
        if (vcpu->vcpu_id == 0)
                vcpu->apic_base |= MSR_IA32_APICBASE_BSP;
index 6d84d30f5ed00aea64d11214ead90a15fcbb1ded..feb5ac986c5d0eb23480512193a706f247ccd4b3 100644 (file)
@@ -1049,6 +1049,7 @@ int kvm_mmu_reset_context(struct kvm_vcpu *vcpu)
        destroy_kvm_mmu(vcpu);
        return init_kvm_mmu(vcpu);
 }
+EXPORT_SYMBOL_GPL(kvm_mmu_reset_context);
 
 int kvm_mmu_load(struct kvm_vcpu *vcpu)
 {
@@ -1088,7 +1089,7 @@ static void mmu_pte_write_zap_pte(struct kvm_vcpu *vcpu,
                        mmu_page_remove_parent_pte(child, spte);
                }
        }
-       *spte = 0;
+       set_shadow_pte(spte, 0);
        kvm_flush_remote_tlbs(vcpu->kvm);
 }
 
index 4f115a8e45ef803ae1b1f1d494690bd98b9488c4..bb56ae3f89b601f9c2ae428dd92498f35b8aa181 100644 (file)
@@ -523,6 +523,8 @@ static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu)
 
 static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
 {
+       if (vcpu->rmode.active)
+               rflags |= IOPL_MASK | X86_EFLAGS_VM;
        vmcs_writel(GUEST_RFLAGS, rflags);
 }
 
@@ -1128,6 +1130,7 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
        fix_rmode_seg(VCPU_SREG_GS, &vcpu->rmode.gs);
        fix_rmode_seg(VCPU_SREG_FS, &vcpu->rmode.fs);
 
+       kvm_mmu_reset_context(vcpu);
        init_rmode_tss(vcpu->kvm);
 }
 
@@ -1760,10 +1763,8 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
                set_bit(irq / BITS_PER_LONG, &vcpu->irq_summary);
        }
 
-       if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) { /* nmi */
-               asm ("int $2");
-               return 1;
-       }
+       if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) /* nmi */
+               return 1;  /* already handled by vmx_vcpu_run() */
 
        if (is_no_device(intr_info)) {
                vmx_fpu_activate(vcpu);
@@ -2196,6 +2197,7 @@ static void vmx_intr_assist(struct kvm_vcpu *vcpu)
 static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
        struct vcpu_vmx *vmx = to_vmx(vcpu);
+       u32 intr_info;
 
        /*
         * Loading guest fpu may have cleared host cr0.ts
@@ -2322,6 +2324,12 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 
        asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
        vmx->launched = 1;
+
+       intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
+
+       /* We need to handle NMIs before interrupts are enabled */
+       if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) /* nmi */
+               asm("int $2");
 }
 
 static void vmx_inject_page_fault(struct kvm_vcpu *vcpu,
index 9737c3b2f48c1a2006cd6420ce192f04a323c7e3..a6ace302e0cd454f1f413306013b0920305e4a67 100644 (file)
@@ -212,7 +212,8 @@ static u16 twobyte_table[256] = {
        0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov,
            DstReg | SrcMem16 | ModRM | Mov,
        /* 0xC0 - 0xCF */
-       0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, DstMem | SrcReg | ModRM | Mov, 0, 0, 0, ImplicitOps | ModRM,
+       0, 0, 0, 0, 0, 0, 0, 0,
        /* 0xD0 - 0xDF */
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        /* 0xE0 - 0xEF */
@@ -596,11 +597,10 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
                case 0xf0:      /* LOCK */
                        lock_prefix = 1;
                        break;
+               case 0xf2:      /* REPNE/REPNZ */
                case 0xf3:      /* REP/REPE/REPZ */
                        rep_prefix = 1;
                        break;
-               case 0xf2:      /* REPNE/REPNZ */
-                       break;
                default:
                        goto done_prefixes;
                }
@@ -825,6 +825,14 @@ done_prefixes:
                if (twobyte && b == 0x01 && modrm_reg == 7)
                        break;
              srcmem_common:
+               /*
+                * For instructions with a ModR/M byte, switch to register
+                * access if Mod = 3.
+                */
+               if ((d & ModRM) && modrm_mod == 3) {
+                       src.type = OP_REG;
+                       break;
+               }
                src.type = OP_MEM;
                src.ptr = (unsigned long *)cr2;
                src.val = 0;
@@ -893,6 +901,14 @@ done_prefixes:
                dst.ptr = (unsigned long *)cr2;
                dst.bytes = (d & ByteOp) ? 1 : op_bytes;
                dst.val = 0;
+               /*
+                * For instructions with a ModR/M byte, switch to register
+                * access if Mod = 3.
+                */
+               if ((d & ModRM) && modrm_mod == 3) {
+                       dst.type = OP_REG;
+                       break;
+               }
                if (d & BitOp) {
                        unsigned long mask = ~(dst.bytes * 8 - 1);
 
@@ -1083,31 +1099,6 @@ push:
        case 0xd2 ... 0xd3:     /* Grp2 */
                src.val = _regs[VCPU_REGS_RCX];
                goto grp2;
-       case 0xe8: /* call (near) */ {
-               long int rel;
-               switch (op_bytes) {
-               case 2:
-                       rel = insn_fetch(s16, 2, _eip);
-                       break;
-               case 4:
-                       rel = insn_fetch(s32, 4, _eip);
-                       break;
-               case 8:
-                       rel = insn_fetch(s64, 8, _eip);
-                       break;
-               default:
-                       DPRINTF("Call: Invalid op_bytes\n");
-                       goto cannot_emulate;
-               }
-               src.val = (unsigned long) _eip;
-               JMP_REL(rel);
-               goto push;
-       }
-       case 0xe9: /* jmp rel */
-       case 0xeb: /* jmp rel short */
-               JMP_REL(src.val);
-               no_wb = 1; /* Disable writeback. */
-               break;
        case 0xf6 ... 0xf7:     /* Grp3 */
                switch (modrm_reg) {
                case 0 ... 1:   /* test */
@@ -1350,6 +1341,32 @@ special_insn:
        case 0xae ... 0xaf:     /* scas */
                DPRINTF("Urk! I don't handle SCAS.\n");
                goto cannot_emulate;
+       case 0xe8: /* call (near) */ {
+               long int rel;
+               switch (op_bytes) {
+               case 2:
+                       rel = insn_fetch(s16, 2, _eip);
+                       break;
+               case 4:
+                       rel = insn_fetch(s32, 4, _eip);
+                       break;
+               case 8:
+                       rel = insn_fetch(s64, 8, _eip);
+                       break;
+               default:
+                       DPRINTF("Call: Invalid op_bytes\n");
+                       goto cannot_emulate;
+               }
+               src.val = (unsigned long) _eip;
+               JMP_REL(rel);
+               goto push;
+       }
+       case 0xe9: /* jmp rel */
+       case 0xeb: /* jmp rel short */
+               JMP_REL(src.val);
+               no_wb = 1; /* Disable writeback. */
+               break;
+
 
        }
        goto writeback;
@@ -1501,6 +1518,10 @@ twobyte_insn:
                dst.bytes = op_bytes;
                dst.val = (d & ByteOp) ? (s8) src.val : (s16) src.val;
                break;
+       case 0xc3:              /* movnti */
+               dst.bytes = op_bytes;
+               dst.val = (op_bytes == 4) ? (u32) src.val : (u64) src.val;
+               break;
        }
        goto writeback;
 
index 50914439d861d74072bf9af8d7ac0024469eb2fe..0fd640751294ae143be658800fdffc7e1430da44 100644 (file)
@@ -43,7 +43,7 @@ static void s3c24xx_led_set(struct led_classdev *led_cdev,
        struct s3c24xx_gpio_led *led = to_gpio(led_cdev);
        struct s3c24xx_led_platdata *pd = led->pdata;
 
-       /* there will be a sort delay between setting the output and
+       /* there will be a short delay between setting the output and
         * going from output to input when using tristate. */
 
        s3c2410_gpio_setpin(pd->gpio, (value ? 1 : 0) ^
index 41e2250613a164d8efec6afba60002850ff18375..7eb9ecff8f4a9e4ae1a73a5904048419860aa5f3 100644 (file)
@@ -1,7 +1,6 @@
 config LGUEST
        tristate "Linux hypervisor example code"
-       depends on X86 && PARAVIRT && EXPERIMENTAL && !X86_PAE && FUTEX
-       select LGUEST_GUEST
+       depends on X86_32 && EXPERIMENTAL && !X86_PAE && FUTEX && !(X86_VISWS || X86_VOYAGER)
        select HVC_DRIVER
        ---help---
          This is a very simple module which allows you to run
@@ -18,13 +17,3 @@ config LGUEST_GUEST
          The guest needs code built-in, even if the host has lguest
          support as a module.  The drivers are tiny, so we build them
          in too.
-
-config LGUEST_NET
-       tristate
-       default y
-       depends on LGUEST_GUEST && NET
-
-config LGUEST_BLOCK
-       tristate
-       default y
-       depends on LGUEST_GUEST && BLOCK
index e5047471c334ed0f84081bf594a9ada58f20ba70..5e8272d296d8ff47e03937e766e24fba4d0db6f8 100644 (file)
@@ -1,10 +1,12 @@
-# Guest requires the paravirt_ops replacement and the bus driver.
-obj-$(CONFIG_LGUEST_GUEST) += lguest.o lguest_asm.o lguest_bus.o
+# Guest requires the device configuration and probing code.
+obj-$(CONFIG_LGUEST_GUEST) += lguest_device.o
 
 # Host requires the other files, which can be a module.
 obj-$(CONFIG_LGUEST)   += lg.o
-lg-y := core.o hypercalls.o page_tables.o interrupts_and_traps.o \
-       segments.o io.o lguest_user.o switcher.o
+lg-y = core.o hypercalls.o page_tables.o interrupts_and_traps.o \
+       segments.o lguest_user.o
+
+lg-$(CONFIG_X86_32) += x86/switcher_32.o x86/core.o
 
 Preparation Preparation!: PREFIX=P
 Guest: PREFIX=G
index a0788c12b392bbdfcca0bfea95cc088569db296f..35d19ae58de7eeb30b6ef60dad58ed4a518b4e6f 100644 (file)
 #include <linux/vmalloc.h>
 #include <linux/cpu.h>
 #include <linux/freezer.h>
+#include <linux/highmem.h>
 #include <asm/paravirt.h>
-#include <asm/desc.h>
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
 #include <asm/poll.h>
-#include <asm/highmem.h>
 #include <asm/asm-offsets.h>
-#include <asm/i387.h>
 #include "lg.h"
 
-/* Found in switcher.S */
-extern char start_switcher_text[], end_switcher_text[], switch_to_guest[];
-extern unsigned long default_idt_entries[];
-
-/* Every guest maps the core switcher code. */
-#define SHARED_SWITCHER_PAGES \
-       DIV_ROUND_UP(end_switcher_text - start_switcher_text, PAGE_SIZE)
-/* Pages for switcher itself, then two pages per cpu */
-#define TOTAL_SWITCHER_PAGES (SHARED_SWITCHER_PAGES + 2 * NR_CPUS)
-
-/* We map at -4M for ease of mapping into the guest (one PTE page). */
-#define SWITCHER_ADDR 0xFFC00000
 
 static struct vm_struct *switcher_vma;
 static struct page **switcher_page;
 
-static int cpu_had_pge;
-static struct {
-       unsigned long offset;
-       unsigned short segment;
-} lguest_entry;
-
 /* This One Big lock protects all inter-guest data structures. */
 DEFINE_MUTEX(lguest_lock);
-static DEFINE_PER_CPU(struct lguest *, last_guest);
-
-/* FIXME: Make dynamic. */
-#define MAX_LGUEST_GUESTS 16
-struct lguest lguests[MAX_LGUEST_GUESTS];
-
-/* Offset from where switcher.S was compiled to where we've copied it */
-static unsigned long switcher_offset(void)
-{
-       return SWITCHER_ADDR - (unsigned long)start_switcher_text;
-}
-
-/* This cpu's struct lguest_pages. */
-static struct lguest_pages *lguest_pages(unsigned int cpu)
-{
-       return &(((struct lguest_pages *)
-                 (SWITCHER_ADDR + SHARED_SWITCHER_PAGES*PAGE_SIZE))[cpu]);
-}
 
 /*H:010 We need to set up the Switcher at a high virtual address.  Remember the
  * Switcher is a few hundred bytes of assembler code which actually changes the
@@ -73,9 +35,7 @@ static struct lguest_pages *lguest_pages(unsigned int cpu)
  * Host since it will be running as the switchover occurs.
  *
  * Trying to map memory at a particular address is an unusual thing to do, so
- * it's not a simple one-liner.  We also set up the per-cpu parts of the
- * Switcher here.
- */
+ * it's not a simple one-liner. */
 static __init int map_switcher(void)
 {
        int i, err;
@@ -132,90 +92,11 @@ static __init int map_switcher(void)
                goto free_vma;
        }
 
-       /* Now the switcher is mapped at the right address, we can't fail!
-        * Copy in the compiled-in Switcher code (from switcher.S). */
+       /* Now the Switcher is mapped at the right address, we can't fail!
+        * Copy in the compiled-in Switcher code (from <arch>_switcher.S). */
        memcpy(switcher_vma->addr, start_switcher_text,
               end_switcher_text - start_switcher_text);
 
-       /* Most of the switcher.S doesn't care that it's been moved; on Intel,
-        * jumps are relative, and it doesn't access any references to external
-        * code or data.
-        *
-        * The only exception is the interrupt handlers in switcher.S: their
-        * addresses are placed in a table (default_idt_entries), so we need to
-        * update the table with the new addresses.  switcher_offset() is a
-        * convenience function which returns the distance between the builtin
-        * switcher code and the high-mapped copy we just made. */
-       for (i = 0; i < IDT_ENTRIES; i++)
-               default_idt_entries[i] += switcher_offset();
-
-       /*
-        * Set up the Switcher's per-cpu areas.
-        *
-        * Each CPU gets two pages of its own within the high-mapped region
-        * (aka. "struct lguest_pages").  Much of this can be initialized now,
-        * but some depends on what Guest we are running (which is set up in
-        * copy_in_guest_info()).
-        */
-       for_each_possible_cpu(i) {
-               /* lguest_pages() returns this CPU's two pages. */
-               struct lguest_pages *pages = lguest_pages(i);
-               /* This is a convenience pointer to make the code fit one
-                * statement to a line. */
-               struct lguest_ro_state *state = &pages->state;
-
-               /* The Global Descriptor Table: the Host has a different one
-                * for each CPU.  We keep a descriptor for the GDT which says
-                * where it is and how big it is (the size is actually the last
-                * byte, not the size, hence the "-1"). */
-               state->host_gdt_desc.size = GDT_SIZE-1;
-               state->host_gdt_desc.address = (long)get_cpu_gdt_table(i);
-
-               /* All CPUs on the Host use the same Interrupt Descriptor
-                * Table, so we just use store_idt(), which gets this CPU's IDT
-                * descriptor. */
-               store_idt(&state->host_idt_desc);
-
-               /* The descriptors for the Guest's GDT and IDT can be filled
-                * out now, too.  We copy the GDT & IDT into ->guest_gdt and
-                * ->guest_idt before actually running the Guest. */
-               state->guest_idt_desc.size = sizeof(state->guest_idt)-1;
-               state->guest_idt_desc.address = (long)&state->guest_idt;
-               state->guest_gdt_desc.size = sizeof(state->guest_gdt)-1;
-               state->guest_gdt_desc.address = (long)&state->guest_gdt;
-
-               /* We know where we want the stack to be when the Guest enters
-                * the switcher: in pages->regs.  The stack grows upwards, so
-                * we start it at the end of that structure. */
-               state->guest_tss.esp0 = (long)(&pages->regs + 1);
-               /* And this is the GDT entry to use for the stack: we keep a
-                * couple of special LGUEST entries. */
-               state->guest_tss.ss0 = LGUEST_DS;
-
-               /* x86 can have a finegrained bitmap which indicates what I/O
-                * ports the process can use.  We set it to the end of our
-                * structure, meaning "none". */
-               state->guest_tss.io_bitmap_base = sizeof(state->guest_tss);
-
-               /* Some GDT entries are the same across all Guests, so we can
-                * set them up now. */
-               setup_default_gdt_entries(state);
-               /* Most IDT entries are the same for all Guests, too.*/
-               setup_default_idt_entries(state, default_idt_entries);
-
-               /* The Host needs to be able to use the LGUEST segments on this
-                * CPU, too, so put them in the Host GDT. */
-               get_cpu_gdt_table(i)[GDT_ENTRY_LGUEST_CS] = FULL_EXEC_SEGMENT;
-               get_cpu_gdt_table(i)[GDT_ENTRY_LGUEST_DS] = FULL_SEGMENT;
-       }
-
-       /* In the Switcher, we want the %cs segment register to use the
-        * LGUEST_CS GDT entry: we've put that in the Host and Guest GDTs, so
-        * it will be undisturbed when we switch.  To change %cs and jump we
-        * need this structure to feed to Intel's "lcall" instruction. */
-       lguest_entry.offset = (long)switch_to_guest + switcher_offset();
-       lguest_entry.segment = LGUEST_CS;
-
        printk(KERN_INFO "lguest: mapped switcher at %p\n",
               switcher_vma->addr);
        /* And we succeeded... */
@@ -247,86 +128,12 @@ static void unmap_switcher(void)
                __free_pages(switcher_page[i], 0);
 }
 
-/*H:130 Our Guest is usually so well behaved; it never tries to do things it
- * isn't allowed to.  Unfortunately, Linux's paravirtual infrastructure isn't
- * quite complete, because it doesn't contain replacements for the Intel I/O
- * instructions.  As a result, the Guest sometimes fumbles across one during
- * the boot process as it probes for various things which are usually attached
- * to a PC.
- *
- * When the Guest uses one of these instructions, we get trap #13 (General
- * Protection Fault) and come here.  We see if it's one of those troublesome
- * instructions and skip over it.  We return true if we did. */
-static int emulate_insn(struct lguest *lg)
-{
-       u8 insn;
-       unsigned int insnlen = 0, in = 0, shift = 0;
-       /* The eip contains the *virtual* address of the Guest's instruction:
-        * guest_pa just subtracts the Guest's page_offset. */
-       unsigned long physaddr = guest_pa(lg, lg->regs->eip);
-
-       /* The guest_pa() function only works for Guest kernel addresses, but
-        * that's all we're trying to do anyway. */
-       if (lg->regs->eip < lg->page_offset)
-               return 0;
-
-       /* Decoding x86 instructions is icky. */
-       lgread(lg, &insn, physaddr, 1);
-
-       /* 0x66 is an "operand prefix".  It means it's using the upper 16 bits
-          of the eax register. */
-       if (insn == 0x66) {
-               shift = 16;
-               /* The instruction is 1 byte so far, read the next byte. */
-               insnlen = 1;
-               lgread(lg, &insn, physaddr + insnlen, 1);
-       }
-
-       /* We can ignore the lower bit for the moment and decode the 4 opcodes
-        * we need to emulate. */
-       switch (insn & 0xFE) {
-       case 0xE4: /* in     <next byte>,%al */
-               insnlen += 2;
-               in = 1;
-               break;
-       case 0xEC: /* in     (%dx),%al */
-               insnlen += 1;
-               in = 1;
-               break;
-       case 0xE6: /* out    %al,<next byte> */
-               insnlen += 2;
-               break;
-       case 0xEE: /* out    %al,(%dx) */
-               insnlen += 1;
-               break;
-       default:
-               /* OK, we don't know what this is, can't emulate. */
-               return 0;
-       }
-
-       /* If it was an "IN" instruction, they expect the result to be read
-        * into %eax, so we change %eax.  We always return all-ones, which
-        * traditionally means "there's nothing there". */
-       if (in) {
-               /* Lower bit tells is whether it's a 16 or 32 bit access */
-               if (insn & 0x1)
-                       lg->regs->eax = 0xFFFFFFFF;
-               else
-                       lg->regs->eax |= (0xFFFF << shift);
-       }
-       /* Finally, we've "done" the instruction, so move past it. */
-       lg->regs->eip += insnlen;
-       /* Success! */
-       return 1;
-}
-/*:*/
-
 /*L:305
  * Dealing With Guest Memory.
  *
  * When the Guest gives us (what it thinks is) a physical address, we can use
- * the normal copy_from_user() & copy_to_user() on that address: remember,
- * Guest physical == Launcher virtual.
+ * the normal copy_from_user() & copy_to_user() on the corresponding place in
+ * the memory region allocated by the Launcher.
  *
  * But we can't trust the Guest: it might be trying to access the Launcher
  * code.  We have to check that the range is below the pfn_limit the Launcher
@@ -338,148 +145,27 @@ int lguest_address_ok(const struct lguest *lg,
        return (addr+len) / PAGE_SIZE < lg->pfn_limit && (addr+len >= addr);
 }
 
-/* This is a convenient routine to get a 32-bit value from the Guest (a very
- * common operation).  Here we can see how useful the kill_lguest() routine we
- * met in the Launcher can be: we return a random value (0) instead of needing
- * to return an error. */
-u32 lgread_u32(struct lguest *lg, unsigned long addr)
-{
-       u32 val = 0;
-
-       /* Don't let them access lguest binary. */
-       if (!lguest_address_ok(lg, addr, sizeof(val))
-           || get_user(val, (u32 __user *)addr) != 0)
-               kill_guest(lg, "bad read address %#lx", addr);
-       return val;
-}
-
-/* Same thing for writing a value. */
-void lgwrite_u32(struct lguest *lg, unsigned long addr, u32 val)
-{
-       if (!lguest_address_ok(lg, addr, sizeof(val))
-           || put_user(val, (u32 __user *)addr) != 0)
-               kill_guest(lg, "bad write address %#lx", addr);
-}
-
-/* This routine is more generic, and copies a range of Guest bytes into a
- * buffer.  If the copy_from_user() fails, we fill the buffer with zeroes, so
- * the caller doesn't end up using uninitialized kernel memory. */
-void lgread(struct lguest *lg, void *b, unsigned long addr, unsigned bytes)
+/* This routine copies memory from the Guest.  Here we can see how useful the
+ * kill_lguest() routine we met in the Launcher can be: we return a random
+ * value (all zeroes) instead of needing to return an error. */
+void __lgread(struct lguest *lg, void *b, unsigned long addr, unsigned bytes)
 {
        if (!lguest_address_ok(lg, addr, bytes)
-           || copy_from_user(b, (void __user *)addr, bytes) != 0) {
+           || copy_from_user(b, lg->mem_base + addr, bytes) != 0) {
                /* copy_from_user should do this, but as we rely on it... */
                memset(b, 0, bytes);
                kill_guest(lg, "bad read address %#lx len %u", addr, bytes);
        }
 }
 
-/* Similarly, our generic routine to copy into a range of Guest bytes. */
-void lgwrite(struct lguest *lg, unsigned long addr, const void *b,
-            unsigned bytes)
+/* This is the write (copy into guest) version. */
+void __lgwrite(struct lguest *lg, unsigned long addr, const void *b,
+              unsigned bytes)
 {
        if (!lguest_address_ok(lg, addr, bytes)
-           || copy_to_user((void __user *)addr, b, bytes) != 0)
+           || copy_to_user(lg->mem_base + addr, b, bytes) != 0)
                kill_guest(lg, "bad write address %#lx len %u", addr, bytes);
 }
-/* (end of memory access helper routines) :*/
-
-static void set_ts(void)
-{
-       u32 cr0;
-
-       cr0 = read_cr0();
-       if (!(cr0 & 8))
-               write_cr0(cr0|8);
-}
-
-/*S:010
- * We are getting close to the Switcher.
- *
- * Remember that each CPU has two pages which are visible to the Guest when it
- * runs on that CPU.  This has to contain the state for that Guest: we copy the
- * state in just before we run the Guest.
- *
- * Each Guest has "changed" flags which indicate what has changed in the Guest
- * since it last ran.  We saw this set in interrupts_and_traps.c and
- * segments.c.
- */
-static void copy_in_guest_info(struct lguest *lg, struct lguest_pages *pages)
-{
-       /* Copying all this data can be quite expensive.  We usually run the
-        * same Guest we ran last time (and that Guest hasn't run anywhere else
-        * meanwhile).  If that's not the case, we pretend everything in the
-        * Guest has changed. */
-       if (__get_cpu_var(last_guest) != lg || lg->last_pages != pages) {
-               __get_cpu_var(last_guest) = lg;
-               lg->last_pages = pages;
-               lg->changed = CHANGED_ALL;
-       }
-
-       /* These copies are pretty cheap, so we do them unconditionally: */
-       /* Save the current Host top-level page directory. */
-       pages->state.host_cr3 = __pa(current->mm->pgd);
-       /* Set up the Guest's page tables to see this CPU's pages (and no
-        * other CPU's pages). */
-       map_switcher_in_guest(lg, pages);
-       /* Set up the two "TSS" members which tell the CPU what stack to use
-        * for traps which do directly into the Guest (ie. traps at privilege
-        * level 1). */
-       pages->state.guest_tss.esp1 = lg->esp1;
-       pages->state.guest_tss.ss1 = lg->ss1;
-
-       /* Copy direct-to-Guest trap entries. */
-       if (lg->changed & CHANGED_IDT)
-               copy_traps(lg, pages->state.guest_idt, default_idt_entries);
-
-       /* Copy all GDT entries which the Guest can change. */
-       if (lg->changed & CHANGED_GDT)
-               copy_gdt(lg, pages->state.guest_gdt);
-       /* If only the TLS entries have changed, copy them. */
-       else if (lg->changed & CHANGED_GDT_TLS)
-               copy_gdt_tls(lg, pages->state.guest_gdt);
-
-       /* Mark the Guest as unchanged for next time. */
-       lg->changed = 0;
-}
-
-/* Finally: the code to actually call into the Switcher to run the Guest. */
-static void run_guest_once(struct lguest *lg, struct lguest_pages *pages)
-{
-       /* This is a dummy value we need for GCC's sake. */
-       unsigned int clobber;
-
-       /* Copy the guest-specific information into this CPU's "struct
-        * lguest_pages". */
-       copy_in_guest_info(lg, pages);
-
-       /* Set the trap number to 256 (impossible value).  If we fault while
-        * switching to the Guest (bad segment registers or bug), this will
-        * cause us to abort the Guest. */
-       lg->regs->trapnum = 256;
-
-       /* Now: we push the "eflags" register on the stack, then do an "lcall".
-        * This is how we change from using the kernel code segment to using
-        * the dedicated lguest code segment, as well as jumping into the
-        * Switcher.
-        *
-        * The lcall also pushes the old code segment (KERNEL_CS) onto the
-        * stack, then the address of this call.  This stack layout happens to
-        * exactly match the stack of an interrupt... */
-       asm volatile("pushf; lcall *lguest_entry"
-                    /* This is how we tell GCC that %eax ("a") and %ebx ("b")
-                     * are changed by this routine.  The "=" means output. */
-                    : "=a"(clobber), "=b"(clobber)
-                    /* %eax contains the pages pointer.  ("0" refers to the
-                     * 0-th argument above, ie "a").  %ebx contains the
-                     * physical address of the Guest's top-level page
-                     * directory. */
-                    : "0"(pages), "1"(__pa(lg->pgdirs[lg->pgdidx].pgdir))
-                    /* We tell gcc that all these registers could change,
-                     * which means we don't have to save and restore them in
-                     * the Switcher. */
-                    : "memory", "%edx", "%ecx", "%edi", "%esi");
-}
 /*:*/
 
 /*H:030 Let's jump straight to the the main loop which runs the Guest.
@@ -489,22 +175,16 @@ int run_guest(struct lguest *lg, unsigned long __user *user)
 {
        /* We stop running once the Guest is dead. */
        while (!lg->dead) {
-               /* We need to initialize this, otherwise gcc complains.  It's
-                * not (yet) clever enough to see that it's initialized when we
-                * need it. */
-               unsigned int cr2 = 0; /* Damn gcc */
-
-               /* First we run any hypercalls the Guest wants done: either in
-                * the hypercall ring in "struct lguest_data", or directly by
-                * using int 31 (LGUEST_TRAP_ENTRY). */
-               do_hypercalls(lg);
-               /* It's possible the Guest did a SEND_DMA hypercall to the
+               /* First we run any hypercalls the Guest wants done. */
+               if (lg->hcall)
+                       do_hypercalls(lg);
+
+               /* It's possible the Guest did a NOTIFY hypercall to the
                 * Launcher, in which case we return from the read() now. */
-               if (lg->dma_is_pending) {
-                       if (put_user(lg->pending_dma, user) ||
-                           put_user(lg->pending_key, user+1))
+               if (lg->pending_notify) {
+                       if (put_user(lg->pending_notify, user))
                                return -EFAULT;
-                       return sizeof(unsigned long)*2;
+                       return sizeof(lg->pending_notify);
                }
 
                /* Check for signals */
@@ -542,144 +222,20 @@ int run_guest(struct lguest *lg, unsigned long __user *user)
                 * the "Do Not Disturb" sign: */
                local_irq_disable();
 
-               /* Remember the awfully-named TS bit?  If the Guest has asked
-                * to set it we set it now, so we can trap and pass that trap
-                * to the Guest if it uses the FPU. */
-               if (lg->ts)
-                       set_ts();
-
-               /* SYSENTER is an optimized way of doing system calls.  We
-                * can't allow it because it always jumps to privilege level 0.
-                * A normal Guest won't try it because we don't advertise it in
-                * CPUID, but a malicious Guest (or malicious Guest userspace
-                * program) could, so we tell the CPU to disable it before
-                * running the Guest. */
-               if (boot_cpu_has(X86_FEATURE_SEP))
-                       wrmsr(MSR_IA32_SYSENTER_CS, 0, 0);
-
-               /* Now we actually run the Guest.  It will pop back out when
-                * something interesting happens, and we can examine its
-                * registers to see what it was doing. */
-               run_guest_once(lg, lguest_pages(raw_smp_processor_id()));
-
-               /* The "regs" pointer contains two extra entries which are not
-                * really registers: a trap number which says what interrupt or
-                * trap made the switcher code come back, and an error code
-                * which some traps set.  */
-
-               /* If the Guest page faulted, then the cr2 register will tell
-                * us the bad virtual address.  We have to grab this now,
-                * because once we re-enable interrupts an interrupt could
-                * fault and thus overwrite cr2, or we could even move off to a
-                * different CPU. */
-               if (lg->regs->trapnum == 14)
-                       cr2 = read_cr2();
-               /* Similarly, if we took a trap because the Guest used the FPU,
-                * we have to restore the FPU it expects to see. */
-               else if (lg->regs->trapnum == 7)
-                       math_state_restore();
-
-               /* Restore SYSENTER if it's supposed to be on. */
-               if (boot_cpu_has(X86_FEATURE_SEP))
-                       wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
+               /* Actually run the Guest until something happens. */
+               lguest_arch_run_guest(lg);
 
                /* Now we're ready to be interrupted or moved to other CPUs */
                local_irq_enable();
 
-               /* OK, so what happened? */
-               switch (lg->regs->trapnum) {
-               case 13: /* We've intercepted a GPF. */
-                       /* Check if this was one of those annoying IN or OUT
-                        * instructions which we need to emulate.  If so, we
-                        * just go back into the Guest after we've done it. */
-                       if (lg->regs->errcode == 0) {
-                               if (emulate_insn(lg))
-                                       continue;
-                       }
-                       break;
-               case 14: /* We've intercepted a page fault. */
-                       /* The Guest accessed a virtual address that wasn't
-                        * mapped.  This happens a lot: we don't actually set
-                        * up most of the page tables for the Guest at all when
-                        * we start: as it runs it asks for more and more, and
-                        * we set them up as required. In this case, we don't
-                        * even tell the Guest that the fault happened.
-                        *
-                        * The errcode tells whether this was a read or a
-                        * write, and whether kernel or userspace code. */
-                       if (demand_page(lg, cr2, lg->regs->errcode))
-                               continue;
-
-                       /* OK, it's really not there (or not OK): the Guest
-                        * needs to know.  We write out the cr2 value so it
-                        * knows where the fault occurred.
-                        *
-                        * Note that if the Guest were really messed up, this
-                        * could happen before it's done the INITIALIZE
-                        * hypercall, so lg->lguest_data will be NULL, so
-                        * &lg->lguest_data->cr2 will be address 8.  Writing
-                        * into that address won't hurt the Host at all,
-                        * though. */
-                       if (put_user(cr2, &lg->lguest_data->cr2))
-                               kill_guest(lg, "Writing cr2");
-                       break;
-               case 7: /* We've intercepted a Device Not Available fault. */
-                       /* If the Guest doesn't want to know, we already
-                        * restored the Floating Point Unit, so we just
-                        * continue without telling it. */
-                       if (!lg->ts)
-                               continue;
-                       break;
-               case 32 ... 255:
-                       /* These values mean a real interrupt occurred, in
-                        * which case the Host handler has already been run.
-                        * We just do a friendly check if another process
-                        * should now be run, then fall through to loop
-                        * around: */
-                       cond_resched();
-               case LGUEST_TRAP_ENTRY: /* Handled at top of loop */
-                       continue;
-               }
-
-               /* If we get here, it's a trap the Guest wants to know
-                * about. */
-               if (deliver_trap(lg, lg->regs->trapnum))
-                       continue;
-
-               /* If the Guest doesn't have a handler (either it hasn't
-                * registered any yet, or it's one of the faults we don't let
-                * it handle), it dies with a cryptic error message. */
-               kill_guest(lg, "unhandled trap %li at %#lx (%#lx)",
-                          lg->regs->trapnum, lg->regs->eip,
-                          lg->regs->trapnum == 14 ? cr2 : lg->regs->errcode);
+               /* Now we deal with whatever happened to the Guest. */
+               lguest_arch_handle_trap(lg);
        }
+
        /* The Guest is dead => "No such file or directory" */
        return -ENOENT;
 }
 
-/* Now we can look at each of the routines this calls, in increasing order of
- * complexity: do_hypercalls(), emulate_insn(), maybe_do_interrupt(),
- * deliver_trap() and demand_page().  After all those, we'll be ready to
- * examine the Switcher, and our philosophical understanding of the Host/Guest
- * duality will be complete. :*/
-
-int find_free_guest(void)
-{
-       unsigned int i;
-       for (i = 0; i < MAX_LGUEST_GUESTS; i++)
-               if (!lguests[i].tsk)
-                       return i;
-       return -1;
-}
-
-static void adjust_pge(void *on)
-{
-       if (on)
-               write_cr4(read_cr4() | X86_CR4_PGE);
-       else
-               write_cr4(read_cr4() & ~X86_CR4_PGE);
-}
-
 /*H:000
  * Welcome to the Host!
  *
@@ -701,72 +257,50 @@ static int __init init(void)
        /* First we put the Switcher up in very high virtual memory. */
        err = map_switcher();
        if (err)
-               return err;
+               goto out;
 
        /* Now we set up the pagetable implementation for the Guests. */
        err = init_pagetables(switcher_page, SHARED_SWITCHER_PAGES);
-       if (err) {
-               unmap_switcher();
-               return err;
-       }
+       if (err)
+               goto unmap;
 
-       /* The I/O subsystem needs some things initialized. */
-       lguest_io_init();
+       /* We might need to reserve an interrupt vector. */
+       err = init_interrupts();
+       if (err)
+               goto free_pgtables;
 
        /* /dev/lguest needs to be registered. */
        err = lguest_device_init();
-       if (err) {
-               free_pagetables();
-               unmap_switcher();
-               return err;
-       }
+       if (err)
+               goto free_interrupts;
 
-       /* Finally, we need to turn off "Page Global Enable".  PGE is an
-        * optimization where page table entries are specially marked to show
-        * they never change.  The Host kernel marks all the kernel pages this
-        * way because it's always present, even when userspace is running.
-        *
-        * Lguest breaks this: unbeknownst to the rest of the Host kernel, we
-        * switch to the Guest kernel.  If you don't disable this on all CPUs,
-        * you'll get really weird bugs that you'll chase for two days.
-        *
-        * I used to turn PGE off every time we switched to the Guest and back
-        * on when we return, but that slowed the Switcher down noticibly. */
-
-       /* We don't need the complexity of CPUs coming and going while we're
-        * doing this. */
-       lock_cpu_hotplug();
-       if (cpu_has_pge) { /* We have a broader idea of "global". */
-               /* Remember that this was originally set (for cleanup). */
-               cpu_had_pge = 1;
-               /* adjust_pge is a helper function which sets or unsets the PGE
-                * bit on its CPU, depending on the argument (0 == unset). */
-               on_each_cpu(adjust_pge, (void *)0, 0, 1);
-               /* Turn off the feature in the global feature set. */
-               clear_bit(X86_FEATURE_PGE, boot_cpu_data.x86_capability);
-       }
-       unlock_cpu_hotplug();
+       /* Finally we do some architecture-specific setup. */
+       lguest_arch_host_init();
 
        /* All good! */
        return 0;
+
+free_interrupts:
+       free_interrupts();
+free_pgtables:
+       free_pagetables();
+unmap:
+       unmap_switcher();
+out:
+       return err;
 }
 
 /* Cleaning up is just the same code, backwards.  With a little French. */
 static void __exit fini(void)
 {
        lguest_device_remove();
+       free_interrupts();
        free_pagetables();
        unmap_switcher();
 
-       /* If we had PGE before we started, turn it back on now. */
-       lock_cpu_hotplug();
-       if (cpu_had_pge) {
-               set_bit(X86_FEATURE_PGE, boot_cpu_data.x86_capability);
-               /* adjust_pge's argument "1" means set PGE. */
-               on_each_cpu(adjust_pge, (void *)1, 0, 1);
-       }
-       unlock_cpu_hotplug();
+       lguest_arch_host_fini();
 }
+/*:*/
 
 /* The Host side of lguest can be a module.  This is a nice way for people to
  * play with it.  */
index db6caace3b9c22a7ce16a85580de212d318c4cd2..9d5184c7c14afc83652843f6d3cfe1534a3dcf7e 100644 (file)
 #include <linux/mm.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
-#include <irq_vectors.h>
 #include "lg.h"
 
-/*H:120 This is the core hypercall routine: where the Guest gets what it
- * wants.  Or gets killed.  Or, in the case of LHCALL_CRASH, both.
- *
- * Remember from the Guest: %eax == which call to make, and the arguments are
- * packed into %edx, %ebx and %ecx if needed. */
-static void do_hcall(struct lguest *lg, struct lguest_regs *regs)
+/*H:120 This is the core hypercall routine: where the Guest gets what it wants.
+ * Or gets killed.  Or, in the case of LHCALL_CRASH, both. */
+static void do_hcall(struct lguest *lg, struct hcall_args *args)
 {
-       switch (regs->eax) {
+       switch (args->arg0) {
        case LHCALL_FLUSH_ASYNC:
                /* This call does nothing, except by breaking out of the Guest
                 * it makes us process all the asynchronous hypercalls. */
@@ -51,7 +47,7 @@ static void do_hcall(struct lguest *lg, struct lguest_regs *regs)
                char msg[128];
                /* If the lgread fails, it will call kill_guest() itself; the
                 * kill_guest() with the message will be ignored. */
-               lgread(lg, msg, regs->edx, sizeof(msg));
+               __lgread(lg, msg, args->arg1, sizeof(msg));
                msg[sizeof(msg)-1] = '\0';
                kill_guest(lg, "CRASH: %s", msg);
                break;
@@ -59,67 +55,49 @@ static void do_hcall(struct lguest *lg, struct lguest_regs *regs)
        case LHCALL_FLUSH_TLB:
                /* FLUSH_TLB comes in two flavors, depending on the
                 * argument: */
-               if (regs->edx)
+               if (args->arg1)
                        guest_pagetable_clear_all(lg);
                else
                        guest_pagetable_flush_user(lg);
                break;
-       case LHCALL_BIND_DMA:
-               /* BIND_DMA really wants four arguments, but it's the only call
-                * which does.  So the Guest packs the number of buffers and
-                * the interrupt number into the final argument, and we decode
-                * it here.  This can legitimately fail, since we currently
-                * place a limit on the number of DMA pools a Guest can have.
-                * So we return true or false from this call. */
-               regs->eax = bind_dma(lg, regs->edx, regs->ebx,
-                                    regs->ecx >> 8, regs->ecx & 0xFF);
-               break;
 
        /* All these calls simply pass the arguments through to the right
         * routines. */
-       case LHCALL_SEND_DMA:
-               send_dma(lg, regs->edx, regs->ebx);
-               break;
-       case LHCALL_LOAD_GDT:
-               load_guest_gdt(lg, regs->edx, regs->ebx);
-               break;
-       case LHCALL_LOAD_IDT_ENTRY:
-               load_guest_idt_entry(lg, regs->edx, regs->ebx, regs->ecx);
-               break;
        case LHCALL_NEW_PGTABLE:
-               guest_new_pagetable(lg, regs->edx);
+               guest_new_pagetable(lg, args->arg1);
                break;
        case LHCALL_SET_STACK:
-               guest_set_stack(lg, regs->edx, regs->ebx, regs->ecx);
+               guest_set_stack(lg, args->arg1, args->arg2, args->arg3);
                break;
        case LHCALL_SET_PTE:
-               guest_set_pte(lg, regs->edx, regs->ebx, mkgpte(regs->ecx));
+               guest_set_pte(lg, args->arg1, args->arg2, __pte(args->arg3));
                break;
        case LHCALL_SET_PMD:
-               guest_set_pmd(lg, regs->edx, regs->ebx);
-               break;
-       case LHCALL_LOAD_TLS:
-               guest_load_tls(lg, regs->edx);
+               guest_set_pmd(lg, args->arg1, args->arg2);
                break;
        case LHCALL_SET_CLOCKEVENT:
-               guest_set_clockevent(lg, regs->edx);
+               guest_set_clockevent(lg, args->arg1);
                break;
-
        case LHCALL_TS:
                /* This sets the TS flag, as we saw used in run_guest(). */
-               lg->ts = regs->edx;
+               lg->ts = args->arg1;
                break;
        case LHCALL_HALT:
                /* Similarly, this sets the halted flag for run_guest(). */
                lg->halted = 1;
                break;
+       case LHCALL_NOTIFY:
+               lg->pending_notify = args->arg1;
+               break;
        default:
-               kill_guest(lg, "Bad hypercall %li\n", regs->eax);
+               if (lguest_arch_do_hcall(lg, args))
+                       kill_guest(lg, "Bad hypercall %li\n", args->arg0);
        }
 }
+/*:*/
 
-/* Asynchronous hypercalls are easy: we just look in the array in the Guest's
- * "struct lguest_data" and see if there are any new ones marked "ready".
+/*H:124 Asynchronous hypercalls are easy: we just look in the array in the
+ * Guest's "struct lguest_data" to see if any new ones are marked "ready".
  *
  * We are careful to do these in order: obviously we respect the order the
  * Guest put them in the ring, but we also promise the Guest that they will
@@ -134,10 +112,9 @@ static void do_async_hcalls(struct lguest *lg)
        if (copy_from_user(&st, &lg->lguest_data->hcall_status, sizeof(st)))
                return;
 
-
        /* We process "struct lguest_data"s hcalls[] ring once. */
        for (i = 0; i < ARRAY_SIZE(st); i++) {
-               struct lguest_regs regs;
+               struct hcall_args args;
                /* We remember where we were up to from last time.  This makes
                 * sure that the hypercalls are done in the order the Guest
                 * places them in the ring. */
@@ -152,18 +129,16 @@ static void do_async_hcalls(struct lguest *lg)
                if (++lg->next_hcall == LHCALL_RING_SIZE)
                        lg->next_hcall = 0;
 
-               /* We copy the hypercall arguments into a fake register
-                * structure.  This makes life simple for do_hcall(). */
-               if (get_user(regs.eax, &lg->lguest_data->hcalls[n].eax)
-                   || get_user(regs.edx, &lg->lguest_data->hcalls[n].edx)
-                   || get_user(regs.ecx, &lg->lguest_data->hcalls[n].ecx)
-                   || get_user(regs.ebx, &lg->lguest_data->hcalls[n].ebx)) {
+               /* Copy the hypercall arguments into a local copy of
+                * the hcall_args struct. */
+               if (copy_from_user(&args, &lg->lguest_data->hcalls[n],
+                                  sizeof(struct hcall_args))) {
                        kill_guest(lg, "Fetching async hypercalls");
                        break;
                }
 
                /* Do the hypercall, same as a normal one. */
-               do_hcall(lg, &regs);
+               do_hcall(lg, &args);
 
                /* Mark the hypercall done. */
                if (put_user(0xFF, &lg->lguest_data->hcall_status[n])) {
@@ -171,9 +146,9 @@ static void do_async_hcalls(struct lguest *lg)
                        break;
                }
 
-               /* Stop doing hypercalls if we've just done a DMA to the
-                * Launcher: it needs to service this first. */
-               if (lg->dma_is_pending)
+               /* Stop doing hypercalls if they want to notify the Launcher:
+                * it needs to service this first. */
+               if (lg->pending_notify)
                        break;
        }
 }
@@ -182,76 +157,35 @@ static void do_async_hcalls(struct lguest *lg)
  * Guest makes a hypercall, we end up here to set things up: */
 static void initialize(struct lguest *lg)
 {
-       u32 tsc_speed;
 
        /* You can't do anything until you're initialized.  The Guest knows the
         * rules, so we're unforgiving here. */
-       if (lg->regs->eax != LHCALL_LGUEST_INIT) {
-               kill_guest(lg, "hypercall %li before LGUEST_INIT",
-                          lg->regs->eax);
+       if (lg->hcall->arg0 != LHCALL_LGUEST_INIT) {
+               kill_guest(lg, "hypercall %li before INIT", lg->hcall->arg0);
                return;
        }
 
-       /* We insist that the Time Stamp Counter exist and doesn't change with
-        * cpu frequency.  Some devious chip manufacturers decided that TSC
-        * changes could be handled in software.  I decided that time going
-        * backwards might be good for benchmarks, but it's bad for users.
-        *
-        * We also insist that the TSC be stable: the kernel detects unreliable
-        * TSCs for its own purposes, and we use that here. */
-       if (boot_cpu_has(X86_FEATURE_CONSTANT_TSC) && !check_tsc_unstable())
-               tsc_speed = tsc_khz;
-       else
-               tsc_speed = 0;
-
-       /* The pointer to the Guest's "struct lguest_data" is the only
-        * argument. */
-       lg->lguest_data = (struct lguest_data __user *)lg->regs->edx;
-       /* If we check the address they gave is OK now, we can simply
-        * copy_to_user/from_user from now on rather than using lgread/lgwrite.
-        * I put this in to show that I'm not immune to writing stupid
-        * optimizations. */
-       if (!lguest_address_ok(lg, lg->regs->edx, sizeof(*lg->lguest_data))) {
+       if (lguest_arch_init_hypercalls(lg))
                kill_guest(lg, "bad guest page %p", lg->lguest_data);
-               return;
-       }
+
        /* The Guest tells us where we're not to deliver interrupts by putting
         * the range of addresses into "struct lguest_data". */
        if (get_user(lg->noirq_start, &lg->lguest_data->noirq_start)
-           || get_user(lg->noirq_end, &lg->lguest_data->noirq_end)
-           /* We tell the Guest that it can't use the top 4MB of virtual
-            * addresses used by the Switcher. */
-           || put_user(4U*1024*1024, &lg->lguest_data->reserve_mem)
-           || put_user(tsc_speed, &lg->lguest_data->tsc_khz)
-           /* We also give the Guest a unique id, as used in lguest_net.c. */
-           || put_user(lg->guestid, &lg->lguest_data->guestid))
+           || get_user(lg->noirq_end, &lg->lguest_data->noirq_end))
                kill_guest(lg, "bad guest page %p", lg->lguest_data);
 
        /* We write the current time into the Guest's data page once now. */
        write_timestamp(lg);
 
+       /* page_tables.c will also do some setup. */
+       page_table_guest_data_init(lg);
+
        /* This is the one case where the above accesses might have been the
         * first write to a Guest page.  This may have caused a copy-on-write
         * fault, but the Guest might be referring to the old (read-only)
         * page. */
        guest_pagetable_clear_all(lg);
 }
-/* Now we've examined the hypercall code; our Guest can make requests.  There
- * is one other way we can do things for the Guest, as we see in
- * emulate_insn(). */
-
-/*H:110 Tricky point: we mark the hypercall as "done" once we've done it.
- * Normally we don't need to do this: the Guest will run again and update the
- * trap number before we come back around the run_guest() loop to
- * do_hypercalls().
- *
- * However, if we are signalled or the Guest sends DMA to the Launcher, that
- * loop will exit without running the Guest.  When it comes back it would try
- * to re-run the hypercall. */
-static void clear_hcall(struct lguest *lg)
-{
-       lg->regs->trapnum = 255;
-}
 
 /*H:100
  * Hypercalls
@@ -261,16 +195,12 @@ static void clear_hcall(struct lguest *lg)
  */
 void do_hypercalls(struct lguest *lg)
 {
-       /* Not initialized yet? */
+       /* Not initialized yet?  This hypercall must do it. */
        if (unlikely(!lg->lguest_data)) {
-               /* Did the Guest make a hypercall?  We might have come back for
-                * some other reason (an interrupt, a different trap). */
-               if (lg->regs->trapnum == LGUEST_TRAP_ENTRY) {
-                       /* Set up the "struct lguest_data" */
-                       initialize(lg);
-                       /* The hypercall is done. */
-                       clear_hcall(lg);
-               }
+               /* Set up the "struct lguest_data" */
+               initialize(lg);
+               /* Hcall is done. */
+               lg->hcall = NULL;
                return;
        }
 
@@ -280,12 +210,21 @@ void do_hypercalls(struct lguest *lg)
        do_async_hcalls(lg);
 
        /* If we stopped reading the hypercall ring because the Guest did a
-        * SEND_DMA to the Launcher, we want to return now.  Otherwise if the
-        * Guest asked us to do a hypercall, we do it. */
-       if (!lg->dma_is_pending && lg->regs->trapnum == LGUEST_TRAP_ENTRY) {
-               do_hcall(lg, lg->regs);
-               /* The hypercall is done. */
-               clear_hcall(lg);
+        * NOTIFY to the Launcher, we want to return now.  Otherwise we do
+        * the hypercall. */
+       if (!lg->pending_notify) {
+               do_hcall(lg, lg->hcall);
+               /* Tricky point: we reset the hcall pointer to mark the
+                * hypercall as "done".  We use the hcall pointer rather than
+                * the trap number to indicate a hypercall is pending.
+                * Normally it doesn't matter: the Guest will run again and
+                * update the trap number before we come back here.
+                *
+                * However, if we are signalled or the Guest sends DMA to the
+                * Launcher, the run_guest() loop will exit without running the
+                * Guest.  When it comes back it would try to re-run the
+                * hypercall. */
+               lg->hcall = NULL;
        }
 }
 
@@ -295,6 +234,6 @@ void write_timestamp(struct lguest *lg)
 {
        struct timespec now;
        ktime_get_real_ts(&now);
-       if (put_user(now, &lg->lguest_data->time))
+       if (copy_to_user(&lg->lguest_data->time, &now, sizeof(struct timespec)))
                kill_guest(lg, "Writing timestamp");
 }
index 39731232d82770ecc3a4bb0d76cb27d4b9578621..82966982cb38ed13b515bcae06e56557d6c72a27 100644 (file)
  * them first, so we also have a way of "reflecting" them into the Guest as if
  * they had been delivered to it directly. :*/
 #include <linux/uaccess.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
 #include "lg.h"
 
+/* Allow Guests to use a non-128 (ie. non-Linux) syscall trap. */
+static unsigned int syscall_vector = SYSCALL_VECTOR;
+module_param(syscall_vector, uint, 0444);
+
 /* The address of the interrupt handler is split into two bits: */
 static unsigned long idt_address(u32 lo, u32 hi)
 {
@@ -39,7 +45,7 @@ static void push_guest_stack(struct lguest *lg, unsigned long *gstack, u32 val)
 {
        /* Stack grows upwards: move stack then write value. */
        *gstack -= 4;
-       lgwrite_u32(lg, *gstack, val);
+       lgwrite(lg, *gstack, u32, val);
 }
 
 /*H:210 The set_guest_interrupt() routine actually delivers the interrupt or
@@ -56,8 +62,9 @@ static void push_guest_stack(struct lguest *lg, unsigned long *gstack, u32 val)
  * it). */
 static void set_guest_interrupt(struct lguest *lg, u32 lo, u32 hi, int has_err)
 {
-       unsigned long gstack;
+       unsigned long gstack, origstack;
        u32 eflags, ss, irq_enable;
+       unsigned long virtstack;
 
        /* There are two cases for interrupts: one where the Guest is already
         * in the kernel, and a more complex one where the Guest is in
@@ -65,8 +72,10 @@ static void set_guest_interrupt(struct lguest *lg, u32 lo, u32 hi, int has_err)
        if ((lg->regs->ss&0x3) != GUEST_PL) {
                /* The Guest told us their kernel stack with the SET_STACK
                 * hypercall: both the virtual address and the segment */
-               gstack = guest_pa(lg, lg->esp1);
+               virtstack = lg->esp1;
                ss = lg->ss1;
+
+               origstack = gstack = guest_pa(lg, virtstack);
                /* We push the old stack segment and pointer onto the new
                 * stack: when the Guest does an "iret" back from the interrupt
                 * handler the CPU will notice they're dropping privilege
@@ -75,8 +84,10 @@ static void set_guest_interrupt(struct lguest *lg, u32 lo, u32 hi, int has_err)
                push_guest_stack(lg, &gstack, lg->regs->esp);
        } else {
                /* We're staying on the same Guest (kernel) stack. */
-               gstack = guest_pa(lg, lg->regs->esp);
+               virtstack = lg->regs->esp;
                ss = lg->regs->ss;
+
+               origstack = gstack = guest_pa(lg, virtstack);
        }
 
        /* Remember that we never let the Guest actually disable interrupts, so
@@ -102,7 +113,7 @@ static void set_guest_interrupt(struct lguest *lg, u32 lo, u32 hi, int has_err)
        /* Now we've pushed all the old state, we change the stack, the code
         * segment and the address to execute. */
        lg->regs->ss = ss;
-       lg->regs->esp = gstack + lg->page_offset;
+       lg->regs->esp = virtstack + (gstack - origstack);
        lg->regs->cs = (__KERNEL_CS|GUEST_PL);
        lg->regs->eip = idt_address(lo, hi);
 
@@ -165,7 +176,7 @@ void maybe_do_interrupt(struct lguest *lg)
        /* Look at the IDT entry the Guest gave us for this interrupt.  The
         * first 32 (FIRST_EXTERNAL_VECTOR) entries are for traps, so we skip
         * over them. */
-       idt = &lg->idt[FIRST_EXTERNAL_VECTOR+irq];
+       idt = &lg->arch.idt[FIRST_EXTERNAL_VECTOR+irq];
        /* If they don't have a handler (yet?), we just ignore it */
        if (idt_present(idt->a, idt->b)) {
                /* OK, mark it no longer pending and deliver it. */
@@ -183,6 +194,47 @@ void maybe_do_interrupt(struct lguest *lg)
         * timer interrupt. */
        write_timestamp(lg);
 }
+/*:*/
+
+/* Linux uses trap 128 for system calls.  Plan9 uses 64, and Ron Minnich sent
+ * me a patch, so we support that too.  It'd be a big step for lguest if half
+ * the Plan 9 user base were to start using it.
+ *
+ * Actually now I think of it, it's possible that Ron *is* half the Plan 9
+ * userbase.  Oh well. */
+static bool could_be_syscall(unsigned int num)
+{
+       /* Normal Linux SYSCALL_VECTOR or reserved vector? */
+       return num == SYSCALL_VECTOR || num == syscall_vector;
+}
+
+/* The syscall vector it wants must be unused by Host. */
+bool check_syscall_vector(struct lguest *lg)
+{
+       u32 vector;
+
+       if (get_user(vector, &lg->lguest_data->syscall_vec))
+               return false;
+
+       return could_be_syscall(vector);
+}
+
+int init_interrupts(void)
+{
+       /* If they want some strange system call vector, reserve it now */
+       if (syscall_vector != SYSCALL_VECTOR
+           && test_and_set_bit(syscall_vector, used_vectors)) {
+               printk("lg: couldn't reserve syscall %u\n", syscall_vector);
+               return -EBUSY;
+       }
+       return 0;
+}
+
+void free_interrupts(void)
+{
+       if (syscall_vector != SYSCALL_VECTOR)
+               clear_bit(syscall_vector, used_vectors);
+}
 
 /*H:220 Now we've got the routines to deliver interrupts, delivering traps
  * like page fault is easy.  The only trick is that Intel decided that some
@@ -197,14 +249,14 @@ int deliver_trap(struct lguest *lg, unsigned int num)
 {
        /* Trap numbers are always 8 bit, but we set an impossible trap number
         * for traps inside the Switcher, so check that here. */
-       if (num >= ARRAY_SIZE(lg->idt))
+       if (num >= ARRAY_SIZE(lg->arch.idt))
                return 0;
 
        /* Early on the Guest hasn't set the IDT entries (or maybe it put a
         * bogus one in): if we fail here, the Guest will be killed. */
-       if (!idt_present(lg->idt[num].a, lg->idt[num].b))
+       if (!idt_present(lg->arch.idt[num].a, lg->arch.idt[num].b))
                return 0;
-       set_guest_interrupt(lg, lg->idt[num].a, lg->idt[num].b, has_err(num));
+       set_guest_interrupt(lg, lg->arch.idt[num].a, lg->arch.idt[num].b, has_err(num));
        return 1;
 }
 
@@ -218,28 +270,20 @@ int deliver_trap(struct lguest *lg, unsigned int num)
  * system calls down from 1750ns to 270ns.  Plus, if lguest didn't do it, all
  * the other hypervisors would tease it.
  *
- * This routine determines if a trap can be delivered directly. */
-static int direct_trap(const struct lguest *lg,
-                      const struct desc_struct *trap,
-                      unsigned int num)
+ * This routine indicates if a particular trap number could be delivered
+ * directly. */
+static int direct_trap(unsigned int num)
 {
        /* Hardware interrupts don't go to the Guest at all (except system
         * call). */
-       if (num >= FIRST_EXTERNAL_VECTOR && num != SYSCALL_VECTOR)
+       if (num >= FIRST_EXTERNAL_VECTOR && !could_be_syscall(num))
                return 0;
 
        /* The Host needs to see page faults (for shadow paging and to save the
         * fault address), general protection faults (in/out emulation) and
         * device not available (TS handling), and of course, the hypercall
         * trap. */
-       if (num == 14 || num == 13 || num == 7 || num == LGUEST_TRAP_ENTRY)
-               return 0;
-
-       /* Only trap gates (type 15) can go direct to the Guest.  Interrupt
-        * gates (type 14) disable interrupts as they are entered, which we
-        * never let the Guest do.  Not present entries (type 0x0) also can't
-        * go direct, of course 8) */
-       return idt_type(trap->a, trap->b) == 0xF;
+       return num != 14 && num != 13 && num != 7 && num != LGUEST_TRAP_ENTRY;
 }
 /*:*/
 
@@ -348,15 +392,11 @@ void load_guest_idt_entry(struct lguest *lg, unsigned int num, u32 lo, u32 hi)
         * to copy this again. */
        lg->changed |= CHANGED_IDT;
 
-       /* The IDT which we keep in "struct lguest" only contains 32 entries
-        * for the traps and LGUEST_IRQS (32) entries for interrupts.  We
-        * ignore attempts to set handlers for higher interrupt numbers, except
-        * for the system call "interrupt" at 128: we have a special IDT entry
-        * for that. */
-       if (num < ARRAY_SIZE(lg->idt))
-               set_trap(lg, &lg->idt[num], num, lo, hi);
-       else if (num == SYSCALL_VECTOR)
-               set_trap(lg, &lg->syscall_idt, num, lo, hi);
+       /* Check that the Guest doesn't try to step outside the bounds. */
+       if (num >= ARRAY_SIZE(lg->arch.idt))
+               kill_guest(lg, "Setting idt entry %u", num);
+       else
+               set_trap(lg, &lg->arch.idt[num], num, lo, hi);
 }
 
 /* The default entry for each interrupt points into the Switcher routines which
@@ -399,20 +439,21 @@ void copy_traps(const struct lguest *lg, struct desc_struct *idt,
 
        /* We can simply copy the direct traps, otherwise we use the default
         * ones in the Switcher: they will return to the Host. */
-       for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++) {
-               if (direct_trap(lg, &lg->idt[i], i))
-                       idt[i] = lg->idt[i];
+       for (i = 0; i < ARRAY_SIZE(lg->arch.idt); i++) {
+               /* If no Guest can ever override this trap, leave it alone. */
+               if (!direct_trap(i))
+                       continue;
+
+               /* Only trap gates (type 15) can go direct to the Guest.
+                * Interrupt gates (type 14) disable interrupts as they are
+                * entered, which we never let the Guest do.  Not present
+                * entries (type 0x0) also can't go direct, of course. */
+               if (idt_type(lg->arch.idt[i].a, lg->arch.idt[i].b) == 0xF)
+                       idt[i] = lg->arch.idt[i];
                else
+                       /* Reset it to the default. */
                        default_idt_entry(&idt[i], i, def[i]);
        }
-
-       /* Don't forget the system call trap!  The IDT entries for other
-        * interupts never change, so no need to copy them. */
-       i = SYSCALL_VECTOR;
-       if (direct_trap(lg, &lg->syscall_idt, i))
-               idt[i] = lg->syscall_idt;
-       else
-               default_idt_entry(&idt[i], i, def[i]);
 }
 
 void guest_set_clockevent(struct lguest *lg, unsigned long delta)
diff --git a/drivers/lguest/io.c b/drivers/lguest/io.c
deleted file mode 100644 (file)
index ea68613..0000000
+++ /dev/null
@@ -1,626 +0,0 @@
-/*P:300 The I/O mechanism in lguest is simple yet flexible, allowing the Guest
- * to talk to the Launcher or directly to another Guest.  It uses familiar
- * concepts of DMA and interrupts, plus some neat code stolen from
- * futexes... :*/
-
-/* Copyright (C) 2006 Rusty Russell 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
- */
-#include <linux/types.h>
-#include <linux/futex.h>
-#include <linux/jhash.h>
-#include <linux/mm.h>
-#include <linux/highmem.h>
-#include <linux/uaccess.h>
-#include "lg.h"
-
-/*L:300
- * I/O
- *
- * Getting data in and out of the Guest is quite an art.  There are numerous
- * ways to do it, and they all suck differently.  We try to keep things fairly
- * close to "real" hardware so our Guest's drivers don't look like an alien
- * visitation in the middle of the Linux code, and yet make sure that Guests
- * can talk directly to other Guests, not just the Launcher.
- *
- * To do this, the Guest gives us a key when it binds or sends DMA buffers.
- * The key corresponds to a "physical" address inside the Guest (ie. a virtual
- * address inside the Launcher process).  We don't, however, use this key
- * directly.
- *
- * We want Guests which share memory to be able to DMA to each other: two
- * Launchers can mmap memory the same file, then the Guests can communicate.
- * Fortunately, the futex code provides us with a way to get a "union
- * futex_key" corresponding to the memory lying at a virtual address: if the
- * two processes share memory, the "union futex_key" for that memory will match
- * even if the memory is mapped at different addresses in each.  So we always
- * convert the keys to "union futex_key"s to compare them.
- *
- * Before we dive into this though, we need to look at another set of helper
- * routines used throughout the Host kernel code to access Guest memory.
- :*/
-static struct list_head dma_hash[61];
-
-/* An unfortunate side effect of the Linux double-linked list implementation is
- * that there's no good way to statically initialize an array of linked
- * lists. */
-void lguest_io_init(void)
-{
-       unsigned int i;
-
-       for (i = 0; i < ARRAY_SIZE(dma_hash); i++)
-               INIT_LIST_HEAD(&dma_hash[i]);
-}
-
-/* FIXME: allow multi-page lengths. */
-static int check_dma_list(struct lguest *lg, const struct lguest_dma *dma)
-{
-       unsigned int i;
-
-       for (i = 0; i < LGUEST_MAX_DMA_SECTIONS; i++) {
-               if (!dma->len[i])
-                       return 1;
-               if (!lguest_address_ok(lg, dma->addr[i], dma->len[i]))
-                       goto kill;
-               if (dma->len[i] > PAGE_SIZE)
-                       goto kill;
-               /* We could do over a page, but is it worth it? */
-               if ((dma->addr[i] % PAGE_SIZE) + dma->len[i] > PAGE_SIZE)
-                       goto kill;
-       }
-       return 1;
-
-kill:
-       kill_guest(lg, "bad DMA entry: %u@%#lx", dma->len[i], dma->addr[i]);
-       return 0;
-}
-
-/*L:330 This is our hash function, using the wonderful Jenkins hash.
- *
- * The futex key is a union with three parts: an unsigned long word, a pointer,
- * and an int "offset".  We could use jhash_2words() which takes three u32s.
- * (Ok, the hash functions are great: the naming sucks though).
- *
- * It's nice to be portable to 64-bit platforms, so we use the more generic
- * jhash2(), which takes an array of u32, the number of u32s, and an initial
- * u32 to roll in.  This is uglier, but breaks down to almost the same code on
- * 32-bit platforms like this one.
- *
- * We want a position in the array, so we modulo ARRAY_SIZE(dma_hash) (ie. 61).
- */
-static unsigned int hash(const union futex_key *key)
-{
-       return jhash2((u32*)&key->both.word,
-                     (sizeof(key->both.word)+sizeof(key->both.ptr))/4,
-                     key->both.offset)
-               % ARRAY_SIZE(dma_hash);
-}
-
-/* This is a convenience routine to compare two keys.  It's a much bemoaned C
- * weakness that it doesn't allow '==' on structures or unions, so we have to
- * open-code it like this. */
-static inline int key_eq(const union futex_key *a, const union futex_key *b)
-{
-       return (a->both.word == b->both.word
-               && a->both.ptr == b->both.ptr
-               && a->both.offset == b->both.offset);
-}
-
-/*L:360 OK, when we need to actually free up a Guest's DMA array we do several
- * things, so we have a convenient function to do it.
- *
- * The caller must hold a read lock on dmainfo owner's current->mm->mmap_sem
- * for the drop_futex_key_refs(). */
-static void unlink_dma(struct lguest_dma_info *dmainfo)
-{
-       /* You locked this too, right? */
-       BUG_ON(!mutex_is_locked(&lguest_lock));
-       /* This is how we know that the entry is free. */
-       dmainfo->interrupt = 0;
-       /* Remove it from the hash table. */
-       list_del(&dmainfo->list);
-       /* Drop the references we were holding (to the inode or mm). */
-       drop_futex_key_refs(&dmainfo->key);
-}
-
-/*L:350 This is the routine which we call when the Guest asks to unregister a
- * DMA array attached to a given key.  Returns true if the array was found. */
-static int unbind_dma(struct lguest *lg,
-                     const union futex_key *key,
-                     unsigned long dmas)
-{
-       int i, ret = 0;
-
-       /* We don't bother with the hash table, just look through all this
-        * Guest's DMA arrays. */
-       for (i = 0; i < LGUEST_MAX_DMA; i++) {
-               /* In theory it could have more than one array on the same key,
-                * or one array on multiple keys, so we check both */
-               if (key_eq(key, &lg->dma[i].key) && dmas == lg->dma[i].dmas) {
-                       unlink_dma(&lg->dma[i]);
-                       ret = 1;
-                       break;
-               }
-       }
-       return ret;
-}
-
-/*L:340 BIND_DMA: this is the hypercall which sets up an array of "struct
- * lguest_dma" for receiving I/O.
- *
- * The Guest wants to bind an array of "struct lguest_dma"s to a particular key
- * to receive input.  This only happens when the Guest is setting up a new
- * device, so it doesn't have to be very fast.
- *
- * It returns 1 on a successful registration (it can fail if we hit the limit
- * of registrations for this Guest).
- */
-int bind_dma(struct lguest *lg,
-            unsigned long ukey, unsigned long dmas, u16 numdmas, u8 interrupt)
-{
-       unsigned int i;
-       int ret = 0;
-       union futex_key key;
-       /* Futex code needs the mmap_sem. */
-       struct rw_semaphore *fshared = &current->mm->mmap_sem;
-
-       /* Invalid interrupt?  (We could kill the guest here). */
-       if (interrupt >= LGUEST_IRQS)
-               return 0;
-
-       /* We need to grab the Big Lguest Lock, because other Guests may be
-        * trying to look through this Guest's DMAs to send something while
-        * we're doing this. */
-       mutex_lock(&lguest_lock);
-       down_read(fshared);
-       if (get_futex_key((u32 __user *)ukey, fshared, &key) != 0) {
-               kill_guest(lg, "bad dma key %#lx", ukey);
-               goto unlock;
-       }
-
-       /* We want to keep this key valid once we drop mmap_sem, so we have to
-        * hold a reference. */
-       get_futex_key_refs(&key);
-
-       /* If the Guest specified an interrupt of 0, that means they want to
-        * unregister this array of "struct lguest_dma"s. */
-       if (interrupt == 0)
-               ret = unbind_dma(lg, &key, dmas);
-       else {
-               /* Look through this Guest's dma array for an unused entry. */
-               for (i = 0; i < LGUEST_MAX_DMA; i++) {
-                       /* If the interrupt is non-zero, the entry is already
-                        * used. */
-                       if (lg->dma[i].interrupt)
-                               continue;
-
-                       /* OK, a free one!  Fill on our details. */
-                       lg->dma[i].dmas = dmas;
-                       lg->dma[i].num_dmas = numdmas;
-                       lg->dma[i].next_dma = 0;
-                       lg->dma[i].key = key;
-                       lg->dma[i].guestid = lg->guestid;
-                       lg->dma[i].interrupt = interrupt;
-
-                       /* Now we add it to the hash table: the position
-                        * depends on the futex key that we got. */
-                       list_add(&lg->dma[i].list, &dma_hash[hash(&key)]);
-                       /* Success! */
-                       ret = 1;
-                       goto unlock;
-               }
-       }
-       /* If we didn't find a slot to put the key in, drop the reference
-        * again. */
-       drop_futex_key_refs(&key);
-unlock:
-       /* Unlock and out. */
-       up_read(fshared);
-       mutex_unlock(&lguest_lock);
-       return ret;
-}
-
-/*L:385 Note that our routines to access a different Guest's memory are called
- * lgread_other() and lgwrite_other(): these names emphasize that they are only
- * used when the Guest is *not* the current Guest.
- *
- * The interface for copying from another process's memory is called
- * access_process_vm(), with a final argument of 0 for a read, and 1 for a
- * write.
- *
- * We need lgread_other() to read the destination Guest's "struct lguest_dma"
- * array. */
-static int lgread_other(struct lguest *lg,
-                       void *buf, u32 addr, unsigned bytes)
-{
-       if (!lguest_address_ok(lg, addr, bytes)
-           || access_process_vm(lg->tsk, addr, buf, bytes, 0) != bytes) {
-               memset(buf, 0, bytes);
-               kill_guest(lg, "bad address in registered DMA struct");
-               return 0;
-       }
-       return 1;
-}
-
-/* "lgwrite()" to another Guest: used to update the destination "used_len" once
- * we've transferred data into the buffer. */
-static int lgwrite_other(struct lguest *lg, u32 addr,
-                        const void *buf, unsigned bytes)
-{
-       if (!lguest_address_ok(lg, addr, bytes)
-           || (access_process_vm(lg->tsk, addr, (void *)buf, bytes, 1)
-               != bytes)) {
-               kill_guest(lg, "bad address writing to registered DMA");
-               return 0;
-       }
-       return 1;
-}
-
-/*L:400 This is the generic engine which copies from a source "struct
- * lguest_dma" from this Guest into another Guest's "struct lguest_dma".  The
- * destination Guest's pages have already been mapped, as contained in the
- * pages array.
- *
- * If you're wondering if there's a nice "copy from one process to another"
- * routine, so was I.  But Linux isn't really set up to copy between two
- * unrelated processes, so we have to write it ourselves.
- */
-static u32 copy_data(struct lguest *srclg,
-                    const struct lguest_dma *src,
-                    const struct lguest_dma *dst,
-                    struct page *pages[])
-{
-       unsigned int totlen, si, di, srcoff, dstoff;
-       void *maddr = NULL;
-
-       /* We return the total length transferred. */
-       totlen = 0;
-
-       /* We keep indexes into the source and destination "struct lguest_dma",
-        * and an offset within each region. */
-       si = di = 0;
-       srcoff = dstoff = 0;
-
-       /* We loop until the source or destination is exhausted. */
-       while (si < LGUEST_MAX_DMA_SECTIONS && src->len[si]
-              && di < LGUEST_MAX_DMA_SECTIONS && dst->len[di]) {
-               /* We can only transfer the rest of the src buffer, or as much
-                * as will fit into the destination buffer. */
-               u32 len = min(src->len[si] - srcoff, dst->len[di] - dstoff);
-
-               /* For systems using "highmem" we need to use kmap() to access
-                * the page we want.  We often use the same page over and over,
-                * so rather than kmap() it on every loop, we set the maddr
-                * pointer to NULL when we need to move to the next
-                * destination page. */
-               if (!maddr)
-                       maddr = kmap(pages[di]);
-
-               /* Copy directly from (this Guest's) source address to the
-                * destination Guest's kmap()ed buffer.  Note that maddr points
-                * to the start of the page: we need to add the offset of the
-                * destination address and offset within the buffer. */
-
-               /* FIXME: This is not completely portable.  I looked at
-                * copy_to_user_page(), and some arch's seem to need special
-                * flushes.  x86 is fine. */
-               if (copy_from_user(maddr + (dst->addr[di] + dstoff)%PAGE_SIZE,
-                                  (void __user *)src->addr[si], len) != 0) {
-                       /* If a copy failed, it's the source's fault. */
-                       kill_guest(srclg, "bad address in sending DMA");
-                       totlen = 0;
-                       break;
-               }
-
-               /* Increment the total and src & dst offsets */
-               totlen += len;
-               srcoff += len;
-               dstoff += len;
-
-               /* Presumably we reached the end of the src or dest buffers: */
-               if (srcoff == src->len[si]) {
-                       /* Move to the next buffer at offset 0 */
-                       si++;
-                       srcoff = 0;
-               }
-               if (dstoff == dst->len[di]) {
-                       /* We need to unmap that destination page and reset
-                        * maddr ready for the next one. */
-                       kunmap(pages[di]);
-                       maddr = NULL;
-                       di++;
-                       dstoff = 0;
-               }
-       }
-
-       /* If we still had a page mapped at the end, unmap now. */
-       if (maddr)
-               kunmap(pages[di]);
-
-       return totlen;
-}
-
-/*L:390 This is how we transfer a "struct lguest_dma" from the source Guest
- * (the current Guest which called SEND_DMA) to another Guest. */
-static u32 do_dma(struct lguest *srclg, const struct lguest_dma *src,
-                 struct lguest *dstlg, const struct lguest_dma *dst)
-{
-       int i;
-       u32 ret;
-       struct page *pages[LGUEST_MAX_DMA_SECTIONS];
-
-       /* We check that both source and destination "struct lguest_dma"s are
-        * within the bounds of the source and destination Guests */
-       if (!check_dma_list(dstlg, dst) || !check_dma_list(srclg, src))
-               return 0;
-
-       /* We need to map the pages which correspond to each parts of
-        * destination buffer. */
-       for (i = 0; i < LGUEST_MAX_DMA_SECTIONS; i++) {
-               if (dst->len[i] == 0)
-                       break;
-               /* get_user_pages() is a complicated function, especially since
-                * we only want a single page.  But it works, and returns the
-                * number of pages.  Note that we're holding the destination's
-                * mmap_sem, as get_user_pages() requires. */
-               if (get_user_pages(dstlg->tsk, dstlg->mm,
-                                  dst->addr[i], 1, 1, 1, pages+i, NULL)
-                   != 1) {
-                       /* This means the destination gave us a bogus buffer */
-                       kill_guest(dstlg, "Error mapping DMA pages");
-                       ret = 0;
-                       goto drop_pages;
-               }
-       }
-
-       /* Now copy the data until we run out of src or dst. */
-       ret = copy_data(srclg, src, dst, pages);
-
-drop_pages:
-       while (--i >= 0)
-               put_page(pages[i]);
-       return ret;
-}
-
-/*L:380 Transferring data from one Guest to another is not as simple as I'd
- * like.  We've found the "struct lguest_dma_info" bound to the same address as
- * the send, we need to copy into it.
- *
- * This function returns true if the destination array was empty. */
-static int dma_transfer(struct lguest *srclg,
-                       unsigned long udma,
-                       struct lguest_dma_info *dst)
-{
-       struct lguest_dma dst_dma, src_dma;
-       struct lguest *dstlg;
-       u32 i, dma = 0;
-
-       /* From the "struct lguest_dma_info" we found in the hash, grab the
-        * Guest. */
-       dstlg = &lguests[dst->guestid];
-       /* Read in the source "struct lguest_dma" handed to SEND_DMA. */
-       lgread(srclg, &src_dma, udma, sizeof(src_dma));
-
-       /* We need the destination's mmap_sem, and we already hold the source's
-        * mmap_sem for the futex key lookup.  Normally this would suggest that
-        * we could deadlock if the destination Guest was trying to send to
-        * this source Guest at the same time, which is another reason that all
-        * I/O is done under the big lguest_lock. */
-       down_read(&dstlg->mm->mmap_sem);
-
-       /* Look through the destination DMA array for an available buffer. */
-       for (i = 0; i < dst->num_dmas; i++) {
-               /* We keep a "next_dma" pointer which often helps us avoid
-                * looking at lots of previously-filled entries. */
-               dma = (dst->next_dma + i) % dst->num_dmas;
-               if (!lgread_other(dstlg, &dst_dma,
-                                 dst->dmas + dma * sizeof(struct lguest_dma),
-                                 sizeof(dst_dma))) {
-                       goto fail;
-               }
-               if (!dst_dma.used_len)
-                       break;
-       }
-
-       /* If we found a buffer, we do the actual data copy. */
-       if (i != dst->num_dmas) {
-               unsigned long used_lenp;
-               unsigned int ret;
-
-               ret = do_dma(srclg, &src_dma, dstlg, &dst_dma);
-               /* Put used length in the source "struct lguest_dma"'s used_len
-                * field.  It's a little tricky to figure out where that is,
-                * though. */
-               lgwrite_u32(srclg,
-                           udma+offsetof(struct lguest_dma, used_len), ret);
-               /* Tranferring 0 bytes is OK if the source buffer was empty. */
-               if (ret == 0 && src_dma.len[0] != 0)
-                       goto fail;
-
-               /* The destination Guest might be running on a different CPU:
-                * we have to make sure that it will see the "used_len" field
-                * change to non-zero *after* it sees the data we copied into
-                * the buffer.  Hence a write memory barrier. */
-               wmb();
-               /* Figuring out where the destination's used_len field for this
-                * "struct lguest_dma" in the array is also a little ugly. */
-               used_lenp = dst->dmas
-                       + dma * sizeof(struct lguest_dma)
-                       + offsetof(struct lguest_dma, used_len);
-               lgwrite_other(dstlg, used_lenp, &ret, sizeof(ret));
-               /* Move the cursor for next time. */
-               dst->next_dma++;
-       }
-       up_read(&dstlg->mm->mmap_sem);
-
-       /* We trigger the destination interrupt, even if the destination was
-        * empty and we didn't transfer anything: this gives them a chance to
-        * wake up and refill. */
-       set_bit(dst->interrupt, dstlg->irqs_pending);
-       /* Wake up the destination process. */
-       wake_up_process(dstlg->tsk);
-       /* If we passed the last "struct lguest_dma", the receive had no
-        * buffers left. */
-       return i == dst->num_dmas;
-
-fail:
-       up_read(&dstlg->mm->mmap_sem);
-       return 0;
-}
-
-/*L:370 This is the counter-side to the BIND_DMA hypercall; the SEND_DMA
- * hypercall.  We find out who's listening, and send to them. */
-void send_dma(struct lguest *lg, unsigned long ukey, unsigned long udma)
-{
-       union futex_key key;
-       int empty = 0;
-       struct rw_semaphore *fshared = &current->mm->mmap_sem;
-
-again:
-       mutex_lock(&lguest_lock);
-       down_read(fshared);
-       /* Get the futex key for the key the Guest gave us */
-       if (get_futex_key((u32 __user *)ukey, fshared, &key) != 0) {
-               kill_guest(lg, "bad sending DMA key");
-               goto unlock;
-       }
-       /* Since the key must be a multiple of 4, the futex key uses the lower
-        * bit of the "offset" field (which would always be 0) to indicate a
-        * mapping which is shared with other processes (ie. Guests). */
-       if (key.shared.offset & 1) {
-               struct lguest_dma_info *i;
-               /* Look through the hash for other Guests. */
-               list_for_each_entry(i, &dma_hash[hash(&key)], list) {
-                       /* Don't send to ourselves. */
-                       if (i->guestid == lg->guestid)
-                               continue;
-                       if (!key_eq(&key, &i->key))
-                               continue;
-
-                       /* If dma_transfer() tells us the destination has no
-                        * available buffers, we increment "empty". */
-                       empty += dma_transfer(lg, udma, i);
-                       break;
-               }
-               /* If the destination is empty, we release our locks and
-                * give the destination Guest a brief chance to restock. */
-               if (empty == 1) {
-                       /* Give any recipients one chance to restock. */
-                       up_read(&current->mm->mmap_sem);
-                       mutex_unlock(&lguest_lock);
-                       /* Next time, we won't try again. */
-                       empty++;
-                       goto again;
-               }
-       } else {
-               /* Private mapping: Guest is sending to its Launcher.  We set
-                * the "dma_is_pending" flag so that the main loop will exit
-                * and the Launcher's read() from /dev/lguest will return. */
-               lg->dma_is_pending = 1;
-               lg->pending_dma = udma;
-               lg->pending_key = ukey;
-       }
-unlock:
-       up_read(fshared);
-       mutex_unlock(&lguest_lock);
-}
-/*:*/
-
-void release_all_dma(struct lguest *lg)
-{
-       unsigned int i;
-
-       BUG_ON(!mutex_is_locked(&lguest_lock));
-
-       down_read(&lg->mm->mmap_sem);
-       for (i = 0; i < LGUEST_MAX_DMA; i++) {
-               if (lg->dma[i].interrupt)
-                       unlink_dma(&lg->dma[i]);
-       }
-       up_read(&lg->mm->mmap_sem);
-}
-
-/*M:007 We only return a single DMA buffer to the Launcher, but it would be
- * more efficient to return a pointer to the entire array of DMA buffers, which
- * it can cache and choose one whenever it wants.
- *
- * Currently the Launcher uses a write to /dev/lguest, and the return value is
- * the address of the DMA structure with the interrupt number placed in
- * dma->used_len.  If we wanted to return the entire array, we need to return
- * the address, array size and interrupt number: this seems to require an
- * ioctl(). :*/
-
-/*L:320 This routine looks for a DMA buffer registered by the Guest on the
- * given key (using the BIND_DMA hypercall). */
-unsigned long get_dma_buffer(struct lguest *lg,
-                            unsigned long ukey, unsigned long *interrupt)
-{
-       unsigned long ret = 0;
-       union futex_key key;
-       struct lguest_dma_info *i;
-       struct rw_semaphore *fshared = &current->mm->mmap_sem;
-
-       /* Take the Big Lguest Lock to stop other Guests sending this Guest DMA
-        * at the same time. */
-       mutex_lock(&lguest_lock);
-       /* To match between Guests sharing the same underlying memory we steal
-        * code from the futex infrastructure.  This requires that we hold the
-        * "mmap_sem" for our process (the Launcher), and pass it to the futex
-        * code. */
-       down_read(fshared);
-
-       /* This can fail if it's not a valid address, or if the address is not
-        * divisible by 4 (the futex code needs that, we don't really). */
-       if (get_futex_key((u32 __user *)ukey, fshared, &key) != 0) {
-               kill_guest(lg, "bad registered DMA buffer");
-               goto unlock;
-       }
-       /* Search the hash table for matching entries (the Launcher can only
-        * send to its own Guest for the moment, so the entry must be for this
-        * Guest) */
-       list_for_each_entry(i, &dma_hash[hash(&key)], list) {
-               if (key_eq(&key, &i->key) && i->guestid == lg->guestid) {
-                       unsigned int j;
-                       /* Look through the registered DMA array for an
-                        * available buffer. */
-                       for (j = 0; j < i->num_dmas; j++) {
-                               struct lguest_dma dma;
-
-                               ret = i->dmas + j * sizeof(struct lguest_dma);
-                               lgread(lg, &dma, ret, sizeof(dma));
-                               if (dma.used_len == 0)
-                                       break;
-                       }
-                       /* Store the interrupt the Guest wants when the buffer
-                        * is used. */
-                       *interrupt = i->interrupt;
-                       break;
-               }
-       }
-unlock:
-       up_read(fshared);
-       mutex_unlock(&lguest_lock);
-       return ret;
-}
-/*:*/
-
-/*L:410 This really has completed the Launcher.  Not only have we now finished
- * the longest chapter in our journey, but this also means we are over halfway
- * through!
- *
- * Enough prevaricating around the bush: it is time for us to dive into the
- * core of the Host, in "make Host".
- */
index 64f0abed317c2fbb6afe4c7d3ca881c163353ef7..d9144beca82c2265d5a8a96984ab20249d19c818 100644 (file)
 #ifndef _LGUEST_H
 #define _LGUEST_H
 
-#include <asm/desc.h>
-
-#define GDT_ENTRY_LGUEST_CS    10
-#define GDT_ENTRY_LGUEST_DS    11
-#define LGUEST_CS              (GDT_ENTRY_LGUEST_CS * 8)
-#define LGUEST_DS              (GDT_ENTRY_LGUEST_DS * 8)
-
 #ifndef __ASSEMBLY__
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/stringify.h>
-#include <linux/binfmts.h>
-#include <linux/futex.h>
 #include <linux/lguest.h>
 #include <linux/lguest_launcher.h>
 #include <linux/wait.h>
 #include <linux/err.h>
 #include <asm/semaphore.h>
-#include "irq_vectors.h"
-
-#define GUEST_PL 1
 
-struct lguest_regs
-{
-       /* Manually saved part. */
-       unsigned long ebx, ecx, edx;
-       unsigned long esi, edi, ebp;
-       unsigned long gs;
-       unsigned long eax;
-       unsigned long fs, ds, es;
-       unsigned long trapnum, errcode;
-       /* Trap pushed part */
-       unsigned long eip;
-       unsigned long cs;
-       unsigned long eflags;
-       unsigned long esp;
-       unsigned long ss;
-};
+#include <asm/lguest.h>
 
 void free_pagetables(void);
 int init_pagetables(struct page **switcher_page, unsigned int pages);
 
-/* Full 4G segment descriptors, suitable for CS and DS. */
-#define FULL_EXEC_SEGMENT ((struct desc_struct){0x0000ffff, 0x00cf9b00})
-#define FULL_SEGMENT ((struct desc_struct){0x0000ffff, 0x00cf9300})
-
-struct lguest_dma_info
-{
-       struct list_head list;
-       union futex_key key;
-       unsigned long dmas;
-       u16 next_dma;
-       u16 num_dmas;
-       u16 guestid;
-       u8 interrupt;   /* 0 when not registered */
-};
-
-/*H:310 The page-table code owes a great debt of gratitude to Andi Kleen.  He
- * reviewed the original code which used "u32" for all page table entries, and
- * insisted that it would be far clearer with explicit typing.  I thought it
- * was overkill, but he was right: it is much clearer than it was before.
- *
- * We have separate types for the Guest's ptes & pgds and the shadow ptes &
- * pgds.  There's already a Linux type for these (pte_t and pgd_t) but they
- * change depending on kernel config options (PAE). */
-
-/* Each entry is identical: lower 12 bits of flags and upper 20 bits for the
- * "page frame number" (0 == first physical page, etc).  They are different
- * types so the compiler will warn us if we mix them improperly. */
-typedef union {
-       struct { unsigned flags:12, pfn:20; };
-       struct { unsigned long val; } raw;
-} spgd_t;
-typedef union {
-       struct { unsigned flags:12, pfn:20; };
-       struct { unsigned long val; } raw;
-} spte_t;
-typedef union {
-       struct { unsigned flags:12, pfn:20; };
-       struct { unsigned long val; } raw;
-} gpgd_t;
-typedef union {
-       struct { unsigned flags:12, pfn:20; };
-       struct { unsigned long val; } raw;
-} gpte_t;
-
-/* We have two convenient macros to convert a "raw" value as handed to us by
- * the Guest into the correct Guest PGD or PTE type. */
-#define mkgpte(_val) ((gpte_t){.raw.val = _val})
-#define mkgpgd(_val) ((gpgd_t){.raw.val = _val})
-/*:*/
-
 struct pgdir
 {
-       unsigned long cr3;
-       spgd_t *pgdir;
-};
-
-/* This is a guest-specific page (mapped ro) into the guest. */
-struct lguest_ro_state
-{
-       /* Host information we need to restore when we switch back. */
-       u32 host_cr3;
-       struct Xgt_desc_struct host_idt_desc;
-       struct Xgt_desc_struct host_gdt_desc;
-       u32 host_sp;
-
-       /* Fields which are used when guest is running. */
-       struct Xgt_desc_struct guest_idt_desc;
-       struct Xgt_desc_struct guest_gdt_desc;
-       struct i386_hw_tss guest_tss;
-       struct desc_struct guest_idt[IDT_ENTRIES];
-       struct desc_struct guest_gdt[GDT_ENTRIES];
+       unsigned long gpgdir;
+       pgd_t *pgdir;
 };
 
 /* We have two pages shared with guests, per cpu.  */
@@ -141,9 +47,11 @@ struct lguest
        struct lguest_data __user *lguest_data;
        struct task_struct *tsk;
        struct mm_struct *mm;   /* == tsk->mm, but that becomes NULL on exit */
-       u16 guestid;
        u32 pfn_limit;
-       u32 page_offset;
+       /* This provides the offset to the base of guest-physical
+        * memory in the Launcher. */
+       void __user *mem_base;
+       unsigned long kernel_address;
        u32 cr2;
        int halted;
        int ts;
@@ -151,6 +59,9 @@ struct lguest
        u32 esp1;
        u8 ss1;
 
+       /* If a hypercall was asked for, this points to the arguments. */
+       struct hcall_args *hcall;
+
        /* Do we need to stop what we're doing and return to userspace? */
        int break_out;
        wait_queue_head_t break_wq;
@@ -167,24 +78,15 @@ struct lguest
        struct task_struct *wake;
 
        unsigned long noirq_start, noirq_end;
-       int dma_is_pending;
-       unsigned long pending_dma; /* struct lguest_dma */
-       unsigned long pending_key; /* address they're sending to */
+       unsigned long pending_notify; /* pfn from LHCALL_NOTIFY */
 
        unsigned int stack_pages;
        u32 tsc_khz;
 
-       struct lguest_dma_info dma[LGUEST_MAX_DMA];
-
        /* Dead? */
        const char *dead;
 
-       /* The GDT entries copied into lguest_ro_state when running. */
-       struct desc_struct gdt[GDT_ENTRIES];
-
-       /* The IDT entries: some copied into lguest_ro_state when running. */
-       struct desc_struct idt[FIRST_EXTERNAL_VECTOR+LGUEST_IRQS];
-       struct desc_struct syscall_idt;
+       struct lguest_arch arch;
 
        /* Virtual clock device */
        struct hrtimer hrt;
@@ -193,19 +95,38 @@ struct lguest
        DECLARE_BITMAP(irqs_pending, LGUEST_IRQS);
 };
 
-extern struct lguest lguests[];
 extern struct mutex lguest_lock;
 
 /* core.c: */
-u32 lgread_u32(struct lguest *lg, unsigned long addr);
-void lgwrite_u32(struct lguest *lg, unsigned long addr, u32 val);
-void lgread(struct lguest *lg, void *buf, unsigned long addr, unsigned len);
-void lgwrite(struct lguest *lg, unsigned long, const void *buf, unsigned len);
-int find_free_guest(void);
 int lguest_address_ok(const struct lguest *lg,
                      unsigned long addr, unsigned long len);
+void __lgread(struct lguest *, void *, unsigned long, unsigned);
+void __lgwrite(struct lguest *, unsigned long, const void *, unsigned);
+
+/*L:306 Using memory-copy operations like that is usually inconvient, so we
+ * have the following helper macros which read and write a specific type (often
+ * an unsigned long).
+ *
+ * This reads into a variable of the given type then returns that. */
+#define lgread(lg, addr, type)                                         \
+       ({ type _v; __lgread((lg), &_v, (addr), sizeof(_v)); _v; })
+
+/* This checks that the variable is of the given type, then writes it out. */
+#define lgwrite(lg, addr, type, val)                           \
+       do {                                                    \
+               typecheck(type, val);                           \
+               __lgwrite((lg), (addr), &(val), sizeof(val));   \
+       } while(0)
+/* (end of memory access helper routines) :*/
+
 int run_guest(struct lguest *lg, unsigned long __user *user);
 
+/* Helper macros to obtain the first 12 or the last 20 bits, this is only the
+ * first step in the migration to the kernel types.  pte_pfn is already defined
+ * in the kernel. */
+#define pgd_flags(x)   (pgd_val(x) & ~PAGE_MASK)
+#define pte_flags(x)   (pte_val(x) & ~PAGE_MASK)
+#define pgd_pfn(x)     (pgd_val(x) >> PAGE_SHIFT)
 
 /* interrupts_and_traps.c: */
 void maybe_do_interrupt(struct lguest *lg);
@@ -219,6 +140,9 @@ void copy_traps(const struct lguest *lg, struct desc_struct *idt,
                const unsigned long *def);
 void guest_set_clockevent(struct lguest *lg, unsigned long delta);
 void init_clockdev(struct lguest *lg);
+bool check_syscall_vector(struct lguest *lg);
+int init_interrupts(void);
+void free_interrupts(void);
 
 /* segments.c: */
 void setup_default_gdt_entries(struct lguest_ro_state *state);
@@ -232,28 +156,33 @@ void copy_gdt_tls(const struct lguest *lg, struct desc_struct *gdt);
 int init_guest_pagetable(struct lguest *lg, unsigned long pgtable);
 void free_guest_pagetable(struct lguest *lg);
 void guest_new_pagetable(struct lguest *lg, unsigned long pgtable);
-void guest_set_pmd(struct lguest *lg, unsigned long cr3, u32 i);
+void guest_set_pmd(struct lguest *lg, unsigned long gpgdir, u32 i);
 void guest_pagetable_clear_all(struct lguest *lg);
 void guest_pagetable_flush_user(struct lguest *lg);
-void guest_set_pte(struct lguest *lg, unsigned long cr3,
-                  unsigned long vaddr, gpte_t val);
+void guest_set_pte(struct lguest *lg, unsigned long gpgdir,
+                  unsigned long vaddr, pte_t val);
 void map_switcher_in_guest(struct lguest *lg, struct lguest_pages *pages);
 int demand_page(struct lguest *info, unsigned long cr2, int errcode);
 void pin_page(struct lguest *lg, unsigned long vaddr);
+unsigned long guest_pa(struct lguest *lg, unsigned long vaddr);
+void page_table_guest_data_init(struct lguest *lg);
+
+/* <arch>/core.c: */
+void lguest_arch_host_init(void);
+void lguest_arch_host_fini(void);
+void lguest_arch_run_guest(struct lguest *lg);
+void lguest_arch_handle_trap(struct lguest *lg);
+int lguest_arch_init_hypercalls(struct lguest *lg);
+int lguest_arch_do_hcall(struct lguest *lg, struct hcall_args *args);
+void lguest_arch_setup_regs(struct lguest *lg, unsigned long start);
+
+/* <arch>/switcher.S: */
+extern char start_switcher_text[], end_switcher_text[], switch_to_guest[];
 
 /* lguest_user.c: */
 int lguest_device_init(void);
 void lguest_device_remove(void);
 
-/* io.c: */
-void lguest_io_init(void);
-int bind_dma(struct lguest *lg,
-            unsigned long key, unsigned long udma, u16 numdmas, u8 interrupt);
-void send_dma(struct lguest *info, unsigned long key, unsigned long udma);
-void release_all_dma(struct lguest *lg);
-unsigned long get_dma_buffer(struct lguest *lg, unsigned long key,
-                            unsigned long *interrupt);
-
 /* hypercalls.c: */
 void do_hypercalls(struct lguest *lg);
 void write_timestamp(struct lguest *lg);
@@ -292,9 +221,5 @@ do {                                                                \
 } while(0)
 /* (End of aside) :*/
 
-static inline unsigned long guest_pa(struct lguest *lg, unsigned long vaddr)
-{
-       return vaddr - lg->page_offset;
-}
 #endif /* __ASSEMBLY__ */
 #endif /* _LGUEST_H */
diff --git a/drivers/lguest/lguest_bus.c b/drivers/lguest/lguest_bus.c
deleted file mode 100644 (file)
index 5732978..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
-/*P:050 Lguest guests use a very simple bus for devices.  It's a simple array
- * of device descriptors contained just above the top of normal memory.  The
- * lguest bus is 80% tedious boilerplate code. :*/
-#include <linux/init.h>
-#include <linux/bootmem.h>
-#include <linux/lguest_bus.h>
-#include <asm/io.h>
-#include <asm/paravirt.h>
-
-static ssize_t type_show(struct device *_dev,
-                         struct device_attribute *attr, char *buf)
-{
-       struct lguest_device *dev = container_of(_dev,struct lguest_device,dev);
-       return sprintf(buf, "%hu", lguest_devices[dev->index].type);
-}
-static ssize_t features_show(struct device *_dev,
-                             struct device_attribute *attr, char *buf)
-{
-       struct lguest_device *dev = container_of(_dev,struct lguest_device,dev);
-       return sprintf(buf, "%hx", lguest_devices[dev->index].features);
-}
-static ssize_t pfn_show(struct device *_dev,
-                        struct device_attribute *attr, char *buf)
-{
-       struct lguest_device *dev = container_of(_dev,struct lguest_device,dev);
-       return sprintf(buf, "%u", lguest_devices[dev->index].pfn);
-}
-static ssize_t status_show(struct device *_dev,
-                           struct device_attribute *attr, char *buf)
-{
-       struct lguest_device *dev = container_of(_dev,struct lguest_device,dev);
-       return sprintf(buf, "%hx", lguest_devices[dev->index].status);
-}
-static ssize_t status_store(struct device *_dev, struct device_attribute *attr,
-                            const char *buf, size_t count)
-{
-       struct lguest_device *dev = container_of(_dev,struct lguest_device,dev);
-       if (sscanf(buf, "%hi", &lguest_devices[dev->index].status) != 1)
-               return -EINVAL;
-       return count;
-}
-static struct device_attribute lguest_dev_attrs[] = {
-       __ATTR_RO(type),
-       __ATTR_RO(features),
-       __ATTR_RO(pfn),
-       __ATTR(status, 0644, status_show, status_store),
-       __ATTR_NULL
-};
-
-/*D:130 The generic bus infrastructure requires a function which says whether a
- * device matches a driver.  For us, it is simple: "struct lguest_driver"
- * contains a "device_type" field which indicates what type of device it can
- * handle, so we just cast the args and compare: */
-static int lguest_dev_match(struct device *_dev, struct device_driver *_drv)
-{
-       struct lguest_device *dev = container_of(_dev,struct lguest_device,dev);
-       struct lguest_driver *drv = container_of(_drv,struct lguest_driver,drv);
-
-       return (drv->device_type == lguest_devices[dev->index].type);
-}
-/*:*/
-
-struct lguest_bus {
-       struct bus_type bus;
-       struct device dev;
-};
-
-static struct lguest_bus lguest_bus = {
-       .bus = {
-               .name  = "lguest",
-               .match = lguest_dev_match,
-               .dev_attrs = lguest_dev_attrs,
-       },
-       .dev = {
-               .parent = NULL,
-               .bus_id = "lguest",
-       }
-};
-
-/*D:140 This is the callback which occurs once the bus infrastructure matches
- * up a device and driver, ie. in response to add_lguest_device() calling
- * device_register(), or register_lguest_driver() calling driver_register().
- *
- * At the moment it's always the latter: the devices are added first, since
- * scan_devices() is called from a "core_initcall", and the drivers themselves
- * called later as a normal "initcall".  But it would work the other way too.
- *
- * So now we have the happy couple, we add the status bit to indicate that we
- * found a driver.  If the driver truly loves the device, it will return
- * happiness from its probe function (ok, perhaps this wasn't my greatest
- * analogy), and we set the final "driver ok" bit so the Host sees it's all
- * green. */
-static int lguest_dev_probe(struct device *_dev)
-{
-       int ret;
-       struct lguest_device*dev = container_of(_dev,struct lguest_device,dev);
-       struct lguest_driver*drv = container_of(dev->dev.driver,
-                                               struct lguest_driver, drv);
-
-       lguest_devices[dev->index].status |= LGUEST_DEVICE_S_DRIVER;
-       ret = drv->probe(dev);
-       if (ret == 0)
-               lguest_devices[dev->index].status |= LGUEST_DEVICE_S_DRIVER_OK;
-       return ret;
-}
-
-/* The last part of the bus infrastructure is the function lguest drivers use
- * to register themselves.  Firstly, we do nothing if there's no lguest bus
- * (ie. this is not a Guest), otherwise we fill in the embedded generic "struct
- * driver" fields and call the generic driver_register(). */
-int register_lguest_driver(struct lguest_driver *drv)
-{
-       if (!lguest_devices)
-               return 0;
-
-       drv->drv.bus = &lguest_bus.bus;
-       drv->drv.name = drv->name;
-       drv->drv.owner = drv->owner;
-       drv->drv.probe = lguest_dev_probe;
-
-       return driver_register(&drv->drv);
-}
-
-/* At the moment we build all the drivers into the kernel because they're so
- * simple: 8144 bytes for all three of them as I type this.  And as the console
- * really needs to be built in, it's actually only 3527 bytes for the network
- * and block drivers.
- *
- * If they get complex it will make sense for them to be modularized, so we
- * need to explicitly export the symbol.
- *
- * I don't think non-GPL modules make sense, so it's a GPL-only export.
- */
-EXPORT_SYMBOL_GPL(register_lguest_driver);
-
-/*D:120 This is the core of the lguest bus: actually adding a new device.
- * It's a separate function because it's neater that way, and because an
- * earlier version of the code supported hotplug and unplug.  They were removed
- * early on because they were never used.
- *
- * As Andrew Tridgell says, "Untested code is buggy code".
- *
- * It's worth reading this carefully: we start with an index into the array of
- * "struct lguest_device_desc"s indicating the device which is new: */
-static void add_lguest_device(unsigned int index)
-{
-       struct lguest_device *new;
-
-       /* Each "struct lguest_device_desc" has a "status" field, which the
-        * Guest updates as the device is probed.  In the worst case, the Host
-        * can look at these bits to tell what part of device setup failed,
-        * even if the console isn't available. */
-       lguest_devices[index].status |= LGUEST_DEVICE_S_ACKNOWLEDGE;
-       new = kmalloc(sizeof(struct lguest_device), GFP_KERNEL);
-       if (!new) {
-               printk(KERN_EMERG "Cannot allocate lguest device %u\n", index);
-               lguest_devices[index].status |= LGUEST_DEVICE_S_FAILED;
-               return;
-       }
-
-       /* The "struct lguest_device" setup is pretty straight-forward example
-        * code. */
-       new->index = index;
-       new->private = NULL;
-       memset(&new->dev, 0, sizeof(new->dev));
-       new->dev.parent = &lguest_bus.dev;
-       new->dev.bus = &lguest_bus.bus;
-       sprintf(new->dev.bus_id, "%u", index);
-
-       /* device_register() causes the bus infrastructure to look for a
-        * matching driver. */
-       if (device_register(&new->dev) != 0) {
-               printk(KERN_EMERG "Cannot register lguest device %u\n", index);
-               lguest_devices[index].status |= LGUEST_DEVICE_S_FAILED;
-               kfree(new);
-       }
-}
-
-/*D:110 scan_devices() simply iterates through the device array.  The type 0
- * is reserved to mean "no device", and anything else means we have found a
- * device: add it. */
-static void scan_devices(void)
-{
-       unsigned int i;
-
-       for (i = 0; i < LGUEST_MAX_DEVICES; i++)
-               if (lguest_devices[i].type)
-                       add_lguest_device(i);
-}
-
-/*D:100 Fairly early in boot, lguest_bus_init() is called to set up the lguest
- * bus.  We check that we are a Guest by checking paravirt_ops.name: there are
- * other ways of checking, but this seems most obvious to me.
- *
- * So we can access the array of "struct lguest_device_desc"s easily, we map
- * that memory and store the pointer in the global "lguest_devices".  Then we
- * register the bus with the core.  Doing two registrations seems clunky to me,
- * but it seems to be the correct sysfs incantation.
- *
- * Finally we call scan_devices() which adds all the devices found in the
- * "struct lguest_device_desc" array. */
-static int __init lguest_bus_init(void)
-{
-       if (strcmp(pv_info.name, "lguest") != 0)
-               return 0;
-
-       /* Devices are in a single page above top of "normal" mem */
-       lguest_devices = lguest_map(max_pfn<<PAGE_SHIFT, 1);
-
-       if (bus_register(&lguest_bus.bus) != 0
-           || device_register(&lguest_bus.dev) != 0)
-               panic("lguest bus registration failed");
-
-       scan_devices();
-       return 0;
-}
-/* Do this after core stuff, before devices. */
-postcore_initcall(lguest_bus_init);
diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c
new file mode 100644 (file)
index 0000000..71c6483
--- /dev/null
@@ -0,0 +1,373 @@
+/*P:050 Lguest guests use a very simple method to describe devices.  It's a
+ * series of device descriptors contained just above the top of normal
+ * memory.
+ *
+ * We use the standard "virtio" device infrastructure, which provides us with a
+ * console, a network and a block driver.  Each one expects some configuration
+ * information and a "virtqueue" mechanism to send and receive data. :*/
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/lguest_launcher.h>
+#include <linux/virtio.h>
+#include <linux/virtio_config.h>
+#include <linux/interrupt.h>
+#include <linux/virtio_ring.h>
+#include <linux/err.h>
+#include <asm/io.h>
+#include <asm/paravirt.h>
+#include <asm/lguest_hcall.h>
+
+/* The pointer to our (page) of device descriptions. */
+static void *lguest_devices;
+
+/* Unique numbering for lguest devices. */
+static unsigned int dev_index;
+
+/* For Guests, device memory can be used as normal memory, so we cast away the
+ * __iomem to quieten sparse. */
+static inline void *lguest_map(unsigned long phys_addr, unsigned long pages)
+{
+       return (__force void *)ioremap(phys_addr, PAGE_SIZE*pages);
+}
+
+static inline void lguest_unmap(void *addr)
+{
+       iounmap((__force void __iomem *)addr);
+}
+
+/*D:100 Each lguest device is just a virtio device plus a pointer to its entry
+ * in the lguest_devices page. */
+struct lguest_device {
+       struct virtio_device vdev;
+
+       /* The entry in the lguest_devices page for this device. */
+       struct lguest_device_desc *desc;
+};
+
+/* Since the virtio infrastructure hands us a pointer to the virtio_device all
+ * the time, it helps to have a curt macro to get a pointer to the struct
+ * lguest_device it's enclosed in.  */
+#define to_lgdev(vdev) container_of(vdev, struct lguest_device, vdev)
+
+/*D:130
+ * Device configurations
+ *
+ * The configuration information for a device consists of a series of fields.
+ * The device will look for these fields during setup.
+ *
+ * For us these fields come immediately after that device's descriptor in the
+ * lguest_devices page.
+ *
+ * Each field starts with a "type" byte, a "length" byte, then that number of
+ * bytes of configuration information.  The device descriptor tells us the
+ * total configuration length so we know when we've reached the last field. */
+
+/* type + length bytes */
+#define FHDR_LEN 2
+
+/* This finds the first field of a given type for a device's configuration. */
+static void *lg_find(struct virtio_device *vdev, u8 type, unsigned int *len)
+{
+       struct lguest_device_desc *desc = to_lgdev(vdev)->desc;
+       int i;
+
+       for (i = 0; i < desc->config_len; i += FHDR_LEN + desc->config[i+1]) {
+               if (desc->config[i] == type) {
+                       /* Mark it used, so Host can know we looked at it, and
+                        * also so we won't find the same one twice. */
+                       desc->config[i] |= 0x80;
+                       /* Remember, the second byte is the length. */
+                       *len = desc->config[i+1];
+                       /* We return a pointer to the field header. */
+                       return desc->config + i;
+               }
+       }
+
+       /* Not found: return NULL for failure. */
+       return NULL;
+}
+
+/* Once they've found a field, getting a copy of it is easy. */
+static void lg_get(struct virtio_device *vdev, void *token,
+                  void *buf, unsigned len)
+{
+       /* Check they didn't ask for more than the length of the field! */
+       BUG_ON(len > ((u8 *)token)[1]);
+       memcpy(buf, token + FHDR_LEN, len);
+}
+
+/* Setting the contents is also trivial. */
+static void lg_set(struct virtio_device *vdev, void *token,
+                  const void *buf, unsigned len)
+{
+       BUG_ON(len > ((u8 *)token)[1]);
+       memcpy(token + FHDR_LEN, buf, len);
+}
+
+/* The operations to get and set the status word just access the status field
+ * of the device descriptor. */
+static u8 lg_get_status(struct virtio_device *vdev)
+{
+       return to_lgdev(vdev)->desc->status;
+}
+
+static void lg_set_status(struct virtio_device *vdev, u8 status)
+{
+       to_lgdev(vdev)->desc->status = status;
+}
+
+/*
+ * Virtqueues
+ *
+ * The other piece of infrastructure virtio needs is a "virtqueue": a way of
+ * the Guest device registering buffers for the other side to read from or
+ * write into (ie. send and receive buffers).  Each device can have multiple
+ * virtqueues: for example the console has one queue for sending and one for
+ * receiving.
+ *
+ * Fortunately for us, a very fast shared-memory-plus-descriptors virtqueue
+ * already exists in virtio_ring.c.  We just need to connect it up.
+ *
+ * We start with the information we need to keep about each virtqueue.
+ */
+
+/*D:140 This is the information we remember about each virtqueue. */
+struct lguest_vq_info
+{
+       /* A copy of the information contained in the device config. */
+       struct lguest_vqconfig config;
+
+       /* The address where we mapped the virtio ring, so we can unmap it. */
+       void *pages;
+};
+
+/* When the virtio_ring code wants to prod the Host, it calls us here and we
+ * make a hypercall.  We hand the page number of the virtqueue so the Host
+ * knows which virtqueue we're talking about. */
+static void lg_notify(struct virtqueue *vq)
+{
+       /* We store our virtqueue information in the "priv" pointer of the
+        * virtqueue structure. */
+       struct lguest_vq_info *lvq = vq->priv;
+
+       hcall(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT, 0, 0);
+}
+
+/* This routine finds the first virtqueue described in the configuration of
+ * this device and sets it up.
+ *
+ * This is kind of an ugly duckling.  It'd be nicer to have a standard
+ * representation of a virtqueue in the configuration space, but it seems that
+ * everyone wants to do it differently.  The KVM guys want the Guest to
+ * allocate its own pages and tell the Host where they are, but for lguest it's
+ * simpler for the Host to simply tell us where the pages are.
+ *
+ * So we provide devices with a "find virtqueue and set it up" function. */
+static struct virtqueue *lg_find_vq(struct virtio_device *vdev,
+                                   bool (*callback)(struct virtqueue *vq))
+{
+       struct lguest_vq_info *lvq;
+       struct virtqueue *vq;
+       unsigned int len;
+       void *token;
+       int err;
+
+       /* Look for a field of the correct type to mark a virtqueue.  Note that
+        * if this succeeds, then the type will be changed so it won't be found
+        * again, and future lg_find_vq() calls will find the next
+        * virtqueue (if any). */
+       token = vdev->config->find(vdev, VIRTIO_CONFIG_F_VIRTQUEUE, &len);
+       if (!token)
+               return ERR_PTR(-ENOENT);
+
+       lvq = kmalloc(sizeof(*lvq), GFP_KERNEL);
+       if (!lvq)
+               return ERR_PTR(-ENOMEM);
+
+       /* Note: we could use a configuration space inside here, just like we
+        * do for the device.  This would allow expansion in future, because
+        * our configuration system is designed to be expansible.  But this is
+        * way easier. */
+       if (len != sizeof(lvq->config)) {
+               dev_err(&vdev->dev, "Unexpected virtio config len %u\n", len);
+               err = -EIO;
+               goto free_lvq;
+       }
+       /* Make a copy of the "struct lguest_vqconfig" field.  We need a copy
+        * because the config space might not be aligned correctly. */
+       vdev->config->get(vdev, token, &lvq->config, sizeof(lvq->config));
+
+       /* Figure out how many pages the ring will take, and map that memory */
+       lvq->pages = lguest_map((unsigned long)lvq->config.pfn << PAGE_SHIFT,
+                               DIV_ROUND_UP(vring_size(lvq->config.num),
+                                            PAGE_SIZE));
+       if (!lvq->pages) {
+               err = -ENOMEM;
+               goto free_lvq;
+       }
+
+       /* OK, tell virtio_ring.c to set up a virtqueue now we know its size
+        * and we've got a pointer to its pages. */
+       vq = vring_new_virtqueue(lvq->config.num, vdev, lvq->pages,
+                                lg_notify, callback);
+       if (!vq) {
+               err = -ENOMEM;
+               goto unmap;
+       }
+
+       /* Tell the interrupt for this virtqueue to go to the virtio_ring
+        * interrupt handler. */
+       /* FIXME: We used to have a flag for the Host to tell us we could use
+        * the interrupt as a source of randomness: it'd be nice to have that
+        * back.. */
+       err = request_irq(lvq->config.irq, vring_interrupt, IRQF_SHARED,
+                         vdev->dev.bus_id, vq);
+       if (err)
+               goto destroy_vring;
+
+       /* Last of all we hook up our 'struct lguest_vq_info" to the
+        * virtqueue's priv pointer. */
+       vq->priv = lvq;
+       return vq;
+
+destroy_vring:
+       vring_del_virtqueue(vq);
+unmap:
+       lguest_unmap(lvq->pages);
+free_lvq:
+       kfree(lvq);
+       return ERR_PTR(err);
+}
+/*:*/
+
+/* Cleaning up a virtqueue is easy */
+static void lg_del_vq(struct virtqueue *vq)
+{
+       struct lguest_vq_info *lvq = vq->priv;
+
+       /* Tell virtio_ring.c to free the virtqueue. */
+       vring_del_virtqueue(vq);
+       /* Unmap the pages containing the ring. */
+       lguest_unmap(lvq->pages);
+       /* Free our own queue information. */
+       kfree(lvq);
+}
+
+/* The ops structure which hooks everything together. */
+static struct virtio_config_ops lguest_config_ops = {
+       .find = lg_find,
+       .get = lg_get,
+       .set = lg_set,
+       .get_status = lg_get_status,
+       .set_status = lg_set_status,
+       .find_vq = lg_find_vq,
+       .del_vq = lg_del_vq,
+};
+
+/* The root device for the lguest virtio devices.  This makes them appear as
+ * /sys/devices/lguest/0,1,2 not /sys/devices/0,1,2. */
+static struct device lguest_root = {
+       .parent = NULL,
+       .bus_id = "lguest",
+};
+
+/*D:120 This is the core of the lguest bus: actually adding a new device.
+ * It's a separate function because it's neater that way, and because an
+ * earlier version of the code supported hotplug and unplug.  They were removed
+ * early on because they were never used.
+ *
+ * As Andrew Tridgell says, "Untested code is buggy code".
+ *
+ * It's worth reading this carefully: we start with a pointer to the new device
+ * descriptor in the "lguest_devices" page. */
+static void add_lguest_device(struct lguest_device_desc *d)
+{
+       struct lguest_device *ldev;
+
+       ldev = kzalloc(sizeof(*ldev), GFP_KERNEL);
+       if (!ldev) {
+               printk(KERN_EMERG "Cannot allocate lguest dev %u\n",
+                      dev_index++);
+               return;
+       }
+
+       /* This devices' parent is the lguest/ dir. */
+       ldev->vdev.dev.parent = &lguest_root;
+       /* We have a unique device index thanks to the dev_index counter. */
+       ldev->vdev.index = dev_index++;
+       /* The device type comes straight from the descriptor.  There's also a
+        * device vendor field in the virtio_device struct, which we leave as
+        * 0. */
+       ldev->vdev.id.device = d->type;
+       /* We have a simple set of routines for querying the device's
+        * configuration information and setting its status. */
+       ldev->vdev.config = &lguest_config_ops;
+       /* And we remember the device's descriptor for lguest_config_ops. */
+       ldev->desc = d;
+
+       /* register_virtio_device() sets up the generic fields for the struct
+        * virtio_device and calls device_register().  This makes the bus
+        * infrastructure look for a matching driver. */
+       if (register_virtio_device(&ldev->vdev) != 0) {
+               printk(KERN_ERR "Failed to register lguest device %u\n",
+                      ldev->vdev.index);
+               kfree(ldev);
+       }
+}
+
+/*D:110 scan_devices() simply iterates through the device page.  The type 0 is
+ * reserved to mean "end of devices". */
+static void scan_devices(void)
+{
+       unsigned int i;
+       struct lguest_device_desc *d;
+
+       /* We start at the page beginning, and skip over each entry. */
+       for (i = 0; i < PAGE_SIZE; i += sizeof(*d) + d->config_len) {
+               d = lguest_devices + i;
+
+               /* Once we hit a zero, stop. */
+               if (d->type == 0)
+                       break;
+
+               add_lguest_device(d);
+       }
+}
+
+/*D:105 Fairly early in boot, lguest_devices_init() is called to set up the
+ * lguest device infrastructure.  We check that we are a Guest by checking
+ * pv_info.name: there are other ways of checking, but this seems most
+ * obvious to me.
+ *
+ * So we can access the "struct lguest_device_desc"s easily, we map that memory
+ * and store the pointer in the global "lguest_devices".  Then we register a
+ * root device from which all our devices will hang (this seems to be the
+ * correct sysfs incantation).
+ *
+ * Finally we call scan_devices() which adds all the devices found in the
+ * lguest_devices page. */
+static int __init lguest_devices_init(void)
+{
+       if (strcmp(pv_info.name, "lguest") != 0)
+               return 0;
+
+       if (device_register(&lguest_root) != 0)
+               panic("Could not register lguest root");
+
+       /* Devices are in a single page above top of "normal" mem */
+       lguest_devices = lguest_map(max_pfn<<PAGE_SHIFT, 1);
+
+       scan_devices();
+       return 0;
+}
+/* We do this after core stuff, but before the drivers. */
+postcore_initcall(lguest_devices_init);
+
+/*D:150 At this point in the journey we used to now wade through the lguest
+ * devices themselves: net, block and console.  Since they're all now virtio
+ * devices rather than lguest-specific, I've decided to ignore them.  Mostly,
+ * they're kind of boring.  But this does mean you'll never experience the
+ * thrill of reading the forbidden love scene buried deep in the block driver.
+ *
+ * "make Launcher" beckons, where we answer questions like "Where do Guests
+ * come from?", and "What do you do when someone asks for optimization?". */
index 80d1b58c76986b9d245637e4e29999793260ddcd..ee405b38383d8c4c89eb3560bd3fab2c2ecfade9 100644 (file)
@@ -1,73 +1,17 @@
 /*P:200 This contains all the /dev/lguest code, whereby the userspace launcher
  * controls and communicates with the Guest.  For example, the first write will
- * tell us the memory size, pagetable, entry point and kernel address offset.
- * A read will run the Guest until a signal is pending (-EINTR), or the Guest
- * does a DMA out to the Launcher.  Writes are also used to get a DMA buffer
- * registered by the Guest and to send the Guest an interrupt. :*/
+ * tell us the Guest's memory layout, pagetable, entry point and kernel address
+ * offset.  A read will run the Guest until something happens, such as a signal
+ * or the Guest doing a NOTIFY out to the Launcher. :*/
 #include <linux/uaccess.h>
 #include <linux/miscdevice.h>
 #include <linux/fs.h>
 #include "lg.h"
 
-/*L:030 setup_regs() doesn't really belong in this file, but it gives us an
- * early glimpse deeper into the Host so it's worth having here.
- *
- * Most of the Guest's registers are left alone: we used get_zeroed_page() to
- * allocate the structure, so they will be 0. */
-static void setup_regs(struct lguest_regs *regs, unsigned long start)
-{
-       /* There are four "segment" registers which the Guest needs to boot:
-        * The "code segment" register (cs) refers to the kernel code segment
-        * __KERNEL_CS, and the "data", "extra" and "stack" segment registers
-        * refer to the kernel data segment __KERNEL_DS.
-        *
-        * The privilege level is packed into the lower bits.  The Guest runs
-        * at privilege level 1 (GUEST_PL).*/
-       regs->ds = regs->es = regs->ss = __KERNEL_DS|GUEST_PL;
-       regs->cs = __KERNEL_CS|GUEST_PL;
-
-       /* The "eflags" register contains miscellaneous flags.  Bit 1 (0x002)
-        * is supposed to always be "1".  Bit 9 (0x200) controls whether
-        * interrupts are enabled.  We always leave interrupts enabled while
-        * running the Guest. */
-       regs->eflags = 0x202;
-
-       /* The "Extended Instruction Pointer" register says where the Guest is
-        * running. */
-       regs->eip = start;
-
-       /* %esi points to our boot information, at physical address 0, so don't
-        * touch it. */
-}
-
-/*L:310 To send DMA into the Guest, the Launcher needs to be able to ask for a
- * DMA buffer.  This is done by writing LHREQ_GETDMA and the key to
- * /dev/lguest. */
-static long user_get_dma(struct lguest *lg, const u32 __user *input)
-{
-       unsigned long key, udma, irq;
-
-       /* Fetch the key they wrote to us. */
-       if (get_user(key, input) != 0)
-               return -EFAULT;
-       /* Look for a free Guest DMA buffer bound to that key. */
-       udma = get_dma_buffer(lg, key, &irq);
-       if (!udma)
-               return -ENOENT;
-
-       /* We need to tell the Launcher what interrupt the Guest expects after
-        * the buffer is filled.  We stash it in udma->used_len. */
-       lgwrite_u32(lg, udma + offsetof(struct lguest_dma, used_len), irq);
-
-       /* The (guest-physical) address of the DMA buffer is returned from
-        * the write(). */
-       return udma;
-}
-
 /*L:315 To force the Guest to stop running and return to the Launcher, the
  * Waker sets writes LHREQ_BREAK and the value "1" to /dev/lguest.  The
  * Launcher then writes LHREQ_BREAK and "0" to release the Waker. */
-static int break_guest_out(struct lguest *lg, const u32 __user *input)
+static int break_guest_out(struct lguest *lg, const unsigned long __user *input)
 {
        unsigned long on;
 
@@ -90,9 +34,9 @@ static int break_guest_out(struct lguest *lg, const u32 __user *input)
 
 /*L:050 Sending an interrupt is done by writing LHREQ_IRQ and an interrupt
  * number to /dev/lguest. */
-static int user_send_irq(struct lguest *lg, const u32 __user *input)
+static int user_send_irq(struct lguest *lg, const unsigned long __user *input)
 {
-       u32 irq;
+       unsigned long irq;
 
        if (get_user(irq, input) != 0)
                return -EFAULT;
@@ -133,17 +77,19 @@ static ssize_t read(struct file *file, char __user *user, size_t size,loff_t*o)
                return len;
        }
 
-       /* If we returned from read() last time because the Guest sent DMA,
+       /* If we returned from read() last time because the Guest notified,
         * clear the flag. */
-       if (lg->dma_is_pending)
-               lg->dma_is_pending = 0;
+       if (lg->pending_notify)
+               lg->pending_notify = 0;
 
        /* Run the Guest until something interesting happens. */
        return run_guest(lg, (unsigned long __user *)user);
 }
 
-/*L:020 The initialization write supplies 4 32-bit values (in addition to the
- * 32-bit LHREQ_INITIALIZE value).  These are:
+/*L:020 The initialization write supplies 4 pointer sized (32 or 64 bit)
+ * values (in addition to the LHREQ_INITIALIZE value).  These are:
+ *
+ * base: The start of the Guest-physical memory inside the Launcher memory.
  *
  * pfnlimit: The highest (Guest-physical) page number the Guest should be
  * allowed to access.  The Launcher has to live in Guest memory, so it sets
@@ -153,23 +99,17 @@ static ssize_t read(struct file *file, char __user *user, size_t size,loff_t*o)
  * pagetables (which are set up by the Launcher).
  *
  * start: The first instruction to execute ("eip" in x86-speak).
- *
- * page_offset: The PAGE_OFFSET constant in the Guest kernel.  We should
- * probably wean the code off this, but it's a very useful constant!  Any
- * address above this is within the Guest kernel, and any kernel address can
- * quickly converted from physical to virtual by adding PAGE_OFFSET.  It's
- * 0xC0000000 (3G) by default, but it's configurable at kernel build time.
  */
-static int initialize(struct file *file, const u32 __user *input)
+static int initialize(struct file *file, const unsigned long __user *input)
 {
        /* "struct lguest" contains everything we (the Host) know about a
         * Guest. */
        struct lguest *lg;
-       int err, i;
-       u32 args[4];
+       int err;
+       unsigned long args[4];
 
-       /* We grab the Big Lguest lock, which protects the global array
-        * "lguests" and multiple simultaneous initializations. */
+       /* We grab the Big Lguest lock, which protects against multiple
+        * simultaneous initializations. */
        mutex_lock(&lguest_lock);
        /* You can't initialize twice!  Close the device and start again... */
        if (file->private_data) {
@@ -182,20 +122,15 @@ static int initialize(struct file *file, const u32 __user *input)
                goto unlock;
        }
 
-       /* Find an unused guest. */
-       i = find_free_guest();
-       if (i < 0) {
-               err = -ENOSPC;
+       lg = kzalloc(sizeof(*lg), GFP_KERNEL);
+       if (!lg) {
+               err = -ENOMEM;
                goto unlock;
        }
-       /* OK, we have an index into the "lguest" array: "lg" is a convenient
-        * pointer. */
-       lg = &lguests[i];
 
        /* Populate the easy fields of our "struct lguest" */
-       lg->guestid = i;
-       lg->pfn_limit = args[0];
-       lg->page_offset = args[3];
+       lg->mem_base = (void __user *)(long)args[0];
+       lg->pfn_limit = args[1];
 
        /* We need a complete page for the Guest registers: they are accessible
         * to the Guest and we can only grant it access to whole pages. */
@@ -210,17 +145,13 @@ static int initialize(struct file *file, const u32 __user *input)
        /* Initialize the Guest's shadow page tables, using the toplevel
         * address the Launcher gave us.  This allocates memory, so can
         * fail. */
-       err = init_guest_pagetable(lg, args[1]);
+       err = init_guest_pagetable(lg, args[2]);
        if (err)
                goto free_regs;
 
        /* Now we initialize the Guest's registers, handing it the start
         * address. */
-       setup_regs(lg->regs, args[2]);
-
-       /* There are a couple of GDT entries the Guest expects when first
-        * booting. */
-       setup_guest_gdt(lg);
+       lguest_arch_setup_regs(lg, args[3]);
 
        /* The timer for lguest's clock needs initialization. */
        init_clockdev(lg);
@@ -260,18 +191,19 @@ unlock:
 /*L:010 The first operation the Launcher does must be a write.  All writes
  * start with a 32 bit number: for the first write this must be
  * LHREQ_INITIALIZE to set up the Guest.  After that the Launcher can use
- * writes of other values to get DMA buffers and send interrupts. */
-static ssize_t write(struct file *file, const char __user *input,
+ * writes of other values to send interrupts. */
+static ssize_t write(struct file *file, const char __user *in,
                     size_t size, loff_t *off)
 {
        /* Once the guest is initialized, we hold the "struct lguest" in the
         * file private data. */
        struct lguest *lg = file->private_data;
-       u32 req;
+       const unsigned long __user *input = (const unsigned long __user *)in;
+       unsigned long req;
 
        if (get_user(req, input) != 0)
                return -EFAULT;
-       input += sizeof(req);
+       input++;
 
        /* If you haven't initialized, you must do that first. */
        if (req != LHREQ_INITIALIZE && !lg)
@@ -287,13 +219,11 @@ static ssize_t write(struct file *file, const char __user *input,
 
        switch (req) {
        case LHREQ_INITIALIZE:
-               return initialize(file, (const u32 __user *)input);
-       case LHREQ_GETDMA:
-               return user_get_dma(lg, (const u32 __user *)input);
+               return initialize(file, input);
        case LHREQ_IRQ:
-               return user_send_irq(lg, (const u32 __user *)input);
+               return user_send_irq(lg, input);
        case LHREQ_BREAK:
-               return break_guest_out(lg, (const u32 __user *)input);
+               return break_guest_out(lg, input);
        default:
                return -EINVAL;
        }
@@ -319,8 +249,6 @@ static int close(struct inode *inode, struct file *file)
        mutex_lock(&lguest_lock);
        /* Cancels the hrtimer set via LHCALL_SET_CLOCKEVENT. */
        hrtimer_cancel(&lg->hrt);
-       /* Free any DMA buffers the Guest had bound. */
-       release_all_dma(lg);
        /* Free up the shadow page tables for the Guest. */
        free_guest_pagetable(lg);
        /* Now all the memory cleanups are done, it's safe to release the
index b7a924ace68426d85167adb6121f7e39364e9be4..2a45f0691c9b23006f1aa54575b853b591aa8a57 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/random.h>
 #include <linux/percpu.h>
 #include <asm/tlbflush.h>
+#include <asm/uaccess.h>
 #include "lg.h"
 
 /*M:008 We hold reference to pages, which prevents them from being swapped.
  *  (vii) Setting up the page tables initially.
  :*/
 
-/* Pages a 4k long, and each page table entry is 4 bytes long, giving us 1024
- * (or 2^10) entries per page. */
-#define PTES_PER_PAGE_SHIFT 10
-#define PTES_PER_PAGE (1 << PTES_PER_PAGE_SHIFT)
 
 /* 1024 entries in a page table page maps 1024 pages: 4MB.  The Switcher is
  * conveniently placed at the top 4MB, so it uses a separate, complete PTE
  * page.  */
-#define SWITCHER_PGD_INDEX (PTES_PER_PAGE - 1)
+#define SWITCHER_PGD_INDEX (PTRS_PER_PGD - 1)
 
 /* We actually need a separate PTE page for each CPU.  Remember that after the
  * Switcher code itself comes two pages for each CPU, and we don't want this
  * CPU's guest to see the pages of any other CPU. */
-static DEFINE_PER_CPU(spte_t *, switcher_pte_pages);
+static DEFINE_PER_CPU(pte_t *, switcher_pte_pages);
 #define switcher_pte_page(cpu) per_cpu(switcher_pte_pages, cpu)
 
 /*H:320 With our shadow and Guest types established, we need to deal with
  * them: the page table code is curly enough to need helper functions to keep
  * it clear and clean.
  *
- * The first helper takes a virtual address, and says which entry in the top
- * level page table deals with that address.  Since each top level entry deals
- * with 4M, this effectively divides by 4M. */
-static unsigned vaddr_to_pgd_index(unsigned long vaddr)
-{
-       return vaddr >> (PAGE_SHIFT + PTES_PER_PAGE_SHIFT);
-}
-
-/* There are two functions which return pointers to the shadow (aka "real")
+ * There are two functions which return pointers to the shadow (aka "real")
  * page tables.
  *
  * spgd_addr() takes the virtual address and returns a pointer to the top-level
  * page directory entry for that address.  Since we keep track of several page
  * tables, the "i" argument tells us which one we're interested in (it's
  * usually the current one). */
-static spgd_t *spgd_addr(struct lguest *lg, u32 i, unsigned long vaddr)
+static pgd_t *spgd_addr(struct lguest *lg, u32 i, unsigned long vaddr)
 {
-       unsigned int index = vaddr_to_pgd_index(vaddr);
+       unsigned int index = pgd_index(vaddr);
 
        /* We kill any Guest trying to touch the Switcher addresses. */
        if (index >= SWITCHER_PGD_INDEX) {
@@ -95,28 +84,28 @@ static spgd_t *spgd_addr(struct lguest *lg, u32 i, unsigned long vaddr)
 /* This routine then takes the PGD entry given above, which contains the
  * address of the PTE page.  It then returns a pointer to the PTE entry for the
  * given address. */
-static spte_t *spte_addr(struct lguest *lg, spgd_t spgd, unsigned long vaddr)
+static pte_t *spte_addr(struct lguest *lg, pgd_t spgd, unsigned long vaddr)
 {
-       spte_t *page = __va(spgd.pfn << PAGE_SHIFT);
+       pte_t *page = __va(pgd_pfn(spgd) << PAGE_SHIFT);
        /* You should never call this if the PGD entry wasn't valid */
-       BUG_ON(!(spgd.flags & _PAGE_PRESENT));
-       return &page[(vaddr >> PAGE_SHIFT) % PTES_PER_PAGE];
+       BUG_ON(!(pgd_flags(spgd) & _PAGE_PRESENT));
+       return &page[(vaddr >> PAGE_SHIFT) % PTRS_PER_PTE];
 }
 
 /* These two functions just like the above two, except they access the Guest
  * page tables.  Hence they return a Guest address. */
 static unsigned long gpgd_addr(struct lguest *lg, unsigned long vaddr)
 {
-       unsigned int index = vaddr >> (PAGE_SHIFT + PTES_PER_PAGE_SHIFT);
-       return lg->pgdirs[lg->pgdidx].cr3 + index * sizeof(gpgd_t);
+       unsigned int index = vaddr >> (PGDIR_SHIFT);
+       return lg->pgdirs[lg->pgdidx].gpgdir + index * sizeof(pgd_t);
 }
 
 static unsigned long gpte_addr(struct lguest *lg,
-                              gpgd_t gpgd, unsigned long vaddr)
+                              pgd_t gpgd, unsigned long vaddr)
 {
-       unsigned long gpage = gpgd.pfn << PAGE_SHIFT;
-       BUG_ON(!(gpgd.flags & _PAGE_PRESENT));
-       return gpage + ((vaddr>>PAGE_SHIFT) % PTES_PER_PAGE) * sizeof(gpte_t);
+       unsigned long gpage = pgd_pfn(gpgd) << PAGE_SHIFT;
+       BUG_ON(!(pgd_flags(gpgd) & _PAGE_PRESENT));
+       return gpage + ((vaddr>>PAGE_SHIFT) % PTRS_PER_PTE) * sizeof(pte_t);
 }
 
 /*H:350 This routine takes a page number given by the Guest and converts it to
@@ -149,53 +138,55 @@ static unsigned long get_pfn(unsigned long virtpfn, int write)
  * entry can be a little tricky.  The flags are (almost) the same, but the
  * Guest PTE contains a virtual page number: the CPU needs the real page
  * number. */
-static spte_t gpte_to_spte(struct lguest *lg, gpte_t gpte, int write)
+static pte_t gpte_to_spte(struct lguest *lg, pte_t gpte, int write)
 {
-       spte_t spte;
-       unsigned long pfn;
+       unsigned long pfn, base, flags;
 
        /* The Guest sets the global flag, because it thinks that it is using
         * PGE.  We only told it to use PGE so it would tell us whether it was
         * flushing a kernel mapping or a userspace mapping.  We don't actually
         * use the global bit, so throw it away. */
-       spte.flags = (gpte.flags & ~_PAGE_GLOBAL);
+       flags = (pte_flags(gpte) & ~_PAGE_GLOBAL);
+
+       /* The Guest's pages are offset inside the Launcher. */
+       base = (unsigned long)lg->mem_base / PAGE_SIZE;
 
        /* We need a temporary "unsigned long" variable to hold the answer from
         * get_pfn(), because it returns 0xFFFFFFFF on failure, which wouldn't
         * fit in spte.pfn.  get_pfn() finds the real physical number of the
         * page, given the virtual number. */
-       pfn = get_pfn(gpte.pfn, write);
+       pfn = get_pfn(base + pte_pfn(gpte), write);
        if (pfn == -1UL) {
-               kill_guest(lg, "failed to get page %u", gpte.pfn);
+               kill_guest(lg, "failed to get page %lu", pte_pfn(gpte));
                /* When we destroy the Guest, we'll go through the shadow page
                 * tables and release_pte() them.  Make sure we don't think
                 * this one is valid! */
-               spte.flags = 0;
+               flags = 0;
        }
-       /* Now we assign the page number, and our shadow PTE is complete. */
-       spte.pfn = pfn;
-       return spte;
+       /* Now we assemble our shadow PTE from the page number and flags. */
+       return pfn_pte(pfn, __pgprot(flags));
 }
 
 /*H:460 And to complete the chain, release_pte() looks like this: */
-static void release_pte(spte_t pte)
+static void release_pte(pte_t pte)
 {
        /* Remember that get_user_pages() took a reference to the page, in
         * get_pfn()?  We have to put it back now. */
-       if (pte.flags & _PAGE_PRESENT)
-               put_page(pfn_to_page(pte.pfn));
+       if (pte_flags(pte) & _PAGE_PRESENT)
+               put_page(pfn_to_page(pte_pfn(pte)));
 }
 /*:*/
 
-static void check_gpte(struct lguest *lg, gpte_t gpte)
+static void check_gpte(struct lguest *lg, pte_t gpte)
 {
-       if ((gpte.flags & (_PAGE_PWT|_PAGE_PSE)) || gpte.pfn >= lg->pfn_limit)
+       if ((pte_flags(gpte) & (_PAGE_PWT|_PAGE_PSE))
+           || pte_pfn(gpte) >= lg->pfn_limit)
                kill_guest(lg, "bad page table entry");
 }
 
-static void check_gpgd(struct lguest *lg, gpgd_t gpgd)
+static void check_gpgd(struct lguest *lg, pgd_t gpgd)
 {
-       if ((gpgd.flags & ~_PAGE_TABLE) || gpgd.pfn >= lg->pfn_limit)
+       if ((pgd_flags(gpgd) & ~_PAGE_TABLE) || pgd_pfn(gpgd) >= lg->pfn_limit)
                kill_guest(lg, "bad page directory entry");
 }
 
@@ -211,21 +202,21 @@ static void check_gpgd(struct lguest *lg, gpgd_t gpgd)
  * true. */
 int demand_page(struct lguest *lg, unsigned long vaddr, int errcode)
 {
-       gpgd_t gpgd;
-       spgd_t *spgd;
+       pgd_t gpgd;
+       pgd_t *spgd;
        unsigned long gpte_ptr;
-       gpte_t gpte;
-       spte_t *spte;
+       pte_t gpte;
+       pte_t *spte;
 
        /* First step: get the top-level Guest page table entry. */
-       gpgd = mkgpgd(lgread_u32(lg, gpgd_addr(lg, vaddr)));
+       gpgd = lgread(lg, gpgd_addr(lg, vaddr), pgd_t);
        /* Toplevel not present?  We can't map it in. */
-       if (!(gpgd.flags & _PAGE_PRESENT))
+       if (!(pgd_flags(gpgd) & _PAGE_PRESENT))
                return 0;
 
        /* Now look at the matching shadow entry. */
        spgd = spgd_addr(lg, lg->pgdidx, vaddr);
-       if (!(spgd->flags & _PAGE_PRESENT)) {
+       if (!(pgd_flags(*spgd) & _PAGE_PRESENT)) {
                /* No shadow entry: allocate a new shadow PTE page. */
                unsigned long ptepage = get_zeroed_page(GFP_KERNEL);
                /* This is not really the Guest's fault, but killing it is
@@ -238,34 +229,35 @@ int demand_page(struct lguest *lg, unsigned long vaddr, int errcode)
                check_gpgd(lg, gpgd);
                /* And we copy the flags to the shadow PGD entry.  The page
                 * number in the shadow PGD is the page we just allocated. */
-               spgd->raw.val = (__pa(ptepage) | gpgd.flags);
+               *spgd = __pgd(__pa(ptepage) | pgd_flags(gpgd));
        }
 
        /* OK, now we look at the lower level in the Guest page table: keep its
         * address, because we might update it later. */
        gpte_ptr = gpte_addr(lg, gpgd, vaddr);
-       gpte = mkgpte(lgread_u32(lg, gpte_ptr));
+       gpte = lgread(lg, gpte_ptr, pte_t);
 
        /* If this page isn't in the Guest page tables, we can't page it in. */
-       if (!(gpte.flags & _PAGE_PRESENT))
+       if (!(pte_flags(gpte) & _PAGE_PRESENT))
                return 0;
 
        /* Check they're not trying to write to a page the Guest wants
         * read-only (bit 2 of errcode == write). */
-       if ((errcode & 2) && !(gpte.flags & _PAGE_RW))
+       if ((errcode & 2) && !(pte_flags(gpte) & _PAGE_RW))
                return 0;
 
        /* User access to a kernel page? (bit 3 == user access) */
-       if ((errcode & 4) && !(gpte.flags & _PAGE_USER))
+       if ((errcode & 4) && !(pte_flags(gpte) & _PAGE_USER))
                return 0;
 
        /* Check that the Guest PTE flags are OK, and the page number is below
         * the pfn_limit (ie. not mapping the Launcher binary). */
        check_gpte(lg, gpte);
        /* Add the _PAGE_ACCESSED and (for a write) _PAGE_DIRTY flag */
-       gpte.flags |= _PAGE_ACCESSED;
+       gpte = pte_mkyoung(gpte);
+
        if (errcode & 2)
-               gpte.flags |= _PAGE_DIRTY;
+               gpte = pte_mkdirty(gpte);
 
        /* Get the pointer to the shadow PTE entry we're going to set. */
        spte = spte_addr(lg, *spgd, vaddr);
@@ -275,21 +267,18 @@ int demand_page(struct lguest *lg, unsigned long vaddr, int errcode)
 
        /* If this is a write, we insist that the Guest page is writable (the
         * final arg to gpte_to_spte()). */
-       if (gpte.flags & _PAGE_DIRTY)
+       if (pte_dirty(gpte))
                *spte = gpte_to_spte(lg, gpte, 1);
-       else {
+       else
                /* If this is a read, don't set the "writable" bit in the page
                 * table entry, even if the Guest says it's writable.  That way
                 * we come back here when a write does actually ocur, so we can
                 * update the Guest's _PAGE_DIRTY flag. */
-               gpte_t ro_gpte = gpte;
-               ro_gpte.flags &= ~_PAGE_RW;
-               *spte = gpte_to_spte(lg, ro_gpte, 0);
-       }
+               *spte = gpte_to_spte(lg, pte_wrprotect(gpte), 0);
 
        /* Finally, we write the Guest PTE entry back: we've set the
         * _PAGE_ACCESSED and maybe the _PAGE_DIRTY flags. */
-       lgwrite_u32(lg, gpte_ptr, gpte.raw.val);
+       lgwrite(lg, gpte_ptr, pte_t, gpte);
 
        /* We succeeded in mapping the page! */
        return 1;
@@ -305,17 +294,18 @@ int demand_page(struct lguest *lg, unsigned long vaddr, int errcode)
  * mapped by the shadow page tables, and is it writable? */
 static int page_writable(struct lguest *lg, unsigned long vaddr)
 {
-       spgd_t *spgd;
+       pgd_t *spgd;
        unsigned long flags;
 
        /* Look at the top level entry: is it present? */
        spgd = spgd_addr(lg, lg->pgdidx, vaddr);
-       if (!(spgd->flags & _PAGE_PRESENT))
+       if (!(pgd_flags(*spgd) & _PAGE_PRESENT))
                return 0;
 
        /* Check the flags on the pte entry itself: it must be present and
         * writable. */
-       flags = spte_addr(lg, *spgd, vaddr)->flags;
+       flags = pte_flags(*(spte_addr(lg, *spgd, vaddr)));
+
        return (flags & (_PAGE_PRESENT|_PAGE_RW)) == (_PAGE_PRESENT|_PAGE_RW);
 }
 
@@ -329,22 +319,22 @@ void pin_page(struct lguest *lg, unsigned long vaddr)
 }
 
 /*H:450 If we chase down the release_pgd() code, it looks like this: */
-static void release_pgd(struct lguest *lg, spgd_t *spgd)
+static void release_pgd(struct lguest *lg, pgd_t *spgd)
 {
        /* If the entry's not present, there's nothing to release. */
-       if (spgd->flags & _PAGE_PRESENT) {
+       if (pgd_flags(*spgd) & _PAGE_PRESENT) {
                unsigned int i;
                /* Converting the pfn to find the actual PTE page is easy: turn
                 * the page number into a physical address, then convert to a
                 * virtual address (easy for kernel pages like this one). */
-               spte_t *ptepage = __va(spgd->pfn << PAGE_SHIFT);
+               pte_t *ptepage = __va(pgd_pfn(*spgd) << PAGE_SHIFT);
                /* For each entry in the page, we might need to release it. */
-               for (i = 0; i < PTES_PER_PAGE; i++)
+               for (i = 0; i < PTRS_PER_PTE; i++)
                        release_pte(ptepage[i]);
                /* Now we can free the page of PTEs */
                free_page((long)ptepage);
                /* And zero out the PGD entry we we never release it twice. */
-               spgd->raw.val = 0;
+               *spgd = __pgd(0);
        }
 }
 
@@ -356,7 +346,7 @@ static void flush_user_mappings(struct lguest *lg, int idx)
 {
        unsigned int i;
        /* Release every pgd entry up to the kernel's address. */
-       for (i = 0; i < vaddr_to_pgd_index(lg->page_offset); i++)
+       for (i = 0; i < pgd_index(lg->kernel_address); i++)
                release_pgd(lg, lg->pgdirs[idx].pgdir + i);
 }
 
@@ -369,6 +359,25 @@ void guest_pagetable_flush_user(struct lguest *lg)
 }
 /*:*/
 
+/* We walk down the guest page tables to get a guest-physical address */
+unsigned long guest_pa(struct lguest *lg, unsigned long vaddr)
+{
+       pgd_t gpgd;
+       pte_t gpte;
+
+       /* First step: get the top-level Guest page table entry. */
+       gpgd = lgread(lg, gpgd_addr(lg, vaddr), pgd_t);
+       /* Toplevel not present?  We can't map it in. */
+       if (!(pgd_flags(gpgd) & _PAGE_PRESENT))
+               kill_guest(lg, "Bad address %#lx", vaddr);
+
+       gpte = lgread(lg, gpte_addr(lg, gpgd, vaddr), pte_t);
+       if (!(pte_flags(gpte) & _PAGE_PRESENT))
+               kill_guest(lg, "Bad address %#lx", vaddr);
+
+       return pte_pfn(gpte) * PAGE_SIZE | (vaddr & ~PAGE_MASK);
+}
+
 /* We keep several page tables.  This is a simple routine to find the page
  * table (if any) corresponding to this top-level address the Guest has given
  * us. */
@@ -376,7 +385,7 @@ static unsigned int find_pgdir(struct lguest *lg, unsigned long pgtable)
 {
        unsigned int i;
        for (i = 0; i < ARRAY_SIZE(lg->pgdirs); i++)
-               if (lg->pgdirs[i].cr3 == pgtable)
+               if (lg->pgdirs[i].gpgdir == pgtable)
                        break;
        return i;
 }
@@ -385,7 +394,7 @@ static unsigned int find_pgdir(struct lguest *lg, unsigned long pgtable)
  * allocate a new one (and so the kernel parts are not there), we set
  * blank_pgdir. */
 static unsigned int new_pgdir(struct lguest *lg,
-                             unsigned long cr3,
+                             unsigned long gpgdir,
                              int *blank_pgdir)
 {
        unsigned int next;
@@ -395,7 +404,7 @@ static unsigned int new_pgdir(struct lguest *lg,
        next = random32() % ARRAY_SIZE(lg->pgdirs);
        /* If it's never been allocated at all before, try now. */
        if (!lg->pgdirs[next].pgdir) {
-               lg->pgdirs[next].pgdir = (spgd_t *)get_zeroed_page(GFP_KERNEL);
+               lg->pgdirs[next].pgdir = (pgd_t *)get_zeroed_page(GFP_KERNEL);
                /* If the allocation fails, just keep using the one we have */
                if (!lg->pgdirs[next].pgdir)
                        next = lg->pgdidx;
@@ -405,7 +414,7 @@ static unsigned int new_pgdir(struct lguest *lg,
                        *blank_pgdir = 1;
        }
        /* Record which Guest toplevel this shadows. */
-       lg->pgdirs[next].cr3 = cr3;
+       lg->pgdirs[next].gpgdir = gpgdir;
        /* Release all the non-kernel mappings. */
        flush_user_mappings(lg, next);
 
@@ -472,26 +481,27 @@ void guest_pagetable_clear_all(struct lguest *lg)
  * they set _PAGE_DIRTY then we can put a writable PTE entry in immediately.
  */
 static void do_set_pte(struct lguest *lg, int idx,
-                      unsigned long vaddr, gpte_t gpte)
+                      unsigned long vaddr, pte_t gpte)
 {
        /* Look up the matching shadow page directot entry. */
-       spgd_t *spgd = spgd_addr(lg, idx, vaddr);
+       pgd_t *spgd = spgd_addr(lg, idx, vaddr);
 
        /* If the top level isn't present, there's no entry to update. */
-       if (spgd->flags & _PAGE_PRESENT) {
+       if (pgd_flags(*spgd) & _PAGE_PRESENT) {
                /* Otherwise, we start by releasing the existing entry. */
-               spte_t *spte = spte_addr(lg, *spgd, vaddr);
+               pte_t *spte = spte_addr(lg, *spgd, vaddr);
                release_pte(*spte);
 
                /* If they're setting this entry as dirty or accessed, we might
                 * as well put that entry they've given us in now.  This shaves
                 * 10% off a copy-on-write micro-benchmark. */
-               if (gpte.flags & (_PAGE_DIRTY | _PAGE_ACCESSED)) {
+               if (pte_flags(gpte) & (_PAGE_DIRTY | _PAGE_ACCESSED)) {
                        check_gpte(lg, gpte);
-                       *spte = gpte_to_spte(lg, gpte, gpte.flags&_PAGE_DIRTY);
+                       *spte = gpte_to_spte(lg, gpte,
+                                            pte_flags(gpte) & _PAGE_DIRTY);
                } else
                        /* Otherwise we can demand_page() it in later. */
-                       spte->raw.val = 0;
+                       *spte = __pte(0);
        }
 }
 
@@ -506,18 +516,18 @@ static void do_set_pte(struct lguest *lg, int idx,
  * The benefit is that when we have to track a new page table, we can copy keep
  * all the kernel mappings.  This speeds up context switch immensely. */
 void guest_set_pte(struct lguest *lg,
-                  unsigned long cr3, unsigned long vaddr, gpte_t gpte)
+                  unsigned long gpgdir, unsigned long vaddr, pte_t gpte)
 {
        /* Kernel mappings must be changed on all top levels.  Slow, but
         * doesn't happen often. */
-       if (vaddr >= lg->page_offset) {
+       if (vaddr >= lg->kernel_address) {
                unsigned int i;
                for (i = 0; i < ARRAY_SIZE(lg->pgdirs); i++)
                        if (lg->pgdirs[i].pgdir)
                                do_set_pte(lg, i, vaddr, gpte);
        } else {
                /* Is this page table one we have a shadow for? */
-               int pgdir = find_pgdir(lg, cr3);
+               int pgdir = find_pgdir(lg, gpgdir);
                if (pgdir != ARRAY_SIZE(lg->pgdirs))
                        /* If so, do the update. */
                        do_set_pte(lg, pgdir, vaddr, gpte);
@@ -538,7 +548,7 @@ void guest_set_pte(struct lguest *lg,
  *
  * So with that in mind here's our code to to update a (top-level) PGD entry:
  */
-void guest_set_pmd(struct lguest *lg, unsigned long cr3, u32 idx)
+void guest_set_pmd(struct lguest *lg, unsigned long gpgdir, u32 idx)
 {
        int pgdir;
 
@@ -548,7 +558,7 @@ void guest_set_pmd(struct lguest *lg, unsigned long cr3, u32 idx)
                return;
 
        /* If they're talking about a page table we have a shadow for... */
-       pgdir = find_pgdir(lg, cr3);
+       pgdir = find_pgdir(lg, gpgdir);
        if (pgdir < ARRAY_SIZE(lg->pgdirs))
                /* ... throw it away. */
                release_pgd(lg, lg->pgdirs[pgdir].pgdir + idx);
@@ -560,21 +570,34 @@ void guest_set_pmd(struct lguest *lg, unsigned long cr3, u32 idx)
  * its first page table is.  We set some things up here: */
 int init_guest_pagetable(struct lguest *lg, unsigned long pgtable)
 {
-       /* In flush_user_mappings() we loop from 0 to
-        * "vaddr_to_pgd_index(lg->page_offset)".  This assumes it won't hit
-        * the Switcher mappings, so check that now. */
-       if (vaddr_to_pgd_index(lg->page_offset) >= SWITCHER_PGD_INDEX)
-               return -EINVAL;
        /* We start on the first shadow page table, and give it a blank PGD
         * page. */
        lg->pgdidx = 0;
-       lg->pgdirs[lg->pgdidx].cr3 = pgtable;
-       lg->pgdirs[lg->pgdidx].pgdir = (spgd_t*)get_zeroed_page(GFP_KERNEL);
+       lg->pgdirs[lg->pgdidx].gpgdir = pgtable;
+       lg->pgdirs[lg->pgdidx].pgdir = (pgd_t*)get_zeroed_page(GFP_KERNEL);
        if (!lg->pgdirs[lg->pgdidx].pgdir)
                return -ENOMEM;
        return 0;
 }
 
+/* When the Guest calls LHCALL_LGUEST_INIT we do more setup. */
+void page_table_guest_data_init(struct lguest *lg)
+{
+       /* We get the kernel address: above this is all kernel memory. */
+       if (get_user(lg->kernel_address, &lg->lguest_data->kernel_address)
+           /* We tell the Guest that it can't use the top 4MB of virtual
+            * addresses used by the Switcher. */
+           || put_user(4U*1024*1024, &lg->lguest_data->reserve_mem)
+           || put_user(lg->pgdirs[lg->pgdidx].gpgdir,&lg->lguest_data->pgdir))
+               kill_guest(lg, "bad guest page %p", lg->lguest_data);
+
+       /* In flush_user_mappings() we loop from 0 to
+        * "pgd_index(lg->kernel_address)".  This assumes it won't hit the
+        * Switcher mappings, so check that now. */
+       if (pgd_index(lg->kernel_address) >= SWITCHER_PGD_INDEX)
+               kill_guest(lg, "bad kernel address %#lx", lg->kernel_address);
+}
+
 /* When a Guest dies, our cleanup is fairly simple. */
 void free_guest_pagetable(struct lguest *lg)
 {
@@ -594,14 +617,14 @@ void free_guest_pagetable(struct lguest *lg)
  * for each CPU already set up, we just need to hook them in. */
 void map_switcher_in_guest(struct lguest *lg, struct lguest_pages *pages)
 {
-       spte_t *switcher_pte_page = __get_cpu_var(switcher_pte_pages);
-       spgd_t switcher_pgd;
-       spte_t regs_pte;
+       pte_t *switcher_pte_page = __get_cpu_var(switcher_pte_pages);
+       pgd_t switcher_pgd;
+       pte_t regs_pte;
 
        /* Make the last PGD entry for this Guest point to the Switcher's PTE
         * page for this CPU (with appropriate flags). */
-       switcher_pgd.pfn = __pa(switcher_pte_page) >> PAGE_SHIFT;
-       switcher_pgd.flags = _PAGE_KERNEL;
+       switcher_pgd = __pgd(__pa(switcher_pte_page) | _PAGE_KERNEL);
+
        lg->pgdirs[lg->pgdidx].pgdir[SWITCHER_PGD_INDEX] = switcher_pgd;
 
        /* We also change the Switcher PTE page.  When we're running the Guest,
@@ -611,10 +634,8 @@ void map_switcher_in_guest(struct lguest *lg, struct lguest_pages *pages)
         * CPU's "struct lguest_pages": if we make sure the Guest's register
         * page is already mapped there, we don't have to copy them out
         * again. */
-       regs_pte.pfn = __pa(lg->regs_page) >> PAGE_SHIFT;
-       regs_pte.flags = _PAGE_KERNEL;
-       switcher_pte_page[(unsigned long)pages/PAGE_SIZE%PTES_PER_PAGE]
-               = regs_pte;
+       regs_pte = pfn_pte (__pa(lg->regs_page) >> PAGE_SHIFT, __pgprot(_PAGE_KERNEL));
+       switcher_pte_page[(unsigned long)pages/PAGE_SIZE%PTRS_PER_PTE] = regs_pte;
 }
 /*:*/
 
@@ -635,24 +656,25 @@ static __init void populate_switcher_pte_page(unsigned int cpu,
                                              unsigned int pages)
 {
        unsigned int i;
-       spte_t *pte = switcher_pte_page(cpu);
+       pte_t *pte = switcher_pte_page(cpu);
 
        /* The first entries are easy: they map the Switcher code. */
        for (i = 0; i < pages; i++) {
-               pte[i].pfn = page_to_pfn(switcher_page[i]);
-               pte[i].flags = _PAGE_PRESENT|_PAGE_ACCESSED;
+               pte[i] = mk_pte(switcher_page[i],
+                               __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED));
        }
 
        /* The only other thing we map is this CPU's pair of pages. */
        i = pages + cpu*2;
 
        /* First page (Guest registers) is writable from the Guest */
-       pte[i].pfn = page_to_pfn(switcher_page[i]);
-       pte[i].flags = _PAGE_PRESENT|_PAGE_ACCESSED|_PAGE_RW;
+       pte[i] = pfn_pte(page_to_pfn(switcher_page[i]),
+                        __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED|_PAGE_RW));
+
        /* The second page contains the "struct lguest_ro_state", and is
         * read-only. */
-       pte[i+1].pfn = page_to_pfn(switcher_page[i+1]);
-       pte[i+1].flags = _PAGE_PRESENT|_PAGE_ACCESSED;
+       pte[i+1] = pfn_pte(page_to_pfn(switcher_page[i+1]),
+                          __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED));
 }
 
 /*H:510 At boot or module load time, init_pagetables() allocates and populates
@@ -662,7 +684,7 @@ __init int init_pagetables(struct page **switcher_page, unsigned int pages)
        unsigned int i;
 
        for_each_possible_cpu(i) {
-               switcher_pte_page(i) = (spte_t *)get_zeroed_page(GFP_KERNEL);
+               switcher_pte_page(i) = (pte_t *)get_zeroed_page(GFP_KERNEL);
                if (!switcher_pte_page(i)) {
                        free_switcher_pte_pages();
                        return -ENOMEM;
index 9b81119f46e937ce9b9639fe4e74f65139288a51..c2434ec99f7ba6458ae9da1c6bcb1ef877fbea56 100644 (file)
@@ -73,14 +73,14 @@ static void fixup_gdt_table(struct lguest *lg, unsigned start, unsigned end)
                /* Segment descriptors contain a privilege level: the Guest is
                 * sometimes careless and leaves this as 0, even though it's
                 * running at privilege level 1.  If so, we fix it here. */
-               if ((lg->gdt[i].b & 0x00006000) == 0)
-                       lg->gdt[i].b |= (GUEST_PL << 13);
+               if ((lg->arch.gdt[i].b & 0x00006000) == 0)
+                       lg->arch.gdt[i].b |= (GUEST_PL << 13);
 
                /* Each descriptor has an "accessed" bit.  If we don't set it
                 * now, the CPU will try to set it when the Guest first loads
                 * that entry into a segment register.  But the GDT isn't
                 * writable by the Guest, so bad things can happen. */
-               lg->gdt[i].b |= 0x00000100;
+               lg->arch.gdt[i].b |= 0x00000100;
        }
 }
 
@@ -106,12 +106,12 @@ void setup_default_gdt_entries(struct lguest_ro_state *state)
 void setup_guest_gdt(struct lguest *lg)
 {
        /* Start with full 0-4G segments... */
-       lg->gdt[GDT_ENTRY_KERNEL_CS] = FULL_EXEC_SEGMENT;
-       lg->gdt[GDT_ENTRY_KERNEL_DS] = FULL_SEGMENT;
+       lg->arch.gdt[GDT_ENTRY_KERNEL_CS] = FULL_EXEC_SEGMENT;
+       lg->arch.gdt[GDT_ENTRY_KERNEL_DS] = FULL_SEGMENT;
        /* ...except the Guest is allowed to use them, so set the privilege
         * level appropriately in the flags. */
-       lg->gdt[GDT_ENTRY_KERNEL_CS].b |= (GUEST_PL << 13);
-       lg->gdt[GDT_ENTRY_KERNEL_DS].b |= (GUEST_PL << 13);
+       lg->arch.gdt[GDT_ENTRY_KERNEL_CS].b |= (GUEST_PL << 13);
+       lg->arch.gdt[GDT_ENTRY_KERNEL_DS].b |= (GUEST_PL << 13);
 }
 
 /* Like the IDT, we never simply use the GDT the Guest gives us.  We set up the
@@ -126,7 +126,7 @@ void copy_gdt_tls(const struct lguest *lg, struct desc_struct *gdt)
        unsigned int i;
 
        for (i = GDT_ENTRY_TLS_MIN; i <= GDT_ENTRY_TLS_MAX; i++)
-               gdt[i] = lg->gdt[i];
+               gdt[i] = lg->arch.gdt[i];
 }
 
 /* This is the full version */
@@ -138,7 +138,7 @@ void copy_gdt(const struct lguest *lg, struct desc_struct *gdt)
         * replaced.  See ignored_gdt() above. */
        for (i = 0; i < GDT_ENTRIES; i++)
                if (!ignored_gdt(i))
-                       gdt[i] = lg->gdt[i];
+                       gdt[i] = lg->arch.gdt[i];
 }
 
 /* This is where the Guest asks us to load a new GDT (LHCALL_LOAD_GDT). */
@@ -146,12 +146,12 @@ void load_guest_gdt(struct lguest *lg, unsigned long table, u32 num)
 {
        /* We assume the Guest has the same number of GDT entries as the
         * Host, otherwise we'd have to dynamically allocate the Guest GDT. */
-       if (num > ARRAY_SIZE(lg->gdt))
+       if (num > ARRAY_SIZE(lg->arch.gdt))
                kill_guest(lg, "too many gdt entries %i", num);
 
        /* We read the whole thing in, then fix it up. */
-       lgread(lg, lg->gdt, table, num * sizeof(lg->gdt[0]));
-       fixup_gdt_table(lg, 0, ARRAY_SIZE(lg->gdt));
+       __lgread(lg, lg->arch.gdt, table, num * sizeof(lg->arch.gdt[0]));
+       fixup_gdt_table(lg, 0, ARRAY_SIZE(lg->arch.gdt));
        /* Mark that the GDT changed so the core knows it has to copy it again,
         * even if the Guest is run on the same CPU. */
        lg->changed |= CHANGED_GDT;
@@ -159,9 +159,9 @@ void load_guest_gdt(struct lguest *lg, unsigned long table, u32 num)
 
 void guest_load_tls(struct lguest *lg, unsigned long gtls)
 {
-       struct desc_struct *tls = &lg->gdt[GDT_ENTRY_TLS_MIN];
+       struct desc_struct *tls = &lg->arch.gdt[GDT_ENTRY_TLS_MIN];
 
-       lgread(lg, tls, gtls, sizeof(*tls)*GDT_ENTRY_TLS_ENTRIES);
+       __lgread(lg, tls, gtls, sizeof(*tls)*GDT_ENTRY_TLS_ENTRIES);
        fixup_gdt_table(lg, GDT_ENTRY_TLS_MIN, GDT_ENTRY_TLS_MAX+1);
        lg->changed |= CHANGED_GDT_TLS;
 }
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
new file mode 100644 (file)
index 0000000..9eed12d
--- /dev/null
@@ -0,0 +1,577 @@
+/*
+ * Copyright (C) 2006, Rusty Russell <rusty@rustcorp.com.au> IBM Corporation.
+ * Copyright (C) 2007, Jes Sorensen <jes@sgi.com> SGI.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/kernel.h>
+#include <linux/start_kernel.h>
+#include <linux/string.h>
+#include <linux/console.h>
+#include <linux/screen_info.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/cpu.h>
+#include <linux/lguest.h>
+#include <linux/lguest_launcher.h>
+#include <asm/paravirt.h>
+#include <asm/param.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/desc.h>
+#include <asm/setup.h>
+#include <asm/lguest.h>
+#include <asm/uaccess.h>
+#include <asm/i387.h>
+#include "../lg.h"
+
+static int cpu_had_pge;
+
+static struct {
+       unsigned long offset;
+       unsigned short segment;
+} lguest_entry;
+
+/* Offset from where switcher.S was compiled to where we've copied it */
+static unsigned long switcher_offset(void)
+{
+       return SWITCHER_ADDR - (unsigned long)start_switcher_text;
+}
+
+/* This cpu's struct lguest_pages. */
+static struct lguest_pages *lguest_pages(unsigned int cpu)
+{
+       return &(((struct lguest_pages *)
+                 (SWITCHER_ADDR + SHARED_SWITCHER_PAGES*PAGE_SIZE))[cpu]);
+}
+
+static DEFINE_PER_CPU(struct lguest *, last_guest);
+
+/*S:010
+ * We are getting close to the Switcher.
+ *
+ * Remember that each CPU has two pages which are visible to the Guest when it
+ * runs on that CPU.  This has to contain the state for that Guest: we copy the
+ * state in just before we run the Guest.
+ *
+ * Each Guest has "changed" flags which indicate what has changed in the Guest
+ * since it last ran.  We saw this set in interrupts_and_traps.c and
+ * segments.c.
+ */
+static void copy_in_guest_info(struct lguest *lg, struct lguest_pages *pages)
+{
+       /* Copying all this data can be quite expensive.  We usually run the
+        * same Guest we ran last time (and that Guest hasn't run anywhere else
+        * meanwhile).  If that's not the case, we pretend everything in the
+        * Guest has changed. */
+       if (__get_cpu_var(last_guest) != lg || lg->last_pages != pages) {
+               __get_cpu_var(last_guest) = lg;
+               lg->last_pages = pages;
+               lg->changed = CHANGED_ALL;
+       }
+
+       /* These copies are pretty cheap, so we do them unconditionally: */
+       /* Save the current Host top-level page directory. */
+       pages->state.host_cr3 = __pa(current->mm->pgd);
+       /* Set up the Guest's page tables to see this CPU's pages (and no
+        * other CPU's pages). */
+       map_switcher_in_guest(lg, pages);
+       /* Set up the two "TSS" members which tell the CPU what stack to use
+        * for traps which do directly into the Guest (ie. traps at privilege
+        * level 1). */
+       pages->state.guest_tss.esp1 = lg->esp1;
+       pages->state.guest_tss.ss1 = lg->ss1;
+
+       /* Copy direct-to-Guest trap entries. */
+       if (lg->changed & CHANGED_IDT)
+               copy_traps(lg, pages->state.guest_idt, default_idt_entries);
+
+       /* Copy all GDT entries which the Guest can change. */
+       if (lg->changed & CHANGED_GDT)
+               copy_gdt(lg, pages->state.guest_gdt);
+       /* If only the TLS entries have changed, copy them. */
+       else if (lg->changed & CHANGED_GDT_TLS)
+               copy_gdt_tls(lg, pages->state.guest_gdt);
+
+       /* Mark the Guest as unchanged for next time. */
+       lg->changed = 0;
+}
+
+/* Finally: the code to actually call into the Switcher to run the Guest. */
+static void run_guest_once(struct lguest *lg, struct lguest_pages *pages)
+{
+       /* This is a dummy value we need for GCC's sake. */
+       unsigned int clobber;
+
+       /* Copy the guest-specific information into this CPU's "struct
+        * lguest_pages". */
+       copy_in_guest_info(lg, pages);
+
+       /* Set the trap number to 256 (impossible value).  If we fault while
+        * switching to the Guest (bad segment registers or bug), this will
+        * cause us to abort the Guest. */
+       lg->regs->trapnum = 256;
+
+       /* Now: we push the "eflags" register on the stack, then do an "lcall".
+        * This is how we change from using the kernel code segment to using
+        * the dedicated lguest code segment, as well as jumping into the
+        * Switcher.
+        *
+        * The lcall also pushes the old code segment (KERNEL_CS) onto the
+        * stack, then the address of this call.  This stack layout happens to
+        * exactly match the stack of an interrupt... */
+       asm volatile("pushf; lcall *lguest_entry"
+                    /* This is how we tell GCC that %eax ("a") and %ebx ("b")
+                     * are changed by this routine.  The "=" means output. */
+                    : "=a"(clobber), "=b"(clobber)
+                    /* %eax contains the pages pointer.  ("0" refers to the
+                     * 0-th argument above, ie "a").  %ebx contains the
+                     * physical address of the Guest's top-level page
+                     * directory. */
+                    : "0"(pages), "1"(__pa(lg->pgdirs[lg->pgdidx].pgdir))
+                    /* We tell gcc that all these registers could change,
+                     * which means we don't have to save and restore them in
+                     * the Switcher. */
+                    : "memory", "%edx", "%ecx", "%edi", "%esi");
+}
+/*:*/
+
+/*H:040 This is the i386-specific code to setup and run the Guest.  Interrupts
+ * are disabled: we own the CPU. */
+void lguest_arch_run_guest(struct lguest *lg)
+{
+       /* Remember the awfully-named TS bit?  If the Guest has asked
+        * to set it we set it now, so we can trap and pass that trap
+        * to the Guest if it uses the FPU. */
+       if (lg->ts)
+               lguest_set_ts();
+
+       /* SYSENTER is an optimized way of doing system calls.  We
+        * can't allow it because it always jumps to privilege level 0.
+        * A normal Guest won't try it because we don't advertise it in
+        * CPUID, but a malicious Guest (or malicious Guest userspace
+        * program) could, so we tell the CPU to disable it before
+        * running the Guest. */
+       if (boot_cpu_has(X86_FEATURE_SEP))
+               wrmsr(MSR_IA32_SYSENTER_CS, 0, 0);
+
+       /* Now we actually run the Guest.  It will pop back out when
+        * something interesting happens, and we can examine its
+        * registers to see what it was doing. */
+       run_guest_once(lg, lguest_pages(raw_smp_processor_id()));
+
+       /* The "regs" pointer contains two extra entries which are not
+        * really registers: a trap number which says what interrupt or
+        * trap made the switcher code come back, and an error code
+        * which some traps set.  */
+
+       /* If the Guest page faulted, then the cr2 register will tell
+        * us the bad virtual address.  We have to grab this now,
+        * because once we re-enable interrupts an interrupt could
+        * fault and thus overwrite cr2, or we could even move off to a
+        * different CPU. */
+       if (lg->regs->trapnum == 14)
+               lg->arch.last_pagefault = read_cr2();
+       /* Similarly, if we took a trap because the Guest used the FPU,
+        * we have to restore the FPU it expects to see. */
+       else if (lg->regs->trapnum == 7)
+               math_state_restore();
+
+       /* Restore SYSENTER if it's supposed to be on. */
+       if (boot_cpu_has(X86_FEATURE_SEP))
+               wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
+}
+
+/*H:130 Our Guest is usually so well behaved; it never tries to do things it
+ * isn't allowed to.  Unfortunately, Linux's paravirtual infrastructure isn't
+ * quite complete, because it doesn't contain replacements for the Intel I/O
+ * instructions.  As a result, the Guest sometimes fumbles across one during
+ * the boot process as it probes for various things which are usually attached
+ * to a PC.
+ *
+ * When the Guest uses one of these instructions, we get trap #13 (General
+ * Protection Fault) and come here.  We see if it's one of those troublesome
+ * instructions and skip over it.  We return true if we did. */
+static int emulate_insn(struct lguest *lg)
+{
+       u8 insn;
+       unsigned int insnlen = 0, in = 0, shift = 0;
+       /* The eip contains the *virtual* address of the Guest's instruction:
+        * guest_pa just subtracts the Guest's page_offset. */
+       unsigned long physaddr = guest_pa(lg, lg->regs->eip);
+
+       /* This must be the Guest kernel trying to do something, not userspace!
+        * The bottom two bits of the CS segment register are the privilege
+        * level. */
+       if ((lg->regs->cs & 3) != GUEST_PL)
+               return 0;
+
+       /* Decoding x86 instructions is icky. */
+       insn = lgread(lg, physaddr, u8);
+
+       /* 0x66 is an "operand prefix".  It means it's using the upper 16 bits
+          of the eax register. */
+       if (insn == 0x66) {
+               shift = 16;
+               /* The instruction is 1 byte so far, read the next byte. */
+               insnlen = 1;
+               insn = lgread(lg, physaddr + insnlen, u8);
+       }
+
+       /* We can ignore the lower bit for the moment and decode the 4 opcodes
+        * we need to emulate. */
+       switch (insn & 0xFE) {
+       case 0xE4: /* in     <next byte>,%al */
+               insnlen += 2;
+               in = 1;
+               break;
+       case 0xEC: /* in     (%dx),%al */
+               insnlen += 1;
+               in = 1;
+               break;
+       case 0xE6: /* out    %al,<next byte> */
+               insnlen += 2;
+               break;
+       case 0xEE: /* out    %al,(%dx) */
+               insnlen += 1;
+               break;
+       default:
+               /* OK, we don't know what this is, can't emulate. */
+               return 0;
+       }
+
+       /* If it was an "IN" instruction, they expect the result to be read
+        * into %eax, so we change %eax.  We always return all-ones, which
+        * traditionally means "there's nothing there". */
+       if (in) {
+               /* Lower bit tells is whether it's a 16 or 32 bit access */
+               if (insn & 0x1)
+                       lg->regs->eax = 0xFFFFFFFF;
+               else
+                       lg->regs->eax |= (0xFFFF << shift);
+       }
+       /* Finally, we've "done" the instruction, so move past it. */
+       lg->regs->eip += insnlen;
+       /* Success! */
+       return 1;
+}
+
+/*H:050 Once we've re-enabled interrupts, we look at why the Guest exited. */
+void lguest_arch_handle_trap(struct lguest *lg)
+{
+       switch (lg->regs->trapnum) {
+       case 13: /* We've intercepted a GPF. */
+                /* Check if this was one of those annoying IN or OUT
+                 * instructions which we need to emulate.  If so, we
+                 * just go back into the Guest after we've done it. */
+               if (lg->regs->errcode == 0) {
+                       if (emulate_insn(lg))
+                               return;
+               }
+               break;
+       case 14: /* We've intercepted a page fault. */
+                /* The Guest accessed a virtual address that wasn't
+                 * mapped.  This happens a lot: we don't actually set
+                 * up most of the page tables for the Guest at all when
+                 * we start: as it runs it asks for more and more, and
+                 * we set them up as required. In this case, we don't
+                 * even tell the Guest that the fault happened.
+                 *
+                 * The errcode tells whether this was a read or a
+                 * write, and whether kernel or userspace code. */
+               if (demand_page(lg, lg->arch.last_pagefault, lg->regs->errcode))
+                       return;
+
+                /* OK, it's really not there (or not OK): the Guest
+                 * needs to know.  We write out the cr2 value so it
+                 * knows where the fault occurred.
+                 *
+                 * Note that if the Guest were really messed up, this
+                 * could happen before it's done the INITIALIZE
+                 * hypercall, so lg->lguest_data will be NULL */
+               if (lg->lguest_data &&
+                   put_user(lg->arch.last_pagefault, &lg->lguest_data->cr2))
+                       kill_guest(lg, "Writing cr2");
+               break;
+       case 7: /* We've intercepted a Device Not Available fault. */
+               /* If the Guest doesn't want to know, we already
+                * restored the Floating Point Unit, so we just
+                * continue without telling it. */
+               if (!lg->ts)
+                       return;
+               break;
+       case 32 ... 255:
+               /* These values mean a real interrupt occurred, in which case
+                * the Host handler has already been run.  We just do a
+                * friendly check if another process should now be run, then
+                * return to run the Guest again */
+               cond_resched();
+               return;
+       case LGUEST_TRAP_ENTRY:
+               /* Our 'struct hcall_args' maps directly over our regs: we set
+                * up the pointer now to indicate a hypercall is pending. */
+               lg->hcall = (struct hcall_args *)lg->regs;
+               return;
+       }
+
+       /* We didn't handle the trap, so it needs to go to the Guest. */
+       if (!deliver_trap(lg, lg->regs->trapnum))
+               /* If the Guest doesn't have a handler (either it hasn't
+                * registered any yet, or it's one of the faults we don't let
+                * it handle), it dies with a cryptic error message. */
+               kill_guest(lg, "unhandled trap %li at %#lx (%#lx)",
+                          lg->regs->trapnum, lg->regs->eip,
+                          lg->regs->trapnum == 14 ? lg->arch.last_pagefault
+                          : lg->regs->errcode);
+}
+
+/* Now we can look at each of the routines this calls, in increasing order of
+ * complexity: do_hypercalls(), emulate_insn(), maybe_do_interrupt(),
+ * deliver_trap() and demand_page().  After all those, we'll be ready to
+ * examine the Switcher, and our philosophical understanding of the Host/Guest
+ * duality will be complete. :*/
+static void adjust_pge(void *on)
+{
+       if (on)
+               write_cr4(read_cr4() | X86_CR4_PGE);
+       else
+               write_cr4(read_cr4() & ~X86_CR4_PGE);
+}
+
+/*H:020 Now the Switcher is mapped and every thing else is ready, we need to do
+ * some more i386-specific initialization. */
+void __init lguest_arch_host_init(void)
+{
+       int i;
+
+       /* Most of the i386/switcher.S doesn't care that it's been moved; on
+        * Intel, jumps are relative, and it doesn't access any references to
+        * external code or data.
+        *
+        * The only exception is the interrupt handlers in switcher.S: their
+        * addresses are placed in a table (default_idt_entries), so we need to
+        * update the table with the new addresses.  switcher_offset() is a
+        * convenience function which returns the distance between the builtin
+        * switcher code and the high-mapped copy we just made. */
+       for (i = 0; i < IDT_ENTRIES; i++)
+               default_idt_entries[i] += switcher_offset();
+
+       /*
+        * Set up the Switcher's per-cpu areas.
+        *
+        * Each CPU gets two pages of its own within the high-mapped region
+        * (aka. "struct lguest_pages").  Much of this can be initialized now,
+        * but some depends on what Guest we are running (which is set up in
+        * copy_in_guest_info()).
+        */
+       for_each_possible_cpu(i) {
+               /* lguest_pages() returns this CPU's two pages. */
+               struct lguest_pages *pages = lguest_pages(i);
+               /* This is a convenience pointer to make the code fit one
+                * statement to a line. */
+               struct lguest_ro_state *state = &pages->state;
+
+               /* The Global Descriptor Table: the Host has a different one
+                * for each CPU.  We keep a descriptor for the GDT which says
+                * where it is and how big it is (the size is actually the last
+                * byte, not the size, hence the "-1"). */
+               state->host_gdt_desc.size = GDT_SIZE-1;
+               state->host_gdt_desc.address = (long)get_cpu_gdt_table(i);
+
+               /* All CPUs on the Host use the same Interrupt Descriptor
+                * Table, so we just use store_idt(), which gets this CPU's IDT
+                * descriptor. */
+               store_idt(&state->host_idt_desc);
+
+               /* The descriptors for the Guest's GDT and IDT can be filled
+                * out now, too.  We copy the GDT & IDT into ->guest_gdt and
+                * ->guest_idt before actually running the Guest. */
+               state->guest_idt_desc.size = sizeof(state->guest_idt)-1;
+               state->guest_idt_desc.address = (long)&state->guest_idt;
+               state->guest_gdt_desc.size = sizeof(state->guest_gdt)-1;
+               state->guest_gdt_desc.address = (long)&state->guest_gdt;
+
+               /* We know where we want the stack to be when the Guest enters
+                * the switcher: in pages->regs.  The stack grows upwards, so
+                * we start it at the end of that structure. */
+               state->guest_tss.esp0 = (long)(&pages->regs + 1);
+               /* And this is the GDT entry to use for the stack: we keep a
+                * couple of special LGUEST entries. */
+               state->guest_tss.ss0 = LGUEST_DS;
+
+               /* x86 can have a finegrained bitmap which indicates what I/O
+                * ports the process can use.  We set it to the end of our
+                * structure, meaning "none". */
+               state->guest_tss.io_bitmap_base = sizeof(state->guest_tss);
+
+               /* Some GDT entries are the same across all Guests, so we can
+                * set them up now. */
+               setup_default_gdt_entries(state);
+               /* Most IDT entries are the same for all Guests, too.*/
+               setup_default_idt_entries(state, default_idt_entries);
+
+               /* The Host needs to be able to use the LGUEST segments on this
+                * CPU, too, so put them in the Host GDT. */
+               get_cpu_gdt_table(i)[GDT_ENTRY_LGUEST_CS] = FULL_EXEC_SEGMENT;
+               get_cpu_gdt_table(i)[GDT_ENTRY_LGUEST_DS] = FULL_SEGMENT;
+       }
+
+       /* In the Switcher, we want the %cs segment register to use the
+        * LGUEST_CS GDT entry: we've put that in the Host and Guest GDTs, so
+        * it will be undisturbed when we switch.  To change %cs and jump we
+        * need this structure to feed to Intel's "lcall" instruction. */
+       lguest_entry.offset = (long)switch_to_guest + switcher_offset();
+       lguest_entry.segment = LGUEST_CS;
+
+       /* Finally, we need to turn off "Page Global Enable".  PGE is an
+        * optimization where page table entries are specially marked to show
+        * they never change.  The Host kernel marks all the kernel pages this
+        * way because it's always present, even when userspace is running.
+        *
+        * Lguest breaks this: unbeknownst to the rest of the Host kernel, we
+        * switch to the Guest kernel.  If you don't disable this on all CPUs,
+        * you'll get really weird bugs that you'll chase for two days.
+        *
+        * I used to turn PGE off every time we switched to the Guest and back
+        * on when we return, but that slowed the Switcher down noticibly. */
+
+       /* We don't need the complexity of CPUs coming and going while we're
+        * doing this. */
+       lock_cpu_hotplug();
+       if (cpu_has_pge) { /* We have a broader idea of "global". */
+               /* Remember that this was originally set (for cleanup). */
+               cpu_had_pge = 1;
+               /* adjust_pge is a helper function which sets or unsets the PGE
+                * bit on its CPU, depending on the argument (0 == unset). */
+               on_each_cpu(adjust_pge, (void *)0, 0, 1);
+               /* Turn off the feature in the global feature set. */
+               clear_bit(X86_FEATURE_PGE, boot_cpu_data.x86_capability);
+       }
+       unlock_cpu_hotplug();
+};
+/*:*/
+
+void __exit lguest_arch_host_fini(void)
+{
+       /* If we had PGE before we started, turn it back on now. */
+       lock_cpu_hotplug();
+       if (cpu_had_pge) {
+               set_bit(X86_FEATURE_PGE, boot_cpu_data.x86_capability);
+               /* adjust_pge's argument "1" means set PGE. */
+               on_each_cpu(adjust_pge, (void *)1, 0, 1);
+       }
+       unlock_cpu_hotplug();
+}
+
+
+/*H:122 The i386-specific hypercalls simply farm out to the right functions. */
+int lguest_arch_do_hcall(struct lguest *lg, struct hcall_args *args)
+{
+       switch (args->arg0) {
+       case LHCALL_LOAD_GDT:
+               load_guest_gdt(lg, args->arg1, args->arg2);
+               break;
+       case LHCALL_LOAD_IDT_ENTRY:
+               load_guest_idt_entry(lg, args->arg1, args->arg2, args->arg3);
+               break;
+       case LHCALL_LOAD_TLS:
+               guest_load_tls(lg, args->arg1);
+               break;
+       default:
+               /* Bad Guest.  Bad! */
+               return -EIO;
+       }
+       return 0;
+}
+
+/*H:126 i386-specific hypercall initialization: */
+int lguest_arch_init_hypercalls(struct lguest *lg)
+{
+       u32 tsc_speed;
+
+       /* The pointer to the Guest's "struct lguest_data" is the only
+        * argument.  We check that address now. */
+       if (!lguest_address_ok(lg, lg->hcall->arg1, sizeof(*lg->lguest_data)))
+               return -EFAULT;
+
+       /* Having checked it, we simply set lg->lguest_data to point straight
+        * into the Launcher's memory at the right place and then use
+        * copy_to_user/from_user from now on, instead of lgread/write.  I put
+        * this in to show that I'm not immune to writing stupid
+        * optimizations. */
+       lg->lguest_data = lg->mem_base + lg->hcall->arg1;
+
+       /* We insist that the Time Stamp Counter exist and doesn't change with
+        * cpu frequency.  Some devious chip manufacturers decided that TSC
+        * changes could be handled in software.  I decided that time going
+        * backwards might be good for benchmarks, but it's bad for users.
+        *
+        * We also insist that the TSC be stable: the kernel detects unreliable
+        * TSCs for its own purposes, and we use that here. */
+       if (boot_cpu_has(X86_FEATURE_CONSTANT_TSC) && !check_tsc_unstable())
+               tsc_speed = tsc_khz;
+       else
+               tsc_speed = 0;
+       if (put_user(tsc_speed, &lg->lguest_data->tsc_khz))
+               return -EFAULT;
+
+       /* The interrupt code might not like the system call vector. */
+       if (!check_syscall_vector(lg))
+               kill_guest(lg, "bad syscall vector");
+
+       return 0;
+}
+/* Now we've examined the hypercall code; our Guest can make requests.  There
+ * is one other way we can do things for the Guest, as we see in
+ * emulate_insn(). :*/
+
+/*L:030 lguest_arch_setup_regs()
+ *
+ * Most of the Guest's registers are left alone: we used get_zeroed_page() to
+ * allocate the structure, so they will be 0. */
+void lguest_arch_setup_regs(struct lguest *lg, unsigned long start)
+{
+       struct lguest_regs *regs = lg->regs;
+
+       /* There are four "segment" registers which the Guest needs to boot:
+        * The "code segment" register (cs) refers to the kernel code segment
+        * __KERNEL_CS, and the "data", "extra" and "stack" segment registers
+        * refer to the kernel data segment __KERNEL_DS.
+        *
+        * The privilege level is packed into the lower bits.  The Guest runs
+        * at privilege level 1 (GUEST_PL).*/
+       regs->ds = regs->es = regs->ss = __KERNEL_DS|GUEST_PL;
+       regs->cs = __KERNEL_CS|GUEST_PL;
+
+       /* The "eflags" register contains miscellaneous flags.  Bit 1 (0x002)
+        * is supposed to always be "1".  Bit 9 (0x200) controls whether
+        * interrupts are enabled.  We always leave interrupts enabled while
+        * running the Guest. */
+       regs->eflags = 0x202;
+
+       /* The "Extended Instruction Pointer" register says where the Guest is
+        * running. */
+       regs->eip = start;
+
+       /* %esi points to our boot information, at physical address 0, so don't
+        * touch it. */
+       /* There are a couple of GDT entries the Guest expects when first
+        * booting. */
+
+       setup_guest_gdt(lg);
+}
similarity index 99%
rename from drivers/lguest/switcher.S
rename to drivers/lguest/x86/switcher_32.S
index 7c9c230cc845f184973e6eebea5beb9a41568735..1010b90b11fc234d9d2054af94ec32ce3bb7e5e5 100644 (file)
@@ -48,7 +48,8 @@
 #include <linux/linkage.h>
 #include <asm/asm-offsets.h>
 #include <asm/page.h>
-#include "lg.h"
+#include <asm/segment.h>
+#include <asm/lguest.h>
 
 // We mark the start of the code to copy
 // It's placed in .text tho it's never run here
@@ -132,6 +133,7 @@ ENTRY(switch_to_guest)
        // The Guest's register page has been mapped
        // Writable onto our %esp (stack) --
        // We can simply pop off all Guest regs.
+       popl    %eax
        popl    %ebx
        popl    %ecx
        popl    %edx
@@ -139,7 +141,6 @@ ENTRY(switch_to_guest)
        popl    %edi
        popl    %ebp
        popl    %gs
-       popl    %eax
        popl    %fs
        popl    %ds
        popl    %es
@@ -167,7 +168,6 @@ ENTRY(switch_to_guest)
        pushl   %es;                                                    \
        pushl   %ds;                                                    \
        pushl   %fs;                                                    \
-       pushl   %eax;                                                   \
        pushl   %gs;                                                    \
        pushl   %ebp;                                                   \
        pushl   %edi;                                                   \
@@ -175,6 +175,7 @@ ENTRY(switch_to_guest)
        pushl   %edx;                                                   \
        pushl   %ecx;                                                   \
        pushl   %ebx;                                                   \
+       pushl   %eax;                                                   \
        /* Our stack and our code are using segments                    \
         * Set in the TSS and IDT                                       \
         * Yet if we were to touch data we'd use                        \
index 2766e4fc4ea82e36cfa7ce205076ad7f1c3cae44..883da72b5368d236d6c0246da16509b9a97bc42f 100644 (file)
@@ -791,8 +791,10 @@ adbhid_input_register(int id, int default_id, int original_handler_id,
                        if (hid->keycode[i])
                                set_bit(hid->keycode[i], input_dev->keybit);
 
-               input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
-               input_dev->ledbit[0] = BIT(LED_SCROLLL) | BIT(LED_CAPSL) | BIT(LED_NUML);
+               input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_LED) |
+                       BIT_MASK(EV_REP);
+               input_dev->ledbit[0] = BIT_MASK(LED_SCROLLL) |
+                       BIT_MASK(LED_CAPSL) | BIT_MASK(LED_NUML);
                input_dev->event = adbhid_kbd_event;
                input_dev->keycodemax = KEY_FN;
                input_dev->keycodesize = sizeof(hid->keycode[0]);
@@ -801,16 +803,18 @@ adbhid_input_register(int id, int default_id, int original_handler_id,
        case ADB_MOUSE:
                sprintf(hid->name, "ADB mouse");
 
-               input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-               input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
-               input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+               input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+               input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+                       BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
+               input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
                break;
 
        case ADB_MISC:
                switch (original_handler_id) {
                case 0x02: /* Adjustable keyboard button device */
                        sprintf(hid->name, "ADB adjustable keyboard buttons");
-                       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+                       input_dev->evbit[0] = BIT_MASK(EV_KEY) |
+                               BIT_MASK(EV_REP);
                        set_bit(KEY_SOUND, input_dev->keybit);
                        set_bit(KEY_MUTE, input_dev->keybit);
                        set_bit(KEY_VOLUMEUP, input_dev->keybit);
@@ -818,7 +822,8 @@ adbhid_input_register(int id, int default_id, int original_handler_id,
                        break;
                case 0x1f: /* Powerbook button device */
                        sprintf(hid->name, "ADB Powerbook buttons");
-                       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+                       input_dev->evbit[0] = BIT_MASK(EV_KEY) |
+                               BIT_MASK(EV_REP);
                        set_bit(KEY_MUTE, input_dev->keybit);
                        set_bit(KEY_VOLUMEUP, input_dev->keybit);
                        set_bit(KEY_VOLUMEDOWN, input_dev->keybit);
index 33dee3a773ed29ae4cad14fe9fa37203ba7cbfef..89302309da92d56f397096ad8412a4e7fa2ef1d4 100644 (file)
@@ -117,9 +117,10 @@ static int emumousebtn_input_register(void)
        emumousebtn->id.product = 0x0001;
        emumousebtn->id.version = 0x0100;
 
-       emumousebtn->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-       emumousebtn->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
-       emumousebtn->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+       emumousebtn->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+       emumousebtn->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+               BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
+       emumousebtn->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
 
        ret = input_register_device(emumousebtn);
        if (ret)
index c803d2bba65db3148a3bfd3060deebf4ae9a69af..48d647abea460ce914168072012208690c4c57d5 100644 (file)
@@ -563,7 +563,7 @@ static void media_bay_step(int i)
                                ide_init_hwif_ports(&hw, (unsigned long) bay->cd_base, (unsigned long) 0, NULL);
                                hw.irq = bay->cd_irq;
                                hw.chipset = ide_pmac;
-                               bay->cd_index = ide_register_hw(&hw, 0, NULL);
+                               bay->cd_index = ide_register_hw(&hw, NULL, 0, NULL);
                                pmu_resume();
                        }
                        if (bay->cd_index == -1) {
index f7c509b7a8ea1eaa5c25166f5ec51e3f0840e95d..dc741d3a4531cbe365aa8b89256a0337782b5b00 100644 (file)
@@ -1521,7 +1521,7 @@ pmu_sr_intr(void)
                        req = current_req;
                        /* 
                         * For PMU sleep and freq change requests, we lock the
-                        * PMU until it's explicitely unlocked. This avoids any
+                        * PMU until it's explicitly unlocked. This avoids any
                         * spurrious event polling getting in
                         */
                        current_req = req->next;
index 34a8c60a254a690c288b112ff71d7cdf0a306d6a..9b6fbf044fd803bb04836f36381ea8ec9bdc58f6 100644 (file)
@@ -267,6 +267,12 @@ config DM_MULTIPATH_RDAC
        ---help---
          Multipath support for LSI/Engenio RDAC.
 
+config DM_MULTIPATH_HP
+        tristate "HP MSA multipath support (EXPERIMENTAL)"
+        depends on DM_MULTIPATH && BLK_DEV_DM && EXPERIMENTAL
+        ---help---
+          Multipath support for HP MSA (Active/Passive) series hardware.
+
 config DM_DELAY
        tristate "I/O delaying target (EXPERIMENTAL)"
        depends on BLK_DEV_DM && EXPERIMENTAL
@@ -276,4 +282,10 @@ config DM_DELAY
 
        If unsure, say N.
 
+config DM_UEVENT
+       bool "DM uevents (EXPERIMENTAL)"
+       depends on BLK_DEV_DM && EXPERIMENTAL
+       ---help---
+       Generate udev events for DM events.
+
 endif # MD
index c49366cdc05d07e991a081ac55ea4eaf6e8f1b3a..d9aa7edb87801ec0e7f36b7614f4a23f97827e5c 100644 (file)
@@ -8,6 +8,7 @@ dm-multipath-objs := dm-hw-handler.o dm-path-selector.o dm-mpath.o
 dm-snapshot-objs := dm-snap.o dm-exception-store.o
 dm-mirror-objs := dm-log.o dm-raid1.o
 dm-rdac-objs   := dm-mpath-rdac.o
+dm-hp-sw-objs  := dm-mpath-hp-sw.o
 md-mod-objs     := md.o bitmap.o
 raid456-objs   := raid5.o raid6algos.o raid6recov.o raid6tables.o \
                   raid6int1.o raid6int2.o raid6int4.o \
@@ -35,6 +36,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_MULTIPATH_EMC) += dm-emc.o
+obj-$(CONFIG_DM_MULTIPATH_HP)  += dm-hp-sw.o
 obj-$(CONFIG_DM_MULTIPATH_RDAC)        += dm-rdac.o
 obj-$(CONFIG_DM_SNAPSHOT)      += dm-snapshot.o
 obj-$(CONFIG_DM_MIRROR)                += dm-mirror.o
@@ -48,6 +50,10 @@ ifeq ($(CONFIG_ALTIVEC),y)
 altivec_flags := -maltivec -mabi=altivec
 endif
 
+ifeq ($(CONFIG_DM_UEVENT),y)
+dm-mod-objs                    += dm-uevent.o
+endif
+
 targets += raid6int1.c
 $(obj)/raid6int1.c:   UNROLL := 1
 $(obj)/raid6int1.c:   $(src)/raid6int.uc $(src)/unroll.pl FORCE
index 927cb34c480584d75803d8eb826db7e8f4a45c83..7c426d07a555c0426855571552289c6ed9fcaaaa 100644 (file)
@@ -274,7 +274,7 @@ static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait)
                        if (bitmap->offset < 0) {
                                /* DATA  BITMAP METADATA  */
                                if (bitmap->offset
-                                   + page->index * (PAGE_SIZE/512)
+                                   + (long)(page->index * (PAGE_SIZE/512))
                                    + size/512 > 0)
                                        /* bitmap runs in to metadata */
                                        return -EINVAL;
index 3f7b827649e3d5ceeb93c1e4d51a5290b4dce933..d4509be0fe67f78ecb91c0a5981d28ab9edd31cc 100644 (file)
@@ -21,11 +21,6 @@ static inline int bio_list_empty(const struct bio_list *bl)
        return bl->head == NULL;
 }
 
-#define BIO_LIST_INIT { .head = NULL, .tail = NULL }
-
-#define BIO_LIST(bl) \
-       struct bio_list bl = BIO_LIST_INIT
-
 static inline void bio_list_init(struct bio_list *bl)
 {
        bl->head = bl->tail = NULL;
index 64fee90bb68b92f5ac897c9ebe3fff3f0e578880..ac54f697c508e57adc95d545ca4ec15459118d84 100644 (file)
@@ -36,7 +36,6 @@ struct dm_crypt_io {
        struct work_struct work;
        atomic_t pending;
        int error;
-       int post_process;
 };
 
 /*
@@ -57,7 +56,7 @@ struct crypt_config;
 
 struct crypt_iv_operations {
        int (*ctr)(struct crypt_config *cc, struct dm_target *ti,
-                  const char *opts);
+                  const char *opts);
        void (*dtr)(struct crypt_config *cc);
        const char *(*status)(struct crypt_config *cc);
        int (*generator)(struct crypt_config *cc, u8 *iv, sector_t sector);
@@ -80,6 +79,8 @@ struct crypt_config {
        mempool_t *page_pool;
        struct bio_set *bs;
 
+       struct workqueue_struct *io_queue;
+       struct workqueue_struct *crypt_queue;
        /*
         * crypto related data
         */
@@ -112,7 +113,7 @@ static void clone_init(struct dm_crypt_io *, struct bio *);
  * Different IV generation algorithms:
  *
  * plain: the initial vector is the 32-bit little-endian version of the sector
- *        number, padded with zeros if neccessary.
+ *        number, padded with zeros if necessary.
  *
  * essiv: "encrypted sector|salt initial vector", the sector number is
  *        encrypted with the bulk cipher using a salt as key. The salt
@@ -137,7 +138,7 @@ static int crypt_iv_plain_gen(struct crypt_config *cc, u8 *iv, sector_t sector)
 }
 
 static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti,
-                             const char *opts)
+                             const char *opts)
 {
        struct crypto_cipher *essiv_tfm;
        struct crypto_hash *hash_tfm;
@@ -175,6 +176,7 @@ static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti,
 
        if (err) {
                ti->error = "Error calculating hash in ESSIV";
+               kfree(salt);
                return err;
        }
 
@@ -188,7 +190,7 @@ static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti,
        if (crypto_cipher_blocksize(essiv_tfm) !=
            crypto_blkcipher_ivsize(cc->tfm)) {
                ti->error = "Block size of ESSIV cipher does "
-                               "not match IV size of block cipher";
+                           "not match IV size of block cipher";
                crypto_free_cipher(essiv_tfm);
                kfree(salt);
                return -EINVAL;
@@ -319,10 +321,10 @@ crypt_convert_scatterlist(struct crypt_config *cc, struct scatterlist *out,
        return r;
 }
 
-static void
-crypt_convert_init(struct crypt_config *cc, struct convert_context *ctx,
-                   struct bio *bio_out, struct bio *bio_in,
-                   sector_t sector, int write)
+static void crypt_convert_init(struct crypt_config *cc,
+                              struct convert_context *ctx,
+                              struct bio *bio_out, struct bio *bio_in,
+                              sector_t sector, int write)
 {
        ctx->bio_in = bio_in;
        ctx->bio_out = bio_out;
@@ -338,7 +340,7 @@ crypt_convert_init(struct crypt_config *cc, struct convert_context *ctx,
  * Encrypt / decrypt data from one bio to another one (can be the same one)
  */
 static int crypt_convert(struct crypt_config *cc,
-                         struct convert_context *ctx)
+                        struct convert_context *ctx)
 {
        int r = 0;
 
@@ -346,16 +348,17 @@ static int crypt_convert(struct crypt_config *cc,
              ctx->idx_out < ctx->bio_out->bi_vcnt) {
                struct bio_vec *bv_in = bio_iovec_idx(ctx->bio_in, ctx->idx_in);
                struct bio_vec *bv_out = bio_iovec_idx(ctx->bio_out, ctx->idx_out);
-               struct scatterlist sg_in = {
-                       .page = bv_in->bv_page,
-                       .offset = bv_in->bv_offset + ctx->offset_in,
-                       .length = 1 << SECTOR_SHIFT
-               };
-               struct scatterlist sg_out = {
-                       .page = bv_out->bv_page,
-                       .offset = bv_out->bv_offset + ctx->offset_out,
-                       .length = 1 << SECTOR_SHIFT
-               };
+               struct scatterlist sg_in, sg_out;
+
+               sg_init_table(&sg_in, 1);
+               sg_set_page(&sg_in, bv_in->bv_page);
+               sg_in.offset = bv_in->bv_offset + ctx->offset_in;
+               sg_in.length = 1 << SECTOR_SHIFT;
+
+               sg_init_table(&sg_out, 1);
+               sg_set_page(&sg_out, bv_out->bv_page);
+               sg_out.offset = bv_out->bv_offset + ctx->offset_out;
+               sg_out.length = 1 << SECTOR_SHIFT;
 
                ctx->offset_in += sg_in.length;
                if (ctx->offset_in >= bv_in->bv_len) {
@@ -370,7 +373,7 @@ static int crypt_convert(struct crypt_config *cc,
                }
 
                r = crypt_convert_scatterlist(cc, &sg_out, &sg_in, sg_in.length,
-                                             ctx->write, ctx->sector);
+                                             ctx->write, ctx->sector);
                if (r < 0)
                        break;
 
@@ -380,13 +383,13 @@ static int crypt_convert(struct crypt_config *cc,
        return r;
 }
 
- static void dm_crypt_bio_destructor(struct bio *bio)
- {
+static void dm_crypt_bio_destructor(struct bio *bio)
+{
        struct dm_crypt_io *io = bio->bi_private;
        struct crypt_config *cc = io->target->private;
 
        bio_free(bio, cc->bs);
- }
+}
 
 /*
  * Generate a new unfragmented bio with the given size
@@ -458,7 +461,7 @@ static void crypt_free_buffer_pages(struct crypt_config *cc, struct bio *clone)
  * One of the bios was finished. Check for completion of
  * the whole request and correctly clean up the buffer.
  */
-static void dec_pending(struct dm_crypt_io *io, int error)
+static void crypt_dec_pending(struct dm_crypt_io *io, int error)
 {
        struct crypt_config *cc = (struct crypt_config *) io->target->private;
 
@@ -474,18 +477,36 @@ static void dec_pending(struct dm_crypt_io *io, int error)
 }
 
 /*
- * kcryptd:
+ * kcryptd/kcryptd_io:
  *
  * Needed because it would be very unwise to do decryption in an
  * interrupt context.
+ *
+ * kcryptd performs the actual encryption or decryption.
+ *
+ * kcryptd_io performs the IO submission.
+ *
+ * They must be separated as otherwise the final stages could be
+ * starved by new requests which can block in the first stages due
+ * to memory allocation.
  */
-static struct workqueue_struct *_kcryptd_workqueue;
 static void kcryptd_do_work(struct work_struct *work);
+static void kcryptd_do_crypt(struct work_struct *work);
 
 static void kcryptd_queue_io(struct dm_crypt_io *io)
 {
+       struct crypt_config *cc = io->target->private;
+
        INIT_WORK(&io->work, kcryptd_do_work);
-       queue_work(_kcryptd_workqueue, &io->work);
+       queue_work(cc->io_queue, &io->work);
+}
+
+static void kcryptd_queue_crypt(struct dm_crypt_io *io)
+{
+       struct crypt_config *cc = io->target->private;
+
+       INIT_WORK(&io->work, kcryptd_do_crypt);
+       queue_work(cc->crypt_queue, &io->work);
 }
 
 static void crypt_endio(struct bio *clone, int error)
@@ -508,13 +529,12 @@ static void crypt_endio(struct bio *clone, int error)
        }
 
        bio_put(clone);
-       io->post_process = 1;
-       kcryptd_queue_io(io);
+       kcryptd_queue_crypt(io);
        return;
 
 out:
        bio_put(clone);
-       dec_pending(io, error);
+       crypt_dec_pending(io, error);
 }
 
 static void clone_init(struct dm_crypt_io *io, struct bio *clone)
@@ -544,7 +564,7 @@ static void process_read(struct dm_crypt_io *io)
         */
        clone = bio_alloc_bioset(GFP_NOIO, bio_segments(base_bio), cc->bs);
        if (unlikely(!clone)) {
-               dec_pending(io, -ENOMEM);
+               crypt_dec_pending(io, -ENOMEM);
                return;
        }
 
@@ -579,7 +599,7 @@ static void process_write(struct dm_crypt_io *io)
        while (remaining) {
                clone = crypt_alloc_buffer(io, remaining);
                if (unlikely(!clone)) {
-                       dec_pending(io, -ENOMEM);
+                       crypt_dec_pending(io, -ENOMEM);
                        return;
                }
 
@@ -589,7 +609,7 @@ static void process_write(struct dm_crypt_io *io)
                if (unlikely(crypt_convert(cc, &ctx) < 0)) {
                        crypt_free_buffer_pages(cc, clone);
                        bio_put(clone);
-                       dec_pending(io, -EIO);
+                       crypt_dec_pending(io, -EIO);
                        return;
                }
 
@@ -624,17 +644,23 @@ static void process_read_endio(struct dm_crypt_io *io)
        crypt_convert_init(cc, &ctx, io->base_bio, io->base_bio,
                           io->base_bio->bi_sector - io->target->begin, 0);
 
-       dec_pending(io, crypt_convert(cc, &ctx));
+       crypt_dec_pending(io, crypt_convert(cc, &ctx));
 }
 
 static void kcryptd_do_work(struct work_struct *work)
 {
        struct dm_crypt_io *io = container_of(work, struct dm_crypt_io, work);
 
-       if (io->post_process)
-               process_read_endio(io);
-       else if (bio_data_dir(io->base_bio) == READ)
+       if (bio_data_dir(io->base_bio) == READ)
                process_read(io);
+}
+
+static void kcryptd_do_crypt(struct work_struct *work)
+{
+       struct dm_crypt_io *io = container_of(work, struct dm_crypt_io, work);
+
+       if (bio_data_dir(io->base_bio) == READ)
+               process_read_endio(io);
        else
                process_write(io);
 }
@@ -690,7 +716,7 @@ static int crypt_set_key(struct crypt_config *cc, char *key)
        cc->key_size = key_size; /* initial settings */
 
        if ((!key_size && strcmp(key, "-")) ||
-           (key_size && crypt_decode_key(cc->key, key, key_size) < 0))
+          (key_size && crypt_decode_key(cc->key, key, key_size) < 0))
                return -EINVAL;
 
        set_bit(DM_CRYPT_KEY_VALID, &cc->flags);
@@ -746,7 +772,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 
        if (crypt_set_key(cc, argv[1])) {
                ti->error = "Error decoding key";
-               goto bad1;
+               goto bad_cipher;
        }
 
        /* Compatiblity mode for old dm-crypt cipher strings */
@@ -757,19 +783,19 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 
        if (strcmp(chainmode, "ecb") && !ivmode) {
                ti->error = "This chaining mode requires an IV mechanism";
-               goto bad1;
+               goto bad_cipher;
        }
 
-       if (snprintf(cc->cipher, CRYPTO_MAX_ALG_NAME, "%s(%s)", chainmode, 
-                    cipher) >= CRYPTO_MAX_ALG_NAME) {
+       if (snprintf(cc->cipher, CRYPTO_MAX_ALG_NAME, "%s(%s)",
+                    chainmode, cipher) >= CRYPTO_MAX_ALG_NAME) {
                ti->error = "Chain mode + cipher name is too long";
-               goto bad1;
+               goto bad_cipher;
        }
 
        tfm = crypto_alloc_blkcipher(cc->cipher, 0, CRYPTO_ALG_ASYNC);
        if (IS_ERR(tfm)) {
                ti->error = "Error allocating crypto tfm";
-               goto bad1;
+               goto bad_cipher;
        }
 
        strcpy(cc->cipher, cipher);
@@ -793,18 +819,18 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
                cc->iv_gen_ops = &crypt_iv_null_ops;
        else {
                ti->error = "Invalid IV mode";
-               goto bad2;
+               goto bad_ivmode;
        }
 
        if (cc->iv_gen_ops && cc->iv_gen_ops->ctr &&
            cc->iv_gen_ops->ctr(cc, ti, ivopts) < 0)
-               goto bad2;
+               goto bad_ivmode;
 
        cc->iv_size = crypto_blkcipher_ivsize(tfm);
        if (cc->iv_size)
                /* at least a 64 bit sector number should fit in our buffer */
                cc->iv_size = max(cc->iv_size,
-                                 (unsigned int)(sizeof(u64) / sizeof(u8)));
+                                 (unsigned int)(sizeof(u64) / sizeof(u8)));
        else {
                if (cc->iv_gen_ops) {
                        DMWARN("Selected cipher does not support IVs");
@@ -817,13 +843,13 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
        cc->io_pool = mempool_create_slab_pool(MIN_IOS, _crypt_io_pool);
        if (!cc->io_pool) {
                ti->error = "Cannot allocate crypt io mempool";
-               goto bad3;
+               goto bad_slab_pool;
        }
 
        cc->page_pool = mempool_create_page_pool(MIN_POOL_PAGES, 0);
        if (!cc->page_pool) {
                ti->error = "Cannot allocate page mempool";
-               goto bad4;
+               goto bad_page_pool;
        }
 
        cc->bs = bioset_create(MIN_IOS, MIN_IOS);
@@ -834,25 +860,25 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 
        if (crypto_blkcipher_setkey(tfm, cc->key, key_size) < 0) {
                ti->error = "Error setting key";
-               goto bad5;
+               goto bad_device;
        }
 
        if (sscanf(argv[2], "%llu", &tmpll) != 1) {
                ti->error = "Invalid iv_offset sector";
-               goto bad5;
+               goto bad_device;
        }
        cc->iv_offset = tmpll;
 
        if (sscanf(argv[4], "%llu", &tmpll) != 1) {
                ti->error = "Invalid device sector";
-               goto bad5;
+               goto bad_device;
        }
        cc->start = tmpll;
 
        if (dm_get_device(ti, argv[3], cc->start, ti->len,
-                         dm_table_get_mode(ti->table), &cc->dev)) {
+                         dm_table_get_mode(ti->table), &cc->dev)) {
                ti->error = "Device lookup failed";
-               goto bad5;
+               goto bad_device;
        }
 
        if (ivmode && cc->iv_gen_ops) {
@@ -861,27 +887,45 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
                cc->iv_mode = kmalloc(strlen(ivmode) + 1, GFP_KERNEL);
                if (!cc->iv_mode) {
                        ti->error = "Error kmallocing iv_mode string";
-                       goto bad5;
+                       goto bad_ivmode_string;
                }
                strcpy(cc->iv_mode, ivmode);
        } else
                cc->iv_mode = NULL;
 
+       cc->io_queue = create_singlethread_workqueue("kcryptd_io");
+       if (!cc->io_queue) {
+               ti->error = "Couldn't create kcryptd io queue";
+               goto bad_io_queue;
+       }
+
+       cc->crypt_queue = create_singlethread_workqueue("kcryptd");
+       if (!cc->crypt_queue) {
+               ti->error = "Couldn't create kcryptd queue";
+               goto bad_crypt_queue;
+       }
+
        ti->private = cc;
        return 0;
 
-bad5:
+bad_crypt_queue:
+       destroy_workqueue(cc->io_queue);
+bad_io_queue:
+       kfree(cc->iv_mode);
+bad_ivmode_string:
+       dm_put_device(ti, cc->dev);
+bad_device:
        bioset_free(cc->bs);
 bad_bs:
        mempool_destroy(cc->page_pool);
-bad4:
+bad_page_pool:
        mempool_destroy(cc->io_pool);
-bad3:
+bad_slab_pool:
        if (cc->iv_gen_ops && cc->iv_gen_ops->dtr)
                cc->iv_gen_ops->dtr(cc);
-bad2:
+bad_ivmode:
        crypto_free_blkcipher(tfm);
-bad1:
+bad_cipher:
        /* Must zero key material before freeing */
        memset(cc, 0, sizeof(*cc) + cc->key_size * sizeof(u8));
        kfree(cc);
@@ -892,7 +936,8 @@ static void crypt_dtr(struct dm_target *ti)
 {
        struct crypt_config *cc = (struct crypt_config *) ti->private;
 
-       flush_workqueue(_kcryptd_workqueue);
+       destroy_workqueue(cc->io_queue);
+       destroy_workqueue(cc->crypt_queue);
 
        bioset_free(cc->bs);
        mempool_destroy(cc->page_pool);
@@ -918,9 +963,13 @@ static int crypt_map(struct dm_target *ti, struct bio *bio,
        io = mempool_alloc(cc->io_pool, GFP_NOIO);
        io->target = ti;
        io->base_bio = bio;
-       io->error = io->post_process = 0;
+       io->error = 0;
        atomic_set(&io->pending, 0);
-       kcryptd_queue_io(io);
+
+       if (bio_data_dir(io->base_bio) == READ)
+               kcryptd_queue_io(io);
+       else
+               kcryptd_queue_crypt(io);
 
        return DM_MAPIO_SUBMITTED;
 }
@@ -1037,25 +1086,12 @@ static int __init dm_crypt_init(void)
        if (!_crypt_io_pool)
                return -ENOMEM;
 
-       _kcryptd_workqueue = create_workqueue("kcryptd");
-       if (!_kcryptd_workqueue) {
-               r = -ENOMEM;
-               DMERR("couldn't create kcryptd");
-               goto bad1;
-       }
-
        r = dm_register_target(&crypt_target);
        if (r < 0) {
                DMERR("register failed %d", r);
-               goto bad2;
+               kmem_cache_destroy(_crypt_io_pool);
        }
 
-       return 0;
-
-bad2:
-       destroy_workqueue(_kcryptd_workqueue);
-bad1:
-       kmem_cache_destroy(_crypt_io_pool);
        return r;
 }
 
@@ -1066,7 +1102,6 @@ static void __exit dm_crypt_exit(void)
        if (r < 0)
                DMERR("unregister failed %d", r);
 
-       destroy_workqueue(_kcryptd_workqueue);
        kmem_cache_destroy(_crypt_io_pool);
 }
 
index 6928c136d3c540d8fdcec9730216f436e1cd9131..bdd37f881c42ab757cb381514db10d4d232b854e 100644 (file)
@@ -83,7 +83,7 @@ static struct bio *flush_delayed_bios(struct delay_c *dc, int flush_all)
        struct dm_delay_info *delayed, *next;
        unsigned long next_expires = 0;
        int start_timer = 0;
-       BIO_LIST(flush_bios);
+       struct bio_list flush_bios = { };
 
        mutex_lock(&delayed_bios_lock);
        list_for_each_entry_safe(delayed, next, &dc->delayed_bios, list) {
@@ -163,34 +163,32 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv)
                goto bad;
        }
 
-       if (argc == 3) {
-               dc->dev_write = NULL;
+       dc->dev_write = NULL;
+       if (argc == 3)
                goto out;
-       }
 
        if (sscanf(argv[4], "%llu", &tmpll) != 1) {
                ti->error = "Invalid write device sector";
-               goto bad;
+               goto bad_dev_read;
        }
        dc->start_write = tmpll;
 
        if (sscanf(argv[5], "%u", &dc->write_delay) != 1) {
                ti->error = "Invalid write delay";
-               goto bad;
+               goto bad_dev_read;
        }
 
        if (dm_get_device(ti, argv[3], dc->start_write, ti->len,
                          dm_table_get_mode(ti->table), &dc->dev_write)) {
                ti->error = "Write device lookup failed";
-               dm_put_device(ti, dc->dev_read);
-               goto bad;
+               goto bad_dev_read;
        }
 
 out:
        dc->delayed_pool = mempool_create_slab_pool(128, delayed_cache);
        if (!dc->delayed_pool) {
                DMERR("Couldn't create delayed bio pool.");
-               goto bad;
+               goto bad_dev_write;
        }
 
        setup_timer(&dc->delay_timer, handle_delayed_timer, (unsigned long)dc);
@@ -203,6 +201,11 @@ out:
        ti->private = dc;
        return 0;
 
+bad_dev_write:
+       if (dc->dev_write)
+               dm_put_device(ti, dc->dev_write);
+bad_dev_read:
+       dm_put_device(ti, dc->dev_read);
 bad:
        kfree(dc);
        return -EINVAL;
@@ -305,7 +308,7 @@ static int delay_status(struct dm_target *ti, status_type_t type,
                       (unsigned long long) dc->start_read,
                       dc->read_delay);
                if (dc->dev_write)
-                       DMEMIT("%s %llu %u", dc->dev_write->name,
+                       DMEMIT(" %s %llu %u", dc->dev_write->name,
                               (unsigned long long) dc->start_write,
                               dc->write_delay);
                break;
index 342517261ece129dd115f34897b1ff762a1fd78b..6b91b9ab1d41f537bc81e703ecffa710f0efcdf8 100644 (file)
@@ -81,7 +81,7 @@ static struct bio *get_failover_bio(struct dm_path *path, unsigned data_size)
        }
 
        if (bio_add_page(bio, page, data_size, 0) != data_size) {
-               DMERR("get_failover_bio: alloc_page() failed.");
+               DMERR("get_failover_bio: bio_add_page() failed.");
                __free_page(page);
                bio_put(bio);
                return NULL;
@@ -211,12 +211,10 @@ fail_path:
 
 static struct emc_handler *alloc_emc_handler(void)
 {
-       struct emc_handler *h = kmalloc(sizeof(*h), GFP_KERNEL);
+       struct emc_handler *h = kzalloc(sizeof(*h), GFP_KERNEL);
 
-       if (h) {
-               memset(h, 0, sizeof(*h));
+       if (h)
                spin_lock_init(&h->lock);
-       }
 
        return h;
 }
index baafaaba4d4b5632d177f1a3e1f8cb374de1119c..2ee84d8aa0bf754244196d9189b04a10a99f2461 100644 (file)
@@ -91,12 +91,10 @@ void dm_put_hw_handler(struct hw_handler_type *hwht)
 
 static struct hwh_internal *_alloc_hw_handler(struct hw_handler_type *hwht)
 {
-       struct hwh_internal *hwhi = kmalloc(sizeof(*hwhi), GFP_KERNEL);
+       struct hwh_internal *hwhi = kzalloc(sizeof(*hwhi), GFP_KERNEL);
 
-       if (hwhi) {
-               memset(hwhi, 0, sizeof(*hwhi));
+       if (hwhi)
                hwhi->hwht = *hwht;
-       }
 
        return hwhi;
 }
index e0832e6fcf36c0747c06ae3035c12567e80df797..46809dcb121ae6f7319ac1485f29ac122ef42a9b 100644 (file)
@@ -58,5 +58,6 @@ unsigned dm_scsi_err_handler(struct hw_handler *hwh, struct bio *bio);
 #define MP_FAIL_PATH 1
 #define MP_BYPASS_PG 2
 #define MP_ERROR_IO  4 /* Don't retry this I/O */
+#define MP_RETRY 8
 
 #endif
index b441d82c338a32156a6d270eaa1f7cb5553178f9..138200bf5e0befa90ff67d7ac50c231313f94380 100644 (file)
@@ -700,7 +700,7 @@ static int dev_rename(struct dm_ioctl *param, size_t param_size)
        int r;
        char *new_name = (char *) param + param->data_start;
 
-       if (new_name < (char *) (param + 1) ||
+       if (new_name < (char *) param->data ||
            invalid_str(new_name, (void *) param + param_size)) {
                DMWARN("Invalid new logical volume name supplied.");
                return -EINVAL;
@@ -726,7 +726,7 @@ static int dev_set_geometry(struct dm_ioctl *param, size_t param_size)
        if (!md)
                return -ENXIO;
 
-       if (geostr < (char *) (param + 1) ||
+       if (geostr < (char *) param->data ||
            invalid_str(geostr, (void *) param + param_size)) {
                DMWARN("Invalid geometry supplied.");
                goto out;
@@ -1233,7 +1233,7 @@ static int target_message(struct dm_ioctl *param, size_t param_size)
        if (r)
                goto out;
 
-       if (tmsg < (struct dm_target_msg *) (param + 1) ||
+       if (tmsg < (struct dm_target_msg *) param->data ||
            invalid_str(tmsg->message, (void *) param + param_size)) {
                DMWARN("Invalid target message parameters.");
                r = -EINVAL;
@@ -1358,7 +1358,7 @@ static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl **param)
        if (tmp.data_size < sizeof(tmp))
                return -EINVAL;
 
-       dmi = (struct dm_ioctl *) vmalloc(tmp.data_size);
+       dmi = vmalloc(tmp.data_size);
        if (!dmi)
                return -ENOMEM;
 
@@ -1515,3 +1515,35 @@ void dm_interface_exit(void)
 
        dm_hash_exit();
 }
+
+/**
+ * dm_copy_name_and_uuid - Copy mapped device name & uuid into supplied buffers
+ * @md: Pointer to mapped_device
+ * @name: Buffer (size DM_NAME_LEN) for name
+ * @uuid: Buffer (size DM_UUID_LEN) for uuid or empty string if uuid not defined
+ */
+int dm_copy_name_and_uuid(struct mapped_device *md, char *name, char *uuid)
+{
+       int r = 0;
+       struct hash_cell *hc;
+
+       if (!md)
+               return -ENXIO;
+
+       dm_get(md);
+       down_read(&_hash_lock);
+       hc = dm_get_mdptr(md);
+       if (!hc || hc->md != md) {
+               r = -ENXIO;
+               goto out;
+       }
+
+       strcpy(name, hc->name);
+       strcpy(uuid, hc->uuid ? : "");
+
+out:
+       up_read(&_hash_lock);
+       dm_put(md);
+
+       return r;
+}
index a66428d860fef830d3fddc6d8f48140d7a646a4b..072ee4353eab329620995aceee14b468a49584a4 100644 (file)
@@ -696,7 +696,7 @@ static struct dirty_log_type _disk_type = {
        .module = THIS_MODULE,
        .ctr = disk_ctr,
        .dtr = disk_dtr,
-       .suspend = disk_flush,
+       .postsuspend = disk_flush,
        .resume = disk_resume,
        .get_region_size = core_get_region_size,
        .is_clean = core_is_clean,
index 86a301c8daf15d5962afe2ca8ed6eee39e58d24e..3fae87eb59631bcaf77c82b0924e363716643b0c 100644 (file)
@@ -32,7 +32,8 @@ struct dirty_log_type {
         * There are times when we don't want the log to touch
         * the disk.
         */
-       int (*suspend)(struct dirty_log *log);
+       int (*presuspend)(struct dirty_log *log);
+       int (*postsuspend)(struct dirty_log *log);
        int (*resume)(struct dirty_log *log);
 
        /*
diff --git a/drivers/md/dm-mpath-hp-sw.c b/drivers/md/dm-mpath-hp-sw.c
new file mode 100644 (file)
index 0000000..204bf42
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2005 Mike Christie, All rights reserved.
+ * Copyright (C) 2007 Red Hat, Inc. All rights reserved.
+ * Authors: Mike Christie
+ *          Dave Wysochanski
+ *
+ * This file is released under the GPL.
+ *
+ * This module implements the specific path activation code for
+ * HP StorageWorks and FSC FibreCat Asymmetric (Active/Passive)
+ * storage arrays.
+ * These storage arrays have controller-based failover, not
+ * LUN-based failover.  However, LUN-based failover is the design
+ * of dm-multipath. Thus, this module is written for LUN-based failover.
+ */
+#include <linux/blkdev.h>
+#include <linux/list.h>
+#include <linux/types.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_dbg.h>
+
+#include "dm.h"
+#include "dm-hw-handler.h"
+
+#define DM_MSG_PREFIX "multipath hp-sw"
+#define DM_HP_HWH_NAME "hp-sw"
+#define DM_HP_HWH_VER "1.0.0"
+
+struct hp_sw_context {
+       unsigned char sense[SCSI_SENSE_BUFFERSIZE];
+};
+
+/*
+ * hp_sw_error_is_retryable - Is an HP-specific check condition retryable?
+ * @req: path activation request
+ *
+ * Examine error codes of request and determine whether the error is retryable.
+ * Some error codes are already retried by scsi-ml (see
+ * scsi_decide_disposition), but some HP specific codes are not.
+ * The intent of this routine is to supply the logic for the HP specific
+ * check conditions.
+ *
+ * Returns:
+ *  1 - command completed with retryable error
+ *  0 - command completed with non-retryable error
+ *
+ * Possible optimizations
+ * 1. More hardware-specific error codes
+ */
+static int hp_sw_error_is_retryable(struct request *req)
+{
+       /*
+        * NOT_READY is known to be retryable
+        * For now we just dump out the sense data and call it retryable
+        */
+       if (status_byte(req->errors) == CHECK_CONDITION)
+               __scsi_print_sense(DM_HP_HWH_NAME, req->sense, req->sense_len);
+
+       /*
+        * At this point we don't have complete information about all the error
+        * codes from this hardware, so we are just conservative and retry
+        * when in doubt.
+        */
+       return 1;
+}
+
+/*
+ * hp_sw_end_io - Completion handler for HP path activation.
+ * @req: path activation request
+ * @error: scsi-ml error
+ *
+ *  Check sense data, free request structure, and notify dm that
+ *  pg initialization has completed.
+ *
+ * Context: scsi-ml softirq
+ *
+ */
+static void hp_sw_end_io(struct request *req, int error)
+{
+       struct dm_path *path = req->end_io_data;
+       unsigned err_flags = 0;
+
+       if (!error) {
+               DMDEBUG("%s path activation command - success",
+                       path->dev->name);
+               goto out;
+       }
+
+       if (hp_sw_error_is_retryable(req)) {
+               DMDEBUG("%s path activation command - retry",
+                       path->dev->name);
+               err_flags = MP_RETRY;
+               goto out;
+       }
+
+       DMWARN("%s path activation fail - error=0x%x",
+              path->dev->name, error);
+       err_flags = MP_FAIL_PATH;
+
+out:
+       req->end_io_data = NULL;
+       __blk_put_request(req->q, req);
+       dm_pg_init_complete(path, err_flags);
+}
+
+/*
+ * hp_sw_get_request - Allocate an HP specific path activation request
+ * @path: path on which request will be sent (needed for request queue)
+ *
+ * The START command is used for path activation request.
+ * These arrays are controller-based failover, not LUN based.
+ * One START command issued to a single path will fail over all
+ * LUNs for the same controller.
+ *
+ * Possible optimizations
+ * 1. Make timeout configurable
+ * 2. Preallocate request
+ */
+static struct request *hp_sw_get_request(struct dm_path *path)
+{
+       struct request *req;
+       struct block_device *bdev = path->dev->bdev;
+       struct request_queue *q = bdev_get_queue(bdev);
+       struct hp_sw_context *h = path->hwhcontext;
+
+       req = blk_get_request(q, WRITE, GFP_NOIO);
+       if (!req)
+               goto out;
+
+       req->timeout = 60 * HZ;
+
+       req->errors = 0;
+       req->cmd_type = REQ_TYPE_BLOCK_PC;
+       req->cmd_flags |= REQ_FAILFAST | REQ_NOMERGE;
+       req->end_io_data = path;
+       req->sense = h->sense;
+       memset(req->sense, 0, SCSI_SENSE_BUFFERSIZE);
+
+       memset(&req->cmd, 0, BLK_MAX_CDB);
+       req->cmd[0] = START_STOP;
+       req->cmd[4] = 1;
+       req->cmd_len = COMMAND_SIZE(req->cmd[0]);
+
+out:
+       return req;
+}
+
+/*
+ * hp_sw_pg_init - HP path activation implementation.
+ * @hwh: hardware handler specific data
+ * @bypassed: unused; is the path group bypassed? (see dm-mpath.c)
+ * @path: path to send initialization command
+ *
+ * Send an HP-specific path activation command on 'path'.
+ * Do not try to optimize in any way, just send the activation command.
+ * More than one path activation command may be sent to the same controller.
+ * This seems to work fine for basic failover support.
+ *
+ * Possible optimizations
+ * 1. Detect an in-progress activation request and avoid submitting another one
+ * 2. Model the controller and only send a single activation request at a time
+ * 3. Determine the state of a path before sending an activation request
+ *
+ * Context: kmpathd (see process_queued_ios() in dm-mpath.c)
+ */
+static void hp_sw_pg_init(struct hw_handler *hwh, unsigned bypassed,
+                         struct dm_path *path)
+{
+       struct request *req;
+       struct hp_sw_context *h;
+
+       path->hwhcontext = hwh->context;
+       h = hwh->context;
+
+       req = hp_sw_get_request(path);
+       if (!req) {
+               DMERR("%s path activation command - allocation fail",
+                     path->dev->name);
+               goto retry;
+       }
+
+       DMDEBUG("%s path activation command - sent", path->dev->name);
+
+       blk_execute_rq_nowait(req->q, NULL, req, 1, hp_sw_end_io);
+       return;
+
+retry:
+       dm_pg_init_complete(path, MP_RETRY);
+}
+
+static int hp_sw_create(struct hw_handler *hwh, unsigned argc, char **argv)
+{
+       struct hp_sw_context *h;
+
+       h = kmalloc(sizeof(*h), GFP_KERNEL);
+       if (!h)
+               return -ENOMEM;
+
+       hwh->context = h;
+
+       return 0;
+}
+
+static void hp_sw_destroy(struct hw_handler *hwh)
+{
+       struct hp_sw_context *h = hwh->context;
+
+       kfree(h);
+}
+
+static struct hw_handler_type hp_sw_hwh = {
+       .name = DM_HP_HWH_NAME,
+       .module = THIS_MODULE,
+       .create = hp_sw_create,
+       .destroy = hp_sw_destroy,
+       .pg_init = hp_sw_pg_init,
+};
+
+static int __init hp_sw_init(void)
+{
+       int r;
+
+       r = dm_register_hw_handler(&hp_sw_hwh);
+       if (r < 0)
+               DMERR("register failed %d", r);
+       else
+               DMINFO("version " DM_HP_HWH_VER " loaded");
+
+       return r;
+}
+
+static void __exit hp_sw_exit(void)
+{
+       int r;
+
+       r = dm_unregister_hw_handler(&hp_sw_hwh);
+       if (r < 0)
+               DMERR("unregister failed %d", r);
+}
+
+module_init(hp_sw_init);
+module_exit(hp_sw_exit);
+
+MODULE_DESCRIPTION("DM Multipath HP StorageWorks / FSC FibreCat (A/P) support");
+MODULE_AUTHOR("Mike Christie, Dave Wysochanski <dm-devel@redhat.com>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DM_HP_HWH_VER);
index 16b1613457750e990c131592ff4501d5f9de0724..e04eb5c697fb884081b79c8ad5ed4b378c19abd6 100644 (file)
@@ -664,20 +664,21 @@ static struct hw_handler_type rdac_handler = {
 
 static int __init rdac_init(void)
 {
-       int r = dm_register_hw_handler(&rdac_handler);
-
-       if (r < 0) {
-               DMERR("%s: register failed %d", RDAC_DM_HWH_NAME, r);
-               return r;
-       }
+       int r;
 
        rdac_wkqd = create_singlethread_workqueue("rdac_wkqd");
        if (!rdac_wkqd) {
                DMERR("Failed to create workqueue rdac_wkqd.");
-               dm_unregister_hw_handler(&rdac_handler);
                return -ENOMEM;
        }
 
+       r = dm_register_hw_handler(&rdac_handler);
+       if (r < 0) {
+               DMERR("%s: register failed %d", RDAC_DM_HWH_NAME, r);
+               destroy_workqueue(rdac_wkqd);
+               return r;
+       }
+
        DMINFO("%s: version %s loaded", RDAC_DM_HWH_NAME, RDAC_DM_HWH_VER);
        return 0;
 }
index 31056abca89d31814a210a9785f11d576878fa67..24b2b1e32faefc443bf102949a3674689e505b05 100644 (file)
@@ -10,6 +10,7 @@
 #include "dm-hw-handler.h"
 #include "dm-bio-list.h"
 #include "dm-bio-record.h"
+#include "dm-uevent.h"
 
 #include <linux/ctype.h>
 #include <linux/init.h>
@@ -75,6 +76,8 @@ struct multipath {
        unsigned queue_io;              /* Must we queue all I/O? */
        unsigned queue_if_no_path;      /* Queue I/O if last path fails? */
        unsigned saved_queue_if_no_path;/* Saved state during suspension */
+       unsigned pg_init_retries;       /* Number of times to retry pg_init */
+       unsigned pg_init_count;         /* Number of times pg_init called */
 
        struct work_struct process_queued_ios;
        struct bio_list queued_ios;
@@ -225,6 +228,8 @@ static void __switch_pg(struct multipath *m, struct pgpath *pgpath)
                m->pg_init_required = 0;
                m->queue_io = 0;
        }
+
+       m->pg_init_count = 0;
 }
 
 static int __choose_path_in_pg(struct multipath *m, struct priority_group *pg)
@@ -424,6 +429,7 @@ static void process_queued_ios(struct work_struct *work)
                must_queue = 0;
 
        if (m->pg_init_required && !m->pg_init_in_progress) {
+               m->pg_init_count++;
                m->pg_init_required = 0;
                m->pg_init_in_progress = 1;
                init_required = 1;
@@ -689,9 +695,11 @@ static int parse_features(struct arg_set *as, struct multipath *m)
        int r;
        unsigned argc;
        struct dm_target *ti = m->ti;
+       const char *param_name;
 
        static struct param _params[] = {
-               {0, 1, "invalid number of feature args"},
+               {0, 3, "invalid number of feature args"},
+               {1, 50, "pg_init_retries must be between 1 and 50"},
        };
 
        r = read_param(_params, shift(as), &argc, &ti->error);
@@ -701,12 +709,28 @@ static int parse_features(struct arg_set *as, struct multipath *m)
        if (!argc)
                return 0;
 
-       if (!strnicmp(shift(as), MESG_STR("queue_if_no_path")))
-               return queue_if_no_path(m, 1, 0);
-       else {
+       do {
+               param_name = shift(as);
+               argc--;
+
+               if (!strnicmp(param_name, MESG_STR("queue_if_no_path"))) {
+                       r = queue_if_no_path(m, 1, 0);
+                       continue;
+               }
+
+               if (!strnicmp(param_name, MESG_STR("pg_init_retries")) &&
+                   (argc >= 1)) {
+                       r = read_param(_params + 1, shift(as),
+                                      &m->pg_init_retries, &ti->error);
+                       argc--;
+                       continue;
+               }
+
                ti->error = "Unrecognised multipath feature request";
-               return -EINVAL;
-       }
+               r = -EINVAL;
+       } while (argc && !r);
+
+       return r;
 }
 
 static int multipath_ctr(struct dm_target *ti, unsigned int argc,
@@ -834,6 +858,9 @@ static int fail_path(struct pgpath *pgpath)
        if (pgpath == m->current_pgpath)
                m->current_pgpath = NULL;
 
+       dm_path_uevent(DM_UEVENT_PATH_FAILED, m->ti,
+                     pgpath->path.dev->name, m->nr_valid_paths);
+
        queue_work(kmultipathd, &m->trigger_event);
 
 out:
@@ -873,6 +900,9 @@ static int reinstate_path(struct pgpath *pgpath)
        if (!m->nr_valid_paths++ && m->queue_size)
                queue_work(kmultipathd, &m->process_queued_ios);
 
+       dm_path_uevent(DM_UEVENT_PATH_REINSTATED, m->ti,
+                     pgpath->path.dev->name, m->nr_valid_paths);
+
        queue_work(kmultipathd, &m->trigger_event);
 
 out:
@@ -975,6 +1005,26 @@ static int bypass_pg_num(struct multipath *m, const char *pgstr, int bypassed)
        return 0;
 }
 
+/*
+ * Should we retry pg_init immediately?
+ */
+static int pg_init_limit_reached(struct multipath *m, struct pgpath *pgpath)
+{
+       unsigned long flags;
+       int limit_reached = 0;
+
+       spin_lock_irqsave(&m->lock, flags);
+
+       if (m->pg_init_count <= m->pg_init_retries)
+               m->pg_init_required = 1;
+       else
+               limit_reached = 1;
+
+       spin_unlock_irqrestore(&m->lock, flags);
+
+       return limit_reached;
+}
+
 /*
  * pg_init must call this when it has completed its initialisation
  */
@@ -985,8 +1035,14 @@ void dm_pg_init_complete(struct dm_path *path, unsigned err_flags)
        struct multipath *m = pg->m;
        unsigned long flags;
 
-       /* We insist on failing the path if the PG is already bypassed. */
-       if (err_flags && pg->bypassed)
+       /*
+        * If requested, retry pg_init until maximum number of retries exceeded.
+        * If retry not requested and PG already bypassed, always fail the path.
+        */
+       if (err_flags & MP_RETRY) {
+               if (pg_init_limit_reached(m, pgpath))
+                       err_flags |= MP_FAIL_PATH;
+       } else if (err_flags && pg->bypassed)
                err_flags |= MP_FAIL_PATH;
 
        if (err_flags & MP_FAIL_PATH)
@@ -996,7 +1052,7 @@ void dm_pg_init_complete(struct dm_path *path, unsigned err_flags)
                bypass_pg(m, pg, 1);
 
        spin_lock_irqsave(&m->lock, flags);
-       if (err_flags) {
+       if (err_flags & ~MP_RETRY) {
                m->current_pgpath = NULL;
                m->current_pg = NULL;
        } else if (!m->pg_init_required)
@@ -1148,11 +1204,15 @@ static int multipath_status(struct dm_target *ti, status_type_t type,
 
        /* Features */
        if (type == STATUSTYPE_INFO)
-               DMEMIT("1 %u ", m->queue_size);
-       else if (m->queue_if_no_path)
-               DMEMIT("1 queue_if_no_path ");
-       else
-               DMEMIT("0 ");
+               DMEMIT("2 %u %u ", m->queue_size, m->pg_init_count);
+       else {
+               DMEMIT("%u ", m->queue_if_no_path +
+                             (m->pg_init_retries > 0) * 2);
+               if (m->queue_if_no_path)
+                       DMEMIT("queue_if_no_path ");
+               if (m->pg_init_retries)
+                       DMEMIT("pg_init_retries %u ", m->pg_init_retries);
+       }
 
        if (hwh->type && hwh->type->status)
                sz += hwh->type->status(hwh, type, result + sz, maxlen - sz);
index f10a0c89b3f4e542b3901790504a212d612741ef..ca1bb636a3e4ba808ae63d88dfbb62bc4ee28a04 100644 (file)
@@ -94,12 +94,10 @@ out:
 
 static struct ps_internal *_alloc_path_selector(struct path_selector_type *pst)
 {
-       struct ps_internal *psi = kmalloc(sizeof(*psi), GFP_KERNEL);
+       struct ps_internal *psi = kzalloc(sizeof(*psi), GFP_KERNEL);
 
-       if (psi) {
-               memset(psi, 0, sizeof(*psi));
+       if (psi)
                psi->pst = *pst;
-       }
 
        return psi;
 }
index d09ff15490a5db439aff81566b02cf3f401b364a..31123d4a6b9cc39dbeec455d50b540b97ac99c06 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/time.h>
 #include <linux/vmalloc.h>
 #include <linux/workqueue.h>
+#include <linux/log2.h>
 
 #define DM_MSG_PREFIX "raid1"
 #define DM_IO_PAGES 64
@@ -113,6 +114,7 @@ struct region {
  * Mirror set structures.
  *---------------------------------------------------------------*/
 struct mirror {
+       struct mirror_set *ms;
        atomic_t error_count;
        struct dm_dev *dev;
        sector_t offset;
@@ -974,6 +976,7 @@ static struct mirror_set *alloc_context(unsigned int nr_mirrors,
 
        if (rh_init(&ms->rh, ms, dl, region_size, ms->nr_regions)) {
                ti->error = "Error creating dirty region hash";
+               dm_io_client_destroy(ms->io_client);
                kfree(ms);
                return NULL;
        }
@@ -994,7 +997,7 @@ static void free_context(struct mirror_set *ms, struct dm_target *ti,
 
 static inline int _check_region_size(struct dm_target *ti, uint32_t size)
 {
-       return !(size % (PAGE_SIZE >> 9) || (size & (size - 1)) ||
+       return !(size % (PAGE_SIZE >> 9) || !is_power_of_2(size) ||
                 size > ti->len);
 }
 
@@ -1015,6 +1018,7 @@ static int get_mirror(struct mirror_set *ms, struct dm_target *ti,
                return -ENXIO;
        }
 
+       ms->mirror[mirror].ms = ms;
        ms->mirror[mirror].offset = offset;
 
        return 0;
@@ -1163,16 +1167,14 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv)
        ms->kmirrord_wq = create_singlethread_workqueue("kmirrord");
        if (!ms->kmirrord_wq) {
                DMERR("couldn't start kmirrord");
-               free_context(ms, ti, m);
-               return -ENOMEM;
+               r = -ENOMEM;
+               goto err_free_context;
        }
        INIT_WORK(&ms->kmirrord_work, do_mirror);
 
        r = parse_features(ms, argc, argv, &args_used);
-       if (r) {
-               free_context(ms, ti, ms->nr_mirrors);
-               return r;
-       }
+       if (r)
+               goto err_destroy_wq;
 
        argv += args_used;
        argc -= args_used;
@@ -1188,19 +1190,22 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 
        if (argc) {
                ti->error = "Too many mirror arguments";
-               free_context(ms, ti, ms->nr_mirrors);
-               return -EINVAL;
+               r = -EINVAL;
+               goto err_destroy_wq;
        }
 
        r = kcopyd_client_create(DM_IO_PAGES, &ms->kcopyd_client);
-       if (r) {
-               destroy_workqueue(ms->kmirrord_wq);
-               free_context(ms, ti, ms->nr_mirrors);
-               return r;
-       }
+       if (r)
+               goto err_destroy_wq;
 
        wake(ms);
        return 0;
+
+err_destroy_wq:
+       destroy_workqueue(ms->kmirrord_wq);
+err_free_context:
+       free_context(ms, ti, ms->nr_mirrors);
+       return r;
 }
 
 static void mirror_dtr(struct dm_target *ti)
@@ -1302,7 +1307,7 @@ static void mirror_postsuspend(struct dm_target *ti)
        wait_event(_kmirrord_recovery_stopped,
                   !atomic_read(&ms->rh.recovery_in_flight));
 
-       if (log->type->suspend && log->type->suspend(log))
+       if (log->type->postsuspend && log->type->postsuspend(log))
                /* FIXME: need better error handling */
                DMWARN("log suspend failed");
 }
index 98a633f3d6b002673e17e797b34c30903a2bfa39..cee16fadd9ee70379449ce995ac4043d1ff86e5f 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
+#include <linux/log2.h>
 
 #include "dm-snap.h"
 #include "dm-bio-list.h"
@@ -415,7 +416,7 @@ static int set_chunk_size(struct dm_snapshot *s, const char *chunk_size_arg,
        chunk_size = round_up(chunk_size, PAGE_SIZE >> 9);
 
        /* Check chunk_size is a power of 2 */
-       if (chunk_size & (chunk_size - 1)) {
+       if (!is_power_of_2(chunk_size)) {
                *error = "Chunk size is not a power of 2";
                return -EINVAL;
        }
index 51f5e0760012dd76c35d939bb18862a20e2ee435..969944a8aba2dd0b06dab4191e8b3136ba08bf58 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/blkdev.h>
 #include <linux/bio.h>
 #include <linux/slab.h>
+#include <linux/log2.h>
 
 #define DM_MSG_PREFIX "striped"
 
@@ -99,7 +100,7 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv)
        /*
         * chunk_size is a power of two
         */
-       if (!chunk_size || (chunk_size & (chunk_size - 1)) ||
+       if (!is_power_of_2(chunk_size) ||
            (chunk_size < (PAGE_SIZE >> SECTOR_SHIFT))) {
                ti->error = "Invalid chunk size";
                return -EINVAL;
index fbe477bb2c68ca4005a7f606af18a715edbfc5f9..8939e61050884cd81cda3cdcbf7126b5b55e3dad 100644 (file)
@@ -213,12 +213,11 @@ static int alloc_targets(struct dm_table *t, unsigned int num)
 int dm_table_create(struct dm_table **result, int mode,
                    unsigned num_targets, struct mapped_device *md)
 {
-       struct dm_table *t = kmalloc(sizeof(*t), GFP_KERNEL);
+       struct dm_table *t = kzalloc(sizeof(*t), GFP_KERNEL);
 
        if (!t)
                return -ENOMEM;
 
-       memset(t, 0, sizeof(*t));
        INIT_LIST_HEAD(&t->devices);
        atomic_set(&t->holders, 1);
 
index 477a041a41cfa4601cb796ddf14df3dfcdbde562..835cf95b857fa6cbef32c0c6d0d474e03909221a 100644 (file)
@@ -88,12 +88,10 @@ void dm_put_target_type(struct target_type *t)
 
 static struct tt_internal *alloc_target(struct target_type *t)
 {
-       struct tt_internal *ti = kmalloc(sizeof(*ti), GFP_KERNEL);
+       struct tt_internal *ti = kzalloc(sizeof(*ti), GFP_KERNEL);
 
-       if (ti) {
-               memset(ti, 0, sizeof(*ti));
+       if (ti)
                ti->tt = *t;
-       }
 
        return ti;
 }
diff --git a/drivers/md/dm-uevent.c b/drivers/md/dm-uevent.c
new file mode 100644 (file)
index 0000000..50377e5
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * Device Mapper Uevent Support (dm-uevent)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright IBM Corporation, 2007
+ *     Author: Mike Anderson <andmike@linux.vnet.ibm.com>
+ */
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/kobject.h>
+#include <linux/dm-ioctl.h>
+
+#include "dm.h"
+#include "dm-uevent.h"
+
+#define DM_MSG_PREFIX "uevent"
+
+static const struct {
+       enum dm_uevent_type type;
+       enum kobject_action action;
+       char *name;
+} _dm_uevent_type_names[] = {
+       {DM_UEVENT_PATH_FAILED, KOBJ_CHANGE, "PATH_FAILED"},
+       {DM_UEVENT_PATH_REINSTATED, KOBJ_CHANGE, "PATH_REINSTATED"},
+};
+
+static struct kmem_cache *_dm_event_cache;
+
+struct dm_uevent {
+       struct mapped_device *md;
+       enum kobject_action action;
+       struct kobj_uevent_env ku_env;
+       struct list_head elist;
+       char name[DM_NAME_LEN];
+       char uuid[DM_UUID_LEN];
+};
+
+static void dm_uevent_free(struct dm_uevent *event)
+{
+       kmem_cache_free(_dm_event_cache, event);
+}
+
+static struct dm_uevent *dm_uevent_alloc(struct mapped_device *md)
+{
+       struct dm_uevent *event;
+
+       event = kmem_cache_zalloc(_dm_event_cache, GFP_ATOMIC);
+       if (!event)
+               return NULL;
+
+       INIT_LIST_HEAD(&event->elist);
+       event->md = md;
+
+       return event;
+}
+
+static struct dm_uevent *dm_build_path_uevent(struct mapped_device *md,
+                                             struct dm_target *ti,
+                                             enum kobject_action action,
+                                             const char *dm_action,
+                                             const char *path,
+                                             unsigned nr_valid_paths)
+{
+       struct dm_uevent *event;
+
+       event = dm_uevent_alloc(md);
+       if (!event) {
+               DMERR("%s: dm_uevent_alloc() failed", __FUNCTION__);
+               goto err_nomem;
+       }
+
+       event->action = action;
+
+       if (add_uevent_var(&event->ku_env, "DM_TARGET=%s", ti->type->name)) {
+               DMERR("%s: add_uevent_var() for DM_TARGET failed",
+                     __FUNCTION__);
+               goto err_add;
+       }
+
+       if (add_uevent_var(&event->ku_env, "DM_ACTION=%s", dm_action)) {
+               DMERR("%s: add_uevent_var() for DM_ACTION failed",
+                     __FUNCTION__);
+               goto err_add;
+       }
+
+       if (add_uevent_var(&event->ku_env, "DM_SEQNUM=%u",
+                          dm_next_uevent_seq(md))) {
+               DMERR("%s: add_uevent_var() for DM_SEQNUM failed",
+                     __FUNCTION__);
+               goto err_add;
+       }
+
+       if (add_uevent_var(&event->ku_env, "DM_PATH=%s", path)) {
+               DMERR("%s: add_uevent_var() for DM_PATH failed", __FUNCTION__);
+               goto err_add;
+       }
+
+       if (add_uevent_var(&event->ku_env, "DM_NR_VALID_PATHS=%d",
+                          nr_valid_paths)) {
+               DMERR("%s: add_uevent_var() for DM_NR_VALID_PATHS failed",
+                     __FUNCTION__);
+               goto err_add;
+       }
+
+       return event;
+
+err_add:
+       dm_uevent_free(event);
+err_nomem:
+       return ERR_PTR(-ENOMEM);
+}
+
+/**
+ * dm_send_uevents - send uevents for given list
+ *
+ * @events:    list of events to send
+ * @kobj:      kobject generating event
+ *
+ */
+void dm_send_uevents(struct list_head *events, struct kobject *kobj)
+{
+       int r;
+       struct dm_uevent *event, *next;
+
+       list_for_each_entry_safe(event, next, events, elist) {
+               list_del_init(&event->elist);
+
+               /*
+                * Need to call dm_copy_name_and_uuid from here for now.
+                * Context of previous var adds and locking used for
+                * hash_cell not compatable.
+                */
+               if (dm_copy_name_and_uuid(event->md, event->name,
+                                         event->uuid)) {
+                       DMERR("%s: dm_copy_name_and_uuid() failed",
+                             __FUNCTION__);
+                       goto uevent_free;
+               }
+
+               if (add_uevent_var(&event->ku_env, "DM_NAME=%s", event->name)) {
+                       DMERR("%s: add_uevent_var() for DM_NAME failed",
+                             __FUNCTION__);
+                       goto uevent_free;
+               }
+
+               if (add_uevent_var(&event->ku_env, "DM_UUID=%s", event->uuid)) {
+                       DMERR("%s: add_uevent_var() for DM_UUID failed",
+                             __FUNCTION__);
+                       goto uevent_free;
+               }
+
+               r = kobject_uevent_env(kobj, event->action, event->ku_env.envp);
+               if (r)
+                       DMERR("%s: kobject_uevent_env failed", __FUNCTION__);
+uevent_free:
+               dm_uevent_free(event);
+       }
+}
+EXPORT_SYMBOL_GPL(dm_send_uevents);
+
+/**
+ * dm_path_uevent - called to create a new path event and queue it
+ *
+ * @event_type:        path event type enum
+ * @ti:                        pointer to a dm_target
+ * @path:              string containing pathname
+ * @nr_valid_paths:    number of valid paths remaining
+ *
+ */
+void dm_path_uevent(enum dm_uevent_type event_type, struct dm_target *ti,
+                  const char *path, unsigned nr_valid_paths)
+{
+       struct mapped_device *md = dm_table_get_md(ti->table);
+       struct dm_uevent *event;
+
+       if (event_type >= ARRAY_SIZE(_dm_uevent_type_names)) {
+               DMERR("%s: Invalid event_type %d", __FUNCTION__, event_type);
+               goto out;
+       }
+
+       event = dm_build_path_uevent(md, ti,
+                                    _dm_uevent_type_names[event_type].action,
+                                    _dm_uevent_type_names[event_type].name,
+                                    path, nr_valid_paths);
+       if (IS_ERR(event))
+               goto out;
+
+       dm_uevent_add(md, &event->elist);
+
+out:
+       dm_put(md);
+}
+EXPORT_SYMBOL_GPL(dm_path_uevent);
+
+int dm_uevent_init(void)
+{
+       _dm_event_cache = KMEM_CACHE(dm_uevent, 0);
+       if (!_dm_event_cache)
+               return -ENOMEM;
+
+       DMINFO("version 1.0.3");
+
+       return 0;
+}
+
+void dm_uevent_exit(void)
+{
+       kmem_cache_destroy(_dm_event_cache);
+}
diff --git a/drivers/md/dm-uevent.h b/drivers/md/dm-uevent.h
new file mode 100644 (file)
index 0000000..2eccc8b
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Device Mapper Uevent Support
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright IBM Corporation, 2007
+ *     Author: Mike Anderson <andmike@linux.vnet.ibm.com>
+ */
+#ifndef DM_UEVENT_H
+#define DM_UEVENT_H
+
+enum dm_uevent_type {
+       DM_UEVENT_PATH_FAILED,
+       DM_UEVENT_PATH_REINSTATED,
+};
+
+#ifdef CONFIG_DM_UEVENT
+
+extern int dm_uevent_init(void);
+extern void dm_uevent_exit(void);
+extern void dm_send_uevents(struct list_head *events, struct kobject *kobj);
+extern void dm_path_uevent(enum dm_uevent_type event_type,
+                          struct dm_target *ti, const char *path,
+                          unsigned nr_valid_paths);
+
+#else
+
+static inline int dm_uevent_init(void)
+{
+       return 0;
+}
+static inline void dm_uevent_exit(void)
+{
+}
+static inline void dm_send_uevents(struct list_head *events,
+                                  struct kobject *kobj)
+{
+}
+static inline void dm_path_uevent(enum dm_uevent_type event_type,
+                                 struct dm_target *ti, const char *path,
+                                 unsigned nr_valid_paths)
+{
+}
+
+#endif /* CONFIG_DM_UEVENT */
+
+#endif /* DM_UEVENT_H */
index d837d37f62093d1669a5bf87d160eab34eb45aa3..07cbbb8eb3e0d5d67f5c7bed7ea399f6636e5954 100644 (file)
@@ -7,6 +7,7 @@
 
 #include "dm.h"
 #include "dm-bio-list.h"
+#include "dm-uevent.h"
 
 #include <linux/init.h>
 #include <linux/module.h>
@@ -112,6 +113,9 @@ struct mapped_device {
         */
        atomic_t event_nr;
        wait_queue_head_t eventq;
+       atomic_t uevent_seq;
+       struct list_head uevent_list;
+       spinlock_t uevent_lock; /* Protect access to uevent_list */
 
        /*
         * freeze/thaw support require holding onto a super block
@@ -143,11 +147,19 @@ static int __init local_init(void)
                return -ENOMEM;
        }
 
+       r = dm_uevent_init();
+       if (r) {
+               kmem_cache_destroy(_tio_cache);
+               kmem_cache_destroy(_io_cache);
+               return r;
+       }
+
        _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;
        }
 
@@ -162,6 +174,7 @@ static void local_exit(void)
        kmem_cache_destroy(_tio_cache);
        kmem_cache_destroy(_io_cache);
        unregister_blkdev(_major, _name);
+       dm_uevent_exit();
 
        _major = 0;
 
@@ -751,15 +764,13 @@ static void __clone_and_map(struct clone_info *ci)
 /*
  * Split the bio into several clones.
  */
-static void __split_bio(struct mapped_device *md, struct bio *bio)
+static int __split_bio(struct mapped_device *md, struct bio *bio)
 {
        struct clone_info ci;
 
        ci.map = dm_get_table(md);
-       if (!ci.map) {
-               bio_io_error(bio);
-               return;
-       }
+       if (unlikely(!ci.map))
+               return -EIO;
 
        ci.md = md;
        ci.bio = bio;
@@ -779,6 +790,8 @@ static void __split_bio(struct mapped_device *md, struct bio *bio)
        /* drop the extra reference count */
        dec_pending(ci.io, 0);
        dm_table_put(ci.map);
+
+       return 0;
 }
 /*-----------------------------------------------------------------
  * CRUD END
@@ -790,7 +803,7 @@ static void __split_bio(struct mapped_device *md, struct bio *bio)
  */
 static int dm_request(struct request_queue *q, struct bio *bio)
 {
-       int r;
+       int r = -EIO;
        int rw = bio_data_dir(bio);
        struct mapped_device *md = q->queuedata;
 
@@ -815,18 +828,11 @@ static int dm_request(struct request_queue *q, struct bio *bio)
        while (test_bit(DMF_BLOCK_IO, &md->flags)) {
                up_read(&md->io_lock);
 
-               if (bio_rw(bio) == READA) {
-                       bio_io_error(bio);
-                       return 0;
-               }
-
-               r = queue_io(md, bio);
-               if (r < 0) {
-                       bio_io_error(bio);
-                       return 0;
+               if (bio_rw(bio) != READA)
+                       r = queue_io(md, bio);
 
-               } else if (r == 0)
-                       return 0;       /* deferred successfully */
+               if (r <= 0)
+                       goto out_req;
 
                /*
                 * We're in a while loop, because someone could suspend
@@ -835,8 +841,13 @@ static int dm_request(struct request_queue *q, struct bio *bio)
                down_read(&md->io_lock);
        }
 
-       __split_bio(md, bio);
+       r = __split_bio(md, bio);
        up_read(&md->io_lock);
+
+out_req:
+       if (r < 0)
+               bio_io_error(bio);
+
        return 0;
 }
 
@@ -977,6 +988,9 @@ static struct mapped_device *alloc_dev(int minor)
        atomic_set(&md->holders, 1);
        atomic_set(&md->open_count, 0);
        atomic_set(&md->event_nr, 0);
+       atomic_set(&md->uevent_seq, 0);
+       INIT_LIST_HEAD(&md->uevent_list);
+       spin_lock_init(&md->uevent_lock);
 
        md->queue = blk_alloc_queue(GFP_KERNEL);
        if (!md->queue)
@@ -1044,12 +1058,14 @@ static struct mapped_device *alloc_dev(int minor)
        return NULL;
 }
 
+static void unlock_fs(struct mapped_device *md);
+
 static void free_dev(struct mapped_device *md)
 {
        int minor = md->disk->first_minor;
 
        if (md->suspended_bdev) {
-               thaw_bdev(md->suspended_bdev, NULL);
+               unlock_fs(md);
                bdput(md->suspended_bdev);
        }
        mempool_destroy(md->tio_pool);
@@ -1073,8 +1089,16 @@ static void free_dev(struct mapped_device *md)
  */
 static void event_callback(void *context)
 {
+       unsigned long flags;
+       LIST_HEAD(uevents);
        struct mapped_device *md = (struct mapped_device *) context;
 
+       spin_lock_irqsave(&md->uevent_lock, flags);
+       list_splice_init(&md->uevent_list, &uevents);
+       spin_unlock_irqrestore(&md->uevent_lock, flags);
+
+       dm_send_uevents(&uevents, &md->disk->kobj);
+
        atomic_inc(&md->event_nr);
        wake_up(&md->eventq);
 }
@@ -1233,7 +1257,8 @@ static void __flush_deferred_io(struct mapped_device *md, struct bio *c)
        while (c) {
                n = c->bi_next;
                c->bi_next = NULL;
-               __split_bio(md, c);
+               if (__split_bio(md, c))
+                       bio_io_error(c);
                c = n;
        }
 }
@@ -1491,6 +1516,11 @@ out:
 /*-----------------------------------------------------------------
  * Event notification.
  *---------------------------------------------------------------*/
+uint32_t dm_next_uevent_seq(struct mapped_device *md)
+{
+       return atomic_add_return(1, &md->uevent_seq);
+}
+
 uint32_t dm_get_event_nr(struct mapped_device *md)
 {
        return atomic_read(&md->event_nr);
@@ -1502,6 +1532,15 @@ int dm_wait_event(struct mapped_device *md, int event_nr)
                        (event_nr != atomic_read(&md->event_nr)));
 }
 
+void dm_uevent_add(struct mapped_device *md, struct list_head *elist)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&md->uevent_lock, flags);
+       list_add(elist, &md->uevent_list);
+       spin_unlock_irqrestore(&md->uevent_lock, flags);
+}
+
 /*
  * The gendisk is only valid as long as you have a reference
  * count on 'md'.
index 7e052378c47ea6af6c42eec7f134934b6d49d1c0..f3831f31223e51ba873d67cc2aca45c786b8001b 100644 (file)
@@ -198,7 +198,7 @@ struct kcopyd_job {
         * These fields are only used if the job has been split
         * into more manageable parts.
         */
-       struct semaphore lock;
+       struct mutex lock;
        atomic_t sub_jobs;
        sector_t progress;
 };
@@ -456,7 +456,7 @@ static void segment_complete(int read_err,
        sector_t count = 0;
        struct kcopyd_job *job = (struct kcopyd_job *) context;
 
-       down(&job->lock);
+       mutex_lock(&job->lock);
 
        /* update the error */
        if (read_err)
@@ -480,7 +480,7 @@ static void segment_complete(int read_err,
                        job->progress += count;
                }
        }
-       up(&job->lock);
+       mutex_unlock(&job->lock);
 
        if (count) {
                int i;
@@ -562,7 +562,7 @@ int kcopyd_copy(struct kcopyd_client *kc, struct io_region *from,
                dispatch_job(job);
 
        else {
-               init_MUTEX(&job->lock);
+               mutex_init(&job->lock);
                job->progress = 0;
                split_job(job);
        }
index c059ae6f37e5ae1fe789e3fad66ad0a91da3a264..808cd95494563d260456733e0d1e9ba80cbee21e 100644 (file)
@@ -4717,7 +4717,7 @@ mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev,
 
 void md_unregister_thread(mdk_thread_t *thread)
 {
-       dprintk("interrupting MD-thread pid %d\n", thread->tsk->pid);
+       dprintk("interrupting MD-thread pid %d\n", task_pid_nr(thread->tsk));
 
        kthread_stop(thread->tsk);
        kfree(thread);
index 16775a0df7f6dbedb1648fc45793521557be3b5b..85478d6a9c1af645dfdfdb824aa1b6c7286e9daf 100644 (file)
@@ -9,7 +9,7 @@
  *
  * Better read-balancing code written by Mika Kuoppala <miku@iki.fi>, 2000
  *
- * Fixes to reconstruction by Jakob Østergaard" <jakob@ostenfeld.dk>
+ * Fixes to reconstruction by Jakob Østergaard" <jakob@ostenfeld.dk>
  * Various fixes by Neil Brown <neilb@cse.unsw.edu.au>
  *
  * Changes by Peter T. Breuer <ptb@it.uc3m.es> 31/1/2003 to support
index 8ee181a01f5206730bd0ad23744247bf51fb289a..80a67d789b7252c4311fc1adc54a1af06a519787 100644 (file)
@@ -376,7 +376,12 @@ static unsigned long get_stripe_work(struct stripe_head *sh)
                ack++;
 
        sh->ops.count -= ack;
-       BUG_ON(sh->ops.count < 0);
+       if (unlikely(sh->ops.count < 0)) {
+               printk(KERN_ERR "pending: %#lx ops.pending: %#lx ops.ack: %#lx "
+                       "ops.complete: %#lx\n", pending, sh->ops.pending,
+                       sh->ops.ack, sh->ops.complete);
+               BUG();
+       }
 
        return pending;
 }
@@ -550,8 +555,7 @@ static void ops_complete_biofill(void *stripe_head_ref)
                        }
                }
        }
-       clear_bit(STRIPE_OP_BIOFILL, &sh->ops.ack);
-       clear_bit(STRIPE_OP_BIOFILL, &sh->ops.pending);
+       set_bit(STRIPE_OP_BIOFILL, &sh->ops.complete);
 
        return_io(return_bi);
 
@@ -2893,6 +2897,13 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
        s.expanded = test_bit(STRIPE_EXPAND_READY, &sh->state);
        /* Now to look around and see what can be done */
 
+       /* clean-up completed biofill operations */
+       if (test_bit(STRIPE_OP_BIOFILL, &sh->ops.complete)) {
+               clear_bit(STRIPE_OP_BIOFILL, &sh->ops.pending);
+               clear_bit(STRIPE_OP_BIOFILL, &sh->ops.ack);
+               clear_bit(STRIPE_OP_BIOFILL, &sh->ops.complete);
+       }
+
        rcu_read_lock();
        for (i=disks; i--; ) {
                mdk_rdev_t *rdev;
index aefcf28da1cae1ee0a8dbeddb29e3c026d702d65..185e8a860c1a256c9ca211b12511142efee1e53c 100644 (file)
@@ -1074,41 +1074,41 @@ EXPORT_SYMBOL_GPL(ir_codes_manli);
 /* Mike Baikov <mike@baikov.com> */
 IR_KEYTAB_TYPE ir_codes_gotview7135[IR_KEYTAB_SIZE] = {
 
-       [ 0x21 ] = KEY_POWER,
-       [ 0x69 ] = KEY_TV,
-       [ 0x33 ] = KEY_0,
-       [ 0x51 ] = KEY_1,
-       [ 0x31 ] = KEY_2,
-       [ 0x71 ] = KEY_3,
-       [ 0x3b ] = KEY_4,
-       [ 0x58 ] = KEY_5,
-       [ 0x41 ] = KEY_6,
-       [ 0x48 ] = KEY_7,
-       [ 0x30 ] = KEY_8,
-       [ 0x53 ] = KEY_9,
-       [ 0x73 ] = KEY_AGAIN, /* LOOP */
-       [ 0x0a ] = KEY_AUDIO,
-       [ 0x61 ] = KEY_PRINT, /* PREVIEW */
-       [ 0x7a ] = KEY_VIDEO,
-       [ 0x20 ] = KEY_CHANNELUP,
-       [ 0x40 ] = KEY_CHANNELDOWN,
-       [ 0x18 ] = KEY_VOLUMEDOWN,
-       [ 0x50 ] = KEY_VOLUMEUP,
-       [ 0x10 ] = KEY_MUTE,
-       [ 0x4a ] = KEY_SEARCH,
-       [ 0x7b ] = KEY_SHUFFLE, /* SNAPSHOT */
-       [ 0x22 ] = KEY_RECORD,
-       [ 0x62 ] = KEY_STOP,
-       [ 0x78 ] = KEY_PLAY,
-       [ 0x39 ] = KEY_REWIND,
-       [ 0x59 ] = KEY_PAUSE,
-       [ 0x19 ] = KEY_FORWARD,
-       [ 0x09 ] = KEY_ZOOM,
-
-       [ 0x52 ] = KEY_F21, /* LIVE TIMESHIFT */
-       [ 0x1a ] = KEY_F22, /* MIN TIMESHIFT */
-       [ 0x3a ] = KEY_F23, /* TIMESHIFT */
-       [ 0x70 ] = KEY_F24, /* NORMAL TIMESHIFT */
+       [ 0x11 ] = KEY_POWER,
+       [ 0x35 ] = KEY_TV,
+       [ 0x1b ] = KEY_0,
+       [ 0x29 ] = KEY_1,
+       [ 0x19 ] = KEY_2,
+       [ 0x39 ] = KEY_3,
+       [ 0x1f ] = KEY_4,
+       [ 0x2c ] = KEY_5,
+       [ 0x21 ] = KEY_6,
+       [ 0x24 ] = KEY_7,
+       [ 0x18 ] = KEY_8,
+       [ 0x2b ] = KEY_9,
+       [ 0x3b ] = KEY_AGAIN, /* LOOP */
+       [ 0x06 ] = KEY_AUDIO,
+       [ 0x31 ] = KEY_PRINT, /* PREVIEW */
+       [ 0x3e ] = KEY_VIDEO,
+       [ 0x10 ] = KEY_CHANNELUP,
+       [ 0x20 ] = KEY_CHANNELDOWN,
+       [ 0x0c ] = KEY_VOLUMEDOWN,
+       [ 0x28 ] = KEY_VOLUMEUP,
+       [ 0x08 ] = KEY_MUTE,
+       [ 0x26 ] = KEY_SEARCH, /*SCAN*/
+       [ 0x3f ] = KEY_SHUFFLE, /* SNAPSHOT */
+       [ 0x12 ] = KEY_RECORD,
+       [ 0x32 ] = KEY_STOP,
+       [ 0x3c ] = KEY_PLAY,
+       [ 0x1d ] = KEY_REWIND,
+       [ 0x2d ] = KEY_PAUSE,
+       [ 0x0d ] = KEY_FORWARD,
+       [ 0x05 ] = KEY_ZOOM,  /*FULL*/
+
+       [ 0x2a ] = KEY_F21, /* LIVE TIMESHIFT */
+       [ 0x0e ] = KEY_F22, /* MIN TIMESHIFT */
+       [ 0x1e ] = KEY_F23, /* TIMESHIFT */
+       [ 0x38 ] = KEY_F24, /* NORMAL TIMESHIFT */
 };
 
 EXPORT_SYMBOL_GPL(ir_codes_gotview7135);
index 365a22118a0914c3eb3102af30463694e7cdb6c1..2b1f8b4be00a456c56495ee69525aaa1c8e66596 100644 (file)
@@ -112,12 +112,13 @@ static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages)
        sglist = kcalloc(nr_pages, sizeof(struct scatterlist), GFP_KERNEL);
        if (NULL == sglist)
                return NULL;
+       sg_init_table(sglist, nr_pages);
        for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
                pg = vmalloc_to_page(virt);
                if (NULL == pg)
                        goto err;
                BUG_ON(PageHighMem(pg));
-               sglist[i].page   = pg;
+               sg_set_page(&sglist[i], pg);
                sglist[i].length = PAGE_SIZE;
        }
        return sglist;
index d2905720eb746b782f034b5e2b0aa1898c16b683..9c905399a233028ba9872cc503efa1f6ef8b699f 100644 (file)
@@ -312,7 +312,7 @@ static int sort_and_eliminate(u32* values, int* count)
                return -EINVAL;
        }
 
-       /* bubble sort the first ´count´ items of the array ´values´ */
+       /* bubble sort the first @count items of the array @values */
        for( top = *count; top > 0; top--) {
                for( low = 0, high = 1; high < top; low++, high++) {
                        if( values[low] > values[high] ) {
index eca602d9b3dec38c7971426e1114fd5b38b4ac3c..85e36a1d6d782d4c8c4581014e9944c9ec9e43dc 100644 (file)
@@ -280,7 +280,7 @@ static irqreturn_t bt878_irq(int irq, void *dev_id)
                if (!(astat = (stat & mask)))
                        return IRQ_NONE;        /* this interrupt is not for me */
 /*             dprintk("bt878(%d) debug: irq count %d, stat 0x%8.8x, mask 0x%8.8x\n",bt->nr,count,stat,mask); */
-               btwrite(astat, BT878_AINT_STAT);        /* try to clear interupt condition */
+               btwrite(astat, BT878_AINT_STAT);        /* try to clear interrupt condition */
 
 
                if (astat & (BT878_ASCERR | BT878_AOCERR)) {
index 5a12b5679556a78a2fc70be51beaa3f0433d2fd7..db08b0a8888afc5763e935a53e712844f8a217aa 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * TerraTec Cinergy T²/qanu USB2 DVB-T adapter.
+ * TerraTec Cinergy T²/qanu USB2 DVB-T adapter.
  *
  * Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and
  *                 Holger Waechtler <holger@qanu.de>
@@ -345,7 +345,9 @@ static int cinergyt2_start_feed(struct dvb_demux_feed *dvbdmxfeed)
        struct dvb_demux *demux = dvbdmxfeed->demux;
        struct cinergyt2 *cinergyt2 = demux->priv;
 
-       if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
+       if (cinergyt2->disconnect_pending)
+               return -EAGAIN;
+       if (mutex_lock_interruptible(&cinergyt2->sem))
                return -ERESTARTSYS;
 
        if (cinergyt2->streaming == 0)
@@ -361,7 +363,9 @@ static int cinergyt2_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
        struct dvb_demux *demux = dvbdmxfeed->demux;
        struct cinergyt2 *cinergyt2 = demux->priv;
 
-       if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
+       if (cinergyt2->disconnect_pending)
+               return -EAGAIN;
+       if (mutex_lock_interruptible(&cinergyt2->sem))
                return -ERESTARTSYS;
 
        if (--cinergyt2->streaming == 0)
@@ -481,12 +485,16 @@ static int cinergyt2_open (struct inode *inode, struct file *file)
 {
        struct dvb_device *dvbdev = file->private_data;
        struct cinergyt2 *cinergyt2 = dvbdev->priv;
-       int err = -ERESTARTSYS;
+       int err = -EAGAIN;
 
-       if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->wq_sem))
+       if (cinergyt2->disconnect_pending)
+               goto out;
+       err = mutex_lock_interruptible(&cinergyt2->wq_sem);
+       if (err)
                goto out;
 
-       if (mutex_lock_interruptible(&cinergyt2->sem))
+       err = mutex_lock_interruptible(&cinergyt2->sem);
+       if (err)
                goto out_unlock1;
 
        if ((err = dvb_generic_open(inode, file)))
@@ -550,7 +558,9 @@ static unsigned int cinergyt2_poll (struct file *file, struct poll_table_struct
        struct cinergyt2 *cinergyt2 = dvbdev->priv;
        unsigned int mask = 0;
 
-       if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
+       if (cinergyt2->disconnect_pending)
+               return -EAGAIN;
+       if (mutex_lock_interruptible(&cinergyt2->sem))
                return -ERESTARTSYS;
 
        poll_wait(file, &cinergyt2->poll_wq, wait);
@@ -625,7 +635,9 @@ static int cinergyt2_ioctl (struct inode *inode, struct file *file,
                if (copy_from_user(&p, (void  __user*) arg, sizeof(p)))
                        return -EFAULT;
 
-               if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
+               if (cinergyt2->disconnect_pending)
+                       return -EAGAIN;
+               if (mutex_lock_interruptible(&cinergyt2->sem))
                        return -ERESTARTSYS;
 
                param->cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
@@ -820,7 +832,7 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2)
 
        input_dev->name = DRIVER_NAME " remote control";
        input_dev->phys = cinergyt2->phys;
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
        for (i = 0; i < ARRAY_SIZE(rc_keys); i += 3)
                set_bit(rc_keys[i + 2], input_dev->keybit);
        input_dev->keycodesize = 0;
@@ -996,7 +1008,9 @@ static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state)
 {
        struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
 
-       if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->wq_sem))
+       if (cinergyt2->disconnect_pending)
+               return -EAGAIN;
+       if (mutex_lock_interruptible(&cinergyt2->wq_sem))
                return -ERESTARTSYS;
 
        cinergyt2_suspend_rc(cinergyt2);
@@ -1017,16 +1031,18 @@ static int cinergyt2_resume (struct usb_interface *intf)
 {
        struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
        struct dvbt_set_parameters_msg *param = &cinergyt2->param;
-       int err = -ERESTARTSYS;
+       int err = -EAGAIN;
 
-       if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->wq_sem))
+       if (cinergyt2->disconnect_pending)
+               goto out;
+       err = mutex_lock_interruptible(&cinergyt2->wq_sem);
+       if (err)
                goto out;
 
-       if (mutex_lock_interruptible(&cinergyt2->sem))
+       err = mutex_lock_interruptible(&cinergyt2->sem);
+       if (err)
                goto out_unlock1;
 
-       err = 0;
-
        if (!cinergyt2->sleeping) {
                cinergyt2_sleep(cinergyt2, 0);
                cinergyt2_command(cinergyt2, (char *) param, sizeof(*param), NULL, 0);
index 084a508a03da8e1202b01fd77ee6a8209fc2f729..89437fdab8befcd393578c57f8c44d9434787612 100644 (file)
@@ -972,7 +972,7 @@ static int dvb_ca_en50221_thread(void *data)
        /* main loop */
        while (!kthread_should_stop()) {
                /* sleep for a bit */
-               while (!ca->wakeup) {
+               if (!ca->wakeup) {
                        set_current_state(TASK_INTERRUPTIBLE);
                        schedule_timeout(ca->delay);
                        if (kthread_should_stop())
index b203640ef1c587e7c4f294a7b0be8f2bd9f923a8..445f0266557754f739b5b406abf8f5e5f55a63a0 100644 (file)
@@ -527,7 +527,8 @@ static int dvb_frontend_thread(void *data)
                up(&fepriv->sem);           /* is locked when we enter the thread... */
 restart:
                timeout = wait_event_interruptible_timeout(fepriv->wait_queue,
-                       dvb_frontend_should_wakeup(fe) || kthread_should_stop(),
+                       dvb_frontend_should_wakeup(fe) || kthread_should_stop()
+                               || freezing(current),
                        fepriv->delay);
 
                if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) {
index e8c4a869453249cbbcbfe27793e6369c53feae90..58452b52002c7f9535e37f341f4ea18cd65bc637 100644 (file)
@@ -828,7 +828,7 @@ MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
 #define DIB0700_DEFAULT_DEVICE_PROPERTIES \
        .caps              = DVB_USB_IS_AN_I2C_ADAPTER, \
        .usb_ctrl          = DEVICE_SPECIFIC, \
-       .firmware          = "dvb-usb-dib0700-03-pre1.fw", \
+       .firmware          = "dvb-usb-dib0700-1.10.fw", \
        .download_firmware = dib0700_download_firmware, \
        .no_reconnect      = 1, \
        .size_of_priv      = sizeof(struct dib0700_state), \
index 7b9f35bfb4f062fe132f78de4fd69736bf293b2f..c0c2c22ddd835143d087ca450306e90f342310c4 100644 (file)
@@ -106,7 +106,7 @@ int dvb_usb_remote_init(struct dvb_usb_device *d)
        if (!input_dev)
                return -ENOMEM;
 
-       input_dev->evbit[0] = BIT(EV_KEY);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY);
        input_dev->name = "IR-receiver inside an USB DVB receiver";
        input_dev->phys = d->rc_phys;
        usb_to_input_id(d->udev, &input_dev->id);
index 5d19c402dad13fbf8096aa05147f28f684d93258..a283e1de83facf6edc5ebae02b6ae232d477b885 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/module.h>
 #include <linux/proc_fs.h>
 #include <linux/kernel.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 
 #include "av7110.h"
 #include "av7110_hw.h"
index 288e79f2cb0f9fba41f29fdc7b940edfe9489bef..7902ae1d9a181c80e205eac147fdb92d3f704ee4 100644 (file)
@@ -128,7 +128,7 @@ struct ttusb {
        struct dvb_frontend* fe;
 };
 
-/* ugly workaround ... don't know why it's neccessary to read */
+/* ugly workaround ... don't know why it's necessary to read */
 /* all result codes. */
 
 #define DEBUG 0
index 5e691fd79904e98cbbc8cc5b9a6ddacf1b6d0658..1ec981d98b91bf60da958e0530dccca725b68474 100644 (file)
@@ -1198,7 +1198,7 @@ static int ttusb_init_rc( struct ttusb_dec *dec)
 
        input_dev->name = "ttusb_dec remote control";
        input_dev->phys = dec->rc_phys;
-       input_dev->evbit[0] = BIT(EV_KEY);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY);
        input_dev->keycodesize = sizeof(u16);
        input_dev->keycodemax = 0x1a;
        input_dev->keycode = rc_keys;
index c7c9d1dc06905cb4074c9def7e5bef4c9e05b9d5..3ae56fef8c92f58ce4d2b2123606b795e0adf503 100644 (file)
@@ -229,7 +229,6 @@ static struct video_device pcm20_radio = {
        .owner          = THIS_MODULE,
        .name           = "Miro PCM 20 radio",
        .type           = VID_TYPE_TUNER,
-       .hardware       = VID_HARDWARE_RTRACK,
        .fops           = &pcm20_fops,
        .priv           = &pcm20_unit
 };
index 0c963db03614b4232e002f2b1e0e3ebd5da6feaa..5e4b9ddb23c0a07e59998606acfe672f260e02df 100644 (file)
@@ -554,7 +554,6 @@ static struct video_device gemtek_radio = {
        .owner                  = THIS_MODULE,
        .name                   = "GemTek Radio card",
        .type                   = VID_TYPE_TUNER,
-       .hardware               = VID_HARDWARE_GEMTEK,
        .fops                   = &gemtek_fops,
        .vidioc_querycap        = vidioc_querycap,
        .vidioc_g_tuner         = vidioc_g_tuner,
index 19e9929ffa0fb74adc7c2df4ebf9944b2e551632..c94a4d0f280475c987b306d9716596c35d9256b7 100644 (file)
@@ -755,7 +755,6 @@ static struct video_device ar_template = {
        .owner          = THIS_MODULE,
        .name           = "Colour AR VGA",
        .type           = VID_TYPE_CAPTURE,
-       .hardware       = VID_HARDWARE_ARV,
        .fops           = &ar_fops,
        .release        = ar_release,
        .minor          = -1,
index dd6a7d68b07fca263b2648136c21aedadaf97c2e..3abd9fa54d2cd5a856f8b0d2af24b57e88dec493 100644 (file)
@@ -1259,7 +1259,7 @@ struct tvcard bttv_tvcards[] = {
                .has_radio      = 1,
        },
        [BTTV_BOARD_LIFETEC_9415] = {
-               /* Tim Röstermundt <rosterm@uni-muenster.de>
+               /* Tim Röstermundt <rosterm@uni-muenster.de>
                in de.comp.os.unix.linux.hardware:
                        options bttv card=0 pll=1 radio=1 gpiomask=0x18e0
                        gpiomux =0x44c71f,0x44d71f,0,0x44d71f,0x44dfff
@@ -2824,7 +2824,7 @@ struct tvcard bttv_tvcards[] = {
        },
                /* ---- card 0x8b ---------------------------------- */
        [BTTV_BOARD_PV_M4900] = {
-               /* Sérgio Fortier <sergiofortier@yahoo.com.br> */
+               /* Sérgio Fortier <sergiofortier@yahoo.com.br> */
                .name           = "Prolink PixelView PlayTV MPEG2 PV-M4900",
                .video_inputs   = 3,
                .audio_inputs   = 1,
@@ -4709,18 +4709,18 @@ adtvk503_audio(struct bttv *btv, struct video_audio *v, int set)
  *
  * The board hardwire Y0 (xpoint) to MUX1 and MUXOUT to Yin.
  * GPIO pins are wired as:
- *  GPIO[0:3] - AX[0:3] (xpoint) - P1[0:3] (microcontroler)
- *  GPIO[4:6] - AY[0:2] (xpoint) - P1[4:6] (microcontroler)
- *  GPIO[7]   - DATA (xpoint)    - P1[7] (microcontroler)
- *  GPIO[8]   -                  - P3[5] (microcontroler)
- *  GPIO[9]   - RESET (xpoint)   - P3[6] (microcontroler)
- *  GPIO[10]  - STROBE (xpoint)  - P3[7] (microcontroler)
- *  GPINTR    -                  - P3[4] (microcontroler)
+ *  GPIO[0:3] - AX[0:3] (xpoint) - P1[0:3] (microcontroller)
+ *  GPIO[4:6] - AY[0:2] (xpoint) - P1[4:6] (microcontroller)
+ *  GPIO[7]   - DATA (xpoint)    - P1[7] (microcontroller)
+ *  GPIO[8]   -                  - P3[5] (microcontroller)
+ *  GPIO[9]   - RESET (xpoint)   - P3[6] (microcontroller)
+ *  GPIO[10]  - STROBE (xpoint)  - P3[7] (microcontroller)
+ *  GPINTR    -                  - P3[4] (microcontroller)
  *
- * The microcontroler is a 80C32 like. It should be possible to change xpoint
- * configuration either directly (as we are doing) or using the microcontroler
+ * The microcontroller is a 80C32 like. It should be possible to change xpoint
+ * configuration either directly (as we are doing) or using the microcontroller
  * which is also wired to I2C interface. I have no further info on the
- * microcontroler features, one would need to disassembly the firmware.
+ * microcontroller features, one would need to disassembly the firmware.
  * note: the vendor refused to give any information on this product, all
  *       that stuff was found using a multimeter! :)
  */
@@ -4788,7 +4788,7 @@ static void tibetCS16_init(struct bttv *btv)
  * The analog switch is controlled by the "master", but the detection order
  * of the four BT878A chips is in an order which I just don't understand.
  * The "master" is actually the second controller to be detected.  The
- * logic on the board uses logical numbers for the 4 controlers, but
+ * logic on the board uses logical numbers for the 4 controllers, but
  * those numbers are different from the detection sequence.  When working
  * with the analog switch, we need to "map" from the detection sequence
  * over to the board's logical controller number.  This mapping sequence
index 7a332b3efe51e0aefe5564b5ba58da13c3c6dcb9..9feeb636ff9b6e4e05c9913c06a77975de232cc9 100644 (file)
@@ -3877,7 +3877,6 @@ static struct video_device bttv_video_template =
        .name     = "UNSET",
        .type     = VID_TYPE_CAPTURE|VID_TYPE_TUNER|
                    VID_TYPE_CLIPPING|VID_TYPE_SCALES,
-       .hardware = VID_HARDWARE_BT848,
        .fops     = &bttv_fops,
        .minor    = -1,
 };
@@ -3886,7 +3885,6 @@ static struct video_device bttv_vbi_template =
 {
        .name     = "bt848/878 vbi",
        .type     = VID_TYPE_TUNER|VID_TYPE_TELETEXT,
-       .hardware = VID_HARDWARE_BT848,
        .fops     = &bttv_fops,
        .minor    = -1,
 };
@@ -4034,7 +4032,6 @@ static struct video_device radio_template =
 {
        .name     = "bt848/878 radio",
        .type     = VID_TYPE_TUNER,
-       .hardware = VID_HARDWARE_BT848,
        .fops     = &radio_fops,
        .minor    = -1,
 };
index 7f7e3d3398d0d24e51654d55cf2a1e22aa64e1ba..58423525591fbce1f1e3f876713b8e47f3bced79 100644 (file)
@@ -899,7 +899,6 @@ static struct video_device qcam_template=
        .owner          = THIS_MODULE,
        .name           = "Connectix Quickcam",
        .type           = VID_TYPE_CAPTURE,
-       .hardware       = VID_HARDWARE_QCAM_BW,
        .fops           = &qcam_fops,
 };
 
index f76c6a6c37667cd40564654346d18814f245186a..cf1546b5a7f1b33e8f8f7d8e865fa54f4fe518e5 100644 (file)
@@ -699,7 +699,6 @@ static struct video_device qcam_template=
        .owner          = THIS_MODULE,
        .name           = "Colour QuickCam",
        .type           = VID_TYPE_CAPTURE,
-       .hardware       = VID_HARDWARE_QCAM_C,
        .fops           = &qcam_fops,
 };
 
index a1d02e5ce0fda4dbcf83c8371f3f31e29abb3d6a..7c630f5ee7258faccf51b06180c76859e5f502da 100644 (file)
@@ -65,10 +65,6 @@ MODULE_PARM_DESC(colorspace_conv,
 
 #define ABOUT "V4L-Driver for Vision CPiA based cameras"
 
-#ifndef VID_HARDWARE_CPIA
-#define VID_HARDWARE_CPIA 24    /* FIXME -> from linux/videodev.h */
-#endif
-
 #define CPIA_MODULE_CPIA                       (0<<5)
 #define CPIA_MODULE_SYSTEM                     (1<<5)
 #define CPIA_MODULE_VP_CTRL                    (5<<5)
@@ -3804,7 +3800,6 @@ static struct video_device cpia_template = {
        .owner          = THIS_MODULE,
        .name           = "CPiA Camera",
        .type           = VID_TYPE_CAPTURE,
-       .hardware       = VID_HARDWARE_CPIA,
        .fops           = &cpia_fops,
 };
 
index e3aaba1e0e0a285a7cfca4970102098ea884852c..e378abec806d21ddb75145ed7bb788bc620b57fc 100644 (file)
@@ -86,10 +86,6 @@ MODULE_LICENSE("GPL");
 
 #define ABOUT "V4L-Driver for Vision CPiA2 based cameras"
 
-#ifndef VID_HARDWARE_CPIA2
-#error "VID_HARDWARE_CPIA2 should have been defined in linux/videodev.h"
-#endif
-
 struct control_menu_info {
        int value;
        char name[32];
@@ -1942,7 +1938,6 @@ static struct video_device cpia2_template = {
        .type=          VID_TYPE_CAPTURE,
        .type2 =        V4L2_CAP_VIDEO_CAPTURE |
                        V4L2_CAP_STREAMING,
-       .hardware=      VID_HARDWARE_CPIA2,
        .minor=         -1,
        .fops=          &fops_template,
        .release=       video_device_release,
index af16505bd2e0516a743d213c6924f57d5a3390f0..3cdd136477e58224dcca0ae81b4a5ad5ba260c45 100644 (file)
@@ -793,7 +793,7 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
                       dev->pci->subsystem_device);
 
                cx23885_devcount--;
-               goto fail_free;
+               return -ENODEV;
        }
 
        /* PCIe stuff */
@@ -835,10 +835,6 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
        }
 
        return 0;
-
-fail_free:
-       kfree(dev);
-       return -ENODEV;
 }
 
 void cx23885_dev_unregister(struct cx23885_dev *dev)
index 141dadf7cf1ba6ad9db266f01673129d28bba44c..40ffd7a5579a6f49347263cb21ad287b0ec1e6b7 100644 (file)
@@ -39,6 +39,7 @@
 #include <sound/pcm_params.h>
 #include <sound/control.h>
 #include <sound/initval.h>
+#include <sound/tlv.h>
 
 #include "cx88.h"
 #include "cx88-reg.h"
@@ -82,6 +83,7 @@ typedef struct cx88_audio_dev snd_cx88_card_t;
 
 
 
+
 /****************************************************************************
                        Module global static vars
  ****************************************************************************/
@@ -545,8 +547,8 @@ static int __devinit snd_cx88_pcm(snd_cx88_card_t *chip, int device, char *name)
 /****************************************************************************
                                CONTROL INTERFACE
  ****************************************************************************/
-static int snd_cx88_capture_volume_info(struct snd_kcontrol *kcontrol,
-                                       struct snd_ctl_elem_info *info)
+static int snd_cx88_volume_info(struct snd_kcontrol *kcontrol,
+                               struct snd_ctl_elem_info *info)
 {
        info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
        info->count = 2;
@@ -556,9 +558,8 @@ static int snd_cx88_capture_volume_info(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
-/* OK - TODO: test it */
-static int snd_cx88_capture_volume_get(struct snd_kcontrol *kcontrol,
-                                      struct snd_ctl_elem_value *value)
+static int snd_cx88_volume_get(struct snd_kcontrol *kcontrol,
+                              struct snd_ctl_elem_value *value)
 {
        snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
        struct cx88_core *core=chip->core;
@@ -573,8 +574,8 @@ static int snd_cx88_capture_volume_get(struct snd_kcontrol *kcontrol,
 }
 
 /* OK - TODO: test it */
-static int snd_cx88_capture_volume_put(struct snd_kcontrol *kcontrol,
-                                      struct snd_ctl_elem_value *value)
+static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol,
+                              struct snd_ctl_elem_value *value)
 {
        snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
        struct cx88_core *core=chip->core;
@@ -605,14 +606,67 @@ static int snd_cx88_capture_volume_put(struct snd_kcontrol *kcontrol,
        return changed;
 }
 
-static struct snd_kcontrol_new snd_cx88_capture_volume = {
+static const DECLARE_TLV_DB_SCALE(snd_cx88_db_scale, -6300, 100, 0);
+
+static struct snd_kcontrol_new snd_cx88_volume = {
+       .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+       .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
+                 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
+       .name = "Playback Volume",
+       .info = snd_cx88_volume_info,
+       .get = snd_cx88_volume_get,
+       .put = snd_cx88_volume_put,
+       .tlv.p = snd_cx88_db_scale,
+};
+
+static int snd_cx88_switch_get(struct snd_kcontrol *kcontrol,
+                              struct snd_ctl_elem_value *value)
+{
+       snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
+       struct cx88_core *core = chip->core;
+       u32 bit = kcontrol->private_value;
+
+       value->value.integer.value[0] = !(cx_read(AUD_VOL_CTL) & bit);
+       return 0;
+}
+
+static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol,
+                                      struct snd_ctl_elem_value *value)
+{
+       snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
+       struct cx88_core *core = chip->core;
+       u32 bit = kcontrol->private_value;
+       int ret = 0;
+       u32 vol;
+
+       spin_lock_irq(&chip->reg_lock);
+       vol = cx_read(AUD_VOL_CTL);
+       if (value->value.integer.value[0] != !(vol & bit)) {
+               vol ^= bit;
+               cx_write(AUD_VOL_CTL, vol);
+               ret = 1;
+       }
+       spin_unlock_irq(&chip->reg_lock);
+       return ret;
+}
+
+static struct snd_kcontrol_new snd_cx88_dac_switch = {
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-       .name = "Capture Volume",
-       .info = snd_cx88_capture_volume_info,
-       .get = snd_cx88_capture_volume_get,
-       .put = snd_cx88_capture_volume_put,
+       .name = "Playback Switch",
+       .info = snd_ctl_boolean_mono_info,
+       .get = snd_cx88_switch_get,
+       .put = snd_cx88_switch_put,
+       .private_value = (1<<8),
 };
 
+static struct snd_kcontrol_new snd_cx88_source_switch = {
+       .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+       .name = "Capture Switch",
+       .info = snd_ctl_boolean_mono_info,
+       .get = snd_cx88_switch_get,
+       .put = snd_cx88_switch_put,
+       .private_value = (1<<6),
+};
 
 /****************************************************************************
                        Basic Flow for Sound Devices
@@ -762,7 +816,13 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci,
        if (err < 0)
                goto error;
 
-       err = snd_ctl_add(card, snd_ctl_new1(&snd_cx88_capture_volume, chip));
+       err = snd_ctl_add(card, snd_ctl_new1(&snd_cx88_volume, chip));
+       if (err < 0)
+               goto error;
+       err = snd_ctl_add(card, snd_ctl_new1(&snd_cx88_dac_switch, chip));
+       if (err < 0)
+               goto error;
+       err = snd_ctl_add(card, snd_ctl_new1(&snd_cx88_source_switch, chip));
        if (err < 0)
                goto error;
 
index 6d6f5048d7627a1d3f0923f763caafa0a06ac88e..f33f0b47142cd319b75942ab4d19ec269cb85922 100644 (file)
@@ -527,44 +527,6 @@ static void blackbird_codec_settings(struct cx8802_dev *dev)
        cx2341x_update(dev, blackbird_mbox_func, NULL, &dev->params);
 }
 
-static struct v4l2_mpeg_compression default_mpeg_params = {
-       .st_type          = V4L2_MPEG_PS_2,
-       .st_bitrate       = {
-               .mode     = V4L2_BITRATE_CBR,
-               .min      = 0,
-               .target   = 0,
-               .max      = 0
-       },
-       .ts_pid_pmt       = 16,
-       .ts_pid_audio     = 260,
-       .ts_pid_video     = 256,
-       .ts_pid_pcr       = 259,
-       .ps_size          = 0,
-       .au_type          = V4L2_MPEG_AU_2_II,
-       .au_bitrate       = {
-               .mode     = V4L2_BITRATE_CBR,
-               .min      = 224,
-               .target   = 224,
-               .max      = 224
-       },
-       .au_sample_rate    = 48000,
-       .au_pesid          = 0,
-       .vi_type           = V4L2_MPEG_VI_2,
-       .vi_aspect_ratio   = V4L2_MPEG_ASPECT_4_3,
-       .vi_bitrate        = {
-               .mode      = V4L2_BITRATE_CBR,
-               .min       = 4000,
-               .target    = 4500,
-               .max       = 6000
-       },
-       .vi_frame_rate     = 25,
-       .vi_frames_per_gop = 12,
-       .vi_bframes_count  = 2,
-       .vi_pesid          = 0,
-       .closed_gops       = 1,
-       .pulldown          = 0
-};
-
 static int blackbird_initialize_codec(struct cx8802_dev *dev)
 {
        struct cx88_core *core = dev->core;
@@ -852,23 +814,6 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
        return videobuf_streamoff(&fh->mpegq);
 }
 
-static int vidioc_g_mpegcomp (struct file *file, void *fh,
-                             struct v4l2_mpeg_compression *f)
-{
-       printk(KERN_WARNING "VIDIOC_G_MPEGCOMP is obsolete. "
-                               "Replace with VIDIOC_G_EXT_CTRLS!");
-       memcpy(f,&default_mpeg_params,sizeof(*f));
-       return 0;
-}
-
-static int vidioc_s_mpegcomp (struct file *file, void *fh,
-                             struct v4l2_mpeg_compression *f)
-{
-       printk(KERN_WARNING "VIDIOC_S_MPEGCOMP is obsolete. "
-                               "Replace with VIDIOC_S_EXT_CTRLS!");
-       return 0;
-}
-
 static int vidioc_g_ext_ctrls (struct file *file, void *priv,
                               struct v4l2_ext_controls *f)
 {
@@ -1216,8 +1161,6 @@ static struct video_device cx8802_mpeg_template =
        .vidioc_dqbuf         = vidioc_dqbuf,
        .vidioc_streamon      = vidioc_streamon,
        .vidioc_streamoff     = vidioc_streamoff,
-       .vidioc_g_mpegcomp    = vidioc_g_mpegcomp,
-       .vidioc_s_mpegcomp    = vidioc_s_mpegcomp,
        .vidioc_g_ext_ctrls   = vidioc_g_ext_ctrls,
        .vidioc_s_ext_ctrls   = vidioc_s_ext_ctrls,
        .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls,
index d16e5c6d21c07c325b3da0895f0550b5d4723f0f..fce19caf9d040ddea7f731b8b2996bb021d24298 100644 (file)
@@ -475,8 +475,9 @@ static int dvb_register(struct cx8802_dev *dev)
                break;
        case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
 #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
+               /* MT352 is on a secondary I2C bus made from some GPIO lines */
                dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config,
-                       &((struct vp3054_i2c_state *)dev->card_priv)->adap);
+                                              &dev->vp3054->adap);
                if (dev->dvb.frontend != NULL) {
                        dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
                                   &dev->core->i2c_adap, DVB_PLL_FMD1216ME);
index a652f294d23d8dd8e6a135eab458395ddb8928f6..448c67380945e62d4598793b19bb027445c7ac02 100644 (file)
@@ -79,7 +79,8 @@ static int cx8802_start_dma(struct cx8802_dev    *dev,
 {
        struct cx88_core *core = dev->core;
 
-       dprintk(1, "cx8802_start_dma w: %d, h: %d, f: %d\n", dev->width, dev->height, buf->vb.field);
+       dprintk(1, "cx8802_start_dma w: %d, h: %d, f: %d\n",
+               buf->vb.width, buf->vb.height, buf->vb.field);
 
        /* setup fifo + format */
        cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28],
@@ -177,7 +178,6 @@ static int cx8802_restart_queue(struct cx8802_dev    *dev,
                                struct cx88_dmaqueue *q)
 {
        struct cx88_buffer *buf;
-       struct list_head *item;
 
        dprintk( 1, "cx8802_restart_queue\n" );
        if (list_empty(&q->active))
@@ -223,10 +223,8 @@ static int cx8802_restart_queue(struct cx8802_dev    *dev,
        dprintk(2,"restart_queue [%p/%d]: restart dma\n",
                buf, buf->vb.i);
        cx8802_start_dma(dev, q, buf);
-       list_for_each(item,&q->active) {
-               buf = list_entry(item, struct cx88_buffer, vb.queue);
+       list_for_each_entry(buf, &q->active, vb.queue)
                buf->count = q->count++;
-       }
        mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
        return 0;
 }
@@ -572,42 +570,29 @@ int cx8802_resume_common(struct pci_dev *pci_dev)
        return 0;
 }
 
+#if defined(CONFIG_VIDEO_CX88_BLACKBIRD) || \
+    defined(CONFIG_VIDEO_CX88_BLACKBIRD_MODULE)
 struct cx8802_dev * cx8802_get_device(struct inode *inode)
 {
        int minor = iminor(inode);
-       struct cx8802_dev *h = NULL;
-       struct list_head *list;
+       struct cx8802_dev *dev;
 
-       list_for_each(list,&cx8802_devlist) {
-               h = list_entry(list, struct cx8802_dev, devlist);
-               if (h->mpeg_dev && h->mpeg_dev->minor == minor)
-                       return h;
-       }
+       list_for_each_entry(dev, &cx8802_devlist, devlist)
+               if (dev->mpeg_dev && dev->mpeg_dev->minor == minor)
+                       return dev;
 
        return NULL;
 }
+EXPORT_SYMBOL(cx8802_get_device);
+#endif
 
 struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype)
 {
-       struct cx8802_dev *h = NULL;
-       struct cx8802_driver *d = NULL;
-       struct list_head *list;
-       struct list_head *list2;
-
-       list_for_each(list,&cx8802_devlist) {
-               h = list_entry(list, struct cx8802_dev, devlist);
-               if (h != dev)
-                       continue;
-
-               list_for_each(list2, &h->drvlist.devlist) {
-                       d = list_entry(list2, struct cx8802_driver, devlist);
+       struct cx8802_driver *d;
 
-                       /* only unregister the correct driver type */
-                       if (d->type_id == btype) {
-                               return d;
-                       }
-               }
-       }
+       list_for_each_entry(d, &dev->drvlist, drvlist)
+               if (d->type_id == btype)
+                       return d;
 
        return NULL;
 }
@@ -671,10 +656,9 @@ static int cx8802_check_driver(struct cx8802_driver *drv)
 
 int cx8802_register_driver(struct cx8802_driver *drv)
 {
-       struct cx8802_dev *h;
+       struct cx8802_dev *dev;
        struct cx8802_driver *driver;
-       struct list_head *list;
-       int err = 0, i = 0;
+       int err, i = 0;
 
        printk(KERN_INFO
               "cx88/2: registering cx8802 driver, type: %s access: %s\n",
@@ -686,14 +670,12 @@ int cx8802_register_driver(struct cx8802_driver *drv)
                return err;
        }
 
-       list_for_each(list,&cx8802_devlist) {
-               h = list_entry(list, struct cx8802_dev, devlist);
-
+       list_for_each_entry(dev, &cx8802_devlist, devlist) {
                printk(KERN_INFO
                       "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n",
-                      h->core->name, h->pci->subsystem_vendor,
-                      h->pci->subsystem_device, h->core->board.name,
-                      h->core->boardnr);
+                      dev->core->name, dev->pci->subsystem_vendor,
+                      dev->pci->subsystem_device, dev->core->board.name,
+                      dev->core->boardnr);
 
                /* Bring up a new struct for each driver instance */
                driver = kzalloc(sizeof(*drv),GFP_KERNEL);
@@ -701,7 +683,7 @@ int cx8802_register_driver(struct cx8802_driver *drv)
                        return -ENOMEM;
 
                /* Snapshot of the driver registration data */
-               drv->core = h->core;
+               drv->core = dev->core;
                drv->suspend = cx8802_suspend_common;
                drv->resume = cx8802_resume_common;
                drv->request_acquire = cx8802_request_acquire;
@@ -712,49 +694,38 @@ int cx8802_register_driver(struct cx8802_driver *drv)
                if (err == 0) {
                        i++;
                        mutex_lock(&drv->core->lock);
-                       list_add_tail(&driver->devlist,&h->drvlist.devlist);
+                       list_add_tail(&driver->drvlist, &dev->drvlist);
                        mutex_unlock(&drv->core->lock);
                } else {
                        printk(KERN_ERR
                               "%s/2: cx8802 probe failed, err = %d\n",
-                              h->core->name, err);
+                              dev->core->name, err);
                }
 
        }
-       if (i == 0)
-               err = -ENODEV;
-       else
-               err = 0;
 
-       return err;
+       return i ? 0 : -ENODEV;
 }
 
 int cx8802_unregister_driver(struct cx8802_driver *drv)
 {
-       struct cx8802_dev *h;
-       struct cx8802_driver *d;
-       struct list_head *list;
-       struct list_head *list2, *q;
-       int err = 0, i = 0;
+       struct cx8802_dev *dev;
+       struct cx8802_driver *d, *dtmp;
+       int err = 0;
 
        printk(KERN_INFO
               "cx88/2: unregistering cx8802 driver, type: %s access: %s\n",
               drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird",
               drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive");
 
-       list_for_each(list,&cx8802_devlist) {
-               i++;
-               h = list_entry(list, struct cx8802_dev, devlist);
-
+       list_for_each_entry(dev, &cx8802_devlist, devlist) {
                printk(KERN_INFO
                       "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n",
-                      h->core->name, h->pci->subsystem_vendor,
-                      h->pci->subsystem_device, h->core->board.name,
-                      h->core->boardnr);
-
-               list_for_each_safe(list2, q, &h->drvlist.devlist) {
-                       d = list_entry(list2, struct cx8802_driver, devlist);
+                      dev->core->name, dev->pci->subsystem_vendor,
+                      dev->pci->subsystem_device, dev->core->board.name,
+                      dev->core->boardnr);
 
+               list_for_each_entry_safe(d, dtmp, &dev->drvlist, drvlist) {
                        /* only unregister the correct driver type */
                        if (d->type_id != drv->type_id)
                                continue;
@@ -762,12 +733,12 @@ int cx8802_unregister_driver(struct cx8802_driver *drv)
                        err = d->remove(d);
                        if (err == 0) {
                                mutex_lock(&drv->core->lock);
-                               list_del(list2);
+                               list_del(&d->drvlist);
                                mutex_unlock(&drv->core->lock);
+                               kfree(d);
                        } else
                                printk(KERN_ERR "%s/2: cx8802 driver remove "
-                                      "failed (%d)\n", h->core->name, err);
-
+                                      "failed (%d)\n", dev->core->name, err);
                }
 
        }
@@ -805,7 +776,7 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
        if (err != 0)
                goto fail_free;
 
-       INIT_LIST_HEAD(&dev->drvlist.devlist);
+       INIT_LIST_HEAD(&dev->drvlist);
        list_add_tail(&dev->devlist,&cx8802_devlist);
 
        /* Maintain a reference so cx88-video can query the 8802 device. */
@@ -825,23 +796,30 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
 static void __devexit cx8802_remove(struct pci_dev *pci_dev)
 {
        struct cx8802_dev *dev;
-       struct cx8802_driver *h;
-       struct list_head *list;
 
        dev = pci_get_drvdata(pci_dev);
 
        dprintk( 1, "%s\n", __FUNCTION__);
 
-       list_for_each(list,&dev->drvlist.devlist) {
-               h = list_entry(list, struct cx8802_driver, devlist);
-               dprintk( 1, " ->driver\n");
-               if (h->remove == NULL) {
-                       printk(KERN_ERR "%s .. skipping driver, no probe function\n", __FUNCTION__);
-                       continue;
+       if (!list_empty(&dev->drvlist)) {
+               struct cx8802_driver *drv, *tmp;
+               int err;
+
+               printk(KERN_WARNING "%s/2: Trying to remove cx8802 driver "
+                      "while cx8802 sub-drivers still loaded?!\n",
+                      dev->core->name);
+
+               list_for_each_entry_safe(drv, tmp, &dev->drvlist, drvlist) {
+                       err = drv->remove(drv);
+                       if (err == 0) {
+                               mutex_lock(&drv->core->lock);
+                               list_del(&drv->drvlist);
+                               mutex_unlock(&drv->core->lock);
+                       } else
+                               printk(KERN_ERR "%s/2: cx8802 driver remove "
+                                      "failed (%d)\n", dev->core->name, err);
+                       kfree(drv);
                }
-               printk(KERN_INFO "%s .. Removing driver type %d\n", __FUNCTION__, h->type_id);
-               cx8802_unregister_driver(h);
-               list_del(&dev->drvlist.devlist);
        }
 
        /* Destroy any 8802 reference. */
@@ -901,7 +879,6 @@ EXPORT_SYMBOL(cx8802_fini_common);
 
 EXPORT_SYMBOL(cx8802_register_driver);
 EXPORT_SYMBOL(cx8802_unregister_driver);
-EXPORT_SYMBOL(cx8802_get_device);
 EXPORT_SYMBOL(cx8802_get_driver);
 /* ----------------------------------------------------------- */
 /*
index 231ae6c4dd229f5327dffba44f5379db71b2c77e..5ee05f8f3fad3091d11e2d8381012f5533bbadaa 100644 (file)
@@ -1675,7 +1675,6 @@ static struct video_device cx8800_radio_template =
 {
        .name                 = "cx8800-radio",
        .type                 = VID_TYPE_TUNER,
-       .hardware             = 0,
        .fops                 = &radio_fops,
        .minor                = -1,
        .vidioc_querycap      = radio_querycap,
index 77c37889232b3f4816dd2ffb4d1fc86c108cac3f..6ce5af48847170a12316df9474bbc01f23fd6984 100644 (file)
@@ -41,7 +41,7 @@ static void vp3054_bit_setscl(void *data, int state)
 {
        struct cx8802_dev *dev = data;
        struct cx88_core *core = dev->core;
-       struct vp3054_i2c_state *vp3054_i2c = dev->card_priv;
+       struct vp3054_i2c_state *vp3054_i2c = dev->vp3054;
 
        if (state) {
                vp3054_i2c->state |=  0x0001;   /* SCL high */
@@ -58,7 +58,7 @@ static void vp3054_bit_setsda(void *data, int state)
 {
        struct cx8802_dev *dev = data;
        struct cx88_core *core = dev->core;
-       struct vp3054_i2c_state *vp3054_i2c = dev->card_priv;
+       struct vp3054_i2c_state *vp3054_i2c = dev->vp3054;
 
        if (state) {
                vp3054_i2c->state |=  0x0002;   /* SDA high */
@@ -113,10 +113,10 @@ int vp3054_i2c_probe(struct cx8802_dev *dev)
        if (core->boardnr != CX88_BOARD_DNTV_LIVE_DVB_T_PRO)
                return 0;
 
-       dev->card_priv = kzalloc(sizeof(*vp3054_i2c), GFP_KERNEL);
-       if (dev->card_priv == NULL)
+       vp3054_i2c = kzalloc(sizeof(*vp3054_i2c), GFP_KERNEL);
+       if (vp3054_i2c == NULL)
                return -ENOMEM;
-       vp3054_i2c = dev->card_priv;
+       dev->vp3054 = vp3054_i2c;
 
        memcpy(&vp3054_i2c->algo, &vp3054_i2c_algo_template,
               sizeof(vp3054_i2c->algo));
@@ -139,8 +139,8 @@ int vp3054_i2c_probe(struct cx8802_dev *dev)
        if (0 != rc) {
                printk("%s: vp3054_i2c register FAILED\n", core->name);
 
-               kfree(dev->card_priv);
-               dev->card_priv = NULL;
+               kfree(dev->vp3054);
+               dev->vp3054 = NULL;
        }
 
        return rc;
@@ -148,7 +148,7 @@ int vp3054_i2c_probe(struct cx8802_dev *dev)
 
 void vp3054_i2c_remove(struct cx8802_dev *dev)
 {
-       struct vp3054_i2c_state *vp3054_i2c = dev->card_priv;
+       struct vp3054_i2c_state *vp3054_i2c = dev->vp3054;
 
        if (vp3054_i2c == NULL ||
            dev->core->boardnr != CX88_BOARD_DNTV_LIVE_DVB_T_PRO)
index 42e0a9b8c55006f4770a3de97e41f86eb3d1a882..eb296bdecb1eb7444e6d6c46572e49992fd4aa01 100644 (file)
@@ -412,7 +412,9 @@ struct cx8802_suspend_state {
 
 struct cx8802_driver {
        struct cx88_core *core;
-       struct list_head devlist;
+
+       /* List of drivers attached to device */
+       struct list_head drvlist;
 
        /* Type of driver and access required */
        enum cx88_board_type type_id;
@@ -453,27 +455,33 @@ struct cx8802_dev {
 
        /* for blackbird only */
        struct list_head           devlist;
+#if defined(CONFIG_VIDEO_CX88_BLACKBIRD) || \
+    defined(CONFIG_VIDEO_CX88_BLACKBIRD_MODULE)
        struct video_device        *mpeg_dev;
        u32                        mailbox;
        int                        width;
        int                        height;
 
+       /* mpeg params */
+       struct cx2341x_mpeg_params params;
+#endif
+
 #if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
        /* for dvb only */
        struct videobuf_dvb        dvb;
+#endif
 
-       void                       *card_priv;
+#if defined(CONFIG_VIDEO_CX88_VP3054) || \
+    defined(CONFIG_VIDEO_CX88_VP3054_MODULE)
+       /* For VP3045 secondary I2C bus support */
+       struct vp3054_i2c_state    *vp3054;
 #endif
        /* for switching modulation types */
        unsigned char              ts_gen_cntrl;
 
-       /* mpeg params */
-       struct cx2341x_mpeg_params params;
-
        /* List of attached drivers */
-       struct cx8802_driver       drvlist;
-       struct work_struct request_module_wk;
-
+       struct list_head           drvlist;
+       struct work_struct         request_module_wk;
 };
 
 /* ----------------------------------------------------------- */
index d3282ec62c5be2e1382a2bc01dc5f4755bdd2a7e..d56484f204677105c9fd435fdeb7bf8aca30ed75 100644 (file)
@@ -648,7 +648,7 @@ void em28xx_uninit_isoc(struct em28xx *dev)
  */
 int em28xx_init_isoc(struct em28xx *dev)
 {
-       /* change interface to 3 which allowes the biggest packet sizes */
+       /* change interface to 3 which allows the biggest packet sizes */
        int i, errCode;
        const int sb_size = EM28XX_NUM_PACKETS * dev->max_pkt_size;
 
@@ -673,6 +673,7 @@ int em28xx_init_isoc(struct em28xx *dev)
                                        ("unable to allocate %i bytes for transfer buffer %i\n",
                                         sb_size, i);
                        em28xx_uninit_isoc(dev);
+                       usb_free_urb(urb);
                        return -ENOMEM;
                }
                memset(dev->transfer_buffer[i], 0, sb_size);
index b8d5327c438ded1e879216b485f7d1ac0ea2a82d..a4c2a907124a6529c38e143e2eeb60ed3958746d 100644 (file)
@@ -907,7 +907,7 @@ static int em28xx_set_fmt(struct em28xx *dev, unsigned int cmd, struct v4l2_form
 
        /* stop io in case it is already in progress */
        if (dev->stream == STREAM_ON) {
-               em28xx_videodbg("VIDIOC_SET_FMT: interupting stream\n");
+               em28xx_videodbg("VIDIOC_SET_FMT: interrupting stream\n");
                if ((ret = em28xx_stream_interrupt(dev)))
                        return ret;
        }
@@ -1617,7 +1617,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
 
        /* Fills VBI device info */
        dev->vbi_dev->type = VFL_TYPE_VBI;
-       dev->vbi_dev->hardware = 0;
        dev->vbi_dev->fops = &em28xx_v4l_fops;
        dev->vbi_dev->minor = -1;
        dev->vbi_dev->dev = &dev->udev->dev;
@@ -1629,7 +1628,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
        dev->vdev->type = VID_TYPE_CAPTURE;
        if (dev->has_tuner)
                dev->vdev->type |= VID_TYPE_TUNER;
-       dev->vdev->hardware = 0;
        dev->vdev->fops = &em28xx_v4l_fops;
        dev->vdev->minor = -1;
        dev->vdev->dev = &dev->udev->dev;
index d5fef4c01c87a9ff0f100a34f9925670245a32eb..d19d73b81edef7b37140a092b3365f2538a72480 100644 (file)
@@ -2585,7 +2585,6 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
        strcpy(cam->v4ldev->name, "ET61X[12]51 PC Camera");
        cam->v4ldev->owner = THIS_MODULE;
        cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
-       cam->v4ldev->hardware = 0;
        cam->v4ldev->fops = &et61x251_fops;
        cam->v4ldev->minor = video_nr[dev_nr];
        cam->v4ldev->release = video_device_release;
index d98dd0d1e37301c04644d154d342ca8fde4ca155..29779d8bf7fbecbc0e33ade96d51a75ef0c30e03 100644 (file)
@@ -528,6 +528,7 @@ static int ir_probe(struct i2c_adapter *adap)
                break;
        case I2C_HW_B_CX2388x:
                probe = probe_cx88;
+               break;
        case I2C_HW_B_CX23885:
                probe = probe_cx23885;
                break;
index fd7a932e1d3384653c2e9e2363c411d3aee0d943..6d2dd8764f814c3ae85fc5b96d45bdc080379335 100644 (file)
@@ -1003,8 +1003,6 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
 
        IVTV_DEBUG_INFO("base addr: 0x%08x\n", itv->base_addr);
 
-       mutex_lock(&itv->serialize_lock);
-
        /* PCI Device Setup */
        if ((retval = ivtv_setup_pci(itv, dev, pci_id)) != 0) {
                if (retval == -EIO)
@@ -1064,7 +1062,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
        IVTV_DEBUG_INFO("activating i2c...\n");
        if (init_ivtv_i2c(itv)) {
                IVTV_ERR("Could not initialize i2c\n");
-               goto free_irq;
+               goto free_io;
        }
 
        IVTV_DEBUG_INFO("Active card count: %d.\n", ivtv_cards_active);
@@ -1176,7 +1174,11 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
                IVTV_ERR("Failed to register irq %d\n", retval);
                goto free_streams;
        }
-       mutex_unlock(&itv->serialize_lock);
+       retval = ivtv_streams_register(itv);
+       if (retval) {
+               IVTV_ERR("Error %d registering devices\n", retval);
+               goto free_irq;
+       }
        IVTV_INFO("Initialized card #%d: %s\n", itv->num, itv->card_name);
        return 0;
 
@@ -1195,7 +1197,6 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
                release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
       free_workqueue:
        destroy_workqueue(itv->irq_work_queues);
-       mutex_unlock(&itv->serialize_lock);
       err:
        if (retval == 0)
                retval = -ENODEV;
index 3bda1df63cb62d8c8567bb5690999b60b7f8bfd4..49ce14d14a54b69eeaa5f04ca200840030d1dad2 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/unistd.h>
 #include <linux/byteorder/swab.h>
 #include <linux/pagemap.h>
+#include <linux/scatterlist.h>
 #include <linux/workqueue.h>
 #include <linux/mutex.h>
 #include <asm/uaccess.h>
index da50fa4a72a50411a0cbb3906c070c28d0c55bbf..a200a8a95a2dc2ee125e6b32a94ab69b96727973 100644 (file)
@@ -822,6 +822,11 @@ int ivtv_v4l2_close(struct inode *inode, struct file *filp)
                        crystal_freq.flags = 0;
                        ivtv_saa7115(itv, VIDIOC_INT_S_CRYSTAL_FREQ, &crystal_freq);
                }
+               if (atomic_read(&itv->capturing) > 0) {
+                       /* Undo video mute */
+                       ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1,
+                               itv->params.video_mute | (itv->params.video_mute_yuv << 8));
+               }
                /* Done! Unmute and continue. */
                ivtv_unmute(itv);
                ivtv_release_stream(s);
@@ -892,6 +897,7 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
                        if (atomic_read(&itv->capturing) > 0) {
                                /* switching to radio while capture is
                                   in progress is not polite */
+                               ivtv_release_stream(s);
                                kfree(item);
                                return -EBUSY;
                        }
@@ -947,7 +953,7 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp)
        if (itv == NULL) {
                /* Couldn't find a device registered
                   on that minor, shouldn't happen! */
-               IVTV_WARN("No ivtv device found on minor %d\n", minor);
+               printk(KERN_WARNING "No ivtv device found on minor %d\n", minor);
                return -ENXIO;
        }
 
index 206eee7542db826803db08c73b8778c757f75bca..fd6826f472e3c99ac50029602e0e38ffc136aba7 100644 (file)
@@ -555,6 +555,7 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype,
 
        /* set window size */
        if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+               struct cx2341x_mpeg_params *p = &itv->params;
                int w = fmt->fmt.pix.width;
                int h = fmt->fmt.pix.height;
 
@@ -566,17 +567,19 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype,
                fmt->fmt.pix.width = w;
                fmt->fmt.pix.height = h;
 
-               if (!set_fmt || (itv->params.width == w && itv->params.height == h))
+               if (!set_fmt || (p->width == w && p->height == h))
                        return 0;
                if (atomic_read(&itv->capturing) > 0)
                        return -EBUSY;
 
-               itv->params.width = w;
-               itv->params.height = h;
+               p->width = w;
+               p->height = h;
                if (w != 720 || h != (itv->is_50hz ? 576 : 480))
-                       itv->params.video_temporal_filter = 0;
+                       p->video_temporal_filter = 0;
                else
-                       itv->params.video_temporal_filter = 8;
+                       p->video_temporal_filter = 8;
+               if (p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
+                       fmt->fmt.pix.width /= 2;
                itv->video_dec_func(itv, VIDIOC_S_FMT, fmt);
                return ivtv_get_fmt(itv, streamtype, fmt);
        }
index fd135985e70f8769c4f7cd097cf11c9799490c40..aa03e61ef310f59b84bc4372a23921c4f7517128 100644 (file)
@@ -166,10 +166,9 @@ static void ivtv_stream_init(struct ivtv *itv, int type)
        ivtv_queue_init(&s->q_io);
 }
 
-static int ivtv_reg_dev(struct ivtv *itv, int type)
+static int ivtv_prep_dev(struct ivtv *itv, int type)
 {
        struct ivtv_stream *s = &itv->streams[type];
-       int vfl_type = ivtv_stream_info[type].vfl_type;
        int minor_offset = ivtv_stream_info[type].minor_offset;
        int minor;
 
@@ -187,15 +186,12 @@ static int ivtv_reg_dev(struct ivtv *itv, int type)
        if (type >= IVTV_DEC_STREAM_TYPE_MPG && !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
                return 0;
 
-       if (minor_offset >= 0)
-               /* card number + user defined offset + device offset */
-               minor = itv->num + ivtv_first_minor + minor_offset;
-       else
-               minor = -1;
+       /* card number + user defined offset + device offset */
+       minor = itv->num + ivtv_first_minor + minor_offset;
 
        /* User explicitly selected 0 buffers for these streams, so don't
           create them. */
-       if (minor >= 0 && ivtv_stream_info[type].dma != PCI_DMA_NONE &&
+       if (ivtv_stream_info[type].dma != PCI_DMA_NONE &&
            itv->options.kilobytes[type] == 0) {
                IVTV_INFO("Disabled %s device\n", ivtv_stream_info[type].name);
                return 0;
@@ -223,21 +219,53 @@ static int ivtv_reg_dev(struct ivtv *itv, int type)
        s->v4l2dev->fops = ivtv_stream_info[type].fops;
        s->v4l2dev->release = video_device_release;
 
-       if (minor >= 0) {
-               /* Register device. First try the desired minor, then any free one. */
-               if (video_register_device(s->v4l2dev, vfl_type, minor) &&
-                   video_register_device(s->v4l2dev, vfl_type, -1)) {
-                       IVTV_ERR("Couldn't register v4l2 device for %s minor %d\n",
-                                       s->name, minor);
-                       video_device_release(s->v4l2dev);
-                       s->v4l2dev = NULL;
-                       return -ENOMEM;
-               }
+       return 0;
+}
+
+/* Initialize v4l2 variables and prepare v4l2 devices */
+int ivtv_streams_setup(struct ivtv *itv)
+{
+       int type;
+
+       /* Setup V4L2 Devices */
+       for (type = 0; type < IVTV_MAX_STREAMS; type++) {
+               /* Prepare device */
+               if (ivtv_prep_dev(itv, type))
+                       break;
+
+               if (itv->streams[type].v4l2dev == NULL)
+                       continue;
+
+               /* Allocate Stream */
+               if (ivtv_stream_alloc(&itv->streams[type]))
+                       break;
        }
-       else {
-               /* Don't register a 'hidden' stream (OSD) */
-               IVTV_INFO("Created framebuffer stream for %s\n", s->name);
+       if (type == IVTV_MAX_STREAMS)
                return 0;
+
+       /* One or more streams could not be initialized. Clean 'em all up. */
+       ivtv_streams_cleanup(itv);
+       return -ENOMEM;
+}
+
+static int ivtv_reg_dev(struct ivtv *itv, int type)
+{
+       struct ivtv_stream *s = &itv->streams[type];
+       int vfl_type = ivtv_stream_info[type].vfl_type;
+       int minor;
+
+       if (s->v4l2dev == NULL)
+               return 0;
+
+       minor = s->v4l2dev->minor;
+       /* Register device. First try the desired minor, then any free one. */
+       if (video_register_device(s->v4l2dev, vfl_type, minor) &&
+                       video_register_device(s->v4l2dev, vfl_type, -1)) {
+               IVTV_ERR("Couldn't register v4l2 device for %s minor %d\n",
+                               s->name, minor);
+               video_device_release(s->v4l2dev);
+               s->v4l2dev = NULL;
+               return -ENOMEM;
        }
 
        switch (vfl_type) {
@@ -262,27 +290,18 @@ static int ivtv_reg_dev(struct ivtv *itv, int type)
        return 0;
 }
 
-/* Initialize v4l2 variables and register v4l2 devices */
-int ivtv_streams_setup(struct ivtv *itv)
+/* Register v4l2 devices */
+int ivtv_streams_register(struct ivtv *itv)
 {
        int type;
+       int err = 0;
 
-       /* Setup V4L2 Devices */
-       for (type = 0; type < IVTV_MAX_STREAMS; type++) {
-               /* Register Device */
-               if (ivtv_reg_dev(itv, type))
-                       break;
-
-               if (itv->streams[type].v4l2dev == NULL)
-                       continue;
+       /* Register V4L2 devices */
+       for (type = 0; type < IVTV_MAX_STREAMS; type++)
+               err |= ivtv_reg_dev(itv, type);
 
-               /* Allocate Stream */
-               if (ivtv_stream_alloc(&itv->streams[type]))
-                       break;
-       }
-       if (type == IVTV_MAX_STREAMS) {
+       if (err == 0)
                return 0;
-       }
 
        /* One or more streams could not be initialized. Clean 'em all up. */
        ivtv_streams_cleanup(itv);
@@ -303,11 +322,8 @@ void ivtv_streams_cleanup(struct ivtv *itv)
                        continue;
 
                ivtv_stream_free(&itv->streams[type]);
-               /* Free Device */
-               if (vdev->minor == -1) /* 'Hidden' never registered stream (OSD) */
-                       video_device_release(vdev);
-               else    /* All others, just unregister. */
-                       video_unregister_device(vdev);
+               /* Unregister device */
+               video_unregister_device(vdev);
        }
 }
 
@@ -425,6 +441,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
 {
        u32 data[CX2341X_MBOX_MAX_DATA];
        struct ivtv *itv = s->itv;
+       struct cx2341x_mpeg_params *p = &itv->params;
        int captype = 0, subtype = 0;
        int enable_passthrough = 0;
 
@@ -445,7 +462,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
                }
                itv->mpg_data_received = itv->vbi_data_inserted = 0;
                itv->dualwatch_jiffies = jiffies;
-               itv->dualwatch_stereo_mode = itv->params.audio_properties & 0x0300;
+               itv->dualwatch_stereo_mode = p->audio_properties & 0x0300;
                itv->search_pack_header = 0;
                break;
 
@@ -477,9 +494,6 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
        s->subtype = subtype;
        s->buffers_stolen = 0;
 
-       /* mute/unmute video */
-       ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1, test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? 1 : 0);
-
        /* Clear Streamoff flags in case left from last capture */
        clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
 
@@ -536,7 +550,12 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
                                itv->pgm_info_offset, itv->pgm_info_num);
 
                /* Setup API for Stream */
-               cx2341x_update(itv, ivtv_api_func, NULL, &itv->params);
+               cx2341x_update(itv, ivtv_api_func, NULL, p);
+
+               /* mute if capturing radio */
+               if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags))
+                       ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1,
+                               1 | (p->video_mute_yuv << 8));
        }
 
        /* Vsync Setup */
@@ -585,6 +604,7 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
 {
        u32 data[CX2341X_MBOX_MAX_DATA];
        struct ivtv *itv = s->itv;
+       struct cx2341x_mpeg_params *p = &itv->params;
        int datatype;
 
        if (s->v4l2dev == NULL)
@@ -623,7 +643,7 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
                break;
        }
        if (ivtv_vapi(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, datatype,
-                       itv->params.width, itv->params.height, itv->params.audio_properties)) {
+                       p->width, p->height, p->audio_properties)) {
                IVTV_DEBUG_WARN("Couldn't initialize decoder source\n");
        }
        return 0;
index 8f5f5b1c7c8974f9bf0b4f4077dcfb6ec98b2c05..3d76a415fbd8892a1b425873259177a1314d2d02 100644 (file)
@@ -22,6 +22,7 @@
 #define IVTV_STREAMS_H
 
 int ivtv_streams_setup(struct ivtv *itv);
+int ivtv_streams_register(struct ivtv *itv);
 void ivtv_streams_cleanup(struct ivtv *itv);
 
 /* Capture related */
index c4626d1cdf41c6f1dcd8757c3871f595001c1b87..912b424e520490c50bd5c303ca65c53d8bf2281f 100644 (file)
@@ -63,10 +63,10 @@ int ivtv_udma_fill_sg_list (struct ivtv_user_dma *dma, struct ivtv_dma_page_info
                        memcpy(page_address(dma->bouncemap[map_offset]) + offset, src, len);
                        kunmap_atomic(src, KM_BOUNCE_READ);
                        local_irq_restore(flags);
-                       dma->SGlist[map_offset].page = dma->bouncemap[map_offset];
+                       sg_set_page(&dma->SGlist[map_offset], dma->bouncemap[map_offset]);
                }
                else {
-                       dma->SGlist[map_offset].page = dma->map[map_offset];
+                       sg_set_page(&dma->SGlist[map_offset], dma->map[map_offset]);
                }
                offset = 0;
                map_offset++;
index e2288f224ab699b2a27688d0cb33d455d5ceb5ea..9091c4837bbca23bcb0f65ad0135537406b68bea 100644 (file)
@@ -710,7 +710,7 @@ static u32 ivtv_yuv_window_setup (struct ivtv *itv, struct yuv_frame_info *windo
 
        /* If there's nothing to safe to display, we may as well stop now */
        if ((int)window->dst_w <= 2 || (int)window->dst_h <= 2 || (int)window->src_w <= 2 || (int)window->src_h <= 2) {
-               return 0;
+               return IVTV_YUV_UPDATE_INVALID;
        }
 
        /* Ensure video remains inside OSD area */
@@ -791,7 +791,7 @@ static u32 ivtv_yuv_window_setup (struct ivtv *itv, struct yuv_frame_info *windo
 
        /* Check again. If there's nothing to safe to display, stop now */
        if ((int)window->dst_w <= 2 || (int)window->dst_h <= 2 || (int)window->src_w <= 2 || (int)window->src_h <= 2) {
-               return 0;
+               return IVTV_YUV_UPDATE_INVALID;
        }
 
        /* Both x offset & width are linked, so they have to be done together */
@@ -840,110 +840,118 @@ void ivtv_yuv_work_handler (struct ivtv *itv)
        if (!(yuv_update = ivtv_yuv_window_setup (itv, &window)))
                return;
 
-       /* Update horizontal settings */
-       if (yuv_update & IVTV_YUV_UPDATE_HORIZONTAL)
-               ivtv_yuv_handle_horizontal(itv, &window);
+       if (yuv_update & IVTV_YUV_UPDATE_INVALID) {
+               write_reg(0x01008080, 0x2898);
+       } else if (yuv_update) {
+               write_reg(0x00108080, 0x2898);
 
-       if (yuv_update & IVTV_YUV_UPDATE_VERTICAL)
-               ivtv_yuv_handle_vertical(itv, &window);
+               if (yuv_update & IVTV_YUV_UPDATE_HORIZONTAL)
+                       ivtv_yuv_handle_horizontal(itv, &window);
+
+               if (yuv_update & IVTV_YUV_UPDATE_VERTICAL)
+                       ivtv_yuv_handle_vertical(itv, &window);
+       }
 
        memcpy(&itv->yuv_info.old_frame_info, &window, sizeof (itv->yuv_info.old_frame_info));
 }
 
 static void ivtv_yuv_init (struct ivtv *itv)
 {
+       struct yuv_playback_info *yi = &itv->yuv_info;
+
        IVTV_DEBUG_YUV("ivtv_yuv_init\n");
 
        /* Take a snapshot of the current register settings */
-       itv->yuv_info.reg_2834 = read_reg(0x02834);
-       itv->yuv_info.reg_2838 = read_reg(0x02838);
-       itv->yuv_info.reg_283c = read_reg(0x0283c);
-       itv->yuv_info.reg_2840 = read_reg(0x02840);
-       itv->yuv_info.reg_2844 = read_reg(0x02844);
-       itv->yuv_info.reg_2848 = read_reg(0x02848);
-       itv->yuv_info.reg_2854 = read_reg(0x02854);
-       itv->yuv_info.reg_285c = read_reg(0x0285c);
-       itv->yuv_info.reg_2864 = read_reg(0x02864);
-       itv->yuv_info.reg_2870 = read_reg(0x02870);
-       itv->yuv_info.reg_2874 = read_reg(0x02874);
-       itv->yuv_info.reg_2898 = read_reg(0x02898);
-       itv->yuv_info.reg_2890 = read_reg(0x02890);
-
-       itv->yuv_info.reg_289c = read_reg(0x0289c);
-       itv->yuv_info.reg_2918 = read_reg(0x02918);
-       itv->yuv_info.reg_291c = read_reg(0x0291c);
-       itv->yuv_info.reg_2920 = read_reg(0x02920);
-       itv->yuv_info.reg_2924 = read_reg(0x02924);
-       itv->yuv_info.reg_2928 = read_reg(0x02928);
-       itv->yuv_info.reg_292c = read_reg(0x0292c);
-       itv->yuv_info.reg_2930 = read_reg(0x02930);
-       itv->yuv_info.reg_2934 = read_reg(0x02934);
-       itv->yuv_info.reg_2938 = read_reg(0x02938);
-       itv->yuv_info.reg_293c = read_reg(0x0293c);
-       itv->yuv_info.reg_2940 = read_reg(0x02940);
-       itv->yuv_info.reg_2944 = read_reg(0x02944);
-       itv->yuv_info.reg_2948 = read_reg(0x02948);
-       itv->yuv_info.reg_294c = read_reg(0x0294c);
-       itv->yuv_info.reg_2950 = read_reg(0x02950);
-       itv->yuv_info.reg_2954 = read_reg(0x02954);
-       itv->yuv_info.reg_2958 = read_reg(0x02958);
-       itv->yuv_info.reg_295c = read_reg(0x0295c);
-       itv->yuv_info.reg_2960 = read_reg(0x02960);
-       itv->yuv_info.reg_2964 = read_reg(0x02964);
-       itv->yuv_info.reg_2968 = read_reg(0x02968);
-       itv->yuv_info.reg_296c = read_reg(0x0296c);
-       itv->yuv_info.reg_2970 = read_reg(0x02970);
-
-       itv->yuv_info.v_filter_1 = -1;
-       itv->yuv_info.v_filter_2 = -1;
-       itv->yuv_info.h_filter = -1;
+       yi->reg_2834 = read_reg(0x02834);
+       yi->reg_2838 = read_reg(0x02838);
+       yi->reg_283c = read_reg(0x0283c);
+       yi->reg_2840 = read_reg(0x02840);
+       yi->reg_2844 = read_reg(0x02844);
+       yi->reg_2848 = read_reg(0x02848);
+       yi->reg_2854 = read_reg(0x02854);
+       yi->reg_285c = read_reg(0x0285c);
+       yi->reg_2864 = read_reg(0x02864);
+       yi->reg_2870 = read_reg(0x02870);
+       yi->reg_2874 = read_reg(0x02874);
+       yi->reg_2898 = read_reg(0x02898);
+       yi->reg_2890 = read_reg(0x02890);
+
+       yi->reg_289c = read_reg(0x0289c);
+       yi->reg_2918 = read_reg(0x02918);
+       yi->reg_291c = read_reg(0x0291c);
+       yi->reg_2920 = read_reg(0x02920);
+       yi->reg_2924 = read_reg(0x02924);
+       yi->reg_2928 = read_reg(0x02928);
+       yi->reg_292c = read_reg(0x0292c);
+       yi->reg_2930 = read_reg(0x02930);
+       yi->reg_2934 = read_reg(0x02934);
+       yi->reg_2938 = read_reg(0x02938);
+       yi->reg_293c = read_reg(0x0293c);
+       yi->reg_2940 = read_reg(0x02940);
+       yi->reg_2944 = read_reg(0x02944);
+       yi->reg_2948 = read_reg(0x02948);
+       yi->reg_294c = read_reg(0x0294c);
+       yi->reg_2950 = read_reg(0x02950);
+       yi->reg_2954 = read_reg(0x02954);
+       yi->reg_2958 = read_reg(0x02958);
+       yi->reg_295c = read_reg(0x0295c);
+       yi->reg_2960 = read_reg(0x02960);
+       yi->reg_2964 = read_reg(0x02964);
+       yi->reg_2968 = read_reg(0x02968);
+       yi->reg_296c = read_reg(0x0296c);
+       yi->reg_2970 = read_reg(0x02970);
+
+       yi->v_filter_1 = -1;
+       yi->v_filter_2 = -1;
+       yi->h_filter = -1;
 
        /* Set some valid size info */
-       itv->yuv_info.osd_x_offset = read_reg(0x02a04) & 0x00000FFF;
-       itv->yuv_info.osd_y_offset = (read_reg(0x02a04) >> 16) & 0x00000FFF;
+       yi->osd_x_offset = read_reg(0x02a04) & 0x00000FFF;
+       yi->osd_y_offset = (read_reg(0x02a04) >> 16) & 0x00000FFF;
 
        /* Bit 2 of reg 2878 indicates current decoder output format
           0 : NTSC    1 : PAL */
        if (read_reg(0x2878) & 4)
-               itv->yuv_info.decode_height = 576;
+               yi->decode_height = 576;
        else
-               itv->yuv_info.decode_height = 480;
+               yi->decode_height = 480;
 
-       /* If no visible size set, assume full size */
-       if (!itv->yuv_info.osd_vis_w)
-               itv->yuv_info.osd_vis_w = 720 - itv->yuv_info.osd_x_offset;
-
-       if (!itv->yuv_info.osd_vis_h) {
-               itv->yuv_info.osd_vis_h = itv->yuv_info.decode_height - itv->yuv_info.osd_y_offset;
+       if (!itv->osd_info) {
+               yi->osd_vis_w = 720 - yi->osd_x_offset;
+               yi->osd_vis_h = yi->decode_height - yi->osd_y_offset;
        } else {
-               /* If output video standard has changed, requested height may
-               not be legal */
-               if (itv->yuv_info.osd_vis_h + itv->yuv_info.osd_y_offset > itv->yuv_info.decode_height) {
-                       IVTV_DEBUG_WARN("Clipping yuv output - fb size (%d) exceeds video standard limit (%d)\n",
-                                       itv->yuv_info.osd_vis_h + itv->yuv_info.osd_y_offset,
-                                       itv->yuv_info.decode_height);
-                       itv->yuv_info.osd_vis_h = itv->yuv_info.decode_height - itv->yuv_info.osd_y_offset;
+               /* If no visible size set, assume full size */
+               if (!yi->osd_vis_w)
+                       yi->osd_vis_w = 720 - yi->osd_x_offset;
+
+               if (!yi->osd_vis_h)
+                       yi->osd_vis_h = yi->decode_height - yi->osd_y_offset;
+               else {
+                       /* If output video standard has changed, requested height may
+                       not be legal */
+                       if (yi->osd_vis_h + yi->osd_y_offset > yi->decode_height) {
+                               IVTV_DEBUG_WARN("Clipping yuv output - fb size (%d) exceeds video standard limit (%d)\n",
+                                               yi->osd_vis_h + yi->osd_y_offset,
+                                               yi->decode_height);
+                               yi->osd_vis_h = yi->decode_height - yi->osd_y_offset;
+                       }
                }
        }
 
        /* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */
-       itv->yuv_info.blanking_ptr = kzalloc(720*16,GFP_KERNEL);
-       if (itv->yuv_info.blanking_ptr) {
-               itv->yuv_info.blanking_dmaptr = pci_map_single(itv->dev, itv->yuv_info.blanking_ptr, 720*16, PCI_DMA_TODEVICE);
-       }
+       yi->blanking_ptr = kzalloc(720*16, GFP_KERNEL);
+       if (yi->blanking_ptr)
+               yi->blanking_dmaptr = pci_map_single(itv->dev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE);
        else {
-               itv->yuv_info.blanking_dmaptr = 0;
-               IVTV_DEBUG_WARN ("Failed to allocate yuv blanking buffer\n");
+               yi->blanking_dmaptr = 0;
+               IVTV_DEBUG_WARN("Failed to allocate yuv blanking buffer\n");
        }
 
-       IVTV_DEBUG_WARN("Enable video output\n");
-       write_reg_sync(0x00108080, 0x2898);
-
        /* Enable YUV decoder output */
        write_reg_sync(0x01, IVTV_REG_VDM);
 
        set_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags);
-       atomic_set(&itv->yuv_info.next_dma_frame,0);
+       atomic_set(&yi->next_dma_frame, 0);
 }
 
 int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
index f7215eeca01829bfbab4dd0d79f56fde01944e34..3b966f0a204ab25109ba3742fb96c3601678ac3d 100644 (file)
@@ -34,6 +34,7 @@
 
 #define IVTV_YUV_UPDATE_HORIZONTAL  0x01
 #define IVTV_YUV_UPDATE_VERTICAL    0x02
+#define IVTV_YUV_UPDATE_INVALID     0x04
 
 extern const u32 yuv_offset[4];
 
index 9684048fe56c8b5e69a5015fe2c342e979a0e390..52ffd154a3d80bbb21eb0514c7603c4368040c3d 100644 (file)
@@ -55,7 +55,6 @@
 static int ivtvfb_card_id = -1;
 static int ivtvfb_debug = 0;
 static int osd_laced;
-static int osd_compat;
 static int osd_depth;
 static int osd_upper;
 static int osd_left;
@@ -65,7 +64,6 @@ static int osd_xres;
 module_param(ivtvfb_card_id, int, 0444);
 module_param_named(debug,ivtvfb_debug, int, 0644);
 module_param(osd_laced, bool, 0444);
-module_param(osd_compat, bool, 0444);
 module_param(osd_depth, int, 0444);
 module_param(osd_upper, int, 0444);
 module_param(osd_left, int, 0444);
@@ -80,12 +78,6 @@ MODULE_PARM_DESC(debug,
                 "Debug level (bitmask). Default: errors only\n"
                 "\t\t\t(debug = 3 gives full debugging)");
 
-MODULE_PARM_DESC(osd_compat,
-                "Compatibility mode - Display size is locked (use for old X drivers)\n"
-                "\t\t\t0=off\n"
-                "\t\t\t1=on\n"
-                "\t\t\tdefault off");
-
 /* Why upper, left, xres, yres, depth, laced ? To match terminology used
    by fbset.
    Why start at 1 for left & upper coordinate ? Because X doesn't allow 0 */
@@ -166,9 +158,6 @@ struct osd_info {
        unsigned long fb_end_aligned_physaddr;
 #endif
 
-       /* Current osd mode */
-       int osd_mode;
-
        /* Store the buffer offset */
        int set_osd_coords_x;
        int set_osd_coords_y;
@@ -470,13 +459,11 @@ static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var)
                        IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n");
        }
 
-       /* Change osd mode if needed.
-          Although rare, things can go wrong. The extra mode
-          change seems to help... */
-       if (osd_mode != -1 && osd_mode != oi->osd_mode) {
+       /* Set video mode. Although rare, the display can become scrambled even
+          if we don't change mode. Always 'bounce' to osd_mode via mode 0 */
+       if (osd_mode != -1) {
                ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0);
                ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, osd_mode);
-               oi->osd_mode = osd_mode;
        }
 
        oi->bits_per_pixel = var->bits_per_pixel;
@@ -579,14 +566,6 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
                osd_height_limit = 480;
        }
 
-       /* Check the bits per pixel */
-       if (osd_compat) {
-               if (var->bits_per_pixel != 32) {
-                       IVTVFB_DEBUG_WARN("Invalid colour mode: %d\n", var->bits_per_pixel);
-                       return -EINVAL;
-               }
-       }
-
        if (var->bits_per_pixel == 8 || var->bits_per_pixel == 32) {
                var->transp.offset = 24;
                var->transp.length = 8;
@@ -638,32 +617,20 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
        }
 
        /* Check the resolution */
-       if (osd_compat) {
-               if (var->xres != oi->ivtvfb_defined.xres ||
-                   var->yres != oi->ivtvfb_defined.yres ||
-                   var->xres_virtual != oi->ivtvfb_defined.xres_virtual ||
-                   var->yres_virtual != oi->ivtvfb_defined.yres_virtual) {
-                       IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d (virtual %dx%d)\n",
-                               var->xres, var->yres, var->xres_virtual, var->yres_virtual);
-                       return -EINVAL;
-               }
+       if (var->xres > IVTV_OSD_MAX_WIDTH || var->yres > osd_height_limit) {
+               IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d\n",
+                               var->xres, var->yres);
+               return -EINVAL;
        }
-       else {
-               if (var->xres > IVTV_OSD_MAX_WIDTH || var->yres > osd_height_limit) {
-                       IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d\n",
-                                       var->xres, var->yres);
-                       return -EINVAL;
-               }
 
-               /* Max horizontal size is 1023 @ 32bpp, 2046 & 16bpp, 4092 @ 8bpp */
-               if (var->xres_virtual > 4095 / (var->bits_per_pixel / 8) ||
-                   var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8) > oi->video_buffer_size ||
-                   var->xres_virtual < var->xres ||
-                   var->yres_virtual < var->yres) {
-                       IVTVFB_DEBUG_WARN("Invalid virtual resolution: %dx%d\n",
-                               var->xres_virtual, var->yres_virtual);
-                       return -EINVAL;
-               }
+       /* Max horizontal size is 1023 @ 32bpp, 2046 & 16bpp, 4092 @ 8bpp */
+       if (var->xres_virtual > 4095 / (var->bits_per_pixel / 8) ||
+           var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8) > oi->video_buffer_size ||
+           var->xres_virtual < var->xres ||
+           var->yres_virtual < var->yres) {
+               IVTVFB_DEBUG_WARN("Invalid virtual resolution: %dx%d\n",
+                       var->xres_virtual, var->yres_virtual);
+               return -EINVAL;
        }
 
        /* Some extra checks if in 8 bit mode */
@@ -877,17 +844,15 @@ static int ivtvfb_init_vidmode(struct ivtv *itv)
 
        /* Color mode */
 
-       if (osd_compat) osd_depth = 32;
-       if (osd_depth != 8 && osd_depth != 16 && osd_depth != 32) osd_depth = 8;
+       if (osd_depth != 8 && osd_depth != 16 && osd_depth != 32)
+               osd_depth = 8;
        oi->bits_per_pixel = osd_depth;
        oi->bytes_per_pixel = oi->bits_per_pixel / 8;
 
-       /* Invalidate current osd mode to force a mode switch later */
-       oi->osd_mode = -1;
-
        /* Horizontal size & position */
 
-       if (osd_xres > 720) osd_xres = 720;
+       if (osd_xres > 720)
+               osd_xres = 720;
 
        /* Must be a multiple of 4 for 8bpp & 2 for 16bpp */
        if (osd_depth == 8)
@@ -895,10 +860,7 @@ static int ivtvfb_init_vidmode(struct ivtv *itv)
        else if (osd_depth == 16)
                osd_xres &= ~1;
 
-       if (osd_xres)
-               start_window.width = osd_xres;
-       else
-               start_window.width = osd_compat ? 720: 640;
+       start_window.width = osd_xres ? osd_xres : 640;
 
        /* Check horizontal start (osd_left). */
        if (osd_left && osd_left + start_window.width > 721) {
@@ -921,10 +883,7 @@ static int ivtvfb_init_vidmode(struct ivtv *itv)
        if (osd_yres > max_height)
                osd_yres = max_height;
 
-       if (osd_yres)
-               start_window.height = osd_yres;
-       else
-               start_window.height = osd_compat ? max_height : (itv->is_50hz ? 480 : 400);
+       start_window.height = osd_yres ? osd_yres : itv->is_50hz ? 480 : 400;
 
        /* Check vertical start (osd_upper). */
        if (osd_upper + start_window.height > max_height + 1) {
@@ -1127,10 +1086,6 @@ static int ivtvfb_init_card(struct ivtv *itv)
        /* Enable the osd */
        ivtvfb_blank(FB_BLANK_UNBLANK, &itv->osd_info->ivtvfb_info);
 
-       /* Note if we're running in compatibility mode */
-       if (osd_compat)
-               IVTVFB_INFO("Running in compatibility mode. Display resize & mode change disabled\n");
-
        /* Allocate DMA */
        ivtv_udma_alloc(itv);
        return 0;
@@ -1177,9 +1132,12 @@ static void ivtvfb_cleanup(void)
        for (i = 0; i < ivtv_cards_active; i++) {
                itv = ivtv_cards[i];
                if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) && itv->osd_info) {
+                       if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) {
+                               IVTVFB_WARN("Framebuffer %d is in use, cannot unload\n", i);
+                               return;
+                       }
                        IVTVFB_DEBUG_INFO("Unregister framebuffer %d\n", i);
                        ivtvfb_blank(FB_BLANK_POWERDOWN, &itv->osd_info->ivtvfb_info);
-                       unregister_framebuffer(&itv->osd_info->ivtvfb_info);
                        ivtvfb_release_buffers(itv);
                        itv->osd_video_pbase = 0;
                }
index 7533fc2033195b97e2648a82225514e7663007b1..c3116329043276640c28e6aa9ccf3ca064a25f43 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2001-2004 Stelian Pop <stelian@popies.net>
  *
- * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
+ * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
  *
  * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com>
  *
@@ -1762,7 +1762,6 @@ static struct video_device meye_template = {
        .owner          = THIS_MODULE,
        .name           = "meye",
        .type           = VID_TYPE_CAPTURE,
-       .hardware       = VID_HARDWARE_MEYE,
        .fops           = &meye_fops,
        .release        = video_device_release,
        .minor          = -1,
index 323d0074120da4aa5ad7f0c87413abd72212e219..d535748df445a9d50f121addae83dd9e92d8b617 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2001-2004 Stelian Pop <stelian@popies.net>
  *
- * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
+ * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
  *
  * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com>
  *
index b8d4ac0d938e472a9118c7b1ceec7a5f1b9ada34..d55d5800efb463cb19de27ac6ecd670bbfd6152f 100644 (file)
@@ -4668,7 +4668,6 @@ static struct video_device vdev_template = {
        .owner =        THIS_MODULE,
        .name =         "OV511 USB Camera",
        .type =         VID_TYPE_CAPTURE,
-       .hardware =     VID_HARDWARE_OV511,
        .fops =         &ov511_fops,
        .release =      video_device_release,
        .minor =        -1,
index 0ef73d9d5848554054889c5b83540db000b3fc7a..ce4b2f9791ee5718535435f59f9e833ce4087c01 100644 (file)
@@ -2013,7 +2013,6 @@ static struct video_device planb_template=
        .owner          = THIS_MODULE,
        .name           = PLANB_DEVICE_NAME,
        .type           = VID_TYPE_OVERLAY,
-       .hardware       = VID_HARDWARE_PLANB,
        .open           = planb_open,
        .close          = planb_close,
        .read           = planb_read,
index b5a67f0dd19f95b6cb3ef88f87525056bc91139f..6820c2aabd303affccde30951bd018bc7f1d5673 100644 (file)
@@ -895,7 +895,6 @@ static struct video_device pms_template=
        .owner          = THIS_MODULE,
        .name           = "Mediavision PMS",
        .type           = VID_TYPE_CAPTURE,
-       .hardware       = VID_HARDWARE_PMS,
        .fops           = &pms_fops,
 };
 
index 20b614436d2cffc16b239025ec79736dda9ddab1..205087a3e136fa226cc52495c5055b7121da5b10 100644 (file)
@@ -209,6 +209,11 @@ static int pvr2_encoder_cmd(void *ctxt,
 
        LOCK_TAKE(hdw->ctl_lock); do {
 
+               if (!hdw->flag_encoder_ok) {
+                       ret = -EIO;
+                       break;
+               }
+
                retry_flag = 0;
                try_count++;
                ret = 0;
@@ -273,6 +278,7 @@ static int pvr2_encoder_cmd(void *ctxt,
                        ret = -EBUSY;
                }
                if (ret) {
+                       hdw->flag_encoder_ok = 0;
                        pvr2_trace(
                                PVR2_TRACE_ERROR_LEGS,
                                "Giving up on command."
index 985d9ae7f5ee1c11486ba7ff6cfeb4303a920b95..f873994b088ce3287a7a5b1bfdb4763b0f818fb6 100644 (file)
@@ -225,11 +225,12 @@ struct pvr2_hdw {
        unsigned int cmd_debug_write_len;  //
        unsigned int cmd_debug_read_len;   //
 
-       int flag_ok;            // device in known good state
-       int flag_disconnected;  // flag_ok == 0 due to disconnect
-       int flag_init_ok;       // true if structure is fully initialized
-       int flag_streaming_enabled; // true if streaming should be on
-       int fw1_state;          // current situation with fw1
+       int flag_ok;            /* device in known good state */
+       int flag_disconnected;  /* flag_ok == 0 due to disconnect */
+       int flag_init_ok;       /* true if structure is fully initialized */
+       int flag_streaming_enabled; /* true if streaming should be on */
+       int fw1_state;          /* current situation with fw1 */
+       int flag_encoder_ok;    /* True if encoder is healthy */
 
        int flag_decoder_is_tuned;
 
index 27b12b4b5c883c449b3ce3bd267fdb338ba1e870..402c59488253768ce077708c8787711886988aa1 100644 (file)
@@ -1248,6 +1248,8 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
           time we configure the encoder, then we'll fully configure it. */
        hdw->enc_cur_valid = 0;
 
+       hdw->flag_encoder_ok = 0;
+
        /* First prepare firmware loading */
        ret |= pvr2_write_register(hdw, 0x0048, 0xffffffff); /*interrupt mask*/
        ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000088); /*gpio dir*/
@@ -1346,6 +1348,7 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
                pvr2_trace(PVR2_TRACE_ERROR_LEGS,
                           "firmware2 upload post-proc failure");
        } else {
+               hdw->flag_encoder_ok = !0;
                hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_FIRMWARE);
        }
        return ret;
index 4563b3df8a0d3bbbab866bf2c71a5317f061acc1..7a596ea7cfe698bc59d7f39299845d73e91dfd1c 100644 (file)
@@ -1121,15 +1121,12 @@ static const struct file_operations vdev_fops = {
 };
 
 
-#define VID_HARDWARE_PVRUSB2    38  /* FIXME : need a good value */
-
 static struct video_device vdev_template = {
        .owner      = THIS_MODULE,
        .type       = VID_TYPE_CAPTURE | VID_TYPE_TUNER,
        .type2      = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE
                       | V4L2_CAP_TUNER | V4L2_CAP_AUDIO
                       | V4L2_CAP_READWRITE),
-       .hardware   = VID_HARDWARE_PVRUSB2,
        .fops       = &vdev_fops,
 };
 
index 950da254214870a366a39dc26843b66cb90f962e..7300ace8f44ed1331bb5f385b3821dfb749aedf9 100644 (file)
@@ -166,7 +166,6 @@ static struct video_device pwc_template = {
        .owner =        THIS_MODULE,
        .name =         "Philips Webcam",       /* Filled in later */
        .type =         VID_TYPE_CAPTURE,
-       .hardware =     VID_HARDWARE_PWC,
        .release =      video_device_release,
        .fops =         &pwc_fops,
        .minor =        -1,
index e20aa3612a7c86699053cdd512be1e286e4b3506..ad0232935df6fb760f176f97695f8ce81ed38957 100644 (file)
@@ -196,10 +196,10 @@ static int i2c_senddata(struct saa5246a_device *t, ...)
        return i2c_sendbuf(t, buf[0], ct-1, buf+1);
 }
 
-/* Get count number of bytes from I²C-device at address adr, store them in buf.
+/* Get count number of bytes from I²C-device at address adr, store them in buf.
  * Start & stop handshaking is done by this routine, ack will be sent after the
  * last byte to inhibit further sending of data. If uaccess is 'true', data is
- * written to user-space with put_user. Returns -1 if I²C-device didn't send
+ * written to user-space with put_user. Returns -1 if I²C-device didn't send
  * acknowledge, 0 otherwise
  */
 static int i2c_getdata(struct saa5246a_device *t, int count, u8 *buf)
index 17f1e2e9a66b16c3031fe9e7b29573765da8f86e..94bb59a32b17e3e984dfb0ec03905ef99a4dc855 100644 (file)
@@ -291,10 +291,10 @@ static int i2c_senddata(struct saa5249_device *t, ...)
        return i2c_sendbuf(t, buf[0], ct-1, buf+1);
 }
 
-/* Get count number of bytes from I²C-device at address adr, store them in buf. Start & stop
+/* Get count number of bytes from I²C-device at address adr, store them in buf. Start & stop
  * handshaking is done by this routine, ack will be sent after the last byte to inhibit further
  * sending of data. If uaccess is 'true', data is written to user-space with put_user.
- * Returns -1 if I²C-device didn't send acknowledge, 0 otherwise
+ * Returns -1 if I²C-device didn't send acknowledge, 0 otherwise
  */
 
 static int i2c_getdata(struct saa5249_device *t, int count, u8 *buf)
index 57f1f5d409e0e0f3f11b1b046c4672f57edd16c8..002e70a33a4f6bf2fe847c6223a1a6518f25955a 100644 (file)
@@ -71,7 +71,6 @@ static const struct v4l2_format v4l2_format_table[] =
 
 struct saa6752hs_state {
        struct i2c_client             client;
-       struct v4l2_mpeg_compression  old_params;
        struct saa6752hs_mpeg_params  params;
        enum saa6752hs_videoformat    video_format;
        v4l2_std_id                   standard;
@@ -161,35 +160,6 @@ static struct saa6752hs_mpeg_params param_defaults =
        .au_l2_bitrate   = V4L2_MPEG_AUDIO_L2_BITRATE_256K,
 };
 
-static struct v4l2_mpeg_compression old_param_defaults =
-{
-       .st_type         = V4L2_MPEG_TS_2,
-       .st_bitrate      = {
-               .mode    = V4L2_BITRATE_CBR,
-               .target  = 7000,
-       },
-
-       .ts_pid_pmt      = 16,
-       .ts_pid_video    = 260,
-       .ts_pid_audio    = 256,
-       .ts_pid_pcr      = 259,
-
-       .vi_type         = V4L2_MPEG_VI_2,
-       .vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3,
-       .vi_bitrate      = {
-               .mode    = V4L2_BITRATE_VBR,
-               .target  = 4000,
-               .max     = 6000,
-       },
-
-       .au_type         = V4L2_MPEG_AU_2_II,
-       .au_bitrate      = {
-               .mode    = V4L2_BITRATE_CBR,
-               .target  = 256,
-       },
-
-};
-
 /* ---------------------------------------------------------------------- */
 
 static int saa6752hs_chip_command(struct i2c_client* client,
@@ -362,74 +332,6 @@ static void saa6752hs_set_subsampling(struct i2c_client* client,
 }
 
 
-static void saa6752hs_old_set_params(struct i2c_client* client,
-                                struct v4l2_mpeg_compression* params)
-{
-       struct saa6752hs_state *h = i2c_get_clientdata(client);
-
-       /* check PIDs */
-       if (params->ts_pid_pmt <= MPEG_PID_MAX) {
-               h->old_params.ts_pid_pmt = params->ts_pid_pmt;
-               h->params.ts_pid_pmt = params->ts_pid_pmt;
-       }
-       if (params->ts_pid_pcr <= MPEG_PID_MAX) {
-               h->old_params.ts_pid_pcr = params->ts_pid_pcr;
-               h->params.ts_pid_pcr = params->ts_pid_pcr;
-       }
-       if (params->ts_pid_video <= MPEG_PID_MAX) {
-               h->old_params.ts_pid_video = params->ts_pid_video;
-               h->params.ts_pid_video = params->ts_pid_video;
-       }
-       if (params->ts_pid_audio <= MPEG_PID_MAX) {
-               h->old_params.ts_pid_audio = params->ts_pid_audio;
-               h->params.ts_pid_audio = params->ts_pid_audio;
-       }
-
-       /* check bitrate parameters */
-       if ((params->vi_bitrate.mode == V4L2_BITRATE_CBR) ||
-           (params->vi_bitrate.mode == V4L2_BITRATE_VBR)) {
-               h->old_params.vi_bitrate.mode = params->vi_bitrate.mode;
-               h->params.vi_bitrate_mode = (params->vi_bitrate.mode == V4L2_BITRATE_VBR) ?
-                      V4L2_MPEG_VIDEO_BITRATE_MODE_VBR : V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
-       }
-       if (params->vi_bitrate.mode != V4L2_BITRATE_NONE)
-               h->old_params.st_bitrate.target = params->st_bitrate.target;
-       if (params->vi_bitrate.mode != V4L2_BITRATE_NONE)
-               h->old_params.vi_bitrate.target = params->vi_bitrate.target;
-       if (params->vi_bitrate.mode == V4L2_BITRATE_VBR)
-               h->old_params.vi_bitrate.max = params->vi_bitrate.max;
-       if (params->au_bitrate.mode != V4L2_BITRATE_NONE)
-               h->old_params.au_bitrate.target = params->au_bitrate.target;
-
-       /* aspect ratio */
-       if (params->vi_aspect_ratio == V4L2_MPEG_ASPECT_4_3 ||
-           params->vi_aspect_ratio == V4L2_MPEG_ASPECT_16_9) {
-               h->old_params.vi_aspect_ratio = params->vi_aspect_ratio;
-               if (params->vi_aspect_ratio == V4L2_MPEG_ASPECT_4_3)
-                       h->params.vi_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3;
-               else
-                       h->params.vi_aspect = V4L2_MPEG_VIDEO_ASPECT_16x9;
-       }
-
-       /* range checks */
-       if (h->old_params.st_bitrate.target > MPEG_TOTAL_TARGET_BITRATE_MAX)
-               h->old_params.st_bitrate.target = MPEG_TOTAL_TARGET_BITRATE_MAX;
-       if (h->old_params.vi_bitrate.target > MPEG_VIDEO_TARGET_BITRATE_MAX)
-               h->old_params.vi_bitrate.target = MPEG_VIDEO_TARGET_BITRATE_MAX;
-       if (h->old_params.vi_bitrate.max > MPEG_VIDEO_MAX_BITRATE_MAX)
-               h->old_params.vi_bitrate.max = MPEG_VIDEO_MAX_BITRATE_MAX;
-       h->params.vi_bitrate = params->vi_bitrate.target;
-       h->params.vi_bitrate_peak = params->vi_bitrate.max;
-       if (h->old_params.au_bitrate.target <= 256) {
-               h->old_params.au_bitrate.target = 256;
-               h->params.au_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_256K;
-       }
-       else {
-               h->old_params.au_bitrate.target = 384;
-               h->params.au_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_384K;
-       }
-}
-
 static int handle_ctrl(struct saa6752hs_mpeg_params *params,
                struct v4l2_ext_control *ctrl, unsigned int cmd)
 {
@@ -697,7 +599,6 @@ static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind)
                return -ENOMEM;
        h->client = client_template;
        h->params = param_defaults;
-       h->old_params = old_param_defaults;
        h->client.adapter = adap;
        h->client.addr = addr;
 
@@ -734,23 +635,11 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
 {
        struct saa6752hs_state *h = i2c_get_clientdata(client);
        struct v4l2_ext_controls *ctrls = arg;
-       struct v4l2_mpeg_compression *old_params = arg;
        struct saa6752hs_mpeg_params params;
        int err = 0;
        int i;
 
        switch (cmd) {
-       case VIDIOC_S_MPEGCOMP:
-               if (NULL == old_params) {
-                       /* apply settings and start encoder */
-                       saa6752hs_init(client);
-                       break;
-               }
-               saa6752hs_old_set_params(client, old_params);
-               /* fall through */
-       case VIDIOC_G_MPEGCOMP:
-               *old_params = h->old_params;
-               break;
        case VIDIOC_S_EXT_CTRLS:
                if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
                        return -EINVAL;
index 1a4a24471f204da1bd71cfd6c3578725a09d4da7..a499eea379e65a4e3209ff5c464f5ac83c45b57a 100644 (file)
@@ -429,7 +429,7 @@ int saa7134_set_dmabits(struct saa7134_dev *dev)
 
        assert_spin_locked(&dev->slock);
 
-       if (dev->inresume)
+       if (dev->insuspend)
                return 0;
 
        /* video capture -- dma 0 + video task A */
@@ -563,6 +563,9 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id)
        unsigned long report,status;
        int loop, handled = 0;
 
+       if (dev->insuspend)
+               goto out;
+
        for (loop = 0; loop < 10; loop++) {
                report = saa_readl(SAA7134_IRQ_REPORT);
                status = saa_readl(SAA7134_IRQ_STATUS);
@@ -1163,6 +1166,7 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
        kfree(dev);
 }
 
+#ifdef CONFIG_PM
 static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state)
 {
 
@@ -1176,6 +1180,19 @@ static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state)
        saa_writel(SAA7134_IRQ2, 0);
        saa_writel(SAA7134_MAIN_CTRL, 0);
 
+       synchronize_irq(pci_dev->irq);
+       dev->insuspend = 1;
+
+       /* Disable timeout timers - if we have active buffers, we will
+          fill them on resume*/
+
+       del_timer(&dev->video_q.timeout);
+       del_timer(&dev->vbi_q.timeout);
+       del_timer(&dev->ts_q.timeout);
+
+       if (dev->remote)
+               saa7134_ir_stop(dev);
+
        pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
        pci_save_state(pci_dev);
 
@@ -1194,24 +1211,27 @@ static int saa7134_resume(struct pci_dev *pci_dev)
        /* Do things that are done in saa7134_initdev ,
                except of initializing memory structures.*/
 
-       dev->inresume = 1;
        saa7134_board_init1(dev);
 
+       /* saa7134_hwinit1 */
        if (saa7134_boards[dev->board].video_out)
                saa7134_videoport_init(dev);
-
        if (card_has_mpeg(dev))
                saa7134_ts_init_hw(dev);
-
+       if (dev->remote)
+               saa7134_ir_start(dev, dev->remote);
        saa7134_hw_enable1(dev);
-       saa7134_set_decoder(dev);
-       saa7134_i2c_call_clients(dev, VIDIOC_S_STD, &dev->tvnorm->id);
+
+
        saa7134_board_init2(dev);
-       saa7134_hw_enable2(dev);
 
+       /*saa7134_hwinit2*/
+       saa7134_set_tvnorm_hw(dev);
        saa7134_tvaudio_setmute(dev);
        saa7134_tvaudio_setvolume(dev, dev->ctl_volume);
+       saa7134_tvaudio_do_scan(dev);
        saa7134_enable_i2s(dev);
+       saa7134_hw_enable2(dev);
 
        /*resume unfinished buffer(s)*/
        spin_lock_irqsave(&dev->slock, flags);
@@ -1219,13 +1239,19 @@ static int saa7134_resume(struct pci_dev *pci_dev)
        saa7134_buffer_requeue(dev, &dev->vbi_q);
        saa7134_buffer_requeue(dev, &dev->ts_q);
 
+       /* FIXME: Disable DMA audio sound - temporary till proper support
+                 is implemented*/
+
+       dev->dmasound.dma_running = 0;
+
        /* start DMA now*/
-       dev->inresume = 0;
+       dev->insuspend = 0;
        saa7134_set_dmabits(dev);
        spin_unlock_irqrestore(&dev->slock, flags);
 
        return 0;
 }
+#endif
 
 /* ----------------------------------------------------------- */
 
@@ -1262,8 +1288,10 @@ static struct pci_driver saa7134_pci_driver = {
        .id_table = saa7134_pci_tbl,
        .probe    = saa7134_initdev,
        .remove   = __devexit_p(saa7134_finidev),
+#ifdef CONFIG_PM
        .suspend  = saa7134_suspend,
        .resume   = saa7134_resume
+#endif
 };
 
 static int saa7134_init(void)
index 34ca874dd7fe4e8a65a8643a682954ae1fb80e15..75d0c5bf46d284def842762960d060304e882a02 100644 (file)
@@ -284,17 +284,6 @@ static int ts_do_ioctl(struct inode *inode, struct file *file,
        case VIDIOC_S_CTRL:
                return saa7134_common_ioctl(dev, cmd, arg);
 
-       case VIDIOC_S_MPEGCOMP:
-               printk(KERN_WARNING "VIDIOC_S_MPEGCOMP is obsolete. "
-                                   "Replace with VIDIOC_S_EXT_CTRLS!");
-               saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, arg);
-               ts_init_encoder(dev);
-               return 0;
-       case VIDIOC_G_MPEGCOMP:
-               printk(KERN_WARNING "VIDIOC_G_MPEGCOMP is obsolete. "
-                                   "Replace with VIDIOC_G_EXT_CTRLS!");
-               saa7134_i2c_call_clients(dev, VIDIOC_G_MPEGCOMP, arg);
-               return 0;
        case VIDIOC_S_EXT_CTRLS:
                /* count == 0 is abused in saa6752hs.c, so that special
                   case is handled here explicitly. */
@@ -342,7 +331,6 @@ static struct video_device saa7134_empress_template =
        .name          = "saa7134-empress",
        .type          = 0 /* FIXME */,
        .type2         = 0 /* FIXME */,
-       .hardware      = 0,
        .fops          = &ts_fops,
        .minor         = -1,
 };
index 80d2644f765a9170d82a1f0c5410cd57a4cbcaee..3abaa1b8ac9d76b834b3eb61be7b1f337cd5ab9a 100644 (file)
@@ -44,6 +44,14 @@ module_param(ir_rc5_remote_gap, int, 0644);
 static int ir_rc5_key_timeout = 115;
 module_param(ir_rc5_key_timeout, int, 0644);
 
+static int repeat_delay = 500;
+module_param(repeat_delay, int, 0644);
+MODULE_PARM_DESC(repeat_delay, "delay before key repeat started");
+static int repeat_period = 33;
+module_param(repeat_period, int, 0644);
+MODULE_PARM_DESC(repeat_period, "repeat period between"
+    "keypresses when key is down");
+
 #define dprintk(fmt, arg...)   if (ir_debug) \
        printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg)
 #define i2cdprintk(fmt, arg...)    if (ir_debug) \
@@ -59,6 +67,13 @@ static int build_key(struct saa7134_dev *dev)
        struct card_ir *ir = dev->remote;
        u32 gpio, data;
 
+       /* here comes the additional handshake steps for some cards */
+       switch (dev->board) {
+       case SAA7134_BOARD_GOTVIEW_7135:
+               saa_setb(SAA7134_GPIO_GPSTATUS1, 0x80);
+               saa_clearb(SAA7134_GPIO_GPSTATUS1, 0x80);
+               break;
+       }
        /* rising SAA7134_GPIO_GPRESCAN reads the status */
        saa_clearb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
        saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
@@ -159,7 +174,7 @@ static void saa7134_input_timer(unsigned long data)
        mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling));
 }
 
-static void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir)
+void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir)
 {
        if (ir->polling) {
                setup_timer(&ir->timer, saa7134_input_timer,
@@ -182,7 +197,7 @@ static void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir)
        }
 }
 
-static void saa7134_ir_stop(struct saa7134_dev *dev)
+void saa7134_ir_stop(struct saa7134_dev *dev)
 {
        if (dev->remote->polling)
                del_timer_sync(&dev->remote->timer);
@@ -285,10 +300,10 @@ int saa7134_input_init1(struct saa7134_dev *dev)
                break;
        case SAA7134_BOARD_GOTVIEW_7135:
                ir_codes     = ir_codes_gotview7135;
-               mask_keycode = 0x0003EC;
-               mask_keyup   = 0x008000;
+               mask_keycode = 0x0003CC;
                mask_keydown = 0x000010;
-               polling      = 50; // ms
+               polling      = 5; /* ms */
+               saa_setb(SAA7134_GPIO_GPMODE1, 0x80);
                break;
        case SAA7134_BOARD_VIDEOMATE_TV_PVR:
        case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS:
@@ -386,6 +401,10 @@ int saa7134_input_init1(struct saa7134_dev *dev)
        if (err)
                goto err_out_stop;
 
+       /* the remote isn't as bouncy as a keyboard */
+       ir->dev->rep[REP_DELAY] = repeat_delay;
+       ir->dev->rep[REP_PERIOD] = repeat_period;
+
        return 0;
 
  err_out_stop:
index 1b9e39a5ea47650ea2a3688d173de3e755d2d8a2..f8e304c7623277b0aa43354e01459aeace8f72a2 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/kthread.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/freezer.h>
 #include <asm/div64.h>
 
 #include "saa7134-reg.h"
@@ -231,7 +232,7 @@ static void mute_input_7134(struct saa7134_dev *dev)
        }
 
        if (dev->hw_mute  == mute &&
-               dev->hw_input == in && !dev->inresume) {
+               dev->hw_input == in && !dev->insuspend) {
                dprintk("mute/input: nothing to do [mute=%d,input=%s]\n",
                        mute,in->name);
                return;
@@ -502,13 +503,17 @@ static int tvaudio_thread(void *data)
        unsigned int i, audio, nscan;
        int max1,max2,carrier,rx,mode,lastmode,default_carrier;
 
-       allow_signal(SIGTERM);
+
+       set_freezable();
+
        for (;;) {
                tvaudio_sleep(dev,-1);
-               if (kthread_should_stop() || signal_pending(current))
+               if (kthread_should_stop())
                        goto done;
 
        restart:
+               try_to_freeze();
+
                dev->thread.scan1 = dev->thread.scan2;
                dprintk("tvaudio thread scan start [%d]\n",dev->thread.scan1);
                dev->tvaudio  = NULL;
@@ -612,9 +617,12 @@ static int tvaudio_thread(void *data)
 
                lastmode = 42;
                for (;;) {
+
+                       try_to_freeze();
+
                        if (tvaudio_sleep(dev,5000))
                                goto restart;
-                       if (kthread_should_stop() || signal_pending(current))
+                       if (kthread_should_stop())
                                break;
                        if (UNSET == dev->thread.mode) {
                                rx = tvaudio_getstereo(dev,&tvaudio[i]);
@@ -630,6 +638,7 @@ static int tvaudio_thread(void *data)
        }
 
  done:
+       dev->thread.stopped = 1;
        return 0;
 }
 
@@ -777,7 +786,8 @@ static int tvaudio_thread_ddep(void *data)
        struct saa7134_dev *dev = data;
        u32 value, norms, clock;
 
-       allow_signal(SIGTERM);
+
+       set_freezable();
 
        clock = saa7134_boards[dev->board].audio_clock;
        if (UNSET != audio_clock_override)
@@ -790,10 +800,13 @@ static int tvaudio_thread_ddep(void *data)
 
        for (;;) {
                tvaudio_sleep(dev,-1);
-               if (kthread_should_stop() || signal_pending(current))
+               if (kthread_should_stop())
                        goto done;
 
        restart:
+
+               try_to_freeze();
+
                dev->thread.scan1 = dev->thread.scan2;
                dprintk("tvaudio thread scan start [%d]\n",dev->thread.scan1);
 
@@ -870,6 +883,7 @@ static int tvaudio_thread_ddep(void *data)
        }
 
  done:
+       dev->thread.stopped = 1;
        return 0;
 }
 
@@ -997,7 +1011,7 @@ int saa7134_tvaudio_init2(struct saa7134_dev *dev)
 int saa7134_tvaudio_fini(struct saa7134_dev *dev)
 {
        /* shutdown tvaudio thread */
-       if (dev->thread.thread)
+       if (dev->thread.thread && !dev->thread.stopped)
                kthread_stop(dev->thread.thread);
 
        saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x07, 0x00); /* LINE1 */
@@ -1013,7 +1027,9 @@ int saa7134_tvaudio_do_scan(struct saa7134_dev *dev)
        } else if (dev->thread.thread) {
                dev->thread.mode = UNSET;
                dev->thread.scan2++;
-               wake_up_process(dev->thread.thread);
+
+               if (!dev->insuspend && !dev->thread.stopped)
+                       wake_up_process(dev->thread.thread);
        } else {
                dev->automute = 0;
                saa7134_tvaudio_setmute(dev);
index 471b92793c124aca8a94626390ef079175a3c53c..3b9ffb4b648a67fcf8eeb4eb5637fbec605a5e06 100644 (file)
@@ -560,15 +560,8 @@ void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm)
 
        dev->crop_current = dev->crop_defrect;
 
-       saa7134_set_decoder(dev);
+       saa7134_set_tvnorm_hw(dev);
 
-       if (card_in(dev, dev->ctl_input).tv) {
-               if ((card(dev).tuner_type == TUNER_PHILIPS_TDA8290)
-                               && ((card(dev).tuner_config == 1)
-                               ||  (card(dev).tuner_config == 2)))
-                       saa7134_set_gpio(dev, 22, 5);
-               saa7134_i2c_call_clients(dev, VIDIOC_S_STD, &norm->id);
-       }
 }
 
 static void video_mux(struct saa7134_dev *dev, int input)
@@ -579,7 +572,8 @@ static void video_mux(struct saa7134_dev *dev, int input)
        saa7134_tvaudio_setinput(dev, &card_in(dev, input));
 }
 
-void saa7134_set_decoder(struct saa7134_dev *dev)
+
+static void saa7134_set_decoder(struct saa7134_dev *dev)
 {
        int luma_control, sync_control, mux;
 
@@ -630,6 +624,19 @@ void saa7134_set_decoder(struct saa7134_dev *dev)
        saa_writeb(SAA7134_RAW_DATA_OFFSET,       0x80);
 }
 
+void saa7134_set_tvnorm_hw(struct saa7134_dev *dev)
+{
+       saa7134_set_decoder(dev);
+
+       if (card_in(dev, dev->ctl_input).tv) {
+               if ((card(dev).tuner_type == TUNER_PHILIPS_TDA8290)
+                               && ((card(dev).tuner_config == 1)
+                               ||  (card(dev).tuner_config == 2)))
+                       saa7134_set_gpio(dev, 22, 5);
+               saa7134_i2c_call_clients(dev, VIDIOC_S_STD, &dev->tvnorm->id);
+       }
+}
+
 static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale)
 {
        static const struct {
@@ -2352,7 +2359,6 @@ struct video_device saa7134_video_template =
        .name          = "saa7134-video",
        .type          = VID_TYPE_CAPTURE|VID_TYPE_TUNER|
                         VID_TYPE_CLIPPING|VID_TYPE_SCALES,
-       .hardware      = 0,
        .fops          = &video_fops,
        .minor         = -1,
 };
@@ -2361,7 +2367,6 @@ struct video_device saa7134_vbi_template =
 {
        .name          = "saa7134-vbi",
        .type          = VID_TYPE_TUNER|VID_TYPE_TELETEXT,
-       .hardware      = 0,
        .fops          = &video_fops,
        .minor         = -1,
 };
@@ -2370,7 +2375,6 @@ struct video_device saa7134_radio_template =
 {
        .name          = "saa7134-radio",
        .type          = VID_TYPE_TUNER,
-       .hardware      = 0,
        .fops          = &radio_fops,
        .minor         = -1,
 };
index 28ec6804bd5dca50b472cd40e07973d05c66beab..66a390c321a706079c9ef82bc8168d25b2a31b19 100644 (file)
@@ -333,6 +333,7 @@ struct saa7134_thread {
        unsigned int               scan1;
        unsigned int               scan2;
        unsigned int               mode;
+       unsigned int               stopped;
 };
 
 /* buffer for one video/vbi/ts frame */
@@ -524,7 +525,7 @@ struct saa7134_dev {
        unsigned int               hw_mute;
        int                        last_carrier;
        int                        nosignal;
-       unsigned int               inresume;
+       unsigned int               insuspend;
 
        /* SAA7134_MPEG_* */
        struct saa7134_ts          ts;
@@ -632,7 +633,7 @@ extern struct video_device saa7134_radio_template;
 
 void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm);
 int saa7134_videoport_init(struct saa7134_dev *dev);
-void saa7134_set_decoder(struct saa7134_dev *dev);
+void saa7134_set_tvnorm_hw(struct saa7134_dev *dev);
 
 int saa7134_common_ioctl(struct saa7134_dev *dev,
                         unsigned int cmd, void *arg);
@@ -706,6 +707,8 @@ int  saa7134_input_init1(struct saa7134_dev *dev);
 void saa7134_input_fini(struct saa7134_dev *dev);
 void saa7134_input_irq(struct saa7134_dev *dev);
 void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir);
+void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir);
+void saa7134_ir_stop(struct saa7134_dev *dev);
 
 
 /*
index 93fb04ed99a040d2e28512e21505e424f3133e69..d5d7d6cf734aba40ca0c224051a206bd52fd1b4a 100644 (file)
@@ -1231,7 +1231,6 @@ static struct video_device se401_template = {
        .owner =        THIS_MODULE,
        .name =         "se401 USB camera",
        .type =         VID_TYPE_CAPTURE,
-       .hardware =     VID_HARDWARE_SE401,
        .fops =         &se401_fops,
 };
 
index 6991e06f7651a1601c33688f10bc4e1f16e37f5d..511847912c485fbb2ec85a125e1bd9a29032dd5b 100644 (file)
@@ -3319,7 +3319,6 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
        strcpy(cam->v4ldev->name, "SN9C1xx PC Camera");
        cam->v4ldev->owner = THIS_MODULE;
        cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
-       cam->v4ldev->hardware = 0;
        cam->v4ldev->fops = &sn9c102_fops;
        cam->v4ldev->minor = video_nr[dev_nr];
        cam->v4ldev->release = video_device_release;
index eb220461ac77a8e9f973dae81f837ee4ae54a198..3fb85af5d1f2b8ab45140661298a53062c920fb3 100644 (file)
@@ -1917,7 +1917,6 @@ static const struct file_operations saa_fops = {
 static struct video_device saa_template = {
        .name = "SAA7146A",
        .type = VID_TYPE_CAPTURE | VID_TYPE_OVERLAY,
-       .hardware = VID_HARDWARE_SAA7146,
        .fops = &saa_fops,
        .minor = -1,
 };
index 9e009a7ab863d020a9fe01e42c4174027c5c8af3..afc32aa56fde2eb3952cb69dd214cdd9cd52701b 100644 (file)
@@ -1398,7 +1398,6 @@ static struct video_device stv680_template = {
        .owner =        THIS_MODULE,
        .name =         "STV0680 USB camera",
        .type =         VID_TYPE_CAPTURE,
-       .hardware =     VID_HARDWARE_SE401,
        .fops =         &stv680_fops,
        .release =      video_device_release,
        .minor =        -1,
index 94843086cda90f41f32e2b876b23b0e63908abb9..6a777604f0708d36570a74fd96c704ec71fa3733 100644 (file)
@@ -113,7 +113,7 @@ static void fe_standby(struct tuner *t)
 static int fe_has_signal(struct tuner *t)
 {
        struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
-       u16 strength;
+       u16 strength = 0;
 
        if (fe_tuner_ops->get_rf_strength)
                fe_tuner_ops->get_rf_strength(&t->fe, &strength);
index 491505d6fdeea14d4c7b9934aa656666d83eaa6e..3e93f80587708f2f118d150c8c9a0ac3cc2c3208 100644 (file)
@@ -238,8 +238,8 @@ static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev
        usb_to_input_id(dev, &input_dev->id);
        input_dev->dev.parent = &dev->dev;
 
-       input_dev->evbit[0] = BIT(EV_KEY);
-       input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY);
+       input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
 
        input_dev->private = cam;
 
index dd1a6d6bbc9eef80a81f30162f9f20ca49eaf780..d847273eeba0c247c4f707a4fed3b00feef04b3e 100644 (file)
@@ -102,8 +102,8 @@ static void qcm_register_input(struct qcm *cam, struct usb_device *dev)
        usb_to_input_id(dev, &input_dev->id);
        input_dev->dev.parent = &dev->dev;
 
-       input_dev->evbit[0] = BIT(EV_KEY);
-       input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY);
+       input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
 
        input_dev->private = cam;
 
index 37ce36b9e5878bc9123691e3b859b442995b93bd..fb434b5602a3d5e2c8a76fccb45c9eeba5fd9e8a 100644 (file)
@@ -952,7 +952,6 @@ static const struct file_operations usbvideo_fops = {
 static const struct video_device usbvideo_template = {
        .owner =      THIS_MODULE,
        .type =       VID_TYPE_CAPTURE,
-       .hardware =   VID_HARDWARE_CPIA,
        .fops =       &usbvideo_fops,
 };
 
index ff555129c82f2830d45ec0b3a7e9e30fe3d555b3..da1ba0211108939810983cb3753588d713c257ef 100644 (file)
@@ -955,7 +955,7 @@ read_frame(struct vicam_camera *cam, int framenum)
                request[7] = realShutter >> 8;
        }
 
-       // Per John Markus Bjørndalen, byte at index 8 causes problems if it isn't 0
+       // Per John Markus Bjørndalen, byte at index 8 causes problems if it isn't 0
        request[8] = 0;
        // bytes 9-15 do not seem to affect exposure or image quality
 
@@ -1074,7 +1074,6 @@ static struct video_device vicam_template = {
        .owner          = THIS_MODULE,
        .name           = "ViCam-based USB Camera",
        .type           = VID_TYPE_CAPTURE,
-       .hardware       = VID_HARDWARE_VICAM,
        .fops           = &vicam_fops,
        .minor          = -1,
 };
index e2f3c01cfa134c2290507d3de9d806554bbc69a6..36e689fa16c09f1b0afdbbd25b4a2fbf5f260125 100644 (file)
@@ -1400,7 +1400,6 @@ static const struct file_operations usbvision_fops = {
 static struct video_device usbvision_video_template = {
        .owner             = THIS_MODULE,
        .type           = VID_TYPE_TUNER | VID_TYPE_CAPTURE,
-       .hardware       = VID_HARDWARE_USBVISION,
        .fops           = &usbvision_fops,
        .name           = "usbvision-video",
        .release        = video_device_release,
@@ -1455,7 +1454,6 @@ static struct video_device usbvision_radio_template=
 {
        .owner             = THIS_MODULE,
        .type           = VID_TYPE_TUNER,
-       .hardware       = VID_HARDWARE_USBVISION,
        .fops           = &usbvision_radio_fops,
        .name           = "usbvision-radio",
        .release        = video_device_release,
@@ -1492,7 +1490,6 @@ static struct video_device usbvision_vbi_template=
 {
        .owner             = THIS_MODULE,
        .type           = VID_TYPE_TUNER,
-       .hardware       = VID_HARDWARE_USBVISION,
        .fops           = &usbvision_vbi_fops,
        .release        = video_device_release,
        .name           = "usbvision-vbi",
index 9eac65f34bff815515d36577872424f89dbcd692..dcf22a3b672aa65721994665c284aa99705bd887 100644 (file)
@@ -144,7 +144,7 @@ const static unsigned int palette2pixelformat[] = {
        [VIDEO_PALETTE_YUV422P] = V4L2_PIX_FMT_YUV422P,
 };
 
-static unsigned int __attribute_pure__
+static unsigned int __pure
 palette_to_pixelformat(unsigned int palette)
 {
        if (palette < ARRAY_SIZE(palette2pixelformat))
index c3440b280d208456d6d50980f8949ae423aba493..1141b4bf41ce059ee69349edeb1ad4fde7315167 100644 (file)
@@ -37,7 +37,7 @@
  * Video4linux 1/2 integration by Justin Schoeman
  * <justin@suntiger.ee.up.ac.za>
  * 2.4 PROCFS support ported from 2.4 kernels by
- *  Iñaki García Etxebarria <garetxe@euskalnet.net>
+ *  Iñaki García Etxebarria <garetxe@euskalnet.net>
  * Makefile fix by "W. Michael Petullo" <mike@flyn.org>
  * 2.4 devfs support ported from 2.4 kernels by
  *  Dan Merillat <dan@merillat.org>
@@ -317,8 +317,6 @@ static const char *v4l2_ioctls[] = {
        [_IOC_NR(VIDIOC_ENUM_FMT)]         = "VIDIOC_ENUM_FMT",
        [_IOC_NR(VIDIOC_G_FMT)]            = "VIDIOC_G_FMT",
        [_IOC_NR(VIDIOC_S_FMT)]            = "VIDIOC_S_FMT",
-       [_IOC_NR(VIDIOC_G_MPEGCOMP)]       = "VIDIOC_G_MPEGCOMP",
-       [_IOC_NR(VIDIOC_S_MPEGCOMP)]       = "VIDIOC_S_MPEGCOMP",
        [_IOC_NR(VIDIOC_REQBUFS)]          = "VIDIOC_REQBUFS",
        [_IOC_NR(VIDIOC_QUERYBUF)]         = "VIDIOC_QUERYBUF",
        [_IOC_NR(VIDIOC_G_FBUF)]           = "VIDIOC_G_FBUF",
index 5599a36490fc964239dd01f4473c7f523b60105f..89a44f16f0ba50892be204f19f66c576cf46a2e1 100644 (file)
@@ -967,6 +967,7 @@ int videobuf_cgmbuf(struct videobuf_queue *q,
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(videobuf_cgmbuf);
 #endif
 
 /* --------------------------------------------------------------------- */
@@ -985,7 +986,6 @@ EXPORT_SYMBOL_GPL(videobuf_reqbufs);
 EXPORT_SYMBOL_GPL(videobuf_querybuf);
 EXPORT_SYMBOL_GPL(videobuf_qbuf);
 EXPORT_SYMBOL_GPL(videobuf_dqbuf);
-EXPORT_SYMBOL_GPL(videobuf_cgmbuf);
 EXPORT_SYMBOL_GPL(videobuf_streamon);
 EXPORT_SYMBOL_GPL(videobuf_streamoff);
 
index 3eb6123227b2277225dabb51bbe62c9963ad26a6..9ab94a749d81ec813036e7bef8dc6d0ad35519d2 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/pci.h>
 #include <linux/vmalloc.h>
 #include <linux/pagemap.h>
+#include <linux/scatterlist.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 
@@ -60,12 +61,13 @@ videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages)
        sglist = kcalloc(nr_pages, sizeof(struct scatterlist), GFP_KERNEL);
        if (NULL == sglist)
                return NULL;
+       sg_init_table(sglist, nr_pages);
        for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
                pg = vmalloc_to_page(virt);
                if (NULL == pg)
                        goto err;
                BUG_ON(PageHighMem(pg));
-               sglist[i].page   = pg;
+               sg_set_page(&sglist[i], pg);
                sglist[i].length = PAGE_SIZE;
        }
        return sglist;
@@ -86,13 +88,14 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
        sglist = kcalloc(nr_pages, sizeof(*sglist), GFP_KERNEL);
        if (NULL == sglist)
                return NULL;
+       sg_init_table(sglist, nr_pages);
 
        if (NULL == pages[0])
                goto nopage;
        if (PageHighMem(pages[0]))
                /* DMA to highmem pages might not work */
                goto highmem;
-       sglist[0].page   = pages[0];
+       sg_set_page(&sglist[0], pages[0]);
        sglist[0].offset = offset;
        sglist[0].length = PAGE_SIZE - offset;
        for (i = 1; i < nr_pages; i++) {
@@ -100,7 +103,7 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
                        goto nopage;
                if (PageHighMem(pages[i]))
                        goto highmem;
-               sglist[i].page   = pages[i];
+               sg_set_page(&sglist[i], pages[i]);
                sglist[i].length = PAGE_SIZE;
        }
        return sglist;
index f2bbd7a4d562850ffb306c584b61a10b9b2ab330..87951ec8254f47cd8be33557237cd7bedf54d902 100644 (file)
@@ -86,8 +86,8 @@ videocodec_attach (struct videocodec_master *master)
        }
 
        dprintk(2,
-               "videocodec_attach: '%s', type: %x, flags %lx, magic %lx\n",
-               master->name, master->type, master->flags, master->magic);
+               "videocodec_attach: '%s', flags %lx, magic %lx\n",
+               master->name, master->flags, master->magic);
 
        if (!h) {
                dprintk(1,
index 8d8e517b344f1a46ec3b30db7a4cdad1d9334413..9611c3990285d45133276f22082ec7c4fb8bf73b 100644 (file)
@@ -1313,48 +1313,6 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
                ret=vfd->vidioc_cropcap(file, fh, p);
                break;
        }
-       case VIDIOC_G_MPEGCOMP:
-       {
-               struct v4l2_mpeg_compression *p=arg;
-
-               /*FIXME: Several fields not shown */
-               if (!vfd->vidioc_g_mpegcomp)
-                       break;
-               ret=vfd->vidioc_g_mpegcomp(file, fh, p);
-               if (!ret)
-                       dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d,"
-                                       " ts_pid_video=%d, ts_pid_pcr=%d, "
-                                       "ps_size=%d, au_sample_rate=%d, "
-                                       "au_pesid=%c, vi_frame_rate=%d, "
-                                       "vi_frames_per_gop=%d, "
-                                       "vi_bframes_count=%d, vi_pesid=%c\n",
-                                       p->ts_pid_pmt,p->ts_pid_audio,
-                                       p->ts_pid_video,p->ts_pid_pcr,
-                                       p->ps_size, p->au_sample_rate,
-                                       p->au_pesid, p->vi_frame_rate,
-                                       p->vi_frames_per_gop,
-                                       p->vi_bframes_count, p->vi_pesid);
-               break;
-       }
-       case VIDIOC_S_MPEGCOMP:
-       {
-               struct v4l2_mpeg_compression *p=arg;
-               /*FIXME: Several fields not shown */
-               if (!vfd->vidioc_s_mpegcomp)
-                       break;
-               dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d, "
-                               "ts_pid_video=%d, ts_pid_pcr=%d, ps_size=%d, "
-                               "au_sample_rate=%d, au_pesid=%c, "
-                               "vi_frame_rate=%d, vi_frames_per_gop=%d, "
-                               "vi_bframes_count=%d, vi_pesid=%c\n",
-                               p->ts_pid_pmt,p->ts_pid_audio, p->ts_pid_video,
-                               p->ts_pid_pcr, p->ps_size, p->au_sample_rate,
-                               p->au_pesid, p->vi_frame_rate,
-                               p->vi_frames_per_gop, p->vi_bframes_count,
-                               p->vi_pesid);
-               ret=vfd->vidioc_s_mpegcomp(file, fh, p);
-               break;
-       }
        case VIDIOC_G_JPEGCOMP:
        {
                struct v4l2_jpegcompression *p=arg;
index b532aa280a1be1b4b509b0f184de25e59b92d5df..ee73dc75131ccb5348089ed9548f737937d4cc0c 100644 (file)
@@ -1119,7 +1119,6 @@ static const struct file_operations vivi_fops = {
 static struct video_device vivi = {
        .name           = "vivi",
        .type           = VID_TYPE_CAPTURE,
-       .hardware       = 0,
        .fops           = &vivi_fops,
        .minor          = -1,
 //     .release        = video_device_release,
index 47366408637c7928a7a097a9ebffda1aa90125f0..08aaae07c7e0cb3c4a58e386bb49312068c2f613 100644 (file)
@@ -196,7 +196,6 @@ static struct video_device w9966_template = {
        .owner          = THIS_MODULE,
        .name           = W9966_DRIVERNAME,
        .type           = VID_TYPE_CAPTURE | VID_TYPE_SCALES,
-       .hardware       = VID_HARDWARE_W9966,
        .fops           = &w9966_fops,
 };
 
index 9e7f3e685d73a1c6bae57fee2cbf593f577a7b0f..2ae1430f5f7d0165942d2427d80fdaa833448213 100644 (file)
@@ -3549,7 +3549,6 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
        strcpy(cam->v4ldev->name, symbolic(camlist, mod_id));
        cam->v4ldev->owner = THIS_MODULE;
        cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
-       cam->v4ldev->hardware = VID_HARDWARE_W9968CF;
        cam->v4ldev->fops = &w9968cf_fops;
        cam->v4ldev->minor = video_nr[dev_nr];
        cam->v4ldev->release = video_device_release;
index 08a93c31c0a0e6e542a8a149769d076d577bdbfe..2c5665c824423360481ea49a5f388a4a79c76223 100644 (file)
@@ -1985,7 +1985,6 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
        strcpy(cam->v4ldev->name, "ZC0301[P] PC Camera");
        cam->v4ldev->owner = THIS_MODULE;
        cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
-       cam->v4ldev->hardware = 0;
        cam->v4ldev->fops = &zc0301_fops;
        cam->v4ldev->minor = video_nr[dev_nr];
        cam->v4ldev->release = video_device_release;
index 48da36a15fcae475ea0a10bb384d6be5b0651e41..6e0ac4c5c379683187645e104e467b82c171b196 100644 (file)
@@ -1235,8 +1235,14 @@ zoran_setup_videocodec (struct zoran *zr,
                return m;
        }
 
-       m->magic = 0L; /* magic not used */
-       m->type = VID_HARDWARE_ZR36067;
+       /* magic and type are unused for master struct. Makes sense only at
+          codec structs.
+          In the past, .type were initialized to the old V4L1 .hardware
+          value, as VID_HARDWARE_ZR36067
+        */
+       m->magic = 0L;
+       m->type = 0;
+
        m->flags = CODEC_FLAG_ENCODER | CODEC_FLAG_DECODER;
        strncpy(m->name, ZR_DEVNAME(zr), sizeof(m->name));
        m->data = zr;
index 1c14fa2bd4115623de441807e76688133f6664f3..dd3d7d2c8b0e38323ed29e2a9b21a6a429a46111 100644 (file)
@@ -60,7 +60,6 @@
 
 #include <linux/spinlock.h>
 #define     MAP_NR(x)       virt_to_page(x)
-#define     ZORAN_HARDWARE  VID_HARDWARE_ZR36067
 #define     ZORAN_VID_TYPE  ( \
                                VID_TYPE_CAPTURE | \
                                VID_TYPE_OVERLAY | \
@@ -1285,7 +1284,7 @@ zoran_open (struct inode *inode,
        }
 
        dprintk(1, KERN_INFO "%s: zoran_open(%s, pid=[%d]), users(-)=%d\n",
-               ZR_DEVNAME(zr), current->comm, current->pid, zr->user);
+               ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user);
 
        /* now, create the open()-specific file_ops struct */
        fh = kzalloc(sizeof(struct zoran_fh), GFP_KERNEL);
@@ -1358,7 +1357,7 @@ zoran_close (struct inode *inode,
        struct zoran *zr = fh->zr;
 
        dprintk(1, KERN_INFO "%s: zoran_close(%s, pid=[%d]), users(+)=%d\n",
-               ZR_DEVNAME(zr), current->comm, current->pid, zr->user);
+               ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user);
 
        /* kernel locks (fs/device.c), so don't do that ourselves
         * (prevents deadlocks) */
@@ -4659,7 +4658,6 @@ struct video_device zoran_template __devinitdata = {
 #ifdef CONFIG_VIDEO_V4L2
        .type2 = ZORAN_V4L2_VID_FLAGS,
 #endif
-       .hardware = ZORAN_HARDWARE,
        .fops = &zoran_fops,
        .release = &zoran_vdev_release,
        .minor = -1
index a81f851f7b5de08d08a0c22d33097c0b2731e38c..911fc3021e3bc71d921139ceee08778e024487c2 100644 (file)
@@ -30,13 +30,13 @@ Juha Sievanen, University of Helsinki Finland
        Bug fixes
        Core code extensions
 
-Auvo Häkkinen, University of Helsinki Finland
+Auvo Häkkinen, University of Helsinki Finland
        LAN OSM code
        /Proc interface to LAN class
        Bug fixes
        Core code extensions
 
-Taneli Vähäkangas, University of Helsinki Finland
+Taneli Vähäkangas, University of Helsinki Finland
        Fixes to i2o_config
 
 CREDITS
index ce8f1a34ed2130fbcb7eae0dc6c53c81d689f0c5..6cbcc21de5182b2ce3e4087e3a022654eb7cb606 100644 (file)
@@ -15,8 +15,8 @@
  *
  *     Fixes/additions:
  *             Philipp Rumpf
- *             Juha Sievänen <Juha.Sievanen@cs.Helsinki.FI>
- *             Auvo Häkkinen <Auvo.Hakkinen@cs.Helsinki.FI>
+ *             Juha Sievänen <Juha.Sievanen@cs.Helsinki.FI>
+ *             Auvo Häkkinen <Auvo.Hakkinen@cs.Helsinki.FI>
  *             Deepak Saxena <deepak@plexity.net>
  *             Boji T Kannanthanam <boji.t.kannanthanam@intel.com>
  *             Alan Cox <alan@redhat.com>:
index 84e046e94f5f9829a4bd762db7ef9f8c5062ac85..c0fb77dc19bb1da39d4c969d60691fc634a63235 100644 (file)
  *             Added basic ioctl() support
  *     Deepak Saxena (06/07/1999):
  *             Added software download ioctl (still testing)
- *     Auvo Häkkinen (09/10/1999):
+ *     Auvo Häkkinen (09/10/1999):
  *             Changes to i2o_cfg_reply(), ioctl_parms()
  *             Added ioct_validate()
- *     Taneli Vähäkangas (09/30/1999):
+ *     Taneli Vähäkangas (09/30/1999):
  *             Fixed ioctl_swdl()
- *     Taneli Vähäkangas (10/04/1999):
+ *     Taneli Vähäkangas (10/04/1999):
  *             Changed ioctl_swdl(), implemented ioctl_swul() and ioctl_swdel()
  *     Deepak Saxena (11/18/1999):
  *             Added event managmenet support
index 06892ac2286e4e5ef37edda3b028522f3797201d..6fdd072201f990e4b975724bef3668b08f44dfac 100644 (file)
@@ -19,8 +19,8 @@
  *
  *
  *     Fixes/additions:
- *             Juha Sievänen (Juha.Sievanen@cs.Helsinki.FI),
- *             Auvo Häkkinen (Auvo.Hakkinen@cs.Helsinki.FI)
+ *             Juha Sievänen (Juha.Sievanen@cs.Helsinki.FI),
+ *             Auvo Häkkinen (Auvo.Hakkinen@cs.Helsinki.FI)
  *             University of Helsinki, Department of Computer Science
  *                     LAN entries
  *             Markus Lidel <Markus.Lidel@shadowconnect.com>
index a1ec16a075c62a2a585684e6583a35d23589130f..7814a06ae970f515cc43e21051e0bb13a09c53a9 100644 (file)
@@ -15,8 +15,8 @@
  *
  *     Fixes/additions:
  *             Philipp Rumpf
- *             Juha Sievänen <Juha.Sievanen@cs.Helsinki.FI>
- *             Auvo Häkkinen <Auvo.Hakkinen@cs.Helsinki.FI>
+ *             Juha Sievänen <Juha.Sievanen@cs.Helsinki.FI>
+ *             Auvo Häkkinen <Auvo.Hakkinen@cs.Helsinki.FI>
  *             Deepak Saxena <deepak@plexity.net>
  *             Boji T Kannanthanam <boji.t.kannanthanam@intel.com>
  *             Alan Cox <alan@redhat.com>:
index 3661e6e065d27c705c86d0e5d215b24523939adc..685a89547a51fdc26929c5df2202b1f353188d7a 100644 (file)
@@ -15,8 +15,8 @@
  *
  *     Fixes/additions:
  *             Philipp Rumpf
- *             Juha Sievänen <Juha.Sievanen@cs.Helsinki.FI>
- *             Auvo Häkkinen <Auvo.Hakkinen@cs.Helsinki.FI>
+ *             Juha Sievänen <Juha.Sievanen@cs.Helsinki.FI>
+ *             Auvo Häkkinen <Auvo.Hakkinen@cs.Helsinki.FI>
  *             Deepak Saxena <deepak@plexity.net>
  *             Boji T Kannanthanam <boji.t.kannanthanam@intel.com>
  *             Alan Cox <alan@redhat.com>:
index a20a51efe11896416e2ca4f7bdee82f4e047a592..25716193a534db2d4fb16c00cca5b1a94c481c6a 100644 (file)
@@ -10,8 +10,8 @@ config MFD_SM501
         ---help---
          This is the core driver for the Silicon Motion SM501 multimedia
          companion chip. This device is a multifunction device which may
-         provide numerous interfaces including USB host controller USB gadget,
-         Asyncronous Serial ports, Audio functions and a dual display video
+         provide numerous interfaces including USB host controller, USB gadget,
+         asynchronous serial ports, audio functions, and a dual display video
          interface. The device may be connected by PCI or local bus with
          varying functions enabled.
 
index 346c44eff95eb91370fc832664c2632956473d4d..b5e67c0ff43304d3e16be35525a47e9fc96aaaaf 100644 (file)
@@ -111,6 +111,21 @@ config ASUS_LAPTOP
 
          If you have an ACPI-compatible ASUS laptop, say Y or M here.
 
+config FUJITSU_LAPTOP
+        tristate "Fujitsu Laptop Extras"
+        depends on X86
+        depends on ACPI
+        depends on BACKLIGHT_CLASS_DEVICE
+        ---help---
+         This is a driver for laptops built by Fujitsu:
+
+           * P2xxx/P5xxx/S6xxx/S7xxx series Lifebooks
+           * Possibly other Fujitsu laptop models
+
+         It adds support for LCD brightness control.
+
+         If you have a Fujitsu laptop, say Y or M here.
+
 config MSI_LAPTOP
         tristate "MSI Laptop Extras"
         depends on X86
@@ -134,6 +149,7 @@ config SONY_LAPTOP
        tristate "Sony Laptop Extras"
        depends on X86 && ACPI
        select BACKLIGHT_CLASS_DEVICE
+       depends on INPUT
          ---help---
          This mini-driver drives the SNC and SPIC devices present in the ACPI
          BIOS of the Sony Vaio laptops.
@@ -156,6 +172,7 @@ config THINKPAD_ACPI
        select BACKLIGHT_CLASS_DEVICE
        select HWMON
        select NVRAM
+       depends on INPUT
        ---help---
          This is a driver for the IBM and Lenovo ThinkPad laptops. It adds
          support for Fn-Fx key combinations, Bluetooth control, video
@@ -163,7 +180,7 @@ config THINKPAD_ACPI
          For more information about this driver see 
          <file:Documentation/thinkpad-acpi.txt> and <http://ibm-acpi.sf.net/> .
 
-         This driver was formely known as ibm-acpi.
+         This driver was formerly known as ibm-acpi.
 
          If you have an IBM or Lenovo ThinkPad laptop, say Y or M here.
 
@@ -197,7 +214,7 @@ config THINKPAD_ACPI_BAY
        default y
        ---help---
          Allows the thinkpad_acpi driver to handle removable bays.  It will
-         eletrically disable the device in the bay, and also generate
+         electrically disable the device in the bay, and also generate
          notifications when the bay lever is ejected or inserted.
 
          If you are not sure, say Y here.
index a24c61475c2f8afcd3490a89055bab3587e9b39d..87f2685d728fed038472818507a48741f873e177 100644 (file)
@@ -15,4 +15,5 @@ obj-$(CONFIG_PHANTOM)         += phantom.o
 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_EEPROM_93CX6)     += eeprom_93cx6.o
diff --git a/drivers/misc/fujitsu-laptop.c b/drivers/misc/fujitsu-laptop.c
new file mode 100644 (file)
index 0000000..d366a6c
--- /dev/null
@@ -0,0 +1,358 @@
+/*-*-linux-c-*-*/
+
+/*
+  Copyright (C) 2007 Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
+  Based on earlier work:
+    Copyright (C) 2003 Shane Spencer <shane@bogomip.com>
+    Adrian Yee <brewt-fujitsu@brewt.org>
+
+  Templated from msi-laptop.c which is copyright by its respective authors.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+  02110-1301, USA.
+ */
+
+/*
+ * fujitsu-laptop.c - Fujitsu laptop support, providing access to additional
+ * features made available on a range of Fujitsu laptops including the
+ * P2xxx/P5xxx/S6xxx/S7xxx series.
+ *
+ * This driver exports a few files in /sys/devices/platform/fujitsu-laptop/;
+ * others may be added at a later date.
+ *
+ *   lcd_level - Screen brightness: contains a single integer in the
+ *   range 0..7. (rw)
+ *
+ * In addition to these platform device attributes the driver
+ * registers itself in the Linux backlight control subsystem and is
+ * available to userspace under /sys/class/backlight/fujitsu-laptop/.
+ *
+ * This driver has been tested on a Fujitsu Lifebook S7020.  It should
+ * work on most P-series and S-series Lifebooks, but YMMV.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/acpi.h>
+#include <linux/dmi.h>
+#include <linux/backlight.h>
+#include <linux/platform_device.h>
+#include <linux/autoconf.h>
+
+#define FUJITSU_DRIVER_VERSION "0.3"
+
+#define FUJITSU_LCD_N_LEVELS 8
+
+#define ACPI_FUJITSU_CLASS              "fujitsu"
+#define ACPI_FUJITSU_HID                "FUJ02B1"
+#define ACPI_FUJITSU_DRIVER_NAME        "Fujitsu laptop FUJ02B1 ACPI extras driver"
+#define ACPI_FUJITSU_DEVICE_NAME        "Fujitsu FUJ02B1"
+
+struct fujitsu_t {
+       acpi_handle acpi_handle;
+       struct backlight_device *bl_device;
+       struct platform_device *pf_device;
+
+       unsigned long fuj02b1_state;
+       unsigned int brightness_changed;
+       unsigned int brightness_level;
+};
+
+static struct fujitsu_t *fujitsu;
+
+/* Hardware access */
+
+static int set_lcd_level(int level)
+{
+       acpi_status status = AE_OK;
+       union acpi_object arg0 = { ACPI_TYPE_INTEGER };
+       struct acpi_object_list arg_list = { 1, &arg0 };
+       acpi_handle handle = NULL;
+
+       if (level < 0 || level >= FUJITSU_LCD_N_LEVELS)
+               return -EINVAL;
+
+       if (!fujitsu)
+               return -EINVAL;
+
+       status = acpi_get_handle(fujitsu->acpi_handle, "SBLL", &handle);
+       if (ACPI_FAILURE(status)) {
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "SBLL not present\n"));
+               return -ENODEV;
+       }
+
+       arg0.integer.value = level;
+
+       status = acpi_evaluate_object(handle, NULL, &arg_list, NULL);
+       if (ACPI_FAILURE(status))
+               return -ENODEV;
+
+       return 0;
+}
+
+static int get_lcd_level(void)
+{
+       unsigned long state = 0;
+       acpi_status status = AE_OK;
+
+       // Get the Brightness
+       status =
+           acpi_evaluate_integer(fujitsu->acpi_handle, "GBLL", NULL, &state);
+       if (status < 0)
+               return status;
+
+       fujitsu->fuj02b1_state = state;
+       fujitsu->brightness_level = state & 0x0fffffff;
+
+       if (state & 0x80000000)
+               fujitsu->brightness_changed = 1;
+       else
+               fujitsu->brightness_changed = 0;
+
+       if (status < 0)
+               return status;
+
+       return fujitsu->brightness_level;
+}
+
+/* Backlight device stuff */
+
+static int bl_get_brightness(struct backlight_device *b)
+{
+       return get_lcd_level();
+}
+
+static int bl_update_status(struct backlight_device *b)
+{
+       return set_lcd_level(b->props.brightness);
+}
+
+static struct backlight_ops fujitsubl_ops = {
+       .get_brightness = bl_get_brightness,
+       .update_status = bl_update_status,
+};
+
+/* Platform device */
+
+static ssize_t show_lcd_level(struct device *dev,
+                             struct device_attribute *attr, char *buf)
+{
+
+       int ret;
+
+       ret = get_lcd_level();
+       if (ret < 0)
+               return ret;
+
+       return sprintf(buf, "%i\n", ret);
+}
+
+static ssize_t store_lcd_level(struct device *dev,
+                              struct device_attribute *attr, const char *buf,
+                              size_t count)
+{
+
+       int level, ret;
+
+       if (sscanf(buf, "%i", &level) != 1
+           || (level < 0 || level >= FUJITSU_LCD_N_LEVELS))
+               return -EINVAL;
+
+       ret = set_lcd_level(level);
+       if (ret < 0)
+               return ret;
+
+       return count;
+}
+
+static DEVICE_ATTR(lcd_level, 0644, show_lcd_level, store_lcd_level);
+
+static struct attribute *fujitsupf_attributes[] = {
+       &dev_attr_lcd_level.attr,
+       NULL
+};
+
+static struct attribute_group fujitsupf_attribute_group = {
+       .attrs = fujitsupf_attributes
+};
+
+static struct platform_driver fujitsupf_driver = {
+       .driver = {
+                  .name = "fujitsu-laptop",
+                  .owner = THIS_MODULE,
+                  }
+};
+
+/* ACPI device */
+
+int acpi_fujitsu_add(struct acpi_device *device)
+{
+       int result = 0;
+       int state = 0;
+
+       ACPI_FUNCTION_TRACE("acpi_fujitsu_add");
+
+       if (!device)
+               return -EINVAL;
+
+       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;
+
+       result = acpi_bus_get_power(fujitsu->acpi_handle, &state);
+       if (result) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+                                 "Error reading power state\n"));
+               goto end;
+       }
+
+       printk(KERN_INFO PREFIX "%s [%s] (%s)\n",
+              acpi_device_name(device), acpi_device_bid(device),
+              !device->power.state ? "on" : "off");
+
+      end:
+
+       return result;
+}
+
+int acpi_fujitsu_remove(struct acpi_device *device, int type)
+{
+       ACPI_FUNCTION_TRACE("acpi_fujitsu_remove");
+
+       if (!device || !acpi_driver_data(device))
+               return -EINVAL;
+       fujitsu->acpi_handle = 0;
+
+       return 0;
+}
+
+static const struct acpi_device_id fujitsu_device_ids[] = {
+       {ACPI_FUJITSU_HID, 0},
+       {"", 0},
+};
+
+static struct acpi_driver acpi_fujitsu_driver = {
+       .name = ACPI_FUJITSU_DRIVER_NAME,
+       .class = ACPI_FUJITSU_CLASS,
+       .ids = fujitsu_device_ids,
+       .ops = {
+               .add = acpi_fujitsu_add,
+               .remove = acpi_fujitsu_remove,
+               },
+};
+
+/* Initialization */
+
+static int __init fujitsu_init(void)
+{
+       int ret, result;
+
+       if (acpi_disabled)
+               return -ENODEV;
+
+       fujitsu = kmalloc(sizeof(struct fujitsu_t), GFP_KERNEL);
+       if (!fujitsu)
+               return -ENOMEM;
+       memset(fujitsu, 0, sizeof(struct fujitsu_t));
+
+       result = acpi_bus_register_driver(&acpi_fujitsu_driver);
+       if (result < 0) {
+               ret = -ENODEV;
+               goto fail_acpi;
+       }
+
+       /* Register backlight stuff */
+
+       fujitsu->bl_device =
+           backlight_device_register("fujitsu-laptop", NULL, NULL,
+                                     &fujitsubl_ops);
+       if (IS_ERR(fujitsu->bl_device))
+               return PTR_ERR(fujitsu->bl_device);
+
+       fujitsu->bl_device->props.max_brightness = FUJITSU_LCD_N_LEVELS - 1;
+       ret = platform_driver_register(&fujitsupf_driver);
+       if (ret)
+               goto fail_backlight;
+
+       /* Register platform stuff */
+
+       fujitsu->pf_device = platform_device_alloc("fujitsu-laptop", -1);
+       if (!fujitsu->pf_device) {
+               ret = -ENOMEM;
+               goto fail_platform_driver;
+       }
+
+       ret = platform_device_add(fujitsu->pf_device);
+       if (ret)
+               goto fail_platform_device1;
+
+       ret =
+           sysfs_create_group(&fujitsu->pf_device->dev.kobj,
+                              &fujitsupf_attribute_group);
+       if (ret)
+               goto fail_platform_device2;
+
+       printk(KERN_INFO "fujitsu-laptop: driver " FUJITSU_DRIVER_VERSION
+              " successfully loaded.\n");
+
+       return 0;
+
+      fail_platform_device2:
+
+       platform_device_del(fujitsu->pf_device);
+
+      fail_platform_device1:
+
+       platform_device_put(fujitsu->pf_device);
+
+      fail_platform_driver:
+
+       platform_driver_unregister(&fujitsupf_driver);
+
+      fail_backlight:
+
+       backlight_device_unregister(fujitsu->bl_device);
+
+      fail_acpi:
+
+       kfree(fujitsu);
+
+       return ret;
+}
+
+static void __exit fujitsu_cleanup(void)
+{
+       sysfs_remove_group(&fujitsu->pf_device->dev.kobj,
+                          &fujitsupf_attribute_group);
+       platform_device_unregister(fujitsu->pf_device);
+       platform_driver_unregister(&fujitsupf_driver);
+       backlight_device_unregister(fujitsu->bl_device);
+
+       acpi_bus_unregister_driver(&acpi_fujitsu_driver);
+
+       kfree(fujitsu);
+
+       printk(KERN_INFO "fujitsu-laptop: driver unloaded.\n");
+}
+
+module_init(fujitsu_init);
+module_exit(fujitsu_cleanup);
+
+MODULE_AUTHOR("Jonathan Woithe");
+MODULE_DESCRIPTION("Fujitsu laptop extras support");
+MODULE_VERSION(FUJITSU_DRIVER_VERSION);
+MODULE_LICENSE("GPL");
index 0550ce075fc4f5cde48b3de4a12ea428288b7ad6..477bb43c899c2fdb72e87ca9ecb337f9bb1e8d3e 100644 (file)
@@ -17,7 +17,7 @@
  *
  * Copyright (C) IBM Corporation, 2004
  *
- * Authors: Max Asböck <amax@us.ibm.com>
+ * Authors: Max Asböck <amax@us.ibm.com>
  *          Vernon Mauery <vernux@us.ibm.com>
  *
  */
@@ -226,9 +226,9 @@ int ibmasm_init_remote_input_dev(struct service_processor *sp)
        mouse_dev->id.product = pdev->device;
        mouse_dev->id.version = 1;
        mouse_dev->dev.parent = sp->dev;
-       mouse_dev->evbit[0]  = BIT(EV_KEY) | BIT(EV_ABS);
-       mouse_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) |
-               BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
+       mouse_dev->evbit[0]  = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+       mouse_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+               BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
        set_bit(BTN_TOUCH, mouse_dev->keybit);
        mouse_dev->name = "ibmasm RSA I remote mouse";
        input_set_abs_params(mouse_dev, ABS_X, 0, MOUSE_X_MAX, 0, 0);
@@ -239,7 +239,7 @@ int ibmasm_init_remote_input_dev(struct service_processor *sp)
        keybd_dev->id.product = pdev->device;
        keybd_dev->id.version = 2;
        keybd_dev->dev.parent = sp->dev;
-       keybd_dev->evbit[0]  = BIT(EV_KEY);
+       keybd_dev->evbit[0]  = BIT_MASK(EV_KEY);
        keybd_dev->name = "ibmasm RSA I remote keyboard";
 
        for (i = 0; i < XLATE_SIZE; i++) {
index 5108b7c576dfba8fab2e5794188a04a0fdf7044e..cd221fd0fb94b89a4c54ac3cc52da09cf7a13dee 100644 (file)
@@ -9,6 +9,7 @@
  *  You need an userspace library to cooperate with this driver. It (and other
  *  info) may be obtained here:
  *  http://www.fi.muni.cz/~xslaby/phantom.html
+ *  or alternatively, you might use OpenHaptics provided by Sensable.
  */
 
 #include <linux/kernel.h>
 #include <asm/atomic.h>
 #include <asm/io.h>
 
-#define PHANTOM_VERSION                "n0.9.5"
+#define PHANTOM_VERSION                "n0.9.7"
 
 #define PHANTOM_MAX_MINORS     8
 
 #define PHN_IRQCTL             0x4c    /* irq control in caddr space */
 
 #define PHB_RUNNING            1
+#define PHB_NOT_OH             2
 
 static struct class *phantom_class;
 static int phantom_major;
@@ -47,7 +49,11 @@ struct phantom_device {
        struct cdev cdev;
 
        struct mutex open_lock;
-       spinlock_t ioctl_lock;
+       spinlock_t regs_lock;
+
+       /* used in NOT_OH mode */
+       struct phm_regs oregs;
+       u32 ctl_reg;
 };
 
 static unsigned char phantom_devices[PHANTOM_MAX_MINORS];
@@ -82,6 +88,7 @@ static long phantom_ioctl(struct file *file, unsigned int cmd,
        struct phm_regs rs;
        struct phm_reg r;
        void __user *argp = (void __user *)arg;
+       unsigned long flags;
        unsigned int i;
 
        if (_IOC_TYPE(cmd) != PH_IOC_MAGIC ||
@@ -96,32 +103,45 @@ static long phantom_ioctl(struct file *file, unsigned int cmd,
                if (r.reg > 7)
                        return -EINVAL;
 
-               spin_lock(&dev->ioctl_lock);
+               spin_lock_irqsave(&dev->regs_lock, flags);
                if (r.reg == PHN_CONTROL && (r.value & PHN_CTL_IRQ) &&
                                phantom_status(dev, dev->status | PHB_RUNNING)){
-                       spin_unlock(&dev->ioctl_lock);
+                       spin_unlock_irqrestore(&dev->regs_lock, flags);
                        return -ENODEV;
                }
 
                pr_debug("phantom: writing %x to %u\n", r.value, r.reg);
+
+               /* preserve amp bit (don't allow to change it when in NOT_OH) */
+               if (r.reg == PHN_CONTROL && (dev->status & PHB_NOT_OH)) {
+                       r.value &= ~PHN_CTL_AMP;
+                       r.value |= dev->ctl_reg & PHN_CTL_AMP;
+                       dev->ctl_reg = r.value;
+               }
+
                iowrite32(r.value, dev->iaddr + r.reg);
                ioread32(dev->iaddr); /* PCI posting */
 
                if (r.reg == PHN_CONTROL && !(r.value & PHN_CTL_IRQ))
                        phantom_status(dev, dev->status & ~PHB_RUNNING);
-               spin_unlock(&dev->ioctl_lock);
+               spin_unlock_irqrestore(&dev->regs_lock, flags);
                break;
        case PHN_SET_REGS:
                if (copy_from_user(&rs, argp, sizeof(rs)))
                        return -EFAULT;
 
                pr_debug("phantom: SRS %u regs %x\n", rs.count, rs.mask);
-               spin_lock(&dev->ioctl_lock);
-               for (i = 0; i < min(rs.count, 8U); i++)
-                       if ((1 << i) & rs.mask)
-                               iowrite32(rs.values[i], dev->oaddr + i);
-               ioread32(dev->iaddr); /* PCI posting */
-               spin_unlock(&dev->ioctl_lock);
+               spin_lock_irqsave(&dev->regs_lock, flags);
+               if (dev->status & PHB_NOT_OH)
+                       memcpy(&dev->oregs, &rs, sizeof(rs));
+               else {
+                       u32 m = min(rs.count, 8U);
+                       for (i = 0; i < m; i++)
+                               if (rs.mask & BIT(i))
+                                       iowrite32(rs.values[i], dev->oaddr + i);
+                       ioread32(dev->iaddr); /* PCI posting */
+               }
+               spin_unlock_irqrestore(&dev->regs_lock, flags);
                break;
        case PHN_GET_REG:
                if (copy_from_user(&r, argp, sizeof(r)))
@@ -135,20 +155,35 @@ static long phantom_ioctl(struct file *file, unsigned int cmd,
                if (copy_to_user(argp, &r, sizeof(r)))
                        return -EFAULT;
                break;
-       case PHN_GET_REGS:
+       case PHN_GET_REGS: {
+               u32 m;
+
                if (copy_from_user(&rs, argp, sizeof(rs)))
                        return -EFAULT;
 
+               m = min(rs.count, 8U);
+
                pr_debug("phantom: GRS %u regs %x\n", rs.count, rs.mask);
-               spin_lock(&dev->ioctl_lock);
-               for (i = 0; i < min(rs.count, 8U); i++)
-                       if ((1 << i) & rs.mask)
+               spin_lock_irqsave(&dev->regs_lock, flags);
+               for (i = 0; i < m; i++)
+                       if (rs.mask & BIT(i))
                                rs.values[i] = ioread32(dev->iaddr + i);
-               spin_unlock(&dev->ioctl_lock);
+               spin_unlock_irqrestore(&dev->regs_lock, flags);
 
                if (copy_to_user(argp, &rs, sizeof(rs)))
                        return -EFAULT;
                break;
+       } case PHN_NOT_OH:
+               spin_lock_irqsave(&dev->regs_lock, flags);
+               if (dev->status & PHB_RUNNING) {
+                       printk(KERN_ERR "phantom: you need to set NOT_OH "
+                                       "before you start the device!\n");
+                       spin_unlock_irqrestore(&dev->regs_lock, flags);
+                       return -EINVAL;
+               }
+               dev->status |= PHB_NOT_OH;
+               spin_unlock_irqrestore(&dev->regs_lock, flags);
+               break;
        default:
                return -ENOTTY;
        }
@@ -171,8 +206,11 @@ static int phantom_open(struct inode *inode, struct file *file)
                return -EINVAL;
        }
 
+       WARN_ON(dev->status & PHB_NOT_OH);
+
        file->private_data = dev;
 
+       atomic_set(&dev->counter, 0);
        dev->opened++;
        mutex_unlock(&dev->open_lock);
 
@@ -187,6 +225,7 @@ static int phantom_release(struct inode *inode, struct file *file)
 
        dev->opened = 0;
        phantom_status(dev, dev->status & ~PHB_RUNNING);
+       dev->status &= ~PHB_NOT_OH;
 
        mutex_unlock(&dev->open_lock);
 
@@ -220,12 +259,32 @@ static struct file_operations phantom_file_ops = {
 static irqreturn_t phantom_isr(int irq, void *data)
 {
        struct phantom_device *dev = data;
+       unsigned int i;
+       u32 ctl;
 
-       if (!(ioread32(dev->iaddr + PHN_CONTROL) & PHN_CTL_IRQ))
+       spin_lock(&dev->regs_lock);
+       ctl = ioread32(dev->iaddr + PHN_CONTROL);
+       if (!(ctl & PHN_CTL_IRQ)) {
+               spin_unlock(&dev->regs_lock);
                return IRQ_NONE;
+       }
 
        iowrite32(0, dev->iaddr);
        iowrite32(0xc0, dev->iaddr);
+
+       if (dev->status & PHB_NOT_OH) {
+               struct phm_regs *r = &dev->oregs;
+               u32 m = min(r->count, 8U);
+
+               for (i = 0; i < m; i++)
+                       if (r->mask & BIT(i))
+                               iowrite32(r->values[i], dev->oaddr + i);
+
+               dev->ctl_reg ^= PHN_CTL_AMP;
+               iowrite32(dev->ctl_reg, dev->iaddr + PHN_CONTROL);
+       }
+       spin_unlock(&dev->regs_lock);
+
        ioread32(dev->iaddr); /* PCI posting */
 
        atomic_inc(&dev->counter);
@@ -297,7 +356,7 @@ static int __devinit phantom_probe(struct pci_dev *pdev,
        }
 
        mutex_init(&pht->open_lock);
-       spin_lock_init(&pht->ioctl_lock);
+       spin_lock_init(&pht->regs_lock);
        init_waitqueue_head(&pht->wait);
        cdev_init(&pht->cdev, &phantom_file_ops);
        pht->cdev.owner = THIS_MODULE;
@@ -378,6 +437,8 @@ static int phantom_suspend(struct pci_dev *pdev, pm_message_t state)
        iowrite32(0, dev->caddr + PHN_IRQCTL);
        ioread32(dev->caddr + PHN_IRQCTL); /* PCI posting */
 
+       synchronize_irq(pdev->irq);
+
        return 0;
 }
 
index e73a71f04bb41b26d10b31e4608f8e33adf8ddc6..bb13858f60a135fd71a06525ade38c8e8cd227ed 100644 (file)
@@ -14,7 +14,7 @@
  *
  * Copyright (C) 2005 Narayanan R S <nars@kadamba.org>
  *
- * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
+ * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
  *
  * Copyright (C) 2001 Michael Ashley <m.ashley@unsw.edu.au>
  *
@@ -277,7 +277,7 @@ static void do_sony_laptop_release_key(struct work_struct *work)
 static DECLARE_WORK(sony_laptop_release_key_work,
                do_sony_laptop_release_key);
 
-/* forward event to the input subsytem */
+/* forward event to the input subsystem */
 static void sony_laptop_report_input_event(u8 event)
 {
        struct input_dev *jog_dev = sony_laptop_input.jog_dev;
@@ -411,9 +411,9 @@ static int sony_laptop_setup_input(void)
        jog_dev->id.bustype = BUS_ISA;
        jog_dev->id.vendor = PCI_VENDOR_ID_SONY;
 
-       jog_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-       jog_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_MIDDLE);
-       jog_dev->relbit[0] = BIT(REL_WHEEL);
+       jog_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+       jog_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_MIDDLE);
+       jog_dev->relbit[0] = BIT_MASK(REL_WHEEL);
 
        error = input_register_device(jog_dev);
        if (error)
@@ -1173,7 +1173,8 @@ static struct acpi_driver sony_nc_driver = {
 #define SONYPI_TYPE3_OFFSET    0x12
 
 struct sony_pic_ioport {
-       struct acpi_resource_io io;
+       struct acpi_resource_io io1;
+       struct acpi_resource_io io2;
        struct list_head        list;
 };
 
@@ -1443,11 +1444,11 @@ static u8 sony_pic_call1(u8 dev)
 {
        u8 v1, v2;
 
-       wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2,
+       wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2,
                        ITERATIONS_LONG);
-       outb(dev, spic_dev.cur_ioport->io.minimum + 4);
-       v1 = inb_p(spic_dev.cur_ioport->io.minimum + 4);
-       v2 = inb_p(spic_dev.cur_ioport->io.minimum);
+       outb(dev, spic_dev.cur_ioport->io1.minimum + 4);
+       v1 = inb_p(spic_dev.cur_ioport->io1.minimum + 4);
+       v2 = inb_p(spic_dev.cur_ioport->io1.minimum);
        dprintk("sony_pic_call1: 0x%.4x\n", (v2 << 8) | v1);
        return v2;
 }
@@ -1456,13 +1457,13 @@ static u8 sony_pic_call2(u8 dev, u8 fn)
 {
        u8 v1;
 
-       wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2,
+       wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2,
                        ITERATIONS_LONG);
-       outb(dev, spic_dev.cur_ioport->io.minimum + 4);
-       wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2,
+       outb(dev, spic_dev.cur_ioport->io1.minimum + 4);
+       wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2,
                        ITERATIONS_LONG);
-       outb(fn, spic_dev.cur_ioport->io.minimum);
-       v1 = inb_p(spic_dev.cur_ioport->io.minimum);
+       outb(fn, spic_dev.cur_ioport->io1.minimum);
+       v1 = inb_p(spic_dev.cur_ioport->io1.minimum);
        dprintk("sony_pic_call2: 0x%.4x\n", v1);
        return v1;
 }
@@ -1471,13 +1472,13 @@ static u8 sony_pic_call3(u8 dev, u8 fn, u8 v)
 {
        u8 v1;
 
-       wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2, ITERATIONS_LONG);
-       outb(dev, spic_dev.cur_ioport->io.minimum + 4);
-       wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2, ITERATIONS_LONG);
-       outb(fn, spic_dev.cur_ioport->io.minimum);
-       wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2, ITERATIONS_LONG);
-       outb(v, spic_dev.cur_ioport->io.minimum);
-       v1 = inb_p(spic_dev.cur_ioport->io.minimum);
+       wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG);
+       outb(dev, spic_dev.cur_ioport->io1.minimum + 4);
+       wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG);
+       outb(fn, spic_dev.cur_ioport->io1.minimum);
+       wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG);
+       outb(v, spic_dev.cur_ioport->io1.minimum);
+       v1 = inb_p(spic_dev.cur_ioport->io1.minimum);
        dprintk("sony_pic_call3: 0x%.4x\n", v1);
        return v1;
 }
@@ -2074,7 +2075,18 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context)
 
        switch (resource->type) {
        case ACPI_RESOURCE_TYPE_START_DEPENDENT:
+               {
+                       /* start IO enumeration */
+                       struct sony_pic_ioport *ioport = kzalloc(sizeof(*ioport), GFP_KERNEL);
+                       if (!ioport)
+                               return AE_ERROR;
+
+                       list_add(&ioport->list, &dev->ioports);
+                       return AE_OK;
+               }
+
        case ACPI_RESOURCE_TYPE_END_DEPENDENT:
+               /* end IO enumeration */
                return AE_OK;
 
        case ACPI_RESOURCE_TYPE_IRQ:
@@ -2101,7 +2113,7 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context)
                                if (!interrupt)
                                        return AE_ERROR;
 
-                               list_add_tail(&interrupt->list, &dev->interrupts);
+                               list_add(&interrupt->list, &dev->interrupts);
                                interrupt->irq.triggering = p->triggering;
                                interrupt->irq.polarity = p->polarity;
                                interrupt->irq.sharable = p->sharable;
@@ -2113,18 +2125,27 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context)
        case ACPI_RESOURCE_TYPE_IO:
                {
                        struct acpi_resource_io *io = &resource->data.io;
-                       struct sony_pic_ioport *ioport = NULL;
+                       struct sony_pic_ioport *ioport =
+                               list_first_entry(&dev->ioports, struct sony_pic_ioport, list);
                        if (!io) {
                                dprintk("Blank IO resource\n");
                                return AE_OK;
                        }
 
-                       ioport = kzalloc(sizeof(*ioport), GFP_KERNEL);
-                       if (!ioport)
+                       if (!ioport->io1.minimum) {
+                               memcpy(&ioport->io1, io, sizeof(*io));
+                               dprintk("IO1 at 0x%.4x (0x%.2x)\n", ioport->io1.minimum,
+                                               ioport->io1.address_length);
+                       }
+                       else if (!ioport->io2.minimum) {
+                               memcpy(&ioport->io2, io, sizeof(*io));
+                               dprintk("IO2 at 0x%.4x (0x%.2x)\n", ioport->io2.minimum,
+                                               ioport->io2.address_length);
+                       }
+                       else {
+                               printk(KERN_ERR DRV_PFX "Unknown SPIC Type, more than 2 IO Ports\n");
                                return AE_ERROR;
-
-                       list_add_tail(&ioport->list, &dev->ioports);
-                       memcpy(&ioport->io, io, sizeof(*io));
+                       }
                        return AE_OK;
                }
        default:
@@ -2199,10 +2220,22 @@ static int sony_pic_enable(struct acpi_device *device,
 {
        acpi_status status;
        int result = 0;
+       /* Type 1 resource layout is:
+        *    IO
+        *    IO
+        *    IRQNoFlags
+        *    End
+        *
+        * Type 2 and 3 resource layout is:
+        *    IO
+        *    IRQNoFlags
+        *    End
+        */
        struct {
-               struct acpi_resource io_res;
-               struct acpi_resource irq_res;
-               struct acpi_resource end;
+               struct acpi_resource res1;
+               struct acpi_resource res2;
+               struct acpi_resource res3;
+               struct acpi_resource res4;
        } *resource;
        struct acpi_buffer buffer = { 0, NULL };
 
@@ -2217,21 +2250,49 @@ static int sony_pic_enable(struct acpi_device *device,
        buffer.length = sizeof(*resource) + 1;
        buffer.pointer = resource;
 
-       /* setup io resource */
-       resource->io_res.type = ACPI_RESOURCE_TYPE_IO;
-       resource->io_res.length = sizeof(struct acpi_resource);
-       memcpy(&resource->io_res.data.io, &ioport->io,
-                       sizeof(struct acpi_resource_io));
+       /* setup Type 1 resources */
+       if (spic_dev.model == SONYPI_DEVICE_TYPE1) {
 
-       /* setup irq resource */
-       resource->irq_res.type = ACPI_RESOURCE_TYPE_IRQ;
-       resource->irq_res.length = sizeof(struct acpi_resource);
-       memcpy(&resource->irq_res.data.irq, &irq->irq,
-                       sizeof(struct acpi_resource_irq));
-       /* we requested a shared irq */
-       resource->irq_res.data.irq.sharable = ACPI_SHARED;
+               /* setup io resources */
+               resource->res1.type = ACPI_RESOURCE_TYPE_IO;
+               resource->res1.length = sizeof(struct acpi_resource);
+               memcpy(&resource->res1.data.io, &ioport->io1,
+                               sizeof(struct acpi_resource_io));
 
-       resource->end.type = ACPI_RESOURCE_TYPE_END_TAG;
+               resource->res2.type = ACPI_RESOURCE_TYPE_IO;
+               resource->res2.length = sizeof(struct acpi_resource);
+               memcpy(&resource->res2.data.io, &ioport->io2,
+                               sizeof(struct acpi_resource_io));
+
+               /* setup irq resource */
+               resource->res3.type = ACPI_RESOURCE_TYPE_IRQ;
+               resource->res3.length = sizeof(struct acpi_resource);
+               memcpy(&resource->res3.data.irq, &irq->irq,
+                               sizeof(struct acpi_resource_irq));
+               /* we requested a shared irq */
+               resource->res3.data.irq.sharable = ACPI_SHARED;
+
+               resource->res4.type = ACPI_RESOURCE_TYPE_END_TAG;
+
+       }
+       /* setup Type 2/3 resources */
+       else {
+               /* setup io resource */
+               resource->res1.type = ACPI_RESOURCE_TYPE_IO;
+               resource->res1.length = sizeof(struct acpi_resource);
+               memcpy(&resource->res1.data.io, &ioport->io1,
+                               sizeof(struct acpi_resource_io));
+
+               /* setup irq resource */
+               resource->res2.type = ACPI_RESOURCE_TYPE_IRQ;
+               resource->res2.length = sizeof(struct acpi_resource);
+               memcpy(&resource->res2.data.irq, &irq->irq,
+                               sizeof(struct acpi_resource_irq));
+               /* we requested a shared irq */
+               resource->res2.data.irq.sharable = ACPI_SHARED;
+
+               resource->res3.type = ACPI_RESOURCE_TYPE_END_TAG;
+       }
 
        /* Attempt to set the resource */
        dprintk("Evaluating _SRS\n");
@@ -2239,7 +2300,7 @@ static int sony_pic_enable(struct acpi_device *device,
 
        /* check for total failure */
        if (ACPI_FAILURE(status)) {
-               printk(KERN_ERR DRV_PFX "Error evaluating _SRS");
+               printk(KERN_ERR DRV_PFX "Error evaluating _SRS\n");
                result = -ENODEV;
                goto end;
        }
@@ -2268,11 +2329,14 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id)
 
        struct sony_pic_dev *dev = (struct sony_pic_dev *) dev_id;
 
-       ev = inb_p(dev->cur_ioport->io.minimum);
-       data_mask = inb_p(dev->cur_ioport->io.minimum + dev->evport_offset);
+       ev = inb_p(dev->cur_ioport->io1.minimum);
+       if (dev->cur_ioport->io2.minimum)
+               data_mask = inb_p(dev->cur_ioport->io2.minimum);
+       else
+               data_mask = inb_p(dev->cur_ioport->io1.minimum + dev->evport_offset);
 
        dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n",
-                       ev, data_mask, dev->cur_ioport->io.minimum, dev->evport_offset);
+                       ev, data_mask, dev->cur_ioport->io1.minimum, dev->evport_offset);
 
        if (ev == 0x00 || ev == 0xff)
                return IRQ_HANDLED;
@@ -2323,8 +2387,11 @@ static int sony_pic_remove(struct acpi_device *device, int type)
        }
 
        free_irq(spic_dev.cur_irq->irq.interrupts[0], &spic_dev);
-       release_region(spic_dev.cur_ioport->io.minimum,
-                       spic_dev.cur_ioport->io.address_length);
+       release_region(spic_dev.cur_ioport->io1.minimum,
+                       spic_dev.cur_ioport->io1.address_length);
+       if (spic_dev.cur_ioport->io2.minimum)
+               release_region(spic_dev.cur_ioport->io2.minimum,
+                               spic_dev.cur_ioport->io2.address_length);
 
        sonypi_compat_exit();
 
@@ -2397,14 +2464,36 @@ static int sony_pic_add(struct acpi_device *device)
                goto err_remove_input;
 
        /* request io port */
-       list_for_each_entry(io, &spic_dev.ioports, list) {
-               if (request_region(io->io.minimum, io->io.address_length,
+       list_for_each_entry_reverse(io, &spic_dev.ioports, list) {
+               if (request_region(io->io1.minimum, io->io1.address_length,
                                        "Sony Programable I/O Device")) {
-                       dprintk("I/O port: 0x%.4x (0x%.4x) + 0x%.2x\n",
-                                       io->io.minimum, io->io.maximum,
-                                       io->io.address_length);
-                       spic_dev.cur_ioport = io;
-                       break;
+                       dprintk("I/O port1: 0x%.4x (0x%.4x) + 0x%.2x\n",
+                                       io->io1.minimum, io->io1.maximum,
+                                       io->io1.address_length);
+                       /* Type 1 have 2 ioports */
+                       if (io->io2.minimum) {
+                               if (request_region(io->io2.minimum,
+                                               io->io2.address_length,
+                                               "Sony Programable I/O Device")) {
+                                       dprintk("I/O port2: 0x%.4x (0x%.4x) + 0x%.2x\n",
+                                                       io->io2.minimum, io->io2.maximum,
+                                                       io->io2.address_length);
+                                       spic_dev.cur_ioport = io;
+                                       break;
+                               }
+                               else {
+                                       dprintk("Unable to get I/O port2: "
+                                                       "0x%.4x (0x%.4x) + 0x%.2x\n",
+                                                       io->io2.minimum, io->io2.maximum,
+                                                       io->io2.address_length);
+                                       release_region(io->io1.minimum,
+                                                       io->io1.address_length);
+                               }
+                       }
+                       else {
+                               spic_dev.cur_ioport = io;
+                               break;
+                       }
                }
        }
        if (!spic_dev.cur_ioport) {
@@ -2414,7 +2503,7 @@ static int sony_pic_add(struct acpi_device *device)
        }
 
        /* request IRQ */
-       list_for_each_entry(irq, &spic_dev.interrupts, list) {
+       list_for_each_entry_reverse(irq, &spic_dev.interrupts, list) {
                if (!request_irq(irq->irq.interrupts[0], sony_pic_irq,
                                        IRQF_SHARED, "sony-laptop", &spic_dev)) {
                        dprintk("IRQ: %d - triggering: %d - "
@@ -2462,8 +2551,11 @@ err_free_irq:
        free_irq(spic_dev.cur_irq->irq.interrupts[0], &spic_dev);
 
 err_release_region:
-       release_region(spic_dev.cur_ioport->io.minimum,
-                       spic_dev.cur_ioport->io.address_length);
+       release_region(spic_dev.cur_ioport->io1.minimum,
+                       spic_dev.cur_ioport->io1.address_length);
+       if (spic_dev.cur_ioport->io2.minimum)
+               release_region(spic_dev.cur_ioport->io2.minimum,
+                               spic_dev.cur_ioport->io2.address_length);
 
 err_remove_compat:
        sonypi_compat_exit();
index 81e068fa7ac5f33c6466b28e66770dc72ff7a920..e953276664a0f77aef6a0a997452488d75a294c3 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 #define IBM_VERSION "0.16"
-#define TPACPI_SYSFS_VERSION 0x010000
+#define TPACPI_SYSFS_VERSION 0x020000
 
 /*
  *  Changelog:
@@ -117,6 +117,12 @@ IBM_BIOS_MODULE_ALIAS("K[U,X-Z]");
 
 #define __unused __attribute__ ((unused))
 
+static enum {
+       TPACPI_LIFE_INIT = 0,
+       TPACPI_LIFE_RUNNING,
+       TPACPI_LIFE_EXITING,
+} tpacpi_lifecycle;
+
 /****************************************************************************
  ****************************************************************************
  *
@@ -342,6 +348,9 @@ static void dispatch_acpi_notify(acpi_handle handle, u32 event, void *data)
 {
        struct ibm_struct *ibm = data;
 
+       if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING)
+               return;
+
        if (!ibm || !ibm->acpi || !ibm->acpi->notify)
                return;
 
@@ -517,8 +526,10 @@ static char *next_cmd(char **cmds)
  ****************************************************************************/
 
 static struct platform_device *tpacpi_pdev;
+static struct platform_device *tpacpi_sensors_pdev;
 static struct device *tpacpi_hwmon;
 static struct input_dev *tpacpi_inputdev;
+static struct mutex tpacpi_inputdev_send_mutex;
 
 
 static int tpacpi_resume_handler(struct platform_device *pdev)
@@ -543,6 +554,12 @@ static struct platform_driver tpacpi_pdriver = {
        .resume = tpacpi_resume_handler,
 };
 
+static struct platform_driver tpacpi_hwmon_pdriver = {
+       .driver = {
+               .name = IBM_HWMON_DRVR_NAME,
+               .owner = THIS_MODULE,
+       },
+};
 
 /*************************************************************************
  * thinkpad-acpi driver attributes
@@ -692,6 +709,8 @@ static int parse_strtoul(const char *buf,
 {
        char *endp;
 
+       while (*buf && isspace(*buf))
+               buf++;
        *value = simple_strtoul(buf, &endp, 0);
        while (*endp && isspace(*endp))
                endp++;
@@ -989,6 +1008,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
 
        int res, i;
        int status;
+       int hkeyv;
 
        vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n");
 
@@ -1014,18 +1034,35 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
                        return res;
 
                /* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
-                  A30, R30, R31, T20-22, X20-21, X22-24 */
-               tp_features.hotkey_mask =
-                       acpi_evalf(hkey_handle, NULL, "DHKN", "qv");
+                  A30, R30, R31, T20-22, X20-21, X22-24.  Detected by checking
+                  for HKEY interface version 0x100 */
+               if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) {
+                       if ((hkeyv >> 8) != 1) {
+                               printk(IBM_ERR "unknown version of the "
+                                      "HKEY interface: 0x%x\n", hkeyv);
+                               printk(IBM_ERR "please report this to %s\n",
+                                      IBM_MAIL);
+                       } else {
+                               /*
+                                * MHKV 0x100 in A31, R40, R40e,
+                                * T4x, X31, and later
+                                * */
+                               tp_features.hotkey_mask = 1;
+                       }
+               }
 
                vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n",
                        str_supported(tp_features.hotkey_mask));
 
                if (tp_features.hotkey_mask) {
-                       /* MHKA available in A31, R40, R40e, T4x, X31, and later */
                        if (!acpi_evalf(hkey_handle, &hotkey_all_mask,
-                                       "MHKA", "qd"))
+                                       "MHKA", "qd")) {
+                               printk(IBM_ERR
+                                      "missing MHKA handler, "
+                                      "please report this to %s\n",
+                                      IBM_MAIL);
                                hotkey_all_mask = 0x080cU; /* FN+F12, FN+F4, FN+F3 */
+                       }
                }
 
                res = hotkey_get(&hotkey_orig_status, &hotkey_orig_mask);
@@ -1131,6 +1168,8 @@ static void tpacpi_input_send_key(unsigned int scancode,
                                  unsigned int keycode)
 {
        if (keycode != KEY_RESERVED) {
+               mutex_lock(&tpacpi_inputdev_send_mutex);
+
                input_report_key(tpacpi_inputdev, keycode, 1);
                if (keycode == KEY_UNKNOWN)
                        input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN,
@@ -1142,6 +1181,8 @@ static void tpacpi_input_send_key(unsigned int scancode,
                        input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN,
                                    scancode);
                input_sync(tpacpi_inputdev);
+
+               mutex_unlock(&tpacpi_inputdev_send_mutex);
        }
 }
 
@@ -1149,18 +1190,47 @@ static void tpacpi_input_send_radiosw(void)
 {
        int wlsw;
 
-       if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw))
+       mutex_lock(&tpacpi_inputdev_send_mutex);
+
+       if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw)) {
                input_report_switch(tpacpi_inputdev,
                                    SW_RADIO, !!wlsw);
+               input_sync(tpacpi_inputdev);
+       }
+
+       mutex_unlock(&tpacpi_inputdev_send_mutex);
 }
 
 static void hotkey_notify(struct ibm_struct *ibm, u32 event)
 {
        u32 hkey;
        unsigned int keycode, scancode;
-       int send_acpi_ev = 0;
+       int send_acpi_ev;
+       int ignore_acpi_ev;
+
+       if (event != 0x80) {
+               printk(IBM_ERR "unknown HKEY notification event %d\n", event);
+               /* forward it to userspace, maybe it knows how to handle it */
+               acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
+                                               ibm->acpi->device->dev.bus_id,
+                                               event, 0);
+               return;
+       }
+
+       while (1) {
+               if (!acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) {
+                       printk(IBM_ERR "failed to retrieve HKEY event\n");
+                       return;
+               }
+
+               if (hkey == 0) {
+                       /* queue empty */
+                       return;
+               }
+
+               send_acpi_ev = 0;
+               ignore_acpi_ev = 0;
 
-       if (event == 0x80 && acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) {
                switch (hkey >> 12) {
                case 1:
                        /* 0x1000-0x1FFF: key presses */
@@ -1182,9 +1252,11 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
                         * eat up known LID events */
                        if (hkey != 0x5001 && hkey != 0x5002) {
                                printk(IBM_ERR
-                                       "unknown LID-related hotkey event: 0x%04x\n",
-                                       hkey);
+                                      "unknown LID-related HKEY event: 0x%04x\n",
+                                      hkey);
                                send_acpi_ev = 1;
+                       } else {
+                               ignore_acpi_ev = 1;
                        }
                        break;
                case 7:
@@ -1202,21 +1274,18 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
                        printk(IBM_NOTICE "unhandled HKEY event 0x%04x\n", hkey);
                        send_acpi_ev = 1;
                }
-       } else {
-               printk(IBM_ERR "unknown hotkey notification event %d\n", event);
-               hkey = 0;
-               send_acpi_ev = 1;
-       }
 
-       /* Legacy events */
-       if (send_acpi_ev || hotkey_report_mode < 2)
-               acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey);
+               /* Legacy events */
+               if (!ignore_acpi_ev && (send_acpi_ev || hotkey_report_mode < 2)) {
+                       acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey);
+               }
 
-       /* netlink events */
-       if (send_acpi_ev) {
-               acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
-                                               ibm->acpi->device->dev.bus_id,
-                                               event, hkey);
+               /* netlink events */
+               if (!ignore_acpi_ev && send_acpi_ev) {
+                       acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
+                                                       ibm->acpi->device->dev.bus_id,
+                                                       event, hkey);
+               }
        }
 }
 
@@ -2812,7 +2881,7 @@ static int __init thermal_init(struct ibm_init_struct *iibm)
 
        switch(thermal_read_mode) {
        case TPACPI_THERMAL_TPEC_16:
-               res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
+               res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
                                &thermal_temp_input16_group);
                if (res)
                        return res;
@@ -2820,7 +2889,7 @@ static int __init thermal_init(struct ibm_init_struct *iibm)
        case TPACPI_THERMAL_TPEC_8:
        case TPACPI_THERMAL_ACPI_TMP07:
        case TPACPI_THERMAL_ACPI_UPDT:
-               res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
+               res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
                                &thermal_temp_input8_group);
                if (res)
                        return res;
@@ -2837,13 +2906,13 @@ static void thermal_exit(void)
 {
        switch(thermal_read_mode) {
        case TPACPI_THERMAL_TPEC_16:
-               sysfs_remove_group(&tpacpi_pdev->dev.kobj,
+               sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj,
                                   &thermal_temp_input16_group);
                break;
        case TPACPI_THERMAL_TPEC_8:
        case TPACPI_THERMAL_ACPI_TMP07:
        case TPACPI_THERMAL_ACPI_UPDT:
-               sysfs_remove_group(&tpacpi_pdev->dev.kobj,
+               sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj,
                                   &thermal_temp_input16_group);
                break;
        case TPACPI_THERMAL_NONE:
@@ -3626,7 +3695,7 @@ static struct device_attribute dev_attr_fan_fan1_input =
        __ATTR(fan1_input, S_IRUGO,
                fan_fan1_input_show, NULL);
 
-/* sysfs fan fan_watchdog (driver) ------------------------------------- */
+/* sysfs fan fan_watchdog (hwmon driver) ------------------------------- */
 static ssize_t fan_fan_watchdog_show(struct device_driver *drv,
                                     char *buf)
 {
@@ -3768,10 +3837,10 @@ static int __init fan_init(struct ibm_init_struct *iibm)
 
        if (fan_status_access_mode != TPACPI_FAN_NONE ||
            fan_control_access_mode != TPACPI_FAN_WR_NONE) {
-               rc = sysfs_create_group(&tpacpi_pdev->dev.kobj,
+               rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
                                         &fan_attr_group);
                if (!(rc < 0))
-                       rc = driver_create_file(&tpacpi_pdriver.driver,
+                       rc = driver_create_file(&tpacpi_hwmon_pdriver.driver,
                                        &driver_attr_fan_watchdog);
                if (rc < 0)
                        return rc;
@@ -3854,8 +3923,8 @@ static void fan_exit(void)
        vdbg_printk(TPACPI_DBG_EXIT, "cancelling any pending fan watchdog tasks\n");
 
        /* FIXME: can we really do this unconditionally? */
-       sysfs_remove_group(&tpacpi_pdev->dev.kobj, &fan_attr_group);
-       driver_remove_file(&tpacpi_pdriver.driver, &driver_attr_fan_watchdog);
+       sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, &fan_attr_group);
+       driver_remove_file(&tpacpi_hwmon_pdriver.driver, &driver_attr_fan_watchdog);
 
        cancel_delayed_work(&fan_watchdog_task);
        flush_scheduled_work();
@@ -3888,6 +3957,9 @@ static void fan_watchdog_fire(struct work_struct *ignored)
 {
        int rc;
 
+       if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING)
+               return;
+
        printk(IBM_NOTICE "fan watchdog: enabling fan\n");
        rc = fan_set_enable();
        if (rc < 0) {
@@ -3908,7 +3980,8 @@ static void fan_watchdog_reset(void)
        if (fan_watchdog_active)
                cancel_delayed_work(&fan_watchdog_task);
 
-       if (fan_watchdog_maxinterval > 0) {
+       if (fan_watchdog_maxinterval > 0 &&
+           tpacpi_lifecycle != TPACPI_LIFE_EXITING) {
                fan_watchdog_active = 1;
                if (!schedule_delayed_work(&fan_watchdog_task,
                                msecs_to_jiffies(fan_watchdog_maxinterval
@@ -4302,6 +4375,19 @@ static struct ibm_struct fan_driver_data = {
  ****************************************************************************
  ****************************************************************************/
 
+/* sysfs name ---------------------------------------------------------- */
+static ssize_t thinkpad_acpi_pdev_name_show(struct device *dev,
+                          struct device_attribute *attr,
+                          char *buf)
+{
+       return snprintf(buf, PAGE_SIZE, "%s\n", IBM_NAME);
+}
+
+static struct device_attribute dev_attr_thinkpad_acpi_pdev_name =
+       __ATTR(name, S_IRUGO, thinkpad_acpi_pdev_name_show, NULL);
+
+/* --------------------------------------------------------------------- */
+
 /* /proc support */
 static struct proc_dir_entry *proc_dir;
 
@@ -4674,6 +4760,8 @@ static int __init thinkpad_acpi_module_init(void)
 {
        int ret, i;
 
+       tpacpi_lifecycle = TPACPI_LIFE_INIT;
+
        /* Parameter checking */
        if (hotkey_report_mode > 2)
                return -EINVAL;
@@ -4702,19 +4790,31 @@ static int __init thinkpad_acpi_module_init(void)
 
        ret = platform_driver_register(&tpacpi_pdriver);
        if (ret) {
-               printk(IBM_ERR "unable to register platform driver\n");
+               printk(IBM_ERR "unable to register main platform driver\n");
                thinkpad_acpi_module_exit();
                return ret;
        }
        tp_features.platform_drv_registered = 1;
 
+       ret = platform_driver_register(&tpacpi_hwmon_pdriver);
+       if (ret) {
+               printk(IBM_ERR "unable to register hwmon platform driver\n");
+               thinkpad_acpi_module_exit();
+               return ret;
+       }
+       tp_features.sensors_pdrv_registered = 1;
+
        ret = tpacpi_create_driver_attributes(&tpacpi_pdriver.driver);
+       if (!ret) {
+               tp_features.platform_drv_attrs_registered = 1;
+               ret = tpacpi_create_driver_attributes(&tpacpi_hwmon_pdriver.driver);
+       }
        if (ret) {
                printk(IBM_ERR "unable to create sysfs driver attributes\n");
                thinkpad_acpi_module_exit();
                return ret;
        }
-       tp_features.platform_drv_attrs_registered = 1;
+       tp_features.sensors_pdrv_attrs_registered = 1;
 
 
        /* Device initialization */
@@ -4727,7 +4827,26 @@ static int __init thinkpad_acpi_module_init(void)
                thinkpad_acpi_module_exit();
                return ret;
        }
-       tpacpi_hwmon = hwmon_device_register(&tpacpi_pdev->dev);
+       tpacpi_sensors_pdev = platform_device_register_simple(
+                                                       IBM_HWMON_DRVR_NAME,
+                                                       -1, NULL, 0);
+       if (IS_ERR(tpacpi_sensors_pdev)) {
+               ret = PTR_ERR(tpacpi_sensors_pdev);
+               tpacpi_sensors_pdev = NULL;
+               printk(IBM_ERR "unable to register hwmon platform device\n");
+               thinkpad_acpi_module_exit();
+               return ret;
+       }
+       ret = device_create_file(&tpacpi_sensors_pdev->dev,
+                                &dev_attr_thinkpad_acpi_pdev_name);
+       if (ret) {
+               printk(IBM_ERR
+                       "unable to create sysfs hwmon device attributes\n");
+               thinkpad_acpi_module_exit();
+               return ret;
+       }
+       tp_features.sensors_pdev_attrs_registered = 1;
+       tpacpi_hwmon = hwmon_device_register(&tpacpi_sensors_pdev->dev);
        if (IS_ERR(tpacpi_hwmon)) {
                ret = PTR_ERR(tpacpi_hwmon);
                tpacpi_hwmon = NULL;
@@ -4735,6 +4854,7 @@ static int __init thinkpad_acpi_module_init(void)
                thinkpad_acpi_module_exit();
                return ret;
        }
+       mutex_init(&tpacpi_inputdev_send_mutex);
        tpacpi_inputdev = input_allocate_device();
        if (!tpacpi_inputdev) {
                printk(IBM_ERR "unable to allocate input device\n");
@@ -4769,6 +4889,7 @@ static int __init thinkpad_acpi_module_init(void)
                tp_features.input_device_registered = 1;
        }
 
+       tpacpi_lifecycle = TPACPI_LIFE_RUNNING;
        return 0;
 }
 
@@ -4776,6 +4897,8 @@ static void thinkpad_acpi_module_exit(void)
 {
        struct ibm_struct *ibm, *itmp;
 
+       tpacpi_lifecycle = TPACPI_LIFE_EXITING;
+
        list_for_each_entry_safe_reverse(ibm, itmp,
                                         &tpacpi_all_drivers,
                                         all_drivers) {
@@ -4794,12 +4917,22 @@ static void thinkpad_acpi_module_exit(void)
        if (tpacpi_hwmon)
                hwmon_device_unregister(tpacpi_hwmon);
 
+       if (tp_features.sensors_pdev_attrs_registered)
+               device_remove_file(&tpacpi_sensors_pdev->dev,
+                                  &dev_attr_thinkpad_acpi_pdev_name);
+       if (tpacpi_sensors_pdev)
+               platform_device_unregister(tpacpi_sensors_pdev);
        if (tpacpi_pdev)
                platform_device_unregister(tpacpi_pdev);
 
+       if (tp_features.sensors_pdrv_attrs_registered)
+               tpacpi_remove_driver_attributes(&tpacpi_hwmon_pdriver.driver);
        if (tp_features.platform_drv_attrs_registered)
                tpacpi_remove_driver_attributes(&tpacpi_pdriver.driver);
 
+       if (tp_features.sensors_pdrv_registered)
+               platform_driver_unregister(&tpacpi_hwmon_pdriver);
+
        if (tp_features.platform_drv_registered)
                platform_driver_unregister(&tpacpi_pdriver);
 
index acd5835ec889b2181011a28a60206421a4f55e7e..3abcc812063433e664a23df7d5275918d6906351 100644 (file)
 
 #define IBM_NAME "thinkpad"
 #define IBM_DESC "ThinkPad ACPI Extras"
-#define IBM_FILE "thinkpad_acpi"
+#define IBM_FILE IBM_NAME "_acpi"
 #define IBM_URL "http://ibm-acpi.sf.net/"
 #define IBM_MAIL "ibm-acpi-devel@lists.sourceforge.net"
 
 #define IBM_PROC_DIR "ibm"
 #define IBM_ACPI_EVENT_PREFIX "ibm"
 #define IBM_DRVR_NAME IBM_FILE
+#define IBM_HWMON_DRVR_NAME IBM_NAME "_hwmon"
 
 #define IBM_LOG IBM_FILE ": "
 #define IBM_ERR           KERN_ERR    IBM_LOG
@@ -171,6 +172,7 @@ static int parse_strtoul(const char *buf, unsigned long max,
 
 /* Device model */
 static struct platform_device *tpacpi_pdev;
+static struct platform_device *tpacpi_sensors_pdev;
 static struct device *tpacpi_hwmon;
 static struct platform_driver tpacpi_pdriver;
 static struct input_dev *tpacpi_inputdev;
@@ -233,22 +235,25 @@ struct ibm_init_struct {
 
 static struct {
 #ifdef CONFIG_THINKPAD_ACPI_BAY
-       u16 bay_status:1;
-       u16 bay_eject:1;
-       u16 bay_status2:1;
-       u16 bay_eject2:1;
+       u32 bay_status:1;
+       u32 bay_eject:1;
+       u32 bay_status2:1;
+       u32 bay_eject2:1;
 #endif
-       u16 bluetooth:1;
-       u16 hotkey:1;
-       u16 hotkey_mask:1;
-       u16 hotkey_wlsw:1;
-       u16 light:1;
-       u16 light_status:1;
-       u16 wan:1;
-       u16 fan_ctrl_status_undef:1;
-       u16 input_device_registered:1;
-       u16 platform_drv_registered:1;
-       u16 platform_drv_attrs_registered:1;
+       u32 bluetooth:1;
+       u32 hotkey:1;
+       u32 hotkey_mask:1;
+       u32 hotkey_wlsw:1;
+       u32 light:1;
+       u32 light_status:1;
+       u32 wan:1;
+       u32 fan_ctrl_status_undef:1;
+       u32 input_device_registered:1;
+       u32 platform_drv_registered:1;
+       u32 platform_drv_attrs_registered:1;
+       u32 sensors_pdrv_registered:1;
+       u32 sensors_pdrv_attrs_registered:1;
+       u32 sensors_pdev_attrs_registered:1;
 } tp_features;
 
 struct thinkpad_id_data {
index a5d0354bbbda808e45cdd9594f6c45e75f2e7022..9203a0b221b3364b47531f0af4e963e23e17a49d 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/blkdev.h>
 #include <linux/freezer.h>
 #include <linux/kthread.h>
+#include <linux/scatterlist.h>
 
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
@@ -153,19 +154,21 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
                        blk_queue_max_hw_segments(mq->queue, bouncesz / 512);
                        blk_queue_max_segment_size(mq->queue, bouncesz);
 
-                       mq->sg = kzalloc(sizeof(struct scatterlist),
+                       mq->sg = kmalloc(sizeof(struct scatterlist),
                                GFP_KERNEL);
                        if (!mq->sg) {
                                ret = -ENOMEM;
                                goto cleanup_queue;
                        }
+                       sg_init_table(mq->sg, 1);
 
-                       mq->bounce_sg = kzalloc(sizeof(struct scatterlist) *
+                       mq->bounce_sg = kmalloc(sizeof(struct scatterlist) *
                                bouncesz / 512, GFP_KERNEL);
                        if (!mq->bounce_sg) {
                                ret = -ENOMEM;
                                goto cleanup_queue;
                        }
+                       sg_init_table(mq->bounce_sg, bouncesz / 512);
                }
        }
 #endif
@@ -302,12 +305,12 @@ static void copy_sg(struct scatterlist *dst, unsigned int dst_len,
                BUG_ON(dst_len == 0);
 
                if (dst_size == 0) {
-                       dst_buf = page_address(dst->page) + dst->offset;
+                       dst_buf = sg_virt(dst);
                        dst_size = dst->length;
                }
 
                if (src_size == 0) {
-                       src_buf = page_address(src->page) + src->offset;
+                       src_buf = sg_virt(dst);
                        src_size = src->length;
                }
 
@@ -353,9 +356,7 @@ unsigned int mmc_queue_map_sg(struct mmc_queue *mq)
                return 1;
        }
 
-       mq->sg[0].page = virt_to_page(mq->bounce_buf);
-       mq->sg[0].offset = offset_in_page(mq->bounce_buf);
-       mq->sg[0].length = 0;
+       sg_init_one(mq->sg, mq->bounce_buf, 0);
 
        while (sg_len) {
                mq->sg[0].length += mq->bounce_sg[sg_len - 1].length;
index 7a452c2ad1f9ce2207bc78ba9458b6195796f89d..b1edcefdd4f9e7a615e2e38238f4d43e8456a9b4 100644 (file)
@@ -149,7 +149,7 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data
 
                sg = &data->sg[i];
 
-               sgbuffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset;
+               sgbuffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
                amount = min(size, sg->length);
                size -= amount;
 
@@ -226,7 +226,7 @@ static void at91_mci_pre_dma_read(struct at91mci_host *host)
                sg = &data->sg[host->transfer_index++];
                pr_debug("sg = %p\n", sg);
 
-               sg->dma_address = dma_map_page(NULL, sg->page, sg->offset, sg->length, DMA_FROM_DEVICE);
+               sg->dma_address = dma_map_page(NULL, sg_page(sg), sg->offset, sg->length, DMA_FROM_DEVICE);
 
                pr_debug("dma address = %08X, length = %d\n", sg->dma_address, sg->length);
 
@@ -283,7 +283,7 @@ static void at91_mci_post_dma_read(struct at91mci_host *host)
                        int index;
 
                        /* Swap the contents of the buffer */
-                       buffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset;
+                       buffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
                        pr_debug("buffer = %p, length = %d\n", buffer, sg->length);
 
                        for (index = 0; index < (sg->length / 4); index++)
@@ -292,7 +292,7 @@ static void at91_mci_post_dma_read(struct at91mci_host *host)
                        kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
                }
 
-               flush_dcache_page(sg->page);
+               flush_dcache_page(sg_page(sg));
        }
 
        /* Is there another transfer to trigger? */
index 92c4d0dfee434d4d09eb5183314b2a1c3d09d9ed..bcbb6d247bf7ea44b1cdd50000c5fb48800650e8 100644 (file)
@@ -340,7 +340,7 @@ static void au1xmmc_send_pio(struct au1xmmc_host *host)
 
        /* This is the pointer to the data buffer */
        sg = &data->sg[host->pio.index];
-       sg_ptr = page_address(sg->page) + sg->offset + host->pio.offset;
+       sg_ptr = sg_virt(sg) + host->pio.offset;
 
        /* This is the space left inside the buffer */
        sg_len = data->sg[host->pio.index].length - host->pio.offset;
@@ -400,7 +400,7 @@ static void au1xmmc_receive_pio(struct au1xmmc_host *host)
 
        if (host->pio.index < host->dma.len) {
                sg = &data->sg[host->pio.index];
-               sg_ptr = page_address(sg->page) + sg->offset + host->pio.offset;
+               sg_ptr = sg_virt(sg) + host->pio.offset;
 
                /* This is the space left inside the buffer */
                sg_len = sg_dma_len(&data->sg[host->pio.index]) - host->pio.offset;
@@ -613,14 +613,11 @@ au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data)
 
                        if (host->flags & HOST_F_XMIT){
                                ret = au1xxx_dbdma_put_source_flags(channel,
-                                       (void *) (page_address(sg->page) +
-                                                 sg->offset),
-                                       len, flags);
+                                       (void *) sg_virt(sg), len, flags);
                        }
                        else {
                                ret = au1xxx_dbdma_put_dest_flags(channel,
-                                       (void *) (page_address(sg->page) +
-                                                 sg->offset),
+                                       (void *) sg_virt(sg),
                                        len, flags);
                        }
 
index 6ebc41e7592cefd131915f6d82b4aff87aca1496..fc72e1fadb6adf291356e796d16cc3e036d764c5 100644 (file)
@@ -262,7 +262,7 @@ static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data)
                }
 
                /* Convert back to virtual address */
-               host->data_ptr = (u16*)(page_address(data->sg->page) + data->sg->offset);
+               host->data_ptr = (u16*)sg_virt(sg);
                host->data_cnt = 0;
 
                clear_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events);
index 7ae18eaed6c5d869d3e7d89bffd484bbe9798147..12c2d807c145499975068c162803efa3a91b1fdf 100644 (file)
@@ -813,7 +813,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
                                        && dir == DMA_FROM_DEVICE)
                                dir = DMA_BIDIRECTIONAL;
 
-                       dma_addr = dma_map_page(dma_dev, sg->page, 0,
+                       dma_addr = dma_map_page(dma_dev, sg_page(sg), 0,
                                                PAGE_SIZE, dir);
                        if (direction == DMA_TO_DEVICE)
                                t->tx_dma = dma_addr + sg->offset;
@@ -822,7 +822,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
                }
 
                /* allow pio too; we don't allow highmem */
-               kmap_addr = kmap(sg->page);
+               kmap_addr = kmap(sg_page(sg));
                if (direction == DMA_TO_DEVICE)
                        t->tx_buf = kmap_addr + sg->offset;
                else
@@ -855,8 +855,8 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
 
                /* discard mappings */
                if (direction == DMA_FROM_DEVICE)
-                       flush_kernel_dcache_page(sg->page);
-               kunmap(sg->page);
+                       flush_kernel_dcache_page(sg_page(sg));
+               kunmap(sg_page(sg));
                if (dma_dev)
                        dma_unmap_page(dma_dev, dma_addr, PAGE_SIZE, dir);
 
index 000e6a9197828f38a0a69492bb47fa290738d733..0f39c490f022086dc6e8c8cd99c789252ae6ea27 100644 (file)
@@ -169,7 +169,7 @@ static inline char *mmci_kmap_atomic(struct mmci_host *host, unsigned long *flag
        struct scatterlist *sg = host->sg_ptr;
 
        local_irq_save(*flags);
-       return kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset;
+       return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
 }
 
 static inline void mmci_kunmap_atomic(struct mmci_host *host, void *buffer, unsigned long *flags)
index 60a67dfcda6a86a0d786c33799124981f19f49db..971e18b91f4a352c8bcb4e619b7edfcbb596a37e 100644 (file)
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
 #include <linux/clk.h>
+#include <linux/scatterlist.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/scatterlist.h>
 #include <asm/mach-types.h>
 
 #include <asm/arch/board.h>
@@ -383,7 +383,7 @@ mmc_omap_sg_to_buf(struct mmc_omap_host *host)
 
        sg = host->data->sg + host->sg_idx;
        host->buffer_bytes_left = sg->length;
-       host->buffer = page_address(sg->page) + sg->offset;
+       host->buffer = sg_virt(sg);
        if (host->buffer_bytes_left > host->total_bytes_left)
                host->buffer_bytes_left = host->total_bytes_left;
 }
index b397121b947d5acf78b764c06c486a30a8fe1797..d7c5b94d8c583de00136f8c8f2e435347375b497 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/highmem.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
+#include <linux/scatterlist.h>
 
 #include <linux/mmc/host.h>
 
@@ -231,7 +232,7 @@ static void sdhci_deactivate_led(struct sdhci_host *host)
 
 static inline char* sdhci_sg_to_buffer(struct sdhci_host* host)
 {
-       return page_address(host->cur_sg->page) + host->cur_sg->offset;
+       return sg_virt(host->cur_sg);
 }
 
 static inline int sdhci_next_sg(struct sdhci_host* host)
index 9b904795eb77acd5cb887dbbbf96dec51a742339..c11a3d25605141a2f8017e24055984fb2b8d2160 100644 (file)
@@ -192,7 +192,7 @@ static void tifm_sd_transfer_data(struct tifm_sd *host)
                }
                off = sg[host->sg_pos].offset + host->block_pos;
 
-               pg = nth_page(sg[host->sg_pos].page, off >> PAGE_SHIFT);
+               pg = nth_page(sg_page(&sg[host->sg_pos]), off >> PAGE_SHIFT);
                p_off = offset_in_page(off);
                p_cnt = PAGE_SIZE - p_off;
                p_cnt = min(p_cnt, cnt);
@@ -241,18 +241,18 @@ static void tifm_sd_bounce_block(struct tifm_sd *host, struct mmc_data *r_data)
                }
                off = sg[host->sg_pos].offset + host->block_pos;
 
-               pg = nth_page(sg[host->sg_pos].page, off >> PAGE_SHIFT);
+               pg = nth_page(sg_page(&sg[host->sg_pos]), off >> PAGE_SHIFT);
                p_off = offset_in_page(off);
                p_cnt = PAGE_SIZE - p_off;
                p_cnt = min(p_cnt, cnt);
                p_cnt = min(p_cnt, t_size);
 
                if (r_data->flags & MMC_DATA_WRITE)
-                       tifm_sd_copy_page(host->bounce_buf.page,
+                       tifm_sd_copy_page(sg_page(&host->bounce_buf),
                                          r_data->blksz - t_size,
                                          pg, p_off, p_cnt);
                else if (r_data->flags & MMC_DATA_READ)
-                       tifm_sd_copy_page(pg, p_off, host->bounce_buf.page,
+                       tifm_sd_copy_page(pg, p_off, sg_page(&host->bounce_buf),
                                          r_data->blksz - t_size, p_cnt);
 
                t_size -= p_cnt;
index 80db11c05f2a6e91ab155d9036338448dad2f44f..fa4c8c53cc7ab8dd28aa3b83470e6b2468542558 100644 (file)
@@ -269,7 +269,7 @@ static inline int wbsd_next_sg(struct wbsd_host *host)
 
 static inline char *wbsd_sg_to_buffer(struct wbsd_host *host)
 {
-       return page_address(host->cur_sg->page) + host->cur_sg->offset;
+       return sg_virt(host->cur_sg);
 }
 
 static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data)
@@ -283,7 +283,7 @@ static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data)
        len = data->sg_len;
 
        for (i = 0; i < len; i++) {
-               sgbuf = page_address(sg[i].page) + sg[i].offset;
+               sgbuf = sg_virt(&sg[i]);
                memcpy(dmabuf, sgbuf, sg[i].length);
                dmabuf += sg[i].length;
        }
@@ -300,7 +300,7 @@ static inline void wbsd_dma_to_sg(struct wbsd_host *host, struct mmc_data *data)
        len = data->sg_len;
 
        for (i = 0; i < len; i++) {
-               sgbuf = page_address(sg[i].page) + sg[i].offset;
+               sgbuf = sg_virt(&sg[i]);
                memcpy(sgbuf, dmabuf, sg[i].length);
                dmabuf += sg[i].length;
        }
index 3aa3dca56ae6ea8dd16cef96d222905a14516a76..a9eb1c516247ef5b69104682bb20e208877041cd 100644 (file)
@@ -85,6 +85,7 @@ static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len,
 static void cfi_intelext_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from,
                        size_t len);
 
+static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long adr, int mode);
 static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode);
 static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr);
 #include "fwh_lock.h"
@@ -641,73 +642,13 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
 /*
  *  *********** CHIP ACCESS FUNCTIONS ***********
  */
-
-static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
+static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
 {
        DECLARE_WAITQUEUE(wait, current);
        struct cfi_private *cfi = map->fldrv_priv;
        map_word status, status_OK = CMD(0x80), status_PWS = CMD(0x01);
-       unsigned long timeo;
        struct cfi_pri_intelext *cfip = cfi->cmdset_priv;
-
- resettime:
-       timeo = jiffies + HZ;
- retry:
-       if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING || mode == FL_OTP_WRITE || mode == FL_SHUTDOWN)) {
-               /*
-                * OK. We have possibility for contension on the write/erase
-                * operations which are global to the real chip and not per
-                * partition.  So let's fight it over in the partition which
-                * currently has authority on the operation.
-                *
-                * The rules are as follows:
-                *
-                * - any write operation must own shared->writing.
-                *
-                * - any erase operation must own _both_ shared->writing and
-                *   shared->erasing.
-                *
-                * - contension arbitration is handled in the owner's context.
-                *
-                * The 'shared' struct can be read and/or written only when
-                * its lock is taken.
-                */
-               struct flchip_shared *shared = chip->priv;
-               struct flchip *contender;
-               spin_lock(&shared->lock);
-               contender = shared->writing;
-               if (contender && contender != chip) {
-                       /*
-                        * The engine to perform desired operation on this
-                        * partition is already in use by someone else.
-                        * Let's fight over it in the context of the chip
-                        * currently using it.  If it is possible to suspend,
-                        * that other partition will do just that, otherwise
-                        * it'll happily send us to sleep.  In any case, when
-                        * get_chip returns success we're clear to go ahead.
-                        */
-                       int ret = spin_trylock(contender->mutex);
-                       spin_unlock(&shared->lock);
-                       if (!ret)
-                               goto retry;
-                       spin_unlock(chip->mutex);
-                       ret = get_chip(map, contender, contender->start, mode);
-                       spin_lock(chip->mutex);
-                       if (ret) {
-                               spin_unlock(contender->mutex);
-                               return ret;
-                       }
-                       timeo = jiffies + HZ;
-                       spin_lock(&shared->lock);
-                       spin_unlock(contender->mutex);
-               }
-
-               /* We now own it */
-               shared->writing = chip;
-               if (mode == FL_ERASING)
-                       shared->erasing = chip;
-               spin_unlock(&shared->lock);
-       }
+       unsigned long timeo = jiffies + HZ;
 
        switch (chip->state) {
 
@@ -722,16 +663,11 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
                        if (chip->priv && map_word_andequal(map, status, status_PWS, status_PWS))
                                break;
 
-                       if (time_after(jiffies, timeo)) {
-                               printk(KERN_ERR "%s: Waiting for chip to be ready timed out. Status %lx\n",
-                                      map->name, status.x[0]);
-                               return -EIO;
-                       }
                        spin_unlock(chip->mutex);
                        cfi_udelay(1);
                        spin_lock(chip->mutex);
                        /* Someone else might have been playing with it. */
-                       goto retry;
+                       return -EAGAIN;
                }
 
        case FL_READY:
@@ -809,10 +745,82 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
                schedule();
                remove_wait_queue(&chip->wq, &wait);
                spin_lock(chip->mutex);
-               goto resettime;
+               return -EAGAIN;
        }
 }
 
+static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
+{
+       int ret;
+
+ retry:
+       if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING
+                          || mode == FL_OTP_WRITE || mode == FL_SHUTDOWN)) {
+               /*
+                * OK. We have possibility for contention on the write/erase
+                * operations which are global to the real chip and not per
+                * partition.  So let's fight it over in the partition which
+                * currently has authority on the operation.
+                *
+                * The rules are as follows:
+                *
+                * - any write operation must own shared->writing.
+                *
+                * - any erase operation must own _both_ shared->writing and
+                *   shared->erasing.
+                *
+                * - contention arbitration is handled in the owner's context.
+                *
+                * The 'shared' struct can be read and/or written only when
+                * its lock is taken.
+                */
+               struct flchip_shared *shared = chip->priv;
+               struct flchip *contender;
+               spin_lock(&shared->lock);
+               contender = shared->writing;
+               if (contender && contender != chip) {
+                       /*
+                        * The engine to perform desired operation on this
+                        * partition is already in use by someone else.
+                        * Let's fight over it in the context of the chip
+                        * currently using it.  If it is possible to suspend,
+                        * that other partition will do just that, otherwise
+                        * it'll happily send us to sleep.  In any case, when
+                        * get_chip returns success we're clear to go ahead.
+                        */
+                       ret = spin_trylock(contender->mutex);
+                       spin_unlock(&shared->lock);
+                       if (!ret)
+                               goto retry;
+                       spin_unlock(chip->mutex);
+                       ret = chip_ready(map, contender, contender->start, mode);
+                       spin_lock(chip->mutex);
+
+                       if (ret == -EAGAIN) {
+                               spin_unlock(contender->mutex);
+                               goto retry;
+                       }
+                       if (ret) {
+                               spin_unlock(contender->mutex);
+                               return ret;
+                       }
+                       spin_lock(&shared->lock);
+                       spin_unlock(contender->mutex);
+               }
+
+               /* We now own it */
+               shared->writing = chip;
+               if (mode == FL_ERASING)
+                       shared->erasing = chip;
+               spin_unlock(&shared->lock);
+       }
+       ret = chip_ready(map, chip, adr, mode);
+       if (ret == -EAGAIN)
+               goto retry;
+
+       return ret;
+}
+
 static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr)
 {
        struct cfi_private *cfi = map->fldrv_priv;
index 2a2a125b0c760a795be1f77bb8889aa21c381a15..a592fc04cf781455459bbb390227da7f72fdab50 100644 (file)
@@ -54,7 +54,7 @@ config MTD_PHYSMAP_BANKWIDTH
        help
          This is the total width of the data bus of the flash devices
          in octets. For example, if you have a data bus width of 32
-         bits, you would set the bus width octect value to 4. This is
+         bits, you would set the bus width octet value to 4. This is
          used internally by the CFI drivers.
          Ignore this option if you use run-time physmap configuration
          (i.e., run-time calling physmap_configure()).
@@ -73,12 +73,12 @@ config MTD_PMC_MSP_EVM
        depends on PMC_MSP && MTD_CFI
        select MTD_PARTITIONS
        help
-         This provides a 'mapping' driver which support the way
-          in which user-programmable flash chips are connected on the
-          PMC-Sierra MSP eval/demo boards
+         This provides a 'mapping' driver which supports the way
+         in which user-programmable flash chips are connected on the
+         PMC-Sierra MSP eval/demo boards.
 
 choice
-       prompt "Maximum mappable memory avialable for flash IO"
+       prompt "Maximum mappable memory available for flash IO"
        depends on MTD_PMC_MSP_EVM
        default MSP_FLASH_MAP_LIMIT_32M
 
index 8f9c3baeb38e77ec82a17cc10a80a9e036adba35..246d4512f64bfd8670a5731809d1280cd2cbfcaa 100644 (file)
@@ -300,7 +300,7 @@ config MTD_NAND_PLATFORM
          via platform_data.
 
 config MTD_ALAUDA
-       tristate "MTD driver for Olympus MAUSB-10 and Fijufilm DPC-R1"
+       tristate "MTD driver for Olympus MAUSB-10 and Fujifilm DPC-R1"
        depends on MTD_NAND && USB
        help
          These two (and possibly other) Alauda-based cardreaders for
index ab9f5c5db38d35287c249a93b61c23246d249717..0e72153b329736000e4c43abfc76038b725d5959 100644 (file)
@@ -220,7 +220,7 @@ static int doc_ecc_decode(struct rs_control *rs, uint8_t *data, uint8_t *ecc)
                }
        }
        /* If the parity is wrong, no rescue possible */
-       return parity ? -1 : nerr;
+       return parity ? -EBADMSG : nerr;
 }
 
 static void DoC_Delay(struct doc_priv *doc, unsigned short cycles)
@@ -1034,7 +1034,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat,
                WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);
        else
                WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
-       if (no_ecc_failures && (ret == -1)) {
+       if (no_ecc_failures && (ret == -EBADMSG)) {
                printk(KERN_ERR "suppressing ECC failure\n");
                ret = 0;
        }
index b4e0e7723894749a42752dd0fe26db91bae4743c..e29c1da7f56e82530a987beb96ab84a735a2b637 100644 (file)
@@ -789,7 +789,7 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
                int stat;
 
                stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
-               if (stat == -1)
+               if (stat < 0)
                        mtd->ecc_stats.failed++;
                else
                        mtd->ecc_stats.corrected += stat;
@@ -833,7 +833,7 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
                int stat;
 
                stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
-               if (stat == -1)
+               if (stat < 0)
                        mtd->ecc_stats.failed++;
                else
                        mtd->ecc_stats.corrected += stat;
@@ -874,7 +874,7 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
                chip->read_buf(mtd, oob, eccbytes);
                stat = chip->ecc.correct(mtd, p, oob, NULL);
 
-               if (stat == -1)
+               if (stat < 0)
                        mtd->ecc_stats.failed++;
                else
                        mtd->ecc_stats.corrected += stat;
index fde593e5e634b7ecf564d2f3f04ba5d6c5294636..9003a135e0502089f6a8e44f77f26b129a849375 100644 (file)
@@ -189,7 +189,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat,
        if(countbits(s0 | ((uint32_t)s1 << 8) | ((uint32_t)s2 <<16)) == 1)
                return 1;
 
-       return -1;
+       return -EBADMSG;
 }
 EXPORT_SYMBOL(nand_correct_data);
 
index a7574807dc46a1e2c6ac5697cb1c253cffca8087..10490b48d9f75844c81a00dc8f32825475345afc 100644 (file)
@@ -511,7 +511,7 @@ static int init_nandsim(struct mtd_info *mtd)
        }
 
        if (ns->options & OPT_SMALLPAGE) {
-               if (ns->geom.totsz < (64 << 20)) {
+               if (ns->geom.totsz < (32 << 20)) {
                        ns->geom.pgaddrbytes  = 3;
                        ns->geom.secaddrbytes = 2;
                } else {
index b79a9cf2d162bfe775e02262de401a9429a786ce..66f76e9618ddd9005edcb60faf2b66ea2ec539b2 100644 (file)
@@ -488,12 +488,24 @@ static void s3c2410_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
        readsb(this->IO_ADDR_R, buf, len);
 }
 
+static void s3c2440_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
+{
+       struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
+       readsl(info->regs + S3C2440_NFDATA, buf, len / 4);
+}
+
 static void s3c2410_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
 {
        struct nand_chip *this = mtd->priv;
        writesb(this->IO_ADDR_W, buf, len);
 }
 
+static void s3c2440_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
+{
+       struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
+       writesl(info->regs + S3C2440_NFDATA, buf, len / 4);
+}
+
 /* device management functions */
 
 static int s3c2410_nand_remove(struct platform_device *pdev)
@@ -604,6 +616,8 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
                info->sel_bit   = S3C2440_NFCONT_nFCE;
                chip->cmd_ctrl  = s3c2440_nand_hwcontrol;
                chip->dev_ready = s3c2440_nand_devready;
+               chip->read_buf  = s3c2440_nand_read_buf;
+               chip->write_buf = s3c2440_nand_write_buf;
                break;
 
        case TYPE_S3C2412:
@@ -696,7 +710,7 @@ static int s3c24xx_nand_probe(struct platform_device *pdev,
 
        info->clk = clk_get(&pdev->dev, "nand");
        if (IS_ERR(info->clk)) {
-               dev_err(&pdev->dev, "failed to get clock");
+               dev_err(&pdev->dev, "failed to get clock\n");
                err = -ENOENT;
                goto exit_error;
        }
index 0d89ad5776fa1e8cd10c79aa92a2edeac468711f..d64200b7c94bfd4c0caf5dc782ba2146d0f584f9 100644 (file)
@@ -88,11 +88,11 @@ do {                                                                        \
 
 /**
  * onenand_lock_handle - Handle Lock scheme
- * @param this         OneNAND device structure
- * @param cmd          The command to be sent
+ * @this:              OneNAND device structure
+ * @cmd:               The command to be sent
  *
  * Send lock command to OneNAND device.
- * The lock scheme is depends on chip type.
+ * The lock scheme depends on chip type.
  */
 static void onenand_lock_handle(struct onenand_chip *this, int cmd)
 {
@@ -131,8 +131,8 @@ static void onenand_lock_handle(struct onenand_chip *this, int cmd)
 
 /**
  * onenand_bootram_handle - Handle BootRAM area
- * @param this         OneNAND device structure
- * @param cmd          The command to be sent
+ * @this:              OneNAND device structure
+ * @cmd:               The command to be sent
  *
  * Emulate BootRAM area. It is possible to do basic operation using BootRAM.
  */
@@ -153,10 +153,10 @@ static void onenand_bootram_handle(struct onenand_chip *this, int cmd)
 
 /**
  * onenand_update_interrupt - Set interrupt register
- * @param this         OneNAND device structure
- * @param cmd          The command to be sent
+ * @this:         OneNAND device structure
+ * @cmd:          The command to be sent
  *
- * Update interrupt register. The status is depends on command.
+ * Update interrupt register. The status depends on command.
  */
 static void onenand_update_interrupt(struct onenand_chip *this, int cmd)
 {
@@ -189,11 +189,12 @@ static void onenand_update_interrupt(struct onenand_chip *this, int cmd)
 }
 
 /**
- * onenand_check_overwrite - Check over-write if happend
- * @param dest         The destination pointer
- * @param src          The source pointer
- * @param count                The length to be check
- * @return             0 on same, otherwise 1
+ * onenand_check_overwrite - Check if over-write happened
+ * @dest:              The destination pointer
+ * @src:               The source pointer
+ * @count:             The length to be check
+ *
+ * Returns:            0 on same, otherwise 1
  *
  * Compare the source with destination
  */
@@ -213,10 +214,10 @@ static int onenand_check_overwrite(void *dest, void *src, size_t count)
 
 /**
  * onenand_data_handle - Handle OneNAND Core and DataRAM
- * @param this         OneNAND device structure
- * @param cmd          The command to be sent
- * @param dataram      Which dataram used
- * @param offset       The offset to OneNAND Core
+ * @this:              OneNAND device structure
+ * @cmd:               The command to be sent
+ * @dataram:           Which dataram used
+ * @offset:            The offset to OneNAND Core
  *
  * Copy data from OneNAND Core to DataRAM (read)
  * Copy data from DataRAM to OneNAND Core (write)
@@ -295,8 +296,8 @@ static void onenand_data_handle(struct onenand_chip *this, int cmd,
 
 /**
  * onenand_command_handle - Handle command
- * @param this         OneNAND device structure
- * @param cmd          The command to be sent
+ * @this:              OneNAND device structure
+ * @cmd:               The command to be sent
  *
  * Emulate OneNAND command.
  */
@@ -350,8 +351,8 @@ static void onenand_command_handle(struct onenand_chip *this, int cmd)
 
 /**
  * onenand_writew - [OneNAND Interface] Emulate write operation
- * @param value                value to write
- * @param addr         address to write
+ * @value:             value to write
+ * @addr:              address to write
  *
  * Write OneNAND register with value
  */
@@ -373,7 +374,7 @@ static void onenand_writew(unsigned short value, void __iomem * addr)
 
 /**
  * flash_init - Initialize OneNAND simulator
- * @param flash                OneNAND simulaotr data strucutres
+ * @flash:             OneNAND simulator data strucutres
  *
  * Initialize OneNAND simulator.
  */
@@ -416,7 +417,7 @@ static int __init flash_init(struct onenand_flash *flash)
 
 /**
  * flash_exit - Clean up OneNAND simulator
- * @param flash                OneNAND simulaotr data strucutres
+ * @flash:             OneNAND simulator data structures
  *
  * Clean up OneNAND simulator.
  */
@@ -424,7 +425,6 @@ static void flash_exit(struct onenand_flash *flash)
 {
        vfree(ONENAND_CORE(flash));
        kfree(flash->base);
-       kfree(flash);
 }
 
 static int __init onenand_sim_init(void)
@@ -449,7 +449,7 @@ static int __init onenand_sim_init(void)
        info->onenand.write_word = onenand_writew;
 
        if (flash_init(&info->flash)) {
-               printk(KERN_ERR "Unable to allocat flash.\n");
+               printk(KERN_ERR "Unable to allocate flash.\n");
                kfree(ffchars);
                kfree(info);
                return -ENOMEM;
index a4f1bf33164a1426eb92ea59df1093d856986633..6330c8cc72b5521fa8574d7f4d3f492b7e9cb231 100644 (file)
@@ -1309,7 +1309,7 @@ static int ubi_thread(void *u)
        struct ubi_device *ubi = u;
 
        ubi_msg("background thread \"%s\" started, PID %d",
-               ubi->bgt_name, current->pid);
+               ubi->bgt_name, task_pid_nr(current));
 
        set_freezable();
        for (;;) {
index 862f47223fdc9e26e18df0babf94c5ca5eaefed5..6f8e7d4cf74dbdd224fdbd4d7d1b5924c206ade0 100644 (file)
@@ -1491,7 +1491,7 @@ vortex_up(struct net_device *dev)
        struct vortex_private *vp = netdev_priv(dev);
        void __iomem *ioaddr = vp->ioaddr;
        unsigned int config;
-       int i, mii_reg1, mii_reg5, err;
+       int i, mii_reg1, mii_reg5, err = 0;
 
        if (VORTEX_PCI(vp)) {
                pci_set_power_state(VORTEX_PCI(vp), PCI_D0);    /* Go active */
index 973b684c11e34f5055bf2fde0b86711043ddb5f1..eef6fecfff2ac731eb7259896ea8853adc384c8c 100644 (file)
@@ -73,7 +73,7 @@
 
                Jean-Jacques Michel - bug fix
 
-               Tobias Ringström - Rx interrupt status checking suggestion
+               Tobias Ringström - Rx interrupt status checking suggestion
 
                Andrew Morton - Clear blocked signals, avoid
                buffer overrun setting current->comm.
index 83d52c8acab0399ea82c71b259181b8e0573523f..2538816817aa366f793a611ba407f8e73b316e33 100644 (file)
@@ -855,7 +855,7 @@ config BFIN_MAC_USE_L1
        depends on BFIN_MAC && BF537
        default y
        help
-         To get maximum network performace, you should use L1 memory as rx/tx buffers.
+         To get maximum network performance, you should use L1 memory as rx/tx buffers.
          Say N here if you want to reserve L1 memory for other uses.
 
 config BFIN_TX_DESC_NUM
@@ -1293,9 +1293,6 @@ config PCNET32_NAPI
          deployed on potentially unfriendly networks (e.g. in a firewall),
          then say Y here.
 
-         See <file:Documentation/networking/NAPI_HOWTO.txt> for more
-         information.
-
          If in doubt, say N.
 
 config AMD8111_ETH
@@ -1313,7 +1310,7 @@ config AMD8111_ETH
          will be called amd8111e.
 
 config AMD8111E_NAPI
-       bool "Enable NAPI support"
+       bool "Use RX polling (NAPI)"
        depends on AMD8111_ETH
        help
          NAPI is a new driver API designed to reduce CPU and interrupt load
@@ -1324,9 +1321,6 @@ config AMD8111E_NAPI
          deployed on potentially unfriendly networks (e.g. in a firewall),
          then say Y here.
 
-         See <file:Documentation/networking/NAPI_HOWTO.txt> for more
-         information.
-
          If in doubt, say N.
 
 config ADAPTEC_STARFIRE
@@ -1355,9 +1349,6 @@ config ADAPTEC_STARFIRE_NAPI
          deployed on potentially unfriendly networks (e.g. in a firewall),
          then say Y here.
 
-         See <file:Documentation/networking/NAPI_HOWTO.txt> for more
-         information.
-
          If in doubt, say N.
 
 config AC3200
@@ -1431,7 +1422,7 @@ config FORCEDETH
          called forcedeth.
 
 config FORCEDETH_NAPI
-       bool "Use Rx and Tx Polling (NAPI) (EXPERIMENTAL)"
+       bool "Use Rx Polling (NAPI) (EXPERIMENTAL)"
        depends on FORCEDETH && EXPERIMENTAL
        help
          NAPI is a new driver API designed to reduce CPU and interrupt load
@@ -1442,9 +1433,6 @@ config FORCEDETH_NAPI
          deployed on potentially unfriendly networks (e.g. in a firewall),
          then say Y here.
 
-         See <file:Documentation/networking/NAPI_HOWTO.txt> for more
-         information.
-
          If in doubt, say N.
 
 config CS89x0
@@ -1756,9 +1744,6 @@ config VIA_RHINE_NAPI
          deployed on potentially unfriendly networks (e.g. in a firewall),
          then say Y here.
 
-         See <file:Documentation/networking/NAPI_HOWTO.txt> for more
-         information.
-
 config LAN_SAA9730
        bool "Philips SAA9730 Ethernet support"
        depends on NET_PCI && PCI && MIPS_ATLAS
@@ -2003,9 +1988,6 @@ config E1000_NAPI
          deployed on potentially unfriendly networks (e.g. in a firewall),
          then say Y here.
 
-         See <file:Documentation/networking/NAPI_HOWTO.txt> for more
-         information.
-
          If in doubt, say N.
 
 config E1000_DISABLE_PACKET_SPLIT
@@ -2099,7 +2081,7 @@ config R8169
          will be called r8169.  This is recommended.
 
 config R8169_NAPI
-       bool "Use Rx and Tx Polling (NAPI) (EXPERIMENTAL)"
+       bool "Use Rx Polling (NAPI) (EXPERIMENTAL)"
        depends on R8169 && EXPERIMENTAL
        help
          NAPI is a new driver API designed to reduce CPU and interrupt load
@@ -2110,9 +2092,6 @@ config R8169_NAPI
          deployed on potentially unfriendly networks (e.g. in a firewall),
          then say Y here.
 
-         See <file:Documentation/networking/NAPI_HOWTO.txt> for more
-         information.
-
          If in doubt, say N.
 
 config R8169_VLAN
@@ -2364,7 +2343,7 @@ config GIANFAR
          and MPC86xx family of chips, and the FEC on the 8540.
 
 config GFAR_NAPI
-       bool "NAPI Support"
+       bool "Use Rx Polling (NAPI)"
        depends on GIANFAR
 
 config UCC_GETH
@@ -2376,7 +2355,7 @@ config UCC_GETH
          which is available on some Freescale SOCs.
 
 config UGETH_NAPI
-       bool "NAPI Support"
+       bool "Use Rx Polling (NAPI)"
        depends on UCC_GETH
 
 config UGETH_MAGIC_PACKET
@@ -2494,7 +2473,7 @@ config CHELSIO_T3
 
 config EHEA
        tristate "eHEA Ethernet support"
-       depends on IBMEBUS
+       depends on IBMEBUS && INET
        select INET_LRO
        ---help---
          This driver supports the IBM pSeries eHEA ethernet adapter.
@@ -2559,9 +2538,6 @@ config IXGB_NAPI
          deployed on potentially unfriendly networks (e.g. in a firewall),
          then say Y here.
 
-         See <file:Documentation/networking/NAPI_HOWTO.txt> for more
-         information.
-
          If in doubt, say N.
 
 config S2IO
@@ -2584,14 +2560,11 @@ config S2IO_NAPI
          deployed on potentially unfriendly networks (e.g. in a firewall),
          then say Y here.
 
-         See <file:Documentation/networking/NAPI_HOWTO.txt> for more
-         information.
-
          If in doubt, say N.
 
 config MYRI10GE
        tristate "Myricom Myri-10G Ethernet support"
-       depends on PCI
+       depends on PCI && INET
        select FW_LOADER
        select CRC32
        select INET_LRO
@@ -3127,4 +3100,10 @@ config NETPOLL_TRAP
 config NET_POLL_CONTROLLER
        def_bool NETPOLL
 
+config VIRTIO_NET
+       tristate "Virtio network driver (EXPERIMENTAL)"
+       depends on EXPERIMENTAL && VIRTIO
+       ---help---
+         This is the virtual network driver for lguest.  Say Y or M.
+
 endif # NETDEVICES
index 22f78cbd126b185963e180e08893fa4c30995e67..593262065c9b8b852437034e2fdcaa5fd71981fa 100644 (file)
@@ -183,7 +183,6 @@ obj-$(CONFIG_ZORRO8390) += zorro8390.o
 obj-$(CONFIG_HPLANCE) += hplance.o 7990.o
 obj-$(CONFIG_MVME147_NET) += mvme147.o 7990.o
 obj-$(CONFIG_EQUALIZER) += eql.o
-obj-$(CONFIG_LGUEST_NET) += lguest_net.o
 obj-$(CONFIG_MIPS_JAZZ_SONIC) += jazzsonic.o
 obj-$(CONFIG_MIPS_AU1X00_ENET) += au1000_eth.o
 obj-$(CONFIG_MIPS_SIM_NET) += mipsnet.o
@@ -243,3 +242,4 @@ obj-$(CONFIG_FS_ENET) += fs_enet/
 
 obj-$(CONFIG_NETXEN_NIC) += netxen/
 obj-$(CONFIG_NIU) += niu.o
+obj-$(CONFIG_VIRTIO_NET) += virtio_net.o
index 1cc74ec88a5860e00a895bd05b75882dac7fe9b2..eebf5bb2b03ae6a4958df7bff99d973adddc3771 100644 (file)
@@ -1111,7 +1111,7 @@ static struct net_device_stats *amd8111e_get_stats(struct net_device * dev)
 
        return new_stats;
 }
-/* This function recalculate the interupt coalescing  mode on every interrupt
+/* This function recalculate the interrupt coalescing  mode on every interrupt
 according to the datarate and the packet rate.
 */
 static int amd8111e_calc_coalesce(struct net_device *dev)
index 3fa3bccd1adb26194314986764e6031efb5a8b41..10f3a196be32b729c5ddb075d72f39a0c82199ff 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  Amiga Linux/m68k Ariadne Ethernet Driver
  *
- *  © Copyright 1995-2003 by Geert Uytterhoeven (geert@linux-m68k.org)
+ *  Â© Copyright 1995-2003 by Geert Uytterhoeven (geert@linux-m68k.org)
  *                          Peter De Schrijver (p2@mind.be)
  *
  *  ---------------------------------------------------------------------------
index f7913d5a39f1991a264dea61453812117539561b..bb613f292e04d613808dd8288e7e703d494cc665 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  Amiga Linux/m68k Ariadne Ethernet Driver
  *
- *  © Copyright 1995 by Geert Uytterhoeven (geert@linux-m68k.org)
+ *  Â© Copyright 1995 by Geert Uytterhoeven (geert@linux-m68k.org)
  *                     Peter De Schrijver
  *                    (Peter.DeSchrijver@linux.cc.kuleuven.ac.be)
  *
index 185f98e3964c49b6a1615dc72c09f28ca227419f..504b7ce2747de0c6cf91f6ab945608dd11dcfd76 100644 (file)
@@ -542,7 +542,7 @@ static struct {
 static int num_ifs;
 
 /*
- * Setup the base address and interupt of the Au1xxx ethernet macs
+ * Setup the base address and interrupt of the Au1xxx ethernet macs
  * based on cpu type and whether the interface is enabled in sys_pinfunc
  * register. The last interface is enabled if SYS_PF_NI2 (bit 4) is 0.
  */
index 9fe0517cf89319e70340d952fd189e8365400d4b..7495a9ee8f4bff6dde5b7c7666398d35882059fd 100644 (file)
@@ -900,7 +900,7 @@ static int ax_probe(struct platform_device *pdev)
 
                ax->map2 = ioremap(res->start, size);
                if (ax->map2 == NULL) {
-                       dev_err(&pdev->dev, "cannot map reset register");
+                       dev_err(&pdev->dev, "cannot map reset register\n");
                        ret = -ENXIO;
                        goto exit_mem2;
                }
index 78ed633ceb829e121161a8a230a1350d9de06017..da767d3d5af5bb552a6d0dce0792112a3179fc6c 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/dma-mapping.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <linux/delay.h>
@@ -56,8 +56,8 @@
 
 #define DRV_MODULE_NAME                "bnx2"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "1.6.7"
-#define DRV_MODULE_RELDATE     "October 10, 2007"
+#define DRV_MODULE_VERSION     "1.6.8"
+#define DRV_MODULE_RELDATE     "October 17, 2007"
 
 #define RUN_AT(x) (jiffies + (x))
 
@@ -3079,14 +3079,18 @@ bnx2_set_power_state(struct bnx2 *bp, pci_power_t state)
                        autoneg = bp->autoneg;
                        advertising = bp->advertising;
 
-                       bp->autoneg = AUTONEG_SPEED;
-                       bp->advertising = ADVERTISED_10baseT_Half |
-                               ADVERTISED_10baseT_Full |
-                               ADVERTISED_100baseT_Half |
-                               ADVERTISED_100baseT_Full |
-                               ADVERTISED_Autoneg;
+                       if (bp->phy_port == PORT_TP) {
+                               bp->autoneg = AUTONEG_SPEED;
+                               bp->advertising = ADVERTISED_10baseT_Half |
+                                       ADVERTISED_10baseT_Full |
+                                       ADVERTISED_100baseT_Half |
+                                       ADVERTISED_100baseT_Full |
+                                       ADVERTISED_Autoneg;
+                       }
 
-                       bnx2_setup_copper_phy(bp);
+                       spin_lock_bh(&bp->phy_lock);
+                       bnx2_setup_phy(bp, bp->phy_port);
+                       spin_unlock_bh(&bp->phy_lock);
 
                        bp->autoneg = autoneg;
                        bp->advertising = advertising;
@@ -3097,10 +3101,16 @@ bnx2_set_power_state(struct bnx2 *bp, pci_power_t state)
 
                        /* Enable port mode. */
                        val &= ~BNX2_EMAC_MODE_PORT;
-                       val |= BNX2_EMAC_MODE_PORT_MII |
-                              BNX2_EMAC_MODE_MPKT_RCVD |
+                       val |= BNX2_EMAC_MODE_MPKT_RCVD |
                               BNX2_EMAC_MODE_ACPI_RCVD |
                               BNX2_EMAC_MODE_MPKT;
+                       if (bp->phy_port == PORT_TP)
+                               val |= BNX2_EMAC_MODE_PORT_MII;
+                       else {
+                               val |= BNX2_EMAC_MODE_PORT_GMII;
+                               if (bp->line_speed == SPEED_2500)
+                                       val |= BNX2_EMAC_MODE_25G_MODE;
+                       }
 
                        REG_WR(bp, BNX2_EMAC_MODE, val);
 
@@ -6428,7 +6438,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
        /* enable device (incl. PCI PM wakeup), and bus-mastering */
        rc = pci_enable_device(pdev);
        if (rc) {
-               dev_err(&pdev->dev, "Cannot enable PCI device, aborting.");
+               dev_err(&pdev->dev, "Cannot enable PCI device, aborting.\n");
                goto err_out;
        }
 
index 5bd52bead9bf38b860b29412cfc6cfdda51c430d..4b129b7cbfad94eb58d1887062027c82c2ce77cf 100644 (file)
  */
 
 static u8 bnx2_COM_b09FwText[] = {
-/*     0x1f, 0x8b, 0x08, 0x00, 0x0e, 0x34, 0xe7, 0x45, 0x00, 0x03, */
-                                                                   0xdc, 0x5b,
-       0x6d, 0x70, 0x5c, 0xd5, 0x79, 0x7e, 0xef, 0xd9, 0xbb, 0xf2, 0x5a, 0x92,
-       0xe5, 0x6b, 0x79, 0x23, 0x16, 0x4b, 0xc0, 0xae, 0x75, 0x6d, 0x69, 0xb0,
-       0x43, 0x16, 0xa1, 0x80, 0x9a, 0xd9, 0xc0, 0xb2, 0x2b, 0x33, 0x9e, 0x0c,
-       0x69, 0x64, 0x50, 0x80, 0xb6, 0x4c, 0x46, 0xec, 0x1a, 0x9a, 0x4e, 0x87,
-       0xd6, 0xa6, 0x6e, 0x9b, 0xc9, 0x34, 0x78, 0x47, 0x1f, 0x8d, 0xa7, 0x15,
-       0xba, 0x06, 0x1b, 0xd9, 0xd3, 0xd0, 0xa0, 0x6a, 0x71, 0xf1, 0x8f, 0x8d,
-       0xaf, 0xf9, 0x48, 0xaa, 0x4c, 0x4d, 0xa5, 0x18, 0x48, 0x69, 0xa7, 0x4d,
-       0xfb, 0xa3, 0x9e, 0xa1, 0x5f, 0x84, 0x32, 0xfd, 0xc1, 0x74, 0xda, 0x4e,
-       0x3a, 0x24, 0x53, 0x08, 0x84, 0xed, 0xf3, 0x9c, 0x7b, 0xee, 0xea, 0x6a,
-       0x25, 0x7f, 0xf1, 0x91, 0x1f, 0xd5, 0xcc, 0xfa, 0xde, 0xf3, 0xfd, 0x9e,
-       0xf7, 0xbc, 0xef, 0xf3, 0x7e, 0xdc, 0xe3, 0x4f, 0x8a, 0xb4, 0x8a, 0xf9,
-       0xdb, 0x80, 0x5f, 0xfa, 0xc1, 0xdf, 0x2c, 0x5f, 0x37, 0x78, 0xdd, 0x0d,
-       0x78, 0xbd, 0x41, 0xc5, 0xec, 0x18, 0xeb, 0xf9, 0x4f, 0x12, 0xbf, 0x01,
-       0xf3, 0xbe, 0xd6, 0x9f, 0x83, 0xdf, 0x9b, 0x68, 0x1c, 0xfb, 0x0f, 0x11,
-       0xeb, 0x3c, 0x7d, 0xa2, 0x7f, 0xf5, 0xfa, 0x85, 0xdb, 0x15, 0x69, 0xb9,
-       0x40, 0x7b, 0x2c, 0x58, 0x52, 0xd3, 0xcc, 0x9f, 0x24, 0x54, 0x6e, 0xec,
-       0xe1, 0x82, 0x2b, 0x89, 0x58, 0x6e, 0xf7, 0xc1, 0xb2, 0x2b, 0x92, 0xaf,
-       0xed, 0x48, 0x17, 0xe5, 0x67, 0xf5, 0x4a, 0xd2, 0x16, 0xd6, 0x5f, 0x95,
-       0x7b, 0xef, 0xc9, 0x17, 0x6e, 0xca, 0xfc, 0x68, 0x2e, 0x26, 0x09, 0x27,
-       0xf7, 0xbc, 0x38, 0xdb, 0x25, 0xd1, 0x83, 0x31, 0x4f, 0xf4, 0xe5, 0x2d,
-       0xe9, 0x08, 0xe7, 0x7a, 0xb3, 0xfe, 0x42, 0x9f, 0x54, 0xb6, 0xe4, 0x12,
-       0xa2, 0x72, 0xdb, 0x5e, 0x2d, 0xc4, 0x9c, 0xb1, 0x58, 0xce, 0x91, 0x45,
-       0x5f, 0x46, 0xee, 0x9f, 0x96, 0x44, 0x22, 0xf7, 0xe5, 0xc4, 0xba, 0x6d,
-       0x92, 0xb0, 0x73, 0x4b, 0x0f, 0xff, 0xbe, 0x7b, 0xb0, 0xae, 0x5c, 0xb7,
-       0x7f, 0x5e, 0xda, 0x87, 0x4e, 0x0c, 0xa2, 0xbd, 0x96, 0xe9, 0x17, 0xb9,
-       0x49, 0x94, 0x5b, 0x69, 0x8f, 0xb9, 0x09, 0x29, 0xf8, 0xae, 0x14, 0x7d,
-       0x91, 0xbf, 0xac, 0x59, 0x72, 0xc2, 0xed, 0x92, 0xf9, 0x9d, 0xef, 0xd5,
-       0xf3, 0xa0, 0xe5, 0xfb, 0xee, 0xd2, 0xc3, 0x93, 0x2e, 0xe9, 0x3d, 0x90,
-       0x08, 0xe8, 0xdd, 0xbb, 0xae, 0xec, 0xda, 0x32, 0x5e, 0x63, 0xdd, 0xa8,
-       0x62, 0x5d, 0x3c, 0x97, 0x68, 0x3d, 0xe1, 0xb6, 0x9b, 0xba, 0x57, 0x6f,
-       0x29, 0x60, 0xbe, 0x89, 0x1a, 0xfb, 0xe6, 0xaf, 0x2f, 0xbb, 0x49, 0x53,
-       0xbf, 0x70, 0x63, 0xc1, 0x4d, 0xa1, 0xbe, 0xc7, 0xb4, 0x8d, 0x3d, 0x58,
-       0x76, 0x5d, 0xd3, 0xf6, 0x76, 0xac, 0xe0, 0xf6, 0x9b, 0xfa, 0xf7, 0x6e,
-       0x2e, 0xbb, 0x3b, 0x4d, 0x7d, 0x0f, 0xe6, 0xca, 0x9a, 0xfa, 0x85, 0x7b,
-       0xca, 0xee, 0xa0, 0xa9, 0xdf, 0x7d, 0x73, 0xc1, 0x1d, 0x32, 0xf5, 0x89,
-       0xa1, 0xb2, 0x9b, 0x43, 0xfd, 0x97, 0x13, 0x6a, 0x9b, 0x23, 0x53, 0xb5,
-       0x34, 0x7e, 0x79, 0xb4, 0x0d, 0xa3, 0x6e, 0x37, 0x7e, 0xb7, 0xe3, 0xf7,
-       0xc8, 0x46, 0xe9, 0x18, 0xc1, 0xf3, 0xbf, 0xba, 0x03, 0xde, 0x81, 0x47,
-       0x5e, 0x42, 0x5e, 0x8f, 0xa5, 0xe4, 0x85, 0xbe, 0xd7, 0xc1, 0x43, 0x47,
-       0x4e, 0xfb, 0x62, 0x8d, 0xf4, 0xa5, 0xc0, 0xbb, 0xa4, 0x3c, 0xe3, 0xb7,
-       0x49, 0xec, 0xb1, 0x18, 0x78, 0xf3, 0xcb, 0x52, 0x4a, 0x26, 0x64, 0xd3,
-       0xac, 0x25, 0x5b, 0x07, 0x12, 0x92, 0x77, 0xb8, 0x36, 0x4e, 0x7b, 0x26,
-       0x29, 0xb1, 0xd9, 0xfc, 0x66, 0x25, 0xdb, 0x9c, 0xa2, 0x54, 0xc0, 0xbb,
-       0x57, 0x29, 0x97, 0x68, 0x4b, 0x4b, 0x71, 0xfa, 0x5a, 0x19, 0x73, 0x48,
-       0xd7, 0x1f, 0x5c, 0x15, 0xac, 0x95, 0xb0, 0x0a, 0xc7, 0x46, 0x65, 0xca,
-       0x6b, 0xb7, 0x8a, 0xc7, 0x6e, 0x96, 0x42, 0x56, 0x92, 0x18, 0x97, 0x2a,
-       0xa1, 0xa5, 0x5a, 0x1b, 0x95, 0x49, 0x4f, 0xac, 0x82, 0x47, 0x7e, 0x76,
-       0xa1, 0xbd, 0x43, 0xf7, 0x45, 0x5d, 0x4f, 0x4c, 0xcf, 0x9d, 0x40, 0xbd,
-       0x83, 0xfa, 0x4e, 0x6b, 0x58, 0xcf, 0xa1, 0xeb, 0xd3, 0x13, 0xd2, 0x2e,
-       0x4f, 0xd5, 0x92, 0xa6, 0x6f, 0xbd, 0x5e, 0xc8, 0x3a, 0xe8, 0x37, 0x2a,
-       0x13, 0x5e, 0x52, 0xc6, 0xf0, 0x1c, 0xf7, 0xb8, 0x7e, 0x0a, 0x32, 0x75,
-       0xdd, 0xc1, 0xd2, 0x51, 0x3d, 0x5f, 0x3a, 0x96, 0xe3, 0x7c, 0x3d, 0xe8,
-       0xf7, 0x12, 0xe8, 0xb2, 0xc4, 0xd6, 0x67, 0x99, 0x97, 0xd2, 0xb4, 0x05,
-       0x79, 0xc3, 0x53, 0xf3, 0x75, 0x18, 0xf4, 0xdb, 0xe2, 0x0e, 0x58, 0x52,
-       0xc6, 0x59, 0x55, 0x1c, 0x94, 0x6b, 0x0b, 0xaa, 0xe0, 0xad, 0x93, 0xa2,
-       0x9d, 0x96, 0xd8, 0x0c, 0x65, 0x69, 0x4c, 0x26, 0x30, 0x46, 0xb9, 0xec,
-       0xf3, 0x0e, 0xf6, 0x3d, 0xa6, 0xcf, 0xa1, 0x25, 0x57, 0x51, 0x45, 0xbf,
-       0x4b, 0xd4, 0xec, 0xbd, 0xf2, 0xd2, 0xb4, 0x38, 0x38, 0xc7, 0x7a, 0xc1,
-       0x9d, 0x54, 0x85, 0xa7, 0x6d, 0x89, 0xcf, 0x58, 0x32, 0xe9, 0x66, 0xa0,
-       0x01, 0x87, 0xd4, 0x2e, 0x7f, 0x01, 0xfd, 0x38, 0x0e, 0xfd, 0x6a, 0x0a,
-       0x7c, 0xe5, 0xfb, 0x0e, 0x47, 0x69, 0x79, 0x66, 0x1f, 0x9c, 0x01, 0xf6,
-       0xf1, 0x8c, 0x87, 0x33, 0xd1, 0x67, 0x94, 0xc6, 0x19, 0x89, 0x35, 0xdc,
-       0x07, 0x99, 0x3a, 0x6a, 0x4b, 0x29, 0x8b, 0x7d, 0xa1, 0x77, 0x29, 0xbb,
-       0x4c, 0xd7, 0xc4, 0x74, 0x33, 0x5d, 0x1c, 0x47, 0xba, 0x02, 0x9a, 0xc6,
-       0x8f, 0x92, 0xbe, 0x65, 0x7a, 0xa6, 0xa6, 0x43, 0x1a, 0xb9, 0x1e, 0x69,
-       0x0b, 0xe9, 0xe2, 0x38, 0xd2, 0xb5, 0x99, 0x67, 0xcd, 0x3f, 0x6b, 0x18,
-       0x74, 0x4c, 0x78, 0x36, 0xce, 0xa8, 0x5d, 0x4a, 0x4e, 0xc5, 0x9a, 0x18,
-       0xda, 0x91, 0x82, 0x36, 0x5b, 0xe3, 0x43, 0xa4, 0xd9, 0xc5, 0x39, 0xb6,
-       0xe8, 0xf3, 0x56, 0xb9, 0x49, 0xf2, 0x0e, 0xfd, 0xb9, 0x3e, 0xde, 0x6b,
-       0x8e, 0x4c, 0xea, 0xf9, 0x48, 0xd3, 0x47, 0x31, 0x0f, 0x69, 0x7d, 0x05,
-       0xb2, 0x3a, 0x08, 0x19, 0xcd, 0xca, 0x5f, 0xf8, 0x3b, 0xe5, 0xcf, 0xfc,
-       0x7e, 0xf9, 0x0e, 0xf4, 0xf6, 0xdb, 0x7e, 0x5a, 0x9e, 0xf7, 0x7b, 0xe4,
-       0x39, 0x3f, 0x25, 0xcf, 0x6a, 0xf9, 0x1d, 0x16, 0xe9, 0xa0, 0x4c, 0xa7,
-       0xa5, 0x13, 0xfa, 0xb3, 0x09, 0xba, 0xf9, 0x38, 0xf8, 0x77, 0xb4, 0x4f,
-       0xf2, 0x9b, 0x73, 0x92, 0xb8, 0x1a, 0xbf, 0x2b, 0xf0, 0xeb, 0xca, 0xd9,
-       0x5a, 0x56, 0xec, 0x1c, 0x79, 0x68, 0x4b, 0x51, 0xef, 0xd9, 0x96, 0x09,
-       0xff, 0x91, 0xab, 0x03, 0xd9, 0x15, 0x19, 0x01, 0x8f, 0xd5, 0xc0, 0x4f,
-       0xea, 0x79, 0x07, 0xfb, 0x18, 0xd8, 0xa1, 0x79, 0xaf, 0x06, 0x28, 0xb3,
-       0x69, 0xc8, 0xbd, 0x6d, 0x15, 0xbd, 0x93, 0xc0, 0x8d, 0x36, 0xab, 0x70,
-       0xa4, 0x22, 0xe5, 0x23, 0x75, 0x29, 0x67, 0xe3, 0xf2, 0x90, 0x53, 0x97,
-       0xe1, 0x6c, 0x8b, 0xec, 0x77, 0xc0, 0xfb, 0x9d, 0xbf, 0x6d, 0x85, 0x98,
-       0xfd, 0xb8, 0xff, 0x3b, 0x78, 0x67, 0x9d, 0xc8, 0x51, 0xfd, 0x1e, 0xd4,
-       0x57, 0xfc, 0xb8, 0xe4, 0x93, 0x95, 0x94, 0x2d, 0x5b, 0x54, 0xb0, 0xee,
-       0x78, 0xd8, 0x06, 0x7e, 0x2c, 0x01, 0x27, 0x33, 0x5a, 0x5f, 0x4a, 0xd3,
-       0xeb, 0xdf, 0xce, 0xeb, 0x6a, 0xf4, 0x77, 0x06, 0xe5, 0xac, 0xe6, 0x67,
-       0x7a, 0xcc, 0xca, 0x25, 0x65, 0x6b, 0x8d, 0xe5, 0x21, 0xeb, 0x4e, 0x9f,
-       0xf2, 0x8c, 0x77, 0x9f, 0x74, 0x5e, 0x89, 0x7e, 0x36, 0x9e, 0x79, 0x43,
-       0x6f, 0x94, 0x46, 0xce, 0x43, 0x1a, 0xf9, 0xfc, 0x66, 0x84, 0xc6, 0x27,
-       0x1b, 0xef, 0x47, 0x23, 0xef, 0x15, 0xff, 0x8f, 0x5a, 0x03, 0xda, 0x86,
-       0xe4, 0x8d, 0x99, 0xaf, 0x98, 0x75, 0xf0, 0x7e, 0x8a, 0xf3, 0x7f, 0xab,
-       0x1e, 0xc8, 0x4b, 0xe5, 0x22, 0xeb, 0x2c, 0x44, 0xd6, 0xf9, 0x6e, 0x64,
-       0x9d, 0xef, 0x46, 0xd6, 0xa9, 0x80, 0xa7, 0xb2, 0x51, 0x41, 0x86, 0x4b,
-       0x34, 0x63, 0x72, 0x08, 0x73, 0xbe, 0x2e, 0xb1, 0x1c, 0xf5, 0x3c, 0xc4,
-       0x9b, 0x73, 0xe8, 0x9f, 0x93, 0xb3, 0x33, 0x15, 0x29, 0x1d, 0x89, 0xcb,
-       0x1d, 0xba, 0xdf, 0x26, 0x43, 0x5f, 0xb4, 0x2d, 0x21, 0x7b, 0x92, 0x7c,
-       0x0f, 0xdb, 0x6c, 0xf0, 0x99, 0xe5, 0x6f, 0x5d, 0x19, 0x94, 0xf9, 0xbe,
-       0x60, 0xf6, 0x32, 0x1a, 0x8c, 0x3b, 0xf5, 0xa6, 0xc6, 0xc3, 0x45, 0x9f,
-       0xb8, 0x25, 0xd9, 0x98, 0x2b, 0xfb, 0x86, 0xb3, 0x5d, 0x32, 0xe1, 0x58,
-       0xd9, 0xf1, 0xfe, 0x75, 0xd4, 0x8b, 0xbc, 0x72, 0xdb, 0x80, 0x0d, 0x92,
-       0x56, 0xc4, 0x7c, 0xbd, 0x2f, 0x4b, 0x05, 0xf4, 0x3b, 0x2c, 0x8f, 0x28,
-       0xb7, 0xb3, 0xa9, 0x9e, 0xba, 0x1d, 0xc3, 0x3b, 0x65, 0x78, 0x97, 0x39,
-       0x63, 0x1b, 0x65, 0xe2, 0xf0, 0x35, 0xa6, 0x1c, 0xb6, 0x6f, 0xb6, 0x57,
-       0x96, 0xcf, 0x76, 0xaf, 0x2c, 0x87, 0x38, 0x11, 0xc5, 0x70, 0xee, 0x15,
-       0xf8, 0xe4, 0x52, 0xee, 0xe2, 0xa0, 0x35, 0x0b, 0x9d, 0x5b, 0x67, 0x68,
-       0xb8, 0xc2, 0xd0, 0x00, 0x5a, 0xfb, 0x20, 0x59, 0x5a, 0x97, 0xb4, 0x68,
-       0x35, 0x95, 0xc9, 0xfb, 0xf0, 0x7d, 0x83, 0x6e, 0x0f, 0x74, 0x2e, 0x7c,
-       0x86, 0xf8, 0xfe, 0x66, 0xc4, 0x5e, 0xf4, 0x40, 0x67, 0x93, 0xe0, 0x55,
-       0x88, 0xf5, 0xc4, 0xe0, 0x14, 0xec, 0x03, 0x64, 0x55, 0x63, 0x7b, 0x3b,
-       0xf0, 0xd0, 0x36, 0xd8, 0x9c, 0x30, 0xd8, 0xdc, 0x0e, 0x5c, 0x66, 0xd9,
-       0x31, 0xe5, 0xa4, 0x29, 0xa7, 0x50, 0x86, 0x1d, 0x9f, 0x25, 0x2e, 0x5f,
-       0x77, 0x70, 0xef, 0x51, 0x8d, 0xf7, 0xb4, 0x15, 0x40, 0x61, 0xe2, 0x35,
-       0x71, 0xbb, 0x47, 0xe6, 0x6b, 0x58, 0xaf, 0x81, 0x8d, 0xdc, 0x7b, 0x94,
-       0x1e, 0xd2, 0xb2, 0x5e, 0x14, 0x6c, 0x57, 0x3e, 0x49, 0x7a, 0x1f, 0xc4,
-       0xde, 0x89, 0x3f, 0xa4, 0xfb, 0x2a, 0xd0, 0xca, 0x7d, 0xfc, 0x3c, 0x69,
-       0xe5, 0x7a, 0xcd, 0xf4, 0x7e, 0x58, 0x1c, 0x24, 0xed, 0x27, 0xb1, 0xe7,
-       0x3c, 0x30, 0x4f, 0xac, 0xd1, 0xbe, 0x51, 0xec, 0x79, 0x04, 0x78, 0x78,
-       0x3b, 0xf0, 0x70, 0x37, 0xf0, 0x70, 0x18, 0x78, 0x98, 0x03, 0x16, 0x0e,
-       0x01, 0x0b, 0x07, 0x81, 0x85, 0x59, 0xf0, 0x26, 0x29, 0x73, 0xc0, 0xc6,
-       0x39, 0x60, 0xe4, 0x1c, 0xe6, 0x18, 0x9f, 0x15, 0xeb, 0x4b, 0xd8, 0xc3,
-       0x63, 0x33, 0x99, 0x93, 0x90, 0xa5, 0x54, 0x45, 0x41, 0xfe, 0xb3, 0x43,
-       0x90, 0xed, 0x7e, 0xa9, 0xfa, 0xb6, 0x94, 0x69, 0x53, 0xb7, 0xf7, 0x42,
-       0xd7, 0x20, 0xef, 0x29, 0x31, 0x7f, 0x1b, 0xcc, 0xf3, 0x1f, 0x45, 0xdc,
-       0xbf, 0xa3, 0x2c, 0xa6, 0x45, 0xce, 0x48, 0xc9, 0xeb, 0x75, 0x0a, 0xaa,
-       0x1f, 0xfd, 0x58, 0xce, 0xaa, 0xfb, 0x8f, 0x5c, 0xaf, 0xf6, 0x1e, 0x21,
-       0x5f, 0xa6, 0x81, 0x57, 0x75, 0x99, 0xcc, 0x52, 0xb7, 0xea, 0x72, 0x22,
-       0x9b, 0x19, 0xaa, 0x48, 0x9b, 0x4c, 0x25, 0xa7, 0xb5, 0xad, 0xb5, 0x73,
-       0x87, 0xb5, 0xbd, 0x2a, 0xbb, 0x78, 0xd6, 0x06, 0x54, 0xe9, 0x08, 0xf7,
-       0xdf, 0x8b, 0x5f, 0x1c, 0xb4, 0x70, 0x7e, 0x5b, 0x86, 0x07, 0x1d, 0xf5,
-       0x40, 0x5f, 0x05, 0x08, 0x96, 0x71, 0xce, 0x62, 0xe5, 0xe2, 0x74, 0x6f,
-       0xaa, 0xa8, 0x6c, 0x19, 0xb3, 0x2d, 0x19, 0x87, 0x7c, 0x0f, 0x67, 0xdf,
-       0xa9, 0x4f, 0x25, 0xd9, 0xbe, 0x4e, 0xbe, 0xae, 0x7d, 0x0e, 0xac, 0x5d,
-       0x3d, 0x8a, 0x75, 0xe3, 0x38, 0x03, 0xae, 0xcb, 0x79, 0x50, 0xae, 0xd9,
-       0x28, 0x67, 0x4e, 0x56, 0xc4, 0x87, 0x9e, 0x6c, 0x94, 0xc2, 0xce, 0x16,
-       0xc9, 0x8f, 0xa4, 0x65, 0x7c, 0xc6, 0x07, 0x4e, 0xe1, 0x1c, 0xdd, 0x56,
-       0x29, 0x8d, 0xa6, 0xe5, 0xd1, 0x19, 0xd6, 0x9d, 0xc6, 0xfe, 0x33, 0x87,
-       0xf2, 0xc2, 0xfd, 0xc7, 0xf5, 0xbe, 0xd2, 0xea, 0xb4, 0xec, 0xf7, 0xde,
-       0x30, 0x7a, 0x14, 0x94, 0xef, 0xc7, 0x99, 0x9e, 0xf0, 0x17, 0xb0, 0x7f,
-       0x57, 0xe6, 0x81, 0xff, 0xc5, 0x23, 0xc0, 0x41, 0xb7, 0x03, 0x98, 0x95,
-       0x59, 0xa0, 0x4d, 0x8d, 0xc1, 0xef, 0xab, 0x6a, 0x5e, 0xf7, 0xc8, 0x91,
-       0x19, 0x25, 0xdf, 0xbe, 0x31, 0x8d, 0x32, 0xb0, 0x31, 0x9b, 0x39, 0x3d,
-       0xa6, 0x7a, 0xe4, 0x86, 0xce, 0x14, 0xc6, 0xe5, 0x54, 0xc9, 0xdb, 0x18,
-       0x03, 0x2f, 0x8f, 0xa7, 0x15, 0xfb, 0x2a, 0x29, 0x66, 0x63, 0x38, 0xff,
-       0x0a, 0xfa, 0xbf, 0x8f, 0xf5, 0x7a, 0x64, 0x16, 0xbe, 0xd6, 0xec, 0x4c,
-       0x1e, 0xe3, 0x88, 0x5d, 0x99, 0xe3, 0x4b, 0x0a, 0x18, 0x33, 0x0b, 0xf9,
-       0x1e, 0x85, 0x2f, 0x33, 0x03, 0xd1, 0x69, 0x4d, 0xe3, 0x4c, 0x7b, 0x9d,
-       0x71, 0xe0, 0x41, 0xbe, 0x87, 0xef, 0x9c, 0xd3, 0x95, 0x13, 0x1e, 0xe5,
-       0x30, 0x2d, 0x4f, 0xf9, 0x1c, 0xd7, 0xbb, 0xf0, 0x1c, 0x7c, 0x9f, 0xdf,
-       0xf5, 0xae, 0x44, 0xff, 0x77, 0xe1, 0x07, 0x3b, 0x52, 0xc5, 0xb9, 0x95,
-       0xc1, 0xcb, 0x7c, 0x2a, 0x28, 0x8f, 0xcf, 0x66, 0x16, 0xde, 0x50, 0x7c,
-       0x77, 0x2b, 0xf3, 0xea, 0x5a, 0x91, 0x4e, 0xf2, 0x33, 0x0b, 0x5e, 0xba,
-       0x8e, 0x52, 0xdb, 0x8d, 0xef, 0x47, 0x3d, 0x72, 0x41, 0x9f, 0x2d, 0xf3,
-       0x03, 0x51, 0x3d, 0xa2, 0x3d, 0x0c, 0xf5, 0x28, 0x93, 0x5a, 0x52, 0x0a,
-       0xed, 0xb6, 0x1c, 0xd6, 0x65, 0x0b, 0xb4, 0x66, 0x52, 0xdc, 0xdf, 0x44,
-       0xad, 0x5f, 0x9e, 0xf2, 0xd8, 0x1f, 0x7c, 0x9e, 0x6e, 0x37, 0xfd, 0x4f,
-       0x83, 0x87, 0xf4, 0xdf, 0xfa, 0x41, 0x73, 0xa0, 0x5b, 0xf3, 0xd3, 0x49,
-       0xdd, 0x36, 0xe5, 0x05, 0x7e, 0x9a, 0x82, 0x2f, 0x37, 0x07, 0x5f, 0xae,
-       0xa8, 0xf5, 0xcc, 0xc9, 0xc3, 0xd7, 0x87, 0x9e, 0x04, 0x3a, 0x56, 0xad,
-       0x91, 0x96, 0xbb, 0x40, 0x5f, 0xa6, 0x02, 0x62, 0x0e, 0xab, 0x1c, 0xce,
-       0x7d, 0x50, 0x2a, 0xf4, 0xf7, 0xce, 0xc6, 0x9e, 0x92, 0xb1, 0x2a, 0xed,
-       0x11, 0x7e, 0x9e, 0xeb, 0x30, 0xbe, 0xc8, 0x6b, 0x5b, 0xd1, 0x0d, 0x39,
-       0x80, 0x1d, 0xc9, 0x6e, 0x32, 0x7e, 0xce, 0x13, 0x38, 0xcf, 0x33, 0x38,
-       0xf7, 0x9a, 0xec, 0x3d, 0xf6, 0x0a, 0x65, 0xba, 0xbf, 0x2a, 0x99, 0xfe,
-       0x29, 0xd9, 0xe1, 0xcc, 0x43, 0x1f, 0xf3, 0xa3, 0xf5, 0x5b, 0x54, 0x8e,
-       0x63, 0x0e, 0x62, 0x0c, 0x9e, 0xd5, 0x57, 0xe4, 0x21, 0x9f, 0x75, 0x0f,
-       0x81, 0x9f, 0xd0, 0x95, 0xc1, 0x27, 0x8c, 0x1e, 0x60, 0x3e, 0x3b, 0x9c,
-       0xef, 0x15, 0x33, 0x1f, 0xfb, 0xb1, 0x0f, 0xc7, 0x2c, 0xcf, 0xbb, 0x8b,
-       0xb6, 0x08, 0x78, 0xb4, 0x4b, 0xd5, 0x6f, 0x89, 0xa3, 0xfd, 0xc4, 0x20,
-       0xdf, 0x31, 0x0f, 0x6c, 0x91, 0xe3, 0x9e, 0x41, 0x5f, 0xf8, 0x7a, 0xde,
-       0x7a, 0x29, 0x74, 0x85, 0xf4, 0x52, 0x06, 0xe8, 0x27, 0x68, 0x1b, 0xbc,
-       0x39, 0xe0, 0xfd, 0x1f, 0xc6, 0x02, 0x99, 0x3c, 0x80, 0x32, 0xf5, 0xef,
-       0x80, 0x14, 0xbd, 0x0c, 0xf6, 0x09, 0x1d, 0xf3, 0x3b, 0xac, 0x60, 0x8f,
-       0xe0, 0xff, 0xc8, 0x39, 0xf0, 0x41, 0x2a, 0x01, 0x6f, 0xc8, 0x17, 0xf2,
-       0xa4, 0x03, 0xb2, 0x0f, 0xb9, 0x87, 0xdc, 0x96, 0x34, 0x0f, 0xfe, 0xbd,
-       0x33, 0xf0, 0x8b, 0x33, 0x95, 0x3c, 0xe3, 0xb9, 0x4e, 0xe2, 0x26, 0x30,
-       0xcc, 0x87, 0x70, 0x60, 0xee, 0x25, 0xb5, 0x9e, 0xf4, 0xa6, 0x97, 0x62,
-       0x7d, 0x2c, 0xf7, 0x2f, 0x41, 0x86, 0xab, 0x38, 0x9f, 0xc2, 0xce, 0x5e,
-       0x83, 0x5b, 0xcf, 0xc6, 0x28, 0xaf, 0x55, 0x60, 0x4c, 0xc9, 0xdb, 0xe1,
-       0xdc, 0x4d, 0xbe, 0x39, 0x8e, 0x3c, 0xe7, 0x45, 0xb1, 0x03, 0xb6, 0xcf,
-       0xa5, 0x1c, 0x26, 0x21, 0x07, 0x36, 0x6c, 0x68, 0x0a, 0x67, 0xfe, 0x6f,
-       0x9d, 0xc1, 0x5e, 0xf8, 0x6e, 0xcb, 0x9c, 0x83, 0x35, 0xbd, 0xc5, 0x8d,
-       0x41, 0x1d, 0xdf, 0xb7, 0xf0, 0x8c, 0x0e, 0xaf, 0xa4, 0x9d, 0xe7, 0xdb,
-       0x7c, 0xa6, 0x27, 0xb0, 0x17, 0xd6, 0xe3, 0x59, 0x3d, 0x2e, 0x7b, 0x89,
-       0x9b, 0x83, 0xdb, 0x52, 0x2f, 0xa2, 0x7f, 0x11, 0x36, 0xa1, 0x62, 0xb3,
-       0xed, 0x6d, 0x6b, 0x79, 0x8c, 0xa2, 0x5f, 0x0a, 0x1f, 0x78, 0xc9, 0xfa,
-       0x92, 0xff, 0x92, 0x55, 0xa8, 0xbe, 0x6d, 0x15, 0x21, 0x27, 0x55, 0x8f,
-       0xf1, 0x0b, 0xf5, 0xc7, 0xc1, 0xda, 0x99, 0xd4, 0x5b, 0xaa, 0x37, 0x3d,
-       0x0f, 0x2c, 0xb8, 0x1f, 0x3a, 0x5d, 0xb4, 0x17, 0xa4, 0xec, 0xd7, 0xa4,
-       0x74, 0x6c, 0x07, 0xf4, 0x2d, 0x1d, 0xa1, 0x8b, 0x78, 0x56, 0xa1, 0x1f,
-       0x6e, 0xed, 0xf2, 0xa4, 0xd2, 0x92, 0x23, 0xae, 0x6d, 0x83, 0xec, 0xa0,
-       0xae, 0xb6, 0x2c, 0x7f, 0xb7, 0xad, 0xa2, 0x15, 0xb1, 0xee, 0xe0, 0x4a,
-       0x7a, 0xab, 0x72, 0x71, 0x7a, 0x77, 0x35, 0xe8, 0x25, 0x66, 0x00, 0xff,
-       0x3d, 0xe0, 0xbf, 0x07, 0xfc, 0xf7, 0x80, 0xff, 0x1e, 0xf0, 0xdf, 0x83,
-       0x6d, 0xf0, 0x60, 0x03, 0x3c, 0xd8, 0x00, 0x0f, 0x36, 0xc0, 0x83, 0x0d,
-       0xf0, 0x0a, 0x38, 0x27, 0xe2, 0x3c, 0x6d, 0xc8, 0x3d, 0x0d, 0xbb, 0x19,
-       0xf8, 0x39, 0x57, 0x1a, 0xdf, 0x01, 0xfa, 0xe7, 0x6c, 0x91, 0xf1, 0xfe,
-       0x2b, 0xb0, 0xb7, 0x56, 0x3c, 0xdb, 0xf0, 0xc4, 0x1a, 0xfd, 0x9f, 0x35,
-       0x7a, 0xf2, 0x55, 0xd0, 0xa5, 0x50, 0xfe, 0x05, 0xc8, 0x61, 0x0b, 0xe8,
-       0xf9, 0x94, 0xf1, 0x31, 0xbe, 0x61, 0x07, 0x72, 0xd8, 0x86, 0xba, 0xcf,
-       0xa0, 0xae, 0x0d, 0x7d, 0xf6, 0xa3, 0x0f, 0x7d, 0x94, 0x0e, 0x53, 0x17,
-       0xed, 0x47, 0x5f, 0xe5, 0x0b, 0x58, 0x2b, 0x83, 0x7e, 0x1d, 0x98, 0xbb,
-       0x07, 0x7d, 0x6e, 0x46, 0x9f, 0xab, 0x50, 0xa6, 0x6f, 0xdb, 0x8d, 0xf2,
-       0xa7, 0x9b, 0xc6, 0x5c, 0x83, 0xba, 0xcf, 0x36, 0xd5, 0x9d, 0x45, 0x1d,
-       0x62, 0x62, 0xe7, 0x45, 0x33, 0xae, 0x82, 0x72, 0x57, 0x53, 0x9f, 0x57,
-       0x50, 0x37, 0x84, 0xba, 0xbf, 0xc2, 0x13, 0xb1, 0xb0, 0x43, 0x9a, 0xc2,
-       0x36, 0xfa, 0xa9, 0x69, 0xd4, 0xc7, 0x8d, 0xaf, 0xf9, 0x24, 0x7d, 0x2f,
-       0xd8, 0xdc, 0x3f, 0xb6, 0x03, 0xdf, 0x0c, 0xde, 0xab, 0x96, 0xc3, 0xb0,
-       0xfc, 0xcd, 0xa6, 0x32, 0xfb, 0x7e, 0xbf, 0xa9, 0xae, 0x6d, 0xd3, 0xca,
-       0xf2, 0x4f, 0xe3, 0xab, 0xc7, 0xdc, 0xdb, 0xd4, 0xe7, 0xeb, 0x9d, 0x2b,
-       0xcb, 0xbb, 0x5b, 0x56, 0x8f, 0xd9, 0xbe, 0x71, 0x65, 0xdd, 0xad, 0x9b,
-       0x57, 0x96, 0xe9, 0x03, 0x26, 0x11, 0xc3, 0x84, 0xfd, 0x77, 0x7e, 0x22,
-       0x68, 0x27, 0x7f, 0x9b, 0x65, 0x49, 0x2b, 0x23, 0xca, 0x0a, 0xe7, 0xb0,
-       0x64, 0x41, 0x9f, 0x1c, 0x95, 0x7b, 0xc9, 0x2a, 0x42, 0xa6, 0x0a, 0x7e,
-       0x38, 0x1f, 0x75, 0xb6, 0x39, 0x4f, 0x10, 0xe6, 0x07, 0xe8, 0x6f, 0xb5,
-       0x43, 0x6e, 0xee, 0xa2, 0x4d, 0x3a, 0x54, 0x91, 0x65, 0xfd, 0xdc, 0xaa,
-       0xce, 0xa7, 0x9f, 0xf7, 0x19, 0x8c, 0x3a, 0x07, 0x3a, 0xeb, 0x32, 0x92,
-       0x5d, 0x47, 0x1b, 0x63, 0xb0, 0x8b, 0xb8, 0x53, 0xaf, 0xc7, 0xb6, 0xd7,
-       0x65, 0x5f, 0xf6, 0xdd, 0xba, 0x68, 0xcc, 0xbb, 0x57, 0xe3, 0x4e, 0x5a,
-       0x75, 0xe3, 0x8c, 0x1c, 0xc4, 0x12, 0x88, 0xed, 0x93, 0xb4, 0x49, 0xc7,
-       0xe9, 0x9f, 0x1c, 0x0c, 0x30, 0x95, 0xb8, 0x83, 0xb2, 0x3f, 0x85, 0x39,
-       0xb9, 0x3e, 0x9e, 0x55, 0xe2, 0xb8, 0xad, 0x6d, 0x4a, 0xc9, 0xe1, 0xbc,
-       0x6b, 0x61, 0xe3, 0xbf, 0xd8, 0xf4, 0x0b, 0x6d, 0xf7, 0x24, 0xec, 0x1b,
-       0xdb, 0xe8, 0x2b, 0x9c, 0xa4, 0x5f, 0x12, 0xc1, 0xaa, 0x9b, 0x62, 0xe2,
-       0x2e, 0x63, 0x66, 0xb0, 0xaf, 0x2d, 0xf4, 0xfb, 0x2f, 0x61, 0xaf, 0x6b,
-       0x63, 0x51, 0xaf, 0xba, 0xb8, 0x6e, 0xef, 0x69, 0xe8, 0x76, 0x28, 0x7b,
-       0x6b, 0xe5, 0x03, 0x5e, 0xd5, 0x67, 0xf1, 0xac, 0x9f, 0x39, 0x5c, 0x81,
-       0x2e, 0x2d, 0xea, 0xd8, 0x37, 0x3c, 0x17, 0xfa, 0x38, 0x99, 0xe3, 0x73,
-       0x90, 0xed, 0xbd, 0x3a, 0x26, 0x60, 0x3c, 0x50, 0x97, 0x5d, 0xd9, 0x4f,
-       0x25, 0xc9, 0x87, 0xbc, 0xfa, 0x71, 0x9c, 0x3e, 0xc3, 0xa2, 0x47, 0x9e,
-       0x65, 0xd1, 0x9e, 0x05, 0x26, 0xfc, 0xab, 0x14, 0x93, 0xac, 0x7b, 0xab,
-       0x3e, 0x0f, 0xbf, 0x4a, 0xfb, 0x47, 0xda, 0xde, 0xd3, 0xbf, 0x83, 0x5d,
-       0xf7, 0xc9, 0xd3, 0x25, 0xf0, 0x39, 0xf4, 0x01, 0x7e, 0x40, 0x1f, 0x55,
-       0x56, 0xfa, 0xd2, 0x22, 0x0f, 0xd5, 0xfe, 0x01, 0x36, 0x47, 0x05, 0xbe,
-       0x0a, 0xe3, 0x65, 0x97, 0xf5, 0x37, 0xc6, 0xe9, 0xcb, 0x05, 0xb6, 0x3e,
-       0x86, 0xf5, 0x10, 0x5f, 0xd7, 0xfe, 0xd3, 0x2a, 0x79, 0x3d, 0xf4, 0xb3,
-       0xb0, 0x7f, 0xf8, 0x50, 0x3e, 0xdb, 0x58, 0x97, 0x30, 0xfe, 0x77, 0xbb,
-       0xf1, 0xb7, 0x1d, 0xe3, 0x6f, 0x6b, 0x3a, 0x12, 0x4e, 0x2e, 0xf4, 0x0b,
-       0x78, 0x66, 0xe9, 0x83, 0x6a, 0x3b, 0xfd, 0x82, 0x0e, 0x59, 0xdb, 0x2f,
-       0x08, 0x69, 0x3a, 0x85, 0x7d, 0xd2, 0xcf, 0xd3, 0x79, 0xa0, 0xce, 0x20,
-       0xf7, 0x44, 0x1a, 0x42, 0xfb, 0xa8, 0xed, 0xf0, 0x21, 0x98, 0x3c, 0xe6,
-       0x24, 0x41, 0xeb, 0x6e, 0x29, 0x4c, 0x9f, 0x32, 0xf6, 0x96, 0x71, 0x04,
-       0x7d, 0xf8, 0x40, 0x66, 0x0b, 0xd9, 0x0e, 0xcb, 0xcc, 0xd3, 0x05, 0x0b,
-       0x19, 0xc9, 0x51, 0x71, 0x2d, 0xfa, 0x31, 0xa1, 0x4f, 0xb3, 0x60, 0x7c,
-       0x9a, 0x33, 0xb2, 0xcf, 0x0b, 0xe2, 0x86, 0x91, 0xda, 0x12, 0xea, 0x34,
-       0xed, 0x29, 0xfa, 0x96, 0x0a, 0x3e, 0x77, 0xfe, 0xde, 0x0c, 0x02, 0x90,
-       0x60, 0x2f, 0x5b, 0xb1, 0x97, 0x6a, 0x63, 0x2f, 0x6d, 0x4b, 0xcd, 0x3e,
-       0x0e, 0xc7, 0x4e, 0xae, 0x1a, 0x2b, 0xd8, 0xc7, 0xdc, 0x79, 0xda, 0xb8,
-       0x47, 0xfa, 0x0d, 0x8e, 0xd9, 0x63, 0x78, 0x4e, 0x8f, 0x63, 0x8f, 0x49,
-       0xab, 0xa4, 0x7d, 0x2d, 0xfa, 0x2d, 0x88, 0xb3, 0x6b, 0x2f, 0xe1, 0x49,
-       0xfd, 0xd0, 0xf3, 0x60, 0x4f, 0xed, 0x7a, 0x4f, 0x53, 0xde, 0x2b, 0x7a,
-       0x1f, 0xf3, 0xb5, 0xbf, 0x91, 0xf2, 0xb1, 0x1f, 0xc0, 0xee, 0x45, 0x73,
-       0x73, 0xcc, 0x6b, 0x92, 0x1f, 0x95, 0x08, 0x7e, 0x72, 0xaf, 0xcc, 0xbb,
-       0xbd, 0x1c, 0x0f, 0xe2, 0x83, 0x69, 0x9c, 0xb1, 0x15, 0xb4, 0xeb, 0xf5,
-       0x43, 0xbe, 0xb6, 0x44, 0xe8, 0xa9, 0xc3, 0xe7, 0x4c, 0x81, 0x86, 0xe8,
-       0x98, 0x03, 0x32, 0xec, 0xf1, 0x3c, 0x7a, 0x53, 0x7b, 0xc5, 0x75, 0x4a,
-       0x12, 0xfa, 0x19, 0x5c, 0x9f, 0x3a, 0x5f, 0x84, 0xe3, 0xcb, 0x5c, 0x6a,
-       0xc8, 0xbb, 0x90, 0x6f, 0xed, 0x4b, 0xcd, 0x32, 0x30, 0x89, 0x58, 0xab,
-       0xec, 0x91, 0x4f, 0xa1, 0x6c, 0x86, 0x6b, 0xbf, 0x6a, 0x71, 0x3f, 0x13,
-       0x3a, 0x7f, 0xf8, 0x4f, 0x0d, 0x19, 0x1d, 0x07, 0x76, 0x04, 0x32, 0xf7,
-       0xf7, 0x86, 0x37, 0xa1, 0x6c, 0xb6, 0x9b, 0x73, 0x66, 0x2c, 0x48, 0xdd,
-       0x09, 0xe5, 0x60, 0x9b, 0x73, 0xa7, 0xe6, 0x05, 0xdb, 0xb4, 0xcf, 0xad,
-       0xcf, 0x72, 0xac, 0x71, 0x96, 0x1b, 0x9a, 0xe4, 0xf2, 0xdd, 0x8d, 0x81,
-       0x1e, 0x52, 0xdf, 0xa0, 0xb7, 0xe0, 0xd7, 0xb3, 0x2b, 0xf4, 0xbb, 0xff,
-       0x3c, 0x39, 0xd9, 0x76, 0x89, 0xcd, 0x7e, 0x0f, 0xbc, 0xbc, 0x06, 0xb1,
-       0x8a, 0x88, 0x3d, 0x43, 0x1c, 0xa2, 0xbf, 0xb1, 0xec, 0xef, 0xce, 0xcb,
-       0x5a, 0xbe, 0xee, 0xc5, 0x7c, 0x8d, 0x4f, 0x5e, 0xa2, 0xaf, 0x31, 0xdc,
-       0x22, 0xad, 0xc4, 0xa2, 0x33, 0xf0, 0x6d, 0x2d, 0x69, 0x71, 0xbf, 0x01,
-       0x1b, 0x76, 0xda, 0x5e, 0xe7, 0x86, 0x98, 0xd0, 0x2e, 0x9b, 0x66, 0xb7,
-       0x68, 0x5c, 0x70, 0x66, 0x96, 0x71, 0x61, 0x1c, 0xbc, 0x1f, 0x09, 0xf2,
-       0xbc, 0xc9, 0x4d, 0x72, 0xa9, 0xf1, 0xf5, 0xb2, 0xdf, 0x3f, 0xd6, 0xf0,
-       0xfb, 0xaf, 0x6c, 0xe2, 0xe3, 0x5a, 0xb8, 0x78, 0x1a, 0x7c, 0xcb, 0x21,
-       0xfe, 0x65, 0x5c, 0x3b, 0x8c, 0x78, 0x98, 0xb1, 0x58, 0x1e, 0x31, 0x71,
-       0xe6, 0xb4, 0xc8, 0x6e, 0xc4, 0xc8, 0x99, 0x1f, 0x31, 0x7f, 0xf5, 0xbc,
-       0x9f, 0x99, 0x13, 0xb9, 0x1d, 0x7c, 0x1d, 0x04, 0x6e, 0x66, 0x81, 0xa3,
-       0x3b, 0xc1, 0xdf, 0x7e, 0x8d, 0x9d, 0xf7, 0x1f, 0x11, 0xeb, 0x0e, 0x9d,
-       0xab, 0xa6, 0x3e, 0x27, 0x61, 0x47, 0xeb, 0xf5, 0xfd, 0xd9, 0x5e, 0xc4,
-       0xf5, 0x69, 0xb9, 0xd5, 0x66, 0x1c, 0x6b, 0xd9, 0x5b, 0x07, 0xe6, 0x63,
-       0x51, 0x9f, 0xb4, 0x70, 0x51, 0x3b, 0xb0, 0x9a, 0xf7, 0x45, 0x6d, 0x0b,
-       0x0e, 0xc7, 0x2e, 0xc4, 0xfb, 0x3b, 0x1a, 0xbc, 0x6f, 0x69, 0x95, 0xd6,
-       0xdb, 0x75, 0x1e, 0x61, 0xeb, 0xc0, 0x7e, 0xe2, 0x55, 0x16, 0x76, 0x1d,
-       0xf6, 0xb7, 0x2e, 0xb7, 0x65, 0xdf, 0xae, 0xbf, 0xe8, 0x6e, 0x94, 0xd2,
-       0xce, 0xfb, 0x0c, 0x66, 0x2f, 0x7d, 0xad, 0xe0, 0x56, 0xa0, 0x1f, 0x41,
-       0xce, 0x70, 0xef, 0x74, 0x02, 0x96, 0x80, 0x7f, 0x9d, 0x32, 0x3f, 0xf4,
-       0x16, 0xce, 0x70, 0xc7, 0x49, 0x26, 0x9c, 0x14, 0x70, 0x78, 0x3e, 0xd9,
-       0xae, 0xf3, 0xc5, 0x9f, 0x70, 0x59, 0xef, 0xe0, 0x4c, 0x47, 0x65, 0x1e,
-       0xfe, 0x43, 0x75, 0x08, 0x34, 0xee, 0xec, 0x42, 0x7f, 0xea, 0x1d, 0x79,
-       0x3e, 0x0a, 0xdb, 0x4b, 0x9e, 0x26, 0xd1, 0x7f, 0x0f, 0xfa, 0x74, 0xe2,
-       0x79, 0x5f, 0x6c, 0xde, 0x61, 0xec, 0xfc, 0x79, 0x94, 0x39, 0x47, 0xd4,
-       0x76, 0x7e, 0x2e, 0x2e, 0x7a, 0x4e, 0x8e, 0xe9, 0xd2, 0xfa, 0xbf, 0xbc,
-       0x16, 0xd7, 0x61, 0xdb, 0xcf, 0xea, 0xd7, 0x0f, 0x0c, 0x45, 0xd6, 0xeb,
-       0x88, 0xac, 0x37, 0x14, 0x59, 0x8f, 0x74, 0x76, 0x46, 0xe8, 0xec, 0xc4,
-       0xf8, 0x22, 0xd6, 0x26, 0x3f, 0xa2, 0x6b, 0x3e, 0x18, 0x59, 0x33, 0xdc,
-       0x5f, 0x57, 0x64, 0xdc, 0xbb, 0x58, 0x8f, 0x75, 0xc9, 0x48, 0x1d, 0x69,
-       0xd8, 0x8c, 0x3a, 0x96, 0x3b, 0x23, 0x74, 0x91, 0xd6, 0x0d, 0xa8, 0xd7,
-       0xfe, 0x13, 0xf8, 0xdc, 0x0a, 0xbb, 0xa5, 0x60, 0x3b, 0x5a, 0xe0, 0x5f,
-       0x35, 0xef, 0xf5, 0x51, 0xac, 0x1b, 0xce, 0x97, 0xc4, 0x1c, 0xec, 0xcf,
-       0xbe, 0x31, 0x33, 0x9e, 0xf5, 0x6c, 0xff, 0xf3, 0xfa, 0x9f, 0x6a, 0xbe,
-       0x6d, 0x06, 0xed, 0x3a, 0xef, 0x22, 0x73, 0x9d, 0x36, 0xce, 0x93, 0xf1,
-       0xb1, 0x25, 0x57, 0xbb, 0xca, 0xea, 0x1d, 0xe0, 0xd9, 0x6f, 0x34, 0x58,
-       0xda, 0x6a, 0x15, 0x8e, 0x30, 0x5f, 0xd0, 0x66, 0x62, 0x3e, 0xc4, 0x1e,
-       0xda, 0xc6, 0xd8, 0xa6, 0x9d, 0x36, 0x86, 0x7e, 0x0b, 0xed, 0xe7, 0x69,
-       0xf3, 0x8e, 0x27, 0x64, 0xf8, 0x81, 0x6a, 0xa7, 0xbc, 0xa8, 0x79, 0xea,
-       0xc8, 0xd9, 0x06, 0x4f, 0xe3, 0xe6, 0xbb, 0xcc, 0x01, 0xf3, 0xcd, 0xa3,
-       0x0f, 0x7e, 0x11, 0xde, 0x6b, 0x79, 0xd0, 0x90, 0x96, 0xde, 0x01, 0xc6,
-       0x6e, 0x15, 0x3c, 0x99, 0xa7, 0xb0, 0xf0, 0x0c, 0xf2, 0x17, 0xbd, 0x03,
-       0xb0, 0x4b, 0xc0, 0xa1, 0xde, 0x81, 0x73, 0x3a, 0x9e, 0xab, 0xfa, 0x8e,
-       0x75, 0x9b, 0x17, 0xe4, 0x88, 0xce, 0xba, 0x17, 0xca, 0x11, 0xdd, 0xb3,
-       0x8e, 0x79, 0x8d, 0x30, 0x47, 0x74, 0x56, 0x74, 0x8e, 0xe8, 0xf8, 0x45,
-       0x72, 0x44, 0xf9, 0x4b, 0xcf, 0x11, 0x71, 0x7e, 0x5b, 0xee, 0x1c, 0x74,
-       0xd4, 0xaf, 0x9a, 0x1c, 0xd1, 0x1b, 0x12, 0xe4, 0x88, 0x5e, 0x94, 0xb5,
-       0x73, 0x44, 0x87, 0x9a, 0x72, 0x44, 0x9b, 0x75, 0x8e, 0x88, 0xf3, 0x04,
-       0x39, 0x22, 0x96, 0x4b, 0x03, 0x43, 0x91, 0x5c, 0x07, 0xf0, 0xd7, 0xbb,
-       0x01, 0x7c, 0x73, 0xac, 0x51, 0x2f, 0xc4, 0x34, 0x62, 0xff, 0x15, 0x0d,
-       0xfb, 0xb5, 0x8c, 0x6f, 0x96, 0x96, 0xb9, 0x8b, 0xe1, 0xdb, 0x68, 0xe0,
-       0x97, 0xac, 0xc0, 0xb6, 0xc9, 0x86, 0xef, 0xe2, 0xad, 0x63, 0x0c, 0x3d,
-       0x51, 0x5b, 0x9e, 0x77, 0x02, 0xbc, 0x1e, 0x6b, 0xe4, 0x49, 0xce, 0xe7,
-       0x1f, 0x25, 0xe5, 0xc0, 0x9a, 0xdf, 0xbd, 0x52, 0xf9, 0xd5, 0xdf, 0xbd,
-       0x2c, 0x49, 0x82, 0xce, 0xd2, 0x40, 0x49, 0xc7, 0x5d, 0xf3, 0xde, 0xaf,
-       0xc8, 0xd2, 0xdd, 0x0e, 0xf0, 0x27, 0xcc, 0x9f, 0xf0, 0x7c, 0x97, 0x6d,
-       0x4a, 0x41, 0x7d, 0x7c, 0x39, 0x94, 0x07, 0x74, 0x0e, 0xe5, 0xc5, 0x75,
-       0xd1, 0x1c, 0xca, 0x59, 0xb9, 0x70, 0x0e, 0xe5, 0x81, 0x35, 0x72, 0x28,
-       0x2f, 0xcb, 0x72, 0x0e, 0xe5, 0x65, 0x09, 0x73, 0x28, 0x31, 0x59, 0xda,
-       0x1c, 0x48, 0xe3, 0x03, 0xfe, 0x12, 0x7e, 0x67, 0xf0, 0x0b, 0x72, 0x2a,
-       0x67, 0x1b, 0xf4, 0xaf, 0x95, 0x53, 0x79, 0x7d, 0xdd, 0x07, 0xc9, 0xa9,
-       0x04, 0x36, 0x20, 0xcc, 0xa9, 0xe0, 0xe7, 0xc0, 0xe6, 0xa8, 0x68, 0x4e,
-       0xe5, 0x27, 0xd4, 0x07, 0xd4, 0xb1, 0xcc, 0x7a, 0xe8, 0x05, 0xec, 0x52,
-       0x5e, 0xe7, 0x38, 0x3e, 0x67, 0x78, 0x38, 0x87, 0x3d, 0xa7, 0x71, 0x16,
-       0xe4, 0x63, 0xaf, 0xf6, 0x2d, 0xf3, 0x76, 0xca, 0x2a, 0xf4, 0xc1, 0x9a,
-       0x4d, 0xf3, 0xbb, 0xb8, 0x6d, 0xed, 0xf5, 0x29, 0xe3, 0x09, 0xab, 0x8c,
-       0xbd, 0x0c, 0x4f, 0xcf, 0xc9, 0x5e, 0x3f, 0xf4, 0xa9, 0x06, 0x1a, 0x73,
-       0x50, 0x37, 0xe7, 0x81, 0xb3, 0xc0, 0x89, 0x4b, 0xb0, 0x51, 0xa7, 0x40,
-       0x73, 0x74, 0x1f, 0x88, 0x89, 0x07, 0x51, 0xa7, 0xcf, 0x9c, 0xbe, 0x65,
-       0x48, 0x4b, 0x9a, 0x7a, 0x7e, 0x09, 0xf3, 0xb1, 0xee, 0x94, 0x8e, 0xc7,
-       0xca, 0x83, 0xdc, 0x2b, 0x6d, 0xdd, 0x22, 0xe8, 0x43, 0x5d, 0x95, 0x31,
-       0x20, 0xed, 0x5e, 0x18, 0xa3, 0xb5, 0xeb, 0x18, 0xad, 0x4b, 0xf3, 0x83,
-       0xbc, 0xbe, 0x35, 0x41, 0xac, 0xec, 0x72, 0xb9, 0x87, 0x33, 0x06, 0xeb,
-       0x58, 0x0e, 0x62, 0xc1, 0xbc, 0xe2, 0xfb, 0xef, 0xe1, 0x5c, 0x99, 0xa7,
-       0x09, 0xcf, 0xef, 0x2b, 0x66, 0xdf, 0x43, 0x52, 0xe9, 0x92, 0xc4, 0x66,
-       0xd0, 0x53, 0x9a, 0xa1, 0xdf, 0xfd, 0x69, 0x1d, 0x83, 0x24, 0xdd, 0xf3,
-       0xeb, 0xed, 0x1d, 0x97, 0xa1, 0xb7, 0x23, 0x17, 0xd4, 0xdb, 0xaf, 0x25,
-       0xa2, 0x7a, 0x7b, 0xc7, 0x65, 0xe8, 0xed, 0xbe, 0xcb, 0xd2, 0x5b, 0xee,
-       0x8d, 0x98, 0x14, 0xe6, 0xc4, 0x56, 0xfb, 0x59, 0xe1, 0xba, 0xe3, 0x58,
-       0x33, 0x7f, 0x9e, 0x35, 0xc7, 0xce, 0x9b, 0x5b, 0x6d, 0xf6, 0xb1, 0x2e,
-       0xe5, 0xbc, 0x19, 0x5b, 0xd1, 0xde, 0xb6, 0x1b, 0xbb, 0x74, 0x9f, 0x89,
-       0xe7, 0xc3, 0xb8, 0x3e, 0xaa, 0x3f, 0x94, 0x0b, 0xca, 0xc2, 0x77, 0xc0,
-       0x2f, 0xca, 0x43, 0xa8, 0x73, 0xdd, 0x4d, 0x32, 0xb8, 0x88, 0x78, 0xbf,
-       0xdb, 0xc8, 0x20, 0xcf, 0xba, 0x4f, 0x7f, 0x67, 0xaa, 0x7a, 0x4f, 0x05,
-       0x71, 0xbe, 0x8b, 0x67, 0x35, 0xd4, 0x35, 0xf0, 0x24, 0x19, 0xb6, 0x91,
-       0x8f, 0x2e, 0x7c, 0x9e, 0x1d, 0xf0, 0xd7, 0xc0, 0x23, 0x5d, 0xbf, 0x32,
-       0x27, 0x7c, 0x61, 0x3c, 0x93, 0x4a, 0x1c, 0x7d, 0x4f, 0x0c, 0x42, 0xc7,
-       0x07, 0x89, 0x51, 0x35, 0xc4, 0x3d, 0x94, 0x43, 0xca, 0xe6, 0xb6, 0xfe,
-       0x5d, 0x8a, 0x3e, 0xd5, 0x13, 0x88, 0x83, 0x29, 0xaf, 0x69, 0xd9, 0xe5,
-       0x6f, 0x3b, 0x7d, 0x56, 0x71, 0x8d, 0x7a, 0xbd, 0xc4, 0x58, 0xd1, 0x11,
-       0xb5, 0x75, 0xe0, 0xbf, 0x13, 0xb4, 0x4b, 0x57, 0xb8, 0x31, 0x23, 0x6b,
-       0x79, 0xbc, 0x53, 0x6e, 0x7f, 0x08, 0x7b, 0xcf, 0xef, 0xfd, 0xaf, 0xa1,
-       0x3e, 0x05, 0x9d, 0xa7, 0x7d, 0x67, 0x3c, 0x72, 0x93, 0xe9, 0xd7, 0xad,
-       0xbf, 0x57, 0x16, 0xb2, 0x37, 0x98, 0x6f, 0x57, 0xb4, 0x3f, 0x19, 0xda,
-       0xec, 0x15, 0xe7, 0xcc, 0xfb, 0x12, 0x45, 0x1d, 0xcf, 0x70, 0xbc, 0x96,
-       0x49, 0xc4, 0x20, 0x76, 0x24, 0x97, 0x9e, 0x30, 0xb1, 0x1b, 0x75, 0xac,
-       0x1d, 0x67, 0xe8, 0x9b, 0x58, 0x85, 0xf1, 0xeb, 0xca, 0x7b, 0x12, 0x6b,
-       0xcb, 0xc0, 0x96, 0x0f, 0x20, 0x03, 0xcd, 0xe7, 0x97, 0x80, 0xee, 0x87,
-       0xe7, 0x17, 0xfa, 0x31, 0x73, 0x66, 0xdf, 0xdd, 0xc1, 0x19, 0xfe, 0xbf,
-       0xd8, 0xa7, 0x15, 0xd9, 0x67, 0x88, 0x47, 0x0f, 0x98, 0x7d, 0xde, 0xd4,
-       0x84, 0x47, 0x23, 0x4d, 0x3a, 0xfb, 0x71, 0xe2, 0xd1, 0x9f, 0xac, 0xff,
-       0xf8, 0xf1, 0x88, 0xfb, 0xea, 0x5e, 0x13, 0x87, 0x82, 0x7d, 0x3c, 0x22,
-       0x2a, 0xf7, 0x51, 0xc6, 0x7b, 0x1f, 0xe4, 0x7c, 0xa2, 0x38, 0xc2, 0x33,
-       0xe9, 0xd0, 0x3e, 0x6c, 0xa0, 0x7b, 0xb0, 0xe5, 0xd5, 0xb8, 0xbc, 0x7e,
-       0x57, 0x42, 0xfe, 0xf7, 0x46, 0x7e, 0x0f, 0xb3, 0x4d, 0x4e, 0x8b, 0xe5,
-       0xd7, 0xd6, 0x07, 0x76, 0xe8, 0xb5, 0x4d, 0x81, 0xdd, 0xe1, 0x98, 0x50,
-       0x9f, 0x1d, 0xb4, 0xb3, 0xad, 0x5b, 0x96, 0x3a, 0x2f, 0x27, 0x06, 0xdc,
-       0xe6, 0xbc, 0xa1, 0xd6, 0x8a, 0x01, 0x2f, 0x9c, 0x0f, 0x5c, 0x8e, 0x01,
-       0x89, 0xb3, 0x9d, 0x5a, 0x36, 0x4a, 0x49, 0xc6, 0x3e, 0x7d, 0x06, 0x3b,
-       0xf9, 0x8e, 0xd8, 0xd6, 0x43, 0xbc, 0xeb, 0x21, 0xd6, 0xf5, 0x10, 0xff,
-       0x7a, 0x88, 0x71, 0x3d, 0xc4, 0xb6, 0x1e, 0x62, 0x5b, 0x0f, 0xb1, 0xad,
-       0xd7, 0x6f, 0x62, 0xe4, 0x11, 0x93, 0xf7, 0xe7, 0x77, 0x72, 0xe6, 0x17,
-       0x2a, 0xb0, 0x25, 0x93, 0xbc, 0xe7, 0xa0, 0x0a, 0xd9, 0xf5, 0x66, 0x7f,
-       0x61, 0x4e, 0xbc, 0xc7, 0xe4, 0x6c, 0x5e, 0xd7, 0x79, 0x43, 0x51, 0xb3,
-       0xad, 0xc1, 0xb7, 0x74, 0xde, 0xc7, 0xf8, 0x2d, 0xf8, 0x25, 0xfa, 0x3e,
-       0x13, 0x75, 0xb4, 0xae, 0x72, 0xcc, 0xc9, 0x88, 0x52, 0xb9, 0xeb, 0x31,
-       0x66, 0x47, 0x10, 0x13, 0x24, 0x25, 0xa6, 0x72, 0x6d, 0xe4, 0xa9, 0xa5,
-       0x72, 0x1b, 0xcc, 0x5c, 0x47, 0x5b, 0x03, 0xdf, 0xaa, 0x8f, 0x65, 0x5b,
-       0xe5, 0x6e, 0xe6, 0x13, 0xe7, 0x1e, 0xd6, 0xf7, 0x74, 0xae, 0x5c, 0x6b,
-       0x4a, 0xe3, 0x7b, 0x21, 0x7b, 0x37, 0xe6, 0xd3, 0xf7, 0x88, 0x1a, 0xfc,
-       0x56, 0xe7, 0xe5, 0xf7, 0x94, 0xe1, 0x77, 0xc0, 0xe3, 0x18, 0xfb, 0xe9,
-       0xbc, 0x30, 0x79, 0x1d, 0xce, 0xa7, 0xf3, 0x7a, 0x58, 0x47, 0xdf, 0xa5,
-       0xc0, 0x53, 0xc5, 0xa5, 0x63, 0xf4, 0x9e, 0xb8, 0x1b, 0x5d, 0x37, 0xfc,
-       0x26, 0x7e, 0x29, 0x6b, 0x76, 0xeb, 0xef, 0x68, 0x81, 0xcd, 0x98, 0xd2,
-       0x32, 0x68, 0xe7, 0xb8, 0xaf, 0xf7, 0x21, 0x7f, 0x53, 0x5a, 0xfe, 0x8a,
-       0x88, 0x63, 0x26, 0x07, 0xb7, 0xa5, 0x6d, 0x75, 0xa0, 0x95, 0xf9, 0xd7,
-       0x61, 0x3f, 0xc4, 0x3d, 0xae, 0xd7, 0x6c, 0xc7, 0x99, 0x57, 0x0b, 0xf1,
-       0x4c, 0xb6, 0x04, 0xf9, 0xb6, 0x0f, 0xa3, 0x4b, 0xad, 0x4d, 0xba, 0x14,
-       0xee, 0x93, 0xfb, 0xe7, 0x73, 0xed, 0x3b, 0x15, 0x8b, 0x7e, 0xe4, 0xfb,
-       0x48, 0x43, 0x36, 0x78, 0xb7, 0xe4, 0x8b, 0x90, 0x41, 0xfd, 0x9d, 0x02,
-       0x7a, 0x54, 0xaf, 0x0f, 0x33, 0xc7, 0xbc, 0xf3, 0x0b, 0xe6, 0xde, 0x82,
-       0x3c, 0xcc, 0xfc, 0x83, 0xbd, 0x2a, 0xff, 0x30, 0x0c, 0x59, 0x81, 0x0f,
-       0xe0, 0x75, 0x68, 0x9f, 0x4e, 0xb9, 0xf4, 0x07, 0x9a, 0xbf, 0xbf, 0x3c,
-       0xda, 0x16, 0xf0, 0xe1, 0xed, 0xd6, 0xe0, 0x1b, 0xc4, 0xdf, 0x26, 0x57,
-       0x96, 0x39, 0xfe, 0x7f, 0x8c, 0xac, 0x1c, 0x86, 0x6d, 0x1e, 0x86, 0x2c,
-       0x22, 0x26, 0xd7, 0xf3, 0x1d, 0x96, 0xd2, 0xd3, 0x0b, 0x9d, 0x2b, 0xfb,
-       0xa3, 0xee, 0x58, 0xd8, 0xff, 0xb1, 0xa6, 0xfe, 0x8f, 0xa1, 0xff, 0x0b,
-       0x4d, 0xfd, 0x1f, 0x8b, 0xf4, 0x3f, 0xda, 0xd4, 0x1f, 0x31, 0xe2, 0xd3,
-       0xff, 0xdc, 0xd4, 0xff, 0x68, 0xa4, 0xff, 0x6c, 0x53, 0xff, 0x59, 0xf4,
-       0x7f, 0xad, 0xa9, 0x3f, 0xea, 0x8e, 0xb5, 0x98, 0xef, 0x62, 0xc4, 0xd8,
-       0x7d, 0x26, 0x16, 0xc7, 0xb3, 0xd6, 0xfc, 0xad, 0x85, 0x72, 0xd7, 0x83,
-       0x33, 0x08, 0xef, 0xb4, 0x51, 0x5f, 0xf3, 0xd0, 0xd7, 0x65, 0x5f, 0x26,
-       0x90, 0xc7, 0xa8, 0x2c, 0x12, 0x1f, 0x2a, 0x12, 0x73, 0x7d, 0xfa, 0x47,
-       0x56, 0xb9, 0x1a, 0xda, 0x24, 0xde, 0x5b, 0xe2, 0x7d, 0xd7, 0xc0, 0xf6,
-       0xc6, 0xdd, 0x45, 0x13, 0x83, 0x5d, 0xd1, 0x06, 0xda, 0x81, 0x97, 0x21,
-       0x66, 0xca, 0xe1, 0x40, 0x6f, 0x28, 0xbf, 0x9c, 0xdf, 0xe8, 0x0f, 0x65,
-       0xd5, 0xac, 0x33, 0xbc, 0x0a, 0xd7, 0xd2, 0xab, 0x72, 0x5b, 0xb1, 0x4b,
-       0xc0, 0xb5, 0x91, 0x06, 0xae, 0x7d, 0x51, 0xe6, 0x1a, 0xf1, 0xf6, 0x19,
-       0xd9, 0xef, 0xed, 0xe1, 0x3d, 0x9d, 0xc3, 0x79, 0xf9, 0x68, 0xe2, 0xed,
-       0x3d, 0x0d, 0x3b, 0xc9, 0x3b, 0x1d, 0xe9, 0x83, 0xbc, 0x83, 0x1b, 0xe6,
-       0x66, 0x27, 0xbd, 0x5f, 0xc7, 0xfe, 0x69, 0x33, 0x2f, 0x37, 0xde, 0xe6,
-       0x7c, 0x49, 0xd9, 0x1f, 0xdc, 0x77, 0x68, 0xcc, 0x5b, 0x69, 0xcc, 0x9b,
-       0x32, 0xfa, 0x46, 0x1b, 0xbc, 0x6c, 0x2f, 0x8b, 0xb0, 0x97, 0x63, 0x88,
-       0xb9, 0x17, 0xbd, 0xb5, 0xf2, 0xa3, 0x97, 0x6b, 0x2f, 0x9b, 0xf3, 0xcc,
-       0xcd, 0xf6, 0x92, 0xeb, 0x34, 0xe7, 0x96, 0xd3, 0x4d, 0xf8, 0x4f, 0x79,
-       0x3a, 0x67, 0x7c, 0x6a, 0x3c, 0xab, 0xe7, 0xa0, 0x8f, 0x4a, 0xc6, 0xb4,
-       0xfc, 0xb2, 0x1c, 0xc6, 0x96, 0xf7, 0x34, 0x62, 0xcb, 0xe5, 0x78, 0x10,
-       0xbe, 0x6b, 0xff, 0x67, 0x0c, 0x3e, 0xd2, 0x47, 0x76, 0xac, 0xb2, 0xb7,
-       0x5b, 0xed, 0xd5, 0x6d, 0xcc, 0x97, 0x5e, 0x2b, 0xb7, 0xea, 0x38, 0xfe,
-       0x8c, 0xc9, 0x4d, 0xcd, 0x69, 0xff, 0x9f, 0xdf, 0x0b, 0xca, 0xd9, 0x4d,
-       0xc6, 0xdf, 0xbb, 0x18, 0xae, 0xae, 0x8c, 0x4d, 0x95, 0x3a, 0x88, 0xb1,
-       0x8c, 0x4d, 0xfb, 0xdb, 0x89, 0xa1, 0x05, 0xff, 0x82, 0xe3, 0x31, 0x8e,
-       0xe3, 0xd9, 0x47, 0xc7, 0xa1, 0xe8, 0xb7, 0x68, 0xc6, 0x07, 0x71, 0x68,
-       0xc1, 0xff, 0x71, 0x5b, 0x80, 0x83, 0x17, 0x8a, 0x59, 0x3e, 0xdf, 0xce,
-       0xbc, 0xde, 0xa2, 0x77, 0x31, 0x5a, 0x57, 0xc7, 0xbd, 0xb1, 0x55, 0x71,
-       0xaf, 0x6d, 0xe2, 0xda, 0x5f, 0xd2, 0x71, 0x6f, 0xc0, 0x63, 0xee, 0x25,
-       0x1a, 0x47, 0xb9, 0xc0, 0x42, 0x7e, 0x53, 0x21, 0x3e, 0xd0, 0x47, 0x81,
-       0x9f, 0x35, 0xfd, 0x8b, 0xe0, 0x73, 0x72, 0x0d, 0xb9, 0xf9, 0xb8, 0xed,
-       0x44, 0xb8, 0xf7, 0x73, 0x12, 0xe4, 0xeb, 0x76, 0x83, 0x16, 0xc6, 0x56,
-       0x71, 0x23, 0x0f, 0x3f, 0x35, 0xf7, 0x2a, 0xc3, 0x7e, 0x61, 0x1c, 0xdf,
-       0xf8, 0xee, 0x5a, 0xc9, 0xaf, 0xc8, 0x9f, 0x74, 0x33, 0x0d, 0x8d, 0x73,
-       0xcf, 0x5f, 0xc6, 0x77, 0x8b, 0x0f, 0x73, 0x3f, 0xa2, 0xd9, 0xae, 0xf1,
-       0xbb, 0x29, 0xbf, 0x95, 0x8a, 0x75, 0x67, 0x9f, 0x0b, 0x1d, 0xe0, 0xbd,
-       0xe1, 0x28, 0xbe, 0x26, 0xa4, 0x34, 0x2b, 0x89, 0x64, 0x8e, 0xdf, 0x00,
-       0x68, 0xff, 0x7f, 0x68, 0xf6, 0x99, 0x92, 0x7d, 0x33, 0x41, 0xce, 0x53,
-       0x5d, 0xf0, 0x5e, 0xdc, 0xe3, 0xe0, 0x43, 0xe6, 0x50, 0x98, 0xf3, 0x54,
-       0xc1, 0xbd, 0xb8, 0x43, 0x1f, 0xdd, 0xbd, 0x38, 0xce, 0x6f, 0xcb, 0x9e,
-       0x35, 0xee, 0xc5, 0xc5, 0x2e, 0xf1, 0x5e, 0xdc, 0x26, 0x9d, 0xf3, 0xe4,
-       0x3c, 0x41, 0xce, 0x93, 0xe5, 0xad, 0x03, 0xcc, 0x95, 0xf0, 0xee, 0xdb,
-       0xa0, 0xbe, 0x2f, 0xbc, 0x75, 0xe0, 0xe7, 0x11, 0xa3, 0xfc, 0x75, 0xfb,
-       0xc7, 0x1f, 0xa3, 0x70, 0x2f, 0xbf, 0x11, 0x7c, 0xdf, 0x95, 0xcb, 0xc9,
-       0x03, 0x7c, 0xb8, 0xbc, 0xe6, 0x3e, 0x9d, 0xd7, 0x7c, 0xa7, 0x3d, 0x9a,
-       0xd7, 0x54, 0x17, 0xb9, 0x1b, 0xb6, 0x6f, 0x8d, 0xbc, 0x66, 0x3c, 0x72,
-       0x37, 0x2c, 0x6e, 0xee, 0x86, 0x6d, 0x72, 0x11, 0x4b, 0x9a, 0x3c, 0xa6,
-       0xba, 0xe0, 0xdd, 0xb0, 0xce, 0x0d, 0x1f, 0x3e, 0x8f, 0xb9, 0xea, 0x6e,
-       0x18, 0x6c, 0xdd, 0x16, 0x49, 0x5f, 0x56, 0xdc, 0xf3, 0x61, 0x62, 0x1e,
-       0xde, 0xab, 0x6f, 0xc1, 0x9e, 0xe3, 0xb2, 0x27, 0x49, 0xf9, 0xe4, 0xdd,
-       0xc6, 0x3e, 0xe8, 0x02, 0x9e, 0x3e, 0xcb, 0xfd, 0x3c, 0x23, 0x6b, 0xa4,
-       0x6f, 0xe5, 0x3d, 0x84, 0xe5, 0x3b, 0xbd, 0x89, 0xc6, 0x9d, 0xde, 0x29,
-       0xc8, 0x8d, 0x9a, 0x49, 0xc8, 0x7c, 0x44, 0xa6, 0x26, 0x3d, 0xf8, 0x4b,
-       0xb3, 0x8e, 0x69, 0xe7, 0xff, 0xef, 0x48, 0x02, 0xf3, 0x78, 0x0f, 0xb8,
-       0x43, 0x62, 0xb3, 0xc1, 0x37, 0xcb, 0xe0, 0xff, 0xb8, 0xa4, 0xd0, 0x87,
-       0x77, 0x3c, 0xe3, 0xb2, 0x5f, 0xe7, 0x2c, 0x42, 0x59, 0xfe, 0x35, 0xf0,
-       0x78, 0x73, 0x7e, 0xb9, 0x9c, 0x5c, 0xc3, 0xee, 0x27, 0xa5, 0x3c, 0x43,
-       0x79, 0xbe, 0xc1, 0xfc, 0xff, 0x82, 0xd3, 0x52, 0xf6, 0x4f, 0x99, 0xf8,
-       0x42, 0x7f, 0xdb, 0x01, 0x2f, 0xb7, 0x18, 0x1b, 0x8c, 0x67, 0x75, 0x0b,
-       0x6d, 0x1e, 0xd6, 0x38, 0x2e, 0xc3, 0xd3, 0x3b, 0x52, 0x7b, 0x81, 0x77,
-       0x63, 0x7a, 0xcd, 0xcb, 0xe1, 0xb9, 0x75, 0x9e, 0xef, 0x8d, 0x97, 0xca,
-       0xf7, 0xd0, 0x3f, 0xae, 0x62, 0x7f, 0x5b, 0x20, 0x1f, 0x5f, 0x95, 0xe2,
-       0xb1, 0x6b, 0x65, 0xf8, 0x68, 0x06, 0xf4, 0xbc, 0x5f, 0x2f, 0x67, 0xe1,
-       0x4b, 0x3f, 0xcd, 0x7b, 0x63, 0xc0, 0x50, 0xf0, 0xed, 0xf9, 0x55, 0xdf,
-       0xb1, 0xa3, 0x77, 0xcd, 0xfa, 0x1b, 0x77, 0x87, 0x9e, 0xf5, 0x25, 0xd1,
-       0x49, 0x9a, 0x67, 0x96, 0xef, 0x8f, 0x2f, 0xfa, 0xbb, 0xb4, 0x6d, 0x7b,
-       0xc6, 0x5f, 0x91, 0xfb, 0xd1, 0x67, 0x38, 0x5e, 0xfb, 0x1e, 0xec, 0xdb,
-       0x39, 0x8b, 0xf6, 0x6d, 0xca, 0x93, 0xab, 0x63, 0xc2, 0xf3, 0x10, 0x0b,
-       0x3c, 0xd0, 0x77, 0x38, 0x82, 0xef, 0xfb, 0x3d, 0xfa, 0x5c, 0x03, 0xac,
-       0x58, 0x88, 0xdc, 0xc1, 0x58, 0x3e, 0xdb, 0xe0, 0x6e, 0x46, 0x70, 0x16,
-       0xc1, 0xfd, 0x11, 0xed, 0x6f, 0x1e, 0xdc, 0xe3, 0x06, 0xf7, 0x47, 0x7a,
-       0x67, 0x59, 0xd7, 0xd5, 0x64, 0xfb, 0x12, 0x90, 0x01, 0xde, 0x3b, 0xe2,
-       0xbd, 0x71, 0xd2, 0xac, 0x73, 0x1d, 0xff, 0x47, 0xdd, 0xd5, 0xc7, 0xb6,
-       0x75, 0x5d, 0xf7, 0xc3, 0x47, 0xea, 0xc3, 0xb4, 0x2c, 0x53, 0x32, 0x25,
-       0xd3, 0x96, 0x2c, 0xbf, 0x27, 0x3d, 0x59, 0x72, 0xac, 0x14, 0xac, 0xab,
-       0xad, 0x02, 0x46, 0xa4, 0x0c, 0x49, 0x7f, 0xb4, 0x08, 0x06, 0xfa, 0xa3,
-       0x99, 0x8b, 0x66, 0xab, 0x4b, 0xd9, 0x4e, 0x0a, 0xf4, 0x0f, 0xb7, 0xc5,
-       0x80, 0x6c, 0x58, 0x60, 0x86, 0xb4, 0x12, 0x63, 0x56, 0x4c, 0xd6, 0x66,
-       0x85, 0x0c, 0xd8, 0x30, 0x4e, 0x54, 0x9c, 0x14, 0x50, 0xc6, 0x04, 0x69,
-       0x83, 0xa2, 0x58, 0x61, 0x45, 0x76, 0x36, 0x6c, 0x7f, 0x65, 0x43, 0xd0,
-       0x05, 0x9b, 0xb3, 0x38, 0x76, 0xb0, 0x06, 0x45, 0xd6, 0x7d, 0x62, 0x18,
-       0xd0, 0x0d, 0xdc, 0xf9, 0xdd, 0x0f, 0xf2, 0xf1, 0xf1, 0x51, 0x1f, 0x89,
-       0x33, 0x60, 0x02, 0x04, 0xbe, 0xf7, 0x78, 0xdf, 0x7b, 0xf7, 0x9e, 0x7b,
-       0xce, 0xb9, 0xbf, 0x73, 0xee, 0x39, 0x87, 0x9e, 0x7b, 0xdb, 0x9b, 0xf3,
-       0xb9, 0xca, 0x77, 0x8e, 0x8a, 0x77, 0x0e, 0x28, 0x9d, 0xa5, 0xe3, 0xc5,
-       0x63, 0xc6, 0x6c, 0x61, 0x22, 0xe2, 0x67, 0xfe, 0x9e, 0xad, 0xc2, 0xbe,
-       0x6e, 0x87, 0xe1, 0xd6, 0xa2, 0x67, 0xbc, 0x85, 0x9e, 0xcd, 0x32, 0xc1,
-       0xf6, 0x78, 0x5d, 0x77, 0x4b, 0xda, 0xc9, 0xeb, 0x88, 0x85, 0xd7, 0x31,
-       0x0e, 0x92, 0x76, 0x75, 0x19, 0xba, 0xe2, 0x8c, 0x6f, 0x68, 0xd0, 0xee,
-       0x74, 0x9d, 0x76, 0x3b, 0xff, 0x1f, 0xd1, 0xee, 0x1d, 0x81, 0x7f, 0x5f,
-       0xad, 0x22, 0x6e, 0x4d, 0x63, 0x00, 0x9d, 0x3b, 0x04, 0x3a, 0x42, 0x9f,
-       0x5a, 0xe5, 0x15, 0x82, 0x4e, 0x45, 0x5c, 0x71, 0xad, 0xf6, 0x5a, 0xb4,
-       0xee, 0xa7, 0x64, 0xbb, 0x04, 0xf6, 0x09, 0xfc, 0x79, 0xed, 0xd7, 0xc8,
-       0x63, 0x1f, 0x6b, 0x8d, 0x04, 0x56, 0x72, 0xdb, 0x27, 0x0c, 0x08, 0x1d,
-       0xf6, 0xc9, 0xb1, 0x4d, 0xda, 0x27, 0xe7, 0xa5, 0x7d, 0x92, 0xdd, 0xb8,
-       0x7d, 0xb2, 0xbb, 0x25, 0xae, 0xab, 0x31, 0x9e, 0xcd, 0xdb, 0x27, 0xc6,
-       0x9a, 0xf6, 0xc9, 0x90, 0xc3, 0x17, 0x83, 0xfe, 0xfe, 0x06, 0x65, 0x8f,
-       0x43, 0xc7, 0x69, 0x3a, 0x83, 0xc6, 0xc7, 0x5d, 0x7e, 0xe1, 0x4f, 0x93,
-       0xd6, 0xbf, 0xf8, 0x3f, 0xa6, 0xf5, 0x50, 0x8b, 0xcf, 0xbb, 0x31, 0x1e,
-       0x0a, 0xef, 0xd8, 0x14, 0x8e, 0x77, 0xd3, 0x7a, 0xa8, 0xad, 0xef, 0xb4,
-       0x7d, 0xcc, 0x62, 0xb3, 0xef, 0x74, 0xd4, 0x68, 0xa7, 0xdb, 0xff, 0xd8,
-       0xe1, 0x53, 0x75, 0xea, 0x77, 0xc8, 0x14, 0xf9, 0x8e, 0x4d, 0xe8, 0x77,
-       0x41, 0x96, 0xac, 0x6c, 0x96, 0x60, 0x33, 0xe1, 0x7d, 0x11, 0x21, 0x6b,
-       0x2e, 0xbc, 0xc5, 0xef, 0x63, 0x7a, 0xbe, 0xf8, 0x87, 0x62, 0x9d, 0x92,
-       0xfe, 0x07, 0xb4, 0x0f, 0xfb, 0xce, 0x88, 0xb6, 0x32, 0xbe, 0x49, 0xf9,
-       0x23, 0x14, 0xf6, 0x6f, 0xe7, 0x87, 0x68, 0x5d, 0xf3, 0x36, 0x67, 0x2b,
-       0x68, 0x19, 0xdf, 0xcb, 0xf3, 0x12, 0x69, 0xb2, 0xb5, 0xa0, 0x3f, 0xcf,
-       0x33, 0x2e, 0x18, 0xad, 0x63, 0x82, 0xe6, 0xb9, 0xb9, 0x28, 0x6c, 0x3a,
-       0xad, 0x3b, 0x57, 0x64, 0xec, 0xa9, 0xb8, 0x0e, 0x9c, 0xa6, 0x75, 0xa7,
-       0x1b, 0x07, 0xef, 0xf5, 0xe0, 0x0b, 0xcf, 0xdc, 0x4f, 0x3d, 0x77, 0x26,
-       0x62, 0xce, 0x53, 0x9e, 0x73, 0x57, 0xcf, 0xe1, 0xca, 0x36, 0xda, 0xca,
-       0xfb, 0x53, 0x62, 0x5c, 0xdf, 0xfc, 0x62, 0x02, 0xb9, 0x6a, 0xf5, 0xfc,
-       0x21, 0x77, 0xce, 0x14, 0xd6, 0x01, 0x2d, 0x87, 0x3a, 0x3f, 0x1b, 0xb4,
-       0x18, 0xf1, 0xc8, 0x99, 0x72, 0xae, 0x25, 0xb8, 0xcf, 0x4d, 0x8b, 0xc6,
-       0x3a, 0x32, 0xa7, 0xd6, 0x91, 0x45, 0x87, 0x1e, 0x6f, 0xc5, 0xed, 0xfd,
-       0x1e, 0xb8, 0xdd, 0x2b, 0x6f, 0x0a, 0x7d, 0x7a, 0x92, 0x71, 0xc8, 0x67,
-       0x80, 0x43, 0x42, 0xc8, 0x5b, 0x92, 0x58, 0x04, 0xdf, 0x17, 0x19, 0x8f,
-       0x44, 0x98, 0x57, 0x7e, 0x44, 0xe7, 0x18, 0x6b, 0x5f, 0xa7, 0xfd, 0xca,
-       0x3e, 0x83, 0xdc, 0xea, 0x38, 0x53, 0xc4, 0xf1, 0xfb, 0x28, 0xfb, 0x98,
-       0x35, 0x19, 0xa7, 0x1f, 0xd1, 0x59, 0x11, 0x33, 0x83, 0xfd, 0x3d, 0xc4,
-       0x1c, 0x3c, 0x20, 0xde, 0x2f, 0x7d, 0x19, 0xf7, 0x23, 0xa6, 0x6e, 0xe3,
-       0xf1, 0xfb, 0x2a, 0xb7, 0x8e, 0xdb, 0xe1, 0x9d, 0x4b, 0x4a, 0xa6, 0xc4,
-       0x35, 0xbe, 0xff, 0x49, 0xa3, 0xf5, 0xfe, 0xb8, 0x91, 0xaa, 0xa6, 0x8c,
-       0x44, 0x05, 0xed, 0x9e, 0x34, 0x92, 0x55, 0xd8, 0x90, 0x9a, 0x47, 0xac,
-       0x28, 0xe4, 0x6d, 0x95, 0xd6, 0xdf, 0x8b, 0x58, 0x24, 0x57, 0x9e, 0xc4,
-       0x06, 0xfa, 0x7d, 0xb8, 0xa9, 0xdf, 0x9a, 0xbe, 0x38, 0x86, 0xbf, 0xe7,
-       0x15, 0xa6, 0xa9, 0xc6, 0xb5, 0x41, 0xf8, 0xd7, 0x27, 0xb3, 0xb4, 0x16,
-       0xae, 0xb5, 0x5a, 0x70, 0xed, 0xe2, 0xba, 0xfd, 0xfe, 0xa4, 0x32, 0x2e,
-       0xf3, 0xa3, 0xfd, 0xb6, 0xc0, 0xaf, 0xdc, 0xef, 0x26, 0x6c, 0xeb, 0xe2,
-       0x29, 0xb4, 0xd1, 0x7e, 0x70, 0xed, 0x07, 0xeb, 0x55, 0xf1, 0xc0, 0x3a,
-       0x3e, 0x21, 0x88, 0x7c, 0xaf, 0x90, 0x8c, 0x6b, 0x85, 0x8d, 0xb5, 0xc2,
-       0xfd, 0x83, 0xbd, 0x05, 0x9f, 0x8f, 0xb0, 0xb7, 0xcc, 0x24, 0x49, 0x5f,
-       0xf7, 0x99, 0xaa, 0xd3, 0xbf, 0xeb, 0x95, 0x4b, 0x39, 0xea, 0x91, 0x4b,
-       0xe9, 0x94, 0xb5, 0x80, 0x43, 0xd6, 0x22, 0x0e, 0xdc, 0x36, 0xcc, 0x76,
-       0x4b, 0x0f, 0xeb, 0x90, 0x1e, 0xb1, 0x6d, 0xe2, 0xbf, 0xea, 0xb4, 0x5b,
-       0xdc, 0x79, 0xf1, 0x90, 0x3b, 0x60, 0x33, 0x69, 0xc3, 0xa4, 0x4a, 0xf5,
-       0x9c, 0x7a, 0x1e, 0x77, 0x23, 0x6f, 0xb1, 0xd2, 0x92, 0x63, 0xe9, 0xd5,
-       0xdf, 0x91, 0x96, 0xfe, 0x62, 0xfd, 0x8a, 0xb7, 0xc5, 0x74, 0x5e, 0x76,
-       0xd5, 0xfd, 0xea, 0x9f, 0x5b, 0x9f, 0xe1, 0x5d, 0xa3, 0xc2, 0xe7, 0x9d,
-       0xad, 0xeb, 0xb2, 0x19, 0xd9, 0xdf, 0x42, 0xb3, 0x9d, 0xe1, 0xbf, 0x42,
-       0x8a, 0x76, 0xde, 0xba, 0x7d, 0x73, 0xfe, 0xb3, 0xad, 0x6e, 0x1c, 0xdc,
-       0x27, 0xfd, 0x62, 0x73, 0x2a, 0x0e, 0x7b, 0x40, 0xd9, 0x7b, 0xeb, 0xf1,
-       0x3b, 0xae, 0xcd, 0x29, 0x5f, 0xa2, 0x65, 0x96, 0x09, 0x7c, 0x7e, 0xfc,
-       0x54, 0x87, 0x1d, 0x52, 0x7b, 0x59, 0xd8, 0xaf, 0x02, 0xdf, 0xeb, 0xe7,
-       0x43, 0x67, 0x6f, 0x64, 0xce, 0xcc, 0x96, 0x39, 0x93, 0x7c, 0x05, 0x5b,
-       0x0b, 0xf1, 0xc5, 0x53, 0xae, 0x18, 0xef, 0x4f, 0x42, 0x8b, 0x5e, 0x8f,
-       0xb8, 0x67, 0xc4, 0x2d, 0xb7, 0xeb, 0xe7, 0x1d, 0x07, 0x2e, 0x47, 0x7f,
-       0x6b, 0xb5, 0x57, 0xa2, 0xbb, 0xe5, 0x5a, 0x5c, 0xf5, 0xc6, 0x48, 0xa1,
-       0x0d, 0xf7, 0xcf, 0xbd, 0xf6, 0xee, 0xda, 0xe0, 0xda, 0x2b, 0xea, 0x8b,
-       0xf8, 0x0e, 0x09, 0x1d, 0xd0, 0x43, 0x95, 0x12, 0xe2, 0xaf, 0x3f, 0x0b,
-       0x99, 0x67, 0x3d, 0xeb, 0xc8, 0x49, 0xf3, 0x9e, 0xc7, 0xfa, 0x9e, 0x4a,
-       0x20, 0x86, 0xbd, 0x3f, 0xc4, 0x96, 0xf4, 0xb3, 0xee, 0x41, 0xfb, 0x71,
-       0xf3, 0x16, 0xfc, 0xbd, 0xca, 0xff, 0x94, 0x52, 0xeb, 0xcb, 0xa1, 0x0d,
-       0xec, 0xad, 0x6c, 0x4e, 0x4f, 0x5b, 0xe6, 0x0a, 0x61, 0xdf, 0x07, 0xf1,
-       0xc2, 0xc7, 0x7a, 0xa9, 0xf7, 0x2b, 0x5d, 0x5d, 0xf6, 0x1f, 0xf4, 0xc9,
-       0xbd, 0x28, 0x7c, 0xd7, 0x43, 0x2f, 0x94, 0x10, 0xcb, 0x8d, 0xef, 0x7e,
-       0x8b, 0xbf, 0xf3, 0xd2, 0x51, 0x3a, 0x16, 0x1d, 0x58, 0x4e, 0xce, 0x4f,
-       0x99, 0x60, 0x2b, 0xd5, 0xe8, 0x6f, 0xa2, 0x9f, 0x93, 0xfb, 0x19, 0xd5,
-       0xfb, 0xbd, 0x57, 0xe3, 0xe5, 0x2f, 0xfc, 0x69, 0xdf, 0xc7, 0x8d, 0x8d,
-       0xfc, 0xd6, 0x86, 0xfc, 0x85, 0xd8, 0xe7, 0xdf, 0xc8, 0x9e, 0x89, 0xde,
-       0x1b, 0x9e, 0x16, 0x39, 0xa7, 0x4e, 0x3e, 0xb8, 0x3f, 0xfb, 0xc3, 0xe0,
-       0x87, 0x91, 0x16, 0x5d, 0xf5, 0xc9, 0xfd, 0xfd, 0x6e, 0xba, 0x06, 0x3d,
-       0x7d, 0x55, 0xde, 0xfb, 0xc0, 0xd8, 0xf3, 0x87, 0x9f, 0xba, 0x4a, 0x67,
-       0xae, 0x81, 0x87, 0x0d, 0xe6, 0xb6, 0x31, 0xca, 0x87, 0x91, 0x57, 0x24,
-       0x72, 0x73, 0xf4, 0xbe, 0xa1, 0xc8, 0x15, 0x3a, 0x23, 0x72, 0x20, 0xc7,
-       0x23, 0xf7, 0x78, 0x3d, 0x3c, 0x53, 0x7d, 0x9b, 0xce, 0x56, 0x82, 0xfc,
-       0xdf, 0xc0, 0xee, 0xad, 0x79, 0x90, 0xcd, 0x3c, 0x7e, 0x4f, 0xf0, 0xf8,
-       0xf0, 0x9a, 0x3c, 0x7e, 0xa4, 0xce, 0xe3, 0x5f, 0xe9, 0x97, 0xfc, 0xdc,
-       0xcb, 0xcf, 0xea, 0xa5, 0x43, 0xe2, 0xb9, 0x6f, 0xf3, 0xf1, 0x56, 0x3a,
-       0x14, 0x92, 0xc7, 0x67, 0x2b, 0xac, 0xe3, 0x0b, 0x6f, 0xd3, 0xb9, 0x6b,
-       0x59, 0x5f, 0x4a, 0xe4, 0x2f, 0x38, 0x6b, 0x69, 0xe8, 0xfb, 0xd1, 0xae,
-       0x1d, 0xff, 0x6b, 0xbd, 0x24, 0x73, 0xae, 0xca, 0x52, 0x3f, 0xd1, 0x5b,
-       0xd1, 0x21, 0x17, 0xff, 0x37, 0xdb, 0x8e, 0xe7, 0xd5, 0x1a, 0x78, 0x7c,
-       0x0d, 0xbf, 0x46, 0x2b, 0x5f, 0xf6, 0x79, 0xe0, 0xe1, 0xa7, 0xfb, 0xe5,
-       0x3e, 0xd5, 0x5a, 0x7e, 0x8d, 0xa6, 0xb8, 0x0e, 0xe7, 0xbe, 0x3d, 0xeb,
-       0xfd, 0x3d, 0x2a, 0x17, 0xf0, 0x87, 0xfd, 0x72, 0xbd, 0x40, 0x7e, 0xe0,
-       0x0a, 0xd3, 0xe1, 0x22, 0x63, 0x95, 0x21, 0xea, 0xbc, 0xaa, 0xc7, 0x3a,
-       0x24, 0xf4, 0xad, 0xd3, 0x4f, 0x73, 0x51, 0xe5, 0x76, 0xe7, 0x1c, 0x63,
-       0xba, 0x28, 0x6c, 0x9c, 0xf6, 0xf2, 0xd6, 0x3e, 0xe6, 0x6a, 0xd8, 0xb5,
-       0x26, 0xb8, 0xf9, 0x0d, 0x75, 0x4a, 0x30, 0xbf, 0x64, 0x48, 0x1c, 0x3c,
-       0xc3, 0xf8, 0x76, 0xb3, 0xfb, 0x45, 0x9f, 0x14, 0x23, 0xba, 0x6b, 0x60,
-       0xb8, 0x8f, 0x31, 0x0f, 0xd2, 0xe6, 0xc8, 0xbc, 0x58, 0x15, 0xba, 0xe0,
-       0xe2, 0x54, 0x8d, 0x92, 0xd1, 0x6d, 0x94, 0x99, 0xe2, 0x77, 0xcf, 0xd8,
-       0x6c, 0x7b, 0xf9, 0x29, 0xcb, 0xf2, 0x9b, 0x99, 0xda, 0xa2, 0xf0, 0xa2,
-       0xf6, 0xa7, 0x77, 0xa9, 0x38, 0x87, 0x5e, 0xb1, 0x2f, 0x29, 0x6b, 0xf5,
-       0xf0, 0x71, 0x45, 0x3f, 0x1b, 0xd7, 0xc1, 0xbb, 0x9d, 0xaa, 0xdd, 0x65,
-       0x47, 0x3b, 0xb4, 0xb9, 0xac, 0xda, 0xe2, 0x99, 0x1a, 0x53, 0x74, 0x2b,
-       0x7d, 0x0b, 0x39, 0x5c, 0x51, 0xb9, 0x7a, 0xc2, 0x7e, 0xa0, 0xd9, 0xfa,
-       0x58, 0x2e, 0x73, 0xdb, 0xff, 0xae, 0xc5, 0x85, 0x2d, 0x77, 0x99, 0x31,
-       0x6f, 0x55, 0xc8, 0x8a, 0xbb, 0x4f, 0x18, 0x8b, 0x5f, 0xec, 0x0f, 0xf1,
-       0xb1, 0x7a, 0xcf, 0xe9, 0x7a, 0x9f, 0x10, 0xa3, 0x61, 0x45, 0xe4, 0xb3,
-       0x74, 0xbb, 0xcb, 0x8e, 0x76, 0x5a, 0x57, 0xe8, 0xfd, 0x87, 0x8f, 0x7c,
-       0xb3, 0x85, 0xdb, 0x3e, 0x19, 0xc3, 0x1b, 0x12, 0xfb, 0xa7, 0x32, 0x46,
-       0x43, 0x1f, 0xc3, 0xbf, 0x8c, 0x98, 0x0a, 0xc4, 0x49, 0x38, 0xf5, 0x8d,
-       0x1c, 0x6f, 0x00, 0x6b, 0x51, 0x15, 0xfb, 0xa6, 0xd8, 0xaf, 0x68, 0x87,
-       0x9d, 0x77, 0x21, 0x36, 0x7f, 0x13, 0x18, 0x74, 0x23, 0xf2, 0x67, 0x7a,
-       0xc8, 0x9f, 0xf3, 0xfd, 0xc8, 0x83, 0x43, 0x3e, 0x5c, 0x76, 0xd2, 0xa0,
-       0x1a, 0xdb, 0x0a, 0x06, 0x95, 0x43, 0x3e, 0x3a, 0x67, 0x5b, 0xd1, 0x8a,
-       0xc0, 0x9a, 0x8f, 0xc0, 0x7f, 0x35, 0xb9, 0x42, 0x07, 0x44, 0xce, 0x38,
-       0x6a, 0x1f, 0x94, 0x79, 0x0d, 0x3e, 0xcd, 0x3c, 0x78, 0x96, 0xed, 0x8f,
-       0xec, 0x49, 0xec, 0xb7, 0xe8, 0x79, 0x41, 0x0e, 0x3c, 0x3e, 0x4d, 0x9e,
-       0xbb, 0xdf, 0xdd, 0x41, 0xc1, 0x38, 0x3f, 0xd3, 0x84, 0x7e, 0xe2, 0xe7,
-       0xa4, 0x29, 0xc1, 0x76, 0x12, 0x6c, 0xd6, 0xd3, 0x27, 0xad, 0x50, 0x99,
-       0x0c, 0x6e, 0x0b, 0xdb, 0x15, 0xcf, 0xc1, 0xfd, 0xf1, 0x50, 0x07, 0xb9,
-       0x73, 0x72, 0x7b, 0x45, 0x9e, 0xe2, 0x5b, 0xd1, 0x07, 0xc9, 0x18, 0x84,
-       0xbe, 0xc2, 0xbc, 0x3d, 0xa0, 0xf6, 0x89, 0xb6, 0xf3, 0xf1, 0x84, 0x3a,
-       0x0e, 0x8a, 0xf9, 0x94, 0xc7, 0x9a, 0xbf, 0xf1, 0xf7, 0xf3, 0x2e, 0xb2,
-       0xfd, 0x6a, 0xfe, 0x9a, 0x62, 0x41, 0x22, 0x63, 0x46, 0x90, 0xce, 0x57,
-       0xd6, 0xf2, 0xbf, 0x78, 0xe5, 0xba, 0x6e, 0xdf, 0x60, 0xae, 0xeb, 0x4f,
-       0x76, 0xc8, 0xdc, 0x32, 0x67, 0x5f, 0xfe, 0x93, 0xfb, 0xe2, 0x85, 0xc9,
-       0x5a, 0x70, 0x22, 0x8f, 0xb7, 0x46, 0x3f, 0x8b, 0x7e, 0x9e, 0xee, 0x84,
-       0x23, 0x2a, 0x66, 0x09, 0x31, 0x4a, 0x0f, 0x2a, 0xbe, 0xd6, 0xba, 0x9f,
-       0x3c, 0x74, 0xff, 0xa3, 0x22, 0x56, 0x53, 0xae, 0x1d, 0x43, 0x8a, 0x1e,
-       0xa0, 0x59, 0xc4, 0x41, 0xb3, 0x01, 0x07, 0xcd, 0x0c, 0x75, 0xbc, 0x4d,
-       0x9c, 0x9f, 0xaf, 0x3c, 0xb5, 0x5d, 0xe6, 0x8b, 0x63, 0x2f, 0xf1, 0x92,
-       0x3a, 0x5e, 0x6f, 0xbc, 0x56, 0x98, 0x82, 0xc2, 0xdf, 0xe4, 0x18, 0xeb,
-       0xcb, 0x44, 0xf6, 0x81, 0x70, 0x2b, 0x0d, 0x5e, 0x73, 0x5c, 0x47, 0x1f,
-       0xc7, 0x1d, 0x7d, 0x1c, 0x75, 0xf4, 0x71, 0x6f, 0x9b, 0x3e, 0xb2, 0x8e,
-       0xe7, 0xf7, 0x9c, 0xad, 0x7e, 0xdc, 0xbe, 0xa2, 0x9f, 0xc8, 0x23, 0x06,
-       0x3d, 0xb7, 0x52, 0x2e, 0x1c, 0x51, 0x6b, 0xc7, 0x2f, 0x55, 0x2e, 0xba,
-       0x57, 0x9f, 0xff, 0x8e, 0xda, 0xcf, 0x9b, 0x93, 0x57, 0x9d, 0xf9, 0xc7,
-       0xdf, 0xa5, 0xa4, 0xcc, 0x23, 0x57, 0xb2, 0x7d, 0xb9, 0x8d, 0x1f, 0x1a,
-       0xf1, 0x1c, 0xc0, 0x20, 0xc2, 0x2e, 0xdc, 0x2d, 0x6b, 0xc1, 0x05, 0x68,
-       0xa9, 0x9e, 0xcb, 0xeb, 0x57, 0xb9, 0x3b, 0xc7, 0xc3, 0xf7, 0x37, 0x8f,
-       0x17, 0xd7, 0xff, 0x4c, 0xf8, 0xf2, 0xe4, 0xfe, 0xd1, 0x8a, 0xca, 0x47,
-       0xb6, 0x4c, 0xc4, 0x06, 0x2c, 0x2e, 0xc3, 0xff, 0xda, 0x2e, 0x77, 0x57,
-       0xea, 0xa2, 0x4c, 0xbd, 0x3e, 0x4a, 0x59, 0xe4, 0x35, 0x48, 0xff, 0x98,
-       0xcc, 0xbf, 0x5d, 0x5c, 0xbe, 0x25, 0x72, 0x5e, 0x13, 0x2a, 0x8f, 0x37,
-       0x43, 0x3d, 0x02, 0xe7, 0x7e, 0xfc, 0xfc, 0xdb, 0x17, 0xc2, 0x9b, 0xcf,
-       0xbf, 0x75, 0xde, 0xb3, 0xb9, 0xfc, 0xdb, 0x10, 0x8f, 0xdd, 0x58, 0x90,
-       0xf9, 0xb7, 0xcd, 0x7b, 0x32, 0x32, 0xff, 0x36, 0xe3, 0xc0, 0x0f, 0x12,
-       0xaf, 0xbf, 0xe5, 0x88, 0xdf, 0x96, 0xb9, 0xb5, 0x8b, 0x75, 0xcc, 0x2a,
-       0x73, 0x6b, 0x65, 0xbc, 0xb7, 0xb3, 0x0e, 0x8c, 0xdc, 0xfb, 0x91, 0xef,
-       0xd9, 0xe6, 0xda, 0xfb, 0x91, 0x39, 0xb5, 0xa6, 0xd1, 0xce, 0x86, 0xc3,
-       0x1a, 0x81, 0x7a, 0x08, 0x71, 0xe6, 0xdd, 0xad, 0x6d, 0xea, 0x21, 0xc4,
-       0xdb, 0xd4, 0x43, 0x70, 0xea, 0x7e, 0x27, 0xc6, 0x02, 0x26, 0xc6, 0xda,
-       0x08, 0x2c, 0x8c, 0x7a, 0x06, 0x51, 0x3a, 0x5f, 0xc7, 0x9e, 0x0f, 0x52,
-       0x5a, 0x61, 0xcf, 0xf3, 0x15, 0xad, 0x8f, 0x46, 0x5d, 0xfa, 0xc8, 0x0b,
-       0x8b, 0x5a, 0x2a, 0xce, 0x47, 0xcb, 0x6b, 0xd6, 0x21, 0xaf, 0x59, 0x0f,
-       0x79, 0xc5, 0x3d, 0xd9, 0x36, 0xfd, 0xfe, 0xa5, 0xba, 0x07, 0xff, 0x4f,
-       0x46, 0x50, 0xb3, 0x85, 0x68, 0xf7, 0x80, 0xc2, 0x7f, 0x0e, 0x79, 0x3d,
-       0xcb, 0xf2, 0xaa, 0xaf, 0xa3, 0xbf, 0xed, 0x6c, 0x00, 0x8d, 0x19, 0x87,
-       0x7c, 0x87, 0xaf, 0xbd, 0x21, 0xe2, 0xa4, 0x9a, 0xed, 0x45, 0x8d, 0x27,
-       0xf6, 0x09, 0x59, 0xba, 0xe3, 0x47, 0xdc, 0x8a, 0xbe, 0x16, 0x52, 0x7e,
-       0x32, 0x4d, 0x8b, 0xce, 0x26, 0xcc, 0xd1, 0xc0, 0x1b, 0x22, 0xc6, 0xd7,
-       0xd1, 0xb7, 0x7f, 0xe5, 0xbe, 0xe9, 0xeb, 0x7a, 0xcd, 0x7c, 0xa7, 0xc9,
-       0x9f, 0x71, 0xa3, 0xa9, 0xee, 0x1f, 0x7c, 0x47, 0xdb, 0xd2, 0x86, 0x9d,
-       0x12, 0x31, 0xa6, 0x7d, 0x36, 0xfc, 0x64, 0x09, 0x96, 0xfd, 0xbe, 0x34,
-       0xe2, 0x99, 0xfb, 0xae, 0x98, 0x74, 0xa2, 0x70, 0x7e, 0x8f, 0xe4, 0x95,
-       0x0b, 0xa2, 0xa6, 0x25, 0x6a, 0x20, 0x26, 0x79, 0x7d, 0x4e, 0x30, 0xe8,
-       0x9c, 0xab, 0x76, 0xd1, 0x22, 0xa3, 0x7b, 0xbf, 0x5d, 0x16, 0xbe, 0x3e,
-       0xd6, 0x49, 0x45, 0xd4, 0x36, 0x35, 0x16, 0x3a, 0xf9, 0xb9, 0x83, 0xb4,
-       0x54, 0x1a, 0x17, 0x35, 0xa1, 0x64, 0x7d, 0x11, 0xb4, 0xf5, 0x51, 0xbf,
-       0xfd, 0x0d, 0xa6, 0xdd, 0xd7, 0x44, 0x8c, 0xe5, 0x62, 0xf1, 0x82, 0xfc,
-       0x2c, 0x3f, 0xa5, 0xde, 0xc1, 0xef, 0xab, 0xfe, 0x98, 0xe2, 0xfd, 0xa6,
-       0xc3, 0x96, 0x73, 0xfe, 0x79, 0xe3, 0x95, 0x63, 0x9b, 0xc2, 0x2b, 0xd9,
-       0x74, 0x03, 0xaf, 0x38, 0x9f, 0xad, 0xb1, 0xcb, 0xe4, 0xa0, 0xac, 0xf7,
-       0x00, 0x1a, 0x6c, 0x05, 0x16, 0x4b, 0x83, 0x96, 0x46, 0xcc, 0x8a, 0x24,
-       0xfc, 0x33, 0x94, 0xaf, 0x5e, 0xa7, 0x4c, 0x11, 0x98, 0x99, 0x3f, 0xcb,
-       0xe7, 0x76, 0x4a, 0x1f, 0x8d, 0xbe, 0x07, 0x7a, 0x65, 0x07, 0xb7, 0xff,
-       0xeb, 0x41, 0x19, 0x97, 0xed, 0xbc, 0xde, 0xcb, 0xd7, 0xbf, 0x10, 0x69,
-       0xbe, 0xbe, 0x85, 0xaf, 0xf7, 0xa7, 0x31, 0x87, 0xc6, 0x15, 0xf8, 0x25,
-       0x27, 0x29, 0xc7, 0xf3, 0x93, 0xaf, 0xf2, 0xda, 0x7a, 0x95, 0xf5, 0x55,
-       0x45, 0xb7, 0x1b, 0x40, 0xce, 0x8e, 0x98, 0x13, 0x83, 0xdb, 0x5c, 0x2c,
-       0x4c, 0x71, 0xbb, 0x21, 0xf2, 0x5f, 0x35, 0x29, 0x5f, 0xd1, 0xbc, 0xaa,
-       0xe3, 0xed, 0xdf, 0x18, 0x90, 0x31, 0x55, 0xef, 0xec, 0x94, 0xf4, 0x9b,
-       0x14, 0x3e, 0x4f, 0xc4, 0x73, 0x3c, 0x23, 0xf8, 0xd0, 0x9a, 0x31, 0xeb,
-       0xef, 0xdf, 0x06, 0xbe, 0x42, 0xdd, 0x54, 0x1e, 0x03, 0xeb, 0xc5, 0x98,
-       0x1d, 0xca, 0xd5, 0x63, 0xd5, 0x9e, 0xdb, 0x2d, 0xef, 0xff, 0xe9, 0x80,
-       0xac, 0x55, 0x7a, 0x5b, 0x9d, 0xeb, 0x35, 0x07, 0xf1, 0xcb, 0x3e, 0x41,
-       0x1b, 0xff, 0x02, 0xf4, 0xa5, 0xc1, 0xc7, 0x3c, 0x9e, 0x34, 0xfa, 0xf8,
-       0xb3, 0x01, 0x5d, 0x9f, 0x50, 0x8e, 0xeb, 0x28, 0xf7, 0x37, 0xc5, 0xe3,
-       0xd2, 0xd7, 0xe3, 0x7c, 0xee, 0x35, 0xbf, 0x78, 0x56, 0x30, 0x2d, 0xeb,
-       0x8b, 0x05, 0xd3, 0x99, 0x49, 0x39, 0xcf, 0x0d, 0x9f, 0x6e, 0xa4, 0xee,
-       0xd3, 0x9d, 0x2b, 0xf4, 0x0f, 0xc2, 0xbf, 0x61, 0x5c, 0xe1, 0xf9, 0x0e,
-       0x3f, 0xc3, 0x6d, 0x91, 0xab, 0x90, 0xe3, 0xcf, 0x1e, 0x15, 0xd7, 0xd3,
-       0xca, 0x2b, 0x32, 0x4e, 0x42, 0xaf, 0x5b, 0xb8, 0x77, 0x80, 0x9f, 0x21,
-       0xd7, 0xae, 0xf6, 0xef, 0xa1, 0x96, 0x38, 0x98, 0x56, 0x1e, 0x5b, 0xcb,
-       0x0f, 0x2b, 0xf6, 0x13, 0x3d, 0xf8, 0x6c, 0xad, 0x7a, 0x06, 0xef, 0x08,
-       0x3f, 0x5a, 0xb2, 0x45, 0x5e, 0x21, 0xc7, 0x01, 0xfa, 0xce, 0x7c, 0x96,
-       0xb6, 0xf0, 0x5c, 0x7d, 0xc3, 0xf8, 0x35, 0xec, 0xb7, 0x93, 0x8c, 0x79,
-       0x62, 0x1a, 0x17, 0xec, 0xc9, 0xb3, 0x06, 0xd3, 0xb9, 0x90, 0xad, 0x05,
-       0xec, 0x1e, 0xea, 0x64, 0x59, 0xfd, 0x22, 0x8d, 0xb1, 0xfd, 0x07, 0x99,
-       0xb5, 0x23, 0x29, 0x82, 0xbc, 0x59, 0xa1, 0xc3, 0xcc, 0x13, 0xc9, 0x2a,
-       0xf8, 0xd9, 0xa0, 0x27, 0x4a, 0x44, 0x8f, 0x97, 0xc6, 0x42, 0xdf, 0x27,
-       0xdb, 0x6c, 0x7c, 0x6f, 0x85, 0x12, 0xdc, 0x8f, 0x54, 0xf5, 0x77, 0xe8,
-       0x43, 0x51, 0xe7, 0x04, 0x74, 0xd4, 0xf3, 0xfe, 0xdb, 0x74, 0x3a, 0x8d,
-       0x7e, 0x6f, 0x5c, 0x3e, 0x4f, 0x6c, 0x4a, 0x3e, 0x83, 0x1e, 0xf2, 0xf9,
-       0xea, 0xa0, 0xe4, 0x9b, 0x1a, 0xf3, 0x68, 0x90, 0x66, 0x8b, 0x88, 0x01,
-       0x7b, 0x18, 0x75, 0xa7, 0x8a, 0x19, 0xd6, 0x4b, 0x99, 0x86, 0x5e, 0xba,
-       0x94, 0xf0, 0xc7, 0x21, 0xe3, 0xa8, 0xcb, 0xa6, 0xe2, 0x7e, 0x30, 0x8e,
-       0xdd, 0x34, 0xb6, 0xb0, 0x95, 0xef, 0xa5, 0x95, 0xc4, 0x74, 0x5c, 0xe5,
-       0xfa, 0x5b, 0x66, 0x92, 0xf5, 0xe3, 0x1c, 0xcb, 0x72, 0xae, 0xf8, 0x00,
-       0x2d, 0x86, 0x87, 0x69, 0x74, 0x41, 0xd7, 0x37, 0xc1, 0x58, 0xff, 0x6d,
-       0x48, 0xea, 0x24, 0x3d, 0xee, 0x5f, 0x11, 0xbe, 0x0b, 0xf3, 0xfa, 0xa7,
-       0x35, 0xee, 0xad, 0xeb, 0xe8, 0xa5, 0xbf, 0x52, 0x32, 0x5b, 0xbb, 0x91,
-       0x88, 0x52, 0x36, 0x31, 0xfd, 0x97, 0x82, 0xff, 0x47, 0xaf, 0xc3, 0x0f,
-       0x07, 0x1d, 0x6d, 0x52, 0xba, 0xe0, 0xa6, 0xc5, 0x30, 0x8f, 0x1b, 0xdf,
-       0xd7, 0xfe, 0x79, 0x36, 0xfa, 0x94, 0x58, 0xfb, 0xc7, 0xae, 0x73, 0x3b,
-       0xb1, 0x36, 0x69, 0xbd, 0xe1, 0xc5, 0x87, 0xba, 0x8e, 0xa5, 0xe6, 0x45,
-       0x19, 0xeb, 0xc9, 0xf8, 0x2d, 0x94, 0xf6, 0xbb, 0x79, 0xf2, 0x23, 0x3a,
-       0x36, 0x6f, 0xd2, 0xf1, 0x82, 0xf5, 0x7c, 0x96, 0x66, 0x58, 0xae, 0x9d,
-       0xeb, 0x05, 0xb7, 0x27, 0xf0, 0x59, 0x8c, 0x65, 0x9f, 0xed, 0xe6, 0xa2,
-       0x29, 0xe3, 0xee, 0x44, 0xed, 0xb9, 0x2e, 0xa1, 0x47, 0x43, 0xf6, 0x3f,
-       0x0d, 0xea, 0xf5, 0x20, 0x53, 0x44, 0x1e, 0x21, 0x7f, 0x96, 0xb9, 0x7d,
-       0x61, 0x90, 0x32, 0x25, 0x3c, 0x07, 0xeb, 0x1d, 0xfa, 0xce, 0xe7, 0x4b,
-       0x72, 0x5e, 0x47, 0xf9, 0xd9, 0xc8, 0xbb, 0x3f, 0x5e, 0x9d, 0x12, 0xb1,
-       0x77, 0xd0, 0xcd, 0x72, 0x3e, 0x63, 0x74, 0xd1, 0x53, 0xaf, 0x28, 0x4c,
-       0xe9, 0x90, 0xef, 0x8c, 0x90, 0xef, 0x98, 0x98, 0x8f, 0x4c, 0xc9, 0x60,
-       0xbc, 0xa6, 0x7d, 0x0f, 0xfd, 0x7c, 0x1e, 0x50, 0x3a, 0x04, 0xdf, 0x0d,
-       0xec, 0x14, 0x71, 0x89, 0x36, 0xae, 0xe3, 0x33, 0x46, 0xcf, 0x30, 0xee,
-       0x7c, 0xb6, 0xd0, 0x45, 0xb7, 0x8a, 0x5d, 0xf4, 0x66, 0x71, 0x98, 0x6e,
-       0xce, 0x6f, 0xa7, 0x8b, 0x8c, 0x99, 0x2f, 0xda, 0x01, 0x33, 0xc7, 0xf6,
-       0xc5, 0x0b, 0x51, 0x11, 0x33, 0xc4, 0x72, 0x87, 0xf6, 0xc0, 0x7f, 0x89,
-       0x5d, 0xcc, 0x73, 0x8c, 0xbd, 0xbb, 0xe9, 0x03, 0x7e, 0x67, 0xae, 0xa0,
-       0x63, 0x1d, 0xe0, 0x93, 0x1f, 0xaf, 0xe3, 0xd7, 0xf5, 0x79, 0x24, 0xb4,
-       0x0e, 0x8f, 0xc4, 0x84, 0xae, 0xcf, 0xcf, 0xf3, 0xf7, 0xf3, 0xf0, 0x9f,
-       0x33, 0xbd, 0x59, 0x3f, 0x7f, 0x3d, 0x80, 0xf6, 0xb8, 0x66, 0xcb, 0x58,
-       0x49, 0x31, 0xb6, 0x08, 0x9f, 0x83, 0xb6, 0x11, 0x45, 0x87, 0x6e, 0x1e,
-       0x9f, 0x4f, 0xb4, 0xcf, 0x2c, 0x75, 0xd3, 0x99, 0x12, 0x63, 0x90, 0x92,
-       0x9f, 0x6d, 0x18, 0xb4, 0x0d, 0xec, 0xd5, 0xf5, 0x5f, 0x2f, 0x72, 0xdf,
-       0x73, 0x25, 0x89, 0x41, 0x72, 0x4b, 0xbd, 0x94, 0x2f, 0xf5, 0xa8, 0xf3,
-       0x07, 0x44, 0x8c, 0xbb, 0xac, 0x63, 0x84, 0xef, 0xd6, 0xd2, 0x6f, 0x6f,
-       0x31, 0x4f, 0x61, 0x4d, 0x95, 0x76, 0x29, 0x74, 0xcd, 0x8d, 0x96, 0xba,
-       0xc4, 0xe0, 0xb9, 0x19, 0xfa, 0x2e, 0xaf, 0xb7, 0xa3, 0x57, 0xe1, 0x3f,
-       0xfe, 0x2a, 0xf8, 0xa6, 0x0c, 0x1e, 0x1b, 0xbd, 0x8a, 0xba, 0x48, 0x7e,
-       0x91, 0xe7, 0x94, 0x0c, 0x4f, 0x8a, 0xdc, 0x10, 0x29, 0xa3, 0x27, 0x45,
-       0x2d, 0xba, 0x1f, 0x0a, 0xdd, 0x64, 0x65, 0x4d, 0x03, 0x78, 0x04, 0x3e,
-       0x18, 0x19, 0x83, 0x75, 0xc2, 0xee, 0x7b, 0x6b, 0x20, 0x36, 0x41, 0xf1,
-       0x41, 0xf0, 0xbd, 0x94, 0x59, 0x55, 0x5f, 0x40, 0xe8, 0xfb, 0xd0, 0x3e,
-       0x9d, 0x2f, 0xa9, 0xcf, 0xf5, 0x5a, 0xa1, 0xcf, 0x7b, 0x5c, 0xdf, 0x87,
-       0x5c, 0xdf, 0xd7, 0xe3, 0xe5, 0x78, 0xcd, 0xe3, 0x75, 0x9e, 0x64, 0x8d,
-       0xa2, 0xcc, 0x82, 0xe4, 0xbf, 0xd0, 0xbe, 0xf1, 0xd0, 0x97, 0x15, 0x06,
-       0xcf, 0x2c, 0x8f, 0x45, 0xfa, 0x8c, 0x1e, 0x7f, 0x66, 0xea, 0xef, 0x6b,
-       0xf1, 0x34, 0x70, 0xd1, 0xdc, 0x4e, 0xa9, 0xe3, 0xd0, 0xaf, 0x6c, 0x14,
-       0xd0, 0xed, 0xe4, 0x72, 0x0f, 0xad, 0x88, 0x9a, 0x5c, 0xc0, 0x18, 0xb8,
-       0x1f, 0xcf, 0xc9, 0x86, 0x3a, 0x08, 0x35, 0xd7, 0x21, 0xe3, 0x07, 0x22,
-       0xd7, 0x79, 0x3e, 0x53, 0xcb, 0xff, 0x55, 0x3b, 0x2d, 0x6a, 0xdc, 0xa0,
-       0x2d, 0x63, 0x48, 0x81, 0xf9, 0x19, 0xbf, 0x34, 0xd9, 0x55, 0x33, 0xe8,
-       0x67, 0x16, 0x7b, 0x2b, 0x86, 0xfd, 0x22, 0xcb, 0x98, 0xdc, 0x2b, 0x4f,
-       0xb9, 0xf6, 0xca, 0x4f, 0x8a, 0xbd, 0x72, 0xec, 0x93, 0x83, 0xae, 0xa0,
-       0xa5, 0x57, 0x4c, 0x0b, 0xe6, 0x31, 0xca, 0xf3, 0x68, 0xd2, 0xc5, 0x6b,
-       0x42, 0xdf, 0x44, 0x93, 0x7e, 0x19, 0x5f, 0x9d, 0xa2, 0xac, 0x88, 0xbf,
-       0x96, 0x9f, 0x71, 0x23, 0x61, 0x5b, 0x93, 0xab, 0x8c, 0x29, 0x2a, 0xc5,
-       0x2d, 0x74, 0xb3, 0xdc, 0xc1, 0x98, 0xef, 0x6f, 0x69, 0xb5, 0x4c, 0x8c,
-       0x0d, 0xb7, 0x53, 0x3e, 0xca, 0xbc, 0x36, 0x19, 0xe4, 0x79, 0x65, 0x7c,
-       0x3b, 0xc9, 0xf2, 0xc7, 0x63, 0xa8, 0x94, 0x6a, 0xef, 0xe7, 0xa2, 0x71,
-       0x33, 0x31, 0xdd, 0xc3, 0xf6, 0x4b, 0x88, 0xff, 0x6d, 0xfe, 0xff, 0x6c,
-       0x04, 0xb4, 0x59, 0x5c, 0xc2, 0xf7, 0x8c, 0x7d, 0x0a, 0xb5, 0xf7, 0x67,
-       0xb9, 0xcd, 0xec, 0x34, 0xec, 0x20, 0xd8, 0x7b, 0x36, 0xff, 0xcb, 0x36,
-       0x15, 0xe6, 0xbb, 0xdc, 0xb5, 0x6c, 0xc4, 0x10, 0x3a, 0x1e, 0x75, 0x5d,
-       0xc6, 0xd4, 0x67, 0xdc, 0x98, 0xe5, 0xbe, 0xdc, 0x24, 0x3c, 0xc3, 0xa4,
-       0x4c, 0x74, 0x1f, 0xcb, 0xc1, 0x76, 0xfe, 0x44, 0x3e, 0xd6, 0x56, 0xca,
-       0x4f, 0x8d, 0xab, 0x7c, 0xac, 0x48, 0x9b, 0x7c, 0x2c, 0xdc, 0xc7, 0x38,
-       0x60, 0xbe, 0x76, 0x6f, 0x36, 0xea, 0x7c, 0x2f, 0x19, 0x99, 0xe8, 0x36,
-       0x81, 0x99, 0x2a, 0x4b, 0xfb, 0xb9, 0x0f, 0x71, 0x33, 0x33, 0xcd, 0x7d,
-       0x2d, 0x39, 0xfb, 0x5f, 0xbb, 0x97, 0x8c, 0xa2, 0x9d, 0xdf, 0xd5, 0x2e,
-       0x4e, 0xa2, 0xed, 0x12, 0xda, 0xd7, 0xfe, 0x27, 0x11, 0xd5, 0xe3, 0x74,
-       0xde, 0x8b, 0xf1, 0x40, 0xbe, 0xf8, 0xb3, 0x72, 0x9b, 0x6e, 0x16, 0x61,
-       0x8f, 0x1b, 0xcc, 0xf7, 0xe8, 0x91, 0x49, 0xd9, 0x0a, 0x63, 0xc0, 0x6b,
-       0x7b, 0x7d, 0xab, 0xc5, 0x37, 0x6a, 0x99, 0xa6, 0xd8, 0x96, 0x66, 0x3f,
-       0xbc, 0xb4, 0xc1, 0x86, 0xc9, 0xbe, 0x82, 0x35, 0x14, 0xeb, 0x67, 0xb6,
-       0xe6, 0xb7, 0x81, 0xf7, 0x60, 0x1b, 0x5d, 0x60, 0xfd, 0x25, 0xe3, 0x93,
-       0x58, 0x97, 0xb2, 0x0e, 0x93, 0xf2, 0x93, 0x6a, 0xfa, 0x39, 0x04, 0xc9,
-       0xc3, 0xa3, 0x8d, 0xb8, 0x48, 0xc7, 0xfe, 0x7a, 0xc0, 0xb1, 0xbf, 0x1e,
-       0x72, 0xc4, 0x45, 0x86, 0x05, 0x3e, 0x6b, 0x60, 0xaa, 0xb0, 0xc2, 0x54,
-       0xc0, 0x5e, 0x52, 0xb7, 0x2d, 0xd6, 0x75, 0xdb, 0x8e, 0x75, 0x74, 0x9b,
-       0x97, 0xad, 0xba, 0xa2, 0xf4, 0x88, 0x15, 0xc5, 0x1a, 0x73, 0x83, 0xf5,
-       0xc5, 0xeb, 0xd5, 0x69, 0xd6, 0x23, 0x51, 0xd6, 0x23, 0x53, 0xac, 0x47,
-       0x26, 0x59, 0x8f, 0xd8, 0x4c, 0x03, 0x93, 0xc7, 0xfe, 0x11, 0xeb, 0x69,
-       0xac, 0x1f, 0x33, 0xf4, 0x4c, 0x15, 0x3a, 0x79, 0x8a, 0x31, 0xd0, 0x47,
-       0xb4, 0x3a, 0xdf, 0xcb, 0xfc, 0x2b, 0x71, 0x4f, 0xb3, 0x5d, 0x83, 0xda,
-       0x2b, 0xf0, 0x17, 0xff, 0x39, 0xf4, 0xce, 0x2b, 0x59, 0x1a, 0xf1, 0xdd,
-       0x2c, 0x82, 0xce, 0xab, 0xa8, 0x55, 0xf1, 0x12, 0x64, 0x1b, 0x35, 0x82,
-       0x7f, 0x30, 0x31, 0xc3, 0x7d, 0x1f, 0xf1, 0xe5, 0x79, 0x5e, 0xbe, 0x1d,
-       0xcd, 0x86, 0xfa, 0x59, 0x06, 0x8e, 0x2b, 0x19, 0x38, 0xde, 0x90, 0x81,
-       0x6c, 0x8e, 0x47, 0xd2, 0xb7, 0xb0, 0x9d, 0xc6, 0x0f, 0x26, 0x76, 0xf5,
-       0xb1, 0xfc, 0x22, 0x66, 0xa2, 0x51, 0xbf, 0xc7, 0x4f, 0xa7, 0xc3, 0x41,
-       0x55, 0xf7, 0xc7, 0x14, 0x39, 0xef, 0xf9, 0xe2, 0xbb, 0x8c, 0x4b, 0x58,
-       0x4e, 0x43, 0x38, 0xbf, 0x0c, 0xbf, 0x28, 0xdb, 0x0d, 0xdd, 0xc2, 0xaf,
-       0xb4, 0x28, 0xda, 0xe2, 0xdc, 0x9a, 0x64, 0x1d, 0x17, 0x5d, 0x31, 0xac,
-       0x99, 0xb8, 0xf1, 0x9b, 0xc3, 0xa8, 0xe1, 0xfe, 0x83, 0xea, 0xe7, 0x86,
-       0xe5, 0xde, 0x5c, 0x72, 0x97, 0xd4, 0x27, 0xcc, 0xa3, 0xe1, 0xb8, 0xb0,
-       0xdd, 0x3a, 0xae, 0xc8, 0xf5, 0x73, 0x91, 0xe7, 0xbb, 0x12, 0x9d, 0xe4,
-       0xf9, 0xee, 0x51, 0x6b, 0x67, 0x96, 0xbf, 0x17, 0xeb, 0x32, 0xaf, 0xa1,
-       0xc3, 0xa8, 0x7f, 0x1f, 0x12, 0x75, 0x22, 0x4e, 0xa2, 0x0e, 0x4f, 0x02,
-       0xcf, 0x63, 0xee, 0x85, 0xfe, 0xf8, 0x07, 0x5e, 0xa3, 0xf1, 0x5e, 0xf0,
-       0x23, 0x1f, 0x97, 0x67, 0xe8, 0x52, 0x41, 0xf7, 0xe1, 0x3d, 0x32, 0xbe,
-       0x8b, 0x7e, 0xf8, 0x68, 0x87, 0xfd, 0x9e, 0xc8, 0x05, 0x31, 0xfe, 0xc4,
-       0xdd, 0xa7, 0xa3, 0xaa, 0x4f, 0xa8, 0x75, 0xd9, 0x85, 0xda, 0x3e, 0x84,
-       0x9a, 0x48, 0x8b, 0xa2, 0x16, 0x65, 0xa7, 0xb0, 0x59, 0x17, 0x85, 0xed,
-       0xb1, 0x7f, 0x57, 0xa3, 0x3e, 0xe6, 0x7e, 0xd7, 0xb5, 0x3b, 0xbc, 0x6e,
-       0x1d, 0x12, 0x18, 0x6d, 0x14, 0xf5, 0xda, 0x45, 0x5e, 0xea, 0x8c, 0xf8,
-       0xce, 0x58, 0xc0, 0x77, 0x0f, 0xa9, 0xef, 0x3e, 0x2f, 0xb0, 0xb1, 0x11,
-       0xeb, 0x66, 0xbd, 0x28, 0xf8, 0x9d, 0xe7, 0xd9, 0x9e, 0x64, 0x7e, 0x8f,
-       0x54, 0xf8, 0xb9, 0xa7, 0x05, 0x3d, 0x35, 0x3d, 0x40, 0x0b, 0xc8, 0x40,
-       0x8f, 0xe2, 0x7f, 0xcb, 0x4c, 0xf9, 0xf5, 0xb8, 0xdb, 0xd1, 0x99, 0xb1,
-       0x4e, 0x01, 0x63, 0xc5, 0x98, 0x4c, 0x5f, 0xbc, 0x1c, 0xf1, 0xe5, 0xe6,
-       0x61, 0xeb, 0x20, 0xdf, 0x65, 0x0f, 0xe2, 0xa9, 0xb8, 0x0f, 0x3b, 0x29,
-       0x9e, 0x46, 0xbf, 0xd0, 0x4e, 0xd3, 0xc0, 0x76, 0xd1, 0xc2, 0x79, 0xdf,
-       0x76, 0x75, 0x5f, 0xb7, 0x98, 0x0b, 0x32, 0xf0, 0x1e, 0xfd, 0x6e, 0xbc,
-       0x17, 0xef, 0xc7, 0x7d, 0x78, 0x9e, 0x7c, 0xee, 0x00, 0xeb, 0xed, 0xc4,
-       0xb4, 0x7c, 0x96, 0x71, 0x5d, 0x7e, 0x37, 0x60, 0x7b, 0xf7, 0x57, 0xce,
-       0x9f, 0x4f, 0xd5, 0xf1, 0xc1, 0xfc, 0x6d, 0xa7, 0xb2, 0xf0, 0x7d, 0xe2,
-       0xbb, 0x11, 0x9f, 0xb0, 0x6b, 0x6d, 0xfe, 0xe4, 0x79, 0x9d, 0xe3, 0xf3,
-       0x33, 0xc5, 0xdb, 0xc2, 0x66, 0xcf, 0xa5, 0x47, 0x7c, 0xe5, 0x32, 0xc6,
-       0x3b, 0xe2, 0x4b, 0xb1, 0x0c, 0x24, 0x8b, 0x89, 0x5a, 0x5e, 0xe2, 0x02,
-       0x3a, 0xdd, 0x6f, 0x85, 0x4e, 0x1b, 0xef, 0x0f, 0xcb, 0x9a, 0xb7, 0x38,
-       0x66, 0x39, 0x2c, 0xb0, 0x1c, 0x16, 0x58, 0x0e, 0x0b, 0x2c, 0x87, 0x6c,
-       0xab, 0xbe, 0x56, 0x60, 0x39, 0xe4, 0xb5, 0xe4, 0x55, 0x5e, 0x4b, 0xa4,
-       0xec, 0xc6, 0x95, 0x7f, 0x53, 0xcb, 0xae, 0x3b, 0x6f, 0x53, 0xcb, 0x2a,
-       0xd6, 0x6f, 0xf2, 0x1d, 0x99, 0x68, 0x96, 0xd9, 0x5b, 0x2c, 0xb3, 0x1d,
-       0xb1, 0x41, 0xba, 0x5b, 0xc2, 0x9c, 0x59, 0xe6, 0x1c, 0xeb, 0xea, 0x94,
-       0x1f, 0x58, 0x2b, 0xc0, 0xf2, 0x04, 0xac, 0x69, 0x31, 0xdd, 0x07, 0xe9,
-       0x1e, 0xeb, 0xeb, 0xbb, 0x25, 0xc8, 0xf0, 0x1e, 0x75, 0x6e, 0xb1, 0x0c,
-       0x63, 0xfd, 0xb3, 0x7d, 0xb7, 0x8a, 0x06, 0x63, 0xb2, 0x40, 0x28, 0x43,
-       0xd0, 0xa7, 0x02, 0xa7, 0xf1, 0xbc, 0xaf, 0xb0, 0xde, 0x87, 0x0f, 0x0f,
-       0xeb, 0xc5, 0x19, 0x1f, 0xaf, 0x17, 0x91, 0x9b, 0xac, 0x4f, 0xcf, 0x97,
-       0x6c, 0x96, 0xfb, 0x7e, 0xfa, 0x56, 0x09, 0xeb, 0x34, 0x68, 0xc4, 0xe7,
-       0x65, 0x12, 0xbe, 0x31, 0x23, 0x86, 0xb1, 0x8f, 0x67, 0x0d, 0xc1, 0x27,
-       0x7f, 0x0a, 0x3a, 0x30, 0xed, 0x5f, 0xdc, 0x85, 0xda, 0xf3, 0x71, 0xa3,
-       0x53, 0xf9, 0x1a, 0x71, 0x8c, 0xf6, 0x68, 0x0b, 0xba, 0xe1, 0xbc, 0xdd,
-       0xbe, 0x24, 0x7e, 0xb3, 0x21, 0x0a, 0xff, 0x9b, 0x4b, 0x7f, 0x5d, 0xe2,
-       0xfb, 0x05, 0xbd, 0x66, 0x12, 0x7e, 0xe4, 0x90, 0xd3, 0xd3, 0xfe, 0xd8,
-       0x0c, 0x3d, 0x5b, 0x45, 0xbf, 0xaf, 0x52, 0x3e, 0x0c, 0x7d, 0x64, 0x45,
-       0xef, 0x90, 0xa4, 0x5d, 0x37, 0xe3, 0xce, 0x27, 0xbc, 0x75, 0x9c, 0x99,
-       0x10, 0x38, 0xb9, 0x8b, 0xf5, 0x0b, 0x68, 0xf3, 0x13, 0xe6, 0x35, 0x7e,
-       0x5f, 0x41, 0xeb, 0xb7, 0x1f, 0xb3, 0xce, 0xc1, 0x9c, 0xe1, 0x7c, 0x6d,
-       0x9d, 0xb6, 0xaa, 0x74, 0x9a, 0xed, 0xd0, 0x69, 0xb9, 0xba, 0x4e, 0x63,
-       0xde, 0x10, 0xba, 0x0c, 0xba, 0xea, 0x51, 0xc6, 0x91, 0xf2, 0x18, 0xf8,
-       0x70, 0x87, 0xd0, 0x5d, 0xac, 0xfb, 0xd9, 0xae, 0x58, 0xac, 0x66, 0x7d,
-       0x87, 0x85, 0x0e, 0xd1, 0xfc, 0xbd, 0x7f, 0xb7, 0x94, 0x8b, 0x6e, 0xa1,
-       0x0f, 0x72, 0x27, 0xa1, 0xb7, 0xbc, 0xda, 0x8f, 0x73, 0x3b, 0xb4, 0xb7,
-       0x23, 0x2f, 0xb1, 0x3e, 0x5b, 0x8c, 0xc2, 0xa6, 0xed, 0x51, 0xb6, 0x0f,
-       0xea, 0x72, 0x61, 0xaf, 0x0b, 0x63, 0xd5, 0xfa, 0x6c, 0x40, 0xf9, 0x35,
-       0xe0, 0x87, 0xc4, 0x9c, 0xb7, 0xc5, 0x08, 0x26, 0x30, 0x02, 0xdf, 0x13,
-       0x60, 0x7a, 0x89, 0x1a, 0xe2, 0x44, 0xef, 0xd2, 0xaa, 0x90, 0x8d, 0x77,
-       0x05, 0x76, 0xc9, 0xf3, 0x77, 0xb3, 0xd3, 0x07, 0x45, 0x3f, 0xf3, 0x4b,
-       0x0d, 0xfd, 0x38, 0x57, 0x78, 0x0f, 0xeb, 0x86, 0xe8, 0x6b, 0x65, 0x42,
-       0xea, 0xc0, 0xc5, 0x32, 0x6a, 0x80, 0x89, 0x3e, 0x73, 0x5f, 0xf5, 0x38,
-       0xd1, 0x0f, 0xad, 0x0f, 0x36, 0x22, 0x7b, 0x8c, 0x6b, 0xfb, 0x31, 0x47,
-       0x59, 0x07, 0x0f, 0x3d, 0xcb, 0xef, 0xc7, 0xb5, 0xf5, 0xc7, 0x73, 0xaf,
-       0x3e, 0x1e, 0xf8, 0xf6, 0x70, 0xcf, 0xbb, 0x74, 0x57, 0x8d, 0xe7, 0x6e,
-       0x7d, 0x3c, 0xcf, 0xa8, 0xf1, 0x50, 0xce, 0x88, 0x0d, 0x28, 0xdc, 0xbf,
-       0xe1, 0x67, 0x77, 0x27, 0x18, 0xc7, 0xe4, 0x96, 0x40, 0xe7, 0xfd, 0x8a,
-       0x9f, 0x9c, 0x7e, 0x54, 0x67, 0x5f, 0xad, 0xc9, 0x3b, 0xac, 0x7f, 0xef,
-       0x09, 0x1c, 0x33, 0xc2, 0x38, 0x06, 0xd7, 0x29, 0x0f, 0x3d, 0x9d, 0x0b,
-       0xa3, 0x4e, 0xed, 0x0c, 0x8f, 0x9b, 0xed, 0xb1, 0x69, 0xfe, 0x14, 0xfe,
-       0x35, 0x3c, 0x47, 0xdf, 0xff, 0x3c, 0xdd, 0x9b, 0x87, 0x2e, 0x07, 0x8e,
-       0x95, 0xb5, 0x6c, 0xef, 0x2d, 0x4b, 0xff, 0x6e, 0xca, 0xd3, 0xbf, 0x0b,
-       0xdf, 0xee, 0x34, 0x70, 0x7e, 0x08, 0x7e, 0xe0, 0xa4, 0xfa, 0xad, 0x8f,
-       0x5c, 0x15, 0xcf, 0xf2, 0xd2, 0x4b, 0x33, 0x8e, 0xd8, 0x38, 0xc4, 0xaa,
-       0x64, 0x59, 0xcf, 0xd8, 0xa1, 0x0e, 0x43, 0xe6, 0xdc, 0xdc, 0xa8, 0x6a,
-       0xec, 0x74, 0x94, 0xe7, 0xcc, 0x8e, 0x1a, 0x46, 0x4a, 0xf8, 0x1a, 0xba,
-       0xed, 0x1e, 0xea, 0xe2, 0x75, 0xf4, 0x2c, 0xa1, 0x96, 0x9a, 0x65, 0x62,
-       0x0f, 0xe0, 0x12, 0xf3, 0x64, 0x3e, 0x6a, 0x45, 0x1e, 0x17, 0x76, 0x29,
-       0xd6, 0x17, 0x03, 0x74, 0x62, 0x5a, 0xa3, 0x0f, 0x7c, 0xbc, 0x84, 0x3a,
-       0x9a, 0x51, 0x1e, 0x3f, 0xfc, 0xc7, 0x63, 0xe6, 0x9b, 0xbc, 0x2e, 0x5d,
-       0x12, 0x7e, 0x99, 0x0b, 0x94, 0x63, 0x39, 0x3d, 0x22, 0xe4, 0xd4, 0x18,
-       0x61, 0x29, 0x62, 0xb9, 0x42, 0x6c, 0xc2, 0xb8, 0xa8, 0xdb, 0x23, 0x6d,
-       0x1d, 0x1e, 0xe5, 0xb2, 0xaa, 0x87, 0x90, 0x86, 0xee, 0xd8, 0xb8, 0x4f,
-       0x22, 0xfd, 0x89, 0x7d, 0x31, 0x4e, 0x4c, 0xe6, 0xf6, 0x7d, 0xc3, 0xae,
-       0x33, 0x45, 0xbd, 0x48, 0xd0, 0x4e, 0xf8, 0x13, 0x8d, 0x29, 0xa6, 0x9b,
-       0xfe, 0xdd, 0x19, 0xa7, 0xdf, 0xe0, 0x9c, 0xc8, 0xeb, 0x7f, 0xa5, 0x2a,
-       0xd7, 0xe0, 0x1c, 0xdb, 0xf4, 0xf9, 0x83, 0x4e, 0x4c, 0x62, 0x15, 0x93,
-       0xc2, 0x97, 0xb3, 0x9b, 0x12, 0x0b, 0x53, 0xf4, 0x68, 0x01, 0x3a, 0x8c,
-       0xee, 0x24, 0x6c, 0xfc, 0xa2, 0x0c, 0x64, 0x7c, 0x8a, 0x52, 0x55, 0xd0,
-       0xc8, 0xc7, 0x58, 0x89, 0x79, 0xaf, 0x88, 0x3d, 0x7f, 0x3e, 0x2e, 0xe3,
-       0x77, 0x54, 0x7e, 0x5d, 0xf9, 0xcb, 0x87, 0x29, 0xb9, 0x40, 0xd9, 0x4c,
-       0xf4, 0x4b, 0xa2, 0xd6, 0x75, 0x26, 0x3a, 0xa1, 0x7c, 0x3b, 0x11, 0xbe,
-       0x0e, 0x7f, 0x99, 0x49, 0x5f, 0x2e, 0x58, 0xd9, 0x0c, 0x49, 0x9f, 0x05,
-       0x71, 0x1f, 0x0c, 0x5e, 0x7b, 0x77, 0xb0, 0x0e, 0x39, 0x21, 0xfc, 0x16,
-       0x8c, 0x54, 0xe6, 0xd1, 0x1e, 0x3e, 0x87, 0x7e, 0x82, 0x9d, 0x96, 0x29,
-       0x3e, 0xa5, 0xda, 0xd6, 0x28, 0xc4, 0xbc, 0x10, 0xfa, 0x55, 0x3b, 0x1b,
-       0x35, 0x1a, 0xf7, 0xc3, 0xe7, 0x71, 0x42, 0xe0, 0xc8, 0x11, 0xb6, 0x79,
-       0x44, 0xbb, 0xda, 0xac, 0xf0, 0x5f, 0xf0, 0x79, 0xf9, 0x81, 0x21, 0xfd,
-       0x9b, 0x08, 0xb8, 0x2e, 0xfd, 0x1a, 0xfc, 0xcc, 0x32, 0xf7, 0xa3, 0x29,
-       0x9e, 0x7e, 0x98, 0xe2, 0x9b, 0xf0, 0x33, 0x9d, 0xbc, 0xaf, 0x7e, 0x26,
-       0xa6, 0x35, 0xaf, 0x3d, 0x37, 0x58, 0x36, 0x5e, 0x5f, 0xd7, 0xfe, 0xfb,
-       0x50, 0xaf, 0xe1, 0x4c, 0xab, 0x90, 0xf8, 0xdd, 0x0c, 0x60, 0xf0, 0x7c,
-       0xf5, 0x71, 0xfc, 0x5e, 0x8c, 0x2f, 0x2d, 0xb0, 0x71, 0x84, 0xb1, 0x0d,
-       0x30, 0xce, 0x98, 0xd8, 0x17, 0x8b, 0x3f, 0x16, 0xf1, 0xe5, 0x97, 0x07,
-       0xc9, 0x0f, 0x7f, 0x9c, 0xad, 0x63, 0x29, 0xba, 0x45, 0xdc, 0xbb, 0xdc,
-       0x8f, 0xc4, 0xfa, 0x0c, 0x9d, 0x78, 0x87, 0xed, 0x86, 0x09, 0x15, 0x87,
-       0xd3, 0x21, 0x6a, 0x53, 0xc9, 0xbd, 0x54, 0xad, 0x53, 0x34, 0xef, 0xe9,
-       0xbd, 0x0e, 0xe7, 0x6f, 0x73, 0x41, 0x76, 0x9d, 0x98, 0x02, 0xfe, 0x29,
-       0x31, 0x47, 0x97, 0x88, 0xe4, 0x1c, 0x37, 0xf6, 0x31, 0xba, 0x78, 0x9e,
-       0x60, 0x0f, 0xc2, 0xef, 0xf7, 0x35, 0xfe, 0xc4, 0x7e, 0xc4, 0xd5, 0x21,
-       0xe0, 0xa8, 0x3e, 0x9b, 0x79, 0x66, 0x1a, 0xe7, 0x83, 0x6c, 0x9f, 0x69,
-       0xdc, 0x2b, 0x7d, 0x51, 0x6c, 0xb3, 0xa9, 0xf9, 0x82, 0x1f, 0x6a, 0x54,
-       0xd5, 0x29, 0xb0, 0xc8, 0xec, 0x07, 0x9d, 0x3e, 0x2d, 0x79, 0x5c, 0x6f,
-       0xef, 0x62, 0x23, 0xb1, 0x4e, 0xf8, 0xdd, 0x30, 0xd4, 0xeb, 0xdc, 0x0b,
-       0xda, 0xf3, 0x1c, 0x39, 0xf7, 0x36, 0x1e, 0xdf, 0xa5, 0x7f, 0xb3, 0xe8,
-       0xfe, 0xcc, 0xdb, 0x16, 0x8f, 0x79, 0xfb, 0xf9, 0x90, 0xdc, 0x3b, 0x7b,
-       0x58, 0xb5, 0xf1, 0x8a, 0x6f, 0x5d, 0xfe, 0x0e, 0xfc, 0x50, 0x8d, 0xfc,
-       0x8b, 0x77, 0x84, 0x5e, 0x69, 0xf5, 0x85, 0x47, 0x58, 0x9f, 0x4a, 0x39,
-       0x3e, 0xe1, 0x21, 0xc7, 0xfd, 0x31, 0xe0, 0x96, 0x8f, 0x2f, 0xc7, 0xc7,
-       0xdb, 0xca, 0xf1, 0x9e, 0x61, 0xe9, 0x8b, 0x6d, 0x95, 0x63, 0xe4, 0x00,
-       0x9d, 0xa8, 0xb6, 0xf3, 0x7b, 0x61, 0x1e, 0x90, 0xcb, 0xee, 0xf4, 0x95,
-       0x80, 0x66, 0xda, 0x5f, 0x82, 0x7d, 0x43, 0xf0, 0x25, 0xf6, 0x5e, 0x4e,
-       0x1a, 0xa9, 0x79, 0xf7, 0x5e, 0xea, 0x46, 0xee, 0xbd, 0xed, 0x71, 0x2f,
-       0xb0, 0x3b, 0x64, 0xc3, 0x8a, 0x48, 0x5f, 0x80, 0xa6, 0xdf, 0xb0, 0xef,
-       0x70, 0xc9, 0xca, 0x96, 0x09, 0xbe, 0xee, 0x30, 0x9d, 0xc3, 0xfe, 0xb4,
-       0xf2, 0x25, 0x1f, 0x2b, 0x48, 0x3a, 0x84, 0x0e, 0x0a, 0xfe, 0x00, 0xbe,
-       0x8d, 0xa4, 0xfd, 0x69, 0x9e, 0x63, 0xe9, 0x47, 0xce, 0x2c, 0x45, 0xd4,
-       0xbc, 0x71, 0x5b, 0x3c, 0xcf, 0x33, 0x5f, 0x10, 0xf3, 0x65, 0x3d, 0xbf,
-       0x52, 0x8f, 0x4f, 0xc6, 0xda, 0x50, 0xa3, 0xff, 0xe0, 0x75, 0xcf, 0x7f,
-       0x30, 0x24, 0x6a, 0x37, 0xdc, 0xa8, 0x1e, 0x64, 0xbc, 0x89, 0x39, 0x85,
-       0x0f, 0x52, 0xfb, 0x88, 0x1f, 0xda, 0x4b, 0xbd, 0x07, 0x18, 0x05, 0x18,
-       0x64, 0x33, 0xbe, 0x34, 0x0e, 0x22, 0xce, 0xdc, 0xe4, 0x7b, 0x50, 0x73,
-       0x6a, 0xdc, 0x4c, 0x51, 0x0f, 0xfc, 0x10, 0xa8, 0x25, 0x6d, 0xe6, 0x9a,
-       0x64, 0xec, 0x94, 0x90, 0xb1, 0xd4, 0xf2, 0x29, 0x25, 0x63, 0xa7, 0x94,
-       0x1f, 0xfe, 0x94, 0x92, 0xb1, 0x53, 0x4a, 0xc6, 0x4e, 0x29, 0x19, 0x3b,
-       0xc5, 0x7c, 0x3e, 0xc6, 0xf8, 0x16, 0x58, 0x44, 0xfb, 0x41, 0x7b, 0x29,
-       0x53, 0xc2, 0x75, 0xac, 0xcf, 0x6e, 0x39, 0x7b, 0x69, 0x44, 0xca, 0x19,
-       0x63, 0x13, 0x19, 0xaf, 0xc7, 0xef, 0xc2, 0x1c, 0xfc, 0x1e, 0xd3, 0xef,
-       0x23, 0x3a, 0x33, 0x8f, 0xbe, 0xfa, 0x28, 0x29, 0x6a, 0xc9, 0x76, 0x50,
-       0xc2, 0x89, 0x85, 0x43, 0xc8, 0x0f, 0x93, 0xb6, 0x5f, 0xb6, 0x6d, 0xae,
-       0x98, 0xe6, 0x93, 0x98, 0x9a, 0x2f, 0xb7, 0x5d, 0xd4, 0x45, 0xe9, 0x22,
-       0xe8, 0x8a, 0x98, 0x4a, 0x93, 0xe7, 0x46, 0xd0, 0x49, 0x86, 0x44, 0xb9,
-       0x68, 0x70, 0x4c, 0xd1, 0xe0, 0xdb, 0x62, 0x8c, 0x88, 0x49, 0x84, 0x2f,
-       0xb3, 0x3d, 0x1d, 0x72, 0x85, 0x31, 0x7e, 0x0e, 0xcb, 0xc2, 0xc1, 0x08,
-       0xeb, 0xa4, 0x8d, 0xd3, 0xa1, 0x31, 0xf6, 0x76, 0xba, 0x67, 0xa3, 0x79,
-       0x39, 0x77, 0x1c, 0x6b, 0x49, 0x44, 0xad, 0x23, 0x12, 0x17, 0x6f, 0xb1,
-       0x6b, 0x74, 0x34, 0xba, 0x97, 0x8f, 0xad, 0x74, 0x96, 0x0e, 0x90, 0xd1,
-       0x57, 0xa3, 0xbf, 0x60, 0x39, 0xe8, 0x66, 0x39, 0x38, 0xaa, 0xec, 0x92,
-       0xa3, 0x75, 0xbb, 0x64, 0xcf, 0x1e, 0xc4, 0x65, 0x64, 0xc4, 0xbe, 0xd7,
-       0x56, 0x55, 0x43, 0x00, 0xbe, 0x6f, 0x9c, 0x77, 0x51, 0x7c, 0x18, 0xe7,
-       0xf8, 0x2d, 0x22, 0x6b, 0x32, 0xee, 0x1b, 0xdf, 0x23, 0xb0, 0xbb, 0xcf,
-       0xc2, 0x3d, 0x47, 0xa5, 0xde, 0xf3, 0x91, 0x7f, 0xfc, 0x36, 0xe3, 0x89,
-       0x1a, 0x3d, 0xc1, 0xef, 0xcc, 0x17, 0xf7, 0xf1, 0xb3, 0x75, 0x4d, 0x09,
-       0x3b, 0x6e, 0xf8, 0xb6, 0x92, 0xbf, 0xaf, 0xdd, 0xbb, 0x2d, 0xc1, 0x8f,
-       0x8c, 0xa7, 0x8d, 0xd9, 0xe8, 0x7b, 0xb5, 0xd3, 0x27, 0xe1, 0x63, 0x87,
-       0x9c, 0x58, 0x21, 0xd3, 0xe7, 0x25, 0x1f, 0x12, 0x2b, 0x35, 0xe2, 0x63,
-       0x21, 0x2f, 0x35, 0xfa, 0x77, 0x1e, 0x5b, 0x88, 0xb0, 0x77, 0x22, 0x9f,
-       0x9f, 0xa6, 0x19, 0x91, 0x83, 0x8d, 0x38, 0xe9, 0x33, 0xf3, 0xfa, 0x5d,
-       0xb6, 0xe2, 0x8d, 0xcf, 0x20, 0xce, 0xad, 0xb8, 0x48, 0x6b, 0xaf, 0x39,
-       0xf0, 0xd7, 0x8d, 0x2d, 0xac, 0xf6, 0x85, 0x45, 0x4e, 0xf8, 0x76, 0xc6,
-       0x48, 0x3a, 0x1e, 0x7a, 0x9c, 0x9f, 0x0f, 0x3f, 0x5e, 0x80, 0x92, 0x57,
-       0xd0, 0xae, 0x93, 0x46, 0x17, 0x6a, 0x5f, 0xe0, 0xef, 0xc5, 0xfe, 0x65,
-       0x86, 0xba, 0xd5, 0xde, 0x44, 0x8f, 0xda, 0xcf, 0x8a, 0xb0, 0xec, 0x35,
-       0x72, 0x9d, 0x47, 0xeb, 0x3e, 0x3d, 0xc8, 0x84, 0xdb, 0xa7, 0xf7, 0xf4,
-       0x3a, 0xeb, 0xd5, 0x7a, 0x72, 0x80, 0x58, 0xd6, 0x2e, 0x52, 0xbe, 0x4a,
-       0x33, 0x4f, 0x1b, 0xcd, 0xe9, 0xdb, 0xf4, 0x3d, 0xdd, 0x9d, 0x31, 0xf3,
-       0xc2, 0x9b, 0x76, 0x50, 0xf1, 0x5f, 0x27, 0x9d, 0x29, 0x05, 0x79, 0xcd,
-       0x87, 0x6e, 0x05, 0xbd, 0xfc, 0xc3, 0xc8, 0x73, 0xf9, 0x7a, 0xa0, 0x93,
-       0x96, 0x96, 0x10, 0x6b, 0xf1, 0x47, 0x7b, 0x64, 0x7c, 0x71, 0x9a, 0xe9,
-       0x72, 0x80, 0xd7, 0x47, 0x43, 0xed, 0x1d, 0xe1, 0x1a, 0x74, 0x89, 0xa8,
-       0x37, 0x1a, 0xf8, 0xd2, 0x44, 0x90, 0xed, 0x02, 0xb9, 0xf7, 0x70, 0x88,
-       0x9f, 0xfd, 0xfd, 0x52, 0x1a, 0xfe, 0xb2, 0xd0, 0x11, 0x7e, 0x7e, 0x92,
-       0xf1, 0x44, 0x9c, 0x3a, 0xa9, 0xb2, 0xd4, 0xc9, 0x76, 0x41, 0x27, 0xe3,
-       0x89, 0xb1, 0xd0, 0xa8, 0x4f, 0xbc, 0x4b, 0xe4, 0xd4, 0x3c, 0x1c, 0x38,
-       0xc0, 0x7c, 0x85, 0x77, 0xbd, 0xae, 0xde, 0xe5, 0x7e, 0xc7, 0x2f, 0x6a,
-       0x38, 0x3f, 0xe2, 0x37, 0x2f, 0xdc, 0xc2, 0xef, 0x51, 0xcd, 0xcf, 0x30,
-       0x76, 0x0e, 0x53, 0x7e, 0xbe, 0x83, 0xc7, 0x10, 0x63, 0x3b, 0x22, 0xca,
-       0xe7, 0x8f, 0x50, 0xb6, 0x7a, 0x92, 0x7e, 0xbf, 0xea, 0xf4, 0x09, 0x3f,
-       0xc2, 0x7d, 0x96, 0x39, 0xfd, 0x5d, 0xdc, 0xaf, 0x0f, 0x6d, 0xb7, 0x8e,
-       0x09, 0x92, 0xff, 0x7b, 0x61, 0xea, 0x7c, 0x0e, 0xbe, 0x97, 0x1a, 0x15,
-       0xa3, 0xd6, 0xa5, 0x3b, 0x24, 0xfd, 0xcf, 0x2f, 0x88, 0xb8, 0x5a, 0xbe,
-       0x9f, 0x9f, 0x39, 0x87, 0x76, 0x2f, 0x98, 0x74, 0xd3, 0x96, 0xf4, 0x7e,
-       0x23, 0x10, 0x26, 0xff, 0xcb, 0x88, 0x7d, 0x02, 0x56, 0x33, 0x2f, 0xd8,
-       0xfb, 0x58, 0xbf, 0x3f, 0x87, 0xfb, 0xf8, 0xf3, 0x65, 0x9c, 0x07, 0x79,
-       0x9c, 0x58, 0xaf, 0x11, 0xef, 0x02, 0xbd, 0x78, 0x20, 0x12, 0x12, 0xfc,
-       0xf7, 0x08, 0xf3, 0x54, 0x87, 0xf0, 0x35, 0xf6, 0xa3, 0xad, 0x3d, 0xc4,
-       0xd8, 0xc2, 0xbc, 0x30, 0xb1, 0x0f, 0xe7, 0xf1, 0x3e, 0x3f, 0xd3, 0x48,
-       0xf2, 0x10, 0xc6, 0xd3, 0xc4, 0xdc, 0x81, 0x43, 0x13, 0xc4, 0xf3, 0x09,
-       0xfc, 0xc1, 0xf3, 0x19, 0x42, 0x7d, 0xa7, 0x20, 0xa5, 0xf8, 0x1d, 0xc9,
-       0x92, 0x1c, 0xf7, 0x5c, 0xd5, 0x4f, 0xd2, 0x4f, 0x75, 0x74, 0x44, 0xff,
-       0x9e, 0x21, 0x0d, 0xe2, 0xd9, 0x5a, 0x56, 0x70, 0xdc, 0x4b, 0x77, 0x4b,
-       0x3d, 0x74, 0x4f, 0xed, 0x69, 0xdd, 0x15, 0x76, 0x19, 0xeb, 0xf0, 0x74,
-       0x2f, 0xdd, 0x59, 0xea, 0x20, 0xea, 0x0f, 0x8a, 0x3d, 0xe7, 0xbb, 0xa5,
-       0x32, 0xbf, 0x3f, 0x31, 0x22, 0xfd, 0x3a, 0x0d, 0x1e, 0xb9, 0xeb, 0xc1,
-       0x23, 0x1f, 0x08, 0x1e, 0xd9, 0x37, 0xb2, 0x36, 0x8f, 0xec, 0x52, 0xb6,
-       0x48, 0x90, 0x3a, 0x15, 0x7f, 0xbc, 0xc4, 0xfc, 0xf1, 0x2c, 0xf3, 0xc7,
-       0xe1, 0x36, 0xfc, 0x61, 0xb8, 0xf8, 0xe3, 0x88, 0xe0, 0x8f, 0x87, 0x46,
-       0xd6, 0xe2, 0x8f, 0xc3, 0xfe, 0xb5, 0x7c, 0x4d, 0xe2, 0xb7, 0x3c, 0x2f,
-       0xcc, 0xd9, 0xbb, 0x99, 0xd7, 0x6d, 0xaa, 0xcc, 0x23, 0x67, 0x61, 0x25,
-       0x6a, 0xd0, 0xbf, 0x08, 0x9b, 0x6c, 0x55, 0xd8, 0xfc, 0x31, 0x11, 0xc3,
-       0xba, 0x28, 0xf8, 0x8b, 0xd7, 0xff, 0x18, 0x72, 0xaa, 0xdc, 0x73, 0xd1,
-       0x4d, 0x37, 0xa3, 0x98, 0x0b, 0x53, 0xcd, 0x05, 0xae, 0x75, 0xe9, 0xfa,
-       0x90, 0x01, 0xbe, 0x7e, 0xe1, 0x03, 0xf0, 0xe8, 0x72, 0x4f, 0x20, 0x59,
-       0xf8, 0xe6, 0x08, 0xf0, 0x5f, 0x7e, 0x99, 0x1c, 0xd7, 0x03, 0x7c, 0x3d,
-       0x2c, 0x7e, 0xfb, 0x09, 0xb2, 0xf2, 0x8f, 0x88, 0x71, 0x64, 0x9e, 0xbc,
-       0x59, 0x1a, 0xa6, 0x5b, 0xa5, 0xdd, 0xb4, 0x5a, 0x1a, 0xa1, 0x37, 0x45,
-       0x2d, 0x0d, 0x99, 0x1b, 0xb9, 0x2a, 0xe6, 0xc8, 0xa0, 0x43, 0x61, 0x6e,
-       0xb3, 0xb4, 0x9b, 0x56, 0x96, 0x34, 0x7f, 0x83, 0xb7, 0xc1, 0x2f, 0xf1,
-       0x3e, 0x99, 0x2f, 0xd7, 0xca, 0x33, 0xc9, 0x26, 0x9e, 0x91, 0xf7, 0x80,
-       0x57, 0xf2, 0xad, 0xb9, 0xbe, 0xdd, 0xa1, 0x18, 0x62, 0xf5, 0x82, 0xd4,
-       0x81, 0xb8, 0x45, 0xc3, 0x9a, 0x3c, 0xe4, 0x07, 0x86, 0xfe, 0x2a, 0xaf,
-       0xb9, 0x3c, 0x67, 0x36, 0xe2, 0x9c, 0x46, 0x18, 0x0f, 0x6f, 0x17, 0xf8,
-       0x37, 0x61, 0x07, 0x22, 0x49, 0xaa, 0x5d, 0x30, 0x6c, 0xd4, 0x73, 0x4c,
-       0xf3, 0xf3, 0x0c, 0xe5, 0x6f, 0xda, 0xe6, 0xe0, 0x3f, 0x37, 0xd6, 0xc5,
-       0x5e, 0xf2, 0x63, 0xdc, 0x67, 0xac, 0xc3, 0x8d, 0xfd, 0x1a, 0xaa, 0xef,
-       0xd7, 0x74, 0xf3, 0xb8, 0xa5, 0xec, 0xcd, 0xda, 0xdc, 0xae, 0xca, 0xed,
-       0xaa, 0xd8, 0xfb, 0xe3, 0xeb, 0x4b, 0xd8, 0x77, 0x1e, 0xa6, 0xd5, 0x79,
-       0xc8, 0x28, 0xfc, 0x21, 0x8d, 0xbd, 0xde, 0xd5, 0x65, 0x5c, 0x87, 0x4f,
-       0xa4, 0xb1, 0xd7, 0xbb, 0xaa, 0xf6, 0x7a, 0x57, 0x97, 0x63, 0x42, 0x6f,
-       0xe7, 0x4b, 0x4c, 0xf7, 0x92, 0x5f, 0xc5, 0x39, 0xee, 0x53, 0xbf, 0x2d,
-       0xf4, 0x98, 0xf0, 0x69, 0xf7, 0xd9, 0x6b, 0xd3, 0xf0, 0x50, 0x0b, 0x0d,
-       0x63, 0x02, 0x67, 0xa5, 0xf8, 0x99, 0xc9, 0xd2, 0x63, 0xff, 0x3b, 0x60,
-       0x78, 0x46, 0x00, 0xf3, 0x9e, 0x30, 0x34, 0xef, 0xc1, 0xe6, 0x8e, 0xf9,
-       0x19, 0x20, 0xf7, 0x14, 0xd9, 0x80, 0xfb, 0x16, 0x90, 0xf2, 0x4a, 0x06,
-       0xad, 0xbc, 0x02, 0xa6, 0x09, 0x75, 0x88, 0xfe, 0xa6, 0xf5, 0x9f, 0xe5,
-       0x60, 0xe3, 0x80, 0x4d, 0x40, 0x73, 0x9b, 0xa7, 0x90, 0x32, 0xf7, 0x0c,
-       0xac, 0x6f, 0xb1, 0xae, 0x6d, 0xb4, 0x01, 0xef, 0xb1, 0x5e, 0x34, 0x85,
-       0x85, 0x61, 0x49, 0x0f, 0x03, 0xb0, 0x7e, 0x00, 0xa5, 0x75, 0x50, 0x1d,
-       0x01, 0x4f, 0xef, 0x02, 0x4d, 0x40, 0xf7, 0x39, 0x01, 0xdb, 0xa2, 0xce,
-       0xfd, 0xca, 0xe0, 0xb5, 0xb2, 0x0d, 0xd0, 0x73, 0xab, 0x16, 0xf5, 0x88,
-       0xc9, 0x83, 0xf2, 0x99, 0x93, 0x0a, 0x03, 0x19, 0x79, 0x81, 0x0d, 0x9a,
-       0x17, 0xc0, 0xe1, 0x04, 0x4c, 0xeb, 0xc0, 0x32, 0x6a, 0x8d, 0x2e, 0xd0,
-       0x3c, 0x1e, 0x16, 0x97, 0x7e, 0x90, 0x18, 0x03, 0x54, 0x8c, 0x05, 0xc8,
-       0x97, 0x01, 0xb6, 0x29, 0x41, 0x7e, 0x05, 0xe5, 0x05, 0x90, 0xd9, 0x20,
-       0xbf, 0x83, 0xca, 0x4e, 0x50, 0x5e, 0x04, 0xb2, 0x97, 0x08, 0x41, 0xfd,
-       0x0c, 0xa4, 0x81, 0xec, 0xe6, 0x29, 0x22, 0x60, 0x7e, 0x52, 0x80, 0x10,
-       0x43, 0x03, 0x3c, 0x1f, 0x10, 0x1b, 0xc6, 0x30, 0xf5, 0x31, 0x64, 0xe4,
-       0x1b, 0x88, 0x19, 0x88, 0x7c, 0xc3, 0xce, 0x70, 0x40, 0x00, 0x16, 0x56,
-       0xff, 0xff, 0x1f, 0x53, 0x61, 0x01, 0xa6, 0x53, 0xd0, 0x3a, 0xd6, 0xdf,
-       0xff, 0x0f, 0x88, 0xb0, 0x30, 0xb4, 0xc0, 0xd7, 0x23, 0xe6, 0xc8, 0x83,
-       0xca, 0xd0, 0x05, 0x40, 0x56, 0x1b, 0xbc, 0x4d, 0xc0, 0x02, 0xbe, 0xef,
-       0x79, 0x01, 0xc3, 0x2f, 0x60, 0x99, 0xf5, 0xff, 0xff, 0x52, 0xb8, 0x5a,
-       0x10, 0x00, 0x00, 0x19, 0x3f, 0x16, 0x21, 0xc4, 0x7d, 0x00, 0x00, 0x00 };
+       0xdc, 0x5b, 0x6b, 0x6c, 0x1c, 0xd7, 0x75, 0x3e, 0x33, 0x3b, 0x4b, 0xae,
+       0xc8, 0x15, 0x35, 0x22, 0x57, 0xd4, 0x9a, 0xa2, 0xed, 0x5d, 0x72, 0x28,
+       0xb2, 0x96, 0xea, 0xae, 0x29, 0xa6, 0x62, 0xd3, 0x4d, 0xb4, 0xd9, 0xa5,
+       0x5c, 0xb5, 0x75, 0x5a, 0x4a, 0x26, 0xfc, 0x48, 0x55, 0x83, 0xde, 0xa5,
+       0x9c, 0xa0, 0xa8, 0x53, 0xc9, 0x76, 0x85, 0x20, 0x05, 0xaa, 0x05, 0x1f,
+       0x89, 0x52, 0xb0, 0x1c, 0xc5, 0x92, 0x29, 0xb5, 0x71, 0x6b, 0x96, 0xb4,
+       0x6c, 0x15, 0xd8, 0x6a, 0x65, 0xc7, 0x6d, 0x68, 0x54, 0x2e, 0x65, 0xca,
+       0x69, 0x95, 0x26, 0x48, 0x8d, 0xa0, 0x42, 0x95, 0x3f, 0x8e, 0xe1, 0xf4,
+       0x87, 0x5b, 0xf4, 0x87, 0xd1, 0x07, 0x22, 0xd7, 0x8f, 0xed, 0xf7, 0xdd,
+       0xb9, 0x43, 0x0e, 0x97, 0x14, 0x45, 0xf9, 0xf5, 0xa3, 0x04, 0x56, 0x33,
+       0xf7, 0x7d, 0xee, 0xb9, 0xe7, 0x7c, 0xe7, 0x31, 0x57, 0x3f, 0x2f, 0x52,
+       0x27, 0xfa, 0x6f, 0x3d, 0x7e, 0x89, 0x87, 0x7f, 0xaf, 0x70, 0xfb, 0xce,
+       0xdb, 0x77, 0xe0, 0xf5, 0x0e, 0xd3, 0xa8, 0x0d, 0xb1, 0x9e, 0xff, 0xc4,
+       0xf0, 0xeb, 0xd6, 0xef, 0x2b, 0xfd, 0xd9, 0xf8, 0xbd, 0x89, 0xc6, 0xc1,
+       0x7f, 0x17, 0x31, 0xae, 0xd1, 0x27, 0xf8, 0x57, 0xa9, 0xac, 0xde, 0x6e,
+       0x92, 0x96, 0x55, 0xda, 0x43, 0xde, 0x92, 0x8a, 0x66, 0xfe, 0x24, 0x62,
+       0xa6, 0x33, 0x47, 0xb2, 0x8e, 0x11, 0x09, 0xa5, 0xbb, 0x8a, 0x05, 0x47,
+       0x24, 0x53, 0xda, 0x96, 0xc8, 0xc9, 0x7b, 0x95, 0x62, 0xcc, 0x92, 0xac,
+       0x23, 0x91, 0x9b, 0xd3, 0xef, 0x3e, 0xf5, 0xd2, 0xce, 0xe4, 0x5b, 0x53,
+       0x21, 0x89, 0xd8, 0xe9, 0x17, 0xc4, 0xde, 0x2a, 0x91, 0x56, 0x8c, 0x79,
+       0xb2, 0x33, 0x63, 0x48, 0x83, 0x3f, 0xd7, 0x9b, 0x95, 0x97, 0x3a, 0xa5,
+       0xd8, 0x92, 0x8e, 0x88, 0x99, 0xee, 0xb8, 0x92, 0x0d, 0xd9, 0x83, 0xa1,
+       0xb4, 0x2d, 0x73, 0x65, 0xe9, 0x3f, 0x30, 0x2e, 0x91, 0x48, 0xfa, 0x4b,
+       0x91, 0xda, 0x0e, 0x89, 0x58, 0xe9, 0xa9, 0x23, 0x5f, 0x73, 0x8e, 0x54,
+       0x4c, 0xc7, 0xe9, 0x9a, 0x96, 0x68, 0xef, 0xe9, 0x1e, 0xb4, 0x97, 0x92,
+       0x5d, 0x22, 0x3b, 0xc5, 0x74, 0x8a, 0xd1, 0x90, 0x13, 0x91, 0x6c, 0xd9,
+       0x91, 0x5c, 0x59, 0xe4, 0x1f, 0x4a, 0x86, 0x9c, 0x76, 0x9a, 0x65, 0x7a,
+       0xfb, 0xbb, 0x95, 0x0c, 0x68, 0xf9, 0x7b, 0x67, 0xea, 0xc8, 0xa8, 0x43,
+       0x7a, 0x1f, 0x8b, 0x90, 0xae, 0x50, 0x7a, 0xa8, 0xb6, 0xe0, 0x58, 0x32,
+       0x5c, 0x62, 0xdd, 0x80, 0xc9, 0xba, 0x70, 0x3a, 0x52, 0x77, 0xda, 0x89,
+       0xea, 0xba, 0x52, 0x26, 0x8b, 0xf9, 0x46, 0x4a, 0xec, 0x1b, 0xe9, 0x2e,
+       0x38, 0x31, 0x5d, 0x3f, 0xba, 0x33, 0xeb, 0xc4, 0x51, 0xdf, 0xaa, 0xdb,
+       0x7a, 0xbe, 0x5c, 0x70, 0x1c, 0xdd, 0x76, 0x35, 0x94, 0x75, 0xba, 0x74,
+       0xfd, 0xab, 0xbb, 0x0a, 0xce, 0x76, 0x5d, 0xff, 0xd6, 0xae, 0xac, 0x93,
+       0xd2, 0xf5, 0xe3, 0xf7, 0x17, 0x9c, 0x1e, 0x5d, 0xdf, 0x8a, 0xfa, 0x5e,
+       0x5d, 0xff, 0x83, 0xde, 0x82, 0x93, 0x46, 0xfd, 0x97, 0x22, 0x66, 0x87,
+       0x2d, 0x63, 0xa5, 0x04, 0x7e, 0x19, 0xb4, 0xf5, 0xa1, 0x6e, 0x0f, 0x7e,
+       0x77, 0xe1, 0x37, 0xbf, 0x41, 0x1a, 0xfa, 0xf1, 0x6c, 0x6b, 0xf5, 0x78,
+       0x07, 0x1e, 0xb9, 0x11, 0x79, 0x3d, 0x14, 0x97, 0x97, 0x3a, 0x5f, 0x07,
+       0x0f, 0x6d, 0x39, 0x57, 0x16, 0xa3, 0xbf, 0x33, 0x0e, 0xde, 0xc5, 0xe4,
+       0xb9, 0x72, 0xbd, 0x84, 0x1e, 0x0f, 0x81, 0x37, 0x5f, 0x90, 0x7c, 0x2c,
+       0x22, 0x1b, 0x27, 0x0d, 0x69, 0xeb, 0x8e, 0x48, 0xc6, 0xe6, 0xda, 0x38,
+       0xed, 0x89, 0x98, 0x84, 0x26, 0x33, 0x4d, 0xa6, 0x74, 0xd8, 0x39, 0x29,
+       0x82, 0x77, 0x57, 0x28, 0x97, 0x68, 0x4b, 0x48, 0x6e, 0xfc, 0x36, 0x19,
+       0xb4, 0x49, 0xd7, 0xdc, 0xcd, 0xde, 0x5a, 0x11, 0x23, 0x7b, 0x72, 0x40,
+       0xc6, 0xdc, 0xa8, 0x91, 0x3b, 0xf9, 0x59, 0xc9, 0xa6, 0x24, 0x86, 0x71,
+       0xf1, 0x3c, 0x5a, 0x66, 0x4a, 0x03, 0x32, 0xea, 0x8a, 0x91, 0x75, 0xc9,
+       0xcf, 0x66, 0xb4, 0x37, 0xa8, 0xbe, 0xa8, 0x6b, 0x0d, 0xa9, 0xb9, 0x23,
+       0xa8, 0xb7, 0x51, 0xdf, 0x68, 0xf4, 0xa9, 0x39, 0x54, 0x7d, 0x62, 0x44,
+       0xa2, 0xf2, 0x74, 0x29, 0xa6, 0xfb, 0x56, 0x2a, 0xd9, 0x94, 0x8d, 0x7e,
+       0x03, 0x32, 0xe2, 0xc6, 0x64, 0x10, 0xcf, 0x61, 0x97, 0x72, 0x15, 0x87,
+       0x4c, 0x35, 0x14, 0xf3, 0x27, 0xd4, 0x7c, 0x89, 0x50, 0x9a, 0xf3, 0xb5,
+       0xa2, 0xdf, 0xdb, 0xa0, 0xcb, 0x10, 0x4b, 0x9d, 0x65, 0x46, 0xf2, 0xe3,
+       0x06, 0xe4, 0x0d, 0x4f, 0xc5, 0xd7, 0x3e, 0xd0, 0x6f, 0x89, 0xd3, 0x6d,
+       0x48, 0x01, 0x67, 0x55, 0xb4, 0x51, 0x2e, 0xcd, 0x9a, 0x59, 0xb7, 0x56,
+       0x72, 0x56, 0x42, 0x42, 0x13, 0x94, 0xa5, 0x41, 0x19, 0xc1, 0x18, 0xd3,
+       0x61, 0x9f, 0xb7, 0xb1, 0xef, 0x41, 0x75, 0x0e, 0x35, 0xe9, 0xa2, 0x99,
+       0x2b, 0x37, 0x8b, 0x39, 0xb9, 0x5f, 0x5e, 0x19, 0x17, 0x3b, 0x94, 0x7e,
+       0xb7, 0x92, 0x75, 0x46, 0xcd, 0xec, 0xb3, 0x96, 0x84, 0x27, 0x0c, 0x19,
+       0x75, 0x92, 0xd0, 0x80, 0xa3, 0xe6, 0xee, 0xf2, 0x2c, 0xfa, 0x71, 0x1c,
+       0xfa, 0x95, 0x4c, 0xf0, 0x95, 0xef, 0xdb, 0x6c, 0x53, 0xc9, 0x33, 0xfb,
+       0xe0, 0x0c, 0xb0, 0x8f, 0xe7, 0x5c, 0x9c, 0x89, 0x3a, 0xa3, 0x04, 0xce,
+       0x48, 0x8c, 0xbe, 0x4e, 0xc8, 0xd4, 0x09, 0x4b, 0xf2, 0x29, 0xec, 0x0b,
+       0xbd, 0xf3, 0xa9, 0x45, 0xba, 0x46, 0xc6, 0xab, 0xe9, 0xe2, 0x38, 0xd2,
+       0xe5, 0xd1, 0x34, 0x7c, 0x82, 0xf4, 0x2d, 0xd2, 0x33, 0x36, 0xee, 0xd3,
+       0xc8, 0xf5, 0x48, 0x9b, 0x4f, 0x17, 0xc7, 0x91, 0xae, 0x26, 0x9e, 0x35,
+       0xff, 0x8c, 0x3e, 0xd0, 0x31, 0xe2, 0x5a, 0x38, 0xa3, 0xa8, 0xe4, 0xed,
+       0xa2, 0x31, 0xd2, 0xbb, 0x2d, 0x0e, 0x6d, 0x36, 0x86, 0x7b, 0x49, 0xb3,
+       0x83, 0x73, 0xac, 0x51, 0xe7, 0x0d, 0xf9, 0x26, 0xef, 0xd0, 0x9f, 0xeb,
+       0xe3, 0xbd, 0x64, 0xcb, 0xa8, 0x9a, 0x8f, 0x34, 0x7d, 0x14, 0xf3, 0x90,
+       0xd6, 0x4b, 0x90, 0xd5, 0x1e, 0xc8, 0x68, 0x4a, 0xfe, 0xae, 0xbc, 0x5d,
+       0xbe, 0x53, 0xee, 0x92, 0xbf, 0x81, 0xde, 0xfe, 0x75, 0x39, 0x21, 0x2f,
+       0x94, 0x5b, 0xe5, 0xdb, 0xe5, 0xb8, 0x3c, 0xaf, 0xe4, 0xb7, 0x4f, 0xa4,
+       0x81, 0x32, 0x9d, 0x90, 0x46, 0xe8, 0xcf, 0x46, 0xe8, 0xe6, 0x13, 0xe0,
+       0xdf, 0x89, 0x4e, 0xc9, 0x34, 0xa5, 0x25, 0x72, 0x0b, 0x7e, 0x9b, 0xf1,
+       0x6b, 0x4e, 0x43, 0xee, 0x5c, 0xf2, 0x8e, 0x3c, 0xb4, 0x24, 0xa7, 0xf6,
+       0x6c, 0xc9, 0x48, 0x79, 0xfe, 0x16, 0x4f, 0x76, 0x45, 0xfa, 0xc1, 0x63,
+       0xb3, 0xfb, 0x7f, 0x2a, 0x19, 0x1b, 0xfb, 0xe8, 0xde, 0xa6, 0x78, 0x6f,
+       0x76, 0x53, 0x66, 0x13, 0x90, 0x7b, 0xcb, 0xc8, 0xb9, 0x67, 0x80, 0x1b,
+       0xf5, 0x46, 0xf6, 0x78, 0x51, 0x0a, 0xc7, 0x2b, 0x52, 0x48, 0x85, 0xe5,
+       0x11, 0xbb, 0x22, 0x7d, 0xa9, 0x1a, 0x39, 0x64, 0x83, 0xf7, 0xdb, 0x7f,
+       0xdf, 0xf0, 0x31, 0xfb, 0x89, 0xf2, 0x61, 0xbc, 0xb3, 0x4e, 0xe4, 0x84,
+       0x7a, 0xf7, 0xea, 0x8b, 0xe5, 0xb0, 0x64, 0x62, 0xc5, 0xb8, 0x25, 0x2d,
+       0xa6, 0xb7, 0xee, 0xb0, 0xdf, 0x06, 0x7e, 0x4c, 0x01, 0x27, 0x93, 0x4a,
+       0x5f, 0xf2, 0xe3, 0xeb, 0xae, 0x66, 0x54, 0x35, 0xfa, 0xdb, 0x3d, 0x32,
+       0xaf, 0xf8, 0x99, 0x18, 0x34, 0xd2, 0x31, 0x69, 0x2b, 0xb1, 0xdc, 0x6b,
+       0xdc, 0x5d, 0xa6, 0x3c, 0xe3, 0xbd, 0x4c, 0x3a, 0x6f, 0x42, 0x3f, 0x0b,
+       0xcf, 0x8c, 0xa6, 0x37, 0x48, 0x23, 0xe7, 0x21, 0x8d, 0x7c, 0xfe, 0x79,
+       0x80, 0xc6, 0xa7, 0x16, 0xde, 0x4f, 0x04, 0xde, 0x8b, 0xe5, 0x4b, 0x75,
+       0x1e, 0x6d, 0xbd, 0xf2, 0xc6, 0xc4, 0x57, 0xf4, 0x3a, 0x78, 0x3f, 0xcb,
+       0xf9, 0xff, 0xaa, 0xe2, 0xc9, 0x4b, 0xf1, 0x3a, 0xeb, 0xcc, 0x06, 0xd6,
+       0x79, 0x31, 0xb0, 0xce, 0x8b, 0x81, 0x75, 0x8a, 0xe0, 0xa9, 0x6c, 0x30,
+       0x21, 0xc3, 0x79, 0x9a, 0x31, 0x39, 0x8a, 0x39, 0x5f, 0x97, 0x50, 0x9a,
+       0x7a, 0xee, 0xe3, 0xcd, 0x65, 0xf4, 0x4f, 0xcb, 0xfc, 0x44, 0x51, 0xf2,
+       0xc7, 0xc3, 0xb2, 0x4f, 0xf5, 0xdb, 0xa5, 0xe9, 0x0b, 0xb6, 0x45, 0x64,
+       0x6f, 0x8c, 0xef, 0x7e, 0x9b, 0x05, 0x3e, 0xb3, 0xfc, 0xc6, 0x4d, 0x5e,
+       0x99, 0xef, 0xb3, 0x7a, 0x2f, 0x03, 0xde, 0xb8, 0xb3, 0x6f, 0x2a, 0x3c,
+       0x9c, 0x2b, 0x13, 0xb7, 0x24, 0x15, 0x72, 0xe4, 0x60, 0x5f, 0xaa, 0x59,
+       0x46, 0x6c, 0x23, 0x35, 0xdc, 0x55, 0x4b, 0xbd, 0xc8, 0x98, 0x4e, 0x3d,
+       0xb0, 0x41, 0x12, 0x26, 0x31, 0x5f, 0xed, 0xcb, 0x30, 0x3d, 0xfa, 0x6d,
+       0x96, 0xfb, 0x4d, 0xa7, 0xb1, 0xaa, 0x9e, 0xba, 0x1d, 0xc2, 0x3b, 0x65,
+       0x78, 0xb7, 0x3e, 0x63, 0x0b, 0x65, 0xe2, 0xf0, 0xad, 0xba, 0xec, 0xb7,
+       0xe3, 0xc0, 0x96, 0x94, 0x7f, 0xb6, 0x65, 0x69, 0xd9, 0xc7, 0x89, 0x20,
+       0x86, 0x73, 0xaf, 0xc0, 0x27, 0x87, 0x72, 0x17, 0x06, 0xad, 0x29, 0xe8,
+       0x5c, 0xad, 0xa6, 0x61, 0xb3, 0xa6, 0x01, 0xb4, 0x76, 0x42, 0xb2, 0x94,
+       0x2e, 0x29, 0xd1, 0xaa, 0x2a, 0x93, 0xf7, 0xfe, 0xfb, 0x7a, 0xd5, 0xee,
+       0xe9, 0x9c, 0xff, 0xf4, 0xf1, 0xfd, 0xcd, 0x80, 0xbd, 0x68, 0x85, 0xce,
+       0xc6, 0xc0, 0x2b, 0x1f, 0xeb, 0x89, 0xc1, 0x71, 0xd8, 0x07, 0xc8, 0xaa,
+       0xc2, 0xf6, 0x28, 0xf0, 0xd0, 0xd2, 0xd8, 0x1c, 0xd1, 0xd8, 0x1c, 0x05,
+       0x2e, 0xb3, 0x6c, 0xeb, 0x72, 0x4c, 0x97, 0xe3, 0x28, 0xc3, 0x8e, 0x4f,
+       0x12, 0xbb, 0x1b, 0x8a, 0x43, 0x27, 0x14, 0xde, 0xd3, 0x56, 0x00, 0x85,
+       0x89, 0xd7, 0xc4, 0xed, 0x56, 0x99, 0x2e, 0x61, 0xbd, 0x05, 0x6c, 0xe4,
+       0xde, 0x83, 0xf4, 0x90, 0x96, 0x75, 0x62, 0xc2, 0x76, 0x65, 0x62, 0xa4,
+       0xf7, 0x61, 0xec, 0x9d, 0xf8, 0x43, 0xba, 0x6f, 0x06, 0xad, 0xdc, 0xc7,
+       0x27, 0x49, 0x2b, 0xd7, 0xab, 0xa6, 0xf7, 0xc3, 0xe2, 0x20, 0x69, 0x3f,
+       0x83, 0x3d, 0x67, 0x80, 0x79, 0x62, 0x0c, 0x74, 0x0e, 0x60, 0xcf, 0xfd,
+       0xc0, 0xc3, 0xbb, 0x80, 0x87, 0x7b, 0x80, 0x87, 0x7d, 0xc0, 0xc3, 0x34,
+       0xb0, 0xb0, 0x17, 0x58, 0xd8, 0x03, 0x2c, 0x4c, 0x81, 0x37, 0x31, 0x99,
+       0x02, 0x36, 0x4e, 0x01, 0x23, 0xa7, 0x30, 0xc7, 0xf0, 0xa4, 0x18, 0x0f,
+       0x60, 0x0f, 0xdf, 0x9c, 0x48, 0x9e, 0x82, 0x2c, 0xc5, 0x8b, 0x26, 0xe4,
+       0x3f, 0xd5, 0x0b, 0xd9, 0xee, 0x92, 0x99, 0xb2, 0x25, 0x05, 0xd8, 0xd4,
+       0xb6, 0xad, 0xed, 0xd0, 0x35, 0xc8, 0x7b, 0x5c, 0xf4, 0xdf, 0x7a, 0xfd,
+       0xfc, 0xb1, 0x88, 0xf3, 0x4f, 0x94, 0xc5, 0x84, 0xc8, 0x79, 0xc9, 0xbb,
+       0xed, 0x76, 0x9b, 0xd9, 0x85, 0x7e, 0x2c, 0xa7, 0xcc, 0x03, 0xc7, 0xef,
+       0x30, 0x87, 0x8e, 0x2b, 0x7f, 0x05, 0x78, 0x55, 0x91, 0xd1, 0x14, 0x75,
+       0xab, 0x22, 0xa7, 0x53, 0xc9, 0xde, 0xa2, 0xd4, 0xcb, 0x58, 0x6c, 0x5c,
+       0xd9, 0x5a, 0x2b, 0x7d, 0x4c, 0xd9, 0xab, 0x82, 0x83, 0x67, 0xa9, 0xdb,
+       0xcc, 0x1f, 0xe7, 0xfe, 0xdb, 0xf1, 0x0b, 0x83, 0x16, 0xce, 0x6f, 0x49,
+       0x5f, 0x8f, 0x6d, 0x3e, 0xd4, 0x59, 0x84, 0x42, 0x24, 0xed, 0x79, 0xac,
+       0x9c, 0x1b, 0x6f, 0x8f, 0xb7, 0x9b, 0x96, 0x0c, 0x5a, 0x86, 0x0c, 0x43,
+       0xbe, 0xfb, 0x52, 0x6f, 0x57, 0xc6, 0x62, 0x6c, 0xaf, 0x95, 0xaf, 0x2b,
+       0x9f, 0x03, 0x6b, 0xcf, 0x9c, 0xc0, 0xba, 0x61, 0x9c, 0x01, 0xd7, 0xe5,
+       0x3c, 0x28, 0x97, 0x2c, 0x94, 0x93, 0xa7, 0x8a, 0x52, 0x86, 0x9e, 0x6c,
+       0x90, 0xec, 0xf6, 0x1a, 0xc9, 0xf4, 0x27, 0x64, 0x78, 0xa2, 0x0c, 0x9c,
+       0x8a, 0x28, 0x5d, 0xc9, 0x0f, 0x24, 0xe4, 0xf1, 0x09, 0xd6, 0x9d, 0xc3,
+       0xfe, 0x93, 0xc7, 0x32, 0xc2, 0xfd, 0x1b, 0x92, 0xd9, 0x7f, 0x4e, 0x1e,
+       0x71, 0xcf, 0xc9, 0x10, 0xce, 0xf0, 0xe9, 0xf2, 0xac, 0x1c, 0x70, 0x1d,
+       0x39, 0x0d, 0xbc, 0xcf, 0x1d, 0x07, 0xee, 0x39, 0xeb, 0x81, 0x51, 0xc9,
+       0x73, 0xb4, 0xa1, 0x26, 0xfc, 0xbc, 0x69, 0xf0, 0xf7, 0x89, 0x09, 0xf2,
+       0xd7, 0x94, 0x47, 0x7f, 0xd1, 0x80, 0x3e, 0x26, 0xc0, 0xcf, 0x56, 0x39,
+       0xec, 0x26, 0x67, 0x33, 0x26, 0x70, 0x31, 0x65, 0x87, 0xa4, 0x2e, 0x8e,
+       0x7e, 0x5e, 0x9f, 0x5c, 0x2a, 0x84, 0xb3, 0x2e, 0xa2, 0xef, 0xdb, 0xa0,
+       0x93, 0x63, 0x63, 0xf8, 0x65, 0xd0, 0x0f, 0xf2, 0x6b, 0x27, 0x67, 0xa7,
+       0x4c, 0xf6, 0x4f, 0xe0, 0xcc, 0x80, 0x2b, 0x93, 0x00, 0x1e, 0x9b, 0xef,
+       0x69, 0x33, 0x4f, 0x1a, 0x5c, 0xca, 0x59, 0x02, 0x34, 0x11, 0xd3, 0xda,
+       0xcf, 0x7d, 0x47, 0xb8, 0xce, 0x46, 0xf4, 0x7f, 0x07, 0x7e, 0xae, 0x2d,
+       0x33, 0x38, 0x97, 0x9f, 0x82, 0x57, 0x99, 0xb8, 0x57, 0x1e, 0x9e, 0x4c,
+       0x9e, 0x9b, 0x37, 0xf9, 0xee, 0x14, 0xf3, 0xe6, 0x6d, 0x22, 0x8d, 0xe4,
+       0x57, 0x0a, 0xbc, 0x72, 0x6c, 0xd3, 0xdc, 0xaa, 0x7d, 0x3b, 0xea, 0x89,
+       0x03, 0x9a, 0xe0, 0x67, 0x74, 0x07, 0xf5, 0x84, 0xf6, 0xce, 0xd7, 0x93,
+       0x64, 0x7c, 0xca, 0x84, 0xff, 0xd1, 0x6d, 0xc9, 0x31, 0x55, 0x06, 0x8f,
+       0x06, 0x92, 0xf1, 0x8c, 0x49, 0x9f, 0xb7, 0x4b, 0x9e, 0x76, 0xd9, 0x1f,
+       0x7c, 0x1c, 0x8f, 0xea, 0xfe, 0xe7, 0x20, 0x23, 0xf4, 0xcf, 0xba, 0x40,
+       0xb3, 0xa7, 0x3b, 0xd3, 0xe3, 0x31, 0xd5, 0x36, 0xa6, 0xf6, 0x60, 0x60,
+       0x5d, 0xc8, 0x26, 0x7c, 0xb5, 0x9c, 0xd2, 0x23, 0x3b, 0x03, 0x5f, 0x1e,
+       0x7a, 0xe0, 0xe9, 0xd0, 0x4c, 0x89, 0xb4, 0xdc, 0x43, 0x7e, 0x14, 0x41,
+       0xcc, 0x31, 0x33, 0x8d, 0x73, 0xed, 0x91, 0x22, 0xfd, 0xb9, 0xf9, 0xd0,
+       0xd3, 0x32, 0x38, 0x43, 0x7b, 0x83, 0x9f, 0xeb, 0xd8, 0x8c, 0x1f, 0x32,
+       0xca, 0x16, 0x6c, 0xc1, 0x39, 0xc3, 0x4e, 0xa4, 0x36, 0x6a, 0x3f, 0xe6,
+       0x49, 0x9c, 0xdb, 0x79, 0x9c, 0x6b, 0x49, 0x86, 0x4e, 0x5e, 0xa2, 0xcc,
+       0x76, 0xcd, 0x48, 0xb2, 0x6b, 0x4c, 0xb6, 0xd9, 0xd3, 0xd0, 0xb7, 0xcc,
+       0x40, 0x65, 0x97, 0x99, 0xe6, 0x98, 0x23, 0x18, 0x83, 0xe7, 0xcc, 0x25,
+       0x39, 0x54, 0x66, 0xdd, 0xef, 0x80, 0x9f, 0xb0, 0x3b, 0x3d, 0x4f, 0x6a,
+       0x39, 0xc7, 0x7c, 0x96, 0x3f, 0xdf, 0x25, 0x3d, 0x1f, 0xfb, 0xb1, 0x0f,
+       0xc7, 0x2c, 0xce, 0xbb, 0x9b, 0xb6, 0x06, 0x78, 0xd3, 0x61, 0x56, 0x76,
+       0x85, 0xd1, 0x7e, 0xba, 0x87, 0xef, 0x98, 0x07, 0xb6, 0xc6, 0x76, 0xce,
+       0xa3, 0x2f, 0xf6, 0xe5, 0xae, 0x93, 0xb6, 0x66, 0x9f, 0x5e, 0x9e, 0x3b,
+       0xfd, 0x00, 0x96, 0x1f, 0x6e, 0xf2, 0x78, 0x3f, 0x12, 0xf2, 0xb0, 0xfb,
+       0x2f, 0x51, 0xa6, 0x7e, 0x3d, 0x26, 0x39, 0x37, 0x89, 0x7d, 0x42, 0x87,
+       0xca, 0x0d, 0x86, 0xb7, 0x47, 0xf0, 0xbf, 0xff, 0x32, 0xf8, 0x20, 0x45,
+       0x8f, 0x37, 0xe4, 0x0b, 0x79, 0xd2, 0x00, 0xd9, 0xae, 0xc3, 0xbc, 0x58,
+       0x47, 0xf1, 0xe0, 0x96, 0x26, 0xcf, 0xef, 0x4d, 0x16, 0x33, 0x8c, 0xd7,
+       0x1a, 0x29, 0xb3, 0xc0, 0xa8, 0xf2, 0xfd, 0x36, 0xe7, 0x9e, 0x32, 0xd7,
+       0x91, 0xde, 0xc4, 0x85, 0xd0, 0x7e, 0x96, 0xbb, 0xa6, 0x4c, 0xf0, 0x1e,
+       0xe7, 0x93, 0xdd, 0xde, 0xae, 0x71, 0xe9, 0x99, 0x10, 0x65, 0x94, 0xf2,
+       0x9c, 0x77, 0xb7, 0xd9, 0xf7, 0x08, 0x65, 0x34, 0x86, 0xf3, 0x26, 0x2e,
+       0xf0, 0x69, 0xc1, 0x26, 0xc6, 0x71, 0xc6, 0x5b, 0x34, 0xed, 0x7c, 0xb7,
+       0x64, 0xca, 0xc6, 0x1a, 0xee, 0x7f, 0x6f, 0xf0, 0xea, 0xf8, 0xde, 0xc2,
+       0x33, 0x39, 0xb6, 0x94, 0x56, 0x9e, 0x67, 0xf5, 0x19, 0x9e, 0x06, 0xed,
+       0xac, 0xc7, 0x73, 0xe6, 0x14, 0xf4, 0x0f, 0x58, 0xd1, 0xd3, 0x11, 0xbf,
+       0x88, 0xfe, 0x39, 0x60, 0x7c, 0xd1, 0x62, 0xdb, 0x55, 0x63, 0x71, 0x8c,
+       0x49, 0x3f, 0x13, 0x3e, 0xed, 0x05, 0xe3, 0x81, 0xf2, 0x2b, 0x46, 0x76,
+       0xe6, 0xaa, 0x91, 0x83, 0x5c, 0xcc, 0xb8, 0x3b, 0x20, 0xcf, 0xd4, 0x17,
+       0x1b, 0x6b, 0x27, 0xe3, 0xff, 0x62, 0xb6, 0x27, 0xa6, 0xa1, 0xdb, 0x07,
+       0xc0, 0x58, 0xef, 0x2c, 0x5b, 0xd5, 0xd9, 0xce, 0x9b, 0x61, 0x8d, 0x75,
+       0x2c, 0x27, 0xed, 0x7b, 0xe5, 0x35, 0xec, 0x77, 0x16, 0x7c, 0x9e, 0x95,
+       0x42, 0xb9, 0x24, 0xf9, 0x93, 0xdb, 0xec, 0x61, 0xc4, 0xb8, 0x8b, 0xb4,
+       0x13, 0xc3, 0x8a, 0xf4, 0xbd, 0x8d, 0xdd, 0xae, 0x14, 0x6b, 0xd2, 0xc4,
+       0xb2, 0x0e, 0xc8, 0x13, 0xea, 0x4a, 0x8b, 0x32, 0x79, 0xe7, 0xb2, 0xfd,
+       0x20, 0xbe, 0xed, 0x59, 0xba, 0xa7, 0x19, 0xb9, 0xfe, 0x9e, 0x76, 0x2f,
+       0xec, 0x89, 0xd8, 0x01, 0xcc, 0x77, 0x81, 0xf9, 0x2e, 0x30, 0xdf, 0x05,
+       0xe6, 0xbb, 0xc0, 0x7c, 0x17, 0xf6, 0xc0, 0x05, 0xee, 0xbb, 0xc0, 0x7d,
+       0x17, 0xb8, 0xef, 0x02, 0xf7, 0xdd, 0x2c, 0xce, 0x8e, 0xd8, 0x4e, 0xbb,
+       0x71, 0xdf, 0x82, 0xad, 0xf4, 0x7c, 0x9b, 0x9b, 0xb4, 0xbf, 0x00, 0x9d,
+       0xb4, 0x5b, 0x64, 0xb8, 0x6b, 0x33, 0xf6, 0x56, 0x87, 0x67, 0x3d, 0x9e,
+       0x58, 0xa3, 0xeb, 0x33, 0x5a, 0x77, 0xbe, 0x0a, 0xba, 0x4c, 0x94, 0x7f,
+       0x09, 0xb2, 0x59, 0x03, 0x7a, 0x7e, 0x41, 0xfb, 0x15, 0xa7, 0x2c, 0x4f,
+       0x36, 0xeb, 0x51, 0xf7, 0x69, 0xd4, 0xd5, 0xa3, 0xcf, 0x21, 0xf4, 0xa1,
+       0x5f, 0xd2, 0xa0, 0xeb, 0x82, 0xfd, 0xe8, 0x9f, 0xfc, 0x26, 0xd6, 0x4a,
+       0xa2, 0x5f, 0x03, 0xe6, 0x6e, 0x45, 0x9f, 0xcf, 0xa2, 0xcf, 0xcd, 0x28,
+       0xd3, 0x9f, 0xdd, 0x82, 0xf2, 0xa7, 0xaa, 0xc6, 0xdc, 0x8a, 0xba, 0xcf,
+       0x54, 0xd5, 0xcd, 0xa3, 0x0e, 0x71, 0xb0, 0x7d, 0x51, 0x8f, 0x2b, 0xa2,
+       0xdc, 0x5c, 0xd5, 0xe7, 0x12, 0xea, 0x7a, 0x51, 0xf7, 0x3d, 0x3c, 0x11,
+       0xff, 0xda, 0xa4, 0xc9, 0x6f, 0xa3, 0x6f, 0x9a, 0x40, 0x7d, 0x58, 0xfb,
+       0x97, 0x4f, 0xd2, 0xdf, 0x82, 0x9d, 0xfd, 0x53, 0xcb, 0xf3, 0xc7, 0x9e,
+       0xb1, 0x3d, 0x59, 0xf5, 0xcb, 0x3f, 0xaa, 0x2a, 0xb3, 0xef, 0xff, 0x56,
+       0xd5, 0xed, 0xda, 0xb8, 0xb4, 0xfc, 0x7e, 0x78, 0xf9, 0x98, 0xe3, 0x55,
+       0x7d, 0x5e, 0x6e, 0x5c, 0x5a, 0xfe, 0x7c, 0xcd, 0xf2, 0x31, 0xbf, 0xb5,
+       0x61, 0x69, 0xdd, 0xe1, 0xa6, 0xa5, 0x65, 0xfa, 0x7d, 0x31, 0xc4, 0x2d,
+       0x7e, 0xff, 0x07, 0x37, 0x79, 0xed, 0xe4, 0x6f, 0xb5, 0x2c, 0x29, 0xe3,
+       0x8d, 0xb2, 0x89, 0x73, 0xb8, 0x60, 0x40, 0xe7, 0x6c, 0x33, 0xfd, 0x8a,
+       0x91, 0x83, 0x4c, 0x65, 0xcb, 0xfe, 0x7c, 0xd4, 0xe5, 0xea, 0xdc, 0x80,
+       0x9f, 0x13, 0xa0, 0x8f, 0x15, 0x85, 0xdc, 0x00, 0x8b, 0x63, 0xc9, 0xa3,
+       0x45, 0x59, 0xd4, 0xe1, 0x36, 0xf3, 0x5a, 0x3a, 0x3c, 0xa9, 0x71, 0xeb,
+       0x32, 0xe8, 0xac, 0x48, 0x7f, 0xaa, 0x96, 0x76, 0x47, 0xe3, 0x19, 0xb1,
+       0xa8, 0x52, 0x09, 0x6d, 0xad, 0xc8, 0xc1, 0xd4, 0x3b, 0x15, 0x51, 0x38,
+       0xf8, 0x4d, 0xcd, 0x57, 0xe2, 0xa1, 0x0d, 0xb9, 0x8d, 0x29, 0x3f, 0x2e,
+       0x94, 0x3e, 0x45, 0x9f, 0xe4, 0x88, 0x87, 0xb3, 0xc4, 0x22, 0x94, 0xcb,
+       0x63, 0xe8, 0xc3, 0xf5, 0xf1, 0x9c, 0x21, 0xb6, 0x5b, 0xca, 0xce, 0xe4,
+       0x6d, 0xce, 0xbb, 0x12, 0x5e, 0xfe, 0xd8, 0xa2, 0x2f, 0x68, 0x39, 0x67,
+       0x60, 0xf3, 0xd8, 0x46, 0xff, 0xe0, 0x0c, 0x7d, 0x91, 0x80, 0x6f, 0xd3,
+       0x11, 0x12, 0x67, 0x11, 0x47, 0xbd, 0x7d, 0xb5, 0xd0, 0xd7, 0x5f, 0xc3,
+       0x5e, 0x57, 0xc6, 0xab, 0x76, 0xf3, 0xfa, 0xba, 0xbd, 0x77, 0x41, 0xb7,
+       0x7d, 0xd9, 0x5b, 0x29, 0x07, 0x70, 0x45, 0x9d, 0xc5, 0xf3, 0xe5, 0xe4,
+       0xb1, 0x22, 0x74, 0x69, 0x4e, 0xc5, 0xbb, 0xfe, 0xb9, 0xd0, 0xaf, 0x49,
+       0x9e, 0x9a, 0x82, 0x6c, 0x0f, 0xa9, 0x38, 0x80, 0x31, 0x40, 0x45, 0x76,
+       0xa7, 0x86, 0x62, 0xe4, 0x43, 0xc6, 0xbc, 0x1a, 0xa6, 0x1f, 0x31, 0xe7,
+       0x92, 0x67, 0x29, 0xb4, 0xa7, 0xc0, 0xdb, 0x7f, 0x95, 0x5c, 0x8c, 0x75,
+       0xff, 0x55, 0x99, 0x86, 0xff, 0xa3, 0x7c, 0x22, 0xe5, 0x03, 0xd0, 0xa7,
+       0x83, 0xad, 0x2f, 0x93, 0xa7, 0x17, 0xc0, 0x67, 0xdf, 0x2f, 0xb8, 0x4c,
+       0xbf, 0x54, 0x96, 0xfa, 0xcf, 0x22, 0x8f, 0x94, 0xfe, 0x19, 0x76, 0xc8,
+       0xc4, 0x7c, 0xb4, 0x77, 0xb4, 0x29, 0xac, 0xdf, 0x11, 0xa6, 0xff, 0xe6,
+       0xd9, 0xff, 0x10, 0xd6, 0x43, 0x4c, 0x5d, 0xfa, 0x0f, 0x23, 0xef, 0xb6,
+       0xd2, 0xb7, 0xc2, 0xfe, 0x89, 0xab, 0x6c, 0x63, 0x5d, 0x44, 0xfb, 0xdc,
+       0x51, 0xed, 0x63, 0xdb, 0xda, 0xc7, 0x26, 0x1d, 0x46, 0xc4, 0x4e, 0xfb,
+       0xbe, 0x02, 0xcf, 0x0c, 0x67, 0xb3, 0x55, 0xf9, 0x0a, 0xb2, 0xb2, 0xaf,
+       0xe0, 0xd3, 0x74, 0x16, 0xfb, 0xa4, 0x6f, 0xa7, 0x72, 0x3f, 0x8d, 0x5e,
+       0xbe, 0x89, 0x34, 0xf8, 0x36, 0x53, 0xd9, 0xe6, 0xa3, 0x30, 0x83, 0xd8,
+       0xdb, 0x6f, 0x83, 0xd6, 0x3d, 0x92, 0x1d, 0x3f, 0xab, 0x6d, 0x30, 0x63,
+       0x07, 0xfa, 0xed, 0x9e, 0xcc, 0x66, 0x53, 0x0d, 0x86, 0x9e, 0xa7, 0x19,
+       0x56, 0x33, 0x90, 0x97, 0xe2, 0x5a, 0xf4, 0x6d, 0x7c, 0x3f, 0x67, 0x56,
+       0xfb, 0x39, 0xe7, 0xe5, 0xa0, 0xeb, 0xc5, 0x0a, 0xfd, 0xa5, 0x0b, 0xa8,
+       0x53, 0xb4, 0xc7, 0xe9, 0x4f, 0x9a, 0x26, 0xfd, 0xc9, 0x24, 0x82, 0x0e,
+       0x6f, 0x2f, 0x6d, 0xd8, 0xcb, 0xcc, 0xc2, 0x5e, 0xea, 0x2f, 0x2c, 0xdd,
+       0x0b, 0xe9, 0xb7, 0xc1, 0x4f, 0x4b, 0xe3, 0x14, 0xe7, 0xfc, 0x46, 0x98,
+       0x18, 0xd6, 0x4f, 0x9f, 0xc8, 0xf5, 0x7c, 0xb1, 0xa5, 0xf3, 0xc2, 0x63,
+       0x28, 0x4d, 0x5d, 0xa3, 0x8d, 0xfb, 0xf7, 0xf5, 0xca, 0xd2, 0xd8, 0xce,
+       0x3d, 0xfc, 0x09, 0xe6, 0x8c, 0x19, 0x79, 0xe5, 0x9b, 0xd1, 0xcf, 0x41,
+       0xdc, 0x5d, 0x7a, 0x05, 0x4f, 0xea, 0x8e, 0x9a, 0x07, 0xfb, 0x8d, 0xaa,
+       0xfd, 0x8e, 0xb9, 0x97, 0xd4, 0x1e, 0xa7, 0x4b, 0x3f, 0x90, 0xc2, 0xc9,
+       0x1f, 0xc2, 0x26, 0x06, 0x73, 0x75, 0xcc, 0x73, 0x92, 0x57, 0xc5, 0x00,
+       0xb6, 0x92, 0x66, 0xe6, 0xe1, 0xbe, 0x17, 0xf6, 0xe2, 0x85, 0x71, 0x9c,
+       0xbf, 0xe1, 0xb5, 0xab, 0xf5, 0x7d, 0x9e, 0xd7, 0x04, 0xe8, 0xa9, 0xc0,
+       0x47, 0x8d, 0x83, 0x86, 0xe0, 0x98, 0xc7, 0xa4, 0xcf, 0xe5, 0x59, 0xb5,
+       0xc7, 0x87, 0xc4, 0xb1, 0xf3, 0xe2, 0xfb, 0x25, 0x5c, 0x9f, 0x78, 0x90,
+       0x43, 0x0c, 0xc5, 0xdc, 0xaa, 0xcf, 0x57, 0x9f, 0xa7, 0xd1, 0x0b, 0xd5,
+       0xf2, 0x31, 0x8a, 0xd8, 0xab, 0xe0, 0x92, 0x4f, 0xbe, 0xdc, 0xfa, 0x6b,
+       0x5f, 0x31, 0xb8, 0x9f, 0x11, 0x95, 0x4f, 0x7c, 0x6d, 0x41, 0x7e, 0x87,
+       0x81, 0x2b, 0x9e, 0x3c, 0xbe, 0xaa, 0x79, 0xe3, 0xcb, 0x6d, 0x54, 0xcb,
+       0x00, 0x63, 0x43, 0xea, 0x95, 0x2f, 0x23, 0x1d, 0xf6, 0xdd, 0x8a, 0x17,
+       0x6c, 0x53, 0x79, 0x46, 0x75, 0xce, 0x83, 0x0b, 0xe7, 0xbc, 0xbe, 0x4a,
+       0x66, 0x53, 0xb6, 0xa7, 0xa3, 0xd4, 0x45, 0xe8, 0x34, 0xf8, 0xf5, 0xfc,
+       0x12, 0xdd, 0xef, 0xba, 0x46, 0x8e, 0x36, 0x2a, 0xa1, 0xc9, 0x97, 0xc1,
+       0xcb, 0x5b, 0x11, 0xbb, 0x88, 0x58, 0x13, 0xc4, 0x28, 0xfa, 0x22, 0x8b,
+       0xfe, 0xf1, 0xb4, 0xac, 0xe4, 0x1b, 0x5f, 0xcf, 0x0f, 0xb9, 0x7d, 0x8d,
+       0x7e, 0xc8, 0xaf, 0xd6, 0x30, 0x96, 0x99, 0x83, 0x9e, 0x1e, 0xc0, 0xf8,
+       0x1a, 0xe7, 0x47, 0xb0, 0x6f, 0xa7, 0xad, 0x5a, 0xc7, 0xc7, 0x8b, 0xa8,
+       0x6c, 0x9c, 0xdc, 0xa2, 0x30, 0xc3, 0x9e, 0x58, 0xc4, 0x8c, 0x61, 0x97,
+       0xf2, 0xab, 0xf4, 0x34, 0xb6, 0x51, 0x7c, 0x8c, 0x78, 0xd6, 0x62, 0xbe,
+       0x67, 0x65, 0x1c, 0xf0, 0x72, 0xba, 0x2b, 0xc7, 0x0a, 0x37, 0x55, 0xf1,
+       0x72, 0x25, 0xdc, 0x3c, 0x07, 0xde, 0xa5, 0x11, 0x13, 0x27, 0xcf, 0x88,
+       0xec, 0x41, 0x9c, 0x9c, 0x7c, 0x4b, 0xa4, 0x0f, 0xb1, 0x72, 0x72, 0x56,
+       0x24, 0x83, 0x78, 0x99, 0xf1, 0xdb, 0x5d, 0xe0, 0x69, 0x2f, 0xe2, 0xe9,
+       0x1e, 0x60, 0x6a, 0x0a, 0x18, 0xbb, 0x1d, 0xfc, 0xed, 0x02, 0xbf, 0x6d,
+       0xc4, 0x5b, 0x65, 0x39, 0x70, 0x5c, 0x8c, 0x7d, 0x2a, 0x7f, 0x4d, 0x7d,
+       0x8f, 0xc1, 0xce, 0x56, 0x2a, 0x87, 0x52, 0xed, 0x88, 0xf5, 0x13, 0xf2,
+       0x39, 0x8b, 0xb1, 0xad, 0x61, 0xb5, 0x75, 0x7f, 0x3f, 0x14, 0xf4, 0x6b,
+       0xb3, 0xd7, 0xb5, 0x13, 0xcb, 0xf9, 0x9f, 0x53, 0xb6, 0xe2, 0xc5, 0xd0,
+       0x6a, 0xfc, 0xdf, 0xb7, 0xc0, 0xff, 0x9e, 0x3a, 0xa9, 0xbb, 0x4b, 0xe5,
+       0x16, 0xda, 0xba, 0x0f, 0x11, 0xcf, 0x52, 0xb0, 0xfb, 0xb0, 0xcf, 0x15,
+       0xb9, 0x33, 0x75, 0xb5, 0x72, 0xd1, 0xd9, 0x20, 0xf9, 0xed, 0x0f, 0x6a,
+       0x4c, 0x3f, 0xf5, 0x87, 0x59, 0xa7, 0x08, 0x1d, 0xf1, 0xf2, 0x88, 0x43,
+       0xe3, 0x11, 0x58, 0x0a, 0xfe, 0x35, 0xca, 0x74, 0xef, 0x55, 0x9c, 0xe3,
+       0xb6, 0x33, 0x4c, 0x42, 0x11, 0x6b, 0xa6, 0x63, 0x51, 0x95, 0x43, 0xde,
+       0xe4, 0xb0, 0xde, 0xc6, 0xb9, 0x0e, 0xc8, 0x34, 0xfc, 0x8b, 0x99, 0x5e,
+       0xd0, 0xb8, 0xbd, 0x19, 0xfd, 0xa9, 0x7b, 0xe4, 0xf9, 0x80, 0x0c, 0xc6,
+       0xc8, 0xd3, 0x18, 0xfa, 0xef, 0x45, 0x9f, 0x46, 0x3c, 0xff, 0x28, 0x34,
+       0x6d, 0x33, 0x9e, 0xfe, 0x3c, 0xca, 0x9c, 0x23, 0x68, 0x5b, 0x77, 0x85,
+       0x45, 0xcd, 0xc9, 0x31, 0xcd, 0x0a, 0x03, 0x16, 0xd7, 0xe2, 0x3a, 0x6c,
+       0x7b, 0xaf, 0x72, 0x47, 0x77, 0x6f, 0x60, 0xbd, 0x86, 0xc0, 0x7a, 0xbd,
+       0x81, 0xf5, 0x48, 0x67, 0x63, 0x80, 0xce, 0x46, 0x8c, 0xff, 0x5d, 0xac,
+       0x4d, 0x7e, 0x04, 0xd7, 0xcc, 0x07, 0xd6, 0xf4, 0xf7, 0xd7, 0x1c, 0x18,
+       0xf7, 0x0e, 0xd6, 0x63, 0x5d, 0x2c, 0x50, 0x47, 0x1a, 0x9a, 0x50, 0xc7,
+       0x72, 0x63, 0x80, 0xae, 0xa8, 0x8a, 0xf7, 0xa7, 0xd5, 0x19, 0x92, 0xcf,
+       0x75, 0xb0, 0x6b, 0x26, 0x6c, 0x4b, 0x0d, 0xfc, 0xaf, 0xea, 0xbd, 0x7e,
+       0x0d, 0xeb, 0xfa, 0xf3, 0xc5, 0x30, 0x07, 0xfb, 0xb3, 0x6f, 0x48, 0x8f,
+       0x67, 0x3d, 0xdb, 0xff, 0xb6, 0xf2, 0x8c, 0xe2, 0x5b, 0x1a, 0xb4, 0x93,
+       0xc6, 0x36, 0x99, 0x6a, 0xb4, 0x70, 0x9e, 0xa6, 0xb6, 0xa5, 0xc0, 0xda,
+       0xb2, 0x69, 0xb4, 0x77, 0xf3, 0xfc, 0x37, 0x68, 0x4c, 0xad, 0x33, 0xb2,
+       0xc7, 0x99, 0x4b, 0xa8, 0xd7, 0xb1, 0x22, 0xe2, 0x13, 0x65, 0x87, 0x7c,
+       0x3b, 0x41, 0x3b, 0x44, 0xdf, 0x86, 0x36, 0xf6, 0x9c, 0x7e, 0xc7, 0x13,
+       0x72, 0xfc, 0xd0, 0x4c, 0xa3, 0x5c, 0x54, 0x7c, 0xb5, 0x65, 0x7e, 0x81,
+       0xaf, 0x61, 0xfd, 0xbd, 0xe6, 0x31, 0xfd, 0x2d, 0x64, 0x3f, 0x7c, 0x27,
+       0xbc, 0x97, 0x32, 0xa0, 0x23, 0x21, 0xed, 0xdd, 0xcc, 0x61, 0x14, 0xf1,
+       0x74, 0xf0, 0x34, 0xf0, 0x84, 0xcd, 0x42, 0x0c, 0xd2, 0xde, 0xcd, 0x58,
+       0x50, 0x40, 0xdb, 0x15, 0x15, 0x07, 0xce, 0x94, 0x6d, 0xe3, 0x4e, 0xd7,
+       0xcb, 0x1d, 0xcd, 0x3b, 0xab, 0xe5, 0x8e, 0x1e, 0xa8, 0xc5, 0x79, 0x9c,
+       0xf2, 0x73, 0x47, 0xf3, 0xa2, 0x72, 0x47, 0xa7, 0xae, 0x93, 0x3b, 0xca,
+       0xac, 0x3d, 0x77, 0xc4, 0xf9, 0x2d, 0xb9, 0xbb, 0xc7, 0x36, 0xbf, 0xa8,
+       0x73, 0x47, 0x6f, 0x88, 0x97, 0x3b, 0xba, 0x28, 0x2b, 0xe7, 0x8e, 0x8e,
+       0x56, 0xe5, 0x8e, 0x9a, 0x54, 0xee, 0x88, 0xf3, 0x78, 0xb9, 0x23, 0x96,
+       0xf3, 0xdd, 0xbf, 0xac, 0x72, 0xe9, 0xf9, 0x6e, 0x60, 0xb0, 0xeb, 0x63,
+       0x9c, 0x6d, 0x0c, 0xa8, 0xf8, 0xf2, 0x4a, 0xb8, 0xd9, 0xf1, 0x31, 0x8e,
+       0xb6, 0x60, 0xf3, 0x82, 0x3d, 0xf3, 0xf1, 0x6e, 0x54, 0xd9, 0xbd, 0xe5,
+       0xf9, 0xc5, 0x7b, 0xaa, 0xf2, 0x8b, 0x03, 0x9e, 0xdd, 0x50, 0x38, 0x37,
+       0xa8, 0x71, 0x6e, 0x74, 0xc1, 0xcf, 0x39, 0x59, 0xcb, 0x18, 0x7c, 0xa4,
+       0x14, 0xc4, 0x51, 0x4b, 0x8d, 0xf5, 0xf2, 0x2c, 0x8b, 0x18, 0x7a, 0xb8,
+       0x0a, 0x43, 0x1f, 0x5b, 0xf1, 0xbb, 0x58, 0x3c, 0xb3, 0xfc, 0xbb, 0x98,
+       0x21, 0xcd, 0xf4, 0x39, 0xba, 0xf3, 0xd8, 0x03, 0x63, 0xe6, 0xfd, 0x92,
+       0x19, 0xb0, 0x81, 0x45, 0x7e, 0xfe, 0x85, 0xe7, 0xbc, 0x68, 0x63, 0xb2,
+       0xe6, 0xc7, 0x97, 0x83, 0x79, 0x48, 0xe5, 0x60, 0xbe, 0x5f, 0x1b, 0xcc,
+       0xc1, 0xcc, 0x03, 0xb3, 0x32, 0x16, 0xf3, 0x5b, 0x2b, 0xe7, 0x60, 0x1e,
+       0x5a, 0x21, 0x07, 0xf3, 0x5d, 0x59, 0xcc, 0xc1, 0x7c, 0x57, 0xfc, 0x1c,
+       0x0c, 0xe7, 0x08, 0x69, 0x9f, 0x56, 0x30, 0xee, 0x02, 0x7e, 0xe7, 0xf1,
+       0xf3, 0xf2, 0x32, 0xf3, 0x0b, 0x7b, 0x58, 0x29, 0x2f, 0xf3, 0x6f, 0xb5,
+       0x1f, 0x24, 0x2f, 0xe3, 0xd9, 0x04, 0x3f, 0x2f, 0x83, 0x9f, 0x0d, 0x1b,
+       0x64, 0x06, 0xf3, 0x32, 0xef, 0x53, 0x37, 0x50, 0xc7, 0x32, 0xeb, 0xa1,
+       0x23, 0xb0, 0x53, 0x19, 0xd8, 0x99, 0x69, 0xf7, 0xd7, 0xd5, 0x79, 0xcc,
+       0xb8, 0x53, 0xd8, 0x77, 0x02, 0xe7, 0x41, 0x5e, 0xb6, 0x2b, 0x5f, 0x34,
+       0x63, 0xc5, 0x8d, 0x6c, 0x27, 0xac, 0xda, 0x38, 0xbf, 0x9d, 0x5b, 0xc6,
+       0x50, 0x99, 0xf2, 0x1e, 0x31, 0x0a, 0xd8, 0x4b, 0xdf, 0xf8, 0x94, 0x0c,
+       0x95, 0x7d, 0x3f, 0xab, 0x5b, 0x9f, 0xc5, 0x94, 0xd2, 0xd3, 0x69, 0xf0,
+       0x00, 0x98, 0xb1, 0x06, 0x9b, 0x75, 0x16, 0x34, 0x07, 0xf7, 0x81, 0x18,
+       0xba, 0x07, 0x75, 0xea, 0xdc, 0xe9, 0x6f, 0xfa, 0xb4, 0x24, 0xa8, 0xf3,
+       0x6b, 0x98, 0x8f, 0x75, 0x67, 0x55, 0xfc, 0x56, 0xe8, 0xe1, 0x5e, 0x69,
+       0xfb, 0xe6, 0x40, 0x1f, 0xea, 0x66, 0x18, 0x33, 0xd2, 0x0e, 0xfa, 0x31,
+       0x5d, 0x54, 0xc5, 0x74, 0x9b, 0x15, 0x3f, 0xc8, 0xeb, 0x5f, 0x8b, 0x10,
+       0x3b, 0x37, 0x3b, 0xdc, 0xc3, 0x79, 0x8d, 0x7b, 0x2c, 0xfb, 0xb1, 0x23,
+       0xdf, 0xc9, 0xa7, 0xa7, 0x54, 0xde, 0x67, 0xda, 0xf5, 0xcf, 0xf0, 0x5b,
+       0xd8, 0x3b, 0xcb, 0xbd, 0x72, 0xa1, 0x59, 0x22, 0xb1, 0x34, 0x73, 0xbd,
+       0xf4, 0xd5, 0x77, 0x30, 0xf7, 0x50, 0xd3, 0xb4, 0x8a, 0xfe, 0xee, 0x5b,
+       0x45, 0x7f, 0xef, 0xae, 0xd2, 0xdf, 0xfe, 0x55, 0xf5, 0xf7, 0xeb, 0x91,
+       0xa0, 0xfe, 0xee, 0x5b, 0x45, 0x7f, 0x1f, 0xad, 0xd2, 0xdf, 0x83, 0x37,
+       0xa4, 0xbf, 0x3a, 0x36, 0x4e, 0xdd, 0xaa, 0x72, 0xc6, 0xc3, 0x13, 0xc4,
+       0xac, 0x4f, 0xeb, 0xdc, 0xd5, 0x4a, 0xbe, 0x98, 0x4f, 0x43, 0x5b, 0xcd,
+       0x47, 0xe3, 0x87, 0xfd, 0x23, 0xf6, 0xe9, 0xf9, 0xa3, 0xfd, 0xf0, 0x69,
+       0xaf, 0xbd, 0xee, 0x1f, 0x8b, 0x99, 0xf6, 0x7d, 0xc0, 0xad, 0x1f, 0xd1,
+       0xda, 0x6b, 0x91, 0x3f, 0xc6, 0x56, 0xf4, 0x07, 0xa2, 0xda, 0x66, 0x4e,
+       0x6a, 0x1d, 0xf4, 0xf3, 0x12, 0x41, 0x7d, 0xa6, 0x9c, 0x52, 0x36, 0x7f,
+       0x8a, 0x3d, 0x51, 0x3e, 0x7d, 0x0c, 0xd8, 0x52, 0xa5, 0x13, 0x73, 0x52,
+       0x00, 0x6e, 0x79, 0x3a, 0x41, 0x39, 0xeb, 0xc4, 0xbe, 0x61, 0x2b, 0xdd,
+       0xa7, 0xbd, 0xb3, 0x70, 0xf0, 0x9c, 0xf1, 0x75, 0x3f, 0x81, 0x75, 0xfd,
+       0x36, 0xda, 0x1e, 0x07, 0x3e, 0xd9, 0x36, 0xf8, 0x93, 0x2d, 0xc0, 0x19,
+       0xd6, 0x2f, 0xcd, 0x73, 0xaf, 0x8e, 0xb1, 0x52, 0x0c, 0xa3, 0xef, 0xe9,
+       0x1e, 0x60, 0x4e, 0x0f, 0x71, 0xb3, 0x84, 0xd8, 0x8c, 0x7a, 0x41, 0x5d,
+       0xe9, 0xe8, 0xda, 0x6d, 0xd2, 0xe7, 0x7b, 0x12, 0x71, 0xfc, 0x2d, 0x4a,
+       0xaf, 0x76, 0x97, 0x3b, 0x66, 0xdf, 0x30, 0xb9, 0x46, 0xa5, 0x92, 0x57,
+       0xdf, 0x19, 0xc4, 0x6c, 0xeb, 0xde, 0xb2, 0x8e, 0x36, 0xf3, 0x16, 0x27,
+       0xa4, 0xe5, 0x3e, 0x83, 0x77, 0xea, 0xd1, 0xeb, 0xf0, 0x47, 0x78, 0x47,
+       0xe1, 0x27, 0x2a, 0x5f, 0x37, 0xed, 0xd2, 0xf7, 0x60, 0xcc, 0xb4, 0x53,
+       0xf7, 0xdb, 0xa2, 0xbe, 0xb1, 0x66, 0x53, 0x3b, 0xf4, 0xf7, 0x36, 0xda,
+       0xc4, 0x24, 0x31, 0x75, 0xc9, 0x79, 0xf3, 0x8e, 0x47, 0x4e, 0xc5, 0x5c,
+       0x1c, 0xaf, 0x7c, 0x7f, 0xc4, 0x49, 0x56, 0xe0, 0xfb, 0x40, 0x44, 0xc7,
+       0x97, 0xd4, 0xf9, 0xa8, 0x8a, 0x7d, 0xbd, 0x78, 0x8a, 0xf1, 0xf7, 0xd2,
+       0xbb, 0x1d, 0x2b, 0xcb, 0x40, 0xcb, 0x07, 0x90, 0x81, 0xea, 0xf3, 0x8b,
+       0x00, 0x8b, 0xfc, 0xf3, 0xf3, 0x7d, 0xac, 0xbf, 0xd0, 0xfb, 0xde, 0xa2,
+       0xf5, 0xe9, 0xff, 0xc3, 0x3e, 0x8d, 0xc0, 0x3e, 0x7d, 0x6c, 0xfc, 0xa2,
+       0xde, 0xe7, 0xce, 0x2a, 0x6c, 0xec, 0x41, 0xfd, 0xe1, 0x9a, 0x8d, 0x1f,
+       0x10, 0x1b, 0xf7, 0xde, 0x10, 0x36, 0xfe, 0x70, 0xdd, 0x5a, 0xb1, 0xf1,
+       0xd0, 0x07, 0xc6, 0x46, 0xee, 0x6b, 0x65, 0x3c, 0xda, 0xb7, 0x0c, 0x8f,
+       0xfe, 0xe0, 0x13, 0xc4, 0xa3, 0xd5, 0xb0, 0x84, 0xe7, 0xd2, 0xa0, 0x7c,
+       0x6c, 0x4f, 0xff, 0xe0, 0x5f, 0xcc, 0x84, 0xe5, 0xc2, 0xbd, 0x11, 0x79,
+       0x6d, 0x27, 0xfc, 0x6e, 0xf2, 0x48, 0x9d, 0x07, 0xcb, 0xd1, 0x3a, 0xcf,
+       0x36, 0xc6, 0x1b, 0xbd, 0x9c, 0x02, 0xc7, 0xf8, 0x3a, 0x6d, 0xa3, 0x9d,
+       0x6d, 0x5b, 0xe4, 0xf5, 0xc6, 0x1b, 0x89, 0x53, 0xf9, 0x8d, 0x66, 0xa5,
+       0x38, 0x75, 0xf5, 0x9c, 0xe6, 0x62, 0x9c, 0x4a, 0xac, 0x6d, 0xd4, 0x79,
+       0x2c, 0xc6, 0x67, 0xfb, 0x35, 0x7e, 0xf2, 0x1d, 0xf1, 0xb8, 0x8b, 0x58,
+       0xdc, 0x45, 0x1c, 0xee, 0x22, 0x46, 0x87, 0x6d, 0x7e, 0x01, 0x32, 0xf7,
+       0x6d, 0x17, 0x31, 0xb8, 0x8b, 0x18, 0xdc, 0xed, 0xd2, 0x71, 0x7c, 0xbf,
+       0xfe, 0x76, 0xc1, 0xef, 0xfb, 0xcc, 0x83, 0x14, 0x61, 0x57, 0x46, 0x79,
+       0x3f, 0xc3, 0xcc, 0xa6, 0xd6, 0xe9, 0xfd, 0xf9, 0x79, 0xfd, 0x56, 0x9d,
+       0x5b, 0xda, 0xb4, 0x49, 0xf9, 0x0b, 0xe6, 0x2b, 0x75, 0xde, 0x1d, 0x00,
+       0xde, 0x23, 0x79, 0x14, 0xbe, 0x92, 0xba, 0x87, 0x45, 0x3d, 0xad, 0x98,
+       0x69, 0xe6, 0x8e, 0xc4, 0x34, 0xd3, 0x77, 0x60, 0xcc, 0x36, 0x2f, 0x66,
+       0x89, 0x49, 0xc8, 0x4c, 0xd7, 0x93, 0xa7, 0x86, 0x99, 0x5e, 0xaf, 0xe7,
+       0x9a, 0xaf, 0xf3, 0xfc, 0xbd, 0x4e, 0x96, 0x2d, 0x33, 0xfd, 0x59, 0x3e,
+       0x71, 0xee, 0x7e, 0xfd, 0x3d, 0x8d, 0x4b, 0xd7, 0x1a, 0x53, 0x18, 0x9f,
+       0x4d, 0xdd, 0x8b, 0xf9, 0xd4, 0xfd, 0xa7, 0x05, 0x7e, 0x9b, 0xd7, 0xe4,
+       0xf7, 0x98, 0xe6, 0xb7, 0xc7, 0xe3, 0x10, 0xfb, 0xa9, 0xdc, 0x36, 0x79,
+       0xed, 0xcf, 0xa7, 0x72, 0x93, 0x58, 0x47, 0xdd, 0x01, 0xc1, 0xb3, 0x62,
+       0x49, 0xc3, 0xc0, 0x7d, 0x61, 0x27, 0xb8, 0xae, 0xff, 0x2d, 0x7f, 0x2d,
+       0x6b, 0x6e, 0x51, 0xdf, 0x07, 0x3d, 0xbb, 0x31, 0xa6, 0x64, 0xd0, 0x4a,
+       0x73, 0x5f, 0xef, 0x43, 0xfe, 0xc6, 0x94, 0xfc, 0xe5, 0x10, 0x67, 0x8d,
+       0xf6, 0x74, 0x24, 0x2c, 0x73, 0xba, 0x8e, 0x39, 0xe4, 0xbe, 0xb2, 0x8f,
+       0x7d, 0x5c, 0xaf, 0xda, 0xa6, 0x33, 0xff, 0xe7, 0x63, 0x9a, 0xb4, 0x78,
+       0x79, 0xc1, 0xb5, 0xde, 0xa9, 0x58, 0xd4, 0xa5, 0xc1, 0x05, 0x5d, 0xaa,
+       0xab, 0xd2, 0x25, 0x7f, 0x9f, 0xeb, 0xc5, 0xff, 0xe6, 0xbe, 0xd2, 0x5d,
+       0x90, 0xb9, 0x72, 0xe0, 0x1b, 0xcf, 0x82, 0x6c, 0xf0, 0x4e, 0xcc, 0x3d,
+       0x90, 0x41, 0x7e, 0xdf, 0xd8, 0x03, 0x3d, 0xaa, 0x54, 0xfa, 0x98, 0x27,
+       0xdf, 0xde, 0xaf, 0xef, 0x5b, 0x5c, 0x51, 0x39, 0x12, 0x6b, 0x59, 0x8e,
+       0xa4, 0x0f, 0xb2, 0x02, 0x3f, 0x00, 0x3a, 0x98, 0x57, 0x67, 0x49, 0x9f,
+       0xa0, 0xfa, 0x1b, 0xd2, 0xc5, 0x7a, 0x8f, 0x0f, 0x9d, 0xf5, 0xde, 0x77,
+       0x14, 0x73, 0xd3, 0xd2, 0x32, 0xc7, 0x27, 0xea, 0x3d, 0x59, 0x39, 0x06,
+       0xfb, 0xdc, 0x07, 0x59, 0xac, 0x91, 0x9c, 0x9a, 0xef, 0x98, 0xe4, 0x9f,
+       0xfd, 0xcf, 0xc6, 0xa5, 0xfd, 0x51, 0x77, 0xd2, 0xef, 0xff, 0x78, 0x55,
+       0xff, 0xc7, 0xd1, 0xff, 0x67, 0x55, 0xfd, 0x1f, 0x0f, 0xf4, 0x3f, 0xa1,
+       0xfb, 0xd7, 0xa2, 0xbf, 0xd2, 0x83, 0x26, 0xdf, 0x2f, 0x36, 0x1d, 0xc4,
+       0xb3, 0xcf, 0xfa, 0x63, 0x4e, 0x04, 0xc6, 0x4c, 0x56, 0xad, 0x31, 0x89,
+       0x7e, 0xf1, 0xa6, 0xa5, 0x6b, 0xa0, 0xee, 0x64, 0x8d, 0xfe, 0xbe, 0x47,
+       0x9f, 0xe5, 0xa0, 0xce, 0x17, 0xe0, 0x59, 0x0a, 0x7e, 0x33, 0xe2, 0x77,
+       0x0a, 0xca, 0x9e, 0xff, 0x8d, 0xc2, 0xbf, 0x93, 0x47, 0xbd, 0xcd, 0x40,
+       0x6f, 0x17, 0xfd, 0x1a, 0x4f, 0x2e, 0x83, 0x32, 0x49, 0x9c, 0x28, 0x4a,
+       0xc8, 0x29, 0xd3, 0x57, 0x32, 0x0a, 0x33, 0xbe, 0x7d, 0xe2, 0xbd, 0x2b,
+       0xde, 0xd7, 0xf5, 0xec, 0x70, 0xd8, 0x99, 0xd3, 0x31, 0xe2, 0xaf, 0x90,
+       0x7e, 0xe0, 0xa6, 0x8f, 0x9d, 0x72, 0xcc, 0xd3, 0x1f, 0xca, 0x31, 0xe7,
+       0xd7, 0x7a, 0x44, 0x99, 0xd5, 0xeb, 0xf4, 0x2d, 0xc3, 0xb7, 0xc4, 0xb2,
+       0x3c, 0x5c, 0x68, 0x0d, 0xf8, 0xd6, 0xbf, 0x80, 0x6f, 0xf7, 0xca, 0x94,
+       0x9d, 0x50, 0x79, 0xd0, 0x43, 0x0b, 0x79, 0x81, 0xc3, 0x91, 0x46, 0x87,
+       0x79, 0x81, 0xe4, 0xa9, 0x8c, 0x7c, 0xb0, 0xbc, 0xc0, 0xbe, 0x2a, 0x1d,
+       0xd9, 0xbb, 0xaa, 0xed, 0xfc, 0xb3, 0xfa, 0xb5, 0xe6, 0x05, 0x1e, 0xa9,
+       0xb2, 0x63, 0x87, 0x6e, 0xc0, 0x76, 0xe6, 0x95, 0xed, 0xe4, 0x5e, 0xaf,
+       0xe7, 0xcb, 0x7f, 0x25, 0xf2, 0xd1, 0xd8, 0xce, 0xd5, 0x72, 0xe2, 0x41,
+       0x7b, 0x40, 0xb9, 0xba, 0xac, 0xfd, 0x6c, 0x3c, 0x67, 0x2e, 0x43, 0x3f,
+       0x4d, 0x19, 0x54, 0xb2, 0xcc, 0xb2, 0x1f, 0xff, 0xde, 0xb7, 0x10, 0xff,
+       0x2e, 0xc6, 0xac, 0xf0, 0x67, 0xbb, 0xfc, 0xd8, 0x88, 0x7e, 0xb3, 0x6d,
+       0x14, 0xdc, 0x3d, 0xe6, 0x90, 0x6a, 0x63, 0x8e, 0xf7, 0x36, 0xf9, 0x9c,
+       0xba, 0x27, 0x70, 0x5e, 0xe7, 0xd2, 0xa6, 0x54, 0x4c, 0xc0, 0xef, 0x1c,
+       0x85, 0xd4, 0x46, 0xed, 0x03, 0x5e, 0x0f, 0x67, 0x97, 0xc6, 0xcf, 0xa6,
+       0x79, 0x04, 0x63, 0x19, 0x3f, 0x7f, 0x21, 0x4a, 0x4c, 0xcd, 0x96, 0x57,
+       0x1d, 0x8f, 0x71, 0x1c, 0xcf, 0x3e, 0x2a, 0x56, 0x46, 0xbf, 0x39, 0x3d,
+       0xde, 0x8b, 0x95, 0xb3, 0xe5, 0xad, 0x51, 0x0f, 0x17, 0x57, 0x8b, 0x63,
+       0x8e, 0x44, 0x99, 0x8b, 0x9c, 0x73, 0xaf, 0x47, 0xeb, 0xf2, 0xd8, 0x3c,
+       0xb4, 0x2c, 0x36, 0xb7, 0x74, 0xec, 0x7d, 0xbf, 0x8a, 0xcd, 0x3d, 0x1e,
+       0x73, 0x2f, 0xc1, 0xd8, 0xca, 0x01, 0x36, 0xf2, 0x5b, 0x10, 0xb1, 0x82,
+       0x3e, 0x0b, 0xe4, 0x67, 0xfc, 0x37, 0x94, 0x1f, 0xb3, 0x5c, 0x7e, 0x3e,
+       0x6e, 0xbb, 0xe1, 0xef, 0xfd, 0xb2, 0x78, 0xf9, 0xc5, 0x3d, 0xa0, 0x85,
+       0xf1, 0x56, 0x58, 0xcb, 0xc3, 0xcf, 0x69, 0xfc, 0xf6, 0xfb, 0xf9, 0xb9,
+       0x86, 0x85, 0x6f, 0xc9, 0xc5, 0xcc, 0x92, 0x1c, 0xcf, 0x16, 0xa6, 0xce,
+       0x71, 0xee, 0x99, 0x1b, 0xf8, 0xde, 0xf2, 0x61, 0xee, 0x7c, 0x54, 0xdb,
+       0xb9, 0x57, 0x21, 0xfb, 0x09, 0x7d, 0xff, 0xaf, 0x0b, 0x3a, 0xc0, 0x3b,
+       0xd0, 0xd5, 0x58, 0xab, 0xee, 0xf9, 0x45, 0x36, 0xa5, 0xf9, 0xed, 0x82,
+       0x3e, 0xc1, 0x4f, 0xf4, 0x5e, 0xe3, 0x72, 0x6c, 0xc2, 0xcb, 0xd3, 0x9a,
+       0xab, 0xde, 0xf1, 0xbb, 0x04, 0x5e, 0x24, 0x8f, 0xfa, 0x79, 0x5a, 0xd3,
+       0xbb, 0xe3, 0x77, 0xf4, 0xa3, 0xbb, 0xe3, 0xc7, 0xf9, 0x2d, 0xd9, 0xbb,
+       0xc2, 0x1d, 0xbf, 0xd0, 0x1a, 0xef, 0xf8, 0x6d, 0x54, 0x79, 0x5a, 0xce,
+       0xe3, 0xe5, 0x69, 0x59, 0x6e, 0xeb, 0xfe, 0x94, 0xc2, 0xa8, 0xe9, 0x09,
+       0xe6, 0x75, 0x1e, 0x5c, 0xf7, 0xc9, 0xe4, 0x75, 0xde, 0x8b, 0x7e, 0xfc,
+       0x79, 0x1d, 0x7e, 0x17, 0xf8, 0xb2, 0xf7, 0xdd, 0x5a, 0x6e, 0x24, 0x3f,
+       0xf0, 0xe1, 0x72, 0xb0, 0x07, 0x55, 0x0e, 0x76, 0xfb, 0xfa, 0x60, 0x0e,
+       0xd6, 0xbc, 0xce, 0x3d, 0xb8, 0x83, 0x2b, 0xe4, 0x60, 0xc3, 0x81, 0x7b,
+       0x70, 0x61, 0x7d, 0x0f, 0x6e, 0xa3, 0x83, 0x18, 0x53, 0xe7, 0x5b, 0xcd,
+       0x55, 0xef, 0xc1, 0xed, 0x5e, 0xff, 0xe1, 0xf3, 0xad, 0xcb, 0xee, 0xc1,
+       0x1d, 0xcd, 0x48, 0x8b, 0x24, 0x6e, 0x28, 0x16, 0xfa, 0x30, 0x71, 0x10,
+       0xff, 0x8f, 0x40, 0x0d, 0xf6, 0x0c, 0x99, 0x8f, 0x51, 0x3e, 0x29, 0x77,
+       0x69, 0x33, 0x5f, 0xe6, 0x7b, 0x17, 0xcf, 0xc7, 0xe8, 0xef, 0x5c, 0x7a,
+       0xb7, 0x62, 0xf1, 0x6e, 0x72, 0x64, 0xe1, 0x6e, 0xf2, 0x18, 0x64, 0xc6,
+       0x9c, 0x88, 0xc8, 0x74, 0xc0, 0xb6, 0x8e, 0xba, 0xf0, 0x9b, 0x26, 0x6d,
+       0xdd, 0xce, 0xff, 0xa7, 0x82, 0xb8, 0xb0, 0xc4, 0xfb, 0xcc, 0x0d, 0x12,
+       0x9a, 0x54, 0x98, 0x1a, 0xf3, 0xfe, 0xaf, 0x4e, 0x1c, 0x7d, 0x78, 0x77,
+       0x35, 0x2c, 0x87, 0x62, 0x94, 0x65, 0x5f, 0x8e, 0xbf, 0x05, 0xfe, 0x36,
+       0x65, 0x16, 0xcb, 0x31, 0x2d, 0xd7, 0x94, 0x69, 0x5f, 0xfe, 0x62, 0x32,
+       0x32, 0x41, 0x59, 0xde, 0xa1, 0xff, 0x9f, 0xc4, 0x39, 0x29, 0x94, 0xcf,
+       0xea, 0x78, 0x43, 0x7d, 0x8b, 0x02, 0x1f, 0x5b, 0xb4, 0x0d, 0xc6, 0x73,
+       0xa6, 0x85, 0x36, 0x8f, 0xdf, 0x1e, 0xa5, 0x6f, 0x7c, 0x5b, 0x7c, 0x08,
+       0x78, 0x37, 0xa8, 0x72, 0x27, 0x37, 0xc2, 0x6f, 0xe3, 0x1a, 0xdf, 0x48,
+       0xd7, 0xca, 0x73, 0xdf, 0x5f, 0xbe, 0x8c, 0xfd, 0xb5, 0x40, 0x36, 0xbe,
+       0x2a, 0xb9, 0x93, 0xb7, 0x49, 0xdf, 0x89, 0x24, 0xe8, 0x79, 0xbf, 0x52,
+       0x48, 0xc1, 0xb7, 0x7e, 0x96, 0x77, 0xe1, 0x80, 0xa1, 0x2e, 0x30, 0x14,
+       0xbc, 0x7b, 0x61, 0x99, 0xbf, 0x11, 0xbc, 0x43, 0x97, 0x5a, 0xb8, 0x13,
+       0xf5, 0x7c, 0x59, 0x22, 0x8d, 0xa4, 0x7b, 0x62, 0xf1, 0x2e, 0xfc, 0x5c,
+       0x39, 0xa7, 0xec, 0xdb, 0x73, 0xe5, 0x25, 0x39, 0x21, 0x75, 0x8e, 0xc3,
+       0xa5, 0x97, 0x61, 0xe3, 0x2e, 0x1b, 0xb4, 0x71, 0x63, 0xae, 0xdc, 0x12,
+       0x12, 0x9e, 0x89, 0x18, 0xe0, 0x83, 0xba, 0x9b, 0xe2, 0xdd, 0x4d, 0x68,
+       0x55, 0x67, 0xfb, 0x7f, 0xd4, 0x5d, 0x7d, 0x6c, 0x5b, 0xd7, 0x75, 0x3f,
+       0x7c, 0xa4, 0x3e, 0x4c, 0xcb, 0xd2, 0x93, 0x4c, 0xc9, 0xb4, 0x2d, 0xcb,
+       0x8f, 0xd2, 0x93, 0xa5, 0xc4, 0x4a, 0xc1, 0x79, 0xda, 0xaa, 0x01, 0x5a,
+       0xc7, 0x52, 0xf4, 0xc7, 0x82, 0x60, 0xa5, 0x65, 0x25, 0xf3, 0xd2, 0x2c,
+       0x51, 0x29, 0xdb, 0xc9, 0xfe, 0x18, 0xe0, 0x25, 0xd9, 0x9a, 0xfd, 0x51,
+       0xe4, 0x95, 0x94, 0x12, 0x63, 0x56, 0x4d, 0xc6, 0xe6, 0x84, 0x02, 0x0b,
+       0x36, 0x56, 0x92, 0x9d, 0x14, 0x50, 0xc0, 0x24, 0x6d, 0x87, 0x2c, 0x6d,
+       0x11, 0x55, 0x76, 0xda, 0x7f, 0x8d, 0x2d, 0xc0, 0xb2, 0x2e, 0x69, 0x14,
+       0x3b, 0xc8, 0x02, 0x2c, 0x58, 0xbb, 0x6e, 0x28, 0xf6, 0x4f, 0xc7, 0x9d,
+       0xdf, 0xfd, 0x20, 0x1f, 0xc9, 0x47, 0x7d, 0x24, 0x6e, 0x81, 0x09, 0x10,
+       0xc8, 0xf7, 0xde, 0x7d, 0xef, 0xdd, 0x7b, 0xee, 0xf9, 0xf8, 0x9d, 0x73,
+       0xcf, 0xb9, 0x94, 0xba, 0xe2, 0x35, 0x57, 0x6e, 0x49, 0x65, 0x7e, 0x65,
+       0xce, 0x89, 0x9c, 0x0f, 0x95, 0x43, 0x0b, 0x9a, 0x3a, 0x27, 0x6d, 0x99,
+       0x17, 0x33, 0xb0, 0x80, 0x73, 0x3d, 0x35, 0xf6, 0xaf, 0x95, 0xf9, 0xc0,
+       0x14, 0x31, 0x85, 0x69, 0x13, 0x7d, 0xde, 0x2b, 0xf4, 0x81, 0xf7, 0xba,
+       0x7c, 0x40, 0xe9, 0xbc, 0x56, 0xa5, 0xa3, 0x36, 0xc2, 0x6f, 0xf2, 0x9d,
+       0xfd, 0xe2, 0x9d, 0xdd, 0x4a, 0x67, 0xe9, 0xdc, 0xf7, 0x71, 0x63, 0xba,
+       0x08, 0x5f, 0x9b, 0xe9, 0x52, 0x87, 0xdf, 0xac, 0x4d, 0xe8, 0xf8, 0xb9,
+       0x3a, 0x3a, 0x56, 0xcb, 0x03, 0xfb, 0xe6, 0x65, 0x9d, 0x2d, 0x69, 0x26,
+       0xcf, 0x23, 0x9f, 0x5f, 0xe7, 0x65, 0x48, 0x9a, 0x95, 0xe5, 0xe7, 0x92,
+       0x3b, 0x27, 0xa3, 0x42, 0xb3, 0xe9, 0x32, 0xcd, 0xf6, 0xfc, 0x3f, 0xa0,
+       0xd9, 0x4d, 0x81, 0x79, 0x5f, 0x29, 0x22, 0xff, 0x6e, 0x58, 0xe4, 0x2e,
+       0xac, 0xd2, 0x88, 0xb2, 0xff, 0xee, 0x1a, 0x28, 0xd0, 0x12, 0xba, 0x34,
+       0x52, 0x58, 0xa7, 0x98, 0x8c, 0x43, 0x98, 0xa5, 0xd2, 0x77, 0xa2, 0x90,
+       0x3f, 0xf8, 0x24, 0xf0, 0x51, 0x10, 0xdf, 0x3b, 0xc9, 0x63, 0xfb, 0x97,
+       0x60, 0xd7, 0x06, 0x36, 0xf2, 0xe4, 0x36, 0x7c, 0x94, 0x8a, 0x8d, 0x04,
+       0x5e, 0x22, 0x27, 0x6e, 0x57, 0xf2, 0x5e, 0x66, 0xb3, 0x3f, 0x6c, 0x67,
+       0x3f, 0x92, 0x69, 0x5c, 0x79, 0xee, 0xd6, 0x7c, 0x14, 0x3c, 0x4f, 0xda,
+       0xc9, 0xd9, 0x6c, 0xe5, 0xb9, 0x4e, 0xf9, 0xb9, 0x61, 0x0f, 0x5d, 0x65,
+       0xd1, 0xcc, 0xa5, 0x7d, 0x75, 0xf9, 0x6a, 0x95, 0xf1, 0x48, 0x5f, 0x45,
+       0x8f, 0xe7, 0xc9, 0x4d, 0xf1, 0xa5, 0xcc, 0x3b, 0xab, 0xe4, 0xf0, 0xd4,
+       0xfa, 0x29, 0xfb, 0x5d, 0xf1, 0x19, 0xd0, 0xf8, 0x0f, 0x69, 0x75, 0x12,
+       0x7a, 0xae, 0x96, 0xd6, 0xef, 0xff, 0x9a, 0x68, 0x1d, 0xe9, 0xf8, 0xf5,
+       0xd2, 0x7a, 0x7f, 0x5d, 0x2c, 0xbc, 0x32, 0x1e, 0x0a, 0x75, 0x6f, 0x0b,
+       0xcb, 0xd7, 0xd2, 0x7a, 0x7f, 0xc3, 0x78, 0x6a, 0xe3, 0x5c, 0xcc, 0xea,
+       0x78, 0x6a, 0xbf, 0xc1, 0x32, 0x92, 0x65, 0x79, 0x69, 0xa8, 0xe3, 0xff,
+       0xce, 0x15, 0x6f, 0x75, 0xeb, 0x79, 0xc8, 0x1a, 0xf9, 0x4e, 0x0e, 0xe9,
+       0x77, 0x42, 0xae, 0x22, 0x8e, 0x43, 0xf0, 0x9f, 0xf0, 0x5e, 0xe4, 0x62,
+       0xd5, 0xe1, 0x2e, 0x7e, 0x2f, 0xcb, 0xff, 0x0b, 0xcf, 0x0b, 0x9b, 0x25,
+       0x63, 0x12, 0x68, 0x1f, 0xf2, 0x9d, 0x11, 0x6d, 0x65, 0x8e, 0x96, 0x8a,
+       0x51, 0x28, 0x3f, 0xa0, 0x51, 0x6c, 0xa2, 0xde, 0xfe, 0x6d, 0xcf, 0x6f,
+       0xd0, 0xf1, 0x88, 0x83, 0x3c, 0x3f, 0xe1, 0x2a, 0xbf, 0x0b, 0xfa, 0xf4,
+       0x3c, 0x63, 0x84, 0xfe, 0x32, 0x3e, 0xa8, 0x9e, 0xa3, 0x59, 0xe1, 0xdf,
+       0x69, 0x5d, 0xba, 0x2a, 0x73, 0x6b, 0xc5, 0x79, 0xe0, 0xb5, 0xb2, 0x2e,
+       0xad, 0xc1, 0xc3, 0x07, 0x3d, 0xf8, 0xc3, 0xb3, 0x9e, 0x55, 0xcf, 0xa1,
+       0x85, 0x9c, 0xfa, 0x84, 0xe7, 0x1c, 0x96, 0xeb, 0xd2, 0x9c, 0x4a, 0x5b,
+       0x79, 0x7f, 0x42, 0x8c, 0x6b, 0xea, 0xde, 0x38, 0xea, 0xef, 0xca, 0x35,
+       0x51, 0xb5, 0x75, 0x60, 0xb0, 0x0b, 0x5a, 0x1e, 0x75, 0xcd, 0x39, 0x68,
+       0xd1, 0xe7, 0x51, 0x07, 0xe6, 0xb6, 0x2d, 0xb8, 0xaf, 0x96, 0x16, 0x15,
+       0xbb, 0x32, 0xa7, 0xec, 0xca, 0xa2, 0x4b, 0xaf, 0xd7, 0xe3, 0xf7, 0x2e,
+       0x0f, 0xfc, 0xee, 0x55, 0x0b, 0x86, 0x3e, 0x3d, 0xc5, 0x98, 0xe4, 0x33,
+       0xc0, 0x24, 0x26, 0x6a, 0xb1, 0x24, 0x2e, 0xc1, 0xf5, 0x1c, 0x63, 0x93,
+       0x30, 0xf3, 0xca, 0x6b, 0x74, 0x8e, 0x31, 0xf7, 0x35, 0xba, 0x4b, 0xf9,
+       0x69, 0x90, 0x5f, 0x9d, 0x47, 0x8b, 0x5a, 0x06, 0x1f, 0x39, 0x0f, 0x45,
+       0x86, 0x63, 0xf4, 0x1a, 0x9d, 0x15, 0xf9, 0x3e, 0x58, 0xff, 0x43, 0x9e,
+       0xc4, 0xdd, 0xe2, 0xfd, 0x32, 0xae, 0x71, 0x27, 0xf2, 0x02, 0xb7, 0x5e,
+       0x9f, 0xa0, 0xea, 0x05, 0xb9, 0x1d, 0xde, 0xb9, 0xac, 0x64, 0x4a, 0x9c,
+       0xe3, 0xfb, 0x9f, 0x32, 0xea, 0xef, 0x8f, 0x19, 0x89, 0x62, 0xc2, 0x88,
+       0x2f, 0xa1, 0xdd, 0x53, 0xc6, 0x44, 0x11, 0xbe, 0xa4, 0xe6, 0x91, 0x48,
+       0x14, 0xf2, 0xb6, 0x46, 0x9b, 0xaf, 0x53, 0x2c, 0x52, 0x4d, 0xad, 0xc8,
+       0x16, 0xfa, 0x7d, 0xac, 0xaa, 0xdf, 0x9a, 0xbe, 0xf8, 0x8e, 0xd8, 0xcf,
+       0xcb, 0x4c, 0x53, 0x8d, 0x71, 0x83, 0x88, 0xbd, 0x0f, 0x3b, 0xb4, 0x11,
+       0xc6, 0x8d, 0xd4, 0x61, 0xdc, 0xc5, 0x4d, 0xfb, 0xfd, 0x69, 0x65, 0x5c,
+       0xd6, 0x7c, 0xfb, 0x6d, 0x81, 0x65, 0xb9, 0xdf, 0x55, 0x38, 0xb7, 0x86,
+       0xa7, 0xd0, 0x46, 0xc7, 0xc8, 0x75, 0x4c, 0xac, 0x5d, 0xc5, 0x74, 0x75,
+       0x3e, 0x45, 0x50, 0xc5, 0xb4, 0x71, 0x1d, 0xbe, 0xd6, 0x2a, 0xf7, 0x0f,
+       0x7e, 0x17, 0xe2, 0x3f, 0x6e, 0xbf, 0xcb, 0x1d, 0xf3, 0xf5, 0xaa, 0x0d,
+       0xed, 0xf7, 0xa8, 0x0d, 0x75, 0xcb, 0x59, 0xc0, 0x25, 0x67, 0x61, 0x17,
+       0x86, 0xeb, 0x65, 0xff, 0xa5, 0x8d, 0xf5, 0x07, 0xfc, 0x97, 0x20, 0xf9,
+       0x2f, 0xbb, 0xfd, 0x97, 0xda, 0x3a, 0x7f, 0xc8, 0x1c, 0x70, 0x9a, 0xf4,
+       0x65, 0x12, 0xf9, 0xf2, 0x1e, 0x01, 0x3c, 0xe6, 0x4a, 0x1d, 0xe6, 0x52,
+       0x5d, 0xcd, 0xa8, 0x57, 0x7f, 0xfb, 0xea, 0xfa, 0x0b, 0x1b, 0x16, 0x6b,
+       0x88, 0xef, 0xbc, 0xfc, 0xab, 0x3b, 0xd5, 0xbf, 0x5a, 0x5d, 0x86, 0x77,
+       0xf5, 0x8b, 0x18, 0xb8, 0x53, 0xd6, 0x63, 0x63, 0xb2, 0xbf, 0xd9, 0x6a,
+       0x5f, 0xc3, 0x7f, 0x89, 0x14, 0xed, 0xbc, 0xf5, 0xfa, 0xf6, 0xe2, 0x68,
+       0x3b, 0x6b, 0x6c, 0xef, 0x78, 0xa7, 0x8c, 0x8f, 0xcd, 0xa9, 0x3c, 0xf2,
+       0x6e, 0xe5, 0xf7, 0x6d, 0xc6, 0xeb, 0x38, 0x37, 0xa7, 0x62, 0x8a, 0x11,
+       0xab, 0x40, 0xe0, 0xf1, 0xc9, 0xd3, 0x4d, 0xb6, 0xa9, 0xd6, 0xb8, 0xb0,
+       0x8e, 0x05, 0x9e, 0xd7, 0xcf, 0x97, 0x35, 0x65, 0x9b, 0xcf, 0x99, 0x55,
+       0x37, 0x67, 0x92, 0xaf, 0xe0, 0x6f, 0x21, 0x3f, 0x7a, 0xa4, 0x26, 0x47,
+       0xfd, 0xd3, 0xd0, 0xa2, 0xdd, 0x23, 0x6f, 0x1b, 0x79, 0xd7, 0x8d, 0xfa,
+       0xb9, 0xee, 0xc2, 0xea, 0xb2, 0x6e, 0x63, 0x95, 0xd0, 0xef, 0x52, 0xe9,
+       0xe5, 0x28, 0xb0, 0x69, 0x6f, 0x1d, 0xaf, 0x69, 0xbc, 0x64, 0xba, 0xfa,
+       0xf9, 0xf8, 0xc6, 0xfd, 0xac, 0xb1, 0xbf, 0x7b, 0x3d, 0xec, 0x6f, 0x23,
+       0x5f, 0x42, 0xec, 0x9d, 0xe2, 0x3b, 0x2a, 0x74, 0x41, 0x1b, 0x2d, 0xe5,
+       0x91, 0x4b, 0xfe, 0x1b, 0xa8, 0x67, 0x65, 0x7d, 0xeb, 0xaa, 0xcf, 0xf3,
+       0x9e, 0xd3, 0xf2, 0x7a, 0x4b, 0x60, 0x1c, 0xeb, 0x83, 0xc8, 0x41, 0xe9,
+       0x62, 0x1d, 0x84, 0xf6, 0x83, 0xd6, 0x0d, 0xc4, 0x80, 0x55, 0x3c, 0x2a,
+       0xa1, 0xec, 0xcc, 0xd1, 0x2d, 0xac, 0xbb, 0x6c, 0x4f, 0x5f, 0x47, 0xac,
+       0x55, 0xc2, 0x9a, 0x10, 0xf2, 0x9e, 0x9d, 0x76, 0x6a, 0xbf, 0xbf, 0xa5,
+       0xc5, 0xbe, 0xd9, 0x29, 0xd7, 0xaa, 0x70, 0xad, 0x8d, 0xae, 0xe6, 0x91,
+       0x97, 0x8e, 0x6b, 0x0f, 0xf2, 0x35, 0x2f, 0x7d, 0xf5, 0xb6, 0xe2, 0x25,
+       0x60, 0x3a, 0x39, 0x47, 0x05, 0x92, 0x73, 0xb6, 0x4e, 0xf0, 0xa5, 0x4a,
+       0xf4, 0x4f, 0xd1, 0xdf, 0x14, 0xfe, 0x5f, 0x65, 0xae, 0xb6, 0xb7, 0x8e,
+       0x53, 0x9b, 0x03, 0x31, 0xb9, 0x61, 0x1c, 0xb1, 0xa3, 0x6b, 0xab, 0xeb,
+       0x38, 0xb5, 0x39, 0x10, 0x8f, 0x6f, 0x29, 0x8e, 0x18, 0xb1, 0xa6, 0x37,
+       0xac, 0x33, 0x70, 0xaf, 0xa9, 0xe8, 0xb5, 0xe4, 0x51, 0x51, 0x7b, 0xeb,
+       0xe6, 0x89, 0x3b, 0xb3, 0x9e, 0x0c, 0xde, 0xe8, 0xab, 0xd3, 0x61, 0x77,
+       0x60, 0x3d, 0xa0, 0x86, 0xb6, 0x41, 0xcf, 0x58, 0x96, 0xf7, 0xba, 0x31,
+       0x72, 0x04, 0x10, 0xc3, 0x2e, 0xd2, 0x99, 0x2b, 0xe0, 0x67, 0x83, 0x39,
+       0x6f, 0x80, 0x32, 0x21, 0xd4, 0x52, 0x89, 0xba, 0x28, 0xbd, 0xbe, 0x28,
+       0xea, 0xa3, 0xce, 0x88, 0xba, 0xcf, 0xc1, 0xf0, 0x6d, 0xb6, 0x91, 0x67,
+       0x8a, 0x6f, 0xd1, 0xd9, 0xa5, 0x20, 0xff, 0x57, 0xf0, 0x7c, 0x7d, 0xed,
+       0x67, 0x35, 0xbf, 0xdf, 0x16, 0xfc, 0xde, 0xbb, 0x21, 0xbf, 0x1f, 0x2f,
+       0xf3, 0x3b, 0x77, 0x28, 0x28, 0x6b, 0x2b, 0x53, 0x57, 0xda, 0xe9, 0xa8,
+       0x78, 0xee, 0x5b, 0xfc, 0x7d, 0x27, 0x1d, 0x35, 0xe5, 0xf7, 0xb3, 0x4b,
+       0xac, 0xfb, 0xb3, 0x6f, 0xd1, 0xb9, 0x2b, 0x8e, 0x2f, 0x21, 0xea, 0x32,
+       0xdc, 0x7b, 0x86, 0xe8, 0xfb, 0xd1, 0xce, 0x4b, 0x16, 0xea, 0xf5, 0x55,
+       0x41, 0xea, 0x2b, 0xba, 0x29, 0x62, 0x20, 0xde, 0xfa, 0x0a, 0xfc, 0x79,
+       0x5e, 0xd9, 0xc6, 0xc9, 0x0d, 0x62, 0x1f, 0xf5, 0xbc, 0xd9, 0xe9, 0x81,
+       0x91, 0xbf, 0xdb, 0x25, 0xd7, 0xb1, 0x36, 0x8a, 0x81, 0x54, 0xe5, 0x81,
+       0xb8, 0xd7, 0xf9, 0xd9, 0x1e, 0x4c, 0xaa, 0x75, 0xf7, 0x9f, 0x76, 0x49,
+       0x3b, 0x82, 0x9a, 0xc8, 0x55, 0xa6, 0xc3, 0x3f, 0x30, 0x7e, 0xd9, 0x4f,
+       0xcd, 0x97, 0xf5, 0x58, 0xf7, 0x0b, 0x7f, 0xc8, 0x1d, 0xcb, 0x99, 0x55,
+       0x35, 0xee, 0x69, 0xd7, 0x98, 0x66, 0x85, 0xdf, 0xf3, 0x49, 0xd6, 0x31,
+       0x7b, 0x6b, 0x6c, 0x45, 0x2d, 0xbf, 0x61, 0x3f, 0x16, 0xcc, 0x2f, 0x19,
+       0x12, 0x1b, 0x8f, 0x31, 0xe6, 0xdd, 0xee, 0x7a, 0xd2, 0xa7, 0xc5, 0x8d,
+       0xb5, 0x7b, 0x7d, 0xd4, 0x7e, 0xc7, 0x3c, 0x48, 0x3f, 0x24, 0xf5, 0x42,
+       0x51, 0xe8, 0x82, 0xd9, 0x91, 0x12, 0x4d, 0x44, 0x77, 0x51, 0x6a, 0x84,
+       0xdf, 0x3d, 0x66, 0xb3, 0x3f, 0xe6, 0x27, 0x87, 0xe5, 0x37, 0x35, 0xb2,
+       0x43, 0xd5, 0xcc, 0xe9, 0x58, 0x7b, 0x8b, 0xc2, 0x90, 0xed, 0x62, 0xdd,
+       0x52, 0xee, 0x49, 0xc4, 0xdf, 0x97, 0xf4, 0xb3, 0x71, 0x1e, 0xbc, 0xdb,
+       0xac, 0xda, 0x5d, 0x74, 0xb5, 0x43, 0x9b, 0x8b, 0xaa, 0x2d, 0x9e, 0xa9,
+       0xb1, 0x86, 0xae, 0xd3, 0x82, 0x1c, 0xae, 0xaa, 0xfa, 0x44, 0xf9, 0xbc,
+       0x99, 0xe2, 0x45, 0x6e, 0xd3, 0xa5, 0xae, 0x5f, 0x64, 0xfc, 0x5b, 0x14,
+       0x32, 0x22, 0xfb, 0xd2, 0x54, 0xee, 0x8b, 0xc4, 0xed, 0xb8, 0xa7, 0x5d,
+       0xe5, 0x62, 0xbe, 0x25, 0xd7, 0x05, 0x54, 0x1f, 0xe4, 0x75, 0xfe, 0x5c,
+       0xaa, 0xf6, 0x29, 0xdf, 0x28, 0xea, 0x75, 0x88, 0x8f, 0x7d, 0x33, 0xd9,
+       0x77, 0x7c, 0x32, 0xe7, 0xd8, 0x14, 0x6b, 0xa9, 0x32, 0x7f, 0x43, 0x7f,
+       0x47, 0xac, 0x19, 0x39, 0x16, 0xc8, 0x9f, 0x70, 0xeb, 0x16, 0x39, 0xb6,
+       0x00, 0x6c, 0x50, 0x11, 0x6b, 0xa8, 0x1b, 0xe1, 0xe7, 0xbd, 0xcc, 0x9b,
+       0xe6, 0x36, 0x70, 0xe8, 0x56, 0x64, 0xcd, 0xf2, 0x90, 0x35, 0xf7, 0xfb,
+       0x51, 0xcb, 0x87, 0x9a, 0x3e, 0x67, 0xd8, 0xa0, 0x12, 0xfb, 0x0a, 0x06,
+       0x15, 0x4c, 0x1f, 0x9d, 0xb3, 0x23, 0xd1, 0x25, 0x81, 0x37, 0xef, 0x43,
+       0xce, 0xcf, 0xf0, 0x2a, 0x1d, 0x36, 0xcf, 0x92, 0xdc, 0xef, 0xa1, 0xc0,
+       0xb6, 0x77, 0x9a, 0xf9, 0xed, 0x2c, 0xfb, 0x1f, 0xce, 0x14, 0xd6, 0x5d,
+       0x34, 0xcd, 0xb0, 0x0f, 0x00, 0x3e, 0x2d, 0x9e, 0xa7, 0xe2, 0x6e, 0x0a,
+       0xc6, 0xf8, 0x99, 0x16, 0x74, 0x11, 0x3f, 0x27, 0x49, 0x71, 0xf6, 0x93,
+       0xe0, 0xb3, 0x4e, 0x4f, 0x45, 0xcc, 0x02, 0x19, 0xdc, 0x16, 0xbe, 0x2b,
+       0x9e, 0x83, 0xfb, 0x63, 0x66, 0x13, 0xd5, 0xd6, 0x1c, 0xb7, 0x8b, 0x3a,
+       0xcc, 0x9b, 0xd1, 0x7b, 0xc8, 0xe8, 0x81, 0x6e, 0xc2, 0x9c, 0xdd, 0xad,
+       0xd6, 0x8b, 0x3a, 0xf8, 0xfb, 0x90, 0xfa, 0x2e, 0xe7, 0x5a, 0x7e, 0xd7,
+       0xbc, 0x8c, 0xbf, 0x0f, 0x5b, 0xc8, 0xfe, 0x5d, 0x35, 0x7f, 0xd5, 0xeb,
+       0x66, 0xfd, 0x46, 0x90, 0xce, 0x7b, 0xae, 0x9b, 0x6d, 0x54, 0xcb, 0xdb,
+       0xb1, 0xc5, 0x5a, 0xde, 0x9f, 0xef, 0x96, 0xf5, 0x71, 0xee, 0xbe, 0xfc,
+       0x9c, 0xfb, 0xe2, 0x15, 0x0f, 0x71, 0xeb, 0x5e, 0xad, 0x73, 0x4b, 0xf4,
+       0x6f, 0xd1, 0xcf, 0xd2, 0x7a, 0x28, 0xac, 0xf2, 0x99, 0x90, 0xbf, 0x74,
+       0x8f, 0xe2, 0x55, 0xad, 0xe7, 0xc9, 0x43, 0xcf, 0x3f, 0x20, 0xf2, 0x8e,
+       0xa5, 0x9d, 0xd8, 0xaf, 0xe8, 0x01, 0x9a, 0x85, 0x5d, 0x34, 0xeb, 0x76,
+       0xd1, 0xcc, 0x50, 0xdf, 0x77, 0x89, 0xe3, 0xf3, 0x4b, 0xaf, 0x76, 0xc8,
+       0x7a, 0x78, 0xac, 0x29, 0x7e, 0x5f, 0x7d, 0xdf, 0x6c, 0xbc, 0x0f, 0x84,
+       0x28, 0x28, 0xe2, 0x4d, 0xae, 0xb1, 0xbe, 0x44, 0x64, 0xb3, 0x37, 0x5c,
+       0x47, 0x83, 0x6f, 0xb9, 0xce, 0xa3, 0x8f, 0x83, 0xae, 0x3e, 0xf6, 0xbb,
+       0xfa, 0x78, 0xb0, 0x41, 0x1f, 0x59, 0x9f, 0xf3, 0x7b, 0xce, 0x16, 0x3f,
+       0x69, 0x5f, 0xd1, 0x4f, 0xd4, 0x49, 0x83, 0x9e, 0x3b, 0x29, 0x1d, 0x0a,
+       0x2b, 0x3b, 0x11, 0x55, 0xf5, 0x03, 0x5e, 0x7d, 0xfe, 0x31, 0x35, 0x9e,
+       0x37, 0x37, 0xaf, 0xba, 0xeb, 0xab, 0x9f, 0xa3, 0x09, 0x59, 0x27, 0xaf,
+       0x64, 0xfb, 0x62, 0x83, 0x78, 0x34, 0x72, 0x3b, 0x80, 0x37, 0x84, 0x6f,
+       0xb8, 0x4f, 0xee, 0x6f, 0x17, 0xa0, 0xe5, 0x72, 0xad, 0xb2, 0x5f, 0xd5,
+       0xf0, 0x3d, 0x1b, 0xba, 0xb3, 0x75, 0xca, 0x38, 0xff, 0x3d, 0x11, 0xcb,
+       0x93, 0xeb, 0x48, 0xab, 0xaa, 0xde, 0x3a, 0x62, 0x21, 0x47, 0x60, 0x71,
+       0x05, 0x71, 0xd8, 0x46, 0xb5, 0xc9, 0x52, 0x17, 0xa5, 0xca, 0x7b, 0xc2,
+       0x14, 0x44, 0x1d, 0x86, 0x8c, 0x8f, 0xc9, 0x1a, 0xe2, 0xc5, 0x95, 0x1b,
+       0xa2, 0x6e, 0x37, 0xae, 0x6a, 0x91, 0x53, 0xd4, 0x26, 0x70, 0xed, 0x27,
+       0xaf, 0x21, 0xfe, 0x71, 0x68, 0xfb, 0x35, 0xc4, 0xee, 0x7b, 0xb6, 0x57,
+       0x43, 0x6c, 0xf2, 0xd8, 0x8d, 0x05, 0x59, 0x43, 0x5c, 0xbd, 0x46, 0x23,
+       0x6b, 0x88, 0x53, 0x2e, 0xac, 0x20, 0xf1, 0xf9, 0x4d, 0x57, 0x7e, 0xb7,
+       0xac, 0x0f, 0x5e, 0x2c, 0xe3, 0x53, 0x59, 0x1f, 0x2c, 0xf3, 0xc1, 0xdd,
+       0x7b, 0xdf, 0xc8, 0xb5, 0x20, 0xf9, 0x9e, 0x5d, 0x35, 0x6b, 0x41, 0xb2,
+       0x2e, 0xd8, 0x32, 0xbc, 0xf8, 0x4e, 0xdb, 0x25, 0xec, 0xf7, 0x10, 0x63,
+       0xde, 0xdd, 0xd9, 0x60, 0xbf, 0x87, 0x58, 0x83, 0xfd, 0x1e, 0xdc, 0xba,
+       0xdf, 0x8d, 0xa7, 0x80, 0x7f, 0x61, 0x17, 0x81, 0x7b, 0xb1, 0x5f, 0x43,
+       0x94, 0xce, 0x97, 0x71, 0xe6, 0x3d, 0x94, 0x54, 0x38, 0xf3, 0xfc, 0x92,
+       0xd6, 0x47, 0xfd, 0x35, 0xfa, 0xc8, 0x0b, 0x77, 0x46, 0x54, 0xce, 0x8f,
+       0x96, 0x57, 0xc7, 0x25, 0xaf, 0x8e, 0x87, 0xbc, 0xe2, 0x1e, 0xa7, 0x41,
+       0xbf, 0x41, 0x13, 0xdc, 0x83, 0xff, 0x97, 0xc2, 0xd8, 0xa7, 0x86, 0xe8,
+       0x0b, 0xdd, 0x0a, 0xeb, 0xb9, 0xe4, 0xf5, 0x2c, 0xcb, 0xab, 0x3e, 0x8f,
+       0xfe, 0x36, 0xc2, 0xfb, 0x1a, 0x1f, 0xee, 0xf7, 0x1d, 0xbb, 0xf2, 0x0b,
+       0x91, 0x17, 0x50, 0xed, 0x27, 0x6a, 0x0c, 0x71, 0x48, 0xc8, 0xd2, 0xba,
+       0x1f, 0xf9, 0x2b, 0xfa, 0x1c, 0x6a, 0xa7, 0x20, 0x7f, 0x9a, 0x16, 0xcd,
+       0x35, 0x38, 0xa3, 0x5d, 0xe1, 0x08, 0x91, 0xff, 0xeb, 0xea, 0xdb, 0x7f,
+       0x72, 0xdf, 0xf4, 0x79, 0x6d, 0x33, 0xdf, 0xae, 0x8a, 0x69, 0x54, 0xe7,
+       0x4d, 0x22, 0x7e, 0xb4, 0x2b, 0x69, 0xd8, 0x09, 0x91, 0x7f, 0xda, 0x69,
+       0x23, 0x56, 0x16, 0x67, 0xd9, 0xef, 0x4c, 0x22, 0xd7, 0xb9, 0xf3, 0x92,
+       0x45, 0xa7, 0xb2, 0x57, 0x0f, 0x48, 0x5e, 0x79, 0x5a, 0xec, 0xd3, 0x89,
+       0x7d, 0x1d, 0x27, 0xd8, 0x3e, 0xc7, 0x19, 0x60, 0xce, 0x15, 0x5b, 0x68,
+       0x91, 0x91, 0xbc, 0xdf, 0x2e, 0x88, 0x58, 0x1f, 0xeb, 0xa4, 0x1c, 0xf6,
+       0x6b, 0x35, 0x16, 0x9a, 0xf9, 0xb9, 0x3d, 0xb4, 0x9c, 0x07, 0xcf, 0x35,
+       0xa9, 0xfd, 0x53, 0xd0, 0xd6, 0x47, 0x5d, 0xf6, 0xdf, 0x32, 0xed, 0x1e,
+       0x11, 0x79, 0x97, 0x8b, 0xb9, 0xa7, 0xe5, 0x67, 0xe1, 0x55, 0xf5, 0x0e,
+       0x7e, 0x5f, 0xf1, 0x75, 0x8a, 0x75, 0xb9, 0xf3, 0x00, 0xdd, 0x7f, 0xde,
+       0x78, 0xe5, 0xe4, 0xb6, 0xf0, 0x8a, 0x93, 0xac, 0xe0, 0x15, 0xf7, 0xb3,
+       0x35, 0x76, 0xf9, 0xe3, 0x1e, 0xb9, 0x9f, 0x05, 0x68, 0xb0, 0x13, 0x58,
+       0x2c, 0x09, 0x5a, 0x1a, 0xe3, 0x91, 0x70, 0xdc, 0x3f, 0x46, 0x99, 0xe2,
+       0x35, 0x4a, 0xe5, 0x60, 0xe7, 0xf9, 0xb3, 0xf0, 0x37, 0x7b, 0x64, 0x9c,
+       0x46, 0xdf, 0x03, 0xbd, 0xb2, 0x9b, 0xdb, 0x37, 0xef, 0x91, 0x39, 0xdb,
+       0xee, 0xf3, 0xed, 0x7c, 0xfe, 0xc9, 0x70, 0xf5, 0xf9, 0x1d, 0x7c, 0xbe,
+       0x2b, 0x89, 0x39, 0x34, 0x2e, 0x21, 0x36, 0x39, 0x4c, 0x69, 0x9e, 0x9f,
+       0x4c, 0x91, 0x6d, 0xeb, 0x65, 0xd6, 0x57, 0x4b, 0xba, 0x5d, 0x37, 0xb7,
+       0x0b, 0x89, 0x39, 0x31, 0xb8, 0xcd, 0x6c, 0x76, 0x84, 0xdb, 0xed, 0x27,
+       0xff, 0x65, 0x8b, 0x32, 0x4b, 0x9a, 0x57, 0x75, 0x2e, 0xfe, 0x2f, 0xba,
+       0x65, 0x6e, 0xd5, 0xae, 0xb0, 0xa4, 0xdf, 0xb0, 0x88, 0x7b, 0x22, 0xb7,
+       0xe3, 0x19, 0xc1, 0x87, 0x91, 0x31, 0xab, 0xfc, 0x7e, 0xec, 0x31, 0x26,
+       0xf6, 0x7c, 0xe5, 0x31, 0xb0, 0x5e, 0x1c, 0xb7, 0xcd, 0x74, 0x39, 0x6f,
+       0x6d, 0x6d, 0x9f, 0xbc, 0x7f, 0x67, 0x8f, 0xdc, 0x7f, 0xb5, 0x53, 0xed,
+       0x15, 0xa8, 0x6d, 0xce, 0x17, 0x90, 0xa7, 0x2d, 0x68, 0xe3, 0x5f, 0x80,
+       0xbe, 0x34, 0xf8, 0x3b, 0x8f, 0x27, 0x89, 0x3e, 0xf6, 0xf6, 0xe8, 0x3d,
+       0x17, 0xe5, 0xb8, 0x4e, 0x70, 0x7f, 0x13, 0x3c, 0x2e, 0x7d, 0x3e, 0xc6,
+       0xc7, 0x5e, 0xf3, 0x8b, 0x67, 0x05, 0xf9, 0x39, 0x2c, 0x03, 0x53, 0xc1,
+       0x64, 0x6a, 0x58, 0xce, 0x73, 0x25, 0xae, 0x1b, 0x2e, 0xc7, 0x75, 0xe7,
+       0xb2, 0xc7, 0x7b, 0x10, 0xcf, 0x30, 0x2e, 0xf1, 0x7c, 0x87, 0x9e, 0xe1,
+       0xb6, 0xa8, 0x63, 0x48, 0xf3, 0x67, 0x9b, 0xca, 0xef, 0xa9, 0xe7, 0x15,
+       0x99, 0x2f, 0xa1, 0xed, 0x16, 0xee, 0xbd, 0x97, 0x9f, 0x21, 0x6d, 0x57,
+       0xe3, 0xf7, 0x50, 0x5d, 0x4e, 0x4c, 0x3d, 0x8f, 0x6d, 0x14, 0x8b, 0x15,
+       0xeb, 0x8a, 0x1e, 0x7c, 0xb6, 0x51, 0xac, 0x44, 0xe4, 0x39, 0xfb, 0x26,
+       0xea, 0xe4, 0x15, 0x72, 0x1c, 0xa0, 0x27, 0xe6, 0x1d, 0xda, 0xc1, 0x73,
+       0xf5, 0x27, 0x06, 0xea, 0x86, 0x4b, 0x24, 0x73, 0x9f, 0x98, 0xc6, 0x59,
+       0x7b, 0xf8, 0xac, 0xc1, 0x74, 0xce, 0x3a, 0xa5, 0x80, 0xdd, 0x46, 0xcd,
+       0x2c, 0xab, 0xbf, 0x4f, 0x03, 0xec, 0xeb, 0x41, 0x66, 0xed, 0x70, 0x82,
+       0x20, 0x6f, 0x11, 0xf3, 0x18, 0xf3, 0xc4, 0x44, 0x11, 0xfc, 0x6c, 0xd0,
+       0x63, 0x79, 0xa2, 0x47, 0xf3, 0x03, 0xe6, 0x37, 0xc9, 0xb6, 0x2a, 0xd7,
+       0x23, 0x66, 0x9c, 0xfb, 0x91, 0x28, 0xfe, 0x25, 0x7d, 0x24, 0xf6, 0x71,
+       0x01, 0x1d, 0xf5, 0xbc, 0xff, 0x39, 0x4d, 0x27, 0xd1, 0xef, 0xad, 0xcb,
+       0xe7, 0xa9, 0x6d, 0xc9, 0x67, 0xd0, 0x43, 0x3e, 0x3f, 0x54, 0x7c, 0x53,
+       0x62, 0x1e, 0x0d, 0xd2, 0x4c, 0x0e, 0xb9, 0x60, 0x9f, 0x47, 0x0d, 0x66,
+       0x2e, 0xc5, 0x7a, 0x29, 0x55, 0xd1, 0x4b, 0x17, 0xe2, 0xfe, 0x18, 0x64,
+       0x1c, 0x7b, 0xd1, 0xa9, 0x1c, 0x20, 0x8c, 0x63, 0x1f, 0x0d, 0x2c, 0xec,
+       0xe4, 0x7b, 0x69, 0x35, 0x3e, 0x1a, 0x53, 0x7b, 0x15, 0x44, 0xac, 0x09,
+       0xd6, 0x8f, 0x73, 0x2c, 0xcb, 0xe9, 0xdc, 0xdd, 0xb4, 0x18, 0xea, 0xa5,
+       0xfe, 0x05, 0xbd, 0x7f, 0x0b, 0xc6, 0x3a, 0xd4, 0x2b, 0x75, 0x92, 0x1e,
+       0xf7, 0x6f, 0x89, 0x38, 0x85, 0x75, 0xed, 0x57, 0x35, 0xee, 0x9d, 0x9b,
+       0xe8, 0xa5, 0x92, 0x92, 0xd9, 0xd2, 0x1b, 0xf1, 0x28, 0x39, 0xf1, 0xd1,
+       0xff, 0x15, 0xfc, 0xdf, 0x7f, 0x0d, 0xb5, 0x38, 0xd0, 0xd1, 0x16, 0x25,
+       0xb3, 0xb5, 0xb4, 0xe8, 0xe5, 0x71, 0xe3, 0x7a, 0xe9, 0xa7, 0x33, 0xd1,
+       0x57, 0x85, 0xed, 0x1f, 0xb8, 0xc6, 0xed, 0x84, 0x6d, 0xd2, 0x7a, 0xc3,
+       0x8b, 0x0f, 0xf5, 0xde, 0x9c, 0x9a, 0x17, 0x65, 0xce, 0x27, 0xe3, 0x37,
+       0x33, 0xe9, 0xaf, 0xe5, 0xc9, 0x8f, 0xe9, 0xe4, 0xbc, 0x45, 0x93, 0x59,
+       0xec, 0x81, 0x38, 0xc6, 0x72, 0xed, 0xb6, 0x17, 0xdc, 0x9e, 0xc0, 0x67,
+       0xe3, 0x2c, 0xfb, 0xec, 0xb7, 0xe7, 0x2c, 0x99, 0x7f, 0x27, 0xf6, 0xdb,
+       0x6b, 0x11, 0x7a, 0xd4, 0xb4, 0xfb, 0xf7, 0x68, 0x7b, 0x90, 0xca, 0xa1,
+       0xce, 0x90, 0x3f, 0x0b, 0xdc, 0x3e, 0xdb, 0x43, 0xa9, 0x3c, 0x9e, 0x03,
+       0x7b, 0x87, 0xbe, 0xf3, 0xf1, 0xb2, 0x9c, 0xd7, 0x7e, 0x7e, 0x36, 0xf6,
+       0x0e, 0x98, 0x2c, 0x8e, 0x88, 0x1c, 0x3c, 0xe8, 0x66, 0x39, 0x9f, 0xe3,
+       0x34, 0xeb, 0xa9, 0x57, 0x14, 0xa6, 0x74, 0xc9, 0x77, 0x4a, 0xc8, 0xf7,
+       0xb8, 0x98, 0x8f, 0x54, 0xde, 0x60, 0xbc, 0xa6, 0xe3, 0x0c, 0x5d, 0x7c,
+       0x1c, 0x50, 0x3a, 0x04, 0xd7, 0xee, 0xdd, 0x23, 0xf2, 0x13, 0x6d, 0x9c,
+       0xc7, 0xe7, 0x38, 0x3d, 0xc3, 0xb8, 0xf3, 0xd9, 0x6c, 0x0b, 0xdd, 0xc8,
+       0xb5, 0xd0, 0x9b, 0xb9, 0x5e, 0xba, 0x3e, 0xdf, 0x41, 0xb3, 0x8c, 0x99,
+       0x67, 0xed, 0x80, 0x95, 0x66, 0xff, 0xe2, 0x6a, 0x54, 0xe4, 0x10, 0xb1,
+       0xdc, 0xa1, 0x3d, 0xf0, 0x5f, 0x7c, 0x2f, 0xf3, 0x1c, 0x63, 0xef, 0x56,
+       0xfa, 0x80, 0xdf, 0x99, 0xce, 0xea, 0x9c, 0x07, 0xc4, 0xe3, 0x07, 0xcb,
+       0xf8, 0x75, 0x73, 0x1e, 0x31, 0x37, 0xe1, 0x91, 0x71, 0xa1, 0xeb, 0x33,
+       0xf3, 0x7c, 0x7d, 0x1e, 0x71, 0x73, 0x4b, 0xc4, 0x24, 0xbe, 0x14, 0x40,
+       0x7b, 0x9c, 0xb3, 0x65, 0xce, 0xa4, 0x18, 0x5b, 0x98, 0x8f, 0x41, 0xdb,
+       0xb0, 0xa2, 0x43, 0x2b, 0x8f, 0x4f, 0xc6, 0x30, 0x52, 0xcb, 0xad, 0x74,
+       0x26, 0xcf, 0x18, 0x24, 0xef, 0x67, 0x1f, 0x06, 0x6d, 0x7f, 0xe7, 0xa0,
+       0xde, 0xd3, 0x76, 0x96, 0xfb, 0x9e, 0xce, 0x4b, 0x0c, 0x92, 0x5e, 0x6e,
+       0xa7, 0x4c, 0xbe, 0x4d, 0x1d, 0xdf, 0x2d, 0xf2, 0xdd, 0xe5, 0xde, 0x12,
+       0xb8, 0xb6, 0x91, 0x7e, 0x43, 0xae, 0x11, 0x6c, 0xaa, 0xf4, 0x4b, 0xa1,
+       0x6b, 0xbc, 0xf3, 0x8c, 0xc6, 0xe8, 0x39, 0xb6, 0xb7, 0xfd, 0x97, 0x11,
+       0x2b, 0xfe, 0x22, 0xf8, 0xa6, 0x00, 0x1e, 0xeb, 0xbf, 0x8c, 0x7d, 0x9f,
+       0xfc, 0x22, 0xf7, 0x68, 0x22, 0x34, 0x2c, 0x6a, 0x46, 0xa4, 0x8c, 0x4e,
+       0x89, 0xba, 0xec, 0xef, 0x08, 0xdd, 0x14, 0x71, 0x2c, 0x03, 0x78, 0x24,
+       0x12, 0x26, 0x92, 0x39, 0x59, 0xa7, 0xec, 0xce, 0x9b, 0xdd, 0xe3, 0x43,
+       0x14, 0xeb, 0x01, 0xdf, 0x4b, 0x99, 0x95, 0x7b, 0x22, 0x90, 0xd0, 0xf7,
+       0xe6, 0x21, 0x5d, 0x63, 0xa0, 0x8f, 0xb5, 0xad, 0xd0, 0xc7, 0x6d, 0x35,
+       0xd7, 0xcd, 0x9a, 0xeb, 0x1a, 0x7f, 0x63, 0xad, 0x8c, 0xed, 0x3c, 0xc9,
+       0x3d, 0x98, 0x52, 0x0b, 0x92, 0xff, 0xcc, 0x43, 0x83, 0xe6, 0xfd, 0x0a,
+       0x83, 0xa7, 0x56, 0x06, 0xc2, 0x9d, 0x46, 0x9b, 0x3f, 0x35, 0xf2, 0xaf,
+       0xa5, 0x58, 0x12, 0xb8, 0xe8, 0xf5, 0x3d, 0x52, 0xc7, 0xa1, 0x5f, 0x4e,
+       0x14, 0xd0, 0x6d, 0x6a, 0xa5, 0x8d, 0x56, 0xc5, 0x9e, 0x63, 0xc0, 0x18,
+       0xb8, 0x1f, 0xcf, 0x71, 0xcc, 0x26, 0xc2, 0x3e, 0xf2, 0x90, 0xf1, 0xc3,
+       0xe1, 0x6b, 0x3c, 0x9f, 0x89, 0x95, 0xff, 0x29, 0x4d, 0x8b, 0x7d, 0x7a,
+       0xd0, 0x96, 0x31, 0xa4, 0xc0, 0xfc, 0x8c, 0x5f, 0xaa, 0xfc, 0xaa, 0x31,
+       0xf4, 0xd3, 0xc1, 0x9a, 0x8a, 0x61, 0xbf, 0xc0, 0x32, 0x26, 0xd7, 0xca,
+       0x13, 0x35, 0x6b, 0xe5, 0x53, 0x62, 0xad, 0x1c, 0xeb, 0xe4, 0x1b, 0xe5,
+       0x2d, 0xea, 0x3c, 0x16, 0x8b, 0x66, 0xaf, 0x08, 0x7d, 0x13, 0x9d, 0xf0,
+       0xcb, 0x3c, 0xeb, 0x04, 0xbb, 0x37, 0x86, 0xa8, 0x6d, 0xc0, 0x67, 0xcc,
+       0x88, 0xdb, 0x91, 0xe1, 0x35, 0xc6, 0x14, 0x4b, 0xb9, 0x1d, 0x74, 0xbd,
+       0xd0, 0xc4, 0x98, 0xef, 0x9f, 0x69, 0xad, 0x40, 0x8c, 0x0d, 0x3b, 0x28,
+       0x13, 0x65, 0x5e, 0x1b, 0x0e, 0xf2, 0xbc, 0x32, 0xbe, 0x1d, 0x66, 0xf9,
+       0xe3, 0x31, 0x2c, 0xe5, 0x4b, 0xef, 0xa7, 0xa3, 0x31, 0x2b, 0x3e, 0xda,
+       0xc6, 0xfe, 0x8b, 0xc9, 0xff, 0x36, 0xff, 0x9f, 0x0b, 0x83, 0x36, 0x8b,
+       0xcb, 0xb8, 0xce, 0xd8, 0x27, 0x5b, 0x7a, 0x7f, 0x86, 0xdb, 0xcc, 0x8c,
+       0xc2, 0x0f, 0x82, 0xbf, 0x67, 0xf3, 0xbf, 0x6c, 0xb3, 0xc4, 0x7c, 0x97,
+       0xbe, 0xe2, 0x84, 0x0d, 0xa1, 0xe3, 0xb1, 0x2f, 0xcd, 0x80, 0xfa, 0x8c,
+       0x19, 0x33, 0xdc, 0x97, 0xeb, 0x84, 0x67, 0x58, 0x94, 0x8a, 0x1e, 0x62,
+       0x39, 0xe8, 0xe0, 0x4f, 0xd4, 0x6a, 0xed, 0xa4, 0xcc, 0xc8, 0xa0, 0xaa,
+       0xd5, 0xfa, 0x59, 0x83, 0x5a, 0x2d, 0xdc, 0xc7, 0x38, 0x60, 0xbe, 0x74,
+       0x7b, 0x26, 0xea, 0x7e, 0x2f, 0x19, 0xa9, 0xe8, 0x2e, 0x81, 0x99, 0x96,
+       0x96, 0x1f, 0xe6, 0x3e, 0xc4, 0xac, 0xd4, 0x28, 0xf7, 0x35, 0xef, 0xee,
+       0x7f, 0xe9, 0xf6, 0x44, 0x14, 0xed, 0xfc, 0x35, 0xed, 0x62, 0x24, 0xda,
+       0x2e, 0xa3, 0x7d, 0xe9, 0x97, 0xf1, 0xa8, 0x1e, 0xa7, 0xfb, 0x5e, 0x8c,
+       0x07, 0xf2, 0xc5, 0x9f, 0x4b, 0xef, 0xd0, 0xf5, 0x1c, 0xfc, 0x71, 0x43,
+       0xd5, 0x5f, 0x59, 0xe4, 0x2c, 0x31, 0x06, 0xbc, 0x72, 0xd0, 0xb7, 0x96,
+       0xfb, 0x41, 0x29, 0x55, 0x95, 0xdb, 0x52, 0x1d, 0x73, 0x97, 0x3e, 0x58,
+       0x2f, 0xd9, 0x97, 0x60, 0x43, 0x61, 0x3f, 0x9d, 0x92, 0xdf, 0x06, 0xde,
+       0x83, 0x6f, 0xf4, 0x34, 0xeb, 0x2f, 0x99, 0x9f, 0xc4, 0xba, 0x94, 0x75,
+       0x98, 0x94, 0x9f, 0x44, 0xd5, 0x4f, 0x3c, 0x48, 0x1e, 0xee, 0xaf, 0xe4,
+       0x49, 0xba, 0xd6, 0xd8, 0x03, 0xae, 0x35, 0x76, 0xd3, 0x95, 0x27, 0x19,
+       0x12, 0xf8, 0xac, 0x82, 0xa9, 0x42, 0x0a, 0x53, 0x01, 0x7b, 0x49, 0xdd,
+       0xb6, 0x58, 0xd6, 0x6d, 0xbb, 0x37, 0xd1, 0x6d, 0x5e, 0xbe, 0xea, 0xaa,
+       0xd2, 0x23, 0x91, 0x28, 0x6c, 0x0c, 0xf6, 0x59, 0xfa, 0xfb, 0xe2, 0x28,
+       0xeb, 0x91, 0x28, 0xeb, 0x91, 0x11, 0xd6, 0x23, 0xc3, 0xac, 0x47, 0x6c,
+       0xa6, 0x81, 0xc5, 0x63, 0xff, 0x98, 0xf5, 0x34, 0xec, 0xc7, 0x18, 0x3d,
+       0x53, 0x84, 0x4e, 0x1e, 0x61, 0x0c, 0xf4, 0x31, 0xad, 0xcd, 0xb7, 0x33,
+       0xff, 0x4a, 0xdc, 0x53, 0xed, 0xd7, 0x60, 0xdf, 0x18, 0xc4, 0x86, 0x7f,
+       0x08, 0xbd, 0xf3, 0xb2, 0x43, 0x7d, 0xbe, 0xeb, 0x39, 0xd0, 0x79, 0x0d,
+       0x7b, 0x6b, 0xbc, 0x08, 0xd9, 0xc6, 0xbe, 0xc7, 0xdf, 0x1e, 0x1a, 0xe3,
+       0xbe, 0xf7, 0xf9, 0x32, 0x3c, 0x2f, 0x8f, 0x47, 0x1d, 0xb3, 0x8b, 0x65,
+       0x60, 0x52, 0xc9, 0xc0, 0x64, 0x45, 0x06, 0x9c, 0x34, 0x8f, 0xa4, 0x73,
+       0xa1, 0x83, 0x06, 0x8f, 0xc4, 0xf7, 0x76, 0xb2, 0xfc, 0x22, 0x67, 0xa2,
+       0xb2, 0xff, 0x90, 0x9f, 0xa6, 0x43, 0x41, 0xb5, 0x6f, 0x91, 0xc5, 0x76,
+       0xf3, 0x27, 0x94, 0xc9, 0xbd, 0xcb, 0xb8, 0x84, 0xe5, 0xd4, 0xc4, 0xf1,
+       0x45, 0xc4, 0x45, 0xd9, 0x6f, 0x68, 0x15, 0x71, 0xa5, 0x45, 0xd1, 0x16,
+       0xc7, 0x91, 0x61, 0xd6, 0x71, 0xd1, 0x55, 0x23, 0x32, 0x16, 0x33, 0x2e,
+       0xf7, 0x62, 0x5f, 0xfa, 0x6f, 0x17, 0x1f, 0xeb, 0x95, 0xf5, 0xb9, 0x4f,
+       0xed, 0x95, 0xfa, 0x84, 0x79, 0x34, 0x14, 0x13, 0xbe, 0x5b, 0xd3, 0x25,
+       0x69, 0x3f, 0x17, 0x79, 0xbe, 0x97, 0xa2, 0xc3, 0x3c, 0xdf, 0x6d, 0xca,
+       0x76, 0x3a, 0x7c, 0x5d, 0xd8, 0x65, 0xb6, 0xa1, 0xbd, 0xd8, 0xd3, 0xdf,
+       0x8c, 0x47, 0x9f, 0xe2, 0x77, 0x62, 0x1f, 0xa1, 0x2f, 0xe3, 0x79, 0xcc,
+       0xbd, 0xd0, 0x1f, 0x3f, 0x61, 0x1b, 0x8d, 0xf7, 0x82, 0x1f, 0xf9, 0x7b,
+       0x61, 0x8c, 0x2e, 0x64, 0x75, 0x1f, 0xde, 0x23, 0xe3, 0x39, 0xf4, 0xc3,
+       0x47, 0xbb, 0xed, 0xf7, 0x44, 0x4d, 0x88, 0xf1, 0x8d, 0xda, 0x3e, 0x7d,
+       0x45, 0xf5, 0x09, 0x7b, 0x79, 0xb6, 0xf0, 0x18, 0x76, 0x13, 0xf6, 0x74,
+       0x5a, 0x14, 0x7b, 0x6d, 0x36, 0x0b, 0x9f, 0x75, 0x51, 0xf8, 0x1e, 0x0f,
+       0xef, 0xad, 0xec, 0xff, 0x79, 0x57, 0xcd, 0xb9, 0x75, 0xb6, 0x5b, 0x47,
+       0x05, 0x46, 0xeb, 0xc7, 0x1e, 0xf4, 0xa2, 0x66, 0xf5, 0x4f, 0xc5, 0x35,
+       0x63, 0x01, 0xd7, 0x3e, 0xa7, 0xae, 0x7d, 0x56, 0x60, 0x63, 0x63, 0xbc,
+       0x95, 0xf5, 0xa2, 0xe0, 0x77, 0x9e, 0x67, 0x7b, 0x98, 0xf9, 0x3d, 0xbc,
+       0xc4, 0xcf, 0x9d, 0x16, 0xf4, 0xd4, 0xf4, 0x00, 0x2d, 0x20, 0x03, 0x6d,
+       0x8a, 0xff, 0x23, 0x56, 0xc2, 0xaf, 0xc7, 0xdd, 0x88, 0xce, 0x63, 0xb0,
+       0xcf, 0x3c, 0x56, 0x8c, 0xc9, 0xf2, 0xc5, 0x0a, 0x61, 0x5f, 0x7a, 0x1e,
+       0xbe, 0x0e, 0xea, 0x5e, 0x0e, 0x20, 0x9f, 0x8a, 0xfb, 0xb0, 0x87, 0x62,
+       0x49, 0xf4, 0x0b, 0xed, 0x34, 0x0d, 0xfe, 0xa8, 0x86, 0x16, 0xee, 0xfb,
+       0x3a, 0xd4, 0x7d, 0xad, 0x62, 0x2e, 0xc8, 0xc0, 0x7b, 0xf4, 0xbb, 0xf1,
+       0x5e, 0xbc, 0x1f, 0xf7, 0xe1, 0x79, 0xf2, 0xb9, 0xdd, 0xac, 0xb7, 0xe3,
+       0xa3, 0xf2, 0x59, 0xc6, 0x35, 0x79, 0xad, 0xdb, 0xf6, 0xee, 0xaf, 0x9c,
+       0x3f, 0x9f, 0xda, 0x83, 0x08, 0xf3, 0xd7, 0x41, 0x05, 0x11, 0xfb, 0xc4,
+       0xb5, 0x3e, 0x9f, 0xf0, 0x6b, 0x6d, 0xfe, 0xe4, 0x79, 0x9d, 0xe3, 0xe3,
+       0x33, 0xb9, 0x77, 0x84, 0xcf, 0x9e, 0x4e, 0xf6, 0xf9, 0x0a, 0x05, 0x8c,
+       0xb7, 0xcf, 0x97, 0x60, 0x19, 0x98, 0xc8, 0xc5, 0x4b, 0x19, 0xa1, 0x6b,
+       0x18, 0xeb, 0x76, 0x45, 0xcc, 0x69, 0xa3, 0x47, 0x60, 0x3e, 0x7e, 0x1f,
+       0x7f, 0x67, 0x39, 0xcc, 0xb2, 0x1c, 0x66, 0x59, 0x0e, 0xb3, 0x2c, 0x87,
+       0xec, 0xab, 0x7e, 0x2b, 0xcb, 0x72, 0xc8, 0xb6, 0xe4, 0x15, 0xb6, 0x25,
+       0x52, 0x76, 0x63, 0x2a, 0xbe, 0xa9, 0x65, 0x17, 0xeb, 0x7f, 0x6e, 0x1f,
+       0x47, 0xcb, 0x2a, 0xec, 0x37, 0xf9, 0x8e, 0x0f, 0x55, 0xcb, 0xec, 0x0d,
+       0x96, 0xd9, 0xa6, 0xf1, 0x1e, 0xba, 0x95, 0xc7, 0x9c, 0x45, 0xac, 0x39,
+       0xd6, 0xd5, 0x09, 0x3f, 0xb0, 0x56, 0x80, 0xe5, 0x09, 0x58, 0x33, 0xc2,
+       0x74, 0xef, 0xa1, 0xdb, 0xac, 0xaf, 0x6f, 0xe5, 0x21, 0xc3, 0x07, 0xd4,
+       0x71, 0x84, 0x65, 0x18, 0xf6, 0xcf, 0xf6, 0xdd, 0xc8, 0x19, 0x8c, 0xc9,
+       0x02, 0x66, 0x8a, 0xa0, 0x4f, 0x05, 0x4e, 0xe3, 0x79, 0x5f, 0x65, 0xbd,
+       0x8f, 0x18, 0x1e, 0xec, 0xc5, 0x19, 0x1f, 0xdb, 0x8b, 0xf0, 0x75, 0xd6,
+       0xa7, 0xe7, 0xf3, 0x36, 0xcb, 0x7d, 0x17, 0xfd, 0x59, 0x1e, 0x76, 0x1a,
+       0x34, 0xe2, 0xe3, 0x02, 0x89, 0xd8, 0x98, 0x31, 0x8e, 0xb1, 0x0f, 0x3a,
+       0x86, 0xe0, 0x93, 0xdb, 0x98, 0x23, 0xa6, 0xfd, 0x3b, 0x7b, 0xb1, 0x9f,
+       0x7e, 0xcc, 0x68, 0x56, 0xb1, 0x46, 0x7c, 0x47, 0xfb, 0x1e, 0x85, 0x4d,
+       0x71, 0xdc, 0x68, 0x0d, 0x12, 0xbf, 0x43, 0x11, 0x65, 0x7a, 0xd4, 0xea,
+       0xaf, 0x0b, 0x7c, 0xbf, 0xa0, 0xd7, 0x58, 0xdc, 0x8f, 0xfa, 0x72, 0xfa,
+       0xaa, 0x7f, 0x7c, 0x8c, 0x9e, 0x2d, 0xa2, 0xdf, 0x97, 0x29, 0x13, 0x82,
+       0x3e, 0x8a, 0x44, 0xd7, 0x49, 0xd2, 0xae, 0x95, 0x71, 0xe7, 0x63, 0xde,
+       0x3a, 0xce, 0x8a, 0x0b, 0x9c, 0xdc, 0xc2, 0xfa, 0x05, 0xb4, 0xf9, 0x3e,
+       0xf3, 0x5a, 0x14, 0x75, 0x69, 0x4a, 0xbf, 0xbd, 0xce, 0x3a, 0x07, 0x73,
+       0x86, 0xe3, 0x8d, 0x75, 0xda, 0x9a, 0xd2, 0x69, 0xb6, 0x4b, 0xa7, 0xa5,
+       0xcb, 0x3a, 0x8d, 0x79, 0x43, 0xe8, 0xb2, 0xa0, 0xa8, 0x8d, 0x4e, 0xab,
+       0xef, 0xc0, 0x87, 0xbb, 0x85, 0xee, 0x62, 0xdd, 0x3f, 0x84, 0x3d, 0xc8,
+       0x1c, 0xdf, 0x31, 0xa1, 0x43, 0x34, 0x7f, 0x3f, 0xbc, 0x4f, 0xca, 0x45,
+       0xab, 0xd0, 0x07, 0xe9, 0x29, 0xe8, 0x2d, 0xaf, 0xf6, 0x0f, 0x72, 0x3b,
+       0xb4, 0xb7, 0xc3, 0x2f, 0xb2, 0x3e, 0x5b, 0x8c, 0xc2, 0xa7, 0x6d, 0x53,
+       0xbe, 0x0f, 0xf6, 0x14, 0xc3, 0x5a, 0x17, 0xc6, 0xaa, 0xf5, 0x59, 0xb7,
+       0x8a, 0x6b, 0x20, 0x0e, 0x89, 0x39, 0x6f, 0x88, 0x11, 0x2c, 0x60, 0x04,
+       0xbe, 0x27, 0xc0, 0xf4, 0x82, 0x7e, 0x61, 0x3b, 0xf0, 0x2e, 0xad, 0x09,
+       0xd9, 0x78, 0x57, 0x60, 0x97, 0x0c, 0x5f, 0x9b, 0x19, 0x7d, 0x54, 0xf4,
+       0x33, 0xb3, 0x5c, 0xd1, 0x8f, 0x73, 0xd9, 0xf7, 0x60, 0x37, 0x44, 0x5f,
+       0x97, 0x86, 0xa4, 0x0e, 0x5c, 0x2c, 0x98, 0xd8, 0xe3, 0x0c, 0x7d, 0xe6,
+       0xbe, 0xea, 0x71, 0xa2, 0x1f, 0x5a, 0x1f, 0x6c, 0x45, 0xf6, 0x18, 0xd7,
+       0x76, 0x61, 0x8e, 0x1c, 0x17, 0x0f, 0x7d, 0x8f, 0xdf, 0x8f, 0x73, 0x9b,
+       0x8f, 0xe7, 0x76, 0x79, 0x3c, 0x88, 0xed, 0xe1, 0x9e, 0x77, 0xe9, 0x96,
+       0x1a, 0xcf, 0xad, 0xf2, 0x78, 0xbe, 0xab, 0xc6, 0x43, 0x69, 0x63, 0xbc,
+       0x5b, 0xe1, 0xfe, 0x2d, 0x3f, 0xbb, 0x35, 0xce, 0x38, 0x26, 0xbd, 0x0c,
+       0x3a, 0xdf, 0xa5, 0xf8, 0xc9, 0x1d, 0x47, 0x75, 0xf7, 0x35, 0x32, 0xbc,
+       0xce, 0xfa, 0xf7, 0xb6, 0xc0, 0x31, 0x7d, 0x8c, 0x63, 0x70, 0x9e, 0x32,
+       0xd0, 0xd3, 0xe9, 0x10, 0xf6, 0xe1, 0x1d, 0xe3, 0x71, 0xb3, 0x3f, 0x36,
+       0xca, 0x9f, 0x22, 0xbe, 0x26, 0xe2, 0xbe, 0xea, 0xfe, 0xaf, 0xd3, 0xed,
+       0x79, 0xe8, 0x72, 0xe0, 0x58, 0xb9, 0x57, 0xef, 0xed, 0x15, 0x19, 0xdf,
+       0x4d, 0x78, 0xc6, 0x77, 0x11, 0xdb, 0x1d, 0x05, 0xce, 0x37, 0x11, 0x07,
+       0x9e, 0x50, 0xbf, 0x5f, 0x92, 0x2e, 0xe2, 0x59, 0x5e, 0x7a, 0x69, 0xcc,
+       0x95, 0x1f, 0x87, 0xbc, 0x14, 0x87, 0xf5, 0x8c, 0x6d, 0x36, 0x19, 0x47,
+       0x65, 0x9c, 0xb9, 0xa8, 0xb1, 0xd3, 0x09, 0x9e, 0x33, 0x3b, 0x6a, 0x18,
+       0x09, 0x11, 0x6b, 0x68, 0xb5, 0xdb, 0xa8, 0x85, 0xed, 0xe8, 0x59, 0xc2,
+       0x3e, 0x70, 0x11, 0x0b, 0x6b, 0x00, 0x17, 0x98, 0x27, 0x33, 0xd1, 0x48,
+       0xf8, 0x51, 0xe1, 0x97, 0xc2, 0xbe, 0x18, 0xa0, 0x13, 0xd3, 0x1a, 0x7d,
+       0xe0, 0xef, 0xcb, 0xd8, 0x0b, 0x34, 0xca, 0xe3, 0x47, 0xfc, 0x78, 0xc0,
+       0x7a, 0x93, 0xed, 0xd2, 0x05, 0x11, 0x97, 0x79, 0x9a, 0xd2, 0x2c, 0xa7,
+       0xc7, 0x85, 0x9c, 0x1a, 0x7d, 0x2c, 0x45, 0x2c, 0x57, 0xc8, 0x43, 0x18,
+       0x44, 0x0c, 0x50, 0xf9, 0x3a, 0x3c, 0xca, 0x15, 0xb5, 0x57, 0x42, 0x12,
+       0xba, 0x63, 0xeb, 0x31, 0x89, 0xe4, 0xa7, 0x8e, 0xc5, 0xb8, 0x31, 0x59,
+       0xa3, 0xda, 0x51, 0xf8, 0x69, 0x2a, 0x9e, 0x88, 0xfc, 0xf8, 0xf2, 0x6f,
+       0xe9, 0xb8, 0xe3, 0x06, 0xe7, 0x44, 0x6e, 0xe8, 0xcb, 0x45, 0x69, 0x83,
+       0xd3, 0xec, 0xd3, 0x67, 0x8e, 0xb8, 0x31, 0x49, 0x24, 0x37, 0x21, 0x62,
+       0x39, 0xfb, 0x28, 0xbe, 0x30, 0x42, 0x0f, 0x64, 0xa1, 0xc3, 0x68, 0x3d,
+       0x6e, 0xe3, 0x57, 0x72, 0x20, 0xe3, 0x23, 0x94, 0x28, 0x82, 0x46, 0x3e,
+       0xc6, 0x4a, 0xcc, 0x7b, 0x39, 0xac, 0xef, 0xf3, 0xf7, 0x02, 0x7e, 0x1b,
+       0xe6, 0x0f, 0x54, 0xbc, 0xbc, 0x97, 0x26, 0x16, 0xc8, 0x49, 0x45, 0xef,
+       0x15, 0x7b, 0x79, 0xa7, 0xa2, 0x43, 0x2a, 0xb6, 0x13, 0xe6, 0xf3, 0x88,
+       0x97, 0x59, 0x74, 0x7f, 0x36, 0xe2, 0xa4, 0x48, 0xc6, 0x2c, 0x88, 0xfb,
+       0x60, 0xb0, 0xed, 0xdd, 0xcd, 0x3a, 0xe4, 0x94, 0x88, 0x5b, 0x30, 0x52,
+       0x99, 0x47, 0x7b, 0xc4, 0x1c, 0xba, 0x08, 0x7e, 0x5a, 0x2a, 0xf7, 0xaa,
+       0x6a, 0x5b, 0x22, 0x93, 0x79, 0xc1, 0xfc, 0x6d, 0xdb, 0x89, 0x1a, 0x95,
+       0xfb, 0x11, 0xf3, 0x38, 0x25, 0x70, 0x64, 0x1f, 0xfb, 0x3c, 0xa2, 0x5d,
+       0x69, 0x46, 0xc4, 0x2f, 0xf8, 0xb8, 0xf0, 0xc8, 0x7e, 0xa9, 0xdb, 0xe4,
+       0x79, 0x19, 0xd7, 0xe0, 0x67, 0x16, 0xb8, 0x1f, 0x55, 0xf9, 0xf4, 0xbd,
+       0x14, 0xdb, 0x46, 0x9c, 0x69, 0xea, 0x8e, 0xc6, 0x99, 0x98, 0xd6, 0xc5,
+       0xcd, 0x6a, 0x1a, 0xb4, 0xff, 0xf7, 0x91, 0xb6, 0xe1, 0x4c, 0x2b, 0x53,
+       0xfc, 0x16, 0x08, 0x30, 0x78, 0xa6, 0xf8, 0x3c, 0x7e, 0x03, 0xc7, 0x97,
+       0x14, 0xd8, 0x38, 0xcc, 0xd8, 0x06, 0x18, 0x67, 0x40, 0xac, 0x8b, 0xc5,
+       0x1e, 0x0a, 0xfb, 0x32, 0x2b, 0x3d, 0xe4, 0x47, 0x3c, 0xce, 0xd6, 0xb9,
+       0x1c, 0xad, 0x22, 0xef, 0x5d, 0xae, 0x47, 0xc2, 0x3e, 0x43, 0x27, 0xae,
+       0xb3, 0xdf, 0xf0, 0x90, 0xca, 0xb9, 0x41, 0xcd, 0xa6, 0xce, 0xb9, 0xd1,
+       0x3a, 0x45, 0xf3, 0x9e, 0x5e, 0xeb, 0x70, 0xff, 0xde, 0x18, 0x64, 0xd7,
+       0x8d, 0x29, 0x10, 0x9f, 0x12, 0x73, 0x74, 0x81, 0x48, 0xce, 0x71, 0x65,
+       0x1d, 0xa3, 0x85, 0xe7, 0x09, 0xfe, 0x20, 0xe2, 0x7e, 0x8f, 0xf0, 0x27,
+       0xd6, 0x23, 0x7e, 0xb4, 0x1f, 0x38, 0xaa, 0xd3, 0x66, 0x9e, 0x19, 0xc5,
+       0x71, 0x0f, 0xfb, 0x67, 0x1a, 0xf7, 0xca, 0x58, 0x14, 0xfb, 0x6c, 0x6a,
+       0xbe, 0x10, 0x87, 0xea, 0x97, 0x39, 0x4c, 0xd9, 0x08, 0x59, 0x5d, 0xa0,
+       0xd3, 0xaf, 0x4a, 0x1e, 0x37, 0x5b, 0xbb, 0xd8, 0x4a, 0x5e, 0x13, 0x7e,
+       0x0b, 0x0d, 0xfb, 0x8d, 0x1e, 0x04, 0xed, 0x79, 0x8e, 0xdc, 0x6b, 0x1b,
+       0xcf, 0xef, 0xd5, 0xbf, 0xc3, 0x74, 0x67, 0xe6, 0x6d, 0x87, 0xc7, 0xbc,
+       0x1d, 0xec, 0x95, 0x6b, 0x67, 0x7f, 0xa1, 0xda, 0x78, 0xe5, 0xb8, 0x3a,
+       0x4f, 0x22, 0x0e, 0x55, 0xa9, 0xbf, 0x78, 0x5b, 0xe8, 0x95, 0xfa, 0x58,
+       0x78, 0x98, 0xf5, 0xa9, 0x94, 0xe3, 0x53, 0x1e, 0x72, 0xdc, 0x35, 0x0e,
+       0xdc, 0xf2, 0xc9, 0xe5, 0x78, 0xb2, 0xa1, 0x1c, 0x4f, 0xf6, 0xca, 0x58,
+       0x6c, 0xbd, 0x1c, 0xbf, 0x81, 0xbe, 0x14, 0x37, 0xca, 0x81, 0x44, 0x4d,
+       0xbb, 0x3b, 0x56, 0x02, 0x9a, 0xe9, 0x78, 0x09, 0xd6, 0x0d, 0xc1, 0x97,
+       0x58, 0x7b, 0x99, 0x32, 0x12, 0xf3, 0xb5, 0x6b, 0xa9, 0x5b, 0xb9, 0x17,
+       0xeb, 0x34, 0xb5, 0xf7, 0x02, 0xbb, 0x43, 0x36, 0x22, 0x61, 0x19, 0x0b,
+       0xd0, 0xf4, 0xeb, 0xf5, 0x1d, 0xcb, 0x47, 0x9c, 0x02, 0x21, 0xd6, 0x1d,
+       0xa2, 0x73, 0x58, 0x9f, 0x56, 0xb1, 0xe4, 0x93, 0x59, 0x49, 0x07, 0xf3,
+       0x88, 0xe0, 0x0f, 0xe0, 0xdb, 0x70, 0xd2, 0x9f, 0xe4, 0x39, 0x96, 0x71,
+       0xe4, 0xd4, 0x72, 0x58, 0xcd, 0x1b, 0xb7, 0xc5, 0xf3, 0xaa, 0xf6, 0x92,
+       0xd7, 0x71, 0x07, 0xcc, 0x57, 0xe4, 0xeb, 0x95, 0xdc, 0x64, 0xd8, 0x86,
+       0x12, 0xfd, 0x37, 0xdb, 0x3d, 0xff, 0x11, 0x53, 0xec, 0xe3, 0xf0, 0x46,
+       0xf1, 0x08, 0xe3, 0x4d, 0xcc, 0x29, 0x62, 0x90, 0x3a, 0x46, 0xfc, 0xc4,
+       0x41, 0x6a, 0x3f, 0xcc, 0x28, 0xc0, 0x20, 0x9b, 0xf1, 0xa5, 0x71, 0x04,
+       0xb9, 0xe6, 0x16, 0xdf, 0x83, 0xfd, 0xa8, 0x06, 0xad, 0x04, 0xb5, 0x21,
+       0x0e, 0x81, 0xfd, 0xb0, 0xad, 0x74, 0x95, 0x8c, 0x9d, 0x16, 0x32, 0x96,
+       0x58, 0x39, 0xad, 0x64, 0xec, 0xb4, 0x8a, 0xc3, 0x9f, 0x56, 0x32, 0x76,
+       0x5a, 0xc9, 0xd8, 0x69, 0x25, 0x63, 0xa7, 0x99, 0xcf, 0x07, 0x18, 0xdf,
+       0x02, 0x8b, 0xe8, 0x38, 0x68, 0x3b, 0xa5, 0xf2, 0x38, 0x0f, 0xfb, 0x5c,
+       0x2b, 0x67, 0xef, 0xf6, 0x49, 0x39, 0x63, 0x6c, 0x22, 0xeb, 0xc9, 0xf8,
+       0x5d, 0x98, 0x83, 0x57, 0x98, 0xe6, 0x1f, 0xd3, 0x99, 0x79, 0xf4, 0xd5,
+       0x47, 0x13, 0x62, 0x1f, 0xdc, 0x26, 0x8a, 0xbb, 0xb1, 0xb0, 0xc9, 0x63,
+       0xcd, 0x4a, 0xdf, 0xcf, 0x31, 0x6c, 0xc1, 0x27, 0xde, 0x7a, 0x15, 0x7c,
+       0x32, 0xae, 0xe6, 0xab, 0xd6, 0x2f, 0x6a, 0xa1, 0x64, 0x0e, 0x74, 0x45,
+       0xfe, 0xa4, 0xc5, 0x73, 0x23, 0xe8, 0xe4, 0x98, 0x1e, 0x34, 0x38, 0xa9,
+       0x68, 0xf0, 0xb8, 0x18, 0x23, 0xf2, 0x0f, 0x11, 0xcb, 0x6c, 0x4c, 0x87,
+       0x74, 0x76, 0x80, 0x9f, 0xc3, 0xb2, 0x70, 0x24, 0xcc, 0x3a, 0x69, 0xeb,
+       0x74, 0xa8, 0x8c, 0xbd, 0x91, 0xee, 0xd9, 0x6a, 0x5d, 0xce, 0xba, 0xcb,
+       0x96, 0x84, 0x95, 0x1d, 0x91, 0xb8, 0x78, 0x87, 0x5d, 0xa2, 0x13, 0xd1,
+       0x83, 0xfc, 0x3d, 0x92, 0x74, 0xe8, 0x30, 0x19, 0x9d, 0x25, 0xfa, 0x11,
+       0xcb, 0x41, 0x2b, 0xcb, 0xc1, 0x09, 0xe5, 0x97, 0x9c, 0x28, 0xfb, 0x25,
+       0x93, 0x07, 0x90, 0x97, 0x91, 0x12, 0xeb, 0x5e, 0x3b, 0xcb, 0xbf, 0xc3,
+       0x02, 0x3d, 0xb6, 0x88, 0xfd, 0x28, 0x7a, 0x71, 0x6c, 0xd2, 0x55, 0xf6,
+       0xab, 0x63, 0xbe, 0x07, 0x0f, 0x08, 0xec, 0xee, 0x7b, 0x00, 0xf7, 0x9c,
+       0x90, 0x7a, 0xcf, 0x47, 0xfe, 0xc1, 0x77, 0x18, 0x4f, 0x94, 0xe8, 0x31,
+       0x7e, 0x67, 0x26, 0x77, 0x88, 0x9f, 0xad, 0xf7, 0x96, 0xb0, 0x63, 0x86,
+       0x6f, 0x27, 0xf9, 0x3b, 0x1b, 0xbd, 0x3b, 0x22, 0xf8, 0x91, 0xf1, 0xb4,
+       0x31, 0x13, 0x7d, 0xaf, 0x34, 0x3d, 0x85, 0x18, 0x3b, 0xe4, 0x24, 0x62,
+       0x5a, 0x3e, 0x2f, 0xf9, 0x90, 0x58, 0xa9, 0x92, 0x0b, 0x2b, 0xf3, 0xc2,
+       0xff, 0x8b, 0xc7, 0x66, 0x12, 0xd6, 0x4e, 0xe4, 0xf3, 0x93, 0x04, 0x9f,
+       0x00, 0xfb, 0x53, 0x58, 0x4c, 0x67, 0xfd, 0x2e, 0x5b, 0xf1, 0xc6, 0x67,
+       0x90, 0xe7, 0x96, 0x5b, 0xa4, 0x8d, 0x6d, 0x0e, 0xe2, 0x75, 0x03, 0x0b,
+       0x6b, 0x9d, 0x21, 0x51, 0x1b, 0xde, 0xc1, 0x18, 0x49, 0xe7, 0x3e, 0x0f,
+       0xf2, 0xf3, 0x11, 0xc7, 0x0b, 0xd0, 0xc4, 0x25, 0xb4, 0x6b, 0xa6, 0xfe,
+       0x85, 0xd2, 0xef, 0xf1, 0x75, 0xb1, 0x7e, 0x99, 0xa2, 0x56, 0xb5, 0x36,
+       0xa1, 0xf7, 0xad, 0x08, 0xb3, 0xec, 0x55, 0x6a, 0x9f, 0xfb, 0xcb, 0x31,
+       0x3d, 0x21, 0x13, 0x35, 0x31, 0xbd, 0xaf, 0x6e, 0x62, 0xaf, 0x36, 0x93,
+       0x03, 0xe4, 0xd4, 0xb5, 0x90, 0x8a, 0x55, 0x5a, 0x19, 0xda, 0x6a, 0x4d,
+       0xdf, 0x76, 0xef, 0xf1, 0xb5, 0x36, 0x8f, 0x93, 0xf3, 0xa6, 0x1d, 0x54,
+       0xfc, 0xd7, 0x4c, 0x67, 0xf2, 0x41, 0xb6, 0xf9, 0xd0, 0xad, 0xa0, 0x97,
+       0xbf, 0x17, 0xb5, 0x2e, 0x5f, 0x0a, 0x34, 0xd3, 0xf2, 0x32, 0x72, 0x2d,
+       0xfe, 0xf1, 0x80, 0xcc, 0x25, 0x4e, 0x32, 0x5d, 0x0e, 0xb3, 0x7d, 0x34,
+       0xd4, 0xda, 0x11, 0xce, 0x41, 0x97, 0x88, 0xdf, 0x21, 0x0a, 0xdc, 0x3b,
+       0x14, 0x64, 0xbf, 0x40, 0xae, 0x3d, 0x1c, 0xe5, 0x67, 0x7f, 0x33, 0x9f,
+       0x44, 0xbc, 0xcc, 0x3c, 0xce, 0xcf, 0x9f, 0x60, 0x3c, 0x11, 0xa3, 0x66,
+       0x5a, 0x5a, 0x6e, 0x66, 0xbf, 0xa0, 0x99, 0xf1, 0xc4, 0x80, 0xd9, 0xef,
+       0x13, 0xef, 0x12, 0x75, 0x35, 0x9f, 0x0f, 0x1c, 0x66, 0xbe, 0xc2, 0xbb,
+       0xfe, 0x5d, 0xbd, 0xab, 0xf6, 0x1d, 0xff, 0x51, 0xc2, 0xf1, 0x71, 0x3f,
+       0x39, 0x37, 0xf0, 0x1b, 0x5c, 0xf3, 0x63, 0x8c, 0x9d, 0x43, 0x94, 0x99,
+       0x6f, 0xe2, 0x31, 0x8c, 0xb3, 0x1f, 0x11, 0xe5, 0xe3, 0xfb, 0xc8, 0x29,
+       0x4e, 0xd1, 0x5f, 0x15, 0xdd, 0x31, 0xe1, 0xfb, 0xb8, 0xcf, 0xb2, 0xb6,
+       0xbf, 0x85, 0xfb, 0xf5, 0x91, 0x5d, 0xab, 0x63, 0x82, 0xe4, 0xff, 0xeb,
+       0x10, 0x35, 0x7f, 0x0d, 0xb1, 0x97, 0x12, 0xe5, 0xa2, 0xa8, 0x57, 0x90,
+       0xf1, 0xe7, 0xab, 0x22, 0x87, 0x96, 0xef, 0xe7, 0x67, 0xce, 0xa1, 0xdd,
+       0x55, 0x8b, 0xae, 0xdb, 0x92, 0xde, 0x3f, 0x08, 0x84, 0xc8, 0xff, 0x12,
+       0x72, 0x9f, 0xc4, 0xfe, 0x1a, 0x8e, 0x7d, 0x88, 0xf5, 0xfb, 0xd7, 0x70,
+       0x1f, 0x7f, 0xbe, 0x84, 0xe3, 0x20, 0x8f, 0x13, 0xf6, 0x1a, 0xf9, 0x2e,
+       0xd0, 0x8b, 0x87, 0xc3, 0xa6, 0xe0, 0xbf, 0xfb, 0x98, 0xa7, 0x9a, 0x44,
+       0xac, 0xb1, 0x0b, 0x6d, 0xed, 0xfd, 0xc0, 0x16, 0xce, 0xd0, 0x21, 0x1c,
+       0xc7, 0x3a, 0xfd, 0x4c, 0x23, 0xc9, 0x43, 0x18, 0x4f, 0x15, 0x73, 0x07,
+       0x8e, 0x0e, 0x11, 0xcf, 0x27, 0xf0, 0xc7, 0x2f, 0xf1, 0x1b, 0x91, 0x4e,
+       0x3f, 0xbf, 0x23, 0xc1, 0xef, 0x98, 0xc8, 0xcb, 0x71, 0xcf, 0x15, 0xfd,
+       0x24, 0xe3, 0x54, 0x5f, 0xe9, 0xd3, 0xbf, 0xd1, 0x48, 0x3d, 0x78, 0x76,
+       0x59, 0x56, 0xf8, 0x7b, 0x3b, 0xdd, 0xca, 0xb7, 0xd1, 0x6d, 0xb5, 0xa6,
+       0x75, 0x4b, 0xf8, 0x65, 0xac, 0xc3, 0x93, 0xed, 0xb4, 0xbe, 0xdc, 0x44,
+       0xd4, 0x15, 0x14, 0x6b, 0xce, 0xb7, 0xf2, 0x05, 0x7e, 0xff, 0x97, 0xfb,
+       0x64, 0x5c, 0xa7, 0xc2, 0x23, 0xb7, 0x3c, 0x78, 0xe4, 0x03, 0xc1, 0x23,
+       0x5f, 0xec, 0xdb, 0x98, 0x47, 0x50, 0xf3, 0x0f, 0xde, 0x08, 0x52, 0xb3,
+       0xe2, 0x8f, 0x17, 0x99, 0x3f, 0x9e, 0x65, 0xfe, 0x38, 0xd6, 0x80, 0x3f,
+       0x8c, 0x1a, 0xfe, 0x38, 0x2e, 0xf8, 0xe3, 0x89, 0xbe, 0x8d, 0xf8, 0xe3,
+       0x98, 0x7f, 0xa3, 0x58, 0x93, 0xaf, 0x35, 0xc0, 0xef, 0x9e, 0xb3, 0xf7,
+       0x31, 0xaf, 0xdb, 0xb4, 0x34, 0x8f, 0xfa, 0x84, 0xd5, 0xa8, 0x41, 0x3f,
+       0x13, 0x3e, 0xd9, 0x9a, 0xf0, 0xf9, 0xc7, 0x45, 0xcd, 0xc1, 0xa2, 0xe0,
+       0x2f, 0xb6, 0xff, 0xe3, 0xa8, 0xab, 0xaa, 0x9d, 0x8b, 0x56, 0xba, 0x1e,
+       0xc5, 0x5c, 0x58, 0x7a, 0x2e, 0x08, 0xeb, 0xbb, 0x6a, 0xef, 0xc8, 0x40,
+       0x3c, 0x4b, 0xce, 0x07, 0xe0, 0xd1, 0x95, 0xb6, 0xc0, 0x44, 0xf6, 0x1b,
+       0x7d, 0xc0, 0x7f, 0x99, 0x15, 0x72, 0x9d, 0x0f, 0xf0, 0xf9, 0x90, 0xf8,
+       0x6d, 0x2b, 0xc8, 0xca, 0x87, 0xc8, 0x71, 0x64, 0x9e, 0xbc, 0x9e, 0xef,
+       0xa5, 0x1b, 0xf9, 0x7d, 0xb4, 0x96, 0xef, 0xa3, 0x37, 0xc5, 0xbe, 0x1a,
+       0xb2, 0x36, 0x72, 0x4d, 0xcc, 0x91, 0x41, 0x47, 0x43, 0xdc, 0x66, 0x79,
+       0x1f, 0xad, 0x2e, 0x6b, 0xfe, 0x06, 0x6f, 0x83, 0x5f, 0x62, 0x9d, 0xb2,
+       0x66, 0xae, 0x9e, 0x67, 0x26, 0xaa, 0x79, 0x46, 0xdc, 0x03, 0x5e, 0xc9,
+       0xd4, 0xd5, 0xfa, 0x22, 0x5f, 0x11, 0xb9, 0x7a, 0x41, 0x6a, 0x42, 0xde,
+       0xa2, 0x11, 0x19, 0x3e, 0xea, 0x07, 0x86, 0xce, 0xb1, 0xcd, 0xe5, 0x39,
+       0xb3, 0x91, 0xe7, 0xd4, 0xc7, 0x78, 0xb8, 0x43, 0xe0, 0xdf, 0xb8, 0x1d,
+       0x08, 0x4f, 0x50, 0xe9, 0x69, 0xc3, 0xc6, 0x5e, 0x8f, 0x49, 0x7e, 0x9e,
+       0xa1, 0xe2, 0x4d, 0xbb, 0x5c, 0xfc, 0x57, 0x8b, 0x75, 0xb1, 0x96, 0xfc,
+       0x10, 0xf7, 0x19, 0x76, 0xb8, 0xb2, 0x5e, 0x43, 0xe5, 0xf5, 0x9a, 0x56,
+       0x1e, 0xb7, 0x94, 0xbd, 0x19, 0x9b, 0xdb, 0x15, 0xff, 0x6f, 0x40, 0x75,
+       0xeb, 0x41, 0x73, 0x7f, 0x40, 0xf1, 0x25, 0xa0, 0x79, 0x67, 0x19, 0x86,
+       0x43, 0x3d, 0xa0, 0x3c, 0x0a, 0x1a, 0x0f, 0x41, 0xcc, 0xf5, 0x1e, 0x5a,
+       0x03, 0x12, 0x07, 0x8d, 0x89, 0x20, 0xe6, 0x7a, 0x0f, 0x41, 0xe7, 0x7a,
+       0x0f, 0xad, 0xb1, 0x01, 0x97, 0xdb, 0xcd, 0x53, 0x80, 0xe1, 0x3e, 0x85,
+       0x19, 0xba, 0xce, 0x51, 0x0d, 0x7a, 0x77, 0x52, 0x0c, 0x78, 0x4c, 0x5b,
+       0x50, 0x05, 0x7f, 0x18, 0xba, 0x62, 0x84, 0xa1, 0x0d, 0xb8, 0x9d, 0xe5,
+       0x02, 0x34, 0xd3, 0x79, 0x4a, 0x0c, 0x30, 0x3c, 0x23, 0x80, 0x79, 0x4f,
+       0x18, 0x9a, 0xf7, 0x60, 0x73, 0xc7, 0xfc, 0x0c, 0x90, 0x7b, 0x98, 0x6c,
+       0xc0, 0x7d, 0x0b, 0x48, 0x79, 0x25, 0x83, 0x56, 0x5e, 0x01, 0xd3, 0x84,
+       0x3a, 0x44, 0x7f, 0xd3, 0x7a, 0x0d, 0x79, 0xd8, 0x38, 0x60, 0x13, 0xd0,
+       0xdc, 0xe6, 0x29, 0xa4, 0xcc, 0x3d, 0x03, 0xeb, 0x5b, 0xac, 0x6b, 0x1b,
+       0x6d, 0xc0, 0x7b, 0xac, 0x17, 0x4d, 0x61, 0x61, 0x58, 0xd2, 0xc3, 0x00,
+       0xac, 0x1f, 0x40, 0x69, 0x1d, 0x54, 0x47, 0xc0, 0xd3, 0xbb, 0x40, 0x13,
+       0xd0, 0x7d, 0x4e, 0xc0, 0xb6, 0xa8, 0x73, 0xbf, 0x32, 0x78, 0xad, 0x6c,
+       0x03, 0xf4, 0xfc, 0xaa, 0x45, 0x3d, 0xde, 0xf2, 0xa0, 0x7c, 0xe6, 0xa4,
+       0xc2, 0x40, 0x46, 0x5e, 0x60, 0x83, 0xe6, 0x05, 0x70, 0x38, 0x01, 0xd3,
+       0x3a, 0xb0, 0x8c, 0x5a, 0x93, 0x04, 0x34, 0x8f, 0x87, 0xc5, 0xa5, 0x1f,
+       0x24, 0xc6, 0x00, 0x15, 0x63, 0x01, 0xf2, 0x65, 0x80, 0x6d, 0x4a, 0x90,
+       0x5f, 0x41, 0x79, 0x01, 0x64, 0x36, 0xc8, 0xef, 0xa0, 0xb2, 0x13, 0x94,
+       0x17, 0x81, 0xec, 0x25, 0x42, 0x50, 0x3f, 0x03, 0x69, 0x20, 0xbb, 0x79,
+       0x8a, 0x08, 0x98, 0x9f, 0x14, 0x20, 0xc4, 0xd0, 0x00, 0xcf, 0x07, 0xc4,
+       0x86, 0x31, 0x4c, 0x7d, 0x0c, 0x19, 0xf9, 0x06, 0x62, 0x06, 0x22, 0xdf,
+       0xb0, 0x33, 0x1c, 0x10, 0x80, 0x85, 0xd5, 0xff, 0xff, 0xc7, 0x54, 0x58,
+       0x80, 0xe9, 0x14, 0xb4, 0x8e, 0xf5, 0xf7, 0xff, 0x03, 0x22, 0x2c, 0x0c,
+       0x2d, 0xf0, 0xf5, 0x88, 0x0b, 0xe5, 0x41, 0x65, 0xe8, 0x02, 0x20, 0xab,
+       0x0d, 0xde, 0x26, 0x60, 0x01, 0xdf, 0x61, 0xbd, 0x80, 0xe1, 0x17, 0xb0,
+       0xcc, 0xfa, 0xff, 0x7f, 0x29, 0x5c, 0x2d, 0x08, 0x00, 0x00, 0xff, 0x88,
+       0x78, 0xb5, 0x98, 0x7e, 0x00, 0x00, 0x00 };
 
 static const u32 bnx2_COM_b09FwData[(0x0/4) + 1] = { 0x0 };
 static const u32 bnx2_COM_b09FwRodata[(0x88/4) + 1] = {
-       0x08001b68, 0x08001ba4, 0x08001ba4, 0x08001ba4, 0x08001ba4, 0x08001ba4,
-       0x08001ab4, 0x08001ba4, 0x08001b28, 0x08001ba4, 0x08001a3c, 0x08001ba4,
-       0x08001ba4, 0x08001ba4, 0x08001a48, 0x00000000, 0x08002abc, 0x08002b0c,
-       0x08002b3c, 0x08002b6c, 0x08002b9c, 0x00000000, 0x0800604c, 0x0800604c,
-       0x0800604c, 0x0800604c, 0x0800604c, 0x08006078, 0x08006078, 0x080060b8,
-       0x080060c4, 0x080060c4, 0x0800604c, 0x00000000, 0x00000000 };
+       0x08001b7c, 0x08001bb8, 0x08001bb8, 0x08001bb8, 0x08001bb8, 0x08001bb8,
+       0x08001ac8, 0x08001bb8, 0x08001b3c, 0x08001bb8, 0x08001a50, 0x08001bb8,
+       0x08001bb8, 0x08001bb8, 0x08001a5c, 0x00000000, 0x08002b74, 0x08002bc4,
+       0x08002bf4, 0x08002c24, 0x08002c58, 0x00000000, 0x08006120, 0x08006120,
+       0x08006120, 0x08006120, 0x08006120, 0x0800614c, 0x0800614c, 0x0800618c,
+       0x08006198, 0x08006198, 0x08006120, 0x00000000, 0x00000000 };
 
 static struct fw_info bnx2_com_fw_09 = {
+       /* Firmware version:  3.7.1 */
        .ver_major                      = 0x3,
-       .ver_minor                      = 0x4,
-       .ver_fix                        = 0x3,
+       .ver_minor                      = 0x7,
+       .ver_fix                        = 0x1,
 
        .start_addr                     = 0x080000b4,
 
        .text_addr                      = 0x08000000,
-       .text_len                       = 0x7dc0,
+       .text_len                       = 0x7e94,
        .text_index                     = 0x0,
        .gz_text                        = bnx2_COM_b09FwText,
        .gz_text_len                    = sizeof(bnx2_COM_b09FwText),
 
-       .data_addr                      = 0x08007e60,
+       .data_addr                      = 0x08007f40,
        .data_len                       = 0x0,
        .data_index                     = 0x0,
        .data                           = bnx2_COM_b09FwData,
 
-       .sbss_addr                      = 0x08007e60,
+       .sbss_addr                      = 0x08007f40,
        .sbss_len                       = 0x60,
        .sbss_index                     = 0x0,
 
-       .bss_addr                       = 0x08007ec0,
+       .bss_addr                       = 0x08007fa0,
        .bss_len                        = 0x88,
        .bss_index                      = 0x0,
 
-       .rodata_addr                    = 0x08007dc0,
+       .rodata_addr                    = 0x08007e98,
        .rodata_len                     = 0x88,
        .rodata_index                   = 0x0,
        .rodata                         = bnx2_COM_b09FwRodata,
 };
 
 static u8 bnx2_CP_b09FwText[] = {
-/*     0x1f, 0x8b, 0x08, 0x00, 0x0f, 0x34, 0xe7, 0x45, 0x00, 0x03, */
-                                                                   0xbd, 0x7d,
-       0x0d, 0x74, 0x5c, 0x57, 0x7d, 0xe7, 0xff, 0xdd, 0x19, 0x49, 0x63, 0x59,
-       0x96, 0x9f, 0xe5, 0x89, 0x32, 0x51, 0x84, 0x3d, 0x23, 0x3d, 0xd9, 0x22,
-       0x12, 0xe1, 0xc5, 0x11, 0xac, 0xda, 0x2a, 0xe9, 0x30, 0x92, 0x3f, 0x12,
-       0x02, 0xab, 0x10, 0x43, 0xb3, 0x1c, 0x4a, 0xc5, 0x48, 0x4e, 0x02, 0x04,
-       0xea, 0x40, 0xe8, 0x86, 0xdd, 0xec, 0x66, 0x32, 0x92, 0x3f, 0x9a, 0x8e,
-       0x3d, 0x93, 0x44, 0x89, 0xbd, 0xdd, 0x9c, 0xad, 0x90, 0x14, 0x3b, 0x74,
-       0x07, 0x4f, 0xe2, 0x98, 0x96, 0x73, 0x0a, 0x8d, 0x50, 0x8c, 0x9b, 0xe6,
-       0xb0, 0xdd, 0xd0, 0xa6, 0x34, 0xdb, 0x86, 0x22, 0x8c, 0x81, 0xf4, 0x2c,
-       0xdd, 0x86, 0x42, 0x77, 0xd3, 0x36, 0xe5, 0xed, 0xef, 0x77, 0xef, 0x7d,
-       0x9a, 0x91, 0x34, 0xce, 0x07, 0xdd, 0xad, 0xcf, 0x79, 0x7e, 0xf3, 0xee,
-       0xbb, 0x1f, 0xff, 0xfb, 0xbf, 0xff, 0xef, 0xfb, 0xbf, 0x4f, 0x97, 0x8b,
-       0x34, 0x8b, 0xfd, 0xb7, 0x01, 0xd7, 0xd5, 0xc9, 0xfd, 0xe3, 0x57, 0x5f,
-       0x39, 0x70, 0x25, 0x9f, 0xa3, 0x91, 0x68, 0x44, 0xde, 0xc4, 0xbf, 0xe4,
-       0x1b, 0xa8, 0x83, 0x0e, 0xdd, 0x70, 0x2c, 0x5e, 0x12, 0x53, 0x43, 0xde,
-       0xfe, 0x8c, 0x27, 0xb1, 0xc8, 0x50, 0xee, 0xce, 0x71, 0x4f, 0x24, 0x5d,
-       0xee, 0x4b, 0x0e, 0xcb, 0x3f, 0x05, 0xb9, 0x78, 0x54, 0x58, 0xfe, 0x96,
-       0xa1, 0x57, 0x7f, 0xeb, 0x2b, 0xff, 0x2a, 0xf5, 0xf2, 0x4c, 0x44, 0x62,
-       0xee, 0xd0, 0xed, 0xe2, 0x6e, 0x93, 0x58, 0xe7, 0x50, 0x72, 0xff, 0x23,
-       0xdb, 0x97, 0x44, 0x5a, 0xc3, 0xbe, 0x5e, 0x0a, 0xbe, 0xb2, 0x5d, 0x72,
-       0x1d, 0x43, 0x89, 0xb1, 0x86, 0x21, 0x57, 0x9e, 0xaa, 0xc8, 0xe8, 0x89,
-       0xc2, 0xcb, 0x41, 0x74, 0x28, 0x88, 0x4c, 0x0d, 0x38, 0x12, 0x19, 0x92,
-       0xb3, 0xe3, 0x03, 0xf7, 0x04, 0xca, 0xf3, 0xfc, 0x45, 0x69, 0x19, 0x3c,
-       0x37, 0x80, 0xf7, 0x65, 0x41, 0xdd, 0xbd, 0xd7, 0x9c, 0x28, 0xc4, 0x44,
-       0x0d, 0xf5, 0xbc, 0x90, 0x89, 0x5c, 0x25, 0x7c, 0x7f, 0x56, 0x7a, 0xfc,
-       0xa7, 0x05, 0xe5, 0xe5, 0x98, 0x64, 0x2a, 0xd2, 0x82, 0x32, 0xdc, 0x9b,
-       0x51, 0x27, 0xe5, 0x66, 0x22, 0xae, 0xe4, 0x2b, 0x3f, 0x5e, 0x67, 0xc6,
-       0x9d, 0xb3, 0xf7, 0xbf, 0x8e, 0x99, 0x3b, 0xc6, 0x2d, 0xc6, 0x64, 0x29,
-       0x92, 0x10, 0xc0, 0x82, 0x79, 0x25, 0x64, 0xb2, 0x98, 0x94, 0x4c, 0x81,
-       0xb0, 0x45, 0x25, 0xeb, 0x12, 0xae, 0x04, 0xda, 0xb7, 0x39, 0xf5, 0xeb,
-       0xb3, 0xee, 0x0b, 0xa8, 0x9b, 0x44, 0xbd, 0x4e, 0x79, 0x12, 0x75, 0x4f,
-       0x57, 0xe2, 0xf2, 0x44, 0xe5, 0x57, 0x25, 0x8d, 0xb6, 0x8f, 0x57, 0x30,
-       0x76, 0xb1, 0x51, 0x86, 0xa7, 0x9b, 0x25, 0x33, 0xdd, 0x9d, 0xc8, 0x4a,
-       0x10, 0x7c, 0xda, 0xff, 0xa8, 0x8c, 0xb5, 0xa1, 0x7e, 0x91, 0xef, 0x12,
-       0x2b, 0xde, 0x65, 0xfd, 0x3e, 0x37, 0xab, 0x1c, 0x49, 0xef, 0x4d, 0x25,
-       0xc6, 0x14, 0x9f, 0x1b, 0x24, 0xd3, 0x8f, 0xe7, 0xd1, 0xa8, 0x44, 0xbc,
-       0x20, 0xb8, 0xc3, 0xbf, 0x0c, 0x70, 0xa4, 0x92, 0x49, 0xc5, 0xb6, 0x6c,
-       0x97, 0xca, 0x25, 0x55, 0x5c, 0x72, 0x95, 0x2b, 0x25, 0xd9, 0x16, 0x04,
-       0xef, 0xf3, 0x3b, 0x51, 0x2e, 0x32, 0x5c, 0x90, 0xfd, 0x58, 0x23, 0xf4,
-       0x29, 0xbe, 0x1a, 0xda, 0x8c, 0x79, 0xf4, 0xb9, 0xc3, 0xd2, 0x28, 0xe9,
-       0xb8, 0xa4, 0xd5, 0x90, 0x24, 0xd5, 0xd0, 0x3a, 0x94, 0x39, 0xd2, 0xe0,
-       0x7d, 0xc1, 0xd2, 0xd2, 0x46, 0x3c, 0xcb, 0xa8, 0x1a, 0x6a, 0x5b, 0x55,
-       0x9e, 0x4a, 0x8a, 0x5a, 0x07, 0x5c, 0xa5, 0x7a, 0xd3, 0x8a, 0x65, 0xb8,
-       0xeb, 0xb2, 0x0f, 0x36, 0xad, 0x2d, 0xdb, 0xef, 0xac, 0x2c, 0xbb, 0xbd,
-       0x85, 0xb0, 0x8a, 0xe2, 0xef, 0xb8, 0x9e, 0x6b, 0x3a, 0xde, 0xed, 0x36,
-       0x60, 0x5e, 0xa3, 0x7e, 0xca, 0xdd, 0xa9, 0x9e, 0x0f, 0xa4, 0x9d, 0x30,
-       0xf3, 0x9d, 0xc2, 0x3b, 0x54, 0x1d, 0xf2, 0xb1, 0x6e, 0xae, 0x1c, 0xc2,
-       0xdc, 0xce, 0x4f, 0xa7, 0xdc, 0x2e, 0x85, 0xfb, 0x3c, 0x7f, 0x07, 0x41,
-       0xc6, 0xcf, 0xe9, 0x35, 0xfd, 0xee, 0x74, 0x02, 0xcf, 0x80, 0x3f, 0x9e,
-       0x4e, 0x6d, 0x92, 0xab, 0xed, 0xba, 0x7c, 0x13, 0x63, 0x76, 0xbb, 0x77,
-       0xa8, 0x6e, 0xd7, 0x57, 0x29, 0x77, 0x56, 0xce, 0xe0, 0x39, 0x08, 0x6e,
-       0xf4, 0x53, 0x89, 0x1c, 0xd6, 0xec, 0x42, 0x21, 0x2e, 0xdf, 0x2b, 0xa4,
-       0x40, 0xc5, 0xa9, 0xde, 0x39, 0xe9, 0xf3, 0xe7, 0x00, 0x6f, 0x1e, 0xd7,
-       0x41, 0xbe, 0x2b, 0xe3, 0x5d, 0x99, 0x6d, 0x83, 0xe0, 0x26, 0xff, 0x37,
-       0x83, 0xb1, 0x76, 0xc3, 0x17, 0x4f, 0x15, 0xb1, 0x9e, 0x80, 0xf9, 0x74,
-       0x11, 0xeb, 0x89, 0xb5, 0x7a, 0x5c, 0xaf, 0x7b, 0x2f, 0xd6, 0x9d, 0xb4,
-       0x41, 0xba, 0xd8, 0x61, 0x69, 0xf9, 0x03, 0xf6, 0x2e, 0x92, 0x29, 0x3a,
-       0x92, 0xf1, 0xff, 0x31, 0x48, 0x6b, 0x7e, 0x11, 0x67, 0xb8, 0x48, 0x5a,
-       0x6c, 0x00, 0xac, 0x7c, 0xcc, 0xda, 0x7a, 0x1b, 0x1d, 0xe0, 0x96, 0xeb,
-       0xc0, 0xf7, 0x31, 0xe5, 0x35, 0xd9, 0xf7, 0x21, 0x5f, 0xf0, 0xdf, 0x26,
-       0x47, 0xbc, 0x6a, 0xbd, 0x0c, 0x69, 0xb2, 0x92, 0x93, 0xec, 0x83, 0x81,
-       0x0c, 0xfb, 0xc0, 0x13, 0xfb, 0x74, 0x7d, 0xd1, 0x6d, 0x5d, 0xd6, 0xd1,
-       0x75, 0xf1, 0x6f, 0x7d, 0x23, 0xc6, 0x70, 0x46, 0x8a, 0xd5, 0xb6, 0x23,
-       0xc5, 0xfc, 0x66, 0x0b, 0x1f, 0x9e, 0x07, 0x9d, 0x4c, 0xe5, 0x82, 0x5d,
-       0xdb, 0x70, 0x1e, 0x57, 0xd7, 0xa1, 0x6d, 0x17, 0x7c, 0xe0, 0x4a, 0xb6,
-       0x30, 0x88, 0x71, 0xe3, 0xb8, 0x07, 0xc1, 0x94, 0x9f, 0x4e, 0x45, 0x65,
-       0x08, 0xcf, 0xa3, 0xe4, 0x3d, 0xe0, 0x4f, 0xa2, 0x99, 0xed, 0xbe, 0x8c,
-       0x80, 0xee, 0xf3, 0x95, 0xd7, 0x97, 0x22, 0x7a, 0x0e, 0xfe, 0x3f, 0x59,
-       0xdc, 0x70, 0x1c, 0x33, 0xe6, 0x54, 0xb1, 0x43, 0xf2, 0xd3, 0x9e, 0x4c,
-       0x16, 0x16, 0x7a, 0x95, 0xbc, 0x4c, 0x7e, 0xc7, 0xfa, 0xa5, 0x40, 0xbb,
-       0x43, 0x32, 0x5c, 0xf1, 0x24, 0x5f, 0xc0, 0xbd, 0xd8, 0x0d, 0xfa, 0x8d,
-       0x4a, 0x3a, 0x61, 0xd6, 0x26, 0x5f, 0x18, 0xc1, 0xfc, 0x80, 0x6b, 0x8f,
-       0xbf, 0x07, 0x2d, 0x4c, 0xae, 0x64, 0x06, 0x48, 0x3f, 0x6f, 0x06, 0x96,
-       0x98, 0xcc, 0xfa, 0xe0, 0x0b, 0xd7, 0xc0, 0x92, 0x2f, 0xc6, 0xa2, 0xc3,
-       0x98, 0xf7, 0x70, 0xf9, 0x57, 0xd0, 0x7f, 0x8b, 0xfe, 0x0d, 0x7e, 0xb2,
-       0x65, 0x51, 0xdc, 0xe3, 0xb8, 0x13, 0xe6, 0x90, 0x56, 0x21, 0x1b, 0xa6,
-       0x3b, 0x65, 0x12, 0xb4, 0x3a, 0x2c, 0xf8, 0x3d, 0xcf, 0xb9, 0x10, 0xae,
-       0x0e, 0xfd, 0x7b, 0x72, 0x7a, 0x8b, 0x7e, 0xce, 0x8e, 0x76, 0x48, 0x6e,
-       0x3e, 0x9c, 0x33, 0xe5, 0x05, 0x65, 0x44, 0xea, 0xb0, 0x08, 0x65, 0x46,
-       0x10, 0x3c, 0xe8, 0x53, 0x6e, 0x04, 0xc1, 0x69, 0x9f, 0x72, 0xe4, 0x0c,
-       0xe4, 0x03, 0x65, 0x07, 0x79, 0xd9, 0x53, 0x5c, 0xab, 0x4c, 0xa1, 0x17,
-       0xeb, 0xd1, 0x28, 0xd9, 0xfe, 0xe3, 0x84, 0x15, 0x72, 0xe7, 0xa5, 0x4f,
-       0x66, 0xbc, 0x5c, 0x22, 0xa2, 0xf1, 0x04, 0xca, 0x82, 0x3c, 0x4c, 0xeb,
-       0x99, 0x75, 0x49, 0xbe, 0xbf, 0x64, 0xeb, 0xc8, 0xaf, 0xb2, 0x4e, 0x74,
-       0x4d, 0x9d, 0x7f, 0xa7, 0x0c, 0x5f, 0xf6, 0x62, 0xdd, 0x3a, 0x14, 0xf1,
-       0xd8, 0xb5, 0x8d, 0xcf, 0x12, 0x6b, 0x18, 0xfa, 0x3d, 0xbc, 0x7b, 0xee,
-       0x53, 0x8f, 0x7a, 0xf5, 0xde, 0xfd, 0x28, 0xba, 0xf6, 0xdd, 0x94, 0x44,
-       0xbd, 0x54, 0xef, 0x8d, 0xea, 0x4f, 0x1a, 0xa4, 0x35, 0x08, 0x1e, 0xf5,
-       0xc3, 0xf2, 0xc6, 0x86, 0xb5, 0x63, 0x5c, 0x55, 0xa7, 0xec, 0x68, 0x9d,
-       0xb2, 0xcf, 0xd7, 0x29, 0x7b, 0x7b, 0xe3, 0xda, 0xb2, 0xdb, 0xeb, 0x94,
-       0xcd, 0xd6, 0x29, 0xfb, 0x69, 0x9d, 0x32, 0x69, 0x5a, 0x5b, 0x16, 0xa9,
-       0x53, 0xd6, 0x57, 0xa7, 0x2c, 0x0a, 0xbe, 0xdb, 0x26, 0xf9, 0xf8, 0xbd,
-       0x9c, 0xbb, 0xc5, 0x4d, 0x29, 0xb2, 0x16, 0x37, 0x0d, 0xa8, 0xd7, 0xb9,
-       0xaa, 0xde, 0x17, 0xeb, 0xd4, 0x6b, 0x44, 0xbd, 0xb6, 0x55, 0xf5, 0x76,
-       0xd4, 0xc1, 0x75, 0x13, 0xea, 0xc5, 0x56, 0xd5, 0x7b, 0xb0, 0x4e, 0x3d,
-       0x96, 0x7f, 0xc6, 0x8e, 0xd3, 0x07, 0x2d, 0xf4, 0x5a, 0xeb, 0xd5, 0x28,
-       0xd2, 0xce, 0xf2, 0x5e, 0xe8, 0x90, 0x0e, 0x65, 0xe4, 0x02, 0x65, 0x10,
-       0xcb, 0x3a, 0x41, 0xe7, 0x71, 0xd0, 0x1d, 0xe5, 0x28, 0xf8, 0x8c, 0x73,
-       0xa9, 0x6c, 0x90, 0xb1, 0x78, 0x9f, 0x7b, 0xb5, 0x6a, 0x01, 0x8d, 0xa5,
-       0xdc, 0xa4, 0x22, 0xff, 0x49, 0x2e, 0x32, 0xe4, 0xe5, 0x86, 0x45, 0xc5,
-       0x95, 0x04, 0x32, 0xe2, 0xab, 0x36, 0x25, 0xf7, 0x80, 0xbf, 0xd2, 0xd0,
-       0x59, 0x37, 0x06, 0xc3, 0x9a, 0xb7, 0x4c, 0xdd, 0x8b, 0xcb, 0x54, 0x5f,
-       0x0e, 0x52, 0x16, 0x0e, 0x8d, 0x7e, 0x2a, 0xe3, 0x2d, 0x0c, 0x36, 0x82,
-       0x66, 0xcf, 0xa3, 0xcd, 0x6e, 0xb4, 0xdc, 0x57, 0x8e, 0xca, 0x48, 0x79,
-       0x00, 0xbc, 0xe0, 0xc8, 0x39, 0x6f, 0xa3, 0x9c, 0xf3, 0x51, 0xb7, 0x12,
-       0x91, 0xc5, 0xb8, 0x23, 0x8b, 0x78, 0xce, 0xf8, 0x78, 0x57, 0x09, 0x79,
-       0x6b, 0x40, 0x0e, 0x14, 0x7d, 0x39, 0x5c, 0xbc, 0x41, 0x85, 0x7a, 0x6d,
-       0xa7, 0xbf, 0x5e, 0x1e, 0x73, 0x4d, 0xdf, 0xbb, 0xbd, 0x05, 0x68, 0xd4,
-       0xa8, 0x9c, 0xf7, 0x52, 0x89, 0x45, 0xcd, 0x13, 0xff, 0x27, 0x18, 0x41,
-       0x3f, 0xb3, 0x5e, 0xca, 0xfd, 0x03, 0x3c, 0x8f, 0x95, 0x69, 0xcb, 0x54,
-       0xfb, 0x9a, 0x44, 0x5f, 0x87, 0x8a, 0x1b, 0xe4, 0x56, 0xdb, 0x7e, 0x97,
-       0xb7, 0xd0, 0x0b, 0x9e, 0x73, 0x4f, 0x50, 0x86, 0x14, 0x00, 0xd7, 0x5e,
-       0xf0, 0x36, 0xda, 0x7e, 0x4d, 0xcb, 0x33, 0xd8, 0x3e, 0x85, 0x8d, 0x90,
-       0xcf, 0x7f, 0x17, 0xdc, 0x1a, 0x67, 0x7d, 0x96, 0x51, 0xe7, 0x48, 0x49,
-       0x0d, 0x41, 0x26, 0x0c, 0x50, 0x66, 0x26, 0x21, 0x2f, 0x21, 0x7b, 0x8a,
-       0x3f, 0x0d, 0xd2, 0xd1, 0x5a, 0x39, 0x28, 0xb9, 0x6a, 0x1d, 0x96, 0x25,
-       0x8d, 0x5c, 0x2d, 0x2e, 0x2d, 0xcb, 0x8a, 0x1c, 0xe4, 0xcb, 0x53, 0x15,
-       0xca, 0x85, 0x0f, 0x82, 0x47, 0x3b, 0x65, 0xa4, 0x90, 0xca, 0xa5, 0x65,
-       0x1b, 0xd6, 0xef, 0xd7, 0xb1, 0xa6, 0x51, 0x5c, 0x0f, 0xad, 0x97, 0x56,
-       0x1f, 0xba, 0x9b, 0xe5, 0xe8, 0xb4, 0x9d, 0x36, 0xd2, 0x6f, 0x03, 0x0f,
-       0x93, 0x5c, 0xf3, 0x44, 0x26, 0xe2, 0x8c, 0xd2, 0x5e, 0x19, 0x85, 0x7c,
-       0xcc, 0x96, 0xd9, 0x37, 0xe1, 0x4d, 0xd8, 0xdf, 0xb0, 0x9b, 0x0a, 0x9d,
-       0xf6, 0x77, 0x0b, 0x7e, 0x27, 0xed, 0x6f, 0xc8, 0xd4, 0x82, 0x67, 0x7f,
-       0xc7, 0xb5, 0x1c, 0x32, 0xbf, 0x13, 0xf8, 0xdd, 0xaf, 0x7f, 0x4f, 0x15,
-       0x77, 0xed, 0x52, 0xde, 0x95, 0x92, 0x9d, 0xef, 0x94, 0x03, 0x85, 0x77,
-       0x58, 0xd9, 0x82, 0x4b, 0xbe, 0xe4, 0x98, 0x79, 0x26, 0xf4, 0xba, 0xe7,
-       0x8b, 0x39, 0x67, 0x94, 0xf0, 0xe3, 0xf7, 0x70, 0xa1, 0xcf, 0xdd, 0x24,
-       0xa4, 0x81, 0x29, 0x67, 0xb8, 0xe2, 0xa4, 0x23, 0x43, 0x3d, 0x89, 0x49,
-       0x39, 0x8c, 0xdf, 0xe2, 0x46, 0x86, 0xbe, 0x84, 0xbb, 0xc1, 0xc1, 0x57,
-       0xb6, 0x43, 0xb6, 0x16, 0x29, 0x2f, 0x3d, 0xcc, 0x3d, 0x29, 0x67, 0x56,
-       0xd8, 0x58, 0xc4, 0x85, 0x92, 0xec, 0x74, 0xea, 0x78, 0x4e, 0x52, 0xb9,
-       0x19, 0x30, 0xc4, 0x8d, 0x7e, 0x54, 0xde, 0xe7, 0x83, 0x76, 0xaf, 0x74,
-       0x64, 0xd7, 0x95, 0x51, 0xd8, 0x44, 0xde, 0xcc, 0x2e, 0xc8, 0x58, 0xc8,
-       0xbe, 0x08, 0xe9, 0x41, 0x9d, 0x92, 0xb1, 0xe8, 0x10, 0xb0, 0x7d, 0xaa,
-       0x7f, 0x64, 0xb2, 0x90, 0xbd, 0x5d, 0x0d, 0xed, 0xff, 0x6c, 0x66, 0xe0,
-       0xad, 0x92, 0xdd, 0xab, 0x80, 0xa3, 0xf6, 0x31, 0xc8, 0x4c, 0xcc, 0x2b,
-       0x08, 0x40, 0xcf, 0x90, 0xe7, 0x37, 0xdd, 0x14, 0x19, 0x6a, 0x90, 0xe1,
-       0xbd, 0xed, 0x68, 0xc3, 0x77, 0xc4, 0xd7, 0x79, 0xe0, 0x33, 0x95, 0x1c,
-       0x11, 0xb9, 0x7b, 0x6a, 0x60, 0xc9, 0x99, 0x2c, 0x7d, 0x10, 0x3c, 0x79,
-       0x15, 0xda, 0x3f, 0x80, 0xf6, 0x2f, 0x3b, 0xf9, 0xe9, 0x57, 0x9c, 0xc9,
-       0xe9, 0xbf, 0x75, 0xa6, 0xa6, 0xb7, 0x6c, 0xd9, 0x39, 0xb8, 0x65, 0xcb,
-       0xf8, 0x60, 0xd4, 0xea, 0x97, 0x2d, 0x5b, 0xa6, 0x06, 0x07, 0x81, 0x83,
-       0x3e, 0x77, 0x44, 0x3c, 0x77, 0x97, 0x80, 0x7f, 0xe2, 0x1c, 0x93, 0xfa,
-       0x27, 0x85, 0xf7, 0x6c, 0xef, 0xe9, 0xf7, 0xc3, 0xd2, 0x97, 0x68, 0x13,
-       0x8e, 0x1f, 0xb1, 0x75, 0xda, 0x01, 0xfb, 0x03, 0x76, 0x7d, 0x0b, 0xaa,
-       0xc1, 0x63, 0x39, 0xe7, 0xc2, 0x72, 0xae, 0xed, 0x8f, 0xac, 0x2d, 0xbb,
-       0x11, 0xe5, 0x7c, 0x26, 0xce, 0x88, 0x17, 0xda, 0x22, 0x0d, 0xda, 0x76,
-       0xcc, 0x16, 0x48, 0x33, 0x51, 0x99, 0x28, 0xb4, 0xa1, 0x0d, 0xe8, 0xe2,
-       0x94, 0xbd, 0x8e, 0x02, 0xb6, 0xbd, 0xe8, 0xeb, 0xe8, 0x21, 0xb4, 0xa3,
-       0xcc, 0x48, 0xf5, 0x8a, 0xfa, 0x04, 0xea, 0xf4, 0xb9, 0x9b, 0x85, 0x36,
-       0xc7, 0x71, 0xc9, 0x16, 0xc9, 0xdf, 0x3d, 0x80, 0x27, 0x26, 0xc9, 0x76,
-       0x3c, 0x57, 0x0e, 0xc0, 0x0e, 0x69, 0xb0, 0x3a, 0x33, 0x94, 0x17, 0xfc,
-       0x77, 0x87, 0x12, 0xef, 0x80, 0x8c, 0xcd, 0x5d, 0x8e, 0x7a, 0x0e, 0xf0,
-       0x42, 0x3b, 0x05, 0x36, 0xcb, 0x5c, 0x5a, 0x32, 0xdb, 0xee, 0xc5, 0xdd,
-       0xc5, 0x73, 0x1e, 0xf7, 0xb7, 0xe0, 0x3e, 0x89, 0x7b, 0x08, 0x27, 0xf0,
-       0xea, 0x47, 0xac, 0xce, 0xba, 0x06, 0x63, 0xff, 0x6b, 0xc9, 0x94, 0x12,
-       0xb4, 0x39, 0x36, 0x66, 0xbc, 0xb4, 0xab, 0x44, 0x6d, 0x56, 0x32, 0x85,
-       0xfa, 0xf0, 0x09, 0xbc, 0x83, 0x32, 0x7e, 0x12, 0xbf, 0x1f, 0xa4, 0x4d,
-       0x3c, 0x25, 0xe3, 0x73, 0x1c, 0xa7, 0x00, 0x98, 0x4a, 0x92, 0x3d, 0xf9,
-       0x00, 0xae, 0x69, 0x5c, 0x0f, 0xe3, 0xe2, 0xdc, 0xd8, 0xff, 0xe2, 0x26,
-       0x05, 0x5c, 0xf3, 0x39, 0x4b, 0x3a, 0xae, 0xe0, 0x37, 0x69, 0xb8, 0x42,
-       0xdb, 0x06, 0xf4, 0x5b, 0x09, 0xe9, 0xda, 0xb7, 0xbf, 0x13, 0x9a, 0xaf,
-       0x73, 0x6d, 0xa0, 0x99, 0xca, 0xa0, 0x96, 0x39, 0x19, 0x0f, 0xf7, 0x0a,
-       0x6c, 0x8f, 0x36, 0xce, 0xd1, 0xb3, 0x65, 0x9e, 0x2e, 0x4b, 0xea, 0xb2,
-       0x7e, 0x5b, 0x86, 0x7b, 0xa5, 0x41, 0xc6, 0xda, 0x01, 0x31, 0xe5, 0xb3,
-       0x84, 0xf8, 0xa4, 0x0c, 0x00, 0xfd, 0xc2, 0x66, 0x38, 0x73, 0x51, 0xf9,
-       0xb7, 0xa4, 0x6d, 0xb1, 0xc7, 0x2b, 0xa4, 0x63, 0xd2, 0x76, 0x10, 0xdc,
-       0xef, 0x37, 0xa1, 0x7f, 0xf2, 0xbc, 0x48, 0xc3, 0xd1, 0xa8, 0xcc, 0xb8,
-       0xa4, 0x85, 0x77, 0xb4, 0x90, 0x06, 0x1a, 0x3d, 0xd2, 0x70, 0x2d, 0x7f,
-       0x71, 0x0d, 0xd9, 0x5f, 0x0e, 0xf6, 0x1d, 0xed, 0xbc, 0x1e, 0xd8, 0xce,
-       0x1c, 0xe3, 0x30, 0x9f, 0x5d, 0x05, 0x9e, 0xca, 0x2c, 0xf3, 0x94, 0xc8,
-       0x6c, 0x81, 0xb8, 0x09, 0xed, 0x3f, 0xae, 0x33, 0xf1, 0xf3, 0x38, 0xe6,
-       0xcc, 0xfb, 0x19, 0x8b, 0xa7, 0x2f, 0x59, 0x3c, 0x7d, 0xd9, 0xde, 0x5d,
-       0x27, 0xab, 0x6d, 0xc1, 0x05, 0x3c, 0x73, 0x7d, 0xa2, 0x1a, 0x67, 0xd9,
-       0xc2, 0x0c, 0xee, 0xa8, 0x5b, 0x7c, 0x5c, 0xc6, 0xb5, 0x9d, 0x16, 0x91,
-       0x77, 0x69, 0xd9, 0x06, 0x21, 0xdd, 0x5c, 0x00, 0xcc, 0x0d, 0x92, 0x8b,
-       0x47, 0xf4, 0xda, 0x47, 0xbd, 0x03, 0x51, 0x43, 0xab, 0xc4, 0xc9, 0x0a,
-       0x5f, 0xaa, 0x06, 0xa6, 0xb8, 0x95, 0x73, 0x84, 0x8b, 0xb4, 0xfb, 0x88,
-       0x86, 0xeb, 0x16, 0xc8, 0xbb, 0x9c, 0xa8, 0xf6, 0x46, 0xb9, 0x0c, 0xb4,
-       0xa0, 0xe2, 0xd0, 0x5c, 0xc1, 0xd3, 0xb0, 0x9b, 0xb2, 0x73, 0xb4, 0xa1,
-       0xbb, 0xe8, 0xb7, 0xc4, 0xb2, 0xfd, 0xad, 0xa4, 0x23, 0xa5, 0x60, 0x7f,
-       0xe1, 0x59, 0x65, 0xfb, 0x35, 0x9d, 0x3a, 0xca, 0x8b, 0x6b, 0x3b, 0x19,
-       0xbc, 0x12, 0xb1, 0xbe, 0x73, 0x54, 0x79, 0x9b, 0x57, 0x97, 0x25, 0xa9,
-       0x87, 0xd1, 0x2e, 0x99, 0xed, 0x6f, 0x27, 0x8f, 0xb9, 0xca, 0x03, 0x2e,
-       0x3d, 0xed, 0x1b, 0xe5, 0xd4, 0xc0, 0xc6, 0x55, 0xf5, 0xf5, 0xdd, 0xb1,
-       0xcf, 0x51, 0x7b, 0x77, 0xed, 0x3d, 0x69, 0xef, 0xb9, 0xe8, 0x00, 0xef,
-       0x8e, 0x44, 0x87, 0x78, 0xc7, 0x1a, 0x0e, 0xb1, 0x0f, 0xcd, 0x57, 0x56,
-       0xce, 0xf4, 0xb8, 0x79, 0x21, 0x5f, 0xfd, 0xa9, 0xdc, 0x32, 0x67, 0xe4,
-       0xef, 0x2e, 0xc8, 0x20, 0xf8, 0x6f, 0xee, 0xa2, 0x00, 0xfe, 0xbd, 0x65,
-       0xb9, 0xa5, 0x42, 0xbc, 0xfd, 0x06, 0xf0, 0xb7, 0x35, 0x4a, 0xde, 0x74,
-       0x85, 0x72, 0xf7, 0x4e, 0xd1, 0xf6, 0x69, 0x81, 0x38, 0x3f, 0x2b, 0x5c,
-       0x9b, 0x7c, 0xe1, 0x19, 0xbd, 0x36, 0x07, 0x0b, 0x8b, 0xc0, 0xcf, 0xd7,
-       0x41, 0xf7, 0x41, 0xb0, 0xe8, 0xe7, 0x41, 0x39, 0x7f, 0x84, 0xdf, 0xe8,
-       0xbb, 0xf0, 0x1c, 0xde, 0xb7, 0x4a, 0xbe, 0x44, 0x9e, 0x8b, 0x5a, 0x1e,
-       0x3e, 0x05, 0x7e, 0xba, 0x0c, 0xfd, 0xa2, 0x6c, 0x80, 0xbf, 0xff, 0x11,
-       0xef, 0x70, 0x9f, 0xc3, 0x22, 0xb6, 0xd3, 0xd6, 0xe1, 0xd8, 0x5c, 0x3b,
-       0xae, 0x59, 0x5c, 0xfb, 0xad, 0x8f, 0x2f, 0xaf, 0x1b, 0xd7, 0x2b, 0xd5,
-       0x9b, 0x93, 0x70, 0xcd, 0x44, 0x1e, 0x2f, 0xb0, 0x3e, 0xe9, 0xff, 0x1f,
-       0x62, 0x46, 0x17, 0xfc, 0xc9, 0x3a, 0x73, 0x5f, 0xdd, 0x96, 0x6b, 0x5e,
-       0x4b, 0x83, 0xf4, 0x6f, 0x52, 0x83, 0x39, 0xc8, 0x9d, 0xa8, 0xd7, 0x2a,
-       0x23, 0xda, 0x27, 0x22, 0x4d, 0x90, 0x06, 0x6e, 0x56, 0x86, 0x36, 0x3f,
-       0xa4, 0x0c, 0x6d, 0x3e, 0x03, 0x5a, 0xc4, 0x55, 0x5c, 0x72, 0x0c, 0x6d,
-       0x7e, 0x1d, 0x77, 0x5c, 0xc5, 0x0b, 0x4e, 0xc8, 0xc7, 0xc3, 0xf0, 0xf9,
-       0x76, 0x15, 0xa2, 0xce, 0x78, 0x05, 0xf4, 0x5b, 0x8c, 0xa1, 0x7c, 0x81,
-       0x38, 0xc7, 0xfc, 0x39, 0xce, 0x56, 0xdb, 0xff, 0xe3, 0x32, 0x51, 0x0c,
-       0xb4, 0x5d, 0x95, 0x9d, 0xbb, 0x17, 0xf7, 0xf5, 0x5a, 0xce, 0x28, 0x2f,
-       0xad, 0x8c, 0xbc, 0x7a, 0x17, 0xee, 0xdd, 0x89, 0x83, 0xd2, 0xed, 0x46,
-       0xe4, 0x39, 0xf4, 0xf5, 0x43, 0x67, 0xa2, 0xf2, 0x32, 0xae, 0x9f, 0xe0,
-       0x7a, 0x15, 0xd7, 0x2b, 0xe8, 0xf7, 0x45, 0x94, 0xaf, 0x97, 0x05, 0xb7,
-       0x19, 0xf5, 0x45, 0x8d, 0x57, 0x5e, 0x70, 0xc6, 0x4e, 0xbe, 0x84, 0x2b,
-       0xaa, 0x26, 0x2a, 0xcf, 0x3b, 0xd9, 0xb9, 0x60, 0xe3, 0xa2, 0x47, 0x19,
-       0xf6, 0xa7, 0x8e, 0xe9, 0x7b, 0x08, 0x73, 0x00, 0x4d, 0x17, 0x17, 0x30,
-       0xf6, 0x33, 0x9a, 0x67, 0x46, 0x20, 0xf3, 0xb3, 0xb0, 0x4b, 0xc6, 0x34,
-       0x4c, 0x97, 0x03, 0x3e, 0xf8, 0xba, 0x03, 0xb8, 0xcf, 0x35, 0xca, 0x52,
-       0x9c, 0x76, 0xe4, 0x97, 0x75, 0xfd, 0x6c, 0xb1, 0x5b, 0xe3, 0x76, 0x66,
-       0x0d, 0xff, 0xd0, 0x3f, 0x0b, 0xe5, 0x81, 0x91, 0xc6, 0xb3, 0x05, 0xca,
-       0x02, 0xe8, 0x9f, 0xc2, 0x14, 0xee, 0x8d, 0x5a, 0x26, 0xe4, 0x25, 0x94,
-       0x07, 0x6c, 0x47, 0x99, 0x50, 0x2b, 0x77, 0x28, 0x6b, 0x28, 0x7b, 0x28,
-       0x4b, 0xcc, 0x7a, 0x8c, 0x3f, 0x48, 0x19, 0x7e, 0x2d, 0xfc, 0x53, 0xda,
-       0x1f, 0x9d, 0xc6, 0x07, 0x99, 0xce, 0x28, 0x23, 0x4f, 0xf7, 0xe8, 0xb5,
-       0x98, 0x28, 0xa8, 0x38, 0x20, 0x47, 0x19, 0xae, 0x63, 0x7b, 0x71, 0xcf,
-       0xaa, 0x09, 0x5c, 0xd9, 0x63, 0x1f, 0xc0, 0x6f, 0xae, 0xcd, 0x04, 0xea,
-       0xe1, 0x2a, 0x8e, 0xe2, 0x8e, 0x0b, 0xb6, 0x99, 0x91, 0x23, 0x5c, 0xd3,
-       0x84, 0x5d, 0xd3, 0x2f, 0x03, 0x0f, 0x9c, 0x9f, 0xd2, 0xf1, 0x07, 0xe5,
-       0xed, 0x00, 0xde, 0x2b, 0xd6, 0xdf, 0x6d, 0x15, 0xc3, 0x83, 0xb8, 0x7a,
-       0xc9, 0xcf, 0x2d, 0x66, 0xbd, 0x34, 0xed, 0x7e, 0x37, 0x6a, 0x78, 0x31,
-       0x8e, 0xb2, 0x08, 0xca, 0xda, 0x45, 0xf3, 0xfe, 0x32, 0x1e, 0xd3, 0x16,
-       0x8f, 0xfc, 0xad, 0xec, 0x6f, 0xd0, 0x13, 0x6c, 0xda, 0x8c, 0x37, 0x80,
-       0x71, 0x31, 0x97, 0x63, 0x7b, 0xd4, 0x38, 0xe4, 0xf7, 0xb8, 0x47, 0x19,
-       0xce, 0x38, 0x03, 0xe7, 0xc7, 0x7e, 0x51, 0xae, 0x71, 0xe0, 0x4b, 0xd5,
-       0x87, 0xff, 0x32, 0xd6, 0xec, 0x71, 0xd9, 0x57, 0xbc, 0x5a, 0xfb, 0xd4,
-       0x8d, 0x47, 0xcd, 0x7a, 0x88, 0x0a, 0xeb, 0xa1, 0xef, 0x38, 0x6d, 0x9b,
-       0x31, 0xfd, 0x3e, 0x7a, 0x94, 0xbf, 0x29, 0x9f, 0x6b, 0xe5, 0xbd, 0xb1,
-       0x6b, 0xf2, 0x2b, 0x64, 0x1d, 0x6d, 0x0b, 0xac, 0x59, 0xb9, 0x16, 0xef,
-       0xf4, 0xf1, 0x29, 0xf3, 0xc8, 0x4f, 0x07, 0xc1, 0x13, 0xaa, 0xc1, 0xf0,
-       0x3e, 0x7d, 0x8d, 0x7a, 0xfc, 0x04, 0xfb, 0x0b, 0xbc, 0x72, 0x02, 0xb6,
-       0xdb, 0xae, 0xe5, 0x3e, 0x20, 0x2b, 0xe3, 0x31, 0x39, 0x59, 0x68, 0x91,
-       0xb9, 0x82, 0x82, 0xc1, 0x60, 0x64, 0x67, 0x44, 0x12, 0x5a, 0xff, 0xd2,
-       0xbe, 0x1b, 0x9e, 0x8e, 0x58, 0xba, 0x83, 0xc3, 0xd2, 0xfc, 0x1b, 0xd0,
-       0xb1, 0x65, 0xe8, 0xd8, 0x56, 0xe8, 0xe0, 0xd5, 0x32, 0xa2, 0xab, 0x61,
-       0xad, 0x8c, 0x60, 0x9b, 0x14, 0xbc, 0xf2, 0x83, 0x68, 0x17, 0xd2, 0x5f,
-       0x4c, 0xd3, 0x5a, 0x56, 0x72, 0xce, 0xae, 0xca, 0x94, 0xb3, 0xbb, 0xb2,
-       0x5a, 0x07, 0xf5, 0xb9, 0x51, 0x31, 0xb0, 0x9e, 0xd4, 0x71, 0xbc, 0x94,
-       0x9f, 0x01, 0x4e, 0x76, 0x83, 0xee, 0x9e, 0x2e, 0xc1, 0x8f, 0xa7, 0x5c,
-       0x06, 0xcc, 0x8f, 0x01, 0xe6, 0xd9, 0x92, 0x13, 0xda, 0x06, 0xc2, 0xe0,
-       0xc9, 0xec, 0x74, 0xbf, 0x2c, 0xce, 0x93, 0x0e, 0x21, 0x03, 0x4a, 0x58,
-       0x4f, 0x7f, 0x1d, 0xec, 0x00, 0x8e, 0x0f, 0xb9, 0x3d, 0xdd, 0xa1, 0xdf,
-       0x19, 0x7d, 0xde, 0x29, 0x8b, 0xe5, 0xf7, 0x58, 0xd8, 0x0e, 0xd7, 0xc0,
-       0xb6, 0x6e, 0x19, 0xb6, 0xdd, 0x80, 0x6d, 0x4f, 0x5d, 0xd8, 0xea, 0xe9,
-       0xe2, 0x2e, 0xd8, 0x34, 0xe4, 0x8f, 0x10, 0xaf, 0xed, 0x96, 0x1e, 0x6e,
-       0xb7, 0xf6, 0x2e, 0x6d, 0xa2, 0x9f, 0x02, 0x1e, 0xd2, 0x18, 0x7e, 0xcf,
-       0x3d, 0x4a, 0x59, 0x86, 0x72, 0x3e, 0x7f, 0x06, 0x75, 0xf0, 0x3c, 0xf7,
-       0xe7, 0x56, 0x0e, 0xde, 0x65, 0x61, 0xa1, 0x9d, 0x90, 0x86, 0x4d, 0x3c,
-       0xe2, 0x64, 0xe6, 0x08, 0x43, 0x0e, 0xf0, 0xe2, 0x5d, 0xa5, 0xb6, 0x4f,
-       0xde, 0xd9, 0xef, 0x15, 0xb6, 0x1f, 0xf6, 0x1d, 0xce, 0x65, 0xbd, 0xd5,
-       0xf3, 0x21, 0x7d, 0x85, 0xf6, 0xf5, 0x94, 0x93, 0x5e, 0x33, 0xaf, 0x5a,
-       0x9a, 0xa3, 0xbc, 0x8d, 0xca, 0x4e, 0xd0, 0xc9, 0xce, 0x15, 0xb4, 0xa6,
-       0xdd, 0x10, 0x4b, 0xc7, 0xeb, 0xec, 0xfc, 0x0e, 0x18, 0xbe, 0xf1, 0x63,
-       0xd0, 0x87, 0x94, 0x37, 0x37, 0x1b, 0xdf, 0x5c, 0x4e, 0x00, 0xd6, 0xf0,
-       0x99, 0xb4, 0xc9, 0xdf, 0x94, 0x49, 0x55, 0x5a, 0x34, 0xbe, 0x4b, 0xa7,
-       0x8e, 0x9f, 0x56, 0xed, 0xf5, 0xa8, 0x8c, 0x9a, 0x35, 0x3f, 0xcc, 0x35,
-       0xa7, 0x2f, 0xd2, 0xfd, 0xc0, 0xa8, 0xe5, 0xaf, 0x54, 0x29, 0x27, 0xbb,
-       0xed, 0xdc, 0xbf, 0x5c, 0x67, 0xed, 0x5a, 0x97, 0xd7, 0x6e, 0xb4, 0xb2,
-       0x7a, 0x8e, 0x22, 0x5d, 0x0f, 0x44, 0xb5, 0x6f, 0x2b, 0xca, 0x97, 0x46,
-       0x8f, 0xf2, 0x93, 0xb6, 0x12, 0xca, 0x67, 0xfb, 0xdc, 0x36, 0xd0, 0xdb,
-       0x53, 0x6b, 0xec, 0xae, 0xa4, 0x95, 0x9b, 0xf4, 0x83, 0xc3, 0x31, 0x72,
-       0x56, 0x4e, 0xe6, 0xd0, 0xff, 0x94, 0xb3, 0xb3, 0x52, 0x4f, 0x5e, 0x86,
-       0x72, 0x92, 0xf3, 0xb9, 0x57, 0xee, 0x78, 0x90, 0x3c, 0x7a, 0xbb, 0xb6,
-       0xaf, 0xaf, 0xda, 0x71, 0x00, 0xf8, 0x23, 0xfc, 0x8b, 0x9b, 0x60, 0x32,
-       0x40, 0xe7, 0xa6, 0x65, 0xdc, 0xae, 0xdb, 0xf8, 0xf2, 0xfa, 0xf3, 0x6a,
-       0xc7, 0x6f, 0xc6, 0x59, 0x95, 0x85, 0x59, 0xdb, 0xb1, 0xb0, 0xeb, 0x56,
-       0xdb, 0xb2, 0x9c, 0x03, 0xed, 0xd9, 0x46, 0x63, 0x0b, 0x16, 0x69, 0x7f,
-       0x52, 0x76, 0xd1, 0xfe, 0x8c, 0x35, 0x4a, 0x33, 0xe7, 0x33, 0x68, 0xcb,
-       0x68, 0xa7, 0xae, 0x9e, 0xdf, 0x6a, 0xff, 0x91, 0x70, 0x12, 0x6e, 0x43,
-       0x5b, 0x49, 0x45, 0xd8, 0x02, 0x19, 0xf5, 0xaf, 0xd5, 0x6b, 0xa0, 0x68,
-       0xbb, 0xee, 0xf8, 0x76, 0x83, 0x89, 0x31, 0x27, 0xd1, 0x3f, 0xc7, 0x24,
-       0xff, 0xf1, 0x4e, 0x3b, 0xbf, 0x9e, 0x2c, 0xab, 0xd5, 0x3d, 0x97, 0x2d,
-       0xe3, 0x6f, 0xe7, 0x8a, 0x35, 0x0a, 0xf1, 0x17, 0xd2, 0x45, 0x2d, 0x0e,
-       0x49, 0x13, 0xa4, 0x85, 0x90, 0x16, 0xb7, 0x5a, 0x7d, 0x13, 0xd2, 0xde,
-       0xa5, 0xa0, 0xbd, 0xfb, 0x80, 0x27, 0xca, 0x70, 0xc6, 0xed, 0x36, 0xe3,
-       0xf9, 0x08, 0x9e, 0x43, 0x3e, 0xb9, 0x98, 0x0c, 0xa7, 0xfc, 0x66, 0x9b,
-       0x8c, 0x95, 0xfb, 0xa1, 0x9f, 0xcb, 0x36, 0x9c, 0x37, 0xe5, 0xff, 0x57,
-       0xe9, 0x77, 0x35, 0x1a, 0x3b, 0xfd, 0x43, 0x8d, 0x94, 0xaf, 0x9b, 0xe4,
-       0x60, 0x4d, 0xd9, 0xc5, 0xe4, 0x77, 0xed, 0x9c, 0x2f, 0xff, 0x7f, 0x30,
-       0xe7, 0xc4, 0xaa, 0x39, 0xbb, 0x76, 0xce, 0x15, 0xbc, 0x6f, 0xc3, 0xfb,
-       0x16, 0xea, 0x82, 0x64, 0x55, 0xde, 0x58, 0x5c, 0xe8, 0x79, 0xd5, 0xca,
-       0x89, 0x50, 0x46, 0x70, 0x5e, 0x1f, 0xb1, 0x73, 0x78, 0xa0, 0x66, 0x5e,
-       0x1f, 0x79, 0x13, 0xf3, 0xea, 0x5c, 0x31, 0xaf, 0x5d, 0x17, 0x9d, 0x57,
-       0x3d, 0x1e, 0x27, 0x2f, 0x87, 0xf3, 0x8b, 0xc9, 0x8d, 0x05, 0xce, 0x71,
-       0x27, 0xe6, 0x48, 0x18, 0xc2, 0x39, 0x0e, 0xd9, 0x39, 0x8a, 0xea, 0xda,
-       0xf1, 0x73, 0xf8, 0x5d, 0x3b, 0x3f, 0xea, 0xfe, 0x1f, 0x83, 0xa6, 0x9b,
-       0x24, 0xd3, 0xdf, 0x64, 0xe5, 0xff, 0x97, 0xe5, 0xd6, 0x22, 0xd7, 0x3a,
-       0x95, 0x16, 0xd9, 0xa3, 0xf6, 0x15, 0x9f, 0x6d, 0x64, 0x8c, 0x7f, 0x97,
-       0x6f, 0xf5, 0x18, 0xf4, 0xc5, 0x6e, 0xd8, 0x7c, 0x3b, 0x0b, 0x6a, 0x20,
-       0x22, 0x41, 0x70, 0x9b, 0xdf, 0x8c, 0xb1, 0x37, 0x6a, 0x5f, 0x75, 0x6d,
-       0x7c, 0xfd, 0x99, 0x46, 0xf1, 0x68, 0x6f, 0x50, 0x9f, 0x43, 0xdf, 0x1d,
-       0xa3, 0x0d, 0x96, 0x81, 0x9d, 0x9c, 0x4e, 0x44, 0xb4, 0x2d, 0x46, 0x9d,
-       0x98, 0x4a, 0xa4, 0xa5, 0x2c, 0xd9, 0x63, 0xe9, 0x84, 0x12, 0x8e, 0x01,
-       0x5b, 0x0d, 0x36, 0xe4, 0xad, 0x90, 0x35, 0xb7, 0x56, 0xf6, 0xaa, 0x5b,
-       0x60, 0xef, 0xdc, 0x72, 0xf2, 0x03, 0xea, 0x36, 0xd8, 0x3a, 0xb7, 0x9d,
-       0xbc, 0x41, 0xed, 0x83, 0x6d, 0xb3, 0x0f, 0x76, 0xce, 0xbe, 0x0a, 0x6d,
-       0xcf, 0x9b, 0x41, 0x7b, 0x9d, 0x35, 0xb4, 0x46, 0x1b, 0x87, 0xf3, 0x23,
-       0xee, 0x8f, 0x71, 0x0d, 0xfc, 0xa4, 0x7a, 0x45, 0xaf, 0x4b, 0xdb, 0x8a,
-       0xb2, 0xd7, 0x92, 0x55, 0xa1, 0x7e, 0xda, 0x60, 0xe3, 0x46, 0x94, 0xb7,
-       0xaf, 0x45, 0x5b, 0xa4, 0x11, 0x17, 0x78, 0x26, 0xfe, 0x48, 0x5b, 0xb5,
-       0xf3, 0xdf, 0xd4, 0x24, 0x5e, 0x67, 0x93, 0x34, 0xdf, 0x0b, 0xf9, 0x5a,
-       0x4b, 0x53, 0xbc, 0xbb, 0x56, 0xd7, 0x90, 0xb6, 0x28, 0x83, 0x43, 0x7a,
-       0xd8, 0xfa, 0x1a, 0xf2, 0xf7, 0xa2, 0xf4, 0x74, 0x4f, 0x64, 0x28, 0x08,
-       0xc6, 0x07, 0x64, 0x23, 0xe3, 0x01, 0x99, 0x4a, 0x35, 0x26, 0xa0, 0xbc,
-       0xda, 0x98, 0x00, 0xfd, 0xac, 0x47, 0x80, 0xdf, 0x19, 0x5c, 0x22, 0x63,
-       0x8c, 0x3b, 0x54, 0x42, 0xbb, 0xfc, 0x1b, 0xd6, 0x2e, 0x0f, 0xe1, 0x48,
-       0x02, 0x0e, 0x23, 0x9f, 0xd7, 0xea, 0xb9, 0x95, 0xfa, 0x3b, 0xb7, 0x6c,
-       0xd3, 0x26, 0xe5, 0xc6, 0x22, 0xe7, 0x4d, 0x19, 0x4c, 0xdc, 0xd4, 0xca,
-       0xe0, 0x84, 0xb5, 0xa3, 0x50, 0x47, 0xcb, 0xcf, 0xb5, 0xb2, 0x93, 0x72,
-       0x8f, 0xf1, 0xf9, 0x07, 0x7c, 0xd2, 0xfa, 0x7b, 0x24, 0xbd, 0x1c, 0x9f,
-       0x17, 0xd0, 0x9b, 0xf8, 0x91, 0x21, 0xbd, 0xdf, 0xe6, 0xce, 0xca, 0x6e,
-       0x19, 0x8e, 0x33, 0xd6, 0xc9, 0x78, 0x9e, 0x97, 0x9b, 0x05, 0x0f, 0x4c,
-       0x16, 0x15, 0x2c, 0xf8, 0x46, 0x19, 0x73, 0x03, 0xd9, 0xe5, 0x3b, 0x3a,
-       0x76, 0x6c, 0x74, 0xed, 0x4c, 0x93, 0xb1, 0x5d, 0x1d, 0x1d, 0xff, 0x5d,
-       0x04, 0xf5, 0x2d, 0x6a, 0xfb, 0x56, 0x69, 0xfd, 0xbb, 0xa0, 0xeb, 0x7c,
-       0xae, 0x29, 0x8c, 0x63, 0x2e, 0xba, 0x11, 0x5b, 0xaf, 0xb6, 0xfc, 0x8b,
-       0x36, 0x3e, 0x9d, 0x84, 0xec, 0x0f, 0xcb, 0xfe, 0xb0, 0x4e, 0xd9, 0xb7,
-       0xea, 0x94, 0xfd, 0xcf, 0x3a, 0x65, 0x26, 0x2e, 0xb8, 0xb3, 0xf0, 0xf7,
-       0x78, 0x37, 0xa5, 0x7d, 0x77, 0xb1, 0xfb, 0x61, 0xb9, 0xe5, 0x3a, 0x1b,
-       0xac, 0x5f, 0xc6, 0x18, 0xb1, 0x89, 0x0d, 0x67, 0x75, 0x6c, 0xb8, 0xcf,
-       0xdd, 0xa1, 0xf4, 0x5e, 0xca, 0x7e, 0xc6, 0x19, 0xf7, 0x69, 0xbc, 0x10,
-       0x27, 0x5f, 0x61, 0x0c, 0x38, 0xc7, 0xbd, 0xd8, 0xa4, 0xba, 0x18, 0x6d,
-       0x57, 0x6d, 0x13, 0xb3, 0x6e, 0xb4, 0x8b, 0x5b, 0x64, 0x04, 0xb6, 0xc2,
-       0xce, 0x42, 0x9b, 0xec, 0x9a, 0x1e, 0x58, 0x47, 0xbd, 0xb5, 0x7b, 0xda,
-       0xf8, 0x83, 0xfb, 0xc0, 0x57, 0x69, 0x21, 0x8c, 0x29, 0x5f, 0x84, 0x36,
-       0xf1, 0x5a, 0x5b, 0xf8, 0xb5, 0xfb, 0xfb, 0xa5, 0x8b, 0xf4, 0xe7, 0xc0,
-       0x76, 0x78, 0xa3, 0xfd, 0x35, 0xcb, 0xc8, 0x74, 0x88, 0x2b, 0xf5, 0x33,
-       0xb6, 0x8b, 0x5c, 0xa4, 0x9d, 0xb6, 0x4b, 0xe4, 0xe9, 0x65, 0x59, 0xbc,
-       0x15, 0x36, 0x93, 0x04, 0x99, 0x01, 0xe9, 0x8c, 0x88, 0x8e, 0xf1, 0xf8,
-       0x46, 0x36, 0xf7, 0x70, 0x6f, 0x07, 0xf4, 0x6f, 0x6c, 0x15, 0x13, 0x37,
-       0x0d, 0xed, 0x94, 0x7a, 0xb4, 0x7b, 0x9d, 0xa5, 0x5d, 0xee, 0xb9, 0xee,
-       0xa6, 0xcc, 0xd5, 0x6b, 0x42, 0x3a, 0xde, 0x55, 0x90, 0x64, 0x48, 0xc7,
-       0x8b, 0x92, 0x5e, 0x41, 0xc7, 0x8b, 0x32, 0xa4, 0xe9, 0xb8, 0x71, 0x05,
-       0x1d, 0x77, 0x5a, 0x3a, 0xde, 0x13, 0x33, 0x74, 0xa1, 0xb4, 0x9e, 0x22,
-       0x9d, 0x1a, 0x3a, 0x76, 0x34, 0x1d, 0x2f, 0xe2, 0x1e, 0xf5, 0xae, 0xb3,
-       0x75, 0x22, 0xb6, 0x8c, 0xbf, 0xc3, 0x32, 0xca, 0xc5, 0x4f, 0xc6, 0x8c,
-       0x5e, 0x1a, 0x02, 0x1d, 0x85, 0xe5, 0xfb, 0x6d, 0xfc, 0xa0, 0xb6, 0xcc,
-       0xc4, 0x47, 0x76, 0x16, 0xc6, 0x62, 0x2b, 0xe9, 0x73, 0x08, 0xf4, 0x19,
-       0xd6, 0x79, 0x2d, 0xfa, 0x6c, 0xb6, 0xfb, 0x16, 0x71, 0xbd, 0x2f, 0x9f,
-       0x8e, 0x1b, 0x5a, 0xbd, 0x45, 0xcf, 0x9d, 0xf3, 0x3e, 0xfb, 0x06, 0x68,
-       0xd5, 0xac, 0xcd, 0xb9, 0xaa, 0xbf, 0xcd, 0x58, 0x54, 0xd2, 0xc4, 0xb0,
-       0x19, 0x27, 0xbd, 0x98, 0xed, 0x68, 0xe4, 0x53, 0x83, 0x96, 0x4f, 0xad,
-       0x63, 0xcc, 0x35, 0xa8, 0xca, 0xec, 0x01, 0xe8, 0x0a, 0xda, 0xd8, 0x5a,
-       0x4e, 0xe3, 0x5d, 0x67, 0x32, 0x53, 0x78, 0x35, 0x88, 0x78, 0x8c, 0x0f,
-       0x71, 0x5f, 0x40, 0xc6, 0x1c, 0x94, 0x75, 0x95, 0xcd, 0xbc, 0x94, 0xd7,
-       0x8a, 0xe7, 0x01, 0xe9, 0x2a, 0x2b, 0xf9, 0xe8, 0x74, 0x8b, 0xec, 0x2f,
-       0x44, 0xe5, 0xe3, 0x68, 0xff, 0xb1, 0x82, 0x0b, 0x7f, 0xfc, 0x4c, 0x8c,
-       0x76, 0xe1, 0xbe, 0x02, 0xf7, 0x27, 0x59, 0x37, 0xbe, 0x6a, 0x7f, 0x36,
-       0x22, 0x5d, 0x3d, 0x79, 0x78, 0x2a, 0x12, 0xdd, 0x03, 0x38, 0x9a, 0x86,
-       0x86, 0xe4, 0x07, 0x03, 0x1b, 0x51, 0xf6, 0xb2, 0x1d, 0x6f, 0xd4, 0x31,
-       0xf1, 0xde, 0x41, 0x79, 0x77, 0x65, 0x48, 0xae, 0xaf, 0x98, 0x3d, 0xd5,
-       0xea, 0x9e, 0x69, 0xca, 0x5d, 0x80, 0xfe, 0x49, 0xbb, 0x41, 0x70, 0xce,
-       0xc3, 0xaa, 0x1f, 0x89, 0x4a, 0xac, 0x27, 0x95, 0x58, 0x10, 0xf3, 0x7c,
-       0xbe, 0xfc, 0x0f, 0xc1, 0x58, 0x3c, 0x2a, 0x3f, 0xf0, 0x38, 0xc7, 0x41,
-       0xb9, 0xae, 0x5c, 0x3b, 0x36, 0x97, 0xf3, 0x0f, 0x63, 0xdc, 0xa7, 0xc8,
-       0x54, 0x16, 0x62, 0x8c, 0xa5, 0xd3, 0xe7, 0xe8, 0x7a, 0x1b, 0xfc, 0x38,
-       0x48, 0xee, 0xae, 0xb7, 0x81, 0x6e, 0xe2, 0xd0, 0xf9, 0x57, 0x01, 0xc6,
-       0xab, 0x18, 0xfb, 0x62, 0xcc, 0x8b, 0xcf, 0x5f, 0xc7, 0xb8, 0x6c, 0xfb,
-       0x1b, 0xd6, 0x5e, 0xe6, 0xfa, 0x1b, 0xde, 0xa9, 0xaf, 0x77, 0x5a, 0xc7,
-       0x62, 0x43, 0xe2, 0xc4, 0xde, 0x91, 0x90, 0x75, 0x5e, 0xed, 0xf8, 0xdc,
-       0x27, 0x86, 0xc5, 0x38, 0x20, 0xd1, 0xdd, 0xdb, 0x07, 0x65, 0x04, 0xf3,
-       0xdb, 0xb9, 0x66, 0x7e, 0xf7, 0x08, 0xe3, 0xab, 0xe7, 0x0b, 0x9c, 0x43,
-       0x75, 0x5e, 0xea, 0x0b, 0x66, 0x5e, 0xb1, 0x9e, 0xd5, 0xf3, 0xd1, 0xed,
-       0xd5, 0x09, 0xc0, 0xf2, 0x35, 0x9d, 0x57, 0x10, 0x04, 0x6f, 0xed, 0x39,
-       0x1f, 0x24, 0x2f, 0x49, 0xf5, 0x2e, 0x54, 0xf7, 0x77, 0xc6, 0x22, 0x43,
-       0x69, 0xad, 0xcf, 0xf0, 0x9c, 0xcc, 0x96, 0xd3, 0x58, 0x47, 0x89, 0x66,
-       0xfb, 0xa3, 0x9a, 0x4f, 0xb2, 0x5e, 0xda, 0xee, 0x61, 0x85, 0x3e, 0x54,
-       0x10, 0x28, 0x6f, 0xb5, 0xdc, 0xa0, 0xbe, 0xc2, 0xdc, 0xe5, 0xdf, 0xda,
-       0x1c, 0x96, 0x5e, 0xc6, 0xb3, 0xc6, 0xa2, 0x43, 0xb1, 0x64, 0xbe, 0xec,
-       0xe1, 0x77, 0x0b, 0xee, 0x3b, 0x60, 0xaf, 0xf8, 0xb0, 0x67, 0x24, 0xae,
-       0x8c, 0x6c, 0x00, 0x2d, 0xf7, 0xe4, 0x94, 0x22, 0x6f, 0xba, 0xc9, 0xc9,
-       0x72, 0x3c, 0x59, 0x2a, 0x7f, 0x96, 0xed, 0x51, 0xb7, 0x5e, 0x2c, 0xcf,
-       0xc8, 0x86, 0xa7, 0x2a, 0x1c, 0x83, 0xfe, 0xef, 0x1b, 0x19, 0x23, 0x6a,
-       0xfb, 0x66, 0x9f, 0x21, 0x5e, 0xa2, 0x74, 0xc9, 0xf1, 0x2f, 0x6d, 0x7d,
-       0x13, 0xce, 0xef, 0xb3, 0x16, 0xee, 0xd5, 0xe3, 0xbe, 0xa0, 0xed, 0x97,
-       0xd3, 0x15, 0xda, 0x8c, 0xdc, 0xdf, 0x49, 0x1d, 0x9f, 0x11, 0xc2, 0x11,
-       0x04, 0xcf, 0xf9, 0x46, 0x77, 0x3f, 0x55, 0xe1, 0x1e, 0x47, 0x10, 0xfc,
-       0x88, 0x76, 0xf1, 0xde, 0x22, 0xc6, 0x0b, 0x71, 0xb0, 0x35, 0x17, 0x85,
-       0x5c, 0x9c, 0x1a, 0x20, 0x7e, 0x05, 0x1e, 0x6a, 0x8f, 0x7b, 0xa3, 0xc4,
-       0x92, 0x9f, 0x2a, 0xb7, 0x24, 0x3f, 0x5d, 0x76, 0x81, 0x67, 0xce, 0x3b,
-       0x9e, 0x9c, 0xb0, 0x73, 0xce, 0x96, 0x89, 0xdf, 0xd7, 0xda, 0x87, 0x7c,
-       0x61, 0x85, 0xbf, 0x44, 0x98, 0xaa, 0xb0, 0x10, 0xb6, 0xa4, 0xc5, 0x4d,
-       0x10, 0xfc, 0xd8, 0x37, 0x6b, 0x3a, 0x55, 0x94, 0x29, 0x8c, 0x9b, 0xdb,
-       0xac, 0x88, 0x87, 0x58, 0xf2, 0x0e, 0x8c, 0xfd, 0x29, 0x8c, 0xbd, 0xbf,
-       0xcc, 0xf1, 0x20, 0x2b, 0x30, 0xf7, 0xa9, 0x4a, 0x08, 0x6f, 0xbd, 0xb1,
-       0xc3, 0x35, 0xef, 0xb5, 0x36, 0x5e, 0xf8, 0xac, 0x11, 0xd9, 0xae, 0xbc,
-       0x7e, 0xd0, 0xd7, 0xe2, 0xa6, 0xa8, 0xfc, 0x22, 0xe4, 0x6e, 0x20, 0x8f,
-       0x42, 0x9e, 0x2d, 0x6a, 0xba, 0xc9, 0x5c, 0xce, 0xff, 0x23, 0xf2, 0xeb,
-       0xeb, 0x18, 0x5f, 0x1e, 0xf6, 0x68, 0xbb, 0x2e, 0x05, 0x8b, 0x1e, 0xe5,
-       0xf3, 0x06, 0x99, 0x71, 0x73, 0xbd, 0xd0, 0x15, 0x28, 0x6b, 0xa5, 0xbf,
-       0x9d, 0xcc, 0x44, 0x52, 0xc9, 0x49, 0x61, 0x3e, 0x14, 0x73, 0x15, 0x98,
-       0x23, 0x44, 0xd9, 0x10, 0x85, 0xcc, 0xe3, 0x1a, 0x9a, 0xf1, 0x26, 0xcb,
-       0xd5, 0xba, 0x07, 0x84, 0x7b, 0x86, 0xa9, 0xc4, 0x3e, 0x6d, 0x9f, 0x88,
-       0x8c, 0x17, 0x58, 0x77, 0x3b, 0xac, 0x13, 0xaf, 0xa6, 0xbe, 0xce, 0xe1,
-       0x02, 0x9f, 0x87, 0x71, 0xac, 0x58, 0x2c, 0x53, 0x90, 0x97, 0x23, 0x03,
-       0xf2, 0x32, 0xed, 0xce, 0x61, 0xd0, 0xb6, 0xeb, 0xf1, 0xbd, 0x29, 0xcf,
-       0xf8, 0xb2, 0x94, 0x19, 0xec, 0xa3, 0x9d, 0x9d, 0x53, 0x9a, 0x27, 0x44,
-       0xa1, 0x6d, 0x2c, 0x5b, 0x96, 0x91, 0x6c, 0xc1, 0xc6, 0x7a, 0x46, 0x39,
-       0xe7, 0x0d, 0x35, 0x73, 0x6f, 0x95, 0x28, 0x60, 0x1a, 0x89, 0x24, 0x9d,
-       0x06, 0xef, 0x23, 0x2d, 0x46, 0xe7, 0x43, 0xee, 0xb7, 0xdd, 0xdf, 0xce,
-       0x3d, 0x53, 0x05, 0x1f, 0x5a, 0xb5, 0xdf, 0x7e, 0x8d, 0x1a, 0xfa, 0xf3,
-       0x04, 0xf4, 0xa0, 0x95, 0x95, 0xb1, 0x91, 0xae, 0x65, 0xfa, 0xe6, 0xf8,
-       0xd2, 0x1e, 0xf1, 0x92, 0x23, 0xc3, 0x65, 0x51, 0x91, 0x21, 0x37, 0x36,
-       0x5c, 0x5e, 0x49, 0xf3, 0x4f, 0x55, 0xfe, 0xbd, 0xb5, 0x05, 0x6b, 0x63,
-       0xaa, 0xb5, 0xef, 0xc8, 0x77, 0x2b, 0xf6, 0x2b, 0x92, 0x26, 0x07, 0x86,
-       0xfb, 0xb4, 0x5c, 0x93, 0xf4, 0x5b, 0x1b, 0xa0, 0x7c, 0x66, 0xb4, 0x8f,
-       0xc6, 0x9c, 0x8b, 0x98, 0xcd, 0x3d, 0x33, 0xb8, 0x4e, 0x97, 0x1d, 0x99,
-       0x82, 0x7c, 0x38, 0x20, 0x7f, 0x1f, 0xa4, 0xe3, 0xe6, 0xbd, 0x59, 0x5f,
-       0xd6, 0xe7, 0x5e, 0x44, 0xb3, 0xe4, 0x4f, 0x46, 0x25, 0x77, 0x92, 0x7b,
-       0x60, 0xcf, 0xed, 0xaf, 0xe6, 0x6d, 0x50, 0x0e, 0x70, 0xbf, 0xd6, 0x91,
-       0x3c, 0xfc, 0xda, 0x11, 0xee, 0xc3, 0xf7, 0xff, 0x1f, 0xf4, 0xc1, 0x7a,
-       0x61, 0xdb, 0x16, 0xb4, 0x6d, 0xb4, 0x6d, 0x47, 0xef, 0x78, 0x73, 0x6d,
-       0x5b, 0xd1, 0x36, 0x16, 0x8e, 0xfb, 0x06, 0xdb, 0x6a, 0x7c, 0x5e, 0x33,
-       0x5c, 0x28, 0x2e, 0xc1, 0x4f, 0x4e, 0x4c, 0x48, 0xda, 0x19, 0x1f, 0xd0,
-       0xf3, 0xb9, 0x66, 0xb8, 0x0c, 0x38, 0xe2, 0x41, 0x90, 0xf7, 0x43, 0x3d,
-       0xcc, 0x7f, 0xc7, 0x44, 0x3c, 0x96, 0x71, 0xdf, 0x92, 0xfe, 0x04, 0xa3,
-       0xa4, 0x2e, 0xf3, 0xd9, 0x24, 0xcf, 0xfd, 0xc9, 0xf8, 0x46, 0xdc, 0x55,
-       0x17, 0x71, 0x92, 0xf5, 0x18, 0xef, 0xdd, 0x68, 0xcb, 0x23, 0x2c, 0x4f,
-       0x45, 0x21, 0x4b, 0x4c, 0x79, 0xc4, 0x96, 0x03, 0x26, 0x3f, 0x9f, 0x04,
-       0xb7, 0xd9, 0x72, 0x3e, 0x2b, 0x5d, 0x6e, 0x9e, 0x0d, 0x0f, 0x8d, 0x09,
-       0xe3, 0x3a, 0x99, 0xeb, 0x1a, 0x64, 0x2b, 0xd6, 0x87, 0x3e, 0xa3, 0x23,
-       0xcd, 0x80, 0xe3, 0x9c, 0xff, 0x76, 0xd8, 0xd6, 0x81, 0xfc, 0xc0, 0x37,
-       0xf4, 0x3f, 0x2b, 0x3d, 0x69, 0xe5, 0x30, 0x07, 0x20, 0x90, 0x9d, 0xfe,
-       0xb6, 0xc4, 0x2e, 0xfc, 0x1e, 0xef, 0x4f, 0xca, 0xec, 0x20, 0xe8, 0xb1,
-       0x9f, 0xbc, 0xb1, 0x15, 0x36, 0x0f, 0x7e, 0xf7, 0xb4, 0xc8, 0x92, 0x9b,
-       0x73, 0xd7, 0xc1, 0x5f, 0x1b, 0xc1, 0xac, 0xe6, 0x0a, 0x9e, 0x7b, 0x1b,
-       0x84, 0x5c, 0xda, 0xed, 0xc1, 0xbd, 0x76, 0xbe, 0xdf, 0xc2, 0x7c, 0x7f,
-       0xad, 0x59, 0x9a, 0x59, 0x5e, 0x5b, 0xb7, 0x51, 0xf6, 0xb8, 0xdb, 0xdd,
-       0xd8, 0x8a, 0xba, 0xe7, 0x51, 0x97, 0x65, 0x9e, 0xcb, 0x1c, 0x9d, 0xd9,
-       0x32, 0xe9, 0xcc, 0xc0, 0xda, 0xd5, 0x13, 0x04, 0xd7, 0xf9, 0x1c, 0x37,
-       0x08, 0xae, 0xf7, 0xfb, 0xdc, 0x67, 0xe5, 0xf9, 0xc0, 0xd8, 0x54, 0x21,
-       0xed, 0x3c, 0x67, 0xe5, 0x75, 0x10, 0xbc, 0xec, 0xf7, 0xca, 0xef, 0x54,
-       0x52, 0x8f, 0xd3, 0xe7, 0x3e, 0x83, 0xe7, 0x33, 0xbe, 0xc9, 0x2b, 0xfa,
-       0x13, 0xb4, 0x8b, 0xab, 0x7e, 0xd0, 0xb0, 0x27, 0x5f, 0xd4, 0x3e, 0x3a,
-       0xf1, 0x67, 0x62, 0xfc, 0x55, 0x18, 0x30, 0x61, 0x2f, 0xb3, 0xc9, 0x65,
-       0x7e, 0xa0, 0xa6, 0xdf, 0xda, 0x77, 0x0a, 0xef, 0x58, 0x16, 0x04, 0x97,
-       0x0c, 0xfc, 0x31, 0xe6, 0x94, 0x2a, 0x71, 0xef, 0xee, 0x03, 0x9a, 0xff,
-       0x04, 0x7e, 0x3d, 0xe9, 0x24, 0xea, 0x2a, 0xe5, 0x1d, 0xee, 0x52, 0xa9,
-       0x9c, 0xc8, 0x5b, 0xb0, 0xfe, 0x5c, 0x63, 0x30, 0x48, 0x1b, 0x60, 0xdf,
-       0xb6, 0xbd, 0xd9, 0xc4, 0x92, 0xe8, 0x4b, 0xa7, 0x37, 0xc1, 0xd7, 0xd5,
-       0xf6, 0x4c, 0x14, 0x7c, 0x3d, 0xd1, 0x16, 0x04, 0xef, 0xf7, 0xc3, 0x35,
-       0xb3, 0xb1, 0x6a, 0xe8, 0xf8, 0x6c, 0xff, 0xb9, 0x66, 0x63, 0xc7, 0x31,
-       0x4f, 0x30, 0xa9, 0xe3, 0xfa, 0xaa, 0x1d, 0x3a, 0x64, 0xdb, 0x57, 0x39,
-       0x7e, 0x8e, 0xe5, 0xef, 0xf3, 0x43, 0x98, 0xaa, 0xed, 0xb3, 0xfd, 0xeb,
-       0xac, 0xcd, 0x19, 0x05, 0x2e, 0x3d, 0xb7, 0x4b, 0xfd, 0x4d, 0x60, 0x74,
-       0x6b, 0x48, 0xc3, 0x7f, 0x17, 0x3c, 0x18, 0x37, 0xcf, 0x99, 0x6d, 0xec,
-       0x63, 0xab, 0x4c, 0x6e, 0xc3, 0x73, 0xf4, 0x5a, 0xdc, 0x87, 0x2f, 0x8b,
-       0xc8, 0x15, 0x89, 0x61, 0xb5, 0xcd, 0x7d, 0x50, 0xfa, 0xac, 0x8c, 0xfb,
-       0x1a, 0xf4, 0x7d, 0x0e, 0xfe, 0x78, 0x93, 0x3c, 0x08, 0x9a, 0x56, 0x03,
-       0xa9, 0xe4, 0x82, 0x4a, 0xf5, 0xce, 0xa8, 0x94, 0x3f, 0xa6, 0xae, 0xe7,
-       0xbc, 0x06, 0x89, 0x8b, 0x19, 0xe2, 0xb7, 0x08, 0xfc, 0x17, 0x81, 0xe3,
-       0x8b, 0xee, 0xf1, 0xfa, 0x56, 0xb7, 0x18, 0xfd, 0x96, 0xd3, 0xb4, 0x69,
-       0xec, 0xf2, 0x3f, 0xf6, 0xc3, 0x35, 0x84, 0x6d, 0xc8, 0x1c, 0x99, 0xba,
-       0x6b, 0x94, 0xe5, 0x1a, 0x41, 0x31, 0xe4, 0x40, 0xf7, 0xa9, 0xe4, 0x84,
-       0x5a, 0x0a, 0x36, 0xed, 0xe8, 0xee, 0x7d, 0x42, 0xf7, 0x93, 0xf2, 0xd3,
-       0x2a, 0x0f, 0x78, 0xb6, 0x4a, 0xd3, 0x0e, 0xe2, 0x99, 0xb0, 0xc6, 0x18,
-       0x4f, 0x72, 0xef, 0x40, 0xdd, 0x31, 0xa5, 0xf7, 0xa0, 0x6d, 0x1d, 0xc2,
-       0x1c, 0x5f, 0x2f, 0xcd, 0xd4, 0x43, 0x8c, 0x93, 0xbd, 0x96, 0x2e, 0x84,
-       0x4c, 0x3a, 0x46, 0x19, 0x18, 0x31, 0xb1, 0xdf, 0xca, 0xcf, 0xa1, 0x9d,
-       0xce, 0x67, 0x89, 0x45, 0x21, 0xa3, 0xa6, 0xc0, 0xc5, 0x87, 0x8e, 0x49,
-       0xb4, 0xc1, 0xfb, 0x5f, 0xcd, 0xc6, 0x6f, 0xa2, 0x0f, 0xc5, 0xb1, 0x1b,
-       0x24, 0xbf, 0x26, 0xde, 0x52, 0x02, 0xfc, 0xcd, 0x32, 0x79, 0x8c, 0x6b,
-       0x11, 0x85, 0xcc, 0xe1, 0xd8, 0x12, 0xcd, 0xf4, 0x07, 0xc1, 0x38, 0xcb,
-       0x4f, 0x92, 0x7f, 0x25, 0xc5, 0x77, 0xb9, 0x93, 0x0b, 0x9b, 0xd4, 0x0a,
-       0x59, 0xdb, 0x62, 0xe1, 0xd0, 0x78, 0x92, 0x92, 0x96, 0x23, 0xd4, 0x37,
-       0xb7, 0xd5, 0xc0, 0x33, 0x7a, 0xc7, 0x94, 0xd7, 0xf8, 0x26, 0xe0, 0xf9,
-       0x3d, 0xc0, 0xd3, 0x62, 0xe1, 0x69, 0x5c, 0x05, 0x4f, 0x4b, 0x08, 0x0f,
-       0xe4, 0x1c, 0xe5, 0x6a, 0xec, 0x9a, 0x74, 0x59, 0x9c, 0xbc, 0x27, 0x9d,
-       0x4a, 0xfb, 0x2f, 0xd4, 0x37, 0x8d, 0xee, 0xf8, 0x80, 0x2b, 0xe3, 0x5a,
-       0xd7, 0x44, 0xaf, 0xe9, 0x2e, 0x2f, 0xc0, 0x7a, 0x15, 0x27, 0xe3, 0x11,
-       0xf6, 0x7a, 0x76, 0xd5, 0x3d, 0x90, 0xff, 0x8b, 0xa9, 0xa8, 0xb5, 0x25,
-       0x4a, 0x3e, 0xfd, 0x96, 0xb8, 0xde, 0xdb, 0xaf, 0xc2, 0xf4, 0x12, 0x60,
-       0x82, 0x3c, 0x3e, 0xd6, 0xe7, 0x8e, 0xca, 0xa5, 0xda, 0x37, 0xb3, 0xb8,
-       0xc6, 0xdc, 0x62, 0x35, 0x73, 0x83, 0xfe, 0x53, 0xe1, 0xdc, 0x20, 0x13,
-       0x51, 0xaf, 0x24, 0xf7, 0x5b, 0x5c, 0xb4, 0x62, 0x4e, 0xb1, 0x9a, 0xf9,
-       0x74, 0x27, 0xf6, 0xb3, 0xcc, 0xcc, 0xa7, 0x27, 0xef, 0xc5, 0x2c, 0x7e,
-       0x57, 0xc3, 0x58, 0xf5, 0x17, 0x67, 0x24, 0x90, 0x29, 0x1f, 0x6b, 0xd4,
-       0x4b, 0xff, 0x24, 0x66, 0xf3, 0x98, 0x15, 0x9e, 0x37, 0x58, 0xfe, 0x72,
-       0x25, 0xaf, 0xfd, 0xb7, 0x2f, 0xad, 0x37, 0x7c, 0x1a, 0xb5, 0xf9, 0x6b,
-       0xfc, 0xdd, 0xb1, 0xde, 0xee, 0xef, 0xe7, 0xd2, 0xf2, 0xfb, 0xeb, 0x69,
-       0x97, 0x34, 0x78, 0x43, 0xab, 0xca, 0x62, 0x28, 0xbb, 0x7d, 0xbd, 0x95,
-       0x0b, 0x28, 0xbb, 0x07, 0x7e, 0x1a, 0xf3, 0x34, 0xf8, 0x8e, 0x32, 0xb8,
-       0x16, 0x27, 0x7d, 0x60, 0x45, 0xf2, 0x3c, 0xe5, 0x22, 0x6d, 0x4a, 0xcc,
-       0x51, 0x7d, 0x27, 0x8c, 0xa3, 0xe3, 0x77, 0x3d, 0xdb, 0x9f, 0xf8, 0x26,
-       0xae, 0xe5, 0xdb, 0x53, 0xe0, 0xfb, 0x03, 0xbe, 0x13, 0x9d, 0x65, 0x1e,
-       0x80, 0xa6, 0xe1, 0xda, 0xbe, 0xaf, 0x47, 0xdf, 0x21, 0x2d, 0x93, 0x5e,
-       0xae, 0xd7, 0x74, 0xd3, 0x44, 0x5d, 0x7c, 0x8c, 0xf4, 0xc7, 0x58, 0x72,
-       0xb3, 0xd6, 0x8f, 0xd5, 0x75, 0x6c, 0x82, 0xae, 0x89, 0x1b, 0x1e, 0x75,
-       0xcd, 0x7e, 0x77, 0xb5, 0xbf, 0x31, 0xf4, 0x47, 0x3b, 0x0d, 0x7e, 0xba,
-       0xc7, 0x68, 0x0e, 0xe5, 0x97, 0x13, 0x55, 0x57, 0x6a, 0x3f, 0x33, 0xa6,
-       0xf3, 0x8e, 0x96, 0xeb, 0x4e, 0xd8, 0xb1, 0x49, 0xb7, 0x26, 0xfe, 0x5f,
-       0x1d, 0x5f, 0x1c, 0xb5, 0x4d, 0x40, 0x65, 0x8d, 0x32, 0x35, 0x40, 0x1a,
-       0xe5, 0xdc, 0xb5, 0x0d, 0x75, 0x0d, 0xed, 0x08, 0x43, 0x9f, 0xb4, 0x9d,
-       0xa2, 0xd7, 0x64, 0x0b, 0x8d, 0xc6, 0x67, 0x89, 0xcb, 0xe6, 0x06, 0x9d,
-       0x47, 0x80, 0xb2, 0x72, 0xa8, 0xcb, 0xa2, 0x32, 0xdb, 0xff, 0xbf, 0x83,
-       0xf4, 0x5e, 0xd6, 0xad, 0xbb, 0x6f, 0x9f, 0x98, 0x11, 0x8d, 0xa7, 0xbf,
-       0xa8, 0xe2, 0xc9, 0xce, 0x2d, 0xbe, 0x7a, 0x6e, 0x05, 0xc0, 0x7b, 0x0f,
-       0x64, 0x27, 0xd7, 0xc9, 0xe4, 0x6f, 0x3f, 0x2e, 0x4e, 0x34, 0xd3, 0x5b,
-       0x6f, 0x6e, 0xa5, 0x10, 0xaf, 0x9c, 0x1b, 0x68, 0x35, 0x9c, 0x17, 0x69,
-       0x3b, 0xae, 0xf7, 0x89, 0x94, 0x22, 0x2c, 0xad, 0xab, 0x70, 0x1b, 0xd2,
-       0x9d, 0xa1, 0xb9, 0xa7, 0x34, 0xcd, 0xb5, 0x58, 0x9a, 0x43, 0x5d, 0x97,
-       0xfb, 0xde, 0xa3, 0x2d, 0x55, 0x9a, 0xdb, 0x60, 0x69, 0xee, 0x99, 0xf5,
-       0x66, 0x4f, 0xfc, 0xfd, 0x2d, 0x66, 0x4f, 0xea, 0x2f, 0x57, 0x3d, 0x6f,
-       0xa2, 0xcd, 0x08, 0x5f, 0x2c, 0x7c, 0xae, 0x85, 0xf5, 0x0c, 0x60, 0xad,
-       0x95, 0x35, 0x4d, 0x36, 0xee, 0xc6, 0xfd, 0x73, 0xfa, 0x7d, 0x51, 0x79,
-       0x14, 0x76, 0x50, 0xbe, 0xfc, 0x8f, 0xc1, 0x02, 0x7c, 0xbf, 0xa9, 0x65,
-       0xdd, 0x7b, 0x5b, 0x0b, 0xf9, 0x6d, 0x06, 0xbf, 0x0e, 0xd6, 0xf8, 0x3c,
-       0x98, 0x2f, 0xca, 0xfe, 0x01, 0xeb, 0x01, 0xb9, 0xbc, 0x5c, 0x97, 0x31,
-       0x0b, 0xe3, 0xe3, 0x30, 0x66, 0x68, 0xf6, 0x13, 0x29, 0xe7, 0xef, 0x84,
-       0x4f, 0x74, 0x0f, 0xf4, 0x24, 0xe9, 0xfb, 0xa5, 0x16, 0x93, 0xe7, 0x1b,
-       0x87, 0x1e, 0xfb, 0x65, 0x9b, 0x0b, 0x75, 0xf8, 0x57, 0xeb, 0xe7, 0xf8,
-       0x82, 0xf6, 0x1d, 0xd2, 0xcc, 0xdf, 0xb7, 0x98, 0x98, 0xf1, 0xb7, 0x5a,
-       0xc8, 0x67, 0x6a, 0xdb, 0x0f, 0x37, 0x68, 0xbe, 0x70, 0xc2, 0xe7, 0xcf,
-       0xb4, 0xae, 0x7c, 0x0e, 0xdb, 0x3d, 0xd9, 0xba, 0xb2, 0x5d, 0x58, 0xfe,
-       0x73, 0x1b, 0x57, 0x96, 0x5f, 0xe3, 0xae, 0x6c, 0xff, 0xf5, 0x55, 0xcf,
-       0x2d, 0x9b, 0x56, 0x3e, 0x5f, 0xbd, 0xea, 0x79, 0x6a, 0xd5, 0xf3, 0x85,
-       0x55, 0xcf, 0x57, 0xb5, 0xad, 0x7c, 0xbe, 0xbd, 0xad, 0x3e, 0xbc, 0x87,
-       0xdb, 0x56, 0xc2, 0x75, 0xa7, 0x8e, 0xf7, 0xcf, 0x54, 0xa2, 0xb2, 0xab,
-       0x80, 0xf7, 0x4e, 0xe7, 0x66, 0xa3, 0xd7, 0x6a, 0xdf, 0x33, 0xbe, 0xf6,
-       0xd7, 0xab, 0xfa, 0xab, 0xb6, 0xdb, 0x5d, 0x6d, 0xe7, 0x57, 0xdb, 0x19,
-       0xd9, 0x36, 0x5b, 0xe1, 0x3b, 0x96, 0x87, 0xfd, 0x9a, 0xb6, 0x53, 0xc5,
-       0x4e, 0x9d, 0x0b, 0x3b, 0xaa, 0x73, 0x61, 0x93, 0xe0, 0xc3, 0x3b, 0x75,
-       0x4c, 0x69, 0x93, 0x42, 0x79, 0xa5, 0x55, 0xc7, 0x95, 0x74, 0x2c, 0xb5,
-       0x30, 0x0a, 0xdb, 0x96, 0x39, 0xb0, 0x81, 0xec, 0xf1, 0xcd, 0xdd, 0xe4,
-       0xc4, 0x1e, 0x0e, 0x86, 0xdd, 0x20, 0x98, 0xf4, 0x6e, 0xb3, 0xf9, 0x62,
-       0xb8, 0x57, 0x4c, 0x1b, 0xea, 0xe0, 0x27, 0xa0, 0x83, 0xab, 0xba, 0xf7,
-       0x4e, 0x8c, 0xb5, 0x00, 0x9a, 0x19, 0x90, 0xdf, 0xad, 0xa4, 0xbe, 0x24,
-       0xfa, 0xcc, 0x4d, 0x3f, 0x6c, 0xb8, 0xa5, 0x4f, 0xbd, 0xdf, 0xf3, 0x61,
-       0xeb, 0x05, 0xf2, 0xb0, 0x3f, 0x08, 0x1a, 0xea, 0x85, 0xbd, 0xe7, 0x69,
-       0xbf, 0xf4, 0xb4, 0xa6, 0x2d, 0xd2, 0x58, 0x8b, 0xce, 0xd7, 0x7f, 0xd4,
-       0x77, 0x62, 0x99, 0xfe, 0x3f, 0x32, 0x71, 0x1a, 0xbf, 0xdb, 0xfd, 0x1a,
-       0xf8, 0x76, 0xa7, 0xb7, 0x05, 0x3e, 0x0a, 0x69, 0x88, 0xf1, 0xaf, 0xcb,
-       0x75, 0x1e, 0x21, 0x03, 0x68, 0x33, 0x51, 0xc6, 0x09, 0x53, 0x83, 0x63,
-       0xc2, 0x79, 0xa7, 0x12, 0x49, 0xa5, 0xed, 0xaa, 0xe0, 0x46, 0x9f, 0x39,
-       0xb6, 0xdc, 0x63, 0x21, 0x3f, 0xef, 0xff, 0xf4, 0x94, 0x97, 0x73, 0x23,
-       0x36, 0x2f, 0x37, 0x53, 0x30, 0xb4, 0x39, 0x41, 0xda, 0x84, 0x3f, 0xb5,
-       0xd8, 0xff, 0xb7, 0x01, 0xed, 0xfb, 0xa4, 0x22, 0xed, 0xff, 0x4d, 0x30,
-       0x17, 0x65, 0x5f, 0x84, 0x7b, 0xff, 0xa7, 0x33, 0x1a, 0x57, 0x77, 0xca,
-       0x81, 0x22, 0x6d, 0xe1, 0x98, 0xce, 0xe7, 0x18, 0xf7, 0x69, 0xa7, 0xc5,
-       0x80, 0xc7, 0x0f, 0x01, 0x7f, 0x2d, 0xb0, 0xb9, 0x47, 0x50, 0x27, 0x22,
-       0x63, 0x60, 0xf1, 0xd9, 0x02, 0xf9, 0x93, 0xf7, 0x28, 0xea, 0xbb, 0x32,
-       0x5f, 0xb8, 0x59, 0xe7, 0xdb, 0x9d, 0x46, 0xdb, 0x27, 0x71, 0xcd, 0x16,
-       0x26, 0xd0, 0x66, 0xaf, 0xae, 0x3f, 0x5b, 0x62, 0x8e, 0xb2, 0x40, 0x2e,
-       0xed, 0x97, 0xfc, 0x5c, 0x97, 0x8c, 0xc5, 0x17, 0x66, 0xa2, 0xcb, 0x71,
-       0x99, 0x8f, 0x6f, 0xe0, 0x1e, 0x47, 0xfe, 0x4a, 0xee, 0x07, 0x4b, 0x74,
-       0x74, 0xbb, 0xea, 0x6d, 0xd3, 0x3e, 0xd7, 0xa0, 0xec, 0xac, 0x0c, 0xc9,
-       0x4d, 0x95, 0xcf, 0x6e, 0x36, 0xb1, 0xa8, 0x15, 0xf1, 0xad, 0xc3, 0xc4,
-       0x8a, 0x3a, 0x1a, 0xe5, 0xb9, 0x25, 0x99, 0x3d, 0x25, 0x12, 0x39, 0x1a,
-       0xc6, 0x12, 0x59, 0xe6, 0x4a, 0xd7, 0x95, 0x80, 0xeb, 0x14, 0x64, 0x6b,
-       0x3c, 0x26, 0x5f, 0xdc, 0x16, 0x8e, 0x95, 0x0b, 0xa6, 0xb7, 0xe5, 0xe4,
-       0xd3, 0xb8, 0xb2, 0x57, 0xa6, 0x4a, 0x19, 0xc5, 0x71, 0xbf, 0x13, 0x50,
-       0x96, 0xa9, 0x21, 0x4f, 0x72, 0x6d, 0xe1, 0xd8, 0xf0, 0x6f, 0x76, 0x84,
-       0xe3, 0xd3, 0xe6, 0x36, 0x67, 0x1e, 0xf2, 0xdc, 0x77, 0x01, 0xfd, 0x45,
-       0x86, 0xee, 0xde, 0x40, 0xdf, 0x61, 0x58, 0xd8, 0x0e, 0x32, 0x5d, 0xb1,
-       0x6f, 0xc2, 0x49, 0xf8, 0x6b, 0xe1, 0x5c, 0x4c, 0xc6, 0x81, 0xa3, 0xdc,
-       0xeb, 0xc2, 0xdb, 0xe7, 0x7a, 0xaa, 0x1e, 0xbc, 0xa3, 0x36, 0x96, 0xc8,
-       0xf8, 0xe0, 0x3a, 0xe0, 0xad, 0x05, 0xe5, 0x1f, 0x94, 0xa9, 0x63, 0x6f,
-       0xdb, 0xcc, 0xbd, 0xec, 0x06, 0xcf, 0xb1, 0x39, 0xa7, 0x3c, 0xbf, 0x73,
-       0x37, 0xea, 0xf0, 0xfd, 0xcd, 0x68, 0x93, 0xca, 0x65, 0x22, 0x9b, 0xe1,
-       0x13, 0x71, 0xdc, 0x20, 0xd2, 0xb5, 0xa3, 0x59, 0xe7, 0x90, 0xca, 0x29,
-       0xea, 0xf3, 0xb0, 0xed, 0xdd, 0x3a, 0x47, 0x03, 0x7e, 0x7b, 0x6e, 0x24,
-       0x42, 0xf9, 0xd5, 0x2b, 0xc3, 0xd4, 0x27, 0xa7, 0x6e, 0xd6, 0xb4, 0xdf,
-       0xbd, 0x8d, 0x67, 0x99, 0xfa, 0x8c, 0x8d, 0x1e, 0x27, 0x8c, 0xa3, 0x28,
-       0x87, 0xfd, 0xfe, 0x9a, 0x30, 0xdc, 0xf5, 0x26, 0x61, 0xb8, 0xeb, 0x4d,
-       0xc2, 0x40, 0x5c, 0x00, 0x8e, 0xca, 0x5f, 0x6c, 0x08, 0x63, 0xd5, 0x97,
-       0x62, 0x1e, 0x07, 0x8b, 0x77, 0xc9, 0xa1, 0xa2, 0xa3, 0xe3, 0x8e, 0x0b,
-       0x8a, 0x32, 0xc1, 0x05, 0x4f, 0x82, 0xf7, 0x8a, 0xe0, 0xcd, 0x22, 0x78,
-       0xb1, 0x08, 0xbe, 0x84, 0xfd, 0x7f, 0x06, 0xf6, 0xff, 0x93, 0x58, 0x9b,
-       0xd3, 0x2b, 0x78, 0x39, 0xad, 0x79, 0x39, 0x5f, 0xa4, 0xaf, 0xd6, 0x7f,
-       0x11, 0x7e, 0x8d, 0xca, 0x70, 0x21, 0x05, 0x55, 0xe2, 0x44, 0xb3, 0xfd,
-       0x9f, 0x24, 0xbf, 0xca, 0x83, 0xfe, 0x0d, 0x68, 0x73, 0x18, 0x34, 0x9e,
-       0xa2, 0x1d, 0x48, 0xfb, 0x27, 0x07, 0xde, 0x3c, 0x4c, 0x5f, 0x4d, 0x5d,
-       0xb9, 0x49, 0xa8, 0x5f, 0xa2, 0x3b, 0x98, 0x7b, 0xc8, 0xb9, 0x26, 0x57,
-       0xe1, 0xc9, 0xf0, 0xef, 0x84, 0x47, 0x3d, 0x43, 0xbe, 0x7d, 0x99, 0x7c,
-       0x5b, 0xc3, 0xab, 0x01, 0xe7, 0x17, 0xb8, 0xdb, 0xea, 0xb5, 0xad, 0xd6,
-       0xdf, 0xb4, 0x5c, 0x5f, 0x8f, 0x5f, 0x22, 0x3f, 0x42, 0x27, 0x11, 0xf7,
-       0xc9, 0x4c, 0x64, 0x8b, 0xc5, 0x3d, 0x6c, 0xb7, 0x1d, 0x97, 0x00, 0xf7,
-       0x9d, 0x92, 0x9b, 0x0f, 0xc4, 0xdb, 0x11, 0xf6, 0x59, 0xed, 0xc7, 0xb5,
-       0xfd, 0x8c, 0x17, 0x1c, 0x19, 0xd9, 0xc6, 0x7d, 0x08, 0x07, 0x7a, 0x3e,
-       0x5c, 0x0f, 0xd8, 0xfb, 0x7a, 0xcd, 0x29, 0x63, 0x29, 0x5b, 0x5b, 0x6c,
-       0xfc, 0x89, 0xfd, 0x1d, 0x5e, 0xb5, 0x4e, 0x17, 0x02, 0x9e, 0x11, 0x9b,
-       0xf2, 0x6e, 0xa8, 0xa1, 0x95, 0xfb, 0x2c, 0xad, 0xa8, 0x55, 0xf3, 0xb8,
-       0xdd, 0xd2, 0x4a, 0x08, 0x6f, 0x3c, 0xa4, 0x95, 0xa6, 0x90, 0x56, 0x72,
-       0x33, 0x21, 0xad, 0xb0, 0xed, 0xed, 0x21, 0xad, 0x24, 0x6b, 0x69, 0x25,
-       0x37, 0xe3, 0xe0, 0x5a, 0x0d, 0x07, 0xe9, 0x85, 0xfd, 0x90, 0x5e, 0x00,
-       0x4b, 0xe5, 0xd6, 0xd6, 0x90, 0x5e, 0xe2, 0xe8, 0xe7, 0x50, 0xd1, 0xe4,
-       0x74, 0xc0, 0xef, 0xb2, 0x3a, 0xc4, 0xc5, 0x9a, 0x1b, 0x1f, 0xb1, 0x3e,
-       0x8d, 0xf8, 0x96, 0x46, 0xaa, 0x79, 0xee, 0xab, 0x68, 0x03, 0xb8, 0x67,
-       0x2e, 0xeb, 0x76, 0x4d, 0x1b, 0xf7, 0xfb, 0x53, 0xa8, 0xbb, 0x07, 0xb4,
-       0x11, 0xe2, 0xe0, 0x7a, 0x8b, 0x83, 0xd5, 0x6b, 0x39, 0x66, 0x71, 0xb0,
-       0xc7, 0xe2, 0x40, 0xf3, 0x4b, 0x8e, 0x6b, 0xa6, 0x34, 0x0e, 0x9a, 0x34,
-       0x0e, 0x44, 0x85, 0x6d, 0xc7, 0xea, 0xe0, 0x80, 0x75, 0xf6, 0xe8, 0xf9,
-       0x47, 0x30, 0xff, 0xfd, 0x98, 0xbf, 0xd2, 0xf3, 0xe7, 0x3a, 0x70, 0xfe,
-       0x80, 0xa5, 0x72, 0x72, 0x79, 0xfe, 0x6d, 0xe8, 0xe3, 0x60, 0x31, 0xa2,
-       0xe7, 0x0f, 0xdb, 0x7e, 0x30, 0x9c, 0xff, 0xe9, 0x8a, 0xc9, 0x7f, 0x3e,
-       0xbd, 0x46, 0xcf, 0x4d, 0x59, 0xde, 0xf0, 0xb4, 0x5f, 0xcc, 0x98, 0xf6,
-       0x19, 0xe8, 0xb6, 0x69, 0x3f, 0x69, 0xcf, 0x43, 0x19, 0x7b, 0xe9, 0x1b,
-       0x3e, 0x79, 0xe7, 0xe3, 0x3a, 0x0f, 0xe5, 0x71, 0xda, 0x4d, 0xc5, 0x36,
-       0x19, 0x99, 0xae, 0x85, 0x9b, 0xf0, 0xe6, 0xb4, 0x1c, 0xcd, 0x62, 0x7e,
-       0xe3, 0x7e, 0x2f, 0xe4, 0x9b, 0xa6, 0x25, 0x94, 0xa7, 0x72, 0xc3, 0x91,
-       0x26, 0x51, 0x0f, 0x7c, 0x08, 0x73, 0x8e, 0xca, 0x66, 0xaf, 0xdb, 0xdd,
-       0xa1, 0xa8, 0x0b, 0x2f, 0xab, 0xd1, 0x85, 0xed, 0x56, 0x17, 0x6e, 0xa2,
-       0x2e, 0x04, 0xdc, 0x77, 0xca, 0xe1, 0x22, 0xd7, 0x2f, 0x97, 0x6c, 0x82,
-       0xfe, 0xff, 0x81, 0xc7, 0xb3, 0x27, 0x3a, 0x6e, 0x96, 0x38, 0xac, 0x69,
-       0x99, 0x3a, 0x2d, 0xa5, 0xcf, 0x6a, 0x2c, 0xd2, 0xc6, 0x8e, 0x33, 0x16,
-       0x4a, 0xbd, 0xf7, 0xe3, 0xe0, 0x73, 0x75, 0xf4, 0xde, 0x64, 0xd1, 0xd8,
-       0x6f, 0x0d, 0xb0, 0x09, 0xe5, 0x44, 0x3b, 0xae, 0x8d, 0x3c, 0xab, 0xd0,
-       0xdb, 0xa3, 0x9a, 0xa5, 0xe1, 0x44, 0xab, 0x4c, 0x4c, 0x1b, 0x1b, 0x57,
-       0x9d, 0x00, 0xfe, 0x4f, 0x30, 0xdf, 0x55, 0x74, 0x7e, 0x7e, 0xb6, 0x04,
-       0x3b, 0x77, 0xf6, 0x4e, 0x93, 0xb7, 0x32, 0xdd, 0xa0, 0x7f, 0xd3, 0x06,
-       0xc9, 0xfb, 0x69, 0xe8, 0xbb, 0x98, 0x4c, 0xa0, 0xcf, 0xee, 0x6d, 0x8d,
-       0x98, 0x73, 0x1c, 0x6d, 0xe9, 0xf3, 0x31, 0x8e, 0xd6, 0x28, 0xd1, 0xd9,
-       0xb8, 0xce, 0xad, 0xe7, 0xd9, 0xd1, 0xcc, 0x60, 0x1b, 0xde, 0x31, 0x9f,
-       0xc1, 0xc5, 0x58, 0xa1, 0xec, 0x47, 0xbf, 0x47, 0xc5, 0xee, 0xf7, 0x0c,
-       0x69, 0xfd, 0x17, 0x39, 0xea, 0xda, 0x33, 0x74, 0x83, 0x58, 0xf7, 0x7a,
-       0x7a, 0xd1, 0x18, 0xb9, 0x19, 0xac, 0x9f, 0x3a, 0x15, 0xc5, 0xbd, 0x13,
-       0xf7, 0xb0, 0xbf, 0x50, 0x8f, 0x40, 0x37, 0xbe, 0xb3, 0x6f, 0xa3, 0x34,
-       0x03, 0xdf, 0xb3, 0x0a, 0xb8, 0x36, 0x39, 0x59, 0x39, 0xcd, 0x0b, 0x55,
-       0x7a, 0x78, 0xf2, 0x75, 0xf9, 0x81, 0x34, 0x41, 0x5a, 0xa0, 0x5c, 0x24,
-       0x6d, 0x50, 0x26, 0x3a, 0xfa, 0x6c, 0x03, 0xe9, 0xe1, 0x09, 0xdf, 0x8b,
-       0x70, 0xdf, 0xde, 0xc4, 0xe5, 0x49, 0x1b, 0xa4, 0xf9, 0xa4, 0x8e, 0xd7,
-       0xa7, 0xe5, 0x7b, 0x92, 0x6e, 0xeb, 0x86, 0x5d, 0xf6, 0x2f, 0xbb, 0xc6,
-       0xe6, 0xdc, 0xad, 0xa6, 0x39, 0xe8, 0x26, 0xe6, 0xd0, 0xf5, 0xca, 0xfb,
-       0x2a, 0x39, 0xe0, 0xe1, 0x5e, 0x28, 0xe5, 0x3b, 0x75, 0x5e, 0xe2, 0xee,
-       0xc2, 0x46, 0xb9, 0xc5, 0x8f, 0xd9, 0xb8, 0xfb, 0x41, 0xd0, 0xc1, 0xa2,
-       0x23, 0x27, 0xce, 0xe2, 0x3a, 0xe7, 0x70, 0xfd, 0xce, 0xfb, 0xe9, 0x94,
-       0x22, 0xb3, 0x7b, 0xd1, 0xc4, 0xa2, 0xf4, 0xb9, 0x13, 0xfa, 0x0c, 0xc8,
-       0x82, 0xd3, 0x74, 0xe2, 0xd0, 0x46, 0xe3, 0x4b, 0x03, 0x16, 0xaf, 0xd1,
-       0x1d, 0xa1, 0x2d, 0xe7, 0x07, 0x41, 0x96, 0x76, 0x83, 0x28, 0xed, 0x23,
-       0xc1, 0xe7, 0x43, 0x19, 0xe3, 0x13, 0x5b, 0x9d, 0xc6, 0x53, 0x2f, 0x5a,
-       0x5a, 0x91, 0x88, 0x1a, 0x7a, 0xc6, 0x69, 0x38, 0x71, 0x9c, 0x6b, 0xa6,
-       0xf3, 0xa4, 0x0d, 0x5d, 0x3d, 0xe7, 0x54, 0xe9, 0xea, 0x1b, 0xf6, 0xb7,
-       0x1a, 0x6a, 0x92, 0x74, 0xaa, 0x09, 0xf3, 0x1d, 0x2e, 0x84, 0x30, 0x7e,
-       0x1f, 0x70, 0x11, 0x1e, 0xd0, 0xed, 0xec, 0x9f, 0xe1, 0x5a, 0x02, 0x2c,
-       0xf7, 0x01, 0xee, 0xf3, 0x80, 0xf9, 0x02, 0x2e, 0xd5, 0x11, 0x91, 0x3f,
-       0x76, 0x22, 0xb3, 0xb5, 0xf0, 0x12, 0xc6, 0xd3, 0x16, 0xde, 0xd7, 0x82,
-       0xd5, 0x95, 0xc5, 0x81, 0x2e, 0xc0, 0x43, 0x38, 0x5f, 0x02, 0x8c, 0xb4,
-       0x5b, 0x9f, 0xc7, 0xb3, 0x0b, 0xf8, 0x5e, 0xb0, 0x30, 0x81, 0x1e, 0xa7,
-       0xff, 0x47, 0xf5, 0x77, 0x81, 0x76, 0xf4, 0x9f, 0xdb, 0xe7, 0xce, 0x55,
-       0x32, 0xa0, 0xc7, 0x21, 0x9e, 0xa7, 0x8a, 0x4b, 0xb4, 0x03, 0xc0, 0xf7,
-       0x3f, 0x94, 0xc8, 0xa9, 0x84, 0x1c, 0x2a, 0x70, 0x0f, 0xe8, 0x24, 0xf0,
-       0xa1, 0xcf, 0xa4, 0xa0, 0xce, 0x15, 0xb8, 0xa0, 0xec, 0x67, 0xb7, 0xe3,
-       0xea, 0xc5, 0xf5, 0x56, 0x5c, 0x20, 0x87, 0xd9, 0x13, 0xb8, 0xfa, 0xd0,
-       0xb7, 0x8a, 0x37, 0x09, 0x73, 0xa9, 0xbe, 0x8d, 0x36, 0xda, 0xb6, 0xcc,
-       0xa9, 0xa1, 0x01, 0xe0, 0x6f, 0x00, 0xb0, 0x25, 0x70, 0x31, 0xff, 0xf8,
-       0x87, 0x8e, 0x9c, 0x7a, 0x19, 0x17, 0x18, 0xec, 0x14, 0x08, 0xf3, 0xd4,
-       0x20, 0x2e, 0x28, 0xb1, 0x53, 0x69, 0x5c, 0x23, 0xb8, 0xfe, 0xd2, 0x31,
-       0x3c, 0xd7, 0x09, 0x7c, 0x85, 0x3c, 0x02, 0x9c, 0xaf, 0xe0, 0xb9, 0xaf,
-       0x3b, 0x6f, 0x9c, 0xe7, 0x7e, 0xe2, 0x18, 0x9e, 0x7b, 0xc5, 0xa9, 0xf2,
-       0xdc, 0x59, 0x47, 0x3d, 0xfc, 0x8c, 0x13, 0x79, 0x98, 0xbe, 0xc4, 0x59,
-       0xc7, 0xf0, 0x7f, 0x44, 0x86, 0xf7, 0x82, 0x96, 0x1e, 0x5e, 0xc0, 0x45,
-       0xba, 0x7a, 0x16, 0xe5, 0x2f, 0xac, 0x1a, 0xf7, 0xf9, 0x37, 0x31, 0xee,
-       0xab, 0x76, 0x5c, 0x51, 0xd5, 0x71, 0x2f, 0xa0, 0xef, 0x97, 0xec, 0xb8,
-       0x17, 0x6a, 0xc6, 0x05, 0xad, 0x3c, 0xbc, 0x84, 0x8b, 0x74, 0xf1, 0x22,
-       0xca, 0x43, 0x99, 0x80, 0x85, 0x6e, 0x6e, 0xd0, 0x67, 0x9d, 0xe2, 0x5e,
-       0xc3, 0xb2, 0x6e, 0x4c, 0xd7, 0xe8, 0x87, 0x37, 0xa2, 0x1f, 0x27, 0x8b,
-       0xb4, 0x11, 0x17, 0x6a, 0xe4, 0x02, 0x7d, 0xa3, 0x40, 0x8e, 0x69, 0x3f,
-       0x88, 0x3e, 0x11, 0xfd, 0xa3, 0xd5, 0xb6, 0xd5, 0x27, 0x75, 0xee, 0xd8,
-       0xaf, 0x15, 0x3a, 0xe5, 0xd3, 0x05, 0xda, 0x84, 0xa4, 0x97, 0x20, 0x98,
-       0xd8, 0x41, 0xfb, 0x34, 0x17, 0x5c, 0xe2, 0x91, 0x4e, 0x3c, 0xf7, 0x33,
-       0x6b, 0x75, 0x46, 0x69, 0x18, 0xbe, 0x7b, 0xe6, 0xe8, 0xaf, 0x40, 0x67,
-       0x34, 0x00, 0x6e, 0xd2, 0x5b, 0x87, 0xdc, 0x58, 0x52, 0x53, 0x9b, 0x25,
-       0x21, 0x37, 0x15, 0x1a, 0x61, 0xf7, 0x30, 0xaf, 0xaa, 0x59, 0xba, 0x77,
-       0xc4, 0x4c, 0xde, 0xb7, 0x1b, 0xc7, 0x6f, 0xd7, 0xe4, 0xa1, 0xc7, 0x13,
-       0x78, 0xff, 0x7b, 0x2e, 0xe5, 0x60, 0xdc, 0xbb, 0x56, 0xe7, 0xf4, 0x74,
-       0xed, 0xa0, 0xdd, 0x72, 0xbd, 0xd6, 0xe1, 0xd1, 0x35, 0x76, 0x92, 0xea,
-       0x70, 0xa5, 0x6a, 0xa3, 0x8d, 0x17, 0x52, 0x49, 0xc2, 0xf5, 0x90, 0x70,
-       0xff, 0xeb, 0x1e, 0xc9, 0xfb, 0xad, 0xf0, 0x0b, 0x18, 0x3b, 0x4f, 0xf5,
-       0xd2, 0x36, 0x9a, 0x9d, 0x76, 0x6d, 0x5e, 0xf4, 0x46, 0x79, 0x4e, 0x8f,
-       0xd3, 0xa8, 0x61, 0x34, 0x67, 0x25, 0xb8, 0x8f, 0x10, 0xd3, 0xe7, 0x73,
-       0x66, 0xcb, 0x2d, 0x5a, 0xef, 0xcc, 0x96, 0x99, 0x87, 0x0f, 0x7f, 0xaa,
-       0xcc, 0xbc, 0x7b, 0x5f, 0xdc, 0x77, 0xc2, 0xcf, 0x2d, 0x6f, 0x91, 0xf1,
-       0xe9, 0x75, 0xd2, 0xe8, 0xa9, 0xf8, 0x66, 0xc8, 0x47, 0xb6, 0xe9, 0xda,
-       0x01, 0xff, 0x70, 0x66, 0xab, 0x3c, 0x39, 0xc3, 0xbe, 0x3b, 0x64, 0x6e,
-       0x5e, 0x1c, 0xf7, 0x9d, 0xeb, 0x51, 0x07, 0x72, 0x7d, 0x07, 0xcb, 0x92,
-       0xb8, 0x8b, 0x72, 0xdf, 0x19, 0x95, 0x73, 0x03, 0x7c, 0x66, 0xee, 0xbf,
-       0x44, 0xd9, 0xdf, 0xb9, 0x81, 0x4e, 0x79, 0x7c, 0x1e, 0x34, 0x01, 0xb9,
-       0x3f, 0x72, 0x82, 0x30, 0x89, 0xec, 0x9a, 0x65, 0x2c, 0xbd, 0xdb, 0x65,
-       0xdc, 0x94, 0xfb, 0x34, 0xb7, 0x0c, 0x70, 0x2c, 0xe8, 0x25, 0xe8, 0xb8,
-       0xae, 0x1d, 0x46, 0x16, 0xa4, 0x67, 0x1b, 0x50, 0xce, 0x7e, 0xe1, 0x3f,
-       0xee, 0x65, 0x3f, 0x61, 0x5b, 0x85, 0x39, 0x35, 0x6a, 0x7a, 0x59, 0x5a,
-       0xa5, 0x3f, 0xce, 0xfc, 0x4c, 0xf6, 0x37, 0xfb, 0xe8, 0xd5, 0x7b, 0x21,
-       0xdc, 0x53, 0x36, 0xb6, 0x15, 0xd7, 0x44, 0xef, 0x29, 0xc0, 0xae, 0xba,
-       0x42, 0xdb, 0x17, 0x73, 0x15, 0xae, 0x20, 0x63, 0x51, 0xe1, 0x1a, 0x25,
-       0xe4, 0xd1, 0xe2, 0xf2, 0x3a, 0x6d, 0x69, 0x58, 0xb9, 0x4e, 0xa4, 0x15,
-       0x7f, 0xcc, 0xda, 0x1e, 0x8b, 0x92, 0x83, 0x5d, 0xd6, 0xab, 0xd7, 0x6c,
-       0x11, 0xb6, 0xac, 0x5d, 0x33, 0x6d, 0xcf, 0xe6, 0xc3, 0x35, 0x1b, 0x85,
-       0xc6, 0x29, 0xab, 0x4d, 0x5c, 0x33, 0x97, 0xf1, 0x6e, 0xe0, 0x3d, 0x87,
-       0x75, 0xca, 0x61, 0x8d, 0x72, 0xe5, 0x0e, 0x99, 0x3d, 0xa6, 0x3a, 0x1b,
-       0x44, 0x92, 0xe3, 0x5e, 0x87, 0x4c, 0xce, 0x33, 0x96, 0xb0, 0x05, 0x36,
-       0xd8, 0x56, 0x5c, 0x9d, 0x78, 0x66, 0x3b, 0xf0, 0x54, 0x59, 0xa1, 0x6d,
-       0xd3, 0x1a, 0x3b, 0xeb, 0x71, 0x8c, 0xcd, 0x1c, 0xe1, 0x27, 0x80, 0x87,
-       0x2a, 0xef, 0x4c, 0xd5, 0xc4, 0x9f, 0x38, 0x57, 0xad, 0x43, 0x31, 0xdf,
-       0xb8, 0x5e, 0x4f, 0x1d, 0x87, 0x2a, 0x36, 0xbe, 0x19, 0x7b, 0x2a, 0x41,
-       0x7b, 0x2a, 0x5b, 0x72, 0xcd, 0xf9, 0x80, 0x51, 0xf8, 0x4e, 0x5e, 0xef,
-       0x26, 0xd2, 0xfa, 0xd8, 0x0c, 0xe1, 0x8a, 0x85, 0x70, 0xad, 0x58, 0x33,
-       0x9e, 0xe7, 0x5a, 0x1b, 0xe7, 0x98, 0x5a, 0xce, 0x5f, 0x34, 0xb1, 0x7d,
-       0xc6, 0x51, 0x3a, 0xeb, 0xc0, 0x74, 0xa7, 0xb6, 0x61, 0x45, 0x8d, 0xc9,
-       0x81, 0x22, 0xcf, 0x82, 0x31, 0x9e, 0x78, 0x23, 0xe3, 0x49, 0xbd, 0xb3,
-       0xf2, 0x5e, 0x8c, 0xcd, 0x5c, 0x1d, 0x65, 0xe3, 0x37, 0x1b, 0x6c, 0x8e,
-       0x48, 0x6d, 0x0c, 0xc7, 0xe4, 0xf2, 0xac, 0xcc, 0x8b, 0x4e, 0x8d, 0x2e,
-       0x61, 0x9d, 0x7f, 0x5d, 0xef, 0x0d, 0x4a, 0x29, 0x02, 0xed, 0x37, 0x3e,
-       0x90, 0x1a, 0x34, 0xe7, 0x60, 0x92, 0xb2, 0xb3, 0x68, 0xe6, 0x7f, 0x5e,
-       0xe7, 0xf4, 0x98, 0xdc, 0x45, 0x93, 0xef, 0x73, 0x8f, 0x9c, 0x87, 0x0e,
-       0xaf, 0xae, 0x6d, 0x93, 0x4c, 0x02, 0x17, 0x59, 0xbd, 0x2f, 0x91, 0x94,
-       0xec, 0xc0, 0xc7, 0x37, 0xf1, 0x9c, 0x44, 0x0c, 0xeb, 0x93, 0x9f, 0xe1,
-       0xd9, 0x49, 0xf6, 0x7b, 0xb1, 0xbe, 0x28, 0x66, 0x99, 0x87, 0x0f, 0x59,
-       0xf9, 0xb6, 0xbe, 0x44, 0xb3, 0x7e, 0xbf, 0xce, 0xe6, 0x5b, 0x3b, 0x22,
-       0x37, 0x06, 0xf2, 0x87, 0x10, 0x9f, 0x8f, 0xd9, 0x39, 0x25, 0x75, 0xcc,
-       0x4a, 0x82, 0x73, 0x7e, 0xc2, 0xc6, 0x2c, 0x39, 0x97, 0x1b, 0x2c, 0x7d,
-       0x1b, 0xfb, 0xa7, 0x6a, 0x43, 0x9b, 0x7d, 0xbf, 0x27, 0xb5, 0x2c, 0xec,
-       0xb7, 0xb6, 0xb3, 0x8e, 0xf3, 0x1c, 0x17, 0x9d, 0x13, 0x10, 0xfa, 0x46,
-       0x3d, 0x35, 0x7e, 0x81, 0xf1, 0xe5, 0xf2, 0xd3, 0xf5, 0x64, 0x54, 0xd5,
-       0x27, 0xa4, 0x2f, 0x37, 0xb1, 0x8d, 0xdf, 0x2d, 0x08, 0x7d, 0xb9, 0x7e,
-       0xeb, 0xcb, 0xb5, 0x6a, 0x5f, 0xce, 0xc4, 0x1e, 0x5a, 0x97, 0x7d, 0xb9,
-       0xfc, 0x74, 0x0e, 0xb4, 0x12, 0x7e, 0x67, 0xc1, 0xd8, 0x42, 0x93, 0x05,
-       0x9e, 0x79, 0x69, 0x94, 0xec, 0xa8, 0x82, 0xdf, 0x60, 0x7c, 0x2c, 0xc6,
-       0x2a, 0x94, 0xfa, 0x96, 0xf5, 0x2f, 0x3a, 0x25, 0xdd, 0xbe, 0x0e, 0xf3,
-       0xbe, 0x53, 0xaf, 0xf9, 0x5c, 0xc1, 0xec, 0x7d, 0x66, 0xf7, 0x32, 0x26,
-       0xc4, 0x73, 0x4d, 0x9a, 0xbf, 0x92, 0xc3, 0x91, 0x5e, 0x63, 0xcf, 0x7a,
-       0xdf, 0x04, 0xde, 0x4f, 0x02, 0xe7, 0x31, 0x3b, 0x6e, 0x12, 0x30, 0x1d,
-       0xc0, 0xda, 0x5c, 0x6b, 0x65, 0x32, 0xc7, 0xde, 0xd3, 0xc4, 0xd8, 0xc0,
-       0x7c, 0x21, 0x8c, 0x11, 0x46, 0xec, 0x99, 0x4a, 0x2f, 0xd2, 0xe8, 0xad,
-       0xab, 0x6b, 0xab, 0x9e, 0x7e, 0x5d, 0xdd, 0x44, 0x5a, 0xba, 0x53, 0xe7,
-       0xb9, 0xac, 0x1f, 0x48, 0xed, 0xd1, 0x39, 0xf2, 0x3a, 0xc6, 0x98, 0x13,
-       0xe6, 0x94, 0x7d, 0x57, 0xde, 0xa1, 0x65, 0xfe, 0x01, 0x9f, 0xfa, 0x6b,
-       0x87, 0xfe, 0xdd, 0x38, 0x14, 0x04, 0xe7, 0x06, 0xee, 0x86, 0xad, 0xe2,
-       0xb9, 0xdf, 0x97, 0xee, 0xc4, 0xb0, 0xb6, 0x9d, 0xb0, 0x46, 0x7b, 0x9b,
-       0x65, 0x9d, 0x77, 0xb3, 0xcd, 0x99, 0xc9, 0x41, 0x6e, 0xa6, 0x60, 0x33,
-       0xf1, 0x4c, 0x70, 0x8f, 0x7d, 0x97, 0x0b, 0x9a, 0x41, 0x47, 0x1f, 0x13,
-       0x23, 0x63, 0xb2, 0x55, 0x19, 0xc3, 0x5c, 0x83, 0x34, 0x09, 0x39, 0x7a,
-       0x44, 0x52, 0xfc, 0xee, 0x07, 0xc7, 0xce, 0xcb, 0xa5, 0xd0, 0xcb, 0x6c,
-       0xa7, 0xbf, 0xd9, 0x83, 0x67, 0xee, 0xe1, 0x78, 0xee, 0x41, 0xe8, 0x96,
-       0xeb, 0xd7, 0xea, 0x96, 0x04, 0xfd, 0xfa, 0x6c, 0x89, 0xbe, 0xe1, 0x7a,
-       0xb4, 0xe9, 0x90, 0x8f, 0x4f, 0x77, 0xb7, 0x91, 0xb7, 0xc6, 0x20, 0xd7,
-       0xd5, 0xfd, 0xe1, 0x59, 0x20, 0x96, 0xf1, 0x3d, 0xfb, 0x6d, 0x92, 0xe4,
-       0xfb, 0x5d, 0xf9, 0x7c, 0x25, 0x95, 0x5c, 0x82, 0x6e, 0x1a, 0x73, 0x7e,
-       0xf1, 0x72, 0x13, 0x53, 0x7d, 0x7b, 0x9b, 0x39, 0x3b, 0xd0, 0x4c, 0x9b,
-       0xdd, 0xc6, 0x59, 0x6b, 0x69, 0x76, 0xc9, 0xca, 0xe3, 0x20, 0x68, 0x1e,
-       0xd0, 0x32, 0x78, 0x0f, 0x65, 0xf0, 0x01, 0xbf, 0xc7, 0xd0, 0xbe, 0xf6,
-       0x99, 0x02, 0xac, 0x23, 0xf0, 0x30, 0x10, 0x65, 0x7e, 0x9e, 0xe5, 0x4f,
-       0x2f, 0xbd, 0x68, 0xe5, 0x92, 0x72, 0xd6, 0xf2, 0xa5, 0xba, 0x2a, 0xb6,
-       0x42, 0xe6, 0x1e, 0x9a, 0xa6, 0x3e, 0xf6, 0x17, 0xbe, 0x0b, 0x39, 0x95,
-       0xd5, 0x78, 0xe8, 0x90, 0xfb, 0xa6, 0x25, 0x7d, 0x1e, 0xba, 0x2a, 0x3f,
-       0xbf, 0x92, 0x37, 0xd7, 0xf6, 0xc7, 0xb9, 0x7e, 0xb8, 0xcd, 0xf8, 0xb6,
-       0x2b, 0xe7, 0xba, 0x80, 0xb9, 0xa6, 0xf5, 0x5c, 0xb9, 0x6f, 0xf3, 0x31,
-       0x3b, 0xd7, 0xf5, 0xe1, 0x5c, 0x07, 0x57, 0xce, 0x35, 0xf4, 0xed, 0x43,
-       0xb9, 0x9b, 0xd4, 0xf9, 0xf2, 0x3a, 0x4f, 0x7b, 0x7a, 0xbd, 0x0c, 0x97,
-       0x5a, 0xad, 0xbc, 0x74, 0xa1, 0x7b, 0x98, 0xc3, 0xbe, 0x70, 0xaf, 0x2b,
-       0x16, 0x67, 0x8a, 0x78, 0xa0, 0xac, 0x6d, 0xd3, 0x67, 0x6c, 0x66, 0xe1,
-       0x5f, 0xdd, 0x5a, 0x60, 0xdd, 0xf0, 0xfd, 0xc5, 0x62, 0xc7, 0xa1, 0x4f,
-       0x4d, 0xbf, 0xa9, 0x77, 0x4d, 0x4c, 0xc1, 0xc4, 0x87, 0x19, 0x17, 0x36,
-       0x67, 0x7f, 0x99, 0x8b, 0x78, 0x07, 0x78, 0xea, 0x53, 0x85, 0xd4, 0x60,
-       0x26, 0x42, 0x39, 0x7a, 0x5c, 0x0e, 0x55, 0x46, 0xa4, 0x4b, 0x9f, 0xff,
-       0x7c, 0xdd, 0xd8, 0x71, 0xba, 0x36, 0x76, 0xcc, 0x74, 0x02, 0xc6, 0x8e,
-       0xf7, 0xfc, 0x0c, 0xb1, 0x63, 0x71, 0x4c, 0xec, 0xb8, 0x9e, 0x7f, 0x35,
-       0x55, 0x3c, 0x8e, 0x79, 0x35, 0x43, 0x96, 0x2c, 0x3a, 0xd9, 0xf9, 0x16,
-       0xdc, 0xcf, 0xe2, 0x1e, 0xc3, 0xfd, 0x3c, 0xee, 0x2e, 0xee, 0x17, 0x70,
-       0x8f, 0xcb, 0xd4, 0xb2, 0xce, 0x38, 0x0e, 0xb9, 0x41, 0x5d, 0xc6, 0xb6,
-       0xc6, 0x1f, 0x98, 0x2b, 0xb7, 0xf3, 0x7b, 0x2d, 0xce, 0xec, 0x3c, 0xe7,
-       0xd0, 0x2a, 0x93, 0xd3, 0x94, 0xd9, 0x6d, 0x52, 0x9a, 0x0e, 0x6d, 0xdb,
-       0x9f, 0xef, 0xe0, 0x9e, 0xc1, 0x98, 0x84, 0xb6, 0xeb, 0x3d, 0x1d, 0x66,
-       0xaf, 0xf1, 0x3b, 0x58, 0xe3, 0x8d, 0x58, 0x83, 0x93, 0x72, 0x7e, 0x66,
-       0xe3, 0x0a, 0x1b, 0x36, 0x69, 0x63, 0x82, 0x33, 0x56, 0xf7, 0xd6, 0x97,
-       0x11, 0xb5, 0xeb, 0x9f, 0xb0, 0x67, 0xcb, 0xc2, 0x1c, 0xa1, 0xa4, 0x5e,
-       0x9f, 0xd1, 0xca, 0x71, 0x8c, 0x37, 0x28, 0xe9, 0x19, 0xce, 0x73, 0xf9,
-       0x9b, 0x11, 0x90, 0x87, 0x27, 0xa0, 0x57, 0x57, 0xd0, 0x25, 0xe8, 0x96,
-       0x73, 0x73, 0x40, 0xbb, 0x8f, 0xca, 0x6c, 0x89, 0xf0, 0xf5, 0x24, 0x22,
-       0xfa, 0xac, 0x19, 0x9e, 0x67, 0x4c, 0x8e, 0xfb, 0x70, 0x25, 0x3c, 0x67,
-       0xb6, 0x89, 0x67, 0x07, 0x57, 0x9d, 0x35, 0xb3, 0xfa, 0x59, 0xdb, 0x0e,
-       0x3c, 0x73, 0x16, 0xce, 0xa1, 0x1e, 0x3d, 0x05, 0x32, 0xa9, 0xf3, 0xce,
-       0x36, 0xcb, 0x63, 0x0f, 0x2e, 0xe7, 0xbc, 0xb6, 0xc1, 0x46, 0xe9, 0x84,
-       0x89, 0x3c, 0x1a, 0x1d, 0xea, 0x81, 0x8f, 0xc7, 0x3c, 0x99, 0x9e, 0xc4,
-       0x6d, 0x3a, 0x17, 0xb9, 0x7a, 0xee, 0xaf, 0x9a, 0x8f, 0x1c, 0x9e, 0xb3,
-       0x4a, 0xe8, 0xef, 0x5a, 0xec, 0xd4, 0xe5, 0x71, 0xcc, 0x87, 0xfb, 0x7e,
-       0x1a, 0x0f, 0x09, 0x7e, 0xa7, 0xeb, 0x29, 0xe0, 0x60, 0xb2, 0xf2, 0x6d,
-       0xd0, 0xbb, 0x63, 0xcf, 0x9c, 0x91, 0xc6, 0x06, 0x64, 0xa2, 0x9c, 0x70,
-       0x26, 0xca, 0x03, 0xce, 0xbe, 0xb2, 0x7d, 0x37, 0xb0, 0x67, 0xb3, 0x34,
-       0xe3, 0xf7, 0x4c, 0x97, 0x33, 0x06, 0x7c, 0xe5, 0x8b, 0xdd, 0x4e, 0x5a,
-       0xdf, 0x3d, 0x7b, 0x87, 0x1c, 0xc0, 0x5a, 0x0d, 0xcf, 0xc4, 0xb5, 0x9c,
-       0xaf, 0x7e, 0x5b, 0x2a, 0x5c, 0x57, 0x7e, 0x13, 0x89, 0x7c, 0x7c, 0x5c,
-       0x7f, 0xe7, 0xc8, 0xd8, 0x0e, 0x27, 0xd1, 0xdf, 0x71, 0x1b, 0x13, 0xef,
-       0x73, 0xb2, 0xba, 0x1f, 0xb3, 0x1e, 0xf9, 0xe2, 0x09, 0xdc, 0x57, 0x9f,
-       0x79, 0x0e, 0xf5, 0x8c, 0x85, 0xbb, 0x10, 0xdc, 0x63, 0xe4, 0xd5, 0x71,
-       0x99, 0xaa, 0x30, 0x7f, 0xc4, 0xd1, 0x7c, 0x34, 0x59, 0x3e, 0x00, 0x9d,
-       0xb4, 0xf2, 0xcc, 0xdf, 0xce, 0xea, 0x3a, 0x24, 0x67, 0x84, 0xb0, 0x70,
-       0x0d, 0x56, 0x9e, 0x87, 0xbf, 0xf8, 0xbf, 0x70, 0x5f, 0xd1, 0xc8, 0x50,
-       0x0b, 0x47, 0x9a, 0xf2, 0xce, 0xc8, 0x95, 0x69, 0x39, 0x08, 0x78, 0x0e,
-       0xe3, 0x52, 0xf7, 0xf3, 0x3b, 0x2c, 0xf3, 0x92, 0x9f, 0xbb, 0x4f, 0xd4,
-       0x43, 0xe7, 0x9d, 0xe8, 0x43, 0x07, 0x25, 0xf2, 0xd0, 0xa2, 0xd3, 0xf0,
-       0x50, 0xb7, 0xf6, 0xcb, 0x77, 0xfb, 0xdd, 0x89, 0x7d, 0x72, 0x52, 0xa2,
-       0xf7, 0x2b, 0x7d, 0xfe, 0x2b, 0xef, 0x32, 0xc6, 0x77, 0x52, 0x22, 0xf7,
-       0xc7, 0xec, 0xd9, 0x51, 0x13, 0xd7, 0x5b, 0xd2, 0x7c, 0xff, 0x9b, 0x71,
-       0xe2, 0x6c, 0x49, 0x8e, 0x6b, 0xde, 0x19, 0x86, 0x9e, 0xc8, 0x94, 0x92,
-       0xcb, 0x75, 0x4c, 0xbe, 0xe7, 0xf3, 0x9b, 0x0d, 0xbf, 0xb0, 0x4e, 0x8f,
-       0xc3, 0xef, 0x38, 0x18, 0x9d, 0x91, 0xb9, 0x2c, 0xcc, 0xfd, 0x34, 0x6b,
-       0xca, 0xf7, 0x67, 0xb1, 0x86, 0x3d, 0x58, 0x2f, 0x8e, 0xe7, 0xe8, 0xfd,
-       0x5c, 0x9e, 0x9d, 0x75, 0xa5, 0x2f, 0xd1, 0xb4, 0x6c, 0x07, 0xb1, 0xee,
-       0x7d, 0xd2, 0x04, 0xb8, 0xd5, 0x43, 0x79, 0x63, 0xd7, 0x09, 0xe9, 0x54,
-       0x20, 0xb9, 0x49, 0xb3, 0x3d, 0x83, 0xbb, 0xf5, 0x1a, 0xde, 0x6b, 0x69,
-       0x66, 0x9d, 0xb1, 0x1f, 0xf1, 0x6c, 0xe8, 0x22, 0x2f, 0xbb, 0xa6, 0x7f,
-       0x08, 0x3d, 0xcf, 0x7d, 0x17, 0x6d, 0x2f, 0xd6, 0xb1, 0x05, 0xc9, 0x4b,
-       0xcf, 0x58, 0xbf, 0x32, 0x08, 0xa6, 0x7d, 0x1f, 0x78, 0xac, 0xe7, 0x4b,
-       0x6e, 0x71, 0xe6, 0x4a, 0x5b, 0x9d, 0xd9, 0x52, 0x20, 0x13, 0x3e, 0xbf,
-       0xe3, 0xc1, 0x1c, 0x00, 0xda, 0x5b, 0x2c, 0xeb, 0x86, 0x6e, 0xfd, 0xeb,
-       0xcd, 0x3c, 0x8f, 0x74, 0x93, 0xf7, 0xa2, 0x98, 0x7a, 0xc4, 0x31, 0x7d,
-       0xe4, 0xee, 0xe3, 0x59, 0xe1, 0xf7, 0x34, 0xfa, 0x12, 0x71, 0xfd, 0x5d,
-       0x8f, 0xcf, 0xa1, 0x1d, 0xc6, 0x28, 0x72, 0xdc, 0x67, 0x9d, 0x59, 0xc8,
-       0xb3, 0xb9, 0x69, 0x9e, 0xe1, 0x67, 0x3e, 0x6d, 0xa4, 0x53, 0xc9, 0x15,
-       0xee, 0xa4, 0xfd, 0x06, 0x5c, 0x0e, 0x2e, 0x50, 0x44, 0x97, 0xf5, 0xb9,
-       0xe3, 0xcb, 0xdf, 0x85, 0x0b, 0xcb, 0xc2, 0xef, 0xc3, 0x29, 0x9d, 0x3b,
-       0x0d, 0x5f, 0xf6, 0xb1, 0x31, 0xf9, 0x89, 0x33, 0x5f, 0x78, 0xc5, 0x79,
-       0xb4, 0x90, 0xbe, 0xea, 0x12, 0xd0, 0xc7, 0x39, 0xbf, 0x97, 0xf2, 0x0b,
-       0x36, 0x5f, 0x41, 0x72, 0x95, 0x09, 0x99, 0xe9, 0xe8, 0x76, 0xef, 0xd7,
-       0x6b, 0x33, 0x03, 0x9c, 0x7d, 0x1b, 0xeb, 0xf7, 0xc9, 0x38, 0xf5, 0xdb,
-       0x78, 0x41, 0x81, 0x97, 0xd5, 0xcf, 0xe3, 0x82, 0x6d, 0xdb, 0xa8, 0x6d,
-       0x94, 0x7d, 0x3e, 0xeb, 0x6d, 0x75, 0x86, 0x4b, 0x5b, 0xb0, 0x8e, 0x7b,
-       0xa1, 0x3f, 0x1d, 0xd8, 0x69, 0xa0, 0x6d, 0x94, 0x4d, 0x02, 0x07, 0xe3,
-       0xbe, 0x91, 0xe7, 0xc3, 0x92, 0xd3, 0x3e, 0x9e, 0xb9, 0xa7, 0x95, 0x89,
-       0x99, 0x05, 0xc1, 0x1c, 0xec, 0x83, 0x6c, 0x7f, 0x09, 0xbc, 0xf0, 0x08,
-       0xae, 0xb7, 0xdb, 0x3d, 0xed, 0x17, 0x2e, 0xb2, 0xa7, 0xed, 0xca, 0xc9,
-       0x8a, 0x3e, 0xd7, 0xae, 0xf3, 0xab, 0x92, 0xea, 0xbf, 0x5f, 0xa2, 0xd7,
-       0x4a, 0xf5, 0xe8, 0x9c, 0xb4, 0xb4, 0x7c, 0x38, 0x6e, 0xf4, 0x30, 0x61,
-       0x4a, 0x02, 0x9e, 0xad, 0xc0, 0x05, 0xe1, 0x31, 0x6d, 0x44, 0x6d, 0xba,
-       0x94, 0xfa, 0x70, 0x49, 0x3e, 0x12, 0x0f, 0xcf, 0x14, 0xa0, 0x1f, 0xc8,
-       0xb8, 0x8f, 0x5d, 0x6a, 0xf4, 0xe4, 0xe6, 0x3a, 0xfd, 0x84, 0x73, 0x73,
-       0xec, 0xdc, 0x48, 0xb7, 0x7f, 0x96, 0xa0, 0x4f, 0xb1, 0x24, 0x4d, 0xab,
-       0xea, 0x33, 0xa6, 0xbf, 0xe1, 0x72, 0x73, 0x46, 0x81, 0x75, 0x5d, 0xd8,
-       0xa6, 0xb4, 0x73, 0x89, 0x47, 0xbd, 0x6e, 0x05, 0x25, 0x3c, 0x67, 0x00,
-       0x6e, 0xae, 0x5c, 0xe1, 0xbe, 0x43, 0x91, 0x0e, 0x43, 0x5c, 0x7f, 0x5b,
-       0xf3, 0xc9, 0x78, 0x81, 0xb1, 0x95, 0x47, 0x83, 0xf4, 0x28, 0x79, 0x8c,
-       0x7d, 0xf0, 0x7d, 0x41, 0xc7, 0x73, 0xf7, 0xfa, 0x8c, 0x15, 0x75, 0x1f,
-       0xbf, 0x43, 0x85, 0x72, 0x0a, 0xfa, 0xb7, 0xb8, 0xe8, 0xf0, 0x1b, 0x78,
-       0x37, 0x0a, 0xee, 0xf3, 0x8b, 0xce, 0x77, 0xa7, 0x9f, 0xc5, 0x73, 0x83,
-       0xfd, 0xee, 0x9d, 0xd1, 0x53, 0x22, 0xc5, 0x70, 0xbe, 0x89, 0x1c, 0xd6,
-       0xfe, 0x02, 0xd6, 0xbe, 0xfe, 0x77, 0xee, 0xf0, 0xae, 0x8c, 0x77, 0xe5,
-       0x0f, 0x07, 0xe9, 0x36, 0xd2, 0x22, 0xe9, 0xef, 0xb5, 0xfc, 0xe6, 0x41,
-       0xcd, 0x17, 0x93, 0xc5, 0xc7, 0xc1, 0x17, 0x69, 0xee, 0x37, 0x07, 0x0f,
-       0xfb, 0x37, 0x80, 0x2f, 0xf6, 0xc8, 0xef, 0xc3, 0x2e, 0xf8, 0xdd, 0xca,
-       0x10, 0xf8, 0x63, 0x10, 0xfc, 0x32, 0x00, 0x1e, 0xf1, 0xb5, 0x8d, 0xfc,
-       0x04, 0xf4, 0x1f, 0xf4, 0x9a, 0xb3, 0xaf, 0xd4, 0xe5, 0x64, 0x4b, 0x9e,
-       0x33, 0x51, 0xe2, 0xf7, 0x5a, 0xd4, 0x5b, 0x1b, 0x24, 0x9a, 0x98, 0x13,
-       0xf2, 0x42, 0x37, 0x73, 0x1c, 0xdb, 0x81, 0xab, 0x53, 0xc4, 0xd5, 0x5c,
-       0xa5, 0xcf, 0xbd, 0x04, 0x3c, 0xd1, 0xae, 0x79, 0xa2, 0xd5, 0x49, 0xbb,
-       0x37, 0x58, 0x9e, 0x78, 0x11, 0x3c, 0x71, 0x7e, 0x0d, 0x4f, 0x3c, 0x6d,
-       0xe9, 0x7f, 0xa1, 0x86, 0x27, 0xe6, 0x6c, 0xd9, 0xcc, 0x45, 0x78, 0xe2,
-       0x52, 0x2f, 0xf5, 0xa5, 0x31, 0x79, 0x15, 0x3c, 0x21, 0x8a, 0x3c, 0x71,
-       0xa9, 0xe6, 0x09, 0xc6, 0x8e, 0xc8, 0x17, 0x9d, 0x90, 0x23, 0xe4, 0x8b,
-       0xb3, 0xb2, 0x04, 0xbe, 0x78, 0x5e, 0x71, 0xec, 0x19, 0xda, 0x0a, 0x25,
-       0xfa, 0x64, 0x27, 0x8a, 0x5d, 0xe0, 0x77, 0x25, 0xff, 0x65, 0x3a, 0x08,
-       0x16, 0xe1, 0xa7, 0x3f, 0x08, 0x7b, 0x3e, 0xaa, 0xbf, 0xa9, 0xb8, 0x00,
-       0xba, 0x0f, 0xe9, 0x7d, 0xc2, 0x01, 0xbd, 0x1f, 0x9e, 0xc5, 0x1c, 0x26,
-       0xd4, 0x7f, 0x86, 0x2f, 0xec, 0x62, 0x5d, 0x69, 0xe7, 0x1f, 0xd3, 0x3c,
-       0xd4, 0x00, 0x7d, 0xf0, 0xe8, 0x00, 0x63, 0x4d, 0x9e, 0xbb, 0x4f, 0x75,
-       0xe7, 0x46, 0x00, 0x73, 0x44, 0xdd, 0x2f, 0x8c, 0x73, 0xb4, 0xad, 0xb2,
-       0xf3, 0x29, 0x23, 0x46, 0x21, 0xeb, 0xcc, 0xbb, 0x5c, 0xd0, 0x04, 0x9b,
-       0xb4, 0x49, 0x19, 0x1b, 0x5d, 0xed, 0x48, 0xb9, 0x1f, 0x84, 0x00, 0x6d,
-       0x84, 0xbd, 0xb0, 0x0b, 0xab, 0x3d, 0x52, 0xa8, 0xb5, 0xf1, 0xff, 0x03,
-       0x6c, 0x7c, 0xb6, 0x91, 0xa8, 0xb1, 0xf1, 0x7f, 0xcd, 0xf2, 0x1a, 0x7f,
-       0xbb, 0xda, 0xde, 0x3f, 0x00, 0xf8, 0x76, 0x2f, 0xdb, 0xfb, 0xec, 0x83,
-       0x76, 0x87, 0xc8, 0xf5, 0xb0, 0xf9, 0xde, 0x0d, 0x1e, 0xbc, 0x01, 0xbe,
-       0xd4, 0x7b, 0x0a, 0xae, 0xec, 0x29, 0xb4, 0xc3, 0xe7, 0xee, 0x94, 0xf7,
-       0x4e, 0x6f, 0x95, 0x9d, 0x25, 0xff, 0x12, 0x69, 0xee, 0x80, 0x8d, 0x5a,
-       0x00, 0x9c, 0x11, 0x2b, 0xb7, 0xcf, 0x02, 0x6f, 0xdd, 0xc9, 0x9f, 0xa8,
-       0x17, 0xad, 0x5d, 0xc4, 0xb3, 0x8e, 0xf5, 0xfa, 0x89, 0xa3, 0x3d, 0x63,
-       0x29, 0x1d, 0x72, 0xea, 0x18, 0xbd, 0xaf, 0x24, 0xec, 0x72, 0x1f, 0x36,
-       0xc9, 0x16, 0xf4, 0xc7, 0x78, 0xf2, 0x46, 0x79, 0xfa, 0xaa, 0xe8, 0x5d,
-       0x59, 0xcd, 0x87, 0x9d, 0x4e, 0x66, 0x1a, 0x3e, 0xc0, 0xde, 0x18, 0xe6,
-       0xa0, 0xda, 0x37, 0xcb, 0x75, 0xb2, 0x53, 0xcf, 0x67, 0x46, 0x0e, 0x42,
-       0x37, 0xff, 0x41, 0x61, 0xa7, 0x2c, 0x8d, 0xb6, 0xe1, 0x39, 0x26, 0x4f,
-       0x17, 0xfa, 0xe0, 0xfb, 0xbc, 0x0b, 0x38, 0x6a, 0xc4, 0x73, 0xa3, 0x0c,
-       0x5f, 0x42, 0x5e, 0x6d, 0x91, 0x45, 0x94, 0xbf, 0x5b, 0x7e, 0xc1, 0x96,
-       0xb3, 0x8c, 0xbc, 0xd1, 0x82, 0xb6, 0x31, 0x39, 0x57, 0xa0, 0x5d, 0xa9,
-       0x79, 0x62, 0xf0, 0x7b, 0xd2, 0x97, 0xfe, 0x1e, 0xec, 0xd4, 0xb3, 0xb8,
-       0x9e, 0x91, 0xd4, 0x9e, 0x71, 0xa7, 0x2f, 0xd9, 0xed, 0x40, 0x77, 0xe2,
-       0x8a, 0x3a, 0x7d, 0x6e, 0xa3, 0x73, 0x85, 0xed, 0xa3, 0x41, 0x9e, 0xd9,
-       0xab, 0x12, 0x2d, 0x58, 0x93, 0xed, 0x4e, 0x8f, 0x2d, 0xe3, 0x73, 0xca,
-       0x78, 0x40, 0xa7, 0xd4, 0x96, 0x0d, 0x22, 0x5d, 0x2d, 0xb0, 0x79, 0x26,
-       0x44, 0xb5, 0xb7, 0x48, 0x54, 0xba, 0x67, 0x55, 0x27, 0xca, 0x3c, 0x5b,
-       0x16, 0x6f, 0x81, 0x7e, 0x40, 0x59, 0x07, 0xca, 0xb6, 0xd9, 0xb2, 0xb6,
-       0x16, 0x69, 0x44, 0xd9, 0x8c, 0xe6, 0xf9, 0xf3, 0x3d, 0x9e, 0x9b, 0x75,
-       0x9a, 0xa5, 0xeb, 0x44, 0x0b, 0x64, 0xc3, 0x46, 0x59, 0xbc, 0xaa, 0x49,
-       0xba, 0xf0, 0x8e, 0x71, 0x6e, 0xff, 0x44, 0x4c, 0xae, 0x3d, 0xd1, 0x9d,
-       0xf8, 0x38, 0xe6, 0xd0, 0x7d, 0x8a, 0x71, 0xef, 0xfc, 0x25, 0x8c, 0xfb,
-       0x74, 0x9d, 0xe2, 0xbd, 0x49, 0xcb, 0x1f, 0xe2, 0xc3, 0x7c, 0x93, 0x88,
-       0x32, 0xf9, 0x24, 0xfc, 0x5c, 0xea, 0xf0, 0x6e, 0xfb, 0xfd, 0x8c, 0xe3,
-       0x97, 0xd0, 0x6f, 0x9b, 0xa5, 0x5d, 0x52, 0x24, 0x3f, 0x52, 0x0f, 0xe1,
-       0x3e, 0xe3, 0x48, 0xbe, 0x2a, 0xb3, 0xe6, 0xc9, 0x57, 0xc7, 0x14, 0x73,
-       0x59, 0x50, 0x56, 0xf9, 0xc5, 0xc0, 0xac, 0x31, 0x79, 0xc1, 0xc8, 0xa5,
-       0x0f, 0x18, 0xb9, 0xf4, 0xd8, 0x99, 0x15, 0x72, 0xe9, 0xbc, 0x96, 0x4b,
-       0x7b, 0x05, 0xf7, 0xf9, 0xf3, 0x90, 0x4b, 0x2f, 0xe2, 0xd9, 0xd5, 0x72,
-       0x29, 0x2e, 0xd6, 0x5e, 0x96, 0xaf, 0xea, 0xf1, 0xe7, 0x8a, 0x51, 0x6d,
-       0x57, 0xe5, 0x67, 0x60, 0x93, 0x14, 0xa7, 0xac, 0xfe, 0x96, 0xa1, 0x36,
-       0xe9, 0x19, 0xfc, 0xa9, 0x84, 0x36, 0xe7, 0x7f, 0xba, 0x84, 0xdf, 0xee,
-       0x7c, 0x5e, 0x51, 0x86, 0xbd, 0x0a, 0x19, 0x26, 0xaa, 0xbe, 0x0c, 0xc3,
-       0xbb, 0x32, 0xde, 0x95, 0xd9, 0xef, 0x8f, 0x7e, 0x3a, 0xe6, 0x52, 0x7e,
-       0x50, 0x66, 0x40, 0x26, 0x15, 0x21, 0x93, 0x8a, 0x90, 0x53, 0x45, 0xc8,
-       0x25, 0xd8, 0x6c, 0x67, 0x8a, 0x90, 0x4b, 0x45, 0xc8, 0x25, 0xc8, 0xb8,
-       0x27, 0x20, 0xe3, 0x8c, 0x4c, 0x1b, 0x85, 0x4c, 0x9b, 0x91, 0xfb, 0xac,
-       0xae, 0x37, 0xb1, 0x92, 0x7e, 0xeb, 0x23, 0x0d, 0xe8, 0x18, 0xf2, 0x99,
-       0x9a, 0xd8, 0xe0, 0x8d, 0x47, 0x34, 0xbf, 0xbb, 0x9e, 0xba, 0xc2, 0x61,
-       0x0e, 0xcd, 0x4f, 0xb4, 0xff, 0xbe, 0x9d, 0xbf, 0xa5, 0x09, 0x7c, 0xfd,
-       0x03, 0xcb, 0xd7, 0xdb, 0x97, 0xf9, 0x3a, 0xe5, 0x30, 0x56, 0x5c, 0x9f,
-       0xaf, 0x3b, 0xec, 0xbb, 0x5c, 0xb0, 0x0e, 0x7c, 0xbd, 0x6e, 0x15, 0x5f,
-       0xc7, 0xc0, 0xd7, 0x7b, 0xd6, 0xf0, 0xf5, 0x06, 0x67, 0x58, 0xb7, 0xe1,
-       0x19, 0x09, 0x3e, 0x37, 0x3a, 0x55, 0xbe, 0xbe, 0x47, 0xf3, 0xf5, 0x21,
-       0xf0, 0xf5, 0x75, 0x35, 0x7c, 0xbd, 0x47, 0x52, 0x37, 0x67, 0x22, 0x5b,
-       0x65, 0xfc, 0x7e, 0xd5, 0xbe, 0x49, 0xfe, 0x49, 0x4c, 0x7b, 0xc3, 0x63,
-       0xc3, 0xd3, 0xed, 0x92, 0x7d, 0xe8, 0x15, 0x94, 0x91, 0xcf, 0x52, 0x63,
-       0x69, 0xc7, 0x95, 0x83, 0x47, 0x7e, 0x22, 0x0b, 0x9a, 0xb7, 0x44, 0x26,
-       0x8e, 0xc4, 0x64, 0xf2, 0x08, 0xe3, 0x10, 0x7f, 0x63, 0xe9, 0xbd, 0x49,
-       0x26, 0xf7, 0x32, 0x6f, 0x2e, 0x2a, 0xe3, 0x47, 0xe0, 0x6f, 0x1d, 0x61,
-       0x1c, 0xe2, 0xa5, 0x65, 0x1e, 0x5b, 0x80, 0x6c, 0x19, 0x3f, 0xc2, 0xb5,
-       0x8e, 0xa1, 0x9f, 0x16, 0x39, 0x74, 0x44, 0xe4, 0xb6, 0x23, 0x51, 0xf9,
-       0xe8, 0x91, 0x65, 0x5e, 0x1b, 0x0d, 0x79, 0xed, 0x59, 0xf0, 0x5a, 0xb7,
-       0xe5, 0x35, 0xb5, 0xcc, 0x6b, 0x7f, 0x5a, 0xc3, 0x6b, 0x6c, 0x4f, 0x5e,
-       0x7b, 0xce, 0x96, 0xf1, 0x39, 0x2a, 0xfb, 0x8e, 0x74, 0xca, 0xf8, 0x43,
-       0x6f, 0x91, 0x89, 0xfb, 0x09, 0xab, 0xf9, 0x8e, 0x13, 0x6d, 0xb1, 0x99,
-       0x4a, 0x37, 0xfa, 0x0f, 0x73, 0x88, 0xf4, 0xf7, 0x10, 0x7a, 0x67, 0x25,
-       0x95, 0xe3, 0x78, 0x8d, 0xf0, 0xa3, 0x4f, 0xc0, 0xbf, 0xd8, 0x07, 0x98,
-       0x6e, 0x39, 0x22, 0xa9, 0xa8, 0xbc, 0x2c, 0x53, 0xfe, 0x27, 0x2e, 0x37,
-       0xf6, 0x04, 0x6c, 0x11, 0x6d, 0xfb, 0xa4, 0x25, 0xfb, 0xce, 0x40, 0xfb,
-       0x18, 0xa5, 0xb2, 0x30, 0x16, 0xc0, 0xb8, 0xb9, 0x63, 0xbe, 0xc7, 0xc4,
-       0xfc, 0xc7, 0x06, 0x7d, 0xe6, 0x45, 0xc7, 0x6c, 0x07, 0xf8, 0x9e, 0xcf,
-       0xb0, 0x67, 0xf4, 0x59, 0x43, 0xb6, 0x7f, 0x44, 0x7f, 0x1b, 0x91, 0x31,
-       0xf5, 0x7c, 0x99, 0xdf, 0xb0, 0x81, 0xff, 0x59, 0xe6, 0xb7, 0xb0, 0xf6,
-       0xb7, 0x9b, 0xf8, 0x2c, 0xf9, 0xee, 0x87, 0x0e, 0xbf, 0x5d, 0x35, 0xa5,
-       0x73, 0xbd, 0xf0, 0xbb, 0xcc, 0x67, 0xd6, 0x7f, 0x84, 0xf1, 0x8e, 0x64,
-       0x52, 0xbd, 0xf7, 0x72, 0xe6, 0x1e, 0xec, 0x9d, 0x67, 0xdd, 0xad, 0x96,
-       0x47, 0xb7, 0x6a, 0xbf, 0x83, 0x36, 0xd6, 0x78, 0xe9, 0x45, 0xc9, 0xd3,
-       0x36, 0x19, 0xdd, 0xea, 0xe4, 0x66, 0x92, 0x97, 0x1b, 0xfb, 0x79, 0xdd,
-       0xa5, 0xcc, 0x3b, 0x4c, 0xab, 0xb5, 0x32, 0xf9, 0x84, 0x84, 0x32, 0x39,
-       0x75, 0x33, 0xbf, 0xb7, 0x9b, 0x3d, 0xa2, 0xbf, 0x2f, 0x95, 0xec, 0x56,
-       0x9c, 0xd3, 0xa7, 0x21, 0x5f, 0x43, 0x5a, 0x48, 0xc8, 0x27, 0x8f, 0x90,
-       0x1e, 0x54, 0xbc, 0x55, 0x3e, 0x61, 0xe9, 0x61, 0x46, 0x0a, 0x90, 0x3b,
-       0x47, 0x8e, 0x7c, 0x54, 0x66, 0x6e, 0x5c, 0x4d, 0x0f, 0x13, 0x55, 0x7a,
-       0x88, 0xc3, 0x3e, 0x73, 0x6a, 0xe9, 0xe1, 0x97, 0x97, 0xe9, 0x61, 0xc6,
-       0xf9, 0xe7, 0xd2, 0xc3, 0xf5, 0x2b, 0xe8, 0x61, 0x4a, 0xd3, 0xc3, 0xce,
-       0x65, 0x7a, 0x98, 0x3a, 0xc2, 0x71, 0xf5, 0xde, 0xa8, 0xbb, 0xe8, 0x70,
-       0xcd, 0x97, 0x69, 0x21, 0x39, 0xa9, 0xf3, 0xf5, 0x53, 0x39, 0x9e, 0x6f,
-       0xda, 0xa0, 0x18, 0x27, 0xa9, 0xae, 0x7f, 0xeb, 0xbf, 0xe8, 0xfa, 0xbf,
-       0xfc, 0xff, 0x79, 0xfd, 0xd5, 0xa5, 0xcc, 0xdd, 0xe7, 0x99, 0x55, 0x23,
-       0x8f, 0x43, 0x7a, 0x88, 0x5d, 0x6a, 0xf4, 0x02, 0xd7, 0x98, 0xcf, 0x90,
-       0x67, 0x90, 0x7f, 0x67, 0x20, 0xff, 0x9e, 0x84, 0xfc, 0x3b, 0xbd, 0x62,
-       0x4f, 0x60, 0xd0, 0xc6, 0x23, 0x02, 0x39, 0xe8, 0x57, 0xf1, 0xb1, 0x38,
-       0x40, 0x7c, 0x98, 0xfc, 0x13, 0xe6, 0xfe, 0xae, 0xc4, 0x49, 0x54, 0xe7,
-       0x1c, 0x3d, 0xea, 0xd7, 0xe2, 0x84, 0x70, 0xbf, 0x5c, 0x33, 0x47, 0xfc,
-       0x2e, 0xf3, 0x79, 0x46, 0xe7, 0x91, 0xe4, 0xf5, 0x1e, 0x14, 0xf1, 0xc2,
-       0x3d, 0x28, 0xe2, 0x24, 0xaa, 0xed, 0xfd, 0x7c, 0xb9, 0x49, 0xe7, 0xd0,
-       0x1f, 0x98, 0x8f, 0xcb, 0x62, 0x9c, 0x31, 0x3e, 0x7e, 0x97, 0x90, 0x7e,
-       0xb3, 0x97, 0xc8, 0x4b, 0x8e, 0xb9, 0x72, 0xe0, 0xe9, 0x0d, 0x96, 0xb6,
-       0x19, 0x1b, 0xe4, 0x99, 0xdd, 0x70, 0x2f, 0xa2, 0xd7, 0xca, 0xba, 0x96,
-       0x9a, 0x98, 0x25, 0xf0, 0x3e, 0x2d, 0xc9, 0xcc, 0x00, 0xee, 0xf3, 0x1c,
-       0x7b, 0xbf, 0x4c, 0x3d, 0x38, 0x01, 0x5b, 0x6e, 0x2f, 0x74, 0x0e, 0xcf,
-       0x9f, 0x99, 0xef, 0x70, 0x13, 0x86, 0x59, 0xfd, 0xdd, 0x29, 0xfa, 0x80,
-       0xa4, 0x87, 0x04, 0x9e, 0x67, 0x6c, 0x5c, 0x29, 0x21, 0xf9, 0xc2, 0x05,
-       0xf3, 0x6d, 0xcb, 0xc2, 0x4b, 0xb8, 0xbf, 0xde, 0x7a, 0x18, 0x3f, 0x64,
-       0xd4, 0xdc, 0xd1, 0xd7, 0x92, 0xa4, 0xcb, 0x26, 0xc7, 0xa5, 0x1a, 0x37,
-       0x99, 0x91, 0xc3, 0xda, 0x7e, 0x1e, 0xb2, 0xb9, 0x2d, 0xa9, 0xd1, 0x9c,
-       0x18, 0x1b, 0xfa, 0x77, 0x60, 0x43, 0x7f, 0xb1, 0x92, 0xd6, 0xfb, 0x58,
-       0xa7, 0x61, 0x43, 0x3f, 0x01, 0xdd, 0x43, 0x9d, 0x13, 0xb7, 0x3a, 0x67,
-       0x4a, 0xdd, 0xa8, 0x75, 0xce, 0x37, 0xb5, 0xce, 0x79, 0xef, 0x1a, 0x9d,
-       0x73, 0x48, 0x75, 0x97, 0xa8, 0x73, 0x86, 0xd5, 0x1e, 0x87, 0xf6, 0xe2,
-       0xe6, 0x3a, 0x3a, 0xe7, 0x7d, 0xf2, 0x2e, 0xfb, 0xee, 0x1e, 0x79, 0xff,
-       0x0e, 0xbd, 0x77, 0xe3, 0xce, 0x2a, 0x7e, 0x6b, 0xc9, 0xe8, 0xa0, 0xeb,
-       0x54, 0xaf, 0xde, 0xf3, 0xfd, 0x46, 0x8d, 0xce, 0xe9, 0x52, 0x03, 0xce,
-       0xb0, 0x6e, 0xc3, 0xd8, 0x04, 0x9f, 0x7d, 0x27, 0x3d, 0xda, 0x84, 0xe7,
-       0x84, 0x44, 0x8e, 0x60, 0xee, 0xe6, 0x7b, 0x50, 0xca, 0xbc, 0x7b, 0xab,
-       0x7d, 0xa7, 0xc2, 0xf2, 0xa8, 0x29, 0xef, 0xb6, 0xe5, 0x46, 0x57, 0x75,
-       0xa9, 0x4e, 0xad, 0xab, 0xb6, 0x83, 0xa1, 0x66, 0xa1, 0x5f, 0x67, 0x8b,
-       0xa1, 0xce, 0xe2, 0x6f, 0xc6, 0x9e, 0x19, 0xa3, 0x08, 0x63, 0xd8, 0x49,
-       0xd4, 0xc1, 0x55, 0x0c, 0x6d, 0x4a, 0xfe, 0x86, 0xaf, 0x80, 0x6b, 0x1e,
-       0x78, 0xbd, 0x19, 0xfc, 0xf3, 0x6f, 0x0a, 0x8c, 0x81, 0xb6, 0xcb, 0xd1,
-       0xe9, 0xda, 0x77, 0x9d, 0xf2, 0x9e, 0xe9, 0x2d, 0xb2, 0xbf, 0xf4, 0x2d,
-       0xf0, 0xc1, 0x56, 0x99, 0x2a, 0x15, 0xf4, 0x79, 0xf5, 0x4d, 0xfa, 0x3b,
-       0x1e, 0xfc, 0xbe, 0x8d, 0x91, 0x91, 0x3b, 0x1d, 0x23, 0x23, 0xd3, 0xaa,
-       0x6a, 0xb3, 0x86, 0x7d, 0xf2, 0xdb, 0x21, 0x23, 0xa5, 0x84, 0xfe, 0xc6,
-       0xe9, 0x6c, 0xe5, 0x0a, 0xf9, 0xc2, 0x31, 0x75, 0xa7, 0xaa, 0x9e, 0xef,
-       0xd5, 0x36, 0xeb, 0xdc, 0x0a, 0x9b, 0xf5, 0xaf, 0x64, 0xf1, 0xfd, 0x31,
-       0xcc, 0x13, 0x34, 0x7c, 0xe5, 0xf7, 0xb8, 0x17, 0xda, 0x1e, 0x97, 0x0b,
-       0x32, 0xa2, 0xf1, 0x47, 0x79, 0xda, 0x02, 0x39, 0xb8, 0xa4, 0xf5, 0xeb,
-       0x66, 0xd0, 0x20, 0x65, 0xe9, 0xc7, 0xe4, 0x45, 0x2d, 0xcf, 0x36, 0x5b,
-       0xdb, 0x75, 0x81, 0xb1, 0xd4, 0x23, 0xb4, 0x5d, 0xbf, 0x69, 0xcb, 0x59,
-       0x96, 0x4a, 0x2c, 0x09, 0xf5, 0x5d, 0x1c, 0x32, 0x94, 0xf2, 0xf4, 0x8d,
-       0xda, 0xae, 0x5f, 0xb3, 0x7d, 0x50, 0x7e, 0x1a, 0xd9, 0xbd, 0xdd, 0x59,
-       0xb0, 0x65, 0x7c, 0x0e, 0xe3, 0xe9, 0x5e, 0x3a, 0x6b, 0xf9, 0x4c, 0x39,
-       0x5f, 0xc2, 0xfb, 0x4d, 0x78, 0x4f, 0x3e, 0x3b, 0xad, 0xf9, 0x4c, 0xdb,
-       0x27, 0x4e, 0xbf, 0xdd, 0x5f, 0x58, 0xde, 0x1b, 0xc8, 0x91, 0xcf, 0xd4,
-       0x51, 0x77, 0xc1, 0xc8, 0x03, 0xe6, 0xa9, 0x7e, 0x1e, 0xba, 0x83, 0x6d,
-       0x51, 0xfe, 0x70, 0x9a, 0xbe, 0x2d, 0xfc, 0x9f, 0x56, 0x3c, 0xb7, 0xe3,
-       0x79, 0x56, 0xde, 0xbb, 0x37, 0xa6, 0xe7, 0x3d, 0x85, 0x79, 0x1c, 0x38,
-       0x82, 0x39, 0x39, 0xc6, 0x76, 0x8e, 0x9e, 0x8a, 0x4a, 0xc3, 0x29, 0xf2,
-       0x1d, 0xcf, 0xda, 0x04, 0xc1, 0xbe, 0x7e, 0xd2, 0x6d, 0xca, 0xdd, 0xa9,
-       0xcf, 0x96, 0x6e, 0x4f, 0x44, 0x80, 0x93, 0x03, 0x58, 0x8f, 0xa9, 0x82,
-       0xe7, 0x66, 0x1c, 0x2f, 0x81, 0x79, 0xc2, 0x06, 0xec, 0x86, 0x2d, 0xd8,
-       0x0d, 0x3b, 0xb0, 0x1b, 0x76, 0xe0, 0x46, 0x39, 0x71, 0x15, 0x73, 0x4c,
-       0x72, 0xd7, 0xc2, 0x2b, 0x97, 0xef, 0xe8, 0x38, 0x7d, 0xe3, 0xcd, 0x23,
-       0xf0, 0xd9, 0xc5, 0x4d, 0x8d, 0x32, 0x0f, 0x7f, 0xc9, 0x6d, 0xbc, 0x79,
-       0xa7, 0x74, 0x0f, 0xe2, 0xfd, 0xe0, 0x05, 0xe9, 0xb9, 0xf9, 0x56, 0xa7,
-       0x71, 0x74, 0x04, 0x78, 0x4c, 0x3b, 0xa9, 0xc4, 0x98, 0xb3, 0x80, 0x71,
-       0x32, 0xdb, 0x23, 0xc2, 0xb8, 0xe5, 0x02, 0x63, 0x11, 0x37, 0x77, 0x47,
-       0xfa, 0x92, 0xe3, 0x4e, 0x6a, 0x54, 0x45, 0x52, 0xa3, 0x23, 0x4e, 0x58,
-       0x8f, 0xdf, 0x48, 0x85, 0x9c, 0x01, 0xac, 0x07, 0x8a, 0xd3, 0xa0, 0xa7,
-       0xff, 0x28, 0xf9, 0x63, 0x2d, 0x32, 0x5f, 0xe8, 0x76, 0x33, 0x2a, 0xae,
-       0x73, 0x4b, 0xd4, 0x09, 0x10, 0xfd, 0xa9, 0x98, 0xcc, 0x96, 0xb6, 0x8a,
-       0xd2, 0xb6, 0x7b, 0x87, 0x64, 0xa6, 0x4b, 0x72, 0x6e, 0x40, 0xda, 0x14,
-       0xfa, 0xe7, 0xb7, 0x67, 0xd5, 0x09, 0xee, 0x25, 0x86, 0xbc, 0x70, 0x39,
-       0xf9, 0xa4, 0x04, 0x1c, 0x82, 0x6e, 0x19, 0xe3, 0x6d, 0x12, 0xca, 0xbd,
-       0x8f, 0xea, 0xf8, 0x29, 0x63, 0xb6, 0xb5, 0x7b, 0x0f, 0xe4, 0x8f, 0x58,
-       0x5d, 0xfe, 0x98, 0x2b, 0x72, 0x9f, 0x46, 0x72, 0x51, 0xc6, 0x88, 0x3d,
-       0xfc, 0x9e, 0x61, 0xdd, 0x26, 0x99, 0x1a, 0xc8, 0xd9, 0x3c, 0x8f, 0x47,
-       0x12, 0xcc, 0x21, 0x26, 0x4e, 0xc6, 0x07, 0xc8, 0xeb, 0xab, 0xf7, 0x36,
-       0x62, 0x35, 0xf2, 0xc0, 0x91, 0xc5, 0x52, 0xb8, 0x17, 0xc2, 0xfe, 0xf0,
-       0x3c, 0x63, 0xe4, 0x6d, 0x66, 0x4d, 0x3b, 0xc2, 0xc5, 0xfd, 0xca, 0x95,
-       0x32, 0x56, 0x79, 0x94, 0xa9, 0xae, 0x96, 0xaf, 0x8f, 0x55, 0x8c, 0x6c,
-       0x9d, 0xa9, 0x84, 0xba, 0x25, 0x66, 0x74, 0xe9, 0x1a, 0x7d, 0x62, 0xa2,
-       0x99, 0x55, 0x7d, 0x42, 0xbd, 0xa8, 0xe4, 0x03, 0xf3, 0x1d, 0x12, 0x7d,
-       0x58, 0x96, 0xa6, 0xbc, 0xec, 0xe5, 0xcc, 0xd5, 0x98, 0xf2, 0xdf, 0x8c,
-       0x7e, 0xfc, 0x6f, 0x09, 0xea, 0xc3, 0x31, 0xf5, 0x75, 0xdc, 0x37, 0x69,
-       0xfa, 0x03, 0x4f, 0xe1, 0xd9, 0xf8, 0x09, 0xbf, 0x03, 0x3f, 0xe1, 0x8b,
-       0xd0, 0x75, 0x67, 0xe0, 0x27, 0x3c, 0x09, 0x3f, 0xe1, 0x34, 0xfc, 0x84,
-       0x27, 0xa0, 0x27, 0x6b, 0xfd, 0x83, 0xc9, 0x15, 0xfe, 0x41, 0xa0, 0xf9,
-       0x9f, 0xf1, 0xc0, 0x27, 0x6b, 0x7c, 0x83, 0x7d, 0x46, 0x5f, 0xc1, 0xef,
-       0x37, 0x7c, 0xd4, 0xa5, 0x6e, 0xd2, 0xfa, 0xd1, 0xe4, 0xed, 0x8e, 0x2e,
-       0xeb, 0xab, 0x2e, 0x65, 0xf4, 0xd5, 0x6c, 0x55, 0x5f, 0x19, 0x3e, 0x7a,
-       0xb8, 0x24, 0x11, 0xaf, 0xb4, 0x90, 0xf1, 0x77, 0x69, 0x1e, 0x6a, 0xf3,
-       0xb6, 0x4a, 0xe4, 0x01, 0xd5, 0xde, 0x20, 0x19, 0xfb, 0x0c, 0xfa, 0x3a,
-       0x3a, 0x8d, 0xbe, 0xae, 0x95, 0xac, 0xb6, 0xcf, 0x2e, 0x8e, 0xef, 0x27,
-       0x56, 0xe1, 0x3b, 0x5f, 0xbc, 0x5b, 0xe3, 0xfc, 0xfe, 0x32, 0xf7, 0x59,
-       0x5a, 0x64, 0xb2, 0x1c, 0xe2, 0x9c, 0xe7, 0x59, 0x99, 0x8b, 0xd1, 0x29,
-       0x91, 0x87, 0x3b, 0x78, 0xce, 0x4a, 0x65, 0xfd, 0xf5, 0x3a, 0x87, 0xe5,
-       0xc4, 0x80, 0x24, 0xb2, 0x03, 0xa4, 0xd5, 0xfb, 0x64, 0x56, 0xaf, 0x45,
-       0x87, 0x34, 0x3c, 0x4c, 0x1b, 0x25, 0xdc, 0xcf, 0xeb, 0xba, 0xcc, 0x7e,
-       0x23, 0x35, 0x66, 0xea, 0x89, 0x1c, 0xd4, 0xeb, 0x75, 0x5c, 0xe7, 0x19,
-       0xde, 0x34, 0xcf, 0xb8, 0x3c, 0xbf, 0x47, 0xc5, 0x98, 0xfc, 0x3f, 0x67,
-       0xfd, 0x7e, 0xe1, 0x32, 0x63, 0xcf, 0x6c, 0xb2, 0x76, 0x8c, 0x89, 0x53,
-       0xd5, 0xb7, 0x61, 0xd8, 0x4f, 0xed, 0x37, 0x14, 0xb7, 0x38, 0x93, 0xa5,
-       0xad, 0x4e, 0xbe, 0xc4, 0xbd, 0x6c, 0xfb, 0xf7, 0x2e, 0xdc, 0x3d, 0xce,
-       0x01, 0x6f, 0x0b, 0xca, 0x18, 0xb3, 0x64, 0xcc, 0xe6, 0x97, 0x2e, 0x63,
-       0x8c, 0x36, 0xe3, 0x71, 0x6c, 0x96, 0x6d, 0x71, 0xa6, 0x4a, 0xdd, 0xf0,
-       0xcd, 0x79, 0xae, 0x8a, 0xef, 0x77, 0x72, 0xed, 0xa0, 0x83, 0x5d, 0x7d,
-       0x66, 0x77, 0x42, 0xae, 0xb0, 0x31, 0x68, 0xea, 0xe1, 0x9f, 0x5f, 0xb1,
-       0x77, 0x7b, 0x08, 0x7a, 0xec, 0x16, 0xc8, 0x23, 0xea, 0xe1, 0x43, 0x72,
-       0xb5, 0xa5, 0xe7, 0x95, 0x7a, 0xf8, 0xbc, 0x30, 0x4e, 0xdc, 0x8f, 0x77,
-       0xb9, 0x20, 0x06, 0x7a, 0x38, 0x5c, 0xe3, 0xab, 0xd1, 0xef, 0x6b, 0x1a,
-       0x32, 0xfb, 0x61, 0x2b, 0xfd, 0x3e, 0xc8, 0x81, 0x78, 0xe8, 0xe7, 0x35,
-       0x2e, 0xef, 0xd7, 0xee, 0xb1, 0x6d, 0xa7, 0xfc, 0xfb, 0x89, 0xa3, 0xe4,
-       0x21, 0xe9, 0x81, 0x2e, 0x63, 0x0e, 0xc8, 0x6f, 0x69, 0x9c, 0x89, 0x22,
-       0xed, 0x6d, 0xd2, 0x30, 0x5a, 0x39, 0x9f, 0x0c, 0x73, 0x38, 0xf2, 0xb6,
-       0xed, 0x84, 0xdd, 0x93, 0xcf, 0xcb, 0xdc, 0x65, 0xd4, 0x83, 0x23, 0x91,
-       0xf5, 0xfc, 0x7e, 0x22, 0xda, 0xf6, 0x18, 0xbd, 0x28, 0x61, 0x5f, 0x7c,
-       0x6e, 0xa8, 0xe9, 0x9b, 0x76, 0x14, 0xef, 0xab, 0xcf, 0x91, 0x3d, 0xa3,
-       0xf7, 0x19, 0xcd, 0xf7, 0x12, 0x42, 0x3e, 0x21, 0xef, 0x24, 0xf5, 0x59,
-       0x27, 0xef, 0x61, 0xda, 0x3d, 0xdc, 0x83, 0x75, 0x17, 0x26, 0xfd, 0x4f,
-       0xe8, 0x6f, 0xfc, 0xcd, 0x88, 0x38, 0x79, 0xff, 0x36, 0x9d, 0x7b, 0x92,
-       0xd7, 0xb1, 0xe6, 0x1c, 0xee, 0x55, 0x1f, 0xb5, 0xeb, 0x61, 0xfe, 0x4d,
-       0x0b, 0x96, 0x65, 0x01, 0x1b, 0x75, 0x08, 0x65, 0x6f, 0x5c, 0xba, 0x8e,
-       0x7e, 0x58, 0xf3, 0xc2, 0x66, 0xf8, 0x02, 0xc3, 0x47, 0xa1, 0xab, 0x8f,
-       0x26, 0x64, 0xe7, 0x51, 0xad, 0x1b, 0xd3, 0x6b, 0x63, 0x05, 0x7d, 0x6e,
-       0xd4, 0x79, 0x8f, 0x3e, 0xc7, 0xf6, 0xd6, 0xa3, 0x11, 0x39, 0x1c, 0xef,
-       0x73, 0x7b, 0x9c, 0xf7, 0x5a, 0x5d, 0x18, 0xc6, 0xb0, 0x5b, 0xd0, 0xfe,
-       0xf5, 0xe2, 0xd8, 0x61, 0xfc, 0x3a, 0x22, 0x33, 0x7b, 0x3b, 0x01, 0xdb,
-       0x5f, 0x5d, 0x66, 0xce, 0x20, 0x63, 0xad, 0xf4, 0xb7, 0xe7, 0xa3, 0x09,
-       0xca, 0xb2, 0x2e, 0xc0, 0x32, 0x72, 0x94, 0xfa, 0xcc, 0xd3, 0x3c, 0x0e,
-       0x18, 0xdc, 0x06, 0xed, 0x87, 0x90, 0x2f, 0xdf, 0x22, 0xde, 0x03, 0x90,
-       0x71, 0x47, 0x63, 0xd2, 0x73, 0xb4, 0x45, 0xb6, 0x1d, 0xa5, 0x1f, 0x52,
-       0xeb, 0x97, 0xd2, 0x2e, 0x7d, 0x04, 0x73, 0x7c, 0xb7, 0x96, 0x93, 0xdc,
-       0xd3, 0xdc, 0x4f, 0xde, 0x45, 0xdd, 0x2c, 0x6c, 0xe6, 0xcc, 0x51, 0x57,
-       0xef, 0x91, 0x66, 0x30, 0xe7, 0x6c, 0xd9, 0xc5, 0x38, 0x46, 0xe6, 0xe4,
-       0xe9, 0xa7, 0x8c, 0x76, 0x00, 0xc7, 0xef, 0xb5, 0xbc, 0xb3, 0xbe, 0xc3,
-       0xf2, 0xe8, 0xcf, 0xc8, 0x7b, 0x5b, 0x3a, 0x8c, 0xec, 0x7c, 0x4b, 0x07,
-       0x73, 0x93, 0x36, 0x7b, 0xbc, 0x37, 0x69, 0x7b, 0xc2, 0xc8, 0xd0, 0xd7,
-       0xe2, 0x45, 0x01, 0x8e, 0xc2, 0x7d, 0x29, 0x7d, 0x96, 0x2f, 0x38, 0xe7,
-       0xeb, 0xf3, 0x2b, 0xfe, 0xa2, 0xfe, 0x3b, 0x21, 0xdc, 0x23, 0xab, 0x7e,
-       0x6f, 0x65, 0x57, 0x85, 0x71, 0xf2, 0xcf, 0x86, 0x7f, 0x97, 0xa4, 0x26,
-       0xef, 0xb0, 0x76, 0x0f, 0x8c, 0xb1, 0xa6, 0xe5, 0xdc, 0xa0, 0xa0, 0xa4,
-       0xbf, 0x5f, 0xf4, 0x9c, 0x73, 0xbe, 0x70, 0xd6, 0xf9, 0xee, 0xb4, 0x04,
-       0x51, 0xef, 0x27, 0xce, 0xf7, 0x3d, 0xee, 0x99, 0x7f, 0xdd, 0xf9, 0x5e,
-       0xc1, 0x03, 0x1f, 0xde, 0x87, 0x79, 0xbc, 0xe2, 0xfc, 0x00, 0xeb, 0x7b,
-       0xb0, 0x98, 0x4e, 0xb9, 0x36, 0x26, 0x7e, 0xb6, 0xf0, 0x8a, 0xf3, 0xb5,
-       0x6a, 0x3c, 0x69, 0x30, 0xa4, 0x91, 0x43, 0x7c, 0x57, 0xc6, 0xbb, 0xb2,
-       0xde, 0xff, 0x71, 0xe6, 0xa6, 0x6d, 0x7e, 0x89, 0xe6, 0xe3, 0x85, 0xe5,
-       0x7d, 0x99, 0x51, 0xbd, 0x57, 0xf1, 0xac, 0x33, 0x37, 0x7f, 0x77, 0x87,
-       0xc9, 0x33, 0x3a, 0x8b, 0x77, 0x26, 0xe7, 0x72, 0x76, 0xfe, 0x2c, 0xea,
-       0x3c, 0xe3, 0xcc, 0xea, 0xf8, 0x97, 0xf6, 0xc5, 0x9d, 0x99, 0xf9, 0x67,
-       0x9c, 0x79, 0xbd, 0x07, 0x7d, 0xce, 0x79, 0x74, 0x9a, 0x7d, 0x9f, 0x43,
-       0x9d, 0x05, 0xe7, 0x04, 0xfa, 0x9b, 0x9f, 0xe6, 0x79, 0xdc, 0x6e, 0xd8,
-       0x05, 0xfc, 0x7b, 0x3f, 0xfc, 0x1e, 0xc7, 0xb3, 0xce, 0xfc, 0x72, 0xbf,
-       0x8b, 0xe8, 0x87, 0x75, 0x49, 0x8b, 0x1c, 0xf7, 0x59, 0xf4, 0xbf, 0x76,
-       0xaf, 0x6a, 0x2d, 0x4e, 0x5e, 0x00, 0x4e, 0x2e, 0x58, 0x9c, 0xbc, 0x6a,
-       0x71, 0xf2, 0x7c, 0x0d, 0x4e, 0x44, 0xad, 0xc4, 0xc9, 0xab, 0xc0, 0x89,
-       0xa8, 0xfa, 0x38, 0xc1, 0xbb, 0x32, 0xde, 0x69, 0x9c, 0xbc, 0xb4, 0x0a,
-       0x27, 0x4b, 0xcb, 0x71, 0x79, 0x83, 0x93, 0x17, 0x81, 0x93, 0xaf, 0x5a,
-       0xd8, 0x2f, 0x58, 0x9c, 0xe0, 0x3e, 0x7f, 0x01, 0x75, 0x5e, 0xaa, 0xc1,
-       0xc9, 0x05, 0xe0, 0xe4, 0x25, 0x8b, 0x93, 0xef, 0x5b, 0x9c, 0x7c, 0x1f,
-       0x75, 0x96, 0x80, 0x93, 0xf3, 0x75, 0x70, 0xf2, 0x22, 0x70, 0x12, 0xf6,
-       0x7b, 0x1e, 0xfd, 0x7c, 0xbf, 0x06, 0x27, 0x2f, 0xd6, 0xc1, 0x09, 0xf7,
-       0x62, 0xc3, 0x9c, 0xee, 0x99, 0xd7, 0xc9, 0xe9, 0x96, 0x3b, 0x5f, 0x3f,
-       0xa7, 0x9b, 0x75, 0x66, 0xa4, 0xfa, 0x37, 0x25, 0xee, 0xb6, 0x39, 0x6a,
-       0x26, 0x17, 0xb0, 0xfa, 0xcd, 0xa6, 0x6e, 0xf0, 0x79, 0x3e, 0xe7, 0x8a,
-       0xc9, 0x29, 0x8d, 0xee, 0xf8, 0x10, 0x78, 0x6d, 0x97, 0x1c, 0x38, 0xd6,
-       0x78, 0x38, 0x6b, 0xcb, 0xbc, 0x1d, 0xdd, 0x39, 0xa5, 0xf8, 0x2e, 0xcc,
-       0x49, 0xa0, 0x5f, 0xd2, 0xc0, 0x6f, 0x0b, 0xf6, 0xa6, 0xa5, 0x76, 0x4f,
-       0xba, 0xc0, 0x6f, 0x34, 0x61, 0xec, 0x25, 0xfe, 0xfd, 0x8b, 0x24, 0xf3,
-       0xac, 0xf2, 0x1a, 0xde, 0x14, 0xf4, 0xc7, 0xa0, 0xce, 0xad, 0xca, 0x14,
-       0x68, 0x73, 0x27, 0x99, 0xa3, 0x06, 0x5b, 0x79, 0xc8, 0x9e, 0x09, 0xf3,
-       0xf5, 0x39, 0x95, 0x2a, 0xff, 0xd4, 0x9e, 0x87, 0x26, 0xdf, 0x55, 0xe9,
-       0xe6, 0xe0, 0xf2, 0x77, 0x02, 0x4f, 0xca, 0xd3, 0x3a, 0x56, 0xdc, 0x8c,
-       0xf5, 0x09, 0x82, 0xc7, 0x7c, 0x13, 0xa3, 0x5d, 0xd4, 0x31, 0x5a, 0x81,
-       0x37, 0x3e, 0x69, 0xe3, 0xb4, 0x3d, 0x83, 0x2f, 0x2d, 0xc7, 0x68, 0x6b,
-       0xf3, 0x59, 0xcc, 0xfe, 0x7a, 0xa6, 0xf4, 0x88, 0xce, 0xd1, 0x19, 0xe1,
-       0xf7, 0x37, 0x20, 0x23, 0x26, 0x66, 0xe6, 0x65, 0xf2, 0x41, 0x3e, 0x53,
-       0xbf, 0x45, 0xa0, 0xc3, 0x28, 0xc3, 0x73, 0x92, 0x19, 0x64, 0x99, 0x69,
-       0x33, 0xa2, 0xfd, 0xe5, 0x93, 0x32, 0xbc, 0x3c, 0x3e, 0xf1, 0x7b, 0x57,
-       0xcd, 0x77, 0xab, 0x69, 0xf3, 0xa4, 0x9d, 0x4c, 0x85, 0xef, 0xc3, 0x3d,
-       0xf2, 0xbb, 0xec, 0xb7, 0xb3, 0xf8, 0xbe, 0xf6, 0x5b, 0xad, 0x5a, 0x74,
-       0xe0, 0x37, 0xbf, 0x87, 0x36, 0xe5, 0x8c, 0xa0, 0xcd, 0x82, 0xdb, 0x32,
-       0xaa, 0x86, 0x6e, 0x18, 0xe5, 0xb9, 0xb9, 0xd9, 0x35, 0xdf, 0xba, 0xae,
-       0xea, 0xc5, 0xbc, 0x5e, 0x53, 0xe6, 0x67, 0xdd, 0x05, 0x5a, 0xd4, 0xb4,
-       0xa5, 0xe9, 0xff, 0xc0, 0xb2, 0xbe, 0xa4, 0x9e, 0x35, 0xdf, 0x9e, 0x31,
-       0xfa, 0x32, 0x95, 0x18, 0xc1, 0xf8, 0xfa, 0x6f, 0x2a, 0xd8, 0x73, 0xbd,
-       0xd9, 0xf9, 0xdb, 0xb5, 0xae, 0x9f, 0xf2, 0xd3, 0xc9, 0xa8, 0xd4, 0xa9,
-       0x5b, 0xaa, 0xa9, 0xab, 0xe7, 0xed, 0xca, 0x7f, 0xc5, 0xda, 0x7c, 0xbe,
-       0x58, 0x96, 0xe1, 0xe9, 0xbf, 0x84, 0xff, 0x98, 0x90, 0xdf, 0x2e, 0x96,
-       0x40, 0xaf, 0xb9, 0xcd, 0xf6, 0x5b, 0x4d, 0x19, 0xc0, 0xcd, 0x6f, 0xaf,
-       0xe8, 0x7c, 0xe2, 0xc8, 0x17, 0x40, 0x17, 0x9f, 0x2b, 0x71, 0x0c, 0xc0,
-       0x12, 0x81, 0x6d, 0x0f, 0x3b, 0x61, 0xa6, 0xa4, 0x73, 0xe7, 0xae, 0x2b,
-       0x97, 0x74, 0xcc, 0x62, 0x67, 0xb9, 0x53, 0x76, 0x95, 0x5b, 0x64, 0x37,
-       0xf4, 0xc2, 0xee, 0xb2, 0x87, 0x2b, 0x26, 0xef, 0x2e, 0x9b, 0x75, 0xfa,
-       0x58, 0x99, 0xeb, 0xbd, 0x43, 0x66, 0x8f, 0xad, 0xfe, 0x3e, 0xe7, 0x42,
-       0x2e, 0xfc, 0x3b, 0x4b, 0x4a, 0x31, 0xbf, 0x8c, 0xb4, 0x84, 0xab, 0x98,
-       0x3a, 0xbc, 0xa0, 0xf1, 0xc0, 0x0c, 0xd7, 0x54, 0x69, 0x49, 0x98, 0xa7,
-       0xcf, 0xbf, 0xad, 0x34, 0x73, 0x39, 0xcf, 0x4d, 0xf3, 0x5b, 0x5e, 0x3b,
-       0x2b, 0x61, 0xde, 0x78, 0xbd, 0x9c, 0x71, 0xd8, 0xf9, 0x3b, 0xc2, 0x1c,
-       0xbf, 0x18, 0x73, 0xc6, 0xa5, 0xeb, 0x54, 0x0b, 0xee, 0xa7, 0x2f, 0xd7,
-       0x67, 0x9b, 0x4f, 0x89, 0x2d, 0xd3, 0xf9, 0xe4, 0x78, 0x5e, 0xfd, 0x7d,
-       0xb5, 0x90, 0x1f, 0xaa, 0x7f, 0xa7, 0x40, 0xe4, 0xff, 0x02, 0xfb, 0x2e,
-       0x88, 0x71, 0xec, 0x6e, 0x00, 0x00, 0x00 };
+       0xbd, 0x7d, 0x0d, 0x74, 0x5c, 0xd7, 0x5d, 0xe7, 0xff, 0xdd, 0x79, 0x92,
+       0xc6, 0xb2, 0x6c, 0x3f, 0xcb, 0x13, 0x79, 0x62, 0xab, 0xf6, 0x8c, 0xf4,
+       0x64, 0xab, 0x91, 0x08, 0x2f, 0xae, 0x28, 0x82, 0x9d, 0x84, 0xe9, 0x48,
+       0xb2, 0x9d, 0x34, 0xed, 0xca, 0x8d, 0x5b, 0xb2, 0x9c, 0x02, 0x62, 0x24,
+       0x27, 0xe9, 0x77, 0xd2, 0x04, 0xb6, 0xec, 0xc9, 0x6e, 0x26, 0x23, 0xf9,
+       0x83, 0x74, 0xec, 0x51, 0x12, 0x25, 0xce, 0xa1, 0x3d, 0xbb, 0xaa, 0xa4,
+       0xd8, 0x06, 0x06, 0x8f, 0x93, 0xb8, 0xa5, 0xec, 0xa6, 0x54, 0x28, 0xae,
+       0x09, 0xa1, 0x07, 0x52, 0x48, 0xd9, 0x40, 0x53, 0x2a, 0xdc, 0xb4, 0xcd,
+       0x9e, 0x53, 0xb6, 0x01, 0xca, 0x12, 0x68, 0xe8, 0xdb, 0xdf, 0xef, 0xde,
+       0xfb, 0x34, 0xa3, 0x0f, 0xe7, 0xa3, 0xec, 0xe2, 0x73, 0x9e, 0xdf, 0xbc,
+       0xfb, 0xee, 0xc7, 0xff, 0xfe, 0xef, 0xff, 0xfb, 0xfe, 0xef, 0xd3, 0x76,
+       0x91, 0x66, 0xb1, 0xff, 0x36, 0xe0, 0x7a, 0x5b, 0xea, 0xf6, 0xd1, 0x6b,
+       0xae, 0xfe, 0xc9, 0xab, 0xf9, 0xec, 0x3a, 0x4d, 0x31, 0x79, 0x13, 0xff,
+       0x52, 0x6f, 0xa0, 0x0e, 0x3a, 0xf4, 0xa2, 0xb1, 0x78, 0x49, 0x5c, 0x65,
+       0xdc, 0x3b, 0x72, 0xbe, 0xc4, 0x63, 0x99, 0x91, 0x5f, 0x1e, 0xf5, 0x45,
+       0xb2, 0x95, 0x9e, 0xd4, 0x80, 0xfc, 0x4b, 0x58, 0x48, 0xb8, 0xc2, 0xf2,
+       0xb7, 0x64, 0x5e, 0xfd, 0x6f, 0x5f, 0xf8, 0xc9, 0xf4, 0xcb, 0xd3, 0x31,
+       0x89, 0x7b, 0x99, 0x0f, 0x8b, 0xb7, 0x4b, 0xe2, 0xed, 0x19, 0xb9, 0xe3,
+       0xd3, 0xbb, 0xff, 0x46, 0x64, 0x63, 0xd4, 0xd7, 0x4b, 0xe1, 0x17, 0x76,
+       0x4b, 0x61, 0x5b, 0x26, 0x39, 0xd2, 0x90, 0x49, 0xc8, 0x17, 0xab, 0x9e,
+       0x9c, 0xab, 0xca, 0xf0, 0xa9, 0xd2, 0xcb, 0xa1, 0x9b, 0x09, 0x63, 0x13,
+       0x7d, 0x8e, 0xc4, 0x32, 0x72, 0x61, 0xb4, 0xef, 0x9e, 0x50, 0xf9, 0x32,
+       0xe2, 0x65, 0xfc, 0x60, 0x41, 0x5a, 0xfa, 0x2f, 0xf6, 0xa1, 0x4e, 0xe5,
+       0xe0, 0xb5, 0x8d, 0x27, 0xe2, 0xa2, 0x32, 0x5d, 0xcf, 0xe7, 0x62, 0xd7,
+       0x88, 0xf2, 0xfd, 0xe0, 0x82, 0x74, 0x05, 0x4f, 0x09, 0xca, 0xcf, 0xc6,
+       0x25, 0x57, 0x95, 0x16, 0x94, 0xe1, 0xde, 0x8c, 0x3a, 0x69, 0x2f, 0x17,
+       0x4b, 0x48, 0xb1, 0xfa, 0x63, 0xcd, 0x66, 0xec, 0xaf, 0xaf, 0x33, 0xf7,
+       0xdd, 0xf6, 0xbe, 0xee, 0x67, 0xdd, 0x4c, 0x3c, 0xae, 0x4e, 0xc8, 0xcb,
+       0x13, 0x7d, 0x2f, 0x87, 0x31, 0xdf, 0xf7, 0x06, 0xa4, 0x41, 0x06, 0x13,
+       0x80, 0xa9, 0xec, 0xa0, 0xef, 0x14, 0xda, 0xfe, 0x12, 0x70, 0x0e, 0xf8,
+       0xca, 0x29, 0x29, 0x10, 0xce, 0x72, 0x5c, 0x16, 0x63, 0x49, 0x01, 0xfc,
+       0xc0, 0x45, 0xbb, 0x8c, 0xa3, 0x3c, 0x57, 0xe2, 0x7c, 0x5c, 0xc9, 0x7b,
+       0x1e, 0xe6, 0xd2, 0x8e, 0x36, 0x3b, 0x1d, 0xd3, 0x3f, 0x9e, 0x97, 0xd5,
+       0x67, 0xdd, 0xe7, 0x51, 0x37, 0xa5, 0xeb, 0x3d, 0x51, 0x4d, 0xca, 0xe3,
+       0xd5, 0x84, 0x3c, 0x56, 0xfd, 0x98, 0x64, 0x3d, 0xe2, 0x00, 0xb0, 0x96,
+       0x1b, 0x65, 0x60, 0xaa, 0x59, 0x72, 0x53, 0x9d, 0xc9, 0xbc, 0x84, 0xe1,
+       0x9d, 0xc1, 0x07, 0x64, 0xa4, 0x15, 0xf5, 0xcb, 0x7c, 0x97, 0x5c, 0xf6,
+       0x2e, 0x1f, 0xf4, 0x78, 0x79, 0xe5, 0x48, 0xf6, 0x60, 0x3a, 0x39, 0xa2,
+       0xf8, 0xdc, 0x20, 0xb9, 0x5e, 0x3c, 0x0f, 0xbb, 0x12, 0xf3, 0xc3, 0xf0,
+       0x8e, 0x60, 0x17, 0xe0, 0x48, 0xa7, 0x52, 0x8a, 0x6d, 0xd9, 0x2e, 0x5d,
+       0x48, 0xa9, 0x24, 0xe6, 0x71, 0xb5, 0xa4, 0x5a, 0xc3, 0xf0, 0x3d, 0x81,
+       0x8f, 0x72, 0x91, 0x81, 0x92, 0xdc, 0xae, 0x32, 0x3e, 0xfa, 0x94, 0x40,
+       0x65, 0xb6, 0x60, 0x1e, 0x3d, 0xc0, 0x43, 0xa3, 0x64, 0x13, 0x92, 0x55,
+       0x19, 0x49, 0xa9, 0xcc, 0x3a, 0x94, 0x39, 0xd2, 0xe0, 0xff, 0x77, 0x4b,
+       0x7f, 0x9b, 0xf0, 0x2c, 0xc3, 0x2a, 0xd3, 0xba, 0xa2, 0x3c, 0x9d, 0x12,
+       0xf5, 0xe3, 0x71, 0x8c, 0xd9, 0x9d, 0x55, 0x2c, 0xc3, 0x5d, 0x97, 0x15,
+       0x9a, 0x56, 0x97, 0x4d, 0x3a, 0xcb, 0xcb, 0x4e, 0xb5, 0x10, 0x56, 0x51,
+       0xfc, 0x9d, 0xd4, 0x73, 0xcd, 0x26, 0x3a, 0xbd, 0x06, 0xcc, 0x6b, 0x38,
+       0x48, 0x7b, 0x43, 0xea, 0xb9, 0x50, 0xda, 0x08, 0x33, 0xdf, 0x29, 0xbc,
+       0x43, 0xd5, 0x4c, 0x80, 0x75, 0x4e, 0xc8, 0x51, 0xcc, 0xed, 0xd2, 0x54,
+       0xda, 0xeb, 0x50, 0xb8, 0xcf, 0xf1, 0x77, 0x18, 0xe6, 0x82, 0x82, 0xa6,
+       0x81, 0x6f, 0x4e, 0x25, 0xf1, 0x0c, 0xf8, 0x13, 0xd9, 0xf4, 0x66, 0xb9,
+       0xc9, 0xae, 0xcb, 0x37, 0x31, 0x66, 0xa7, 0x77, 0x87, 0xea, 0xf4, 0x02,
+       0x95, 0xf6, 0x66, 0xe4, 0xf7, 0xf1, 0x1c, 0x86, 0x07, 0x82, 0x74, 0xb2,
+       0x80, 0x35, 0x7b, 0xb1, 0x94, 0x90, 0x6f, 0x95, 0xd2, 0xa0, 0xfc, 0x74,
+       0xf7, 0xac, 0xf4, 0x04, 0xb3, 0x80, 0xb7, 0x88, 0xeb, 0x08, 0xdf, 0x55,
+       0xf0, 0xae, 0xc2, 0xb6, 0x61, 0x78, 0x53, 0xf0, 0xeb, 0xe1, 0x48, 0x9b,
+       0xe1, 0xa5, 0x2f, 0x96, 0xb1, 0x9e, 0x80, 0xf9, 0x71, 0xac, 0xd3, 0x63,
+       0xe5, 0x88, 0x4e, 0xba, 0xb1, 0xee, 0xa4, 0x0d, 0xd2, 0xc5, 0x1e, 0x4b,
+       0xff, 0xa3, 0xf6, 0x2e, 0x92, 0x03, 0x8d, 0xe5, 0x82, 0x1f, 0x84, 0x59,
+       0xcd, 0x63, 0xe2, 0x0c, 0x94, 0x49, 0xbb, 0x0d, 0x80, 0x95, 0x8f, 0x1f,
+       0xb3, 0xf5, 0xda, 0x1d, 0xe0, 0x96, 0xeb, 0xc0, 0xf7, 0x71, 0xe5, 0x37,
+       0xd9, 0xf7, 0x11, 0x2f, 0xf1, 0x1f, 0xe8, 0xcd, 0xaf, 0xd5, 0xcb, 0x91,
+       0x26, 0xab, 0x05, 0xc9, 0x3f, 0x18, 0xca, 0x40, 0x00, 0x3c, 0xb1, 0x4f,
+       0x2f, 0x10, 0xdd, 0xd6, 0x63, 0x1d, 0x5d, 0x17, 0xff, 0xae, 0x69, 0xc4,
+       0x18, 0xce, 0x60, 0xb9, 0xd6, 0x76, 0xb0, 0xfc, 0xe4, 0x16, 0x0b, 0x1f,
+       0x9e, 0xfb, 0x9d, 0x5c, 0xf5, 0x6f, 0xed, 0xda, 0x46, 0xf3, 0xb8, 0x69,
+       0x0d, 0xda, 0x0e, 0xc3, 0x89, 0x40, 0x46, 0x54, 0x66, 0x31, 0x9e, 0x2b,
+       0x89, 0xd3, 0x90, 0xf1, 0xbd, 0x21, 0x59, 0x27, 0x76, 0x5e, 0xb6, 0xdc,
+       0x03, 0xaf, 0x74, 0xa1, 0xdc, 0x11, 0xc8, 0x8d, 0x11, 0x07, 0x65, 0x1d,
+       0x15, 0x94, 0x61, 0xfd, 0xc6, 0x81, 0xaf, 0x7c, 0xa9, 0x5f, 0xaf, 0x65,
+       0xbe, 0x34, 0x0c, 0xde, 0xcf, 0xe0, 0x77, 0x76, 0xb3, 0x2b, 0x5d, 0xa0,
+       0x43, 0xae, 0xb1, 0xb8, 0xb9, 0xdd, 0xa0, 0xd5, 0xea, 0xeb, 0x4b, 0x2c,
+       0x3d, 0xf7, 0xe0, 0x5f, 0x88, 0xd3, 0x25, 0x78, 0x62, 0x19, 0xf2, 0xf5,
+       0xf3, 0x21, 0xe8, 0x19, 0x65, 0x84, 0x99, 0x35, 0x13, 0x32, 0x51, 0xde,
+       0x26, 0xc5, 0x29, 0x5f, 0xc6, 0x4b, 0xf3, 0xdd, 0x4a, 0x5e, 0x86, 0xac,
+       0xf1, 0x41, 0x0b, 0x69, 0xf0, 0x41, 0x46, 0x06, 0xaa, 0x18, 0xaf, 0x84,
+       0x7b, 0xb9, 0x13, 0x6d, 0x5d, 0xc9, 0x26, 0xcd, 0x3a, 0x17, 0x4b, 0x63,
+       0xc0, 0x15, 0xd6, 0x8d, 0xb2, 0x41, 0xc3, 0x3c, 0x0c, 0x3a, 0xf4, 0x24,
+       0xd7, 0xa7, 0xe1, 0x7c, 0x13, 0xf0, 0xc5, 0x65, 0x26, 0x68, 0xb4, 0x38,
+       0x22, 0x7f, 0xc6, 0xdd, 0x01, 0xe0, 0x61, 0xa0, 0x72, 0x0f, 0xfa, 0x6f,
+       0xc1, 0x6f, 0x96, 0x89, 0x2d, 0x73, 0xf5, 0xf3, 0x40, 0x85, 0x30, 0x47,
+       0x74, 0x0f, 0x3e, 0x98, 0x82, 0xfc, 0x01, 0xdd, 0x0f, 0x90, 0x5f, 0xe6,
+       0x38, 0x17, 0xc2, 0xb5, 0x4d, 0xff, 0x1e, 0x9f, 0xda, 0xa1, 0x9f, 0xf3,
+       0xc3, 0xdb, 0xa4, 0x30, 0x17, 0xcd, 0x99, 0xb2, 0x87, 0xf2, 0x26, 0x7d,
+       0x0c, 0x74, 0x05, 0xf9, 0x13, 0x86, 0x0f, 0x06, 0x94, 0x41, 0x61, 0xf8,
+       0x78, 0x40, 0x99, 0x74, 0x1e, 0xb2, 0x86, 0x72, 0x88, 0x72, 0x61, 0x50,
+       0x71, 0xdd, 0x73, 0xa5, 0x00, 0xeb, 0xd3, 0x28, 0xf9, 0xde, 0x47, 0x08,
+       0x2b, 0x64, 0xd8, 0xb3, 0x1f, 0xcb, 0xf9, 0x85, 0x64, 0x4c, 0xe3, 0x49,
+       0xb0, 0x5e, 0x71, 0xc9, 0xea, 0x99, 0x75, 0x48, 0xb1, 0x77, 0xd2, 0xd6,
+       0x79, 0x49, 0xd7, 0x71, 0x57, 0xd5, 0xf9, 0x75, 0x65, 0x78, 0x3c, 0xc0,
+       0x5a, 0xfe, 0xb4, 0x22, 0x1e, 0x3b, 0x76, 0xf1, 0x59, 0xe2, 0x0d, 0x99,
+       0xaf, 0xe1, 0xdd, 0xb9, 0x3b, 0x1f, 0xf5, 0xd7, 0x7a, 0xb7, 0xb5, 0x61,
+       0xf5, 0xbb, 0x09, 0x71, 0xfd, 0x74, 0xf7, 0x01, 0xf5, 0x4f, 0x78, 0x17,
+       0x86, 0x8f, 0x06, 0x51, 0x79, 0x6f, 0xc3, 0xea, 0x31, 0x7e, 0x76, 0x8d,
+       0xb2, 0xf3, 0x6b, 0x94, 0xfd, 0xc9, 0x1a, 0x65, 0xef, 0x6d, 0x5c, 0x5d,
+       0xf6, 0xc0, 0x1a, 0x65, 0x4f, 0xaf, 0x51, 0xe6, 0x37, 0xad, 0x2e, 0xdb,
+       0xb5, 0x46, 0xd9, 0x5b, 0xd7, 0x28, 0x3b, 0xb0, 0x46, 0x99, 0x0b, 0x1e,
+       0xde, 0x25, 0xc5, 0xc4, 0xbd, 0x9c, 0xbb, 0xc5, 0xcd, 0xe7, 0x62, 0xab,
+       0x71, 0xd3, 0x80, 0x7a, 0xed, 0x2b, 0xea, 0x7d, 0x6d, 0x8d, 0x7a, 0x8d,
+       0xa8, 0xd7, 0xba, 0xa2, 0xde, 0xcd, 0xee, 0xea, 0x7a, 0x4d, 0xa8, 0x17,
+       0x5f, 0x51, 0xef, 0x77, 0xd7, 0xa8, 0xc7, 0xf2, 0x4f, 0xd9, 0x71, 0x7a,
+       0xa0, 0xd1, 0x5e, 0x6b, 0xbd, 0x1a, 0x45, 0xda, 0x58, 0x1e, 0x40, 0x1f,
+       0xfd, 0xb4, 0x32, 0x32, 0x86, 0xf2, 0x4c, 0xe3, 0x0d, 0x74, 0x9e, 0x04,
+       0xdd, 0x51, 0x26, 0x83, 0xcf, 0x7c, 0xf2, 0xfe, 0x06, 0x19, 0x49, 0xf4,
+       0x78, 0x6f, 0x53, 0x2d, 0xa0, 0xb1, 0xb4, 0x97, 0x52, 0xe4, 0x3f, 0x29,
+       0x80, 0xb7, 0x0b, 0x03, 0xa2, 0x12, 0x4a, 0x42, 0x19, 0x0c, 0x54, 0xab,
+       0x92, 0x7b, 0xc0, 0x5f, 0x59, 0xe8, 0xbf, 0x03, 0xe1, 0x80, 0xe6, 0x2d,
+       0x53, 0xf7, 0xf2, 0xf2, 0xb9, 0x5f, 0x8e, 0x50, 0xae, 0x66, 0x82, 0x3b,
+       0x73, 0xfe, 0x7c, 0x7f, 0x23, 0x68, 0xf6, 0x12, 0xda, 0xec, 0x43, 0xcb,
+       0x43, 0x15, 0x57, 0x06, 0x2b, 0x19, 0xf0, 0x82, 0x23, 0x17, 0xfd, 0x4d,
+       0x72, 0x31, 0x40, 0xdd, 0x6a, 0x4c, 0x16, 0x12, 0x8e, 0x2c, 0xe0, 0x39,
+       0x17, 0xe0, 0x5d, 0x35, 0xe2, 0xad, 0x8c, 0x1c, 0x2e, 0xf7, 0xcb, 0xb1,
+       0xf2, 0x87, 0x55, 0xa4, 0x23, 0x87, 0x82, 0xf5, 0x72, 0xc6, 0x33, 0x7d,
+       0xef, 0xf3, 0xe7, 0xa1, 0x9d, 0x5d, 0xb9, 0xe4, 0xa7, 0x93, 0x0b, 0x9a,
+       0x27, 0xfe, 0x31, 0x1c, 0x44, 0x3f, 0x33, 0x7e, 0xda, 0xfb, 0x03, 0x0a,
+       0xc9, 0x0a, 0x6d, 0xa9, 0x5a, 0x5f, 0xe3, 0xe8, 0xeb, 0x68, 0x79, 0x83,
+       0xdc, 0x6a, 0xdb, 0xef, 0xf5, 0xe7, 0xbb, 0xc1, 0x73, 0xde, 0x29, 0xca,
+       0x90, 0x12, 0xe0, 0x3a, 0x08, 0xde, 0x46, 0xdb, 0x2f, 0x09, 0xdb, 0xc0,
+       0xf6, 0x2a, 0x6d, 0x82, 0xac, 0xff, 0x87, 0xf0, 0xd6, 0x04, 0xeb, 0xb3,
+       0x8c, 0xfa, 0x4b, 0x26, 0x55, 0x06, 0x32, 0xa1, 0xaf, 0x0b, 0xfa, 0x2b,
+       0x25, 0x83, 0x55, 0xc8, 0x9e, 0xf2, 0x0f, 0xc3, 0xac, 0xcb, 0x31, 0xa2,
+       0xb1, 0xa4, 0x50, 0xab, 0xc3, 0x32, 0xd6, 0x23, 0xff, 0x2f, 0x2e, 0xc9,
+       0x8a, 0x02, 0xe4, 0x8b, 0xb1, 0xd1, 0xfe, 0x13, 0x78, 0xb4, 0x5d, 0x06,
+       0x4b, 0xe9, 0x42, 0x56, 0x76, 0x61, 0xfd, 0x7e, 0x0d, 0x6b, 0xea, 0xe2,
+       0xfa, 0x93, 0xf5, 0xb2, 0x31, 0x80, 0x1d, 0xc0, 0x72, 0x74, 0xda, 0x46,
+       0xfb, 0xec, 0x19, 0xe0, 0x61, 0x9c, 0x6b, 0x9e, 0xcc, 0xc5, 0x9c, 0x61,
+       0xda, 0x3e, 0xc3, 0x90, 0x8f, 0xf9, 0x0a, 0xfb, 0x26, 0xbc, 0x49, 0xfb,
+       0x1b, 0x36, 0x5b, 0xa9, 0xdd, 0xfe, 0x6e, 0xc1, 0xef, 0x94, 0xfd, 0x0d,
+       0x99, 0x5a, 0xf2, 0xed, 0xef, 0x04, 0x7e, 0x77, 0xdb, 0xdf, 0x49, 0xfc,
+       0xee, 0xd5, 0xbf, 0x27, 0xca, 0x7b, 0xf7, 0x2a, 0xff, 0x6a, 0xc9, 0xcf,
+       0xb5, 0xcb, 0xe1, 0xd2, 0x7b, 0xad, 0x6c, 0xc1, 0x25, 0x9f, 0x77, 0xcc,
+       0x3c, 0x01, 0x77, 0x99, 0x6d, 0x0a, 0xce, 0xb0, 0xb6, 0xdd, 0xda, 0x61,
+       0xeb, 0xf4, 0x78, 0x9b, 0x85, 0x34, 0x30, 0xe1, 0x0c, 0x54, 0x9d, 0x6c,
+       0x2c, 0xd3, 0x95, 0x1c, 0x97, 0x63, 0xf8, 0x2d, 0x5e, 0x2c, 0xf3, 0x79,
+       0xdc, 0x0d, 0x0e, 0xbe, 0x00, 0x7d, 0x33, 0x5e, 0xa6, 0xbc, 0xf4, 0x31,
+       0xf7, 0x94, 0x9c, 0x5f, 0x66, 0xaf, 0x11, 0x17, 0x4a, 0xf2, 0x53, 0xe9,
+       0x47, 0x0a, 0x92, 0x2e, 0x4c, 0x83, 0x21, 0x0e, 0x04, 0xae, 0xbc, 0x27,
+       0x00, 0xed, 0x5e, 0xed, 0xc8, 0xde, 0xab, 0x5d, 0xd8, 0x57, 0xfe, 0xf4,
+       0x5e, 0xc8, 0xd8, 0x7c, 0xe9, 0xea, 0x18, 0xe9, 0x41, 0x9d, 0x95, 0x11,
+       0x37, 0x03, 0x6c, 0x9f, 0xed, 0x1d, 0x1c, 0x2f, 0xe5, 0x3f, 0xac, 0x32,
+       0xb7, 0xff, 0x6a, 0xae, 0x6f, 0x17, 0x74, 0x79, 0x18, 0xc6, 0x32, 0x6d,
+       0xd0, 0x4b, 0x5c, 0x57, 0xea, 0xa9, 0x9b, 0x6e, 0x8a, 0x65, 0x1a, 0x64,
+       0xe0, 0x60, 0x1b, 0xea, 0xb3, 0x9c, 0xb8, 0x72, 0xd0, 0x47, 0x3a, 0x35,
+       0x28, 0x72, 0xf7, 0x44, 0xdf, 0xa2, 0x33, 0x3e, 0xf9, 0x73, 0xe0, 0xc7,
+       0x7e, 0xc9, 0x1f, 0x7c, 0x00, 0xf8, 0x7d, 0xd9, 0x29, 0x4e, 0xbd, 0xe2,
+       0x8c, 0x4f, 0xfd, 0x9d, 0x33, 0x31, 0xb5, 0x63, 0xc7, 0x50, 0xff, 0x8e,
+       0x1d, 0xa3, 0xfd, 0xae, 0xd5, 0x2d, 0x3b, 0x76, 0x4c, 0xf4, 0x67, 0x31,
+       0xff, 0x1e, 0x6f, 0x50, 0x7c, 0x6f, 0x2f, 0x95, 0x7c, 0xc2, 0xac, 0xfd,
+       0x4c, 0xd0, 0x8d, 0xf7, 0x6c, 0xdf, 0xab, 0xdf, 0x0f, 0x48, 0x4f, 0xb2,
+       0x55, 0x38, 0x7e, 0x87, 0xd5, 0x49, 0x6c, 0x07, 0x7a, 0xe9, 0xa5, 0x1d,
+       0xa8, 0x50, 0x2f, 0x05, 0x7c, 0xd0, 0x26, 0xde, 0x06, 0x1b, 0x82, 0xed,
+       0x94, 0x5d, 0xf7, 0x92, 0x6a, 0xf0, 0x63, 0xba, 0x5f, 0x75, 0x36, 0x13,
+       0x33, 0x6b, 0xde, 0x63, 0xed, 0xeb, 0x4d, 0x28, 0xe7, 0x33, 0x71, 0x49,
+       0x7c, 0xd1, 0xde, 0x69, 0xd0, 0xf6, 0x69, 0xbe, 0x44, 0x5a, 0x72, 0x65,
+       0xac, 0xd4, 0x8f, 0x36, 0xa0, 0x97, 0xb3, 0xf6, 0x3a, 0x81, 0xf1, 0x0e,
+       0xa2, 0xaf, 0x13, 0x47, 0xd1, 0x8e, 0xb2, 0x24, 0xdd, 0x2d, 0xea, 0x41,
+       0xd4, 0xe9, 0xf1, 0xb6, 0x08, 0xed, 0x9a, 0x47, 0x24, 0x5f, 0x26, 0xdf,
+       0xd3, 0x36, 0x88, 0x4b, 0xaa, 0x0d, 0xcf, 0xd5, 0xc3, 0xb0, 0x75, 0x1a,
+       0x22, 0x7b, 0x43, 0x6a, 0x76, 0xd1, 0xaf, 0x2a, 0xf1, 0x0f, 0xcb, 0xc8,
+       0xec, 0x76, 0xd4, 0x33, 0xf6, 0xbc, 0xf2, 0x61, 0x17, 0xcd, 0x66, 0x25,
+       0xb7, 0xeb, 0x5e, 0xdc, 0x3d, 0x3c, 0x17, 0x71, 0x7f, 0x0b, 0xee, 0xe3,
+       0xb8, 0x47, 0x70, 0x02, 0xe7, 0x41, 0xcc, 0xea, 0xb2, 0x51, 0x8c, 0xfd,
+       0xef, 0x25, 0x37, 0x09, 0x7a, 0x2d, 0x85, 0x9b, 0x72, 0x7e, 0xd6, 0x53,
+       0xa2, 0xb6, 0x28, 0x99, 0x40, 0x7d, 0xf8, 0x29, 0xfe, 0x11, 0x19, 0x3d,
+       0x8d, 0xdf, 0x0f, 0xd2, 0xee, 0x9e, 0x90, 0xd1, 0x59, 0x8e, 0x53, 0x02,
+       0x4c, 0x93, 0x92, 0x3f, 0xfd, 0x00, 0xae, 0x29, 0x5c, 0x0f, 0xe3, 0xe2,
+       0xdc, 0xd8, 0xff, 0xc2, 0x66, 0x25, 0x2d, 0xfa, 0x39, 0x4f, 0xfa, 0xae,
+       0xe2, 0x37, 0x69, 0xbb, 0x4a, 0x1b, 0x08, 0x74, 0x5d, 0x8d, 0xe8, 0x3d,
+       0xb0, 0xbf, 0x93, 0x9a, 0xdf, 0x0b, 0xad, 0xa0, 0xa5, 0x6a, 0x56, 0xcb,
+       0x22, 0xc0, 0x00, 0xb9, 0x03, 0x9b, 0xa4, 0x95, 0x73, 0xec, 0xb5, 0x65,
+       0xbd, 0xba, 0x2c, 0xa5, 0xcb, 0xfa, 0x6c, 0x19, 0xee, 0xd5, 0x06, 0x19,
+       0x69, 0x03, 0xc4, 0x94, 0xdb, 0x12, 0xe1, 0x93, 0xb2, 0x01, 0x74, 0x8d,
+       0xf5, 0x3d, 0x7f, 0x59, 0xb9, 0xb8, 0xa8, 0xed, 0xbd, 0x73, 0x55, 0xd2,
+       0x37, 0x69, 0x3e, 0x0c, 0xef, 0x0f, 0x9a, 0xd0, 0x3f, 0x65, 0x81, 0x48,
+       0xc3, 0x09, 0x57, 0xa6, 0x3d, 0xd2, 0xc0, 0xc7, 0x5a, 0x48, 0x03, 0x8d,
+       0x3e, 0x69, 0xbb, 0x9e, 0xef, 0xb8, 0x86, 0xec, 0xaf, 0x00, 0x1b, 0x92,
+       0xb6, 0x64, 0x17, 0xec, 0x73, 0x8e, 0x71, 0x8c, 0xcf, 0x9e, 0x02, 0xaf,
+       0xe5, 0x96, 0x78, 0x4d, 0x64, 0xa6, 0x44, 0xdc, 0x44, 0x36, 0x26, 0xd7,
+       0x99, 0xf8, 0x39, 0x87, 0x39, 0xf3, 0x7e, 0xde, 0xe2, 0xe9, 0xf3, 0x16,
+       0x4f, 0x4f, 0xda, 0xbb, 0xe7, 0xe4, 0xb5, 0xcd, 0x38, 0x8f, 0x67, 0xae,
+       0x0f, 0xe8, 0xaa, 0x4a, 0x9e, 0x9b, 0xc6, 0x1d, 0x75, 0xcb, 0xe7, 0x64,
+       0x54, 0xdb, 0x6f, 0x31, 0x79, 0x87, 0x96, 0x79, 0x5f, 0xc5, 0x5a, 0x96,
+       0x00, 0x73, 0x83, 0x14, 0x12, 0x31, 0xbd, 0xf6, 0xae, 0xff, 0x5b, 0xae,
+       0xa1, 0x55, 0xe2, 0x64, 0x99, 0xbf, 0x56, 0x07, 0x53, 0xe4, 0xa3, 0x12,
+       0x2e, 0xd2, 0xee, 0xa7, 0x35, 0x5c, 0xb7, 0x40, 0x0e, 0x16, 0x44, 0xb5,
+       0x35, 0xca, 0x95, 0xa0, 0x05, 0x95, 0x80, 0x46, 0x0b, 0x9f, 0x82, 0x3d,
+       0x95, 0x9f, 0xa5, 0x9d, 0xde, 0x41, 0xdf, 0x28, 0x9e, 0xef, 0xdd, 0x48,
+       0x3a, 0x52, 0x86, 0x6f, 0x1c, 0x95, 0xef, 0xd5, 0x74, 0xea, 0x28, 0x3f,
+       0xa1, 0x6d, 0x71, 0xd7, 0xdf, 0xea, 0x5a, 0x9f, 0xde, 0x55, 0xfe, 0x96,
+       0x95, 0x65, 0x29, 0xea, 0x67, 0xb4, 0x4b, 0xe5, 0x7b, 0xdb, 0xc8, 0x63,
+       0x1e, 0xfc, 0xe1, 0xac, 0xf2, 0xb5, 0xff, 0x55, 0x50, 0x7d, 0x9b, 0x56,
+       0xd4, 0xd7, 0x77, 0xc7, 0x3e, 0xbb, 0xf6, 0xee, 0xd9, 0x7b, 0xca, 0xde,
+       0x0b, 0x6e, 0x1f, 0xef, 0x8e, 0xb8, 0x19, 0xde, 0xb1, 0x86, 0x19, 0xf6,
+       0xa1, 0xf9, 0x2a, 0x34, 0xb6, 0x72, 0x97, 0x57, 0x14, 0xf2, 0xd5, 0x57,
+       0xe5, 0x96, 0x59, 0x23, 0x97, 0xf7, 0x96, 0xc2, 0x10, 0x3e, 0xa2, 0xb7,
+       0x00, 0xff, 0x38, 0x7b, 0xb0, 0x22, 0xb7, 0x54, 0x89, 0xb7, 0x4f, 0x02,
+       0x7f, 0x43, 0x2e, 0x79, 0xd3, 0x13, 0xca, 0xe3, 0xbb, 0x84, 0xf6, 0x6a,
+       0xb1, 0x44, 0x9c, 0x5f, 0x10, 0xae, 0x4d, 0xb1, 0xf4, 0xb4, 0x5e, 0x9b,
+       0x23, 0xa5, 0x05, 0xe0, 0xe7, 0xcb, 0xa0, 0xfb, 0x30, 0x5c, 0x08, 0x8a,
+       0xa0, 0x9c, 0x3f, 0xc6, 0x6f, 0xd8, 0x28, 0xa5, 0x67, 0xf1, 0x7e, 0xa3,
+       0x14, 0x27, 0xc9, 0x73, 0xae, 0xe5, 0xe1, 0xb3, 0xe0, 0xa7, 0x9f, 0x41,
+       0xbf, 0x28, 0xeb, 0xe3, 0xef, 0x1f, 0xe0, 0x1d, 0xee, 0xb3, 0x58, 0xc4,
+       0x36, 0xda, 0x40, 0x1c, 0x9b, 0x6b, 0xc7, 0x35, 0xa3, 0xaf, 0x5e, 0xef,
+       0x97, 0x73, 0xbd, 0xd2, 0xdd, 0x05, 0x59, 0x8a, 0x2b, 0xc8, 0xb9, 0x12,
+       0xeb, 0x93, 0xfe, 0xfb, 0xd6, 0x19, 0x1d, 0xb1, 0xa1, 0xd9, 0xdc, 0x57,
+       0xb6, 0xe5, 0x9a, 0xd7, 0xd3, 0x20, 0x7d, 0xa8, 0x74, 0x7f, 0x01, 0x72,
+       0xc7, 0xf5, 0x37, 0xca, 0xa0, 0x96, 0x9d, 0xa4, 0x09, 0xd2, 0xc0, 0xcd,
+       0xca, 0xd0, 0xe6, 0xfb, 0x95, 0xa1, 0xcd, 0xa7, 0x41, 0x8b, 0xb8, 0xca,
+       0x8b, 0x8e, 0xa1, 0xcd, 0x2f, 0xe3, 0x8e, 0xab, 0xfc, 0xa2, 0x13, 0xf1,
+       0xf1, 0x00, 0xfc, 0xca, 0xbd, 0x25, 0xd7, 0x19, 0xad, 0x82, 0x7e, 0xcb,
+       0x71, 0x94, 0xcf, 0x13, 0xe7, 0x98, 0x3f, 0xc7, 0xd9, 0x69, 0xfb, 0x3f,
+       0x27, 0x63, 0xe5, 0x50, 0xdb, 0x5b, 0xf9, 0xd9, 0x7b, 0x71, 0x5f, 0xaf,
+       0xe5, 0x8c, 0xf2, 0xb3, 0xca, 0xc8, 0xab, 0x77, 0xe0, 0xde, 0x99, 0x3c,
+       0x22, 0x9d, 0x5e, 0x4c, 0x9e, 0x45, 0x5f, 0xdf, 0x75, 0xc6, 0xaa, 0x2f,
+       0xe3, 0xfa, 0x3e, 0xae, 0x57, 0x71, 0xbd, 0x82, 0x7e, 0x5f, 0x40, 0xf9,
+       0x7a, 0x99, 0xf7, 0x9a, 0x51, 0x5f, 0xd4, 0x68, 0xf5, 0x79, 0x67, 0xe4,
+       0xf4, 0x4b, 0xb8, 0x5c, 0x35, 0x56, 0x7d, 0xce, 0xc9, 0xcf, 0x86, 0x9b,
+       0x16, 0x7c, 0xca, 0xb0, 0xaf, 0x3a, 0xa6, 0xef, 0x0c, 0xe6, 0x00, 0x9a,
+       0x2e, 0xcf, 0x63, 0xec, 0xa7, 0x35, 0xcf, 0x0c, 0x42, 0x1f, 0xe4, 0x61,
+       0xaf, 0x8c, 0x68, 0x98, 0xb6, 0x03, 0x3e, 0xf8, 0xd3, 0x7d, 0xb8, 0xcf,
+       0x36, 0xca, 0x62, 0x82, 0xf6, 0xe5, 0x93, 0xba, 0x7e, 0xbe, 0x7c, 0xbd,
+       0xc6, 0xed, 0xf4, 0x2a, 0xfe, 0xa1, 0x4f, 0x18, 0xc9, 0x03, 0x23, 0x8d,
+       0x67, 0x4a, 0x94, 0x05, 0xd0, 0x4d, 0xa5, 0x09, 0xdc, 0x1b, 0xb5, 0x4c,
+       0x28, 0x4a, 0x24, 0x0f, 0xd8, 0x8e, 0x32, 0xa1, 0x5e, 0xee, 0x50, 0xd6,
+       0x50, 0xf6, 0x50, 0x96, 0x98, 0xf5, 0x18, 0x7d, 0x90, 0x32, 0xfc, 0x3a,
+       0xe8, 0x4d, 0xda, 0x25, 0xbe, 0xf1, 0x4d, 0xa6, 0x72, 0xca, 0xc8, 0xd3,
+       0xfd, 0x7a, 0x2d, 0xc6, 0x4a, 0x2a, 0x01, 0xc8, 0x51, 0x86, 0xeb, 0xe4,
+       0x41, 0xdc, 0xf3, 0x6a, 0x0c, 0x57, 0xfe, 0xe4, 0xfb, 0xf0, 0x9b, 0x6b,
+       0x33, 0x86, 0x7a, 0xb8, 0xca, 0xc3, 0xb8, 0xe3, 0x2a, 0xdf, 0xa8, 0x8c,
+       0x1c, 0xe1, 0x9a, 0x26, 0xed, 0x9a, 0x3e, 0x09, 0x3c, 0x70, 0x7e, 0x4a,
+       0xc7, 0x38, 0x94, 0xbf, 0x07, 0x78, 0xaf, 0x5a, 0x9f, 0x7a, 0xa3, 0x18,
+       0x1e, 0xc4, 0xd5, 0x4d, 0x7e, 0x6e, 0x31, 0xeb, 0xa5, 0x69, 0x77, 0x5d,
+       0x83, 0xe1, 0xc5, 0x04, 0xca, 0x62, 0x28, 0x6b, 0x33, 0x3a, 0x73, 0x09,
+       0x8f, 0x59, 0x8b, 0x47, 0xfe, 0x56, 0xf6, 0x37, 0xe8, 0x09, 0xb6, 0x2e,
+       0xe4, 0x35, 0xc6, 0xc5, 0x5c, 0x4e, 0xee, 0x57, 0xa3, 0x65, 0xfa, 0xc9,
+       0x94, 0xe1, 0x8c, 0x65, 0x70, 0x7e, 0xec, 0x17, 0xe5, 0x1a, 0x07, 0x81,
+       0xd4, 0xe2, 0x04, 0x4f, 0x62, 0xcd, 0xce, 0xc9, 0xa1, 0xf2, 0x47, 0xb4,
+       0xdf, 0xde, 0x78, 0xc2, 0xac, 0x87, 0xa8, 0xa8, 0x1e, 0xfa, 0x4e, 0xd0,
+       0xe6, 0xf9, 0x75, 0xfd, 0xde, 0x3d, 0xc1, 0xdf, 0x49, 0x1d, 0x4f, 0xaa,
+       0xc9, 0x7b, 0x63, 0xef, 0x14, 0x97, 0xc9, 0x3a, 0xda, 0x1d, 0x58, 0xb3,
+       0x4a, 0x3d, 0xde, 0x19, 0x47, 0xa0, 0xcc, 0x23, 0x3f, 0x1d, 0x01, 0x4f,
+       0x60, 0xf2, 0x9a, 0xf7, 0xe9, 0x83, 0xac, 0xc5, 0x4f, 0x3e, 0x6c, 0x62,
+       0x57, 0x4e, 0xc1, 0xa6, 0xdb, 0xbb, 0xd4, 0x07, 0x64, 0x65, 0x22, 0x2e,
+       0xa7, 0x4b, 0x2d, 0x32, 0x5b, 0x52, 0x6d, 0x31, 0x2b, 0x3b, 0x63, 0x92,
+       0xd4, 0xfa, 0x97, 0x76, 0xdf, 0xc0, 0x54, 0xcc, 0xd2, 0xdd, 0x8d, 0xe8,
+       0xff, 0x93, 0xd0, 0xb1, 0x15, 0xe8, 0xd8, 0x8d, 0xd0, 0xc1, 0x2b, 0x65,
+       0xc4, 0xfe, 0x86, 0xd5, 0x32, 0x82, 0x6d, 0xd2, 0xf0, 0xd6, 0x8f, 0xa0,
+       0x5d, 0x44, 0x7f, 0x71, 0x4d, 0x6b, 0x79, 0x29, 0x38, 0x7b, 0xab, 0x13,
+       0xce, 0xbe, 0xea, 0x4a, 0x1d, 0xd4, 0xe3, 0xb9, 0x62, 0x60, 0x3d, 0x5d,
+       0xa2, 0xed, 0x9a, 0x0e, 0x72, 0xc0, 0xc9, 0x3e, 0xd0, 0xdd, 0x53, 0x93,
+       0xf0, 0xef, 0x29, 0x97, 0x01, 0xf3, 0x19, 0xc0, 0x3c, 0x33, 0xe9, 0x44,
+       0xb6, 0x81, 0x30, 0x40, 0x33, 0x33, 0xd5, 0x2b, 0x0b, 0x73, 0xa4, 0x43,
+       0xc8, 0x80, 0x49, 0xac, 0x67, 0xb0, 0x0e, 0x76, 0x00, 0xc7, 0x87, 0xdc,
+       0x9e, 0xda, 0xa6, 0xdf, 0x19, 0x7d, 0xde, 0x2e, 0x0b, 0x95, 0x3b, 0x2d,
+       0x6c, 0xc7, 0xea, 0x60, 0x5b, 0xb7, 0x04, 0xdb, 0x3e, 0xc0, 0xb6, 0x7f,
+       0x4d, 0xd8, 0xd6, 0xd2, 0xc5, 0x1d, 0xb0, 0x69, 0xc8, 0x1f, 0x11, 0x5e,
+       0xdb, 0x2c, 0x3d, 0x94, 0xac, 0x1d, 0x4c, 0x9b, 0xe8, 0x87, 0x80, 0x87,
+       0x34, 0x86, 0xdf, 0xb3, 0x8f, 0x52, 0x96, 0xa1, 0x9c, 0xcf, 0x0f, 0xa1,
+       0x0e, 0x9e, 0x67, 0x13, 0x56, 0x0e, 0x7e, 0xc2, 0xc2, 0x42, 0x3b, 0x21,
+       0x0b, 0x5b, 0x79, 0xd0, 0xc9, 0xcd, 0x12, 0x86, 0x53, 0x80, 0x17, 0xef,
+       0xaa, 0xf5, 0x7d, 0xf2, 0xce, 0x7e, 0xaf, 0xb2, 0xfd, 0xb0, 0xef, 0x68,
+       0x2e, 0xeb, 0xad, 0x9e, 0x8f, 0xe8, 0x2b, 0xb2, 0xbb, 0x27, 0x9c, 0xec,
+       0xaa, 0x79, 0xd5, 0xd3, 0x1c, 0xe5, 0xad, 0x2b, 0x43, 0xa0, 0x93, 0xa1,
+       0x65, 0xb4, 0xa6, 0xdd, 0x13, 0x4b, 0xc7, 0xeb, 0xec, 0xfc, 0x0e, 0x1b,
+       0xbe, 0x09, 0xe2, 0xd0, 0x87, 0x94, 0x37, 0xff, 0xc5, 0xf8, 0xec, 0xf2,
+       0xe5, 0x06, 0xc6, 0x69, 0xcd, 0x33, 0x69, 0x93, 0xbf, 0x29, 0x93, 0x6a,
+       0xb4, 0x68, 0x7c, 0x9a, 0x76, 0x8c, 0x55, 0x6f, 0xc7, 0xbb, 0x32, 0x6c,
+       0xd6, 0xfc, 0x18, 0xd7, 0x9c, 0x3e, 0x4a, 0xe7, 0x03, 0xc3, 0x96, 0xbf,
+       0xd2, 0x93, 0x05, 0xb9, 0xd5, 0xce, 0xfd, 0xd2, 0x1a, 0x6b, 0xb7, 0x71,
+       0x69, 0xed, 0x86, 0xab, 0x2b, 0xe7, 0x28, 0xd2, 0xf1, 0x80, 0xab, 0x7d,
+       0x5e, 0xfa, 0xf0, 0x8d, 0x3e, 0xe5, 0x27, 0x6d, 0x25, 0x94, 0xcf, 0xf4,
+       0x78, 0xad, 0xf0, 0x0d, 0xbe, 0xb8, 0xca, 0xee, 0x4a, 0x59, 0xb9, 0x49,
+       0xff, 0x38, 0x1a, 0xa3, 0x60, 0xe5, 0x64, 0x01, 0xfd, 0x4f, 0x38, 0x43,
+       0xd5, 0xb5, 0xe4, 0x65, 0x24, 0x27, 0x39, 0x9f, 0x7b, 0xe5, 0x8e, 0x07,
+       0xc9, 0xa3, 0x25, 0x6d, 0x5f, 0x5f, 0xb3, 0xe7, 0x30, 0xf0, 0x47, 0xf8,
+       0x17, 0x36, 0xc3, 0x64, 0x80, 0xce, 0xcd, 0xca, 0xa8, 0x5d, 0xb7, 0xd1,
+       0xa5, 0xf5, 0xe7, 0x35, 0x0c, 0xdd, 0xc8, 0x58, 0xae, 0xb2, 0x30, 0x6b,
+       0x3b, 0x16, 0x76, 0xdd, 0x4a, 0x5b, 0x96, 0x73, 0xa0, 0x3d, 0xdb, 0x68,
+       0x6c, 0xc1, 0x32, 0xed, 0x4f, 0xca, 0x2e, 0xda, 0x9f, 0x57, 0x37, 0x4a,
+       0x33, 0xe7, 0x93, 0xb5, 0x65, 0xb4, 0x53, 0x57, 0xce, 0x6f, 0xa5, 0x5f,
+       0x49, 0x38, 0x09, 0xb7, 0xa1, 0xad, 0x94, 0x22, 0x6c, 0xa1, 0x0c, 0x07,
+       0xd7, 0xe9, 0x35, 0x50, 0xb4, 0x5d, 0xf7, 0x34, 0x34, 0x9a, 0x38, 0xf6,
+       0x5e, 0xf4, 0xcf, 0x31, 0xc9, 0x7f, 0xbc, 0xd3, 0xce, 0x5f, 0x4b, 0x96,
+       0xd5, 0xeb, 0x9e, 0x2b, 0x97, 0xf0, 0x37, 0xb4, 0x6c, 0x8d, 0x22, 0xfc,
+       0x45, 0x74, 0x51, 0x8f, 0x43, 0xd2, 0x04, 0x69, 0x21, 0xa2, 0xc5, 0x9d,
+       0x56, 0xdf, 0x44, 0xb4, 0xb7, 0x15, 0xb4, 0x77, 0x1f, 0xf0, 0x44, 0x19,
+       0xce, 0x78, 0xde, 0x16, 0x3c, 0x1f, 0xc7, 0x73, 0xc4, 0x27, 0x91, 0x0c,
+       0xa7, 0x4d, 0xb4, 0x52, 0x8e, 0x53, 0x86, 0xc7, 0x61, 0xf7, 0x50, 0xd6,
+       0x6f, 0xb7, 0xfc, 0x94, 0xb3, 0xbc, 0x44, 0x5d, 0xf0, 0xfb, 0xe8, 0xe7,
+       0x86, 0x46, 0x63, 0xa7, 0x17, 0x1b, 0x29, 0x5f, 0x37, 0xcb, 0x91, 0xba,
+       0xb2, 0xcb, 0xc9, 0xef, 0xfa, 0x39, 0x6f, 0xff, 0x7f, 0x30, 0xe7, 0xe4,
+       0x8a, 0x39, 0x7b, 0x76, 0xce, 0x55, 0xbc, 0x6f, 0xc5, 0xfb, 0x16, 0xea,
+       0x82, 0x54, 0x4d, 0xde, 0x58, 0x5c, 0x68, 0x7d, 0x56, 0x2f, 0x27, 0x22,
+       0x19, 0xc1, 0x79, 0x1d, 0xb5, 0x73, 0xf8, 0x7c, 0xdd, 0xbc, 0x8e, 0xbe,
+       0x89, 0x79, 0xb5, 0x2f, 0x9b, 0xd7, 0xde, 0xcb, 0xce, 0x6b, 0x2d, 0x1e,
+       0x27, 0x2f, 0x47, 0xf3, 0x8b, 0xcb, 0x81, 0x12, 0xe7, 0x38, 0x84, 0x39,
+       0x12, 0x86, 0x68, 0x8e, 0x19, 0x3b, 0x47, 0x51, 0x1d, 0x7b, 0x7e, 0x0a,
+       0xbf, 0xeb, 0xe7, 0x47, 0xdd, 0xff, 0xf7, 0xa0, 0xe9, 0x26, 0xf8, 0xc4,
+       0x4d, 0x56, 0xfe, 0x3f, 0x29, 0xb7, 0x96, 0xb9, 0xd6, 0xe9, 0xac, 0xc8,
+       0x7e, 0x75, 0xa8, 0xfc, 0x72, 0x23, 0xf7, 0x11, 0xf6, 0x06, 0x56, 0x8f,
+       0x41, 0x5f, 0xec, 0x83, 0xcd, 0x37, 0x54, 0x52, 0x7d, 0x31, 0x09, 0xc3,
+       0xdb, 0x82, 0x66, 0x8c, 0xbd, 0x49, 0xfb, 0xaa, 0xab, 0x63, 0xf8, 0xcf,
+       0x36, 0x8a, 0x4f, 0x7b, 0x83, 0xfa, 0x1c, 0xfa, 0xee, 0x24, 0x6d, 0xb0,
+       0x1c, 0xec, 0xe4, 0x6c, 0x32, 0xa6, 0x6d, 0x31, 0xea, 0xc4, 0x74, 0x32,
+       0x2b, 0x15, 0xc9, 0x9f, 0xcc, 0x26, 0xe1, 0xd8, 0x62, 0x0c, 0xd8, 0x6a,
+       0xb0, 0x21, 0x6f, 0x85, 0xac, 0xb9, 0xb5, 0x7a, 0x50, 0xdd, 0x02, 0x7b,
+       0xe7, 0x96, 0xd3, 0xef, 0x53, 0xb7, 0xc1, 0xd6, 0xb9, 0xed, 0xf4, 0x8d,
+       0xea, 0x10, 0x6c, 0x9b, 0x43, 0xb0, 0x73, 0x0e, 0x55, 0x69, 0x7b, 0xde,
+       0x0c, 0xba, 0x6b, 0x87, 0x1e, 0xe2, 0x5c, 0xb8, 0x26, 0xb4, 0x71, 0x38,
+       0x3f, 0xe2, 0xfe, 0x0b, 0x5c, 0x83, 0x20, 0xa5, 0x76, 0x34, 0x71, 0x5d,
+       0x5a, 0x97, 0x95, 0xbd, 0x96, 0xac, 0x8a, 0xf4, 0xd3, 0x06, 0x1b, 0x4f,
+       0x32, 0x7e, 0xe5, 0xe5, 0x69, 0x8b, 0x34, 0xe2, 0x01, 0xcf, 0xc4, 0x1f,
+       0x69, 0xab, 0x7e, 0xfe, 0x57, 0x36, 0x89, 0x9f, 0xc3, 0xf8, 0xf7, 0x42,
+       0xbe, 0xd6, 0xd3, 0x14, 0xef, 0x5e, 0x1d, 0x7f, 0x50, 0x06, 0x47, 0xf4,
+       0xb0, 0xf3, 0x35, 0xe4, 0xef, 0x65, 0xe9, 0xe9, 0x9e, 0x58, 0x26, 0x0c,
+       0x47, 0xfb, 0x64, 0x13, 0xe3, 0x01, 0xb9, 0x6a, 0x2d, 0x26, 0xa0, 0xfc,
+       0xfa, 0x98, 0x00, 0xfd, 0xac, 0x4f, 0x03, 0xbf, 0xd3, 0xb8, 0x44, 0x46,
+       0x18, 0x77, 0xa8, 0x46, 0x76, 0xf9, 0x57, 0xac, 0x5d, 0x1e, 0xc1, 0x91,
+       0x02, 0x1c, 0x46, 0x3e, 0xaf, 0xd6, 0x73, 0xcb, 0xf5, 0x77, 0x61, 0xc9,
+       0xa6, 0x4d, 0xc9, 0x81, 0xb2, 0xb6, 0x13, 0x21, 0x83, 0x89, 0x9b, 0x7a,
+       0x19, 0x9c, 0xb4, 0x76, 0x14, 0xea, 0x68, 0xf9, 0xb9, 0x5a, 0x76, 0x52,
+       0xee, 0x31, 0x6e, 0xff, 0x40, 0x40, 0x5a, 0x7f, 0x97, 0x64, 0x97, 0xe2,
+       0xf6, 0x02, 0x7a, 0x93, 0x20, 0x96, 0xd1, 0x7b, 0x7a, 0xde, 0x8c, 0xec,
+       0x93, 0x81, 0x04, 0x63, 0xa0, 0x8c, 0xf3, 0xf9, 0x85, 0x19, 0xe9, 0x66,
+       0x8c, 0x03, 0x16, 0x7c, 0xa3, 0x8c, 0x78, 0xa1, 0xec, 0x0d, 0x1c, 0x1d,
+       0x53, 0x36, 0xba, 0xf6, 0x62, 0x93, 0xb1, 0x5d, 0x1d, 0x1d, 0x17, 0x5e,
+       0x00, 0xf5, 0x2d, 0x68, 0xfb, 0x56, 0x69, 0xfd, 0x3b, 0xaf, 0xeb, 0xfc,
+       0x41, 0x53, 0x14, 0xdf, 0x5c, 0xf0, 0x62, 0xb6, 0x5e, 0x7d, 0xf9, 0xd7,
+       0x6c, 0xdc, 0xba, 0x1b, 0xb2, 0x3f, 0x2a, 0xfb, 0xde, 0x1a, 0x65, 0xb1,
+       0xf8, 0xea, 0xb2, 0xcd, 0x6b, 0x94, 0x99, 0x78, 0xe1, 0x50, 0x69, 0x27,
+       0xde, 0x4d, 0x68, 0xdf, 0x5d, 0xf4, 0x9e, 0x5b, 0xb7, 0x14, 0x96, 0xea,
+       0x6c, 0xb0, 0x7e, 0x19, 0x63, 0xc7, 0x26, 0x66, 0x9c, 0xd7, 0x31, 0xe3,
+       0x1e, 0x6f, 0x8f, 0xd2, 0x7b, 0x2c, 0xb7, 0x33, 0xfe, 0x78, 0x48, 0xe3,
+       0x85, 0x38, 0xf9, 0x02, 0x63, 0xc3, 0x05, 0xee, 0x0f, 0xa7, 0xd4, 0xe5,
+       0x68, 0xbb, 0x66, 0x9b, 0x98, 0x75, 0xa3, 0x5d, 0xdc, 0x22, 0x83, 0xb0,
+       0x15, 0x86, 0x4a, 0xad, 0xb2, 0x77, 0xea, 0xa3, 0xeb, 0xa8, 0xb7, 0xf6,
+       0x4d, 0x19, 0x7f, 0xf0, 0x10, 0xf8, 0x2a, 0x2b, 0x84, 0x31, 0x1d, 0x88,
+       0xd0, 0x26, 0x5e, 0x6d, 0x0b, 0xbf, 0x76, 0x7f, 0xf7, 0x5f, 0xa6, 0x3f,
+       0x07, 0xb6, 0xc3, 0x1b, 0xed, 0xaf, 0x59, 0x06, 0xa7, 0x22, 0x5c, 0xa9,
+       0x1f, 0xb1, 0x5d, 0xec, 0x32, 0xed, 0xb4, 0x5d, 0x22, 0x4f, 0x2d, 0xc9,
+       0xe2, 0x9d, 0xb0, 0x99, 0x24, 0xcc, 0xf5, 0x49, 0x7b, 0x4c, 0x74, 0x8c,
+       0x27, 0x30, 0xb2, 0xb9, 0x8b, 0x7b, 0x3e, 0xa0, 0x7f, 0x63, 0xab, 0x98,
+       0x78, 0x6a, 0x64, 0xa7, 0xac, 0x45, 0xbb, 0xd7, 0x5b, 0xda, 0xe5, 0xbe,
+       0xee, 0x3e, 0xca, 0x5c, 0xac, 0x89, 0xa1, 0xe3, 0xbd, 0x25, 0x49, 0x45,
+       0x74, 0xbc, 0x20, 0xd9, 0x65, 0x74, 0xbc, 0x20, 0x83, 0x9a, 0x8e, 0x1b,
+       0x97, 0xd1, 0x71, 0xbb, 0xa5, 0xe3, 0x8f, 0xc6, 0x0d, 0x5d, 0x28, 0xad,
+       0xa7, 0x48, 0xa7, 0x86, 0x8e, 0x1d, 0x4d, 0xc7, 0x0b, 0xb8, 0xbb, 0xfe,
+       0xc7, 0x6c, 0x9d, 0x98, 0x2d, 0xe3, 0xef, 0xa8, 0x8c, 0x72, 0x71, 0x2a,
+       0x6e, 0xf4, 0xd2, 0x20, 0xe8, 0x28, 0x2a, 0xff, 0x4d, 0x4b, 0x9f, 0xf5,
+       0x65, 0x26, 0x3e, 0x32, 0x54, 0x3a, 0xb2, 0x82, 0x3e, 0x07, 0x41, 0x9f,
+       0x51, 0x9d, 0xd7, 0xa2, 0xcf, 0x66, 0xbb, 0x9f, 0x91, 0xd4, 0x7b, 0xff,
+       0xd9, 0x84, 0xa1, 0xd5, 0x5b, 0xf4, 0xdc, 0x39, 0xef, 0x0b, 0x6f, 0x80,
+       0x56, 0xcd, 0xda, 0x5c, 0xac, 0xf9, 0xdb, 0x8c, 0x45, 0xa5, 0x4c, 0x6c,
+       0x9b, 0x71, 0xd2, 0xcb, 0xd9, 0x8e, 0x2f, 0xd5, 0xf9, 0x15, 0x1b, 0xa4,
+       0xc0, 0xbc, 0x87, 0xea, 0x46, 0xc6, 0xa2, 0x47, 0xdc, 0x4c, 0x9f, 0x64,
+       0x2b, 0xed, 0xa9, 0x62, 0x89, 0x7e, 0xd1, 0xab, 0x36, 0x37, 0x02, 0xcf,
+       0x95, 0x16, 0x79, 0xb4, 0x44, 0xda, 0x3a, 0x62, 0x70, 0xb1, 0x26, 0xad,
+       0x73, 0xad, 0xd9, 0x4f, 0xbd, 0x0e, 0xe8, 0x83, 0xee, 0xa1, 0xcd, 0xae,
+       0xe5, 0x3e, 0xde, 0xb5, 0xa7, 0x72, 0xa5, 0xa8, 0x5f, 0xee, 0x3f, 0x70,
+       0x4f, 0xb8, 0x3d, 0xd5, 0x51, 0xf1, 0x6d, 0x9c, 0x79, 0x23, 0x9e, 0xfb,
+       0xa4, 0xa3, 0xa2, 0xe4, 0x03, 0x53, 0x2d, 0x72, 0x7b, 0xc9, 0x95, 0x0f,
+       0xa1, 0xfd, 0x07, 0x4b, 0x1e, 0xfc, 0xfb, 0xff, 0x1d, 0xa7, 0x9d, 0x79,
+       0xa8, 0xc4, 0x7d, 0x50, 0x47, 0xdb, 0x2a, 0xcb, 0xf7, 0x86, 0x63, 0xd2,
+       0xd1, 0x55, 0x84, 0xe7, 0x23, 0xee, 0x7e, 0xc0, 0xd1, 0x94, 0xc9, 0xc8,
+       0x77, 0xfa, 0x36, 0xa1, 0x2c, 0xca, 0xf1, 0x18, 0x76, 0x4c, 0xfc, 0xb8,
+       0x5f, 0xde, 0x59, 0xcd, 0xc8, 0x0d, 0x55, 0xb3, 0x77, 0x5b, 0xdb, 0x9b,
+       0x4d, 0x7b, 0xf3, 0xd0, 0x67, 0x59, 0x2f, 0x0c, 0x2f, 0xfa, 0xa0, 0xa2,
+       0xe3, 0xae, 0xc4, 0xbb, 0xd2, 0xc9, 0x79, 0x31, 0xcf, 0x97, 0x2a, 0xff,
+       0x1c, 0x8e, 0x24, 0x5c, 0xf9, 0x8e, 0xcf, 0x39, 0xf6, 0xcb, 0xf5, 0x95,
+       0xfa, 0xb1, 0xb9, 0x3f, 0x1b, 0x5b, 0xc7, 0xfd, 0x90, 0x5c, 0xf5, 0x9f,
+       0xe3, 0x8c, 0xdb, 0xd3, 0x87, 0xe9, 0xf8, 0x31, 0xee, 0x87, 0xbb, 0xb8,
+       0x83, 0x0e, 0x13, 0xb0, 0x21, 0xae, 0x01, 0x8c, 0xd7, 0x30, 0x96, 0xc6,
+       0x18, 0x1a, 0x9f, 0xbf, 0x8c, 0x71, 0xd9, 0xf6, 0x93, 0xd6, 0xfe, 0x3e,
+       0xb2, 0xc4, 0x8b, 0x6b, 0xeb, 0xb1, 0x8d, 0x23, 0xf1, 0x8c, 0x38, 0xf1,
+       0x9f, 0x48, 0xca, 0x3a, 0xbf, 0x7e, 0x7c, 0xee, 0x47, 0xc3, 0xa2, 0xec,
+       0x13, 0x77, 0xdf, 0xee, 0x7e, 0x19, 0xc4, 0xfc, 0x86, 0x56, 0xcd, 0xef,
+       0x1e, 0x61, 0xbc, 0xf6, 0x52, 0x89, 0x73, 0xa8, 0xcd, 0x4b, 0xfd, 0xb6,
+       0x99, 0x57, 0xbc, 0x6b, 0xe5, 0x7c, 0x74, 0x7b, 0x75, 0x0a, 0xb0, 0x7c,
+       0x49, 0xe7, 0x42, 0x84, 0xe1, 0x5b, 0xbb, 0x2e, 0x85, 0xa9, 0x2b, 0xd2,
+       0xdd, 0xf3, 0xb5, 0x7d, 0xa4, 0x91, 0x58, 0x26, 0xab, 0xf5, 0x23, 0x9e,
+       0x53, 0xf9, 0xca, 0x7e, 0xac, 0xa3, 0xb8, 0xf9, 0x5e, 0x57, 0xf3, 0x5d,
+       0xde, 0xdf, 0x6f, 0xf7, 0xca, 0x22, 0x9f, 0x2c, 0x0c, 0x95, 0xbf, 0x52,
+       0x0e, 0x51, 0xff, 0x61, 0xee, 0xf2, 0x98, 0xdd, 0x3f, 0xe8, 0x66, 0x7c,
+       0x0c, 0xb4, 0x18, 0x07, 0xdd, 0xf9, 0xf8, 0xdd, 0x82, 0xfb, 0x1e, 0xd8,
+       0x3f, 0x01, 0xec, 0x23, 0x49, 0x28, 0x23, 0x6b, 0xc0, 0x1b, 0x5d, 0x05,
+       0xa5, 0xc8, 0xeb, 0x5e, 0x6a, 0xbc, 0x92, 0x48, 0x4d, 0x56, 0x9e, 0x60,
+       0x7b, 0xd4, 0x5d, 0x2b, 0x36, 0x68, 0xf2, 0x6c, 0xbe, 0x58, 0xe5, 0x18,
+       0xa4, 0xfb, 0x37, 0x32, 0x86, 0x6b, 0xfb, 0x66, 0x9f, 0x11, 0x5e, 0x5c,
+       0xba, 0xf8, 0xf8, 0xb7, 0xdf, 0xfa, 0x3a, 0x9c, 0xdf, 0x13, 0x16, 0xee,
+       0x95, 0xe3, 0x3e, 0xaf, 0xed, 0xa1, 0xc7, 0xab, 0xb4, 0x41, 0xb9, 0x8f,
+       0x94, 0x7e, 0x64, 0x5a, 0x08, 0x47, 0x18, 0x3e, 0x1b, 0x18, 0x5b, 0xe0,
+       0x8b, 0x55, 0xee, 0x99, 0x84, 0xe1, 0xdf, 0xd2, 0xce, 0x3e, 0x58, 0xc6,
+       0x78, 0x11, 0x0e, 0x76, 0x16, 0x5c, 0xc8, 0xd9, 0x89, 0x3e, 0xe2, 0x57,
+       0xe0, 0xf1, 0x76, 0x79, 0x07, 0x24, 0x9e, 0xfa, 0x78, 0xa5, 0x25, 0x75,
+       0x67, 0xc5, 0x03, 0x9e, 0x39, 0xef, 0x44, 0x6a, 0xcc, 0xce, 0x39, 0x5f,
+       0x21, 0x7e, 0x5f, 0x6b, 0xbf, 0xf3, 0xf9, 0x65, 0xfe, 0x17, 0x61, 0xaa,
+       0xc1, 0x42, 0xd8, 0x52, 0x16, 0x37, 0x61, 0xf8, 0xf7, 0x01, 0xc7, 0xdc,
+       0x0f, 0x1f, 0x46, 0x26, 0x30, 0x6e, 0x61, 0x8b, 0x22, 0x1e, 0xe2, 0xa9,
+       0x3b, 0x30, 0xf6, 0xc7, 0x31, 0xf6, 0xed, 0x15, 0x8e, 0x07, 0xd9, 0x83,
+       0xb9, 0x4f, 0x54, 0x23, 0x78, 0xd7, 0x1a, 0x3b, 0x5a, 0xf3, 0x6e, 0x6b,
+       0x33, 0x46, 0xcf, 0x1a, 0x91, 0x6d, 0x0a, 0xbe, 0x63, 0xae, 0xba, 0xb0,
+       0xd9, 0x95, 0x9f, 0x81, 0x1c, 0x0f, 0xe5, 0x51, 0xc8, 0xc7, 0x05, 0x4d,
+       0x37, 0xb9, 0xed, 0xfc, 0x3f, 0x26, 0x4f, 0xad, 0x63, 0xbc, 0x7a, 0xc0,
+       0xa7, 0x2d, 0xbc, 0x18, 0x2e, 0xf8, 0x94, 0xf7, 0x1b, 0x64, 0xda, 0x2b,
+       0x74, 0x43, 0xf7, 0xa0, 0x6c, 0x23, 0xfd, 0xf7, 0x54, 0x2e, 0x96, 0x4e,
+       0x8d, 0x0b, 0x73, 0xbe, 0x98, 0x13, 0xc1, 0xbc, 0x26, 0xca, 0x06, 0x17,
+       0x32, 0x94, 0x6b, 0x68, 0xc6, 0x1b, 0xaf, 0xd4, 0xea, 0x1e, 0x16, 0xee,
+       0x4d, 0xa6, 0x93, 0x87, 0xb4, 0xbd, 0x23, 0x32, 0x5a, 0x62, 0xdd, 0xdd,
+       0xb0, 0x76, 0xfc, 0xba, 0xfa, 0x3a, 0x57, 0x0d, 0x7c, 0x1e, 0xc5, 0xc5,
+       0xe2, 0xcc, 0x29, 0x79, 0x39, 0xd6, 0x27, 0x2f, 0xd3, 0x8e, 0x1d, 0x00,
+       0x6d, 0x7b, 0xbe, 0xce, 0x2b, 0xd1, 0xe5, 0xb9, 0x40, 0x16, 0x73, 0xfd,
+       0x3d, 0xb4, 0xdb, 0x0b, 0x4a, 0xf3, 0x84, 0x28, 0xb4, 0x8d, 0xe7, 0x2b,
+       0x32, 0x98, 0x2f, 0xd9, 0xd8, 0xd1, 0x30, 0xe7, 0xbc, 0xa1, 0x6e, 0xee,
+       0x1b, 0xc5, 0x05, 0x4c, 0x83, 0xb1, 0x94, 0xd3, 0xe0, 0x7f, 0xaa, 0xc5,
+       0xd8, 0x10, 0xd0, 0x23, 0xad, 0xf7, 0xb7, 0x71, 0x6f, 0x56, 0xc1, 0x27,
+       0x57, 0x6d, 0x1f, 0xbe, 0x56, 0x65, 0xfe, 0x32, 0x09, 0xbd, 0x6a, 0x65,
+       0x65, 0x7c, 0xb0, 0x63, 0x89, 0xbe, 0x39, 0xbe, 0xb4, 0xc5, 0xfc, 0xd4,
+       0xe0, 0x40, 0x45, 0x54, 0x2c, 0xe3, 0xc5, 0x07, 0x2a, 0xcb, 0x69, 0xfe,
+       0x8b, 0xd5, 0xcf, 0x5a, 0xdb, 0xb2, 0x3e, 0x46, 0x5b, 0xff, 0x8e, 0x7c,
+       0xb7, 0x6c, 0xff, 0x23, 0x05, 0xbe, 0xb2, 0xfb, 0xc6, 0x5c, 0x93, 0xec,
+       0x5b, 0x19, 0xd8, 0x9c, 0xd6, 0x3e, 0x1f, 0x73, 0x3b, 0xe2, 0x36, 0xbf,
+       0xce, 0xe0, 0x3a, 0x5b, 0x71, 0x64, 0x02, 0xf2, 0xe1, 0xb0, 0xfc, 0x53,
+       0x98, 0x4d, 0x98, 0xf7, 0x66, 0x7d, 0x59, 0x9f, 0x7b, 0x1b, 0xcd, 0x52,
+       0x3c, 0xed, 0x4a, 0xe1, 0x34, 0xf7, 0xd4, 0xce, 0xdd, 0x51, 0xcb, 0x0f,
+       0xa1, 0x1c, 0xe0, 0xbe, 0xb0, 0x23, 0x45, 0xf8, 0xc8, 0x83, 0xdc, 0xef,
+       0xef, 0xfd, 0x47, 0xe6, 0xea, 0xc4, 0xb9, 0x4e, 0xa6, 0x6d, 0x0b, 0xda,
+       0x36, 0xda, 0xb6, 0xc1, 0xc7, 0xdf, 0x5c, 0xdb, 0x8d, 0x68, 0x1b, 0x8f,
+       0xc6, 0x7d, 0x83, 0x6d, 0x35, 0x3e, 0xaf, 0x1d, 0x28, 0x95, 0x17, 0x5d,
+       0xdf, 0x4f, 0x8e, 0x49, 0xd6, 0x19, 0xed, 0xd3, 0xf3, 0xb9, 0x76, 0xa0,
+       0x02, 0x38, 0x12, 0x61, 0x58, 0x0c, 0x22, 0xbd, 0xce, 0x7f, 0x27, 0xa1,
+       0xde, 0x59, 0xc6, 0x7d, 0x50, 0xfa, 0x27, 0x8c, 0xba, 0x7a, 0xcc, 0xc1,
+       0x93, 0x22, 0xf7, 0x3b, 0x13, 0x9b, 0x70, 0x57, 0x1d, 0xc4, 0x49, 0xde,
+       0x67, 0xfc, 0x78, 0x93, 0x2d, 0x8f, 0xb1, 0x3c, 0xed, 0x42, 0x96, 0x98,
+       0xf2, 0x98, 0x2d, 0x07, 0x4c, 0x41, 0x31, 0x05, 0x6e, 0xb3, 0xe5, 0x7c,
+       0x56, 0xba, 0xdc, 0x3c, 0x1b, 0x1e, 0x1a, 0x11, 0xc6, 0x89, 0x72, 0xd7,
+       0x37, 0xc8, 0x4e, 0xac, 0x0f, 0x7d, 0x50, 0x47, 0x9a, 0x01, 0xc7, 0xc5,
+       0xe0, 0xc7, 0x61, 0xab, 0x87, 0xf2, 0x9d, 0xc0, 0xd0, 0xff, 0x8c, 0x74,
+       0x65, 0x95, 0xc3, 0x5c, 0x83, 0x50, 0x86, 0x82, 0x5d, 0xc9, 0xbd, 0xf8,
+       0x3d, 0xda, 0x9b, 0x92, 0x99, 0x7e, 0xd0, 0x63, 0x2f, 0x79, 0x63, 0x27,
+       0x6c, 0x28, 0xfc, 0xee, 0x6a, 0x91, 0x45, 0xaf, 0xe0, 0xad, 0x83, 0xff,
+       0x37, 0x88, 0x59, 0xcd, 0x96, 0x7c, 0xef, 0x36, 0x08, 0xb9, 0xac, 0xd7,
+       0x85, 0x7b, 0xfd, 0x7c, 0xbf, 0x8e, 0xf9, 0x9e, 0x6b, 0x96, 0x66, 0x96,
+       0xd7, 0xd7, 0x6d, 0x94, 0xfd, 0xde, 0x6e, 0x2f, 0xbe, 0xac, 0xee, 0x25,
+       0xd4, 0x65, 0x99, 0xef, 0x31, 0x17, 0x68, 0xa6, 0x42, 0x3a, 0x33, 0xb0,
+       0x76, 0x74, 0x85, 0xe1, 0xf5, 0x01, 0xc7, 0x0d, 0xc3, 0x1b, 0x82, 0x1e,
+       0xef, 0x19, 0x79, 0x2e, 0x34, 0x36, 0x5a, 0x44, 0x3b, 0xcf, 0x5a, 0x79,
+       0x1d, 0x86, 0x2f, 0x07, 0xdd, 0xf2, 0xb9, 0x6a, 0xfa, 0x1c, 0x7d, 0xf8,
+       0xf3, 0x78, 0x3e, 0x1f, 0x98, 0xfc, 0xa5, 0x3f, 0x43, 0xbb, 0x84, 0xea,
+       0x05, 0x0d, 0xfb, 0xf2, 0x59, 0xed, 0xf3, 0x13, 0x7f, 0x66, 0xcf, 0xa0,
+       0x06, 0x03, 0x26, 0xec, 0xe7, 0x36, 0x7b, 0xcc, 0x69, 0xd4, 0xf4, 0x5b,
+       0xff, 0x4e, 0xe1, 0x1d, 0xcb, 0xc2, 0xf0, 0x8a, 0xbe, 0x96, 0xf5, 0xd0,
+       0xd7, 0x93, 0xdc, 0x0b, 0x7c, 0x9f, 0xe6, 0x3f, 0x91, 0x03, 0xdc, 0xf7,
+       0x02, 0x0e, 0x95, 0xf2, 0x8f, 0x75, 0xa8, 0x74, 0x41, 0xe4, 0x2d, 0x58,
+       0x7f, 0xae, 0x31, 0x18, 0xa4, 0x15, 0xb0, 0xef, 0xfa, 0xa5, 0x66, 0x13,
+       0x9b, 0xa2, 0x6f, 0x9e, 0xdd, 0x0c, 0xdf, 0x59, 0xdb, 0x33, 0xdc, 0x57,
+       0x1f, 0x6b, 0x0d, 0xc3, 0xf7, 0x06, 0xd1, 0x9a, 0xd9, 0xd8, 0x37, 0x74,
+       0x7c, 0xbe, 0x57, 0xd6, 0x1b, 0xbb, 0x90, 0xb9, 0x8d, 0x29, 0xbd, 0x4f,
+       0xa0, 0xda, 0xa0, 0x43, 0x76, 0xfd, 0x00, 0x38, 0xe5, 0x18, 0xcc, 0x73,
+       0x8c, 0x60, 0xaa, 0xb5, 0xcf, 0xf7, 0xae, 0xb3, 0x36, 0xac, 0x0b, 0x5c,
+       0xfa, 0x5e, 0x87, 0xfa, 0x5e, 0x68, 0x74, 0x6b, 0x44, 0xc3, 0xff, 0x10,
+       0x3e, 0x98, 0x30, 0xcf, 0xb9, 0x5d, 0xec, 0x63, 0xa7, 0x8c, 0xef, 0xc2,
+       0xb3, 0x7b, 0x1d, 0xee, 0x03, 0x57, 0xc6, 0xe4, 0xaa, 0xe4, 0x80, 0xda,
+       0xe5, 0x3d, 0x28, 0x3d, 0x56, 0xc6, 0x7d, 0x09, 0xfa, 0xbe, 0x00, 0xff,
+       0xbe, 0x49, 0x1e, 0x04, 0x4d, 0xab, 0xbe, 0x74, 0x6a, 0x5e, 0xa5, 0xbb,
+       0xa7, 0x55, 0x3a, 0x18, 0x51, 0x13, 0x9c, 0x57, 0x3f, 0x71, 0x31, 0x4d,
+       0xfc, 0x96, 0x81, 0xff, 0x32, 0x70, 0x7c, 0xd9, 0x3d, 0xe3, 0xc0, 0xea,
+       0x16, 0xa3, 0xdf, 0x0a, 0x9a, 0x36, 0x8d, 0x9d, 0xff, 0xa7, 0x41, 0xb4,
+       0x86, 0x3d, 0x5e, 0x03, 0x73, 0x71, 0xd6, 0x5c, 0xa3, 0x3c, 0xd7, 0x08,
+       0x8a, 0xa1, 0x00, 0xba, 0x4f, 0xa7, 0xc6, 0xd4, 0x62, 0xb8, 0x79, 0x4f,
+       0x67, 0xf7, 0x63, 0xba, 0x9f, 0x74, 0x90, 0x55, 0x4f, 0x02, 0x9e, 0x9d,
+       0xd2, 0xb4, 0x87, 0x78, 0x26, 0xac, 0x71, 0xc6, 0xa7, 0xbc, 0x3b, 0x50,
+       0x77, 0x44, 0xe9, 0x3d, 0x6d, 0x5b, 0x87, 0x30, 0xbf, 0x1b, 0xf8, 0xa5,
+       0x1e, 0x62, 0xcc, 0xed, 0xb5, 0x74, 0x21, 0x64, 0xd2, 0x49, 0xca, 0xc0,
+       0x98, 0x89, 0x25, 0x57, 0xef, 0xe4, 0xfa, 0xd3, 0x13, 0x88, 0xbb, 0x90,
+       0x51, 0x13, 0xe0, 0xe2, 0xa3, 0x27, 0xc5, 0x6d, 0xf0, 0xbb, 0xd7, 0x1b,
+       0x3f, 0x8c, 0x3e, 0x19, 0xc7, 0x6e, 0x90, 0xe2, 0xaa, 0xf8, 0xcd, 0x24,
+       0xe0, 0x6f, 0x96, 0xf1, 0x93, 0x5c, 0x0b, 0x17, 0x32, 0x87, 0x63, 0x8b,
+       0x9b, 0xeb, 0x0d, 0xc3, 0x51, 0x96, 0x9f, 0x26, 0xff, 0x4a, 0x9a, 0xef,
+       0x0a, 0xa7, 0xe7, 0x37, 0xab, 0x65, 0xb2, 0xb6, 0xc5, 0xc2, 0xa1, 0xf1,
+       0x24, 0x93, 0x5a, 0x8e, 0x50, 0xdf, 0xcc, 0xd4, 0xc1, 0x13, 0x7c, 0x7c,
+       0xc2, 0x6f, 0x7c, 0x13, 0xf0, 0xfc, 0x0f, 0xc0, 0xd3, 0x62, 0xe1, 0x69,
+       0x5c, 0x01, 0x4f, 0x4b, 0x04, 0x0f, 0xe4, 0x1c, 0xe5, 0x6a, 0xfc, 0xda,
+       0x6c, 0x45, 0x9c, 0xa2, 0x2f, 0xed, 0x4a, 0xfb, 0x43, 0xd4, 0x37, 0x8d,
+       0xde, 0x68, 0x9f, 0x27, 0xa3, 0x5a, 0xd7, 0xb8, 0xd7, 0x76, 0x56, 0xe6,
+       0x61, 0xbd, 0x8a, 0x93, 0xf3, 0x09, 0xfb, 0x5a, 0x76, 0xd5, 0x3d, 0x90,
+       0xff, 0x0b, 0x69, 0xd7, 0xda, 0x12, 0x93, 0x01, 0xfd, 0xa0, 0x84, 0xce,
+       0x15, 0xa8, 0xc1, 0xf4, 0x12, 0x60, 0x82, 0x3c, 0x3e, 0xd9, 0xe3, 0x0d,
+       0xcb, 0x56, 0xed, 0xeb, 0x59, 0x5c, 0x63, 0x6e, 0xf1, 0xba, 0xb9, 0x41,
+       0xff, 0xa9, 0x68, 0x6e, 0x90, 0x89, 0xa8, 0x37, 0x29, 0x7f, 0x64, 0x71,
+       0xb1, 0x11, 0x73, 0x8a, 0xd7, 0xcd, 0xa7, 0x33, 0x79, 0x3b, 0xcb, 0xcc,
+       0x7c, 0xba, 0x8a, 0x7e, 0xdc, 0xe2, 0x77, 0x2d, 0x9f, 0xc4, 0xd8, 0x3d,
+       0xd3, 0x12, 0xca, 0x44, 0x80, 0x35, 0xea, 0xa6, 0x7f, 0x12, 0xb7, 0xb9,
+       0xd7, 0x0a, 0xcf, 0x1b, 0x2c, 0x7f, 0x79, 0x52, 0xd4, 0xfe, 0xe0, 0xdf,
+       0x59, 0x3e, 0x75, 0x6d, 0x9e, 0x1c, 0x7f, 0x1f, 0x5c, 0x6f, 0xf3, 0x05,
+       0x0a, 0x59, 0x79, 0x65, 0x3d, 0xed, 0x92, 0x06, 0xff, 0x57, 0x56, 0x94,
+       0xc5, 0x51, 0x76, 0x6a, 0xbd, 0x95, 0x0b, 0x28, 0xbb, 0x07, 0x7e, 0x1f,
+       0xf3, 0x3e, 0xf8, 0x8e, 0x32, 0xb8, 0x1e, 0x27, 0x3d, 0x60, 0x45, 0xf2,
+       0x3c, 0xe5, 0x22, 0x6d, 0x4a, 0xcc, 0x51, 0x6d, 0x8f, 0xe2, 0xf2, 0xf8,
+       0xbd, 0x96, 0xed, 0x4f, 0x7c, 0x13, 0xd7, 0xf2, 0x8d, 0x09, 0xf0, 0xfd,
+       0xe1, 0xc0, 0x71, 0x67, 0x98, 0x57, 0xa0, 0x69, 0xb8, 0xbe, 0xef, 0x1b,
+       0x18, 0x26, 0xb4, 0xb4, 0x4c, 0x7a, 0x21, 0x4f, 0x3b, 0xd2, 0x44, 0x5d,
+       0x7c, 0xd2, 0xd3, 0x39, 0xee, 0x39, 0xad, 0x97, 0xeb, 0xd7, 0xb1, 0x09,
+       0xba, 0x26, 0x61, 0x78, 0xd4, 0x33, 0xfb, 0xe7, 0xb5, 0xfe, 0x46, 0xd0,
+       0x1f, 0xed, 0x34, 0xf8, 0xfd, 0x3e, 0xa3, 0x43, 0x94, 0x5f, 0x8e, 0xab,
+       0xae, 0xd6, 0x7e, 0x6b, 0x5c, 0xe7, 0x37, 0x2d, 0xd5, 0x1d, 0xb3, 0x63,
+       0x93, 0x6e, 0xcd, 0x7e, 0x42, 0x6d, 0x7c, 0x71, 0xd4, 0x2e, 0x01, 0x95,
+       0x35, 0xca, 0x44, 0x1f, 0x69, 0x94, 0x73, 0xd7, 0x36, 0xd4, 0xb5, 0xb4,
+       0x23, 0x0c, 0x7d, 0xd2, 0x76, 0x72, 0xaf, 0xcd, 0x97, 0x1a, 0x8d, 0xcf,
+       0x92, 0x90, 0x2d, 0x0d, 0x3a, 0x2f, 0x01, 0x65, 0x95, 0x48, 0x97, 0xb9,
+       0x32, 0xd3, 0xfb, 0x7f, 0xc2, 0xec, 0x41, 0xd6, 0x5d, 0x33, 0x0f, 0x20,
+       0x39, 0x2d, 0x1a, 0x4f, 0x5f, 0xab, 0xe1, 0xc9, 0xce, 0x2d, 0xb1, 0x72,
+       0x6e, 0x70, 0x6a, 0xfd, 0x7b, 0x20, 0x3b, 0xb9, 0x4e, 0x26, 0xe7, 0xfc,
+       0x9c, 0x38, 0x6e, 0xae, 0x7b, 0xad, 0xb9, 0x4d, 0x46, 0x78, 0xe5, 0xdc,
+       0x40, 0xab, 0xd1, 0xbc, 0x48, 0xdb, 0x09, 0xbd, 0xef, 0xa4, 0x14, 0x61,
+       0xd9, 0xb8, 0x02, 0xb7, 0x11, 0xdd, 0x19, 0x9a, 0xfb, 0xa2, 0xa6, 0xb9,
+       0x16, 0x4b, 0x73, 0xa8, 0xeb, 0x71, 0x1f, 0xfd, 0xbe, 0x96, 0x1a, 0xcd,
+       0x6d, 0xb0, 0x34, 0xa7, 0x5a, 0xcc, 0x1e, 0x7b, 0xb9, 0xc5, 0xec, 0x71,
+       0x25, 0x57, 0x3c, 0xbf, 0x93, 0xcf, 0xf0, 0xc5, 0xa2, 0xe7, 0x7a, 0x58,
+       0xcf, 0x03, 0xd6, 0x7a, 0x59, 0xd3, 0x64, 0xe3, 0x78, 0xdc, 0x8f, 0xa7,
+       0xdf, 0xe7, 0xca, 0xa3, 0xb0, 0x83, 0x8a, 0x95, 0x1f, 0x84, 0xf3, 0xf0,
+       0xfd, 0x26, 0x96, 0x74, 0xef, 0x4c, 0x0b, 0xf9, 0x6d, 0x1a, 0xbf, 0x8e,
+       0xd4, 0xf9, 0x3c, 0x98, 0x2f, 0xca, 0xfe, 0x19, 0xeb, 0x01, 0xb9, 0xbc,
+       0x54, 0x97, 0x31, 0x10, 0xe3, 0xe3, 0x9c, 0xab, 0xb6, 0xdb, 0xfd, 0x49,
+       0xca, 0xf9, 0xbb, 0xe1, 0x13, 0xdd, 0x03, 0x3d, 0x49, 0xfa, 0xee, 0xd8,
+       0x60, 0xf2, 0x89, 0x13, 0xd0, 0x63, 0x3f, 0x6f, 0x73, 0xab, 0x6e, 0xbf,
+       0x7d, 0xed, 0x5c, 0x62, 0xd0, 0xbe, 0x43, 0x9a, 0x79, 0xdb, 0x06, 0x13,
+       0x83, 0xde, 0xba, 0x81, 0x7c, 0xa6, 0x76, 0xed, 0xda, 0xa8, 0xf9, 0xc2,
+       0x89, 0x9e, 0xab, 0x2b, 0x9e, 0xa3, 0x76, 0x7f, 0xb3, 0x71, 0x79, 0xbb,
+       0xa8, 0xfc, 0xce, 0x4d, 0xcb, 0xcb, 0xff, 0xa3, 0xb7, 0xbc, 0x7d, 0xe3,
+       0xe6, 0xe5, 0xcf, 0x7b, 0x57, 0x3c, 0x7f, 0x64, 0xc5, 0xf3, 0xef, 0xad,
+       0x78, 0xde, 0xd1, 0xba, 0xfc, 0xf9, 0x43, 0x2b, 0x9e, 0x4f, 0xb5, 0xae,
+       0x0d, 0xef, 0x42, 0xeb, 0x72, 0xb8, 0xee, 0xd6, 0xfb, 0x07, 0xd3, 0x55,
+       0x57, 0xf6, 0x96, 0xf0, 0xde, 0x79, 0xdf, 0x16, 0xa3, 0xd7, 0xea, 0xdf,
+       0x33, 0x5e, 0xb7, 0x7b, 0xcb, 0xf2, 0xfe, 0x6a, 0xed, 0xf6, 0xd5, 0xda,
+       0x05, 0xb5, 0x76, 0x46, 0xb6, 0xcd, 0x54, 0xf9, 0x8e, 0xe5, 0x51, 0xbf,
+       0xa6, 0xed, 0x44, 0xd9, 0xd7, 0x39, 0xb7, 0xc3, 0x3a, 0xe7, 0x36, 0x05,
+       0x3e, 0xbc, 0x5b, 0xc7, 0xa8, 0x36, 0xc3, 0x50, 0x1e, 0xaf, 0x6e, 0xd4,
+       0x71, 0x2a, 0xd1, 0x79, 0xb7, 0xc3, 0xb0, 0x6d, 0x99, 0x6b, 0x1b, 0xca,
+       0xfe, 0xc0, 0xdc, 0x4d, 0xee, 0xed, 0xb1, 0x70, 0xc0, 0x0b, 0xc3, 0x71,
+       0xff, 0x76, 0x9b, 0x7f, 0x86, 0x7b, 0xd5, 0xb4, 0xa1, 0x0e, 0x7e, 0x0c,
+       0x3a, 0xb8, 0xa6, 0x7b, 0xef, 0xc6, 0x58, 0xf3, 0xa0, 0x99, 0x3e, 0xf9,
+       0x9d, 0x6a, 0xfa, 0xf3, 0xa2, 0xcf, 0x16, 0xf5, 0xc2, 0x86, 0x9b, 0xbf,
+       0xf3, 0xbd, 0x7e, 0x00, 0x5b, 0x2f, 0x94, 0x87, 0x83, 0x7e, 0xd0, 0x50,
+       0x37, 0xec, 0x3d, 0x5f, 0xfb, 0xa5, 0x8f, 0x6b, 0xda, 0x22, 0x8d, 0x31,
+       0xdf, 0x86, 0x76, 0x81, 0x13, 0xcf, 0xf5, 0xfe, 0xb1, 0x89, 0xd3, 0x04,
+       0x9d, 0xde, 0x97, 0xc0, 0xb7, 0x43, 0xfe, 0x0e, 0xf8, 0x28, 0xa4, 0x21,
+       0xc6, 0xd3, 0xb6, 0xdb, 0x7c, 0xc7, 0x36, 0x99, 0x76, 0x19, 0x77, 0x4c,
+       0xf7, 0x8f, 0x08, 0xe7, 0x9d, 0x4e, 0xa6, 0x94, 0xb6, 0xab, 0xc2, 0x03,
+       0x01, 0x73, 0x79, 0xb9, 0x67, 0x43, 0x7e, 0x1e, 0xbe, 0x6b, 0xc2, 0x2f,
+       0x78, 0x31, 0x9b, 0xff, 0x9b, 0x2b, 0x19, 0xda, 0x1c, 0x23, 0x6d, 0xc2,
+       0x9f, 0x5a, 0xe8, 0xfd, 0xbb, 0x90, 0xf6, 0x7d, 0x4a, 0x91, 0xf6, 0xbf,
+       0x17, 0xce, 0xba, 0xec, 0x8b, 0x70, 0x0f, 0xdf, 0x95, 0xd3, 0xb8, 0xba,
+       0x5b, 0x0e, 0x97, 0x69, 0x0b, 0xc7, 0x75, 0x7e, 0xc8, 0x68, 0x40, 0x3b,
+       0x2d, 0x0e, 0x3c, 0x8e, 0x01, 0x7f, 0x2d, 0xb0, 0xb9, 0x6f, 0x44, 0x9d,
+       0x98, 0x8c, 0x0c, 0xb7, 0x80, 0xf7, 0xc8, 0x9f, 0xbc, 0xbb, 0xa8, 0xef,
+       0xc9, 0x5c, 0x69, 0x44, 0xe7, 0xef, 0x3d, 0x8e, 0xb6, 0x4f, 0xe0, 0x9a,
+       0x29, 0x7d, 0x18, 0x6d, 0xde, 0xaf, 0xeb, 0xcf, 0x4c, 0x32, 0x17, 0x5a,
+       0x20, 0x97, 0x3e, 0x21, 0xc5, 0xd9, 0x0e, 0x19, 0x49, 0xcc, 0x4f, 0xbb,
+       0x4b, 0x71, 0x99, 0x47, 0x37, 0x70, 0xcf, 0xa4, 0x78, 0x35, 0xf7, 0x97,
+       0xc5, 0x1d, 0xde, 0xad, 0xba, 0x5b, 0xb5, 0xcf, 0xd5, 0x2f, 0x43, 0xd5,
+       0x8c, 0xdc, 0x54, 0x7d, 0x62, 0x8b, 0x89, 0x45, 0x2d, 0x8b, 0x6f, 0x1d,
+       0xd3, 0x52, 0xe5, 0x84, 0xcb, 0xf3, 0x59, 0x32, 0x73, 0x56, 0x24, 0x76,
+       0x22, 0x8a, 0x4d, 0xb2, 0xcc, 0x93, 0x8e, 0xab, 0x01, 0xd7, 0x59, 0xc8,
+       0xd6, 0x44, 0x5c, 0x3e, 0xbb, 0x2b, 0x1a, 0xab, 0x10, 0x4e, 0xed, 0x2a,
+       0xc8, 0x9d, 0xb8, 0xf2, 0x57, 0xa7, 0x27, 0x73, 0x8a, 0xe3, 0xfe, 0x75,
+       0x48, 0x59, 0xa6, 0x32, 0xbe, 0x14, 0x5a, 0xa3, 0xb1, 0xe1, 0xdf, 0xec,
+       0x89, 0xc6, 0xa7, 0xcd, 0x6d, 0xce, 0x56, 0x14, 0xb9, 0x8f, 0x03, 0xfa,
+       0x8b, 0x65, 0x3e, 0xb7, 0x81, 0xbe, 0xc3, 0x80, 0xb0, 0x1d, 0x64, 0xba,
+       0x62, 0xdf, 0x84, 0x93, 0xf0, 0xd7, 0xc3, 0xb9, 0x90, 0x4a, 0x00, 0x47,
+       0x85, 0xd7, 0x85, 0xb7, 0xc7, 0xf3, 0xd5, 0x5a, 0xf0, 0xde, 0x6c, 0x63,
+       0x89, 0x8c, 0x0f, 0xae, 0x03, 0xde, 0x5a, 0x50, 0x9e, 0x97, 0x89, 0x93,
+       0xb7, 0x6e, 0xe1, 0xde, 0x78, 0x83, 0xef, 0xd8, 0x1c, 0x56, 0x9e, 0x39,
+       0x9a, 0x40, 0x1d, 0xbe, 0x1f, 0x41, 0x9b, 0x74, 0x21, 0x17, 0xdb, 0x02,
+       0x9f, 0x88, 0xe3, 0x86, 0xb1, 0x8e, 0x3d, 0xcd, 0x3a, 0x27, 0x55, 0xce,
+       0x52, 0x9f, 0x47, 0x6d, 0x27, 0x74, 0xce, 0x07, 0xfc, 0xf6, 0xc2, 0x60,
+       0x8c, 0xf2, 0xab, 0x5b, 0x06, 0xa8, 0x4f, 0xce, 0x8e, 0x68, 0xda, 0xef,
+       0xdc, 0xc5, 0xf3, 0x57, 0x3d, 0xc6, 0x46, 0x4f, 0x10, 0xc6, 0x9b, 0x51,
+       0x0e, 0xfb, 0xfd, 0x35, 0x61, 0x28, 0xbc, 0x49, 0x18, 0x0a, 0x6f, 0x12,
+       0x06, 0xe2, 0x02, 0x70, 0x54, 0xaf, 0xd8, 0x18, 0xc5, 0xbe, 0xb7, 0x62,
+       0x1e, 0x47, 0xca, 0x05, 0x39, 0x5a, 0x76, 0x74, 0xdc, 0x71, 0x5e, 0x51,
+       0x26, 0x78, 0xe0, 0x49, 0xf0, 0x5e, 0x19, 0xbc, 0x59, 0x06, 0x2f, 0x96,
+       0xc1, 0x97, 0xb0, 0xff, 0xcf, 0x43, 0x3e, 0x3c, 0x81, 0xb5, 0x79, 0x7c,
+       0x19, 0x2f, 0x67, 0x35, 0x2f, 0x17, 0xcb, 0xf4, 0xd5, 0x7a, 0x2f, 0xc3,
+       0xaf, 0xae, 0x0c, 0x94, 0xd2, 0x50, 0x25, 0x8e, 0x9b, 0xef, 0xfd, 0x28,
+       0xf9, 0x55, 0x1e, 0x0c, 0x0e, 0xa2, 0xcd, 0x24, 0x68, 0x3c, 0x4d, 0x3b,
+       0x90, 0xf6, 0x4f, 0x01, 0xbc, 0x79, 0x8c, 0xbe, 0x9a, 0xba, 0x7a, 0xb3,
+       0x50, 0xbf, 0xb8, 0x7b, 0x98, 0xcb, 0xc8, 0xb9, 0xa6, 0x56, 0xe0, 0xc9,
+       0xf0, 0xef, 0x98, 0x4f, 0x3d, 0x43, 0xbe, 0x7d, 0x96, 0x7c, 0x5b, 0xc7,
+       0xab, 0x3f, 0xc5, 0xf9, 0x85, 0xde, 0xae, 0xb5, 0xda, 0xd6, 0xea, 0x6f,
+       0x5e, 0xaa, 0xaf, 0xc7, 0x9f, 0x24, 0x3f, 0xaa, 0xcc, 0x24, 0x71, 0x9f,
+       0xca, 0xc5, 0x76, 0x58, 0xdc, 0xc3, 0x76, 0xdb, 0x73, 0x05, 0x70, 0xdf,
+       0x2e, 0x85, 0xb9, 0x50, 0xfc, 0x3d, 0x51, 0x9f, 0xb5, 0x7e, 0x3c, 0xdb,
+       0xcf, 0x68, 0xc9, 0x91, 0xc1, 0x5d, 0xdc, 0xd7, 0x70, 0xa0, 0xe7, 0xa3,
+       0xf5, 0x80, 0xbd, 0xaf, 0xd7, 0x9c, 0x32, 0x96, 0xb2, 0xb5, 0xc5, 0xc6,
+       0x9f, 0xd8, 0xdf, 0xe4, 0x8a, 0x75, 0x7a, 0x31, 0xe4, 0xb9, 0xb6, 0x09,
+       0xff, 0x60, 0x1d, 0xad, 0x3c, 0x60, 0x69, 0x45, 0xad, 0x98, 0xc7, 0x5d,
+       0x96, 0x56, 0x22, 0x78, 0x13, 0x11, 0xad, 0x34, 0x45, 0xb4, 0x52, 0x98,
+       0x8e, 0x68, 0x85, 0x6d, 0xef, 0x8a, 0x68, 0x25, 0x55, 0x4f, 0x2b, 0x85,
+       0x69, 0x07, 0xd7, 0x4a, 0x38, 0x48, 0x2f, 0xec, 0x87, 0xf4, 0x02, 0x58,
+       0xaa, 0x9f, 0x59, 0xa2, 0x97, 0x04, 0xfa, 0x39, 0x5a, 0x36, 0x39, 0x22,
+       0xf0, 0xbb, 0xac, 0x0e, 0xf1, 0xb0, 0xe6, 0xc6, 0x47, 0x5c, 0x9b, 0x46,
+       0x02, 0x4b, 0x23, 0xb5, 0x7c, 0xfa, 0x15, 0xb4, 0x01, 0xdc, 0x33, 0x37,
+       0x76, 0xb7, 0xa6, 0x8d, 0xfb, 0x83, 0x12, 0xea, 0x0e, 0x83, 0x36, 0x22,
+       0x1c, 0xbc, 0xc7, 0xe2, 0x60, 0xe5, 0x5a, 0xde, 0x66, 0x71, 0x30, 0x6c,
+       0x71, 0xa0, 0xf9, 0xa5, 0xc0, 0x35, 0x53, 0x1a, 0x07, 0x4d, 0x1a, 0x07,
+       0xa2, 0xa2, 0xb6, 0xb7, 0xad, 0x81, 0x03, 0xd6, 0x19, 0xd6, 0xf3, 0x8f,
+       0x61, 0xfe, 0xb7, 0x63, 0xfe, 0x4a, 0xcf, 0x9f, 0xeb, 0x60, 0x72, 0xb9,
+       0x8b, 0xd5, 0xbf, 0x5e, 0x9a, 0x7f, 0x2b, 0xfa, 0x38, 0x52, 0x8e, 0xe9,
+       0xf9, 0xc3, 0xb6, 0xef, 0x8f, 0xe6, 0xff, 0x78, 0xd5, 0xe4, 0x53, 0x3f,
+       0xbe, 0x4a, 0xcf, 0x95, 0x2c, 0x6f, 0xf8, 0xda, 0x2f, 0x66, 0x4c, 0xfb,
+       0x3c, 0x74, 0xdb, 0x54, 0x90, 0xb2, 0xe7, 0xae, 0x8c, 0xbd, 0xf4, 0x95,
+       0x80, 0xbc, 0xf3, 0x21, 0x9d, 0xd7, 0x72, 0x8e, 0x76, 0x53, 0xb9, 0x55,
+       0x06, 0xa7, 0xea, 0xe1, 0x26, 0xbc, 0x05, 0x2d, 0x47, 0xf3, 0x98, 0xdf,
+       0x68, 0xd0, 0x0d, 0xf9, 0xa6, 0x69, 0x09, 0xe5, 0xe9, 0xc2, 0x40, 0xac,
+       0x49, 0xd4, 0x03, 0xef, 0xc7, 0x9c, 0x5d, 0xd9, 0xe2, 0x77, 0x7a, 0x7b,
+       0x14, 0x75, 0xe1, 0x95, 0x75, 0xba, 0xb0, 0xcd, 0xea, 0xc2, 0xcd, 0xd4,
+       0x85, 0x80, 0xfb, 0x6e, 0x39, 0x56, 0xe6, 0xfa, 0x15, 0x52, 0x4d, 0xd0,
+       0xff, 0xdf, 0xf1, 0x79, 0xc6, 0x45, 0xc7, 0xcd, 0x92, 0xc7, 0x34, 0x2d,
+       0x53, 0xa7, 0xa5, 0xf5, 0x99, 0x90, 0x05, 0xda, 0xd8, 0x09, 0xc6, 0x42,
+       0xa9, 0xf7, 0xfe, 0x3e, 0xfc, 0xcc, 0x1a, 0x7a, 0x6f, 0xbc, 0x6c, 0xec,
+       0xb7, 0x06, 0xd8, 0x84, 0x72, 0xaa, 0x0d, 0xd7, 0x26, 0x9e, 0x89, 0xe8,
+       0xee, 0x52, 0xcd, 0xd2, 0x70, 0x6a, 0xa3, 0x8c, 0x4d, 0x19, 0x1b, 0x57,
+       0x9d, 0x02, 0xfe, 0x4f, 0x31, 0x7f, 0x56, 0x74, 0xbe, 0x7f, 0x7e, 0x12,
+       0x76, 0xee, 0xcc, 0xdd, 0xe6, 0x1c, 0xc8, 0x54, 0x83, 0xfe, 0x4d, 0x1b,
+       0xa4, 0x18, 0x64, 0xa1, 0xef, 0xe2, 0x32, 0x86, 0x3e, 0x3b, 0x77, 0x35,
+       0x62, 0xce, 0x09, 0xb4, 0xa5, 0xcf, 0xc7, 0x38, 0x5a, 0xa3, 0xb8, 0x33,
+       0x49, 0x9d, 0xab, 0xcf, 0xf3, 0xae, 0xb9, 0xfe, 0x56, 0xbc, 0x63, 0x7e,
+       0x84, 0x87, 0xb1, 0x22, 0xd9, 0x8f, 0x7e, 0x4f, 0x88, 0xdd, 0xef, 0xc9,
+       0x68, 0xfd, 0x17, 0x3b, 0xe1, 0xd9, 0xb3, 0x7a, 0xfd, 0x58, 0xf7, 0xb5,
+       0xf4, 0xa2, 0x31, 0x72, 0x73, 0x58, 0x3f, 0x75, 0xd6, 0xc5, 0xbd, 0x1d,
+       0xf7, 0xa8, 0xbf, 0x48, 0x8f, 0x40, 0x37, 0xbe, 0xfd, 0xd0, 0x26, 0x69,
+       0x06, 0xbe, 0x67, 0x14, 0x70, 0x6d, 0x72, 0xbc, 0x0a, 0x9a, 0x17, 0x6a,
+       0xf4, 0xf0, 0xc4, 0xeb, 0xf2, 0x03, 0x69, 0x82, 0xb4, 0x40, 0xb9, 0x48,
+       0xda, 0xa0, 0x4c, 0x24, 0x6d, 0x1b, 0x7a, 0x78, 0x2c, 0xf0, 0x63, 0xcc,
+       0x03, 0x30, 0x71, 0x79, 0xd2, 0x06, 0x69, 0x3e, 0xa5, 0xe3, 0xf5, 0x59,
+       0xf9, 0x96, 0x64, 0x5b, 0x3b, 0x61, 0x97, 0xfd, 0xdb, 0xae, 0xb1, 0x39,
+       0x2b, 0xac, 0x69, 0x0e, 0xba, 0x89, 0x39, 0x79, 0xdd, 0xf2, 0x9e, 0x6a,
+       0x01, 0x78, 0xb8, 0x17, 0x4a, 0xf9, 0x6e, 0x9d, 0xe7, 0xb8, 0xaf, 0xb4,
+       0x49, 0x6e, 0x09, 0xe2, 0x36, 0xee, 0x7e, 0x04, 0x74, 0xb0, 0xe0, 0xc8,
+       0xa9, 0x0b, 0xb8, 0x2e, 0x3a, 0x5c, 0xbf, 0x4b, 0x41, 0x36, 0xad, 0xc8,
+       0xec, 0xbe, 0x9b, 0x5c, 0x90, 0x1e, 0x6f, 0x4c, 0x18, 0xeb, 0x98, 0x77,
+       0x9a, 0x4e, 0xfd, 0xfe, 0x26, 0xe3, 0x4b, 0x03, 0x16, 0xbf, 0xd1, 0x1b,
+       0xa4, 0x2d, 0x17, 0x84, 0x61, 0x9e, 0x76, 0x83, 0x28, 0xed, 0x23, 0xc1,
+       0xe7, 0x43, 0x19, 0xe3, 0x13, 0x3b, 0x9d, 0xc6, 0xb3, 0x2f, 0x58, 0x5a,
+       0x91, 0x98, 0xca, 0x3c, 0xed, 0x34, 0x9c, 0x7a, 0x84, 0x6b, 0xa6, 0xf3,
+       0xae, 0x0d, 0x5d, 0x3d, 0xeb, 0xd4, 0xe8, 0xea, 0x2b, 0xf6, 0xb7, 0xca,
+       0x34, 0x49, 0x36, 0xdd, 0x84, 0xf9, 0x0e, 0x94, 0x22, 0x18, 0xbf, 0x0d,
+       0xb8, 0x08, 0x0f, 0xe8, 0x76, 0xe6, 0x7f, 0xe2, 0x5a, 0x04, 0x2c, 0xf7,
+       0x01, 0xee, 0x4b, 0x80, 0xf9, 0x45, 0x5c, 0x6a, 0x5b, 0x4c, 0xfe, 0xd4,
+       0x89, 0xcd, 0xd4, 0xc3, 0x4b, 0x18, 0xbf, 0x6b, 0xe1, 0x7d, 0x2d, 0x58,
+       0x3d, 0x59, 0xe8, 0xeb, 0x00, 0x3c, 0x84, 0xf3, 0x25, 0xc0, 0x48, 0xbb,
+       0xf5, 0x39, 0x3c, 0x7b, 0x80, 0xef, 0x79, 0x0b, 0x13, 0xe8, 0x71, 0xea,
+       0x2f, 0x6a, 0xbf, 0x4b, 0xb4, 0xa3, 0xff, 0xd2, 0x3e, 0xb7, 0xaf, 0x90,
+       0x01, 0x5d, 0x0e, 0xf1, 0x3c, 0x51, 0x5e, 0xa4, 0x1d, 0x00, 0xbe, 0xff,
+       0xae, 0xc4, 0xce, 0x26, 0xe5, 0x68, 0x89, 0x7b, 0x40, 0xa7, 0x81, 0x0f,
+       0x7d, 0xc6, 0x05, 0x75, 0xae, 0xc2, 0x05, 0x65, 0x3f, 0xb3, 0x1b, 0x57,
+       0x37, 0xae, 0xb7, 0xe2, 0x02, 0x39, 0xcc, 0x9c, 0xc2, 0xd5, 0x83, 0xbe,
+       0x55, 0xa2, 0x49, 0x98, 0x9b, 0xf5, 0x0d, 0xb4, 0xd1, 0xb6, 0x65, 0x41,
+       0x65, 0xfa, 0x80, 0xbf, 0x3e, 0xc0, 0x96, 0xc4, 0xc5, 0x7c, 0xe6, 0xef,
+       0x3a, 0x72, 0xf6, 0x65, 0x5c, 0x60, 0xb0, 0xb3, 0x20, 0xcc, 0xb3, 0xfd,
+       0xb8, 0xa0, 0xc4, 0xce, 0x66, 0x71, 0x0d, 0xe2, 0xfa, 0x2b, 0xc7, 0xf0,
+       0x5c, 0x3b, 0xf0, 0x15, 0xf1, 0x08, 0x70, 0xbe, 0x8c, 0xe7, 0xbe, 0xec,
+       0xbc, 0x71, 0x9e, 0xfb, 0xbe, 0x63, 0x78, 0xee, 0x15, 0xa7, 0xc6, 0x73,
+       0x17, 0x1c, 0xf5, 0xf0, 0xd3, 0x4e, 0xec, 0x61, 0xfa, 0x12, 0x17, 0x1c,
+       0xc3, 0xff, 0x31, 0x19, 0x38, 0x08, 0x5a, 0x7a, 0x78, 0x1e, 0x17, 0xe9,
+       0xea, 0x19, 0x94, 0x3f, 0xbf, 0x62, 0xdc, 0xe7, 0xde, 0xc4, 0xb8, 0xaf,
+       0xda, 0x71, 0x45, 0xd5, 0xc6, 0x7d, 0x11, 0x7d, 0xbf, 0x64, 0xc7, 0x7d,
+       0xb1, 0x6e, 0x5c, 0xd0, 0xca, 0xc3, 0x8b, 0xb8, 0x48, 0x17, 0x2f, 0xa0,
+       0x3c, 0x92, 0x09, 0x1f, 0xf4, 0xa4, 0xb9, 0x01, 0xbc, 0x1b, 0x87, 0x7e,
+       0x6c, 0x58, 0xd2, 0x8d, 0xd9, 0x3a, 0xfd, 0xf0, 0x46, 0xf4, 0xe3, 0x78,
+       0x99, 0x36, 0xe2, 0x7c, 0x9d, 0x5c, 0xa0, 0x6f, 0x14, 0xca, 0x49, 0xed,
+       0x07, 0xd1, 0x27, 0xa2, 0x7f, 0xb4, 0xd2, 0xb6, 0xfa, 0xa8, 0xce, 0x45,
+       0xfb, 0x95, 0x52, 0xbb, 0xdc, 0x59, 0xa2, 0x4d, 0x48, 0x7a, 0x09, 0xc3,
+       0xb1, 0x3d, 0xb4, 0x4f, 0x0b, 0xe1, 0x15, 0x3e, 0xe9, 0xc4, 0xf7, 0x7e,
+       0x79, 0xb5, 0xce, 0x98, 0x1c, 0x80, 0xef, 0x9e, 0x3b, 0xf1, 0x8b, 0xd0,
+       0x19, 0x0d, 0x80, 0x9b, 0xf4, 0xb6, 0x4d, 0x0e, 0x4c, 0xaa, 0x89, 0x2d,
+       0x90, 0x25, 0x37, 0x95, 0x1a, 0x61, 0xf7, 0x30, 0x4f, 0xab, 0x59, 0x3a,
+       0xf7, 0xc4, 0x4d, 0x1e, 0xb9, 0x97, 0xc0, 0x6f, 0xcf, 0xe4, 0xb5, 0x27,
+       0x92, 0x78, 0xff, 0x0f, 0x1e, 0xe5, 0x60, 0xc2, 0xbf, 0x4e, 0xe7, 0x08,
+       0x75, 0xec, 0xa1, 0xdd, 0x72, 0x83, 0xd6, 0xe1, 0xee, 0x2a, 0x3b, 0x49,
+       0x6d, 0xf3, 0xa4, 0x66, 0xa3, 0x8d, 0x96, 0xd2, 0x29, 0xc2, 0xf5, 0x90,
+       0x70, 0xff, 0xeb, 0x1e, 0x29, 0x06, 0x1b, 0xe1, 0x17, 0x30, 0x76, 0x9e,
+       0xee, 0xa6, 0x6d, 0x34, 0x33, 0xe5, 0xd9, 0x3c, 0xeb, 0x4d, 0xf2, 0xac,
+       0x1e, 0xa7, 0x51, 0xc3, 0x68, 0xce, 0x5e, 0x70, 0x1f, 0x21, 0xae, 0xcf,
+       0xfb, 0xcc, 0x54, 0x5a, 0xb4, 0xde, 0x99, 0xa9, 0x30, 0xaf, 0x1f, 0xfe,
+       0x54, 0x85, 0x79, 0xfc, 0x81, 0x78, 0x6f, 0x87, 0x9f, 0x5b, 0xd9, 0x21,
+       0xa3, 0x53, 0xeb, 0xa4, 0xd1, 0x57, 0x89, 0x2d, 0xd0, 0x1f, 0x6c, 0xd3,
+       0xb1, 0x07, 0xfe, 0xe1, 0xf4, 0x4e, 0x79, 0x62, 0x9a, 0x7d, 0x6f, 0x93,
+       0xd9, 0x39, 0x71, 0xbc, 0xb7, 0xaf, 0x47, 0x1d, 0xc8, 0xf5, 0x3d, 0x2c,
+       0x4b, 0xe1, 0x2e, 0xca, 0x7b, 0xbb, 0x2b, 0x17, 0xfb, 0xf8, 0xcc, 0xb3,
+       0x04, 0xe2, 0xb2, 0xbf, 0x8b, 0x7d, 0xed, 0x72, 0x6e, 0x0e, 0x34, 0x01,
+       0xb9, 0x3f, 0x78, 0x8a, 0x30, 0x89, 0xec, 0x9d, 0x61, 0x2c, 0xbd, 0xd3,
+       0x63, 0xdc, 0x94, 0xfb, 0x34, 0xb7, 0xf4, 0x71, 0x2c, 0xe8, 0x25, 0xe8,
+       0xb8, 0x8e, 0x3d, 0x46, 0x16, 0x64, 0x67, 0x1a, 0x50, 0xce, 0x7e, 0xe1,
+       0x3f, 0x1e, 0x64, 0x3f, 0x51, 0x5b, 0x85, 0x39, 0x35, 0x6a, 0x7a, 0x59,
+       0x5c, 0xa1, 0x3f, 0xce, 0xff, 0x48, 0xf6, 0x37, 0xfb, 0xe8, 0xd6, 0x7b,
+       0x21, 0xdc, 0x53, 0x36, 0xb6, 0x15, 0xd7, 0x44, 0xef, 0x29, 0xc0, 0xae,
+       0xba, 0x4a, 0xdb, 0x17, 0xb3, 0x55, 0xae, 0x20, 0x63, 0x51, 0xd1, 0x1a,
+       0x25, 0xe5, 0xd1, 0xf2, 0xd2, 0x3a, 0xed, 0x68, 0x58, 0xbe, 0x4e, 0xa4,
+       0x95, 0x60, 0xc4, 0xda, 0x1e, 0x0b, 0x72, 0x0c, 0x76, 0x59, 0xb7, 0x5e,
+       0xb3, 0x05, 0xd8, 0xb2, 0x76, 0xcd, 0xb4, 0x3d, 0x5b, 0x8c, 0xd6, 0x6c,
+       0x18, 0x1a, 0xa7, 0x92, 0xd9, 0xcc, 0x35, 0xf3, 0x18, 0xef, 0x06, 0xde,
+       0x0b, 0x58, 0xa7, 0x02, 0xd6, 0xa8, 0x50, 0xd9, 0x26, 0x33, 0x27, 0x55,
+       0x7b, 0x83, 0x48, 0x6a, 0xd4, 0xdf, 0x26, 0xe3, 0x73, 0x8c, 0x25, 0xec,
+       0x80, 0x0d, 0xb6, 0x13, 0x57, 0x3b, 0x9e, 0xd9, 0x2e, 0x21, 0xc5, 0x8a,
+       0x42, 0xdb, 0xa6, 0x55, 0x76, 0xd6, 0x39, 0x8c, 0xcd, 0x33, 0x9d, 0x8f,
+       0x01, 0x0f, 0x35, 0xde, 0x29, 0xd5, 0xc5, 0x9f, 0x38, 0x57, 0xad, 0x43,
+       0x31, 0xdf, 0x84, 0x5e, 0x4f, 0x1d, 0x87, 0x2a, 0x37, 0xbe, 0x19, 0x7b,
+       0x2a, 0x49, 0x7b, 0x2a, 0x3f, 0xe9, 0x99, 0xf3, 0x06, 0xc3, 0xf0, 0x9d,
+       0xfc, 0xfc, 0x66, 0xd2, 0xfa, 0xc8, 0x34, 0xe1, 0x8a, 0x47, 0x70, 0x2d,
+       0x5b, 0x33, 0x9e, 0x0f, 0x5b, 0x1d, 0xe7, 0x28, 0x2d, 0xe5, 0x43, 0x9a,
+       0xd8, 0x3e, 0xe3, 0x28, 0xed, 0x6b, 0xc0, 0x74, 0xb7, 0xb6, 0x61, 0x45,
+       0xdd, 0x26, 0x87, 0xcb, 0x3c, 0x5b, 0xc6, 0x78, 0xe2, 0x27, 0x19, 0x5f,
+       0xea, 0x9e, 0x91, 0x63, 0x18, 0x9b, 0xb9, 0x3f, 0xca, 0xc6, 0x6f, 0x36,
+       0xd8, 0x1c, 0x91, 0xfa, 0x18, 0x8e, 0xc9, 0x0d, 0x5a, 0x9e, 0x67, 0x9d,
+       0x1e, 0x5e, 0xc4, 0x3a, 0xff, 0x9a, 0xde, 0x1b, 0x94, 0xc9, 0x18, 0xb4,
+       0xdf, 0x68, 0x5f, 0xba, 0xdf, 0x9c, 0xab, 0x49, 0xc9, 0x50, 0xd9, 0xcc,
+       0xff, 0x92, 0xce, 0x11, 0x32, 0xb9, 0x90, 0x26, 0x7f, 0xe8, 0x1e, 0xb9,
+       0x04, 0x1d, 0x5e, 0x5b, 0xdb, 0x26, 0x19, 0x07, 0x2e, 0xf2, 0x7a, 0x5f,
+       0x22, 0x25, 0xf9, 0xbe, 0x47, 0x37, 0xf3, 0xdc, 0x45, 0x1c, 0xeb, 0x53,
+       0x9c, 0xe6, 0x59, 0x4c, 0xf6, 0x7b, 0xb9, 0xbe, 0x28, 0x66, 0x99, 0xd7,
+       0x0f, 0x59, 0xf9, 0x63, 0x3d, 0xc9, 0x66, 0xfd, 0x7e, 0x9d, 0xcd, 0xdf,
+       0x76, 0x44, 0x0e, 0x84, 0xf2, 0x87, 0xd0, 0x93, 0x67, 0xec, 0x9c, 0x52,
+       0x3a, 0x66, 0x25, 0xe1, 0xc5, 0x20, 0x69, 0x63, 0x96, 0x9c, 0xcb, 0x41,
+       0x4b, 0xdf, 0xc6, 0xfe, 0xa9, 0xd9, 0xd0, 0x66, 0xdf, 0xef, 0x09, 0x2d,
+       0x0b, 0x7b, 0xad, 0xed, 0xac, 0xe3, 0x3c, 0x8f, 0x88, 0xce, 0x09, 0x88,
+       0x7c, 0xa3, 0xae, 0x3a, 0xbf, 0xc0, 0xf8, 0x72, 0xc5, 0xa9, 0xb5, 0x64,
+       0x54, 0xcd, 0x27, 0xa4, 0x2f, 0x37, 0xb6, 0x8b, 0xdf, 0x47, 0x88, 0x7c,
+       0xb9, 0x5e, 0xeb, 0xcb, 0x6d, 0xd4, 0xbe, 0x9c, 0x89, 0x3d, 0x6c, 0x5c,
+       0xf2, 0xe5, 0x8a, 0x53, 0x05, 0xd0, 0x4a, 0xf4, 0x3d, 0x07, 0x63, 0x0b,
+       0x8d, 0x97, 0x78, 0x86, 0xa6, 0x51, 0xf2, 0xc3, 0x0a, 0x7e, 0x83, 0xf1,
+       0xb1, 0x18, 0xab, 0x50, 0xea, 0xeb, 0xd6, 0xbf, 0x68, 0x97, 0x6c, 0xdb,
+       0x3a, 0xcc, 0xfb, 0x6e, 0xbd, 0xe6, 0xb3, 0x25, 0xb3, 0xf7, 0x99, 0x3f,
+       0xc8, 0x98, 0x10, 0xcf, 0x49, 0x69, 0xfe, 0x4a, 0x0d, 0xc4, 0xba, 0x8d,
+       0x3d, 0xeb, 0x7b, 0xad, 0xd2, 0x7c, 0x1a, 0x38, 0x8f, 0xdb, 0x71, 0x53,
+       0x80, 0xe9, 0x30, 0xd6, 0xe6, 0x3a, 0x2b, 0x93, 0x39, 0xf6, 0x47, 0x9b,
+       0x18, 0x1b, 0x98, 0x2b, 0x45, 0x31, 0xc2, 0x98, 0x3d, 0xa3, 0xe9, 0xc7,
+       0x1a, 0xfd, 0x75, 0x6b, 0xda, 0xaa, 0x8f, 0xbf, 0xae, 0x6e, 0x22, 0x2d,
+       0xdd, 0xad, 0xf3, 0x5c, 0xd6, 0xf7, 0xa5, 0xf7, 0xeb, 0x9c, 0x7b, 0x1d,
+       0x63, 0x2c, 0x08, 0x73, 0xd4, 0xbe, 0x29, 0x3f, 0xa1, 0x65, 0xfe, 0xe1,
+       0x80, 0xfa, 0x6b, 0x8f, 0xfe, 0xdd, 0x98, 0x09, 0xc3, 0x8b, 0x7d, 0x13,
+       0x8c, 0x29, 0x7a, 0xdf, 0x96, 0xce, 0xe4, 0x80, 0xb6, 0x9d, 0xb0, 0x46,
+       0x07, 0x9b, 0x65, 0x9d, 0x3f, 0x62, 0x73, 0x66, 0x0a, 0x90, 0x9b, 0x69,
+       0xd8, 0x4c, 0x3c, 0x7f, 0xdc, 0x65, 0xdf, 0x15, 0xc2, 0x66, 0xd0, 0xd1,
+       0x07, 0xc5, 0xc8, 0x98, 0x7c, 0x4d, 0xc6, 0x30, 0xd7, 0x20, 0x4b, 0x42,
+       0x76, 0x8f, 0x4b, 0x9a, 0xdf, 0x2a, 0xe1, 0xd8, 0x45, 0xd9, 0x0a, 0xbd,
+       0xcc, 0x76, 0xb4, 0x55, 0xf9, 0xcc, 0x3d, 0x1c, 0xdf, 0x3b, 0x02, 0xdd,
+       0x72, 0xc3, 0x6a, 0xdd, 0x92, 0xa4, 0x5f, 0x9f, 0x9f, 0xa4, 0x6f, 0xb8,
+       0x1e, 0x6d, 0xb6, 0xc9, 0x87, 0xa6, 0x7e, 0xbe, 0x95, 0xbc, 0x35, 0x02,
+       0xb9, 0xae, 0xee, 0x8f, 0xce, 0x16, 0xb1, 0x8c, 0xef, 0xd9, 0x6f, 0x93,
+       0xa4, 0xde, 0xeb, 0xc9, 0x6f, 0x54, 0xd3, 0xa9, 0x45, 0xe8, 0xa6, 0x11,
+       0xe7, 0x57, 0xb7, 0x9b, 0x98, 0xea, 0x07, 0x5a, 0xcd, 0x59, 0x84, 0x66,
+       0xe0, 0x34, 0x8a, 0xb3, 0xd6, 0xd3, 0xec, 0xa2, 0x95, 0xc7, 0x61, 0xd8,
+       0xdc, 0xa7, 0x65, 0xf0, 0x7e, 0xca, 0xe0, 0xc3, 0x41, 0x97, 0xa1, 0x7d,
+       0xed, 0x33, 0x85, 0x58, 0x47, 0xe0, 0xa1, 0xcf, 0x65, 0xbe, 0x9f, 0xe5,
+       0x4f, 0x3f, 0xbb, 0x60, 0xe5, 0x92, 0x72, 0x56, 0xf3, 0xa5, 0xba, 0x26,
+       0xbe, 0x4c, 0xe6, 0x1e, 0x9d, 0xa2, 0x3e, 0x0e, 0xe6, 0xbf, 0x09, 0x39,
+       0x95, 0xd7, 0x78, 0xd8, 0x26, 0xf7, 0x4d, 0x49, 0xf6, 0x12, 0x74, 0x55,
+       0x71, 0x6e, 0x39, 0x6f, 0xae, 0xee, 0x8f, 0x73, 0x7d, 0xa4, 0xd5, 0xf8,
+       0xb6, 0xcb, 0xe7, 0x3a, 0x8f, 0xb9, 0x66, 0xf5, 0x5c, 0xb9, 0x6f, 0x33,
+       0x67, 0xe7, 0xba, 0x3e, 0x9a, 0x6b, 0xff, 0xf2, 0xb9, 0x46, 0xbe, 0x7d,
+       0x24, 0x77, 0x53, 0x3a, 0xff, 0x5e, 0xe7, 0x7d, 0x4f, 0xad, 0x97, 0x81,
+       0xc9, 0x8d, 0x56, 0x5e, 0x7a, 0xd0, 0x3d, 0xcc, 0x89, 0x9f, 0xbf, 0xd7,
+       0x13, 0x8b, 0x33, 0x45, 0x3c, 0x50, 0xd6, 0xb6, 0xea, 0x33, 0x3b, 0x33,
+       0xf0, 0xaf, 0x6e, 0x2d, 0xb1, 0x6e, 0xf4, 0xfe, 0x72, 0xb1, 0xe3, 0xc8,
+       0xa7, 0xa6, 0xdf, 0xd4, 0xbd, 0x2a, 0xa6, 0x60, 0xe2, 0xc3, 0x8c, 0x0b,
+       0x9b, 0xb3, 0xc4, 0xcc, 0x45, 0xbc, 0x03, 0x3c, 0xf5, 0xf1, 0x52, 0xba,
+       0x3f, 0x17, 0xa3, 0x1c, 0x9d, 0x96, 0xa3, 0xd5, 0x41, 0xe9, 0xd0, 0xe7,
+       0x49, 0x5f, 0x37, 0x76, 0x9c, 0xad, 0x8f, 0x1d, 0x33, 0x9d, 0x80, 0xb1,
+       0xe3, 0xfd, 0x3f, 0x42, 0xec, 0x58, 0x1c, 0x13, 0x3b, 0x5e, 0xcb, 0xbf,
+       0x9a, 0x28, 0x4f, 0x63, 0x5e, 0xcd, 0x90, 0x25, 0x0b, 0x4e, 0x7e, 0xae,
+       0x05, 0xf7, 0x0b, 0xb8, 0xc7, 0x71, 0xbf, 0x84, 0xbb, 0x87, 0xfb, 0x8b,
+       0xb8, 0x27, 0x64, 0x62, 0x49, 0x67, 0x4c, 0x43, 0x6e, 0x50, 0x97, 0xb1,
+       0xad, 0xf1, 0x07, 0x66, 0x2b, 0x6d, 0xfc, 0x2e, 0x8c, 0x33, 0x33, 0xc7,
+       0x39, 0x6c, 0x94, 0xf1, 0x29, 0xca, 0xec, 0x56, 0x99, 0x9c, 0x8a, 0x6c,
+       0xdb, 0xbb, 0xb6, 0x71, 0xcf, 0x60, 0x44, 0x22, 0xdb, 0xf5, 0x77, 0xb7,
+       0xd9, 0x5c, 0xfb, 0x2d, 0xd2, 0xbc, 0x09, 0x6b, 0x70, 0x5a, 0x2e, 0x4d,
+       0x6f, 0x5a, 0x66, 0xc3, 0xa6, 0x6c, 0x4c, 0x70, 0xda, 0xea, 0xde, 0xb5,
+       0x65, 0x44, 0xfd, 0xfa, 0x27, 0x6d, 0x4e, 0x69, 0x94, 0x23, 0x94, 0xd2,
+       0xeb, 0x33, 0x5c, 0x9d, 0xc6, 0x78, 0xfd, 0x92, 0x9d, 0xe6, 0x3c, 0x97,
+       0xbe, 0x4d, 0x01, 0x79, 0x78, 0x0a, 0x7a, 0x75, 0x19, 0x5d, 0x82, 0x6e,
+       0x39, 0x37, 0x07, 0xb4, 0xfb, 0xa8, 0xcc, 0x4c, 0x12, 0xbe, 0xae, 0x64,
+       0x4c, 0x9f, 0x5d, 0xc3, 0xf3, 0xb4, 0xc9, 0x99, 0x1f, 0xa8, 0x46, 0xe7,
+       0xd6, 0x36, 0xeb, 0xef, 0x11, 0x2c, 0x3f, 0xbb, 0x66, 0xf5, 0xb3, 0xb6,
+       0x1d, 0x78, 0x86, 0x2d, 0x9a, 0xc3, 0x5a, 0xf4, 0x14, 0xca, 0xb8, 0xce,
+       0x3b, 0xdb, 0x22, 0x67, 0x1e, 0x5c, 0xca, 0xa1, 0x6d, 0x85, 0x8d, 0xd2,
+       0x0e, 0x13, 0x79, 0xd8, 0xcd, 0x74, 0xc1, 0xc7, 0x63, 0x9e, 0x4c, 0x57,
+       0xf2, 0x36, 0x9d, 0xdb, 0x5c, 0x3b, 0x47, 0x58, 0xcb, 0x6f, 0x8e, 0xce,
+       0x6d, 0x25, 0x65, 0x10, 0x74, 0x38, 0xa4, 0xcb, 0x13, 0x98, 0x0f, 0xf7,
+       0xfd, 0x34, 0x1e, 0x20, 0x7b, 0xb8, 0xe7, 0x87, 0xb9, 0x57, 0xbf, 0x01,
+       0x7a, 0x77, 0xec, 0x19, 0x36, 0xd2, 0x58, 0x9f, 0x8c, 0x55, 0x92, 0xce,
+       0x58, 0xa5, 0xcf, 0x39, 0x54, 0xb1, 0xef, 0xfa, 0x8a, 0x58, 0x0f, 0xfc,
+       0x9e, 0xee, 0x70, 0x46, 0x80, 0xaf, 0x62, 0xb9, 0xd3, 0xc9, 0xea, 0xbb,
+       0x6f, 0xef, 0x90, 0x03, 0x58, 0xab, 0x81, 0xe9, 0xa4, 0x96, 0xf3, 0xb5,
+       0xef, 0x61, 0x45, 0xeb, 0xfa, 0xa4, 0xde, 0x1b, 0x9a, 0x97, 0x69, 0xfd,
+       0x7d, 0x25, 0x63, 0x3b, 0x9c, 0x46, 0x7f, 0xd3, 0x36, 0x26, 0xde, 0xe3,
+       0xe4, 0x75, 0x3f, 0x66, 0x3d, 0x8a, 0xe5, 0x53, 0xb8, 0xaf, 0x3c, 0x43,
+       0x1d, 0xe9, 0x19, 0xc2, 0xfd, 0x08, 0xf4, 0x59, 0x78, 0x8f, 0x91, 0x57,
+       0xd3, 0x32, 0x51, 0x65, 0xfe, 0x08, 0xfb, 0x41, 0x79, 0xe5, 0x30, 0x74,
+       0xd2, 0xf2, 0x33, 0x84, 0x43, 0xb5, 0x75, 0x48, 0x4d, 0x0b, 0x61, 0xe1,
+       0x1a, 0x2c, 0x3f, 0x5f, 0x7f, 0xf9, 0x7f, 0xd1, 0xbe, 0xa2, 0x91, 0xa1,
+       0x16, 0x8e, 0x2c, 0xe5, 0x9d, 0x91, 0x2b, 0x9f, 0x96, 0x23, 0xc0, 0xe3,
+       0x31, 0xc0, 0xa4, 0xee, 0xe7, 0xf7, 0x5e, 0x2a, 0x52, 0x9c, 0xbd, 0x4f,
+       0xd4, 0x43, 0x97, 0x1c, 0xf7, 0xa1, 0x23, 0x12, 0x7b, 0x68, 0xc1, 0x69,
+       0x78, 0xa8, 0x53, 0xfb, 0xe5, 0xfb, 0x82, 0xce, 0xe4, 0x21, 0x39, 0x2d,
+       0xee, 0xfd, 0x4a, 0x9f, 0x27, 0x2b, 0x7a, 0x8c, 0xf1, 0x9d, 0x96, 0xd8,
+       0xfd, 0x71, 0x7b, 0x16, 0xd5, 0xc4, 0xf5, 0x16, 0x35, 0xdf, 0x3f, 0x97,
+       0x20, 0xce, 0x16, 0x65, 0x5a, 0xf3, 0xce, 0x00, 0xf4, 0x44, 0x6e, 0x32,
+       0xb5, 0x54, 0xc7, 0xe4, 0x7b, 0x6e, 0x4c, 0x18, 0x7e, 0x61, 0x9d, 0x2e,
+       0x87, 0xdf, 0x85, 0xb0, 0x3a, 0xff, 0xca, 0x28, 0xf7, 0xd3, 0xac, 0x29,
+       0xdf, 0xff, 0x10, 0x6b, 0xd8, 0x85, 0xf5, 0xe2, 0x78, 0x8e, 0xde, 0xcf,
+       0xe5, 0x59, 0x5c, 0x4f, 0x7a, 0x92, 0x4d, 0x4b, 0x76, 0x10, 0xeb, 0xde,
+       0x27, 0x4d, 0x80, 0x5b, 0x3d, 0x54, 0x34, 0x76, 0x9d, 0x90, 0x4e, 0x05,
+       0x92, 0x9b, 0x34, 0xdb, 0xd5, 0xbf, 0x4f, 0xaf, 0xe1, 0xbd, 0x96, 0x66,
+       0xd6, 0x19, 0xfb, 0x11, 0xcf, 0x86, 0x2e, 0x8a, 0xb2, 0x77, 0xea, 0xbb,
+       0xd0, 0xf3, 0xdc, 0x77, 0xd1, 0xf6, 0xe2, 0x1a, 0xb6, 0x20, 0x79, 0xe9,
+       0x69, 0xeb, 0x57, 0x86, 0xe1, 0x54, 0x10, 0x00, 0x8f, 0x6b, 0xf9, 0x92,
+       0x3b, 0x9c, 0xd9, 0xc9, 0x9d, 0xce, 0xcc, 0x64, 0x28, 0x63, 0x01, 0xbf,
+       0x19, 0xc2, 0x1c, 0x00, 0xda, 0x5b, 0x2c, 0xeb, 0x84, 0x6e, 0xdd, 0x9d,
+       0xe0, 0xf9, 0xa6, 0x9b, 0xfc, 0x17, 0xc4, 0xd4, 0x23, 0x8e, 0xe9, 0x23,
+       0x77, 0x3e, 0x92, 0x17, 0x7e, 0x9f, 0xa3, 0x27, 0x99, 0xd0, 0xdf, 0x10,
+       0xf9, 0x0c, 0xda, 0x61, 0x8c, 0x32, 0xc7, 0x7d, 0xc6, 0x99, 0x81, 0x3c,
+       0x9b, 0x9d, 0xe2, 0x37, 0x01, 0x98, 0x4f, 0x1b, 0x6b, 0x57, 0x72, 0x95,
+       0x37, 0x6e, 0xbf, 0x5b, 0x57, 0x80, 0x0b, 0x14, 0xd3, 0x65, 0x3d, 0xde,
+       0xe8, 0xd2, 0xb7, 0xec, 0xa2, 0xb2, 0xe8, 0x9b, 0x76, 0x4a, 0xe7, 0x4e,
+       0xc3, 0x97, 0x3d, 0x33, 0x22, 0xdf, 0x77, 0xe6, 0x4a, 0xaf, 0x38, 0x8f,
+       0x96, 0xb2, 0xd7, 0x5c, 0x01, 0xfa, 0xb8, 0x18, 0xe4, 0x29, 0xbf, 0x60,
+       0xf3, 0x4d, 0x49, 0xa1, 0x3a, 0x26, 0xd3, 0xdb, 0x3a, 0xbd, 0xfb, 0xf5,
+       0xda, 0x9c, 0x01, 0xce, 0xbe, 0x81, 0xf5, 0x3b, 0x93, 0xa0, 0x7e, 0x1b,
+       0x2d, 0x29, 0xf0, 0xb2, 0xfa, 0x69, 0x5c, 0xb0, 0x6d, 0x1b, 0xb5, 0x8d,
+       0x72, 0x28, 0x60, 0xbd, 0x9d, 0xce, 0xc0, 0xe4, 0x0e, 0xac, 0xe3, 0x41,
+       0xe8, 0x4f, 0x07, 0x76, 0x1a, 0x68, 0x1b, 0x65, 0xe3, 0xc0, 0xc1, 0x68,
+       0x60, 0xe4, 0xf9, 0x80, 0x14, 0xb4, 0x8f, 0x67, 0xee, 0x59, 0x65, 0x62,
+       0x66, 0x61, 0x38, 0x0b, 0xfb, 0x80, 0xdf, 0xc5, 0x9a, 0xa8, 0xce, 0xe1,
+       0xfa, 0x71, 0xbb, 0xa7, 0x3d, 0x7f, 0x99, 0x3d, 0x6d, 0x4f, 0x4e, 0x57,
+       0xf5, 0x39, 0x79, 0x9d, 0x5f, 0x95, 0x52, 0xeb, 0xda, 0xf4, 0x5a, 0xa9,
+       0x2e, 0x9d, 0x93, 0x96, 0x95, 0x47, 0x12, 0x46, 0x0f, 0x13, 0xa6, 0x14,
+       0xe0, 0xd9, 0x09, 0x5c, 0x10, 0x1e, 0xd3, 0x46, 0xd4, 0x3b, 0xb7, 0x52,
+       0x1f, 0x2e, 0xca, 0xa7, 0x12, 0xd1, 0x19, 0x05, 0xf4, 0x03, 0x19, 0x37,
+       0xb7, 0xd5, 0xe8, 0xc9, 0x2d, 0x6b, 0xf4, 0x13, 0xcd, 0xcd, 0xb1, 0x73,
+       0x23, 0xdd, 0x6e, 0xbe, 0x92, 0x3e, 0xc5, 0xa2, 0x34, 0xad, 0xa8, 0xcf,
+       0x98, 0xfe, 0xbe, 0xed, 0xe6, 0xcc, 0x03, 0xeb, 0x7a, 0xb0, 0x4d, 0x69,
+       0xe7, 0x12, 0x8f, 0x7a, 0xdd, 0x4a, 0x4a, 0x78, 0x6e, 0xe1, 0x0c, 0x64,
+       0xcb, 0x55, 0xde, 0x4f, 0x28, 0xd2, 0x61, 0x84, 0xeb, 0x6f, 0x68, 0x3e,
+       0x19, 0x2d, 0x31, 0xb6, 0xf2, 0x68, 0x98, 0x1d, 0x26, 0x8f, 0xb1, 0x0f,
+       0xbe, 0x9f, 0xd2, 0xf1, 0xdc, 0x83, 0x01, 0x63, 0x45, 0x9d, 0x8f, 0xdc,
+       0xa1, 0x22, 0x39, 0x05, 0xfd, 0x5b, 0x5e, 0x70, 0xf8, 0xdd, 0xbe, 0x03,
+       0x82, 0xfb, 0xdc, 0x82, 0xf3, 0xcd, 0xa9, 0x67, 0xf0, 0xdc, 0x60, 0xbf,
+       0xd5, 0x67, 0xf4, 0x94, 0xc8, 0x1f, 0x46, 0xf3, 0x4d, 0x16, 0xb0, 0xf6,
+       0x2f, 0x62, 0xed, 0xd7, 0xfe, 0x36, 0x1f, 0xde, 0x55, 0xf0, 0xae, 0xf2,
+       0x0b, 0x61, 0xb6, 0x95, 0xb4, 0x18, 0xe8, 0xb3, 0xa9, 0x97, 0xf7, 0x9b,
+       0xfb, 0x35, 0x5f, 0x8c, 0x97, 0xcf, 0x81, 0x2f, 0xb2, 0xdc, 0x6f, 0x0e,
+       0x1f, 0x0e, 0x6e, 0x04, 0x5f, 0xec, 0x97, 0xdf, 0x83, 0x5d, 0xf0, 0x3b,
+       0xd5, 0x0c, 0xf8, 0xa3, 0x1f, 0xfc, 0xd2, 0x07, 0x1e, 0x09, 0xb4, 0x8d,
+       0xfc, 0x18, 0xf4, 0x1f, 0xf4, 0x9a, 0x73, 0x68, 0xb2, 0xc3, 0xc9, 0x4f,
+       0xfa, 0xce, 0xd8, 0x24, 0xbf, 0xff, 0xa2, 0xde, 0xda, 0x20, 0x6e, 0x72,
+       0x56, 0xc8, 0x0b, 0x9d, 0xcc, 0x71, 0x6c, 0x03, 0xae, 0xce, 0x12, 0x57,
+       0xb3, 0xd5, 0x1e, 0xef, 0x0a, 0xf0, 0x44, 0x9b, 0xe6, 0x89, 0x8d, 0x4e,
+       0xd6, 0xbb, 0xd1, 0xf2, 0xc4, 0x0b, 0xe0, 0x89, 0x4b, 0xab, 0x78, 0xe2,
+       0x29, 0x4b, 0xff, 0xf3, 0x75, 0x3c, 0x31, 0x6b, 0xcb, 0xa6, 0x2f, 0xc3,
+       0x13, 0x5b, 0xfd, 0xf4, 0xe7, 0x47, 0xe4, 0x55, 0xf0, 0x84, 0x28, 0xf2,
+       0xc4, 0x56, 0xcd, 0x13, 0x8c, 0x1d, 0x91, 0x2f, 0xda, 0x21, 0x47, 0xc8,
+       0x17, 0x17, 0x64, 0x11, 0x7c, 0xf1, 0x9c, 0xe2, 0xd8, 0x67, 0x68, 0x2b,
+       0x4c, 0xd2, 0x27, 0x3b, 0x55, 0xee, 0x00, 0xbf, 0x2b, 0xf9, 0xaf, 0x53,
+       0x61, 0xb8, 0x00, 0x3f, 0xfd, 0x41, 0xd8, 0xf3, 0xae, 0xfe, 0x0e, 0xe4,
+       0x3c, 0xe8, 0x3e, 0xa2, 0xf7, 0x31, 0x07, 0xf4, 0x7e, 0x6c, 0x06, 0x73,
+       0x18, 0x53, 0x9f, 0x82, 0x2f, 0xec, 0x61, 0x5d, 0x69, 0xe7, 0x9f, 0xd4,
+       0x3c, 0xd4, 0x00, 0x7d, 0xf0, 0x68, 0x1f, 0x63, 0x4d, 0xbe, 0x77, 0x48,
+       0x75, 0x16, 0x06, 0x01, 0x73, 0x4c, 0xdd, 0x2f, 0x8c, 0x73, 0xb4, 0xae,
+       0xb0, 0xf3, 0x29, 0x23, 0x86, 0x21, 0xeb, 0xcc, 0xbb, 0x42, 0xd8, 0x04,
+       0x9b, 0xb4, 0x49, 0x19, 0x1b, 0x5d, 0xed, 0x49, 0x7b, 0x3f, 0x07, 0x01,
+       0xda, 0x08, 0x7b, 0x61, 0x2f, 0x56, 0x7b, 0xb0, 0x54, 0x6f, 0xe3, 0xff,
+       0x67, 0xd8, 0xf8, 0x6c, 0x23, 0xae, 0xb1, 0xf1, 0x7f, 0xc5, 0xf2, 0x1a,
+       0x7f, 0x7b, 0xda, 0xde, 0x3f, 0x0c, 0xf8, 0xf6, 0x2d, 0xd9, 0xfb, 0xec,
+       0x83, 0x76, 0x87, 0xc8, 0x0d, 0xb0, 0xf9, 0xde, 0x09, 0x1e, 0xbc, 0x11,
+       0xbe, 0xd4, 0xbb, 0x4a, 0x9e, 0xec, 0x2f, 0xb5, 0xc1, 0xe7, 0x6e, 0x97,
+       0x77, 0x4f, 0xed, 0x94, 0xa1, 0xc9, 0x0f, 0x5e, 0x21, 0xcd, 0xdb, 0x60,
+       0xa3, 0x4e, 0x01, 0xce, 0x98, 0x95, 0xdb, 0x3f, 0x04, 0xde, 0x3a, 0x53,
+       0xdf, 0x57, 0x6d, 0xdb, 0x8d, 0x9c, 0xe7, 0xd9, 0xc9, 0xb5, 0xfa, 0x49,
+       0xa0, 0x3d, 0x63, 0x29, 0xdb, 0xe4, 0xec, 0x49, 0x7a, 0x5f, 0x29, 0xd8,
+       0xe5, 0x01, 0x6c, 0x92, 0x1d, 0xe8, 0x8f, 0xf1, 0xe4, 0x4d, 0xf2, 0xd4,
+       0x35, 0xee, 0x27, 0xf2, 0x9a, 0x0f, 0xdb, 0x9d, 0xdc, 0xd4, 0x8d, 0x52,
+       0x3c, 0x18, 0xc7, 0x1c, 0x54, 0xdb, 0x16, 0xb9, 0x5e, 0x86, 0xf4, 0x7c,
+       0xce, 0xc8, 0x11, 0xe8, 0xe6, 0x3f, 0x28, 0x0d, 0xc9, 0xe2, 0x70, 0x2b,
+       0x9e, 0xe3, 0xf2, 0x54, 0xa9, 0x07, 0xbe, 0xcf, 0x3b, 0x80, 0xa3, 0x46,
+       0x3c, 0x37, 0xca, 0xc0, 0x15, 0xe4, 0xd5, 0x16, 0x59, 0x40, 0xf9, 0x3b,
+       0xe5, 0xdf, 0xd9, 0x72, 0x96, 0x91, 0x37, 0x5a, 0xd0, 0x36, 0x2e, 0x17,
+       0x4b, 0xb4, 0x2b, 0x35, 0x4f, 0xf4, 0x7f, 0x4b, 0x7a, 0xb2, 0xdf, 0x82,
+       0x9d, 0x7a, 0x01, 0xd7, 0xd3, 0x92, 0xde, 0x3f, 0xea, 0xf4, 0xa4, 0x3a,
+       0x1d, 0xe8, 0x4e, 0x5c, 0xae, 0xd3, 0xe3, 0x35, 0x3a, 0x57, 0xd9, 0x3e,
+       0x1a, 0xe4, 0xe9, 0x83, 0x2a, 0xd9, 0x82, 0x35, 0xd9, 0xed, 0x74, 0xd9,
+       0x32, 0x3e, 0xeb, 0x9c, 0x3c, 0xe9, 0x3c, 0xab, 0x76, 0x6c, 0x10, 0xe9,
+       0x68, 0x81, 0xcd, 0x33, 0x26, 0xaa, 0xad, 0x45, 0x5c, 0xe9, 0x9c, 0x51,
+       0xed, 0x28, 0xf3, 0x6d, 0x59, 0xa2, 0x05, 0xfa, 0x01, 0x65, 0xdb, 0x50,
+       0xb6, 0xcb, 0x96, 0xb5, 0xb6, 0x48, 0x23, 0xca, 0xce, 0x68, 0x9e, 0xbf,
+       0xd4, 0xe5, 0x7b, 0x79, 0xa7, 0x59, 0x3a, 0x4e, 0xb5, 0x40, 0x36, 0x6c,
+       0x92, 0x85, 0x6b, 0x9a, 0xa4, 0x03, 0xef, 0x18, 0xe7, 0x0e, 0x4e, 0xc5,
+       0xe5, 0xba, 0x53, 0x9d, 0xc9, 0x0f, 0x61, 0x0e, 0x9d, 0x67, 0x19, 0xf7,
+       0x7e, 0xf2, 0x0a, 0xc6, 0x7d, 0x3a, 0xce, 0xf2, 0xde, 0xa4, 0xe5, 0x0f,
+       0xf1, 0x61, 0xbe, 0x71, 0x44, 0x99, 0x7c, 0x1a, 0x7e, 0x2e, 0x75, 0x78,
+       0xa7, 0xfd, 0x1e, 0xc7, 0x9f, 0x5e, 0x41, 0xbf, 0x6d, 0x86, 0xf6, 0x54,
+       0x99, 0xfc, 0x48, 0x3d, 0x84, 0xfb, 0xb4, 0x23, 0xc5, 0x9a, 0xcc, 0x9a,
+       0x23, 0x5f, 0x9d, 0x54, 0xcc, 0x65, 0x41, 0x59, 0xf5, 0x67, 0x42, 0xb3,
+       0xc6, 0xe4, 0x05, 0x23, 0x97, 0xde, 0x67, 0xe4, 0xd2, 0x99, 0xf3, 0xcb,
+       0xe4, 0xd2, 0x25, 0x2d, 0x97, 0x0e, 0x0a, 0xee, 0x73, 0x97, 0x20, 0x97,
+       0x5e, 0xc0, 0xb3, 0xa7, 0xe5, 0x52, 0x42, 0xac, 0xbd, 0x2c, 0x3f, 0xd0,
+       0xe3, 0xcf, 0x96, 0x5d, 0x6d, 0x57, 0x15, 0xa7, 0x61, 0x93, 0x94, 0x27,
+       0xac, 0xfe, 0x96, 0x4c, 0xab, 0x74, 0xf5, 0xff, 0x50, 0x22, 0x9b, 0xf3,
+       0xcf, 0xae, 0xe0, 0xf7, 0x46, 0x9f, 0x53, 0x94, 0x61, 0xaf, 0x42, 0x86,
+       0x89, 0x5a, 0x5b, 0x86, 0xe1, 0x5d, 0x05, 0xef, 0x2a, 0xec, 0xf7, 0x6f,
+       0x7f, 0x38, 0xe2, 0x51, 0x7e, 0x50, 0x66, 0x40, 0x26, 0x95, 0x21, 0x93,
+       0xca, 0x90, 0x53, 0x65, 0xc8, 0x25, 0xd8, 0x6c, 0xe7, 0xcb, 0x90, 0x4b,
+       0x65, 0xc8, 0x25, 0xc8, 0xb8, 0xc7, 0x20, 0xe3, 0x8c, 0x4c, 0x1b, 0x86,
+       0x4c, 0x3b, 0x23, 0xf7, 0x59, 0x5d, 0x6f, 0x62, 0x25, 0xbd, 0xd6, 0x47,
+       0xea, 0xd3, 0x31, 0xe4, 0xf3, 0x75, 0xb1, 0xc1, 0x03, 0xc7, 0x35, 0xbf,
+       0x7b, 0xbe, 0xba, 0xca, 0x61, 0x0e, 0xcd, 0xf7, 0xb5, 0xff, 0xbe, 0x9b,
+       0xbf, 0xa5, 0x09, 0x7c, 0xfd, 0x1d, 0xcb, 0xd7, 0xbb, 0x97, 0xf8, 0x3a,
+       0xed, 0x30, 0x56, 0xbc, 0x36, 0x5f, 0x6f, 0xb3, 0xef, 0x0a, 0xe1, 0x3a,
+       0xf0, 0xf5, 0xba, 0x15, 0x7c, 0x1d, 0x07, 0x5f, 0xef, 0x5f, 0xc5, 0xd7,
+       0x1b, 0x9c, 0x01, 0xdd, 0x86, 0x67, 0x24, 0xf8, 0xdc, 0xe8, 0xd4, 0xf8,
+       0xfa, 0x1e, 0xcd, 0xd7, 0x47, 0xc1, 0xd7, 0xd7, 0xd7, 0xf1, 0xf5, 0x7e,
+       0x49, 0xdf, 0x9c, 0x8b, 0xed, 0x94, 0xd1, 0xfb, 0x55, 0xdb, 0x66, 0xf9,
+       0x17, 0x31, 0xed, 0x0d, 0x8f, 0x0d, 0x4c, 0xb5, 0x49, 0xfe, 0xa1, 0x57,
+       0x50, 0x46, 0x3e, 0x4b, 0x8f, 0x64, 0x1d, 0x4f, 0x8e, 0x1c, 0xff, 0xbe,
+       0xcc, 0x6b, 0xde, 0x12, 0x19, 0x3b, 0x1e, 0x97, 0xf1, 0xe3, 0x8c, 0x43,
+       0x7c, 0xcf, 0xd2, 0x7b, 0x93, 0x8c, 0x1f, 0x64, 0xde, 0x9c, 0x2b, 0xa3,
+       0xc7, 0xe1, 0x6f, 0x1d, 0x67, 0x1c, 0xe2, 0xa5, 0x25, 0x1e, 0x9b, 0x87,
+       0x6c, 0x19, 0x3d, 0xce, 0xb5, 0x8e, 0xa3, 0x9f, 0x16, 0x39, 0x7a, 0x5c,
+       0xe4, 0xb6, 0xe3, 0xae, 0x7c, 0xe0, 0xf8, 0x12, 0xaf, 0x0d, 0x47, 0xbc,
+       0xf6, 0x0c, 0x78, 0xad, 0xd3, 0xf2, 0x9a, 0x5a, 0xe2, 0xb5, 0xaf, 0xd6,
+       0xf1, 0x1a, 0xdb, 0x93, 0xd7, 0x9e, 0xb5, 0x65, 0x7c, 0x76, 0xe5, 0xd0,
+       0xf1, 0x76, 0x19, 0x7d, 0xe8, 0x2d, 0x32, 0x76, 0x3f, 0x61, 0x35, 0xdf,
+       0x85, 0xa2, 0x2d, 0x36, 0x5d, 0xed, 0x44, 0xff, 0x51, 0x0e, 0x11, 0x71,
+       0xed, 0x77, 0xcf, 0x48, 0xba, 0xc0, 0xf1, 0x1a, 0xe1, 0x47, 0x9f, 0x82,
+       0x7f, 0x71, 0x08, 0x30, 0xdd, 0x72, 0x5c, 0xd2, 0xae, 0xbc, 0x2c, 0x13,
+       0xc1, 0xe9, 0xed, 0xc6, 0x9e, 0x80, 0x2d, 0xa2, 0x6d, 0x9f, 0xac, 0xe4,
+       0xdf, 0x1e, 0x6a, 0x1f, 0x63, 0xb2, 0x22, 0x8c, 0x05, 0x30, 0x6e, 0x6e,
+       0xbf, 0x85, 0xca, 0xfc, 0xc7, 0x06, 0x7d, 0xe6, 0x45, 0xc7, 0x6c, 0xfb,
+       0xf8, 0x9e, 0xcf, 0xb0, 0x67, 0xf4, 0xd9, 0x45, 0xb6, 0x67, 0x3f, 0x09,
+       0x1d, 0x53, 0x2f, 0x56, 0xf8, 0x4d, 0x1c, 0xf8, 0x9f, 0x15, 0x7e, 0x5b,
+       0xeb, 0x37, 0xdb, 0x4c, 0x7c, 0x96, 0x7c, 0xf7, 0x5d, 0x27, 0x5f, 0x9a,
+       0xd3, 0xdf, 0x38, 0xc8, 0xf9, 0xf8, 0x5d, 0xe1, 0x33, 0xeb, 0xcf, 0x31,
+       0xde, 0x91, 0x4a, 0xa9, 0x63, 0xdb, 0x99, 0x7b, 0x70, 0x70, 0x8e, 0x75,
+       0x77, 0x5a, 0x1e, 0xdd, 0xa9, 0xfd, 0x0e, 0xda, 0x58, 0xa3, 0x93, 0x2f,
+       0x48, 0x91, 0xb6, 0xc9, 0xf0, 0x4e, 0xa7, 0x30, 0xfd, 0x73, 0xdb, 0x8d,
+       0xfd, 0x3c, 0xb0, 0x95, 0x79, 0x87, 0x59, 0xb5, 0x5a, 0x26, 0x9f, 0x92,
+       0x48, 0x26, 0xa7, 0x6f, 0xce, 0xc2, 0xce, 0xce, 0x1f, 0xd7, 0xdf, 0xab,
+       0x4a, 0x75, 0x2a, 0xce, 0xe9, 0x4e, 0xc8, 0xd7, 0x88, 0x16, 0x92, 0xf2,
+       0xd1, 0xe3, 0xa4, 0x07, 0x95, 0xd8, 0x28, 0x1f, 0xb1, 0xf4, 0x70, 0x46,
+       0x4a, 0x90, 0x3b, 0xc7, 0x8f, 0x7f, 0x40, 0xa6, 0x0f, 0xac, 0xa4, 0x87,
+       0xb1, 0x1a, 0x3d, 0x24, 0x60, 0x9f, 0x39, 0xf5, 0xf4, 0xf0, 0xf3, 0x4b,
+       0xf4, 0x30, 0xed, 0xfc, 0x6b, 0xe9, 0xe1, 0x86, 0x65, 0xf4, 0x30, 0xa1,
+       0xe9, 0x61, 0x68, 0x89, 0x1e, 0x26, 0x8e, 0x73, 0x5c, 0xbd, 0x37, 0xea,
+       0x2d, 0x38, 0x5c, 0xf3, 0x25, 0x5a, 0x48, 0x8d, 0xeb, 0x7c, 0xfd, 0x74,
+       0x81, 0xe7, 0x9b, 0x36, 0x28, 0xc6, 0x49, 0x6a, 0xeb, 0xbf, 0xf1, 0xdf,
+       0x74, 0xfd, 0xaf, 0xda, 0xfa, 0xff, 0x77, 0xfd, 0x33, 0x5b, 0x99, 0xbb,
+       0xcf, 0x33, 0xb0, 0x46, 0x1e, 0x47, 0xf4, 0x90, 0xdb, 0x6a, 0xf4, 0x02,
+       0xd7, 0x98, 0xcf, 0x90, 0x67, 0x90, 0x7f, 0xe7, 0x21, 0xff, 0x9e, 0x80,
+       0xfc, 0x7b, 0x7c, 0xd9, 0x9e, 0x40, 0xbf, 0x8d, 0x47, 0x84, 0x72, 0x24,
+       0xa8, 0xe1, 0x63, 0xa1, 0x8f, 0xf8, 0x30, 0xf9, 0x27, 0xcc, 0xfd, 0x5d,
+       0x8e, 0x13, 0x57, 0xe7, 0x1c, 0x3d, 0x1a, 0xd4, 0xe3, 0x84, 0x70, 0xbf,
+       0x5c, 0x37, 0x47, 0xfc, 0xae, 0xf0, 0xf9, 0x8c, 0xce, 0x23, 0x29, 0xea,
+       0x3d, 0x28, 0xe2, 0x85, 0x7b, 0x50, 0xc4, 0x89, 0xab, 0xed, 0xfd, 0x62,
+       0xa5, 0x49, 0xe7, 0xd0, 0x1f, 0x9e, 0x4b, 0xc8, 0x42, 0x82, 0x31, 0x3e,
+       0x7e, 0xe7, 0x90, 0x7e, 0xb3, 0x9f, 0x2c, 0x4a, 0x81, 0xb9, 0x72, 0xe0,
+       0xe9, 0x0d, 0x96, 0xb6, 0x19, 0x1b, 0xe4, 0x19, 0xe0, 0x68, 0x2f, 0xa2,
+       0xdb, 0xca, 0xba, 0x96, 0xba, 0x98, 0x25, 0xf0, 0x3e, 0x25, 0xa9, 0x5c,
+       0x1f, 0xee, 0x73, 0x1c, 0xfb, 0x13, 0x32, 0xf1, 0xe0, 0x87, 0x61, 0xcb,
+       0xbd, 0x1f, 0x3a, 0x87, 0xe7, 0xcf, 0xb8, 0xf7, 0xe0, 0x69, 0x18, 0x66,
+       0xf4, 0x77, 0xac, 0xe8, 0x03, 0x92, 0x1e, 0x92, 0x78, 0x3e, 0x63, 0xe3,
+       0x4a, 0x49, 0x29, 0x96, 0x5e, 0x94, 0x7c, 0x85, 0xdf, 0x5c, 0x7b, 0x09,
+       0xf7, 0xd7, 0x5b, 0x0f, 0xe3, 0x87, 0x0c, 0xeb, 0x3b, 0xd7, 0x66, 0x51,
+       0xb2, 0x15, 0x93, 0xe3, 0x52, 0x8b, 0x9b, 0x9c, 0x91, 0x63, 0xda, 0x7e,
+       0xce, 0xd8, 0xdc, 0x96, 0xf4, 0x70, 0x41, 0x8c, 0x0d, 0xfd, 0x39, 0xd8,
+       0xd0, 0x9f, 0xad, 0x66, 0xf5, 0x3e, 0xd6, 0xe3, 0xb0, 0xa1, 0x1f, 0x83,
+       0xee, 0xa1, 0xce, 0x49, 0x58, 0x9d, 0x33, 0xa1, 0x0e, 0x68, 0x9d, 0xf3,
+       0xe7, 0x5a, 0xe7, 0xbc, 0x7b, 0x95, 0xce, 0x39, 0xaa, 0x3a, 0x27, 0xa9,
+       0x73, 0x06, 0xd4, 0x7e, 0x87, 0xf6, 0xe2, 0x96, 0x35, 0x74, 0xce, 0x7b,
+       0xe4, 0x1d, 0xf6, 0xdd, 0x3d, 0xf2, 0xde, 0x3d, 0x7a, 0xef, 0xc6, 0x9b,
+       0x51, 0xfc, 0x76, 0x93, 0xd1, 0x41, 0xd7, 0xab, 0x6e, 0xbd, 0xe7, 0xfb,
+       0x95, 0x3a, 0x9d, 0xd3, 0xa1, 0xfa, 0x9c, 0x01, 0xdd, 0x86, 0xb1, 0x09,
+       0x3e, 0x07, 0x4e, 0x76, 0xb8, 0x09, 0xcf, 0x49, 0x89, 0x1d, 0xc7, 0xdc,
+       0xcd, 0xf7, 0xa5, 0x94, 0x79, 0xf7, 0x56, 0xfb, 0x4e, 0x45, 0xe5, 0xae,
+       0x29, 0xef, 0xb4, 0xe5, 0x46, 0x57, 0x75, 0xa8, 0x76, 0xad, 0xab, 0x76,
+       0x83, 0xa1, 0x66, 0xa0, 0x5f, 0x67, 0xca, 0x91, 0xce, 0xe2, 0x6f, 0xc6,
+       0x9e, 0x19, 0xa3, 0x88, 0x62, 0xd8, 0x29, 0xd4, 0xc1, 0x55, 0x8e, 0x6c,
+       0x4a, 0xfe, 0x86, 0xaf, 0x80, 0x6b, 0x0e, 0x78, 0xbd, 0x19, 0xfc, 0xf3,
+       0x1f, 0x4a, 0x8c, 0x81, 0xb6, 0xc9, 0x89, 0xa9, 0xfa, 0x77, 0xed, 0xf2,
+       0xae, 0xa9, 0x1d, 0x72, 0xfb, 0xe4, 0xd6, 0xa4, 0x34, 0xef, 0x94, 0x89,
+       0xc9, 0x29, 0x7d, 0xfe, 0x7d, 0xb3, 0xfe, 0x2e, 0x08, 0xbf, 0x97, 0x63,
+       0x64, 0xe4, 0x90, 0x63, 0x64, 0x64, 0x56, 0xd5, 0x6c, 0xd6, 0xa8, 0x4f,
+       0x7e, 0x8b, 0x64, 0x70, 0x32, 0xa9, 0xbf, 0xa5, 0x3a, 0x53, 0xbd, 0x4a,
+       0x7e, 0xfb, 0xa4, 0xba, 0x4b, 0xd5, 0xce, 0xf7, 0x6a, 0x9b, 0x75, 0x76,
+       0x99, 0xcd, 0xfa, 0xbf, 0x64, 0xe1, 0xbd, 0x71, 0xcc, 0x13, 0x34, 0x7c,
+       0xf5, 0xb7, 0xb8, 0x17, 0xda, 0x96, 0x90, 0x17, 0x65, 0x50, 0xe3, 0x8f,
+       0xf2, 0xb4, 0x05, 0x72, 0x70, 0x51, 0xeb, 0xd7, 0x2d, 0xa0, 0x41, 0xca,
+       0xd2, 0x0f, 0xca, 0x0b, 0x5a, 0x9e, 0x6d, 0xb1, 0xb6, 0xeb, 0x3c, 0xbf,
+       0x6d, 0x7d, 0x9c, 0xb6, 0xeb, 0x9f, 0xdb, 0x72, 0x96, 0xa5, 0x93, 0x8b,
+       0x42, 0x7d, 0x97, 0x80, 0x0c, 0xa5, 0x3c, 0x7d, 0xa3, 0xb6, 0xeb, 0x97,
+       0x6c, 0x1f, 0x94, 0x9f, 0x46, 0x76, 0xef, 0x76, 0xe6, 0x6d, 0x19, 0x9f,
+       0xa3, 0x78, 0xba, 0x9f, 0xcd, 0x5b, 0x3e, 0x53, 0xce, 0xe7, 0xf1, 0x7e,
+       0x33, 0xde, 0x93, 0xcf, 0x1e, 0xd7, 0x7c, 0xa6, 0xed, 0x13, 0xa7, 0xd7,
+       0xee, 0x2f, 0x2c, 0xed, 0x0d, 0x14, 0xc8, 0x67, 0xea, 0x84, 0x37, 0x6f,
+       0xe4, 0x01, 0xf3, 0x54, 0x7f, 0x03, 0xba, 0x83, 0x6d, 0x51, 0xfe, 0x70,
+       0x96, 0xbe, 0x2d, 0xfc, 0x9f, 0x8d, 0x78, 0x6e, 0xc3, 0xf3, 0x8c, 0xbc,
+       0xfb, 0x60, 0x5c, 0xcf, 0x7b, 0x02, 0xf3, 0x38, 0x7c, 0x1c, 0x73, 0x72,
+       0x8c, 0xed, 0xec, 0x9e, 0x75, 0xa5, 0xe1, 0x2c, 0xf9, 0x8e, 0x67, 0x6d,
+       0xc2, 0xf0, 0x50, 0x2f, 0xe9, 0x36, 0xed, 0x0d, 0xe9, 0xb3, 0xa5, 0xbb,
+       0x93, 0x31, 0xe0, 0xe4, 0x30, 0xd6, 0x63, 0xa2, 0xe4, 0x7b, 0x39, 0xc7,
+       0x4f, 0x62, 0x9e, 0xb0, 0x01, 0x3b, 0x61, 0x0b, 0x76, 0xc2, 0x0e, 0xec,
+       0x84, 0x1d, 0xb8, 0x49, 0x4e, 0x5d, 0xc3, 0x1c, 0x93, 0xc2, 0x75, 0xf0,
+       0xca, 0xe5, 0xaf, 0x75, 0x9c, 0xbe, 0xf1, 0xe6, 0x41, 0xf8, 0xec, 0xe2,
+       0xa5, 0x87, 0x99, 0x87, 0xbf, 0xe8, 0x35, 0xde, 0x3c, 0x24, 0x9d, 0xfd,
+       0x78, 0xdf, 0xff, 0xa2, 0x74, 0xdd, 0x7c, 0xab, 0xd3, 0x38, 0x3c, 0x08,
+       0x3c, 0x66, 0x9d, 0x74, 0x72, 0xc4, 0x99, 0xc7, 0x38, 0xb9, 0xdd, 0x31,
+       0x61, 0xdc, 0x72, 0x9e, 0xb1, 0x88, 0x9b, 0x3b, 0x63, 0x3d, 0xa9, 0x51,
+       0x27, 0x3d, 0xac, 0x62, 0xe9, 0xe1, 0x41, 0x27, 0xaa, 0xc7, 0x6f, 0xae,
+       0x42, 0xce, 0x00, 0xd6, 0xc3, 0xe5, 0x4f, 0x83, 0x9e, 0x8e, 0x48, 0xf1,
+       0x64, 0x8b, 0xcc, 0x95, 0x3a, 0xbd, 0x9c, 0x4a, 0xe8, 0xdc, 0x12, 0x75,
+       0x0a, 0x44, 0x7f, 0x36, 0x2e, 0x33, 0x93, 0x3b, 0x45, 0x69, 0xdb, 0x7d,
+       0x9b, 0xe4, 0xa6, 0x26, 0xe5, 0x62, 0x9f, 0xb4, 0x2a, 0xf4, 0xcf, 0x6f,
+       0xdc, 0xaa, 0x53, 0xdc, 0x4b, 0x8c, 0x78, 0x61, 0x3b, 0xf9, 0x64, 0x12,
+       0x38, 0x04, 0xdd, 0x32, 0xc6, 0xdb, 0x24, 0x94, 0x7b, 0x1f, 0xd0, 0xf1,
+       0x53, 0xc6, 0x6c, 0xeb, 0xf7, 0x1e, 0xc8, 0x1f, 0xf1, 0x35, 0xf9, 0x63,
+       0xb6, 0xcc, 0x7d, 0x1a, 0x29, 0xb8, 0x8c, 0x11, 0xfb, 0xf8, 0x3d, 0xcd,
+       0xba, 0x4d, 0x32, 0xd1, 0x57, 0xb0, 0x79, 0x1e, 0x7f, 0x9e, 0x64, 0x0e,
+       0x31, 0x71, 0x32, 0xda, 0x47, 0x5e, 0x5f, 0xb9, 0xb7, 0x11, 0xaf, 0x93,
+       0x07, 0x8e, 0x2c, 0x4c, 0x46, 0x7b, 0x21, 0xec, 0x0f, 0xcf, 0xd3, 0x46,
+       0xde, 0xe6, 0x56, 0xb5, 0x23, 0x5c, 0xdc, 0xaf, 0x5c, 0x2e, 0x63, 0x95,
+       0x4f, 0x99, 0xea, 0x69, 0xf9, 0x7a, 0xa6, 0x6a, 0x64, 0xeb, 0x74, 0x35,
+       0xd2, 0x2d, 0x71, 0xa3, 0x4b, 0x57, 0xe9, 0x13, 0x13, 0xcd, 0xac, 0xe9,
+       0x13, 0xea, 0x45, 0x25, 0xef, 0x9b, 0xdb, 0x26, 0xee, 0xc3, 0xb2, 0x38,
+       0xe1, 0x7f, 0x7a, 0x3b, 0x73, 0x35, 0x26, 0x82, 0x37, 0xa3, 0x1f, 0x9b,
+       0xae, 0xa4, 0x3e, 0x1c, 0x51, 0x8d, 0xb8, 0x6f, 0xd6, 0xf4, 0x07, 0x9e,
+       0xc2, 0xb3, 0xf1, 0x13, 0x3e, 0x07, 0x3f, 0xe1, 0xb3, 0xd0, 0x75, 0xe7,
+       0xe1, 0x27, 0x3c, 0x01, 0x3f, 0xe1, 0x71, 0xf8, 0x09, 0x8f, 0x41, 0x4f,
+       0xd6, 0xfb, 0x07, 0xe3, 0xcb, 0xfc, 0x83, 0x50, 0xf3, 0x3f, 0xe3, 0x81,
+       0x4f, 0xd4, 0xf9, 0x06, 0x87, 0x8c, 0xbe, 0x82, 0xdf, 0x6f, 0xf8, 0xa8,
+       0x43, 0xdd, 0xa4, 0xf5, 0xa3, 0xc9, 0xdb, 0x1d, 0x5e, 0xd2, 0x57, 0x1d,
+       0xca, 0xe8, 0xab, 0x99, 0x9a, 0xbe, 0x32, 0x7c, 0xf4, 0xf0, 0xa4, 0xc4,
+       0xfc, 0xc9, 0xf9, 0x5c, 0xb0, 0x57, 0xf3, 0x50, 0xab, 0xbf, 0x53, 0x62,
+       0x0f, 0xa8, 0xb6, 0x06, 0xc9, 0xd9, 0x67, 0xd0, 0xd7, 0x89, 0x4f, 0xa3,
+       0xaf, 0xeb, 0x24, 0xaf, 0xed, 0xb3, 0xcb, 0xe3, 0xfb, 0xb1, 0x15, 0xf8,
+       0x2e, 0x96, 0x27, 0x34, 0xce, 0xef, 0xaf, 0x70, 0x9f, 0xa5, 0x45, 0xc6,
+       0x2b, 0x11, 0xce, 0x79, 0x9e, 0x95, 0xb9, 0x18, 0xed, 0x12, 0x7b, 0x78,
+       0x1b, 0xcf, 0x59, 0xa9, 0x7c, 0xb0, 0x5e, 0xe7, 0xb0, 0x9c, 0xea, 0x93,
+       0x64, 0xbe, 0x8f, 0xb4, 0x7a, 0x9f, 0xcc, 0xe8, 0xb5, 0xd8, 0x26, 0x0d,
+       0x0f, 0xd3, 0x46, 0x89, 0xf6, 0xf3, 0xde, 0x7f, 0xa5, 0xfd, 0xe6, 0x6a,
+       0xdc, 0xd4, 0x13, 0x39, 0xa2, 0xd7, 0x6b, 0x5a, 0xe7, 0x19, 0xde, 0x34,
+       0xc7, 0xb8, 0x3c, 0xbf, 0x6f, 0xc5, 0x98, 0xfc, 0xbf, 0x66, 0xfd, 0x7e,
+       0xf9, 0x4a, 0x63, 0xcf, 0x6c, 0xb6, 0x76, 0x8c, 0x89, 0x53, 0xad, 0x6d,
+       0xc3, 0xb0, 0x9f, 0xfa, 0x6f, 0x32, 0xee, 0x70, 0xc6, 0x27, 0x77, 0x3a,
+       0xc5, 0x49, 0xee, 0x65, 0xdb, 0xbf, 0xd1, 0xe1, 0xed, 0x77, 0x0e, 0xfb,
+       0x3b, 0x50, 0xc6, 0x98, 0x25, 0x63, 0x36, 0xf7, 0x5f, 0xc9, 0x18, 0x6d,
+       0xce, 0xe7, 0xd8, 0x2c, 0xdb, 0xe1, 0x4c, 0x4c, 0x76, 0xc2, 0x37, 0xe7,
+       0xb9, 0x2a, 0xbe, 0x1f, 0xe2, 0xda, 0x41, 0x07, 0x7b, 0xfa, 0xcc, 0xee,
+       0x98, 0x5c, 0x65, 0x63, 0xd0, 0xd4, 0xc3, 0x3f, 0xbd, 0x6c, 0xef, 0xf6,
+       0x28, 0xf4, 0xd8, 0x2d, 0x90, 0x47, 0xd4, 0xc3, 0x47, 0xe5, 0x6d, 0x96,
+       0x9e, 0x97, 0xeb, 0xe1, 0x4b, 0xc2, 0x38, 0x71, 0x2f, 0xde, 0x15, 0xc2,
+       0x38, 0xe8, 0xe1, 0x58, 0x9d, 0xaf, 0x46, 0xbf, 0xaf, 0x29, 0x63, 0xf6,
+       0xc3, 0x96, 0xfb, 0x7d, 0x90, 0x03, 0x89, 0xc8, 0xcf, 0x6b, 0x5c, 0xda,
+       0xaf, 0xdd, 0x6f, 0xdb, 0x4e, 0x04, 0x7f, 0x44, 0x1c, 0xa5, 0x8e, 0xca,
+       0x2f, 0x42, 0xa7, 0x31, 0x07, 0xe4, 0x2f, 0x34, 0xce, 0x44, 0x91, 0xf6,
+       0x36, 0x6b, 0x18, 0xad, 0x9c, 0x4f, 0x45, 0x39, 0x1c, 0x45, 0xdb, 0x76,
+       0xcc, 0xee, 0xc9, 0x17, 0xe5, 0xeb, 0x8c, 0x73, 0xa6, 0x06, 0x63, 0xeb,
+       0xf9, 0x3d, 0x46, 0xb4, 0xfd, 0x45, 0xed, 0xb7, 0x67, 0x25, 0xea, 0x8b,
+       0xcf, 0x0d, 0x75, 0x7d, 0xd3, 0x8e, 0xe2, 0x7d, 0xe5, 0x39, 0xb2, 0xa7,
+       0xf5, 0x3e, 0xa3, 0xf9, 0x5e, 0x42, 0xc4, 0x27, 0xe4, 0x9d, 0x94, 0x3e,
+       0xeb, 0xe4, 0x3f, 0x4c, 0xbb, 0x87, 0x7b, 0xb0, 0xde, 0xfc, 0x78, 0xf0,
+       0x11, 0xfd, 0xcd, 0xc0, 0x69, 0x11, 0xa7, 0x18, 0xdc, 0xa6, 0x73, 0x4f,
+       0x8a, 0x3a, 0xd6, 0x5c, 0xc0, 0xbd, 0xe6, 0xa3, 0x76, 0x3c, 0xcc, 0xbf,
+       0xc3, 0xc1, 0xb2, 0x3c, 0x60, 0xa3, 0x0e, 0xa1, 0xec, 0x4d, 0x48, 0xc7,
+       0x89, 0x5f, 0xd0, 0xbc, 0xb0, 0x05, 0xbe, 0xc0, 0xc0, 0x09, 0xe8, 0xea,
+       0x13, 0x49, 0x19, 0x3a, 0xa1, 0x75, 0x63, 0x76, 0x75, 0xac, 0xa0, 0xc7,
+       0x73, 0x9d, 0x77, 0xe9, 0x73, 0x6c, 0x6f, 0x3d, 0x11, 0x93, 0x63, 0x89,
+       0x1e, 0xaf, 0xcb, 0x79, 0xb7, 0xd5, 0x85, 0x51, 0x0c, 0xbb, 0x05, 0xed,
+       0x5f, 0x2f, 0x8e, 0x1d, 0xc5, 0xaf, 0x63, 0x32, 0x7d, 0xb0, 0x1d, 0xb0,
+       0x75, 0x6e, 0x33, 0x67, 0x90, 0xb1, 0x56, 0xfa, 0x1b, 0xf7, 0x6e, 0x92,
+       0xb2, 0xac, 0x03, 0xb0, 0x0c, 0x9e, 0xa0, 0x3e, 0xf3, 0x35, 0x8f, 0x03,
+       0x06, 0xaf, 0x41, 0xfb, 0x21, 0xe4, 0xcb, 0xb7, 0x88, 0xff, 0x00, 0x64,
+       0xdc, 0x89, 0xb8, 0x74, 0x9d, 0x68, 0x91, 0x5d, 0x27, 0xe8, 0x87, 0xd4,
+       0xfb, 0xa5, 0xb4, 0x4b, 0xe7, 0x30, 0xc7, 0x77, 0x6a, 0x39, 0xc9, 0x3d,
+       0xcd, 0xdb, 0xc9, 0xbb, 0xa8, 0x9b, 0x87, 0xcd, 0x9c, 0x3b, 0xe1, 0xe9,
+       0x3d, 0xd2, 0x1c, 0xe6, 0x9c, 0xaf, 0x78, 0x18, 0xc7, 0xc8, 0x9c, 0x22,
+       0xfd, 0x94, 0xe1, 0x6d, 0xc0, 0xf1, 0x31, 0xcb, 0x3b, 0x43, 0xdb, 0x2c,
+       0x8f, 0xfe, 0x88, 0xbc, 0x77, 0xf3, 0x36, 0x23, 0x3b, 0x7f, 0x76, 0x1b,
+       0x73, 0x93, 0xb6, 0xf8, 0xbc, 0x37, 0x69, 0x7b, 0xc2, 0xc8, 0xd0, 0xd7,
+       0xe2, 0x45, 0x01, 0x8e, 0xa2, 0x7d, 0x29, 0x7d, 0x96, 0x2f, 0xbc, 0x18,
+       0xe8, 0xf3, 0x2b, 0xc1, 0x02, 0xf3, 0x08, 0xf5, 0x77, 0x14, 0x6a, 0xdf,
+       0x5b, 0xd9, 0x5b, 0x65, 0x9c, 0xfc, 0x89, 0xe8, 0x6f, 0xa9, 0xd4, 0xe5,
+       0x1d, 0xd6, 0xef, 0x81, 0x31, 0xd6, 0xb4, 0x94, 0x1b, 0x14, 0x4e, 0xea,
+       0xef, 0x21, 0x3d, 0xeb, 0x5c, 0x2a, 0x5d, 0x70, 0xbe, 0x39, 0x25, 0xa1,
+       0xeb, 0x7f, 0xdf, 0xf9, 0xb6, 0xcf, 0x3d, 0xf3, 0x2f, 0x3b, 0xdf, 0x2a,
+       0xf9, 0xe0, 0xc3, 0x0b, 0x98, 0xc7, 0x2b, 0xce, 0x77, 0xb0, 0xbe, 0x47,
+       0xca, 0xd9, 0xb4, 0x67, 0x63, 0xe2, 0x17, 0x4a, 0xaf, 0x38, 0x5f, 0xaa,
+       0xc5, 0x93, 0xfa, 0x23, 0x1a, 0x39, 0xca, 0x77, 0x15, 0xbc, 0xab, 0xe8,
+       0xfd, 0x1f, 0x67, 0x76, 0xca, 0xe6, 0x97, 0x68, 0x3e, 0x9e, 0x5f, 0xda,
+       0x97, 0x19, 0xd6, 0x7b, 0x15, 0xcf, 0x38, 0xb3, 0x73, 0x9f, 0xdb, 0x66,
+       0xf2, 0x8c, 0x2e, 0xe0, 0x9d, 0xc9, 0xb9, 0x9c, 0x99, 0xbb, 0x80, 0x3a,
+       0x4f, 0x3b, 0x33, 0x3a, 0xfe, 0xc5, 0x76, 0x17, 0x9c, 0xe9, 0xb9, 0xa7,
+       0x9d, 0x39, 0xbd, 0x07, 0x7d, 0xd1, 0x79, 0x74, 0x8a, 0x7d, 0x5f, 0x44,
+       0x9d, 0x79, 0xe7, 0x14, 0xfa, 0x9b, 0x9b, 0xe2, 0x79, 0xdc, 0x4e, 0xd8,
+       0x05, 0xfc, 0x1b, 0x45, 0xfc, 0x1e, 0xc7, 0x33, 0xce, 0xdc, 0x52, 0xbf,
+       0x0b, 0xe8, 0x87, 0x75, 0x49, 0x8b, 0x1c, 0xf7, 0x19, 0xf4, 0xbf, 0x7a,
+       0xaf, 0x6a, 0x35, 0x4e, 0x9e, 0x07, 0x4e, 0x5e, 0xb4, 0x38, 0x79, 0xd5,
+       0xe2, 0xe4, 0xb9, 0x3a, 0x9c, 0x88, 0x5a, 0x8e, 0x93, 0x57, 0x81, 0x13,
+       0x51, 0x6b, 0xe3, 0x04, 0xef, 0x2a, 0x78, 0xa7, 0x71, 0xf2, 0xd2, 0x0a,
+       0x9c, 0x2c, 0x2e, 0xc5, 0xe5, 0x0d, 0x4e, 0x5e, 0x00, 0x4e, 0x7e, 0x60,
+       0x61, 0x7f, 0xd1, 0xe2, 0x04, 0xf7, 0xb9, 0x17, 0x51, 0xe7, 0xa5, 0x3a,
+       0x9c, 0xbc, 0x08, 0x9c, 0xbc, 0x64, 0x71, 0xf2, 0x6d, 0x8b, 0x93, 0x6f,
+       0xa3, 0xce, 0x22, 0x70, 0x72, 0x69, 0x0d, 0x9c, 0xbc, 0x00, 0x9c, 0x44,
+       0xfd, 0x5e, 0x42, 0x3f, 0xdf, 0xae, 0xc3, 0xc9, 0x0b, 0x6b, 0xe0, 0x84,
+       0x7b, 0xb1, 0x51, 0x4e, 0xf7, 0x99, 0xd7, 0xc9, 0xe9, 0x5e, 0x7c, 0x03,
+       0x39, 0xdd, 0xac, 0x73, 0x46, 0x6a, 0x7f, 0xbb, 0x62, 0xc2, 0xe6, 0xa8,
+       0x99, 0x5c, 0xc0, 0xda, 0x37, 0x9b, 0x3a, 0xc1, 0xe7, 0xc5, 0x02, 0xbc,
+       0x11, 0x9d, 0x53, 0xea, 0xee, 0x19, 0x03, 0xaf, 0xbd, 0x5b, 0x0e, 0x9f,
+       0x6c, 0x3c, 0x96, 0xb7, 0x65, 0xfe, 0x9e, 0xce, 0x82, 0x52, 0x7c, 0x17,
+       0xe5, 0x24, 0xd0, 0x2f, 0x69, 0xe0, 0xb7, 0x0a, 0xbb, 0xb3, 0x52, 0xbf,
+       0x27, 0x3d, 0xc5, 0x6f, 0x34, 0x71, 0x7f, 0x8c, 0x7f, 0x67, 0x23, 0xc5,
+       0x3c, 0xab, 0xa2, 0x86, 0x37, 0x0d, 0xfd, 0xd1, 0xaf, 0x73, 0xab, 0xf8,
+       0x37, 0x82, 0x62, 0xf0, 0xfb, 0x47, 0xfb, 0x68, 0x2b, 0x67, 0xec, 0x99,
+       0xb0, 0x40, 0x9f, 0x53, 0xa9, 0xf1, 0x4f, 0xfd, 0x79, 0x68, 0xf2, 0x5d,
+       0x8d, 0x6e, 0x8e, 0x2c, 0x7d, 0x77, 0xf0, 0xb4, 0x3c, 0xa5, 0x63, 0xc5,
+       0xcd, 0xfa, 0xef, 0x2b, 0x9c, 0x09, 0x4c, 0x8c, 0x76, 0x41, 0xc7, 0x68,
+       0x05, 0xde, 0xf8, 0xb8, 0x8d, 0xd3, 0x76, 0xf5, 0xbf, 0xb4, 0x14, 0xa3,
+       0xad, 0xcf, 0x67, 0x31, 0xfb, 0xeb, 0xb9, 0xc9, 0x39, 0x9d, 0xa3, 0x33,
+       0xc8, 0xef, 0x6f, 0x40, 0x46, 0x8c, 0x4d, 0x57, 0x64, 0xfc, 0x41, 0x3e,
+       0x53, 0xbf, 0xc5, 0xa0, 0xc3, 0x28, 0xc3, 0x0b, 0x92, 0xeb, 0x67, 0x99,
+       0x69, 0x33, 0xa8, 0xfd, 0xe5, 0xd3, 0x32, 0xb0, 0x34, 0x3e, 0xf1, 0xfb,
+       0x89, 0xba, 0xef, 0x60, 0xd3, 0xe6, 0xc9, 0x3a, 0xb9, 0x2a, 0xdf, 0x47,
+       0x7b, 0xe4, 0x9f, 0xb0, 0xdf, 0x0a, 0xe4, 0xfb, 0xfa, 0x6f, 0xbf, 0x6a,
+       0xd1, 0x81, 0xdf, 0xfc, 0xbe, 0xda, 0x84, 0x33, 0x88, 0x36, 0xf3, 0x5e,
+       0xcb, 0xb0, 0xca, 0xdc, 0x38, 0xcc, 0x73, 0x73, 0x33, 0xab, 0xbe, 0x9d,
+       0x5d, 0xd3, 0x8b, 0x45, 0xbd, 0xa6, 0xcc, 0xcf, 0x2a, 0x80, 0x16, 0x35,
+       0x6d, 0x69, 0xfa, 0x3f, 0xbc, 0xa4, 0x2f, 0xa9, 0x67, 0xcd, 0xb7, 0x67,
+       0x8c, 0xbe, 0x4c, 0x27, 0x07, 0x31, 0xbe, 0xfe, 0x1b, 0x0d, 0xf6, 0x5c,
+       0x6f, 0x7e, 0xee, 0x2e, 0xad, 0xeb, 0x27, 0x82, 0x6c, 0xca, 0x95, 0x35,
+       0xea, 0x4e, 0xd6, 0xd5, 0xd5, 0xf3, 0xf6, 0xe4, 0xb7, 0xb0, 0x36, 0xbf,
+       0x51, 0xae, 0xc8, 0xc0, 0xd4, 0x5f, 0xc1, 0x7f, 0x4c, 0xca, 0x6f, 0x96,
+       0x1f, 0x01, 0xbd, 0x16, 0xb6, 0xd8, 0x6f, 0x35, 0xe5, 0x00, 0x37, 0xbf,
+       0xbd, 0xa2, 0xf3, 0x89, 0x63, 0xbf, 0x0d, 0xba, 0xf8, 0xcc, 0x23, 0x1c,
+       0x03, 0xb0, 0xc4, 0x60, 0xdb, 0xc3, 0x4e, 0x98, 0x7e, 0x44, 0xe7, 0xce,
+       0x5d, 0x5f, 0x79, 0x44, 0xc7, 0x2c, 0x86, 0x2a, 0xed, 0xb2, 0xb7, 0xd2,
+       0x22, 0xfb, 0xa0, 0x17, 0xf6, 0x55, 0x7c, 0x5c, 0x71, 0x79, 0x67, 0xc5,
+       0xac, 0xd3, 0x07, 0x2b, 0x5c, 0xef, 0x3d, 0x32, 0x73, 0x72, 0xe5, 0xf7,
+       0x3e, 0xe7, 0x0b, 0xd1, 0xdf, 0x73, 0x52, 0x8a, 0xf9, 0x65, 0xa4, 0x25,
+       0x5c, 0xe5, 0xf4, 0xb1, 0x79, 0x8d, 0x07, 0x66, 0xb8, 0xa6, 0x27, 0x17,
+       0x85, 0x79, 0xfa, 0xfc, 0x1b, 0x4e, 0x7f, 0xb9, 0x9d, 0xe7, 0xa6, 0xf9,
+       0x2d, 0xaf, 0xa1, 0x6a, 0x94, 0x37, 0xbe, 0x56, 0xce, 0x38, 0xec, 0xfc,
+       0x3d, 0x51, 0x8e, 0x5f, 0x9c, 0x39, 0xe3, 0xd2, 0x71, 0xb6, 0x05, 0xf7,
+       0xef, 0x6e, 0xd7, 0x67, 0x9b, 0xcf, 0x8a, 0x2d, 0xd3, 0xf9, 0xe4, 0x78,
+       0x5e, 0xf9, 0xbd, 0xb6, 0x88, 0x1f, 0x6a, 0x7f, 0xf7, 0x40, 0xe4, 0xff,
+       0x02, 0x06, 0x86, 0xe5, 0x0a, 0xd4, 0x6f, 0x00, 0x00, 0x00 };
 
 static const u32 bnx2_CP_b09FwData[(0x0/4) + 1] = { 0x0 };
 static const u32 bnx2_CP_b09FwRodata[(0x118/4) + 1] = {
-       0x0800061c, 0x0800083c, 0x08000780, 0x080007a8, 0x080007d0, 0x080007f8,
-       0x08000654, 0x08000640, 0x08000864, 0x08000864, 0x08000670, 0x0800068c,
-       0x0800068c, 0x08000864, 0x080006a4, 0x080006b8, 0x08000864, 0x080006cc,
-       0x08000864, 0x08000864, 0x080006e0, 0x08000864, 0x08000864, 0x08000864,
-       0x08000864, 0x08000864, 0x08000864, 0x08000864, 0x08000864, 0x08000864,
-       0x08000864, 0x080006f4, 0x08000864, 0x08000708, 0x0800071c, 0x08000730,
-       0x08000864, 0x08000744, 0x08000758, 0x0800076c, 0x08003200, 0x08003218,
-       0x08003228, 0x08003238, 0x08003250, 0x08003268, 0x08003278, 0x08003288,
-       0x080032a8, 0x080032b8, 0x080032c8, 0x08003358, 0x08003298, 0x080032d8,
-       0x080032e8, 0x08003300, 0x08003320, 0x08003358, 0x08003338, 0x08003338,
-       0x080050d4, 0x080050d4, 0x080050d4, 0x080050d4, 0x080050d4, 0x080050fc,
-       0x080050fc, 0x08005124, 0x08005174, 0x08005144, 0x00000000 };
+       0x0800069c, 0x080008bc, 0x08000800, 0x08000828, 0x08000850, 0x08000878,
+       0x080006d4, 0x080006c0, 0x080008e4, 0x080008e4, 0x080006f0, 0x0800070c,
+       0x0800070c, 0x080008e4, 0x08000724, 0x08000738, 0x080008e4, 0x0800074c,
+       0x080008e4, 0x080008e4, 0x08000760, 0x080008e4, 0x080008e4, 0x080008e4,
+       0x080008e4, 0x080008e4, 0x080008e4, 0x080008e4, 0x080008e4, 0x080008e4,
+       0x080008e4, 0x08000774, 0x080008e4, 0x08000788, 0x0800079c, 0x080007b0,
+       0x080008e4, 0x080007c4, 0x080007d8, 0x080007ec, 0x080032e8, 0x08003300,
+       0x08003310, 0x08003320, 0x08003338, 0x08003350, 0x08003360, 0x08003370,
+       0x08003390, 0x080033a0, 0x080033b0, 0x08003440, 0x08003380, 0x080033c0,
+       0x080033d0, 0x080033e8, 0x08003408, 0x08003440, 0x08003420, 0x08003420,
+       0x080051bc, 0x080051bc, 0x080051bc, 0x080051bc, 0x080051bc, 0x080051e4,
+       0x080051e4, 0x0800520c, 0x0800525c, 0x0800522c, 0x00000000 };
 
 static struct fw_info bnx2_cp_fw_09 = {
+       /* Firmware version:  3.7.1 */
        .ver_major                      = 0x3,
-       .ver_minor                      = 0x4,
-       .ver_fix                        = 0x3,
+       .ver_minor                      = 0x7,
+       .ver_fix                        = 0x1,
 
        .start_addr                     = 0x0800006c,
 
        .text_addr                      = 0x08000000,
-       .text_len                       = 0x6ee8,
+       .text_len                       = 0x6fd0,
        .text_index                     = 0x0,
        .gz_text                        = bnx2_CP_b09FwText,
        .gz_text_len                    = sizeof(bnx2_CP_b09FwText),
 
-       .data_addr                      = 0x08007020,
+       .data_addr                      = 0x08007100,
        .data_len                       = 0x0,
        .data_index                     = 0x0,
        .data                           = bnx2_CP_b09FwData,
 
-       .sbss_addr                      = 0x08007024,
-       .sbss_len                       = 0xa1,
+       .sbss_addr                      = 0x08007104,
+       .sbss_len                       = 0xa9,
        .sbss_index                     = 0x0,
 
-       .bss_addr                       = 0x080070d0,
+       .bss_addr                       = 0x080071b0,
        .bss_len                        = 0x3b0,
        .bss_index                      = 0x0,
 
-       .rodata_addr                    = 0x08006ee8,
+       .rodata_addr                    = 0x08006fd0,
        .rodata_len                     = 0x118,
        .rodata_index                   = 0x0,
        .rodata                         = bnx2_CP_b09FwRodata,
 };
 
 static u8 bnx2_RXP_b09FwText[] = {
-/*     0x1f, 0x8b, 0x08, 0x00, 0x0e, 0x34, 0xe7, 0x45, 0x00, 0x03, */
-                                                                   0xec, 0x5c,
-       0x5d, 0x6c, 0x1c, 0xd7, 0x75, 0x3e, 0xf3, 0x43, 0x6a, 0x49, 0xf1, 0x67,
-       0xb8, 0x5c, 0xb1, 0x2b, 0x99, 0x96, 0x77, 0xc9, 0x91, 0xc8, 0x58, 0x8a,
-       0x31, 0xa2, 0x09, 0x5b, 0x48, 0x17, 0xf6, 0x76, 0x76, 0x25, 0xb1, 0xb1,
-       0x03, 0x53, 0xb6, 0x62, 0x07, 0x45, 0x6a, 0xb0, 0x4b, 0xb9, 0x0e, 0x8c,
-       0x06, 0x90, 0xff, 0x52, 0xbf, 0xb0, 0xde, 0x2c, 0xa9, 0x58, 0x4d, 0x17,
-       0x9c, 0xb5, 0x4d, 0x9b, 0x0e, 0x60, 0xb7, 0x0b, 0x92, 0x12, 0xf5, 0xb0,
-       0xd0, 0xb2, 0xa9, 0xdb, 0xea, 0xc1, 0x8e, 0x09, 0x56, 0xb1, 0x53, 0xa0,
-       0x2d, 0x5c, 0x27, 0x69, 0xfc, 0x10, 0x14, 0xaa, 0xec, 0xc4, 0x42, 0xd1,
-       0xa2, 0x02, 0x12, 0xd8, 0x29, 0x22, 0x7b, 0xfa, 0x7d, 0x77, 0x66, 0xc8,
-       0x25, 0x2d, 0xdb, 0x41, 0x1f, 0xfa, 0xd2, 0xbd, 0xc0, 0x62, 0xee, 0xbd,
-       0x73, 0xee, 0xb9, 0xe7, 0x9e, 0xff, 0x73, 0x87, 0xd2, 0x1f, 0x74, 0x48,
-       0xbb, 0x84, 0xad, 0x13, 0xbf, 0xd4, 0x89, 0x27, 0x1e, 0xb9, 0x69, 0xf4,
-       0xa6, 0x9b, 0xd1, 0xbd, 0xd9, 0x30, 0x4c, 0x23, 0x9a, 0x6f, 0xb6, 0x66,
-       0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66,
-       0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66,
-       0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66,
-       0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66,
-       0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66,
-       0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0xfb, 0xff, 0xde,
-       0x0c, 0x11, 0x8b, 0xcf, 0xce, 0xf0, 0x27, 0x31, 0x3d, 0x23, 0x0f, 0xb9,
-       0xb6, 0xc4, 0x8c, 0xcc, 0xd5, 0xa9, 0x49, 0x5b, 0x24, 0x5b, 0xdb, 0x97,
-       0xca, 0xc9, 0x87, 0x7e, 0x31, 0x61, 0x0a, 0xe7, 0xaf, 0xcf, 0x5c, 0xfd,
-       0x8b, 0x57, 0x6f, 0x4d, 0x5f, 0xa9, 0x1a, 0x12, 0xb3, 0x32, 0x33, 0x07,
-       0xac, 0xbd, 0x12, 0xeb, 0xc7, 0x9a, 0x17, 0x87, 0xfe, 0xa9, 0x4b, 0xba,
-       0x22, 0x5c, 0x22, 0x0b, 0xe5, 0xb4, 0x73, 0x18, 0xcf, 0x33, 0xb5, 0x7d,
-       0xce, 0x9a, 0x98, 0xb2, 0x6a, 0x05, 0x3b, 0x96, 0xca, 0x1a, 0xf1, 0x48,
-       0xa9, 0x16, 0x93, 0x8b, 0xea, 0xdf, 0x79, 0x60, 0x4f, 0x9b, 0xfd, 0xf3,
-       0x9a, 0x5b, 0xf7, 0xfd, 0xd3, 0x8e, 0xef, 0xbf, 0x8e, 0xdf, 0x7b, 0x0e,
-       0xc6, 0xde, 0x47, 0x7e, 0xd6, 0x34, 0x44, 0xb7, 0xff, 0x4c, 0x73, 0x17,
-       0x5b, 0xa5, 0x34, 0x2f, 0x32, 0xed, 0xc5, 0xe4, 0x94, 0x57, 0xd4, 0xf2,
-       0xf5, 0xb2, 0x76, 0x68, 0x79, 0x56, 0x3b, 0xbc, 0x7c, 0x4a, 0x3b, 0xb2,
-       0x5c, 0xd1, 0xdc, 0x65, 0x29, 0xea, 0x07, 0x3a, 0x24, 0x6b, 0x9d, 0xd5,
-       0x72, 0xf5, 0x3e, 0xcd, 0x9d, 0xbf, 0xea, 0xbb, 0x4e, 0xda, 0xfa, 0x3d,
-       0x31, 0xb3, 0xdc, 0xcf, 0x2d, 0xfb, 0x18, 0x9b, 0x92, 0x4d, 0xf8, 0xbe,
-       0x9e, 0xf1, 0x9f, 0x74, 0x47, 0x6d, 0x4b, 0xd7, 0x62, 0x52, 0xaa, 0xb7,
-       0x03, 0x6f, 0x87, 0x96, 0x9b, 0x37, 0xb5, 0xbc, 0xe7, 0xbf, 0xe6, 0x3a,
-       0xd2, 0x6f, 0x88, 0xef, 0xcf, 0x38, 0x7b, 0x92, 0xc7, 0xe5, 0x0c, 0xf0,
-       0xd6, 0x80, 0x4f, 0x2c, 0x3d, 0x43, 0xfa, 0x22, 0x9a, 0x8b, 0x5a, 0x6e,
-       0x28, 0xa2, 0x4f, 0x52, 0xa4, 0xbf, 0xb0, 0xa4, 0x83, 0xce, 0xed, 0x52,
-       0xa8, 0x5a, 0x32, 0xb1, 0xb4, 0x15, 0xfe, 0xa2, 0xff, 0xea, 0x50, 0x42,
-       0xfe, 0xb2, 0x9e, 0x3e, 0x55, 0x04, 0x2f, 0x66, 0xbc, 0x94, 0x80, 0xcf,
-       0x59, 0x77, 0xb4, 0x5f, 0x5e, 0xab, 0x27, 0xe5, 0xbb, 0x75, 0x3b, 0x59,
-       0x92, 0x6d, 0x52, 0x48, 0x58, 0xb2, 0x82, 0x35, 0xd3, 0xa0, 0x43, 0xb7,
-       0x6d, 0xab, 0x04, 0xd8, 0x52, 0xfd, 0x27, 0xfc, 0xb7, 0x32, 0xd6, 0xe4,
-       0xa8, 0x5a, 0x53, 0x04, 0xdd, 0x21, 0x2c, 0xcf, 0xa1, 0x60, 0xd5, 0x59,
-       0x02, 0x58, 0x29, 0x4e, 0x8e, 0x62, 0xae, 0xfe, 0x85, 0x50, 0x16, 0xad,
-       0x38, 0x2f, 0x9f, 0xbb, 0x71, 0xbe, 0xdd, 0xe0, 0x89, 0x24, 0x74, 0xd9,
-       0x93, 0x2c, 0x60, 0x66, 0xba, 0xde, 0x81, 0x31, 0x69, 0xf1, 0xfd, 0x23,
-       0x8e, 0x58, 0x25, 0xa7, 0x1b, 0xbc, 0x4b, 0x49, 0xc9, 0xe9, 0xc2, 0x9a,
-       0x16, 0xb1, 0x6c, 0x9e, 0x81, 0x78, 0xdb, 0x30, 0xef, 0x77, 0x1a, 0x19,
-       0xdf, 0x9f, 0x1c, 0x95, 0xae, 0x60, 0x6e, 0x1f, 0x70, 0x98, 0x32, 0x31,
-       0xae, 0x01, 0xee, 0x03, 0xd2, 0x17, 0x8b, 0x67, 0xd8, 0xe7, 0x73, 0x54,
-       0xdc, 0xd9, 0x54, 0xb8, 0x6f, 0x87, 0x94, 0xbc, 0xeb, 0xc3, 0x3e, 0x78,
-       0xed, 0xe1, 0xcc, 0xce, 0x4e, 0x8c, 0xb5, 0x1b, 0x80, 0xc7, 0x29, 0x09,
-       0xf7, 0xd8, 0x21, 0x6b, 0x09, 0xd1, 0x2f, 0x39, 0xbd, 0x21, 0x5c, 0x17,
-       0x68, 0x8d, 0x64, 0xde, 0x2e, 0x33, 0xf3, 0xad, 0x72, 0x72, 0x9e, 0xbc,
-       0x2d, 0x43, 0x16, 0x78, 0xde, 0x52, 0xd4, 0xb2, 0xf5, 0x53, 0xe8, 0x9b,
-       0x32, 0x69, 0xfb, 0xaf, 0xcd, 0x38, 0xb3, 0x5a, 0x6e, 0xf9, 0x8c, 0x96,
-       0x87, 0x0e, 0x1c, 0x5a, 0x3e, 0xaf, 0x1d, 0xae, 0xaf, 0x76, 0x4a, 0x7b,
-       0x1a, 0xda, 0x66, 0xca, 0x49, 0x4f, 0x13, 0xd2, 0xbb, 0x00, 0x7e, 0x65,
-       0x2d, 0x70, 0xde, 0xee, 0xd2, 0x0e, 0x03, 0x57, 0x8b, 0xfd, 0xad, 0x0e,
-       0xe9, 0x32, 0x64, 0x9b, 0x1d, 0xc1, 0xc6, 0xe4, 0x5b, 0xa0, 0x6d, 0xcd,
-       0x49, 0x00, 0x4e, 0xba, 0x83, 0x35, 0x3d, 0x21, 0x3d, 0xd4, 0x25, 0xea,
-       0x91, 0x9e, 0xcd, 0xcf, 0xfd, 0x69, 0x6f, 0x69, 0xff, 0x76, 0xc2, 0xc0,
-       0x3e, 0x52, 0x0f, 0x4d, 0xda, 0x6e, 0x8f, 0x29, 0x45, 0x4b, 0x97, 0xb4,
-       0x95, 0x93, 0x1b, 0x64, 0xc6, 0x11, 0xc9, 0x41, 0xbf, 0x75, 0xdb, 0x04,
-       0x8f, 0x6c, 0xf0, 0x68, 0xcf, 0xa9, 0x41, 0xfd, 0x0e, 0x49, 0xf5, 0x15,
-       0x35, 0x33, 0xe4, 0xe7, 0x82, 0xdc, 0xa6, 0xd6, 0xeb, 0x19, 0x07, 0x3a,
-       0xd9, 0xce, 0x3e, 0xf6, 0x8d, 0xa9, 0x7d, 0x8d, 0x8c, 0x9d, 0x5c, 0x14,
-       0xd1, 0xf4, 0xcc, 0x3e, 0xe0, 0xa3, 0xae, 0x12, 0xee, 0x29, 0xd0, 0x48,
-       0xda, 0xd9, 0xb7, 0xb1, 0x26, 0x26, 0xae, 0xd3, 0xd9, 0x40, 0x27, 0xe8,
-       0x49, 0x90, 0xe7, 0xe4, 0xa1, 0x3a, 0xa7, 0xb6, 0x71, 0xce, 0x5f, 0xfb,
-       0xdb, 0x46, 0x4c, 0x79, 0x5d, 0x9d, 0x97, 0x76, 0x45, 0x38, 0x75, 0x46,
-       0x21, 0x7f, 0xa6, 0x3d, 0xd1, 0x0a, 0x8e, 0xb5, 0x8e, 0x0b, 0x7a, 0xa1,
-       0x1b, 0x99, 0x0e, 0xc9, 0x29, 0xfa, 0x0e, 0x62, 0x2f, 0xda, 0x1b, 0xec,
-       0xc6, 0xe6, 0x59, 0x38, 0x97, 0x81, 0xed, 0xa6, 0x95, 0xfe, 0x14, 0x2a,
-       0xf4, 0x07, 0xa4, 0x6d, 0x35, 0xad, 0x4b, 0x80, 0xaf, 0xf4, 0x6c, 0x37,
-       0x68, 0xe3, 0x18, 0xb6, 0x67, 0xe3, 0xfd, 0x7e, 0xd8, 0xfa, 0xc1, 0x41,
-       0xf0, 0x87, 0x70, 0x76, 0x0a, 0xf2, 0xce, 0xba, 0xd8, 0xd3, 0x75, 0x6e,
-       0x56, 0x3c, 0xe8, 0xc1, 0x79, 0x06, 0x67, 0xc9, 0xaf, 0x76, 0xe8, 0xb3,
-       0x26, 0x05, 0x27, 0x9d, 0xa2, 0xfc, 0x03, 0xda, 0x75, 0xd9, 0x76, 0x4b,
-       0x23, 0xed, 0x91, 0xac, 0xa8, 0x8f, 0xa6, 0xc4, 0x47, 0x08, 0x4b, 0x38,
-       0xc2, 0xa7, 0x0f, 0x8a, 0xfe, 0x6b, 0xdf, 0xda, 0x74, 0x56, 0x5b, 0x06,
-       0x66, 0x41, 0x43, 0xc0, 0x5b, 0xf0, 0xe4, 0xb3, 0x60, 0xc9, 0xd7, 0xad,
-       0xfc, 0x23, 0x6c, 0x23, 0x1c, 0x74, 0xa2, 0x8f, 0x34, 0xac, 0x74, 0x04,
-       0xf6, 0x15, 0xd1, 0x14, 0xc9, 0x46, 0x0b, 0x71, 0x7c, 0xda, 0x39, 0x08,
-       0x0f, 0xbb, 0xf7, 0x60, 0xf7, 0x1e, 0x7c, 0x82, 0x07, 0x9b, 0xf7, 0xe8,
-       0x27, 0x52, 0xf2, 0xea, 0x10, 0xfc, 0xda, 0x86, 0x5f, 0x41, 0x1b, 0x43,
-       0x5f, 0x17, 0x03, 0x7e, 0x65, 0xba, 0xaa, 0xc3, 0x76, 0x61, 0x43, 0x4b,
-       0x9c, 0xb3, 0xf0, 0xcc, 0xe3, 0x69, 0xc3, 0x8f, 0x52, 0xaf, 0x22, 0xff,
-       0x49, 0x3f, 0x93, 0x84, 0x4f, 0xa1, 0xaf, 0xa1, 0x2f, 0x21, 0xac, 0xef,
-       0xe7, 0x1d, 0xae, 0xf5, 0x65, 0xdc, 0xa1, 0x1d, 0x75, 0x88, 0x1e, 0x2f,
-       0x6a, 0x47, 0x87, 0x60, 0x63, 0x37, 0xb6, 0x80, 0x56, 0xda, 0xda, 0x75,
-       0x74, 0x15, 0x68, 0xbf, 0xe8, 0x0c, 0xfe, 0x5d, 0xde, 0x36, 0xc0, 0x28,
-       0xa1, 0x76, 0x05, 0xe3, 0xb6, 0xd0, 0x9f, 0xf0, 0x7d, 0x3a, 0x95, 0x95,
-       0xdd, 0xe1, 0x98, 0xfd, 0x75, 0x7a, 0x1d, 0xfd, 0x96, 0x98, 0x0c, 0x9c,
-       0x09, 0xfc, 0xe0, 0xc0, 0x82, 0x25, 0xf6, 0x99, 0x80, 0xc6, 0x81, 0x73,
-       0x91, 0x3f, 0x6c, 0x01, 0x3e, 0xd0, 0xe7, 0x6d, 0xc4, 0x09, 0x91, 0xf7,
-       0x34, 0x98, 0x0a, 0xe6, 0xb6, 0xf2, 0x82, 0x3e, 0x98, 0xf6, 0x66, 0x35,
-       0xda, 0xdb, 0x01, 0xd8, 0x9b, 0xd3, 0x2a, 0x69, 0xe7, 0xef, 0x60, 0x6f,
-       0x4f, 0x39, 0x1a, 0x78, 0x23, 0x72, 0xa1, 0xdc, 0x01, 0x5b, 0x37, 0x93,
-       0xef, 0xc8, 0x9e, 0xd4, 0xb4, 0x68, 0x72, 0x9a, 0x73, 0x35, 0xcc, 0x29,
-       0xff, 0x1b, 0xd8, 0xf7, 0x45, 0xe3, 0x69, 0xd0, 0xe5, 0xfb, 0xd3, 0xc0,
-       0x59, 0xd8, 0x6f, 0x84, 0xb6, 0x15, 0xcd, 0xa7, 0x10, 0xf3, 0xdc, 0xcf,
-       0x19, 0x52, 0x1c, 0x6e, 0x91, 0xf4, 0xf0, 0x02, 0x70, 0x4f, 0x3a, 0x81,
-       0x1d, 0x53, 0xd7, 0x17, 0x81, 0x7f, 0xc6, 0x1b, 0x82, 0x1e, 0xd3, 0x0e,
-       0x40, 0x17, 0xf0, 0x2f, 0x02, 0xff, 0x4c, 0xbd, 0x45, 0xbe, 0x69, 0x46,
-       0xb1, 0x34, 0x3a, 0x4f, 0x1b, 0xc0, 0xa2, 0x7d, 0x4f, 0xc8, 0x17, 0xbd,
-       0xb8, 0xe6, 0x3e, 0x4b, 0x3f, 0x5b, 0x1a, 0x86, 0x9d, 0x68, 0x25, 0x87,
-       0x7b, 0x1b, 0xb2, 0xb8, 0x0e, 0x23, 0xd9, 0x52, 0x60, 0x83, 0x59, 0x77,
-       0xa8, 0x98, 0x34, 0x94, 0x2f, 0x11, 0x39, 0x5c, 0x36, 0x01, 0xc3, 0x31,
-       0xe7, 0x83, 0xb9, 0xb1, 0x72, 0x1f, 0x7c, 0x23, 0xc7, 0x57, 0xfd, 0x49,
-       0x27, 0x98, 0xfb, 0xdd, 0x72, 0x81, 0x32, 0x62, 0xdc, 0x4e, 0x95, 0x9c,
-       0x7f, 0xf7, 0xa1, 0xbf, 0x9b, 0xd6, 0x5c, 0x1b, 0x4f, 0x7a, 0x2c, 0x8c,
-       0xf5, 0xda, 0x11, 0x5b, 0xef, 0x6b, 0x0d, 0x7d, 0xd8, 0x11, 0x4c, 0x1e,
-       0x2a, 0x97, 0x7a, 0x5b, 0xe5, 0xaa, 0xc1, 0xd8, 0x79, 0x09, 0x46, 0xed,
-       0x96, 0xf7, 0x82, 0x1f, 0xa5, 0x9e, 0x86, 0xb9, 0x58, 0xbe, 0xec, 0xcb,
-       0x9a, 0x13, 0xac, 0xc1, 0xb8, 0x23, 0x57, 0xd6, 0xfb, 0x62, 0xb2, 0x3e,
-       0xb6, 0xb8, 0x66, 0x49, 0xf6, 0x0e, 0x2f, 0x8a, 0x5a, 0xdb, 0x1b, 0xdb,
-       0x58, 0x9b, 0xc8, 0x97, 0x4b, 0x3d, 0x0d, 0xe3, 0x64, 0x0e, 0xb8, 0xf4,
-       0x03, 0xeb, 0x6b, 0xfb, 0x37, 0xd6, 0xee, 0x90, 0x54, 0x0f, 0xd7, 0xeb,
-       0x7d, 0x6d, 0x1b, 0xb8, 0x53, 0x21, 0x3d, 0xbd, 0x6d, 0x1b, 0x38, 0x6c,
-       0xe2, 0x6c, 0x18, 0x0f, 0x13, 0xe7, 0xc0, 0x06, 0xce, 0xfd, 0x9b, 0xe9,
-       0x39, 0x21, 0xf0, 0x41, 0xb1, 0xd6, 0x8c, 0x1c, 0xb8, 0x50, 0x1e, 0x1c,
-       0xff, 0xa2, 0x20, 0xe6, 0xed, 0xdf, 0x16, 0xfa, 0x64, 0xf3, 0x80, 0x0b,
-       0x5e, 0x99, 0x42, 0x1f, 0xa7, 0x49, 0x09, 0x72, 0x7e, 0xa8, 0x26, 0x07,
-       0xd6, 0x6a, 0x12, 0xea, 0x12, 0x75, 0xe2, 0x32, 0x6c, 0x4c, 0x8a, 0xbb,
-       0x32, 0x1d, 0x13, 0x66, 0xc6, 0x82, 0xad, 0xc9, 0x78, 0x09, 0x3e, 0xd9,
-       0xc8, 0xec, 0x79, 0x3b, 0x67, 0x3c, 0xe9, 0x1b, 0x88, 0xdb, 0x39, 0xe9,
-       0x38, 0xe8, 0x8e, 0x62, 0xbe, 0x46, 0xdb, 0x82, 0x5f, 0xa9, 0x13, 0xf7,
-       0x7c, 0xb7, 0x74, 0x21, 0x2e, 0xd6, 0x5e, 0xda, 0x11, 0xd8, 0x8e, 0x98,
-       0x26, 0x7c, 0xed, 0xcc, 0x28, 0xe3, 0x78, 0x6b, 0x0c, 0xf0, 0x13, 0x46,
-       0x66, 0x6c, 0xe7, 0xf1, 0xda, 0x9d, 0x3b, 0x0b, 0xb5, 0xe2, 0xce, 0x42,
-       0xd9, 0xa2, 0x9d, 0xe8, 0xee, 0x28, 0xfa, 0x2a, 0x57, 0x4a, 0xc2, 0x26,
-       0x2e, 0xab, 0x3c, 0xe2, 0xb5, 0x7a, 0x1d, 0xf6, 0x47, 0xfb, 0x16, 0x19,
-       0xf7, 0xb0, 0xc7, 0xc8, 0x87, 0x90, 0x3b, 0x68, 0x83, 0x4f, 0xcb, 0xe2,
-       0xd4, 0xfa, 0xc8, 0xbf, 0x85, 0xf6, 0xc9, 0xfe, 0xfb, 0x7e, 0xe0, 0xef,
-       0xef, 0xe8, 0x0e, 0xe6, 0xde, 0x0a, 0x6d, 0x3a, 0xc2, 0x45, 0x3c, 0xc3,
-       0xda, 0x38, 0x72, 0x92, 0xf1, 0xba, 0xa9, 0xd1, 0x3f, 0xe7, 0x3c, 0xe6,
-       0x12, 0xcc, 0x23, 0xa6, 0x43, 0x3f, 0x27, 0xd9, 0x1c, 0xfc, 0x88, 0x8e,
-       0xdc, 0xa2, 0x00, 0xbb, 0x31, 0x33, 0x57, 0x64, 0x46, 0xf9, 0x48, 0x89,
-       0xb5, 0x64, 0x9e, 0x00, 0xcc, 0x7f, 0xc0, 0xe6, 0xda, 0xba, 0x43, 0x3d,
-       0x0c, 0x7d, 0xbc, 0xf2, 0xbb, 0x80, 0xbd, 0xbc, 0x05, 0xf6, 0xdd, 0x46,
-       0x58, 0xbc, 0xbf, 0xb8, 0xe5, 0xfd, 0x4f, 0x69, 0xbf, 0x78, 0xb7, 0x0a,
-       0x7f, 0xda, 0x1a, 0xda, 0xfe, 0x05, 0x29, 0xc0, 0xb7, 0x9a, 0x36, 0x73,
-       0xc7, 0xdb, 0xb0, 0x16, 0xe3, 0x1a, 0x68, 0x84, 0xbf, 0x40, 0xcc, 0x04,
-       0xbf, 0x11, 0x13, 0x12, 0x37, 0x30, 0x3f, 0xa2, 0x9f, 0x00, 0x2c, 0xfd,
-       0x2f, 0x61, 0x5f, 0xe9, 0x20, 0xcf, 0x0b, 0x35, 0xae, 0xa1, 0xaf, 0x12,
-       0xdf, 0x1d, 0x6d, 0x83, 0x46, 0xf9, 0xaf, 0x19, 0x76, 0x04, 0x1b, 0xe1,
-       0xdd, 0x0a, 0xcb, 0x7c, 0x85, 0xb8, 0xbb, 0xc3, 0x3c, 0x60, 0x4c, 0xb2,
-       0xf5, 0x2c, 0x7e, 0x45, 0x99, 0x7c, 0x16, 0xb9, 0x98, 0xdd, 0x42, 0x5e,
-       0x90, 0x35, 0x56, 0xc0, 0xa3, 0x68, 0xdd, 0x13, 0xbd, 0x9b, 0xc7, 0xf7,
-       0xc5, 0x37, 0x7c, 0x25, 0x2d, 0x4d, 0xb2, 0x88, 0x15, 0xe0, 0x71, 0x6a,
-       0x42, 0xcf, 0x24, 0x24, 0x57, 0x0b, 0xf8, 0x8b, 0x78, 0x0b, 0xff, 0xc8,
-       0x2e, 0x64, 0xb2, 0xee, 0x07, 0x23, 0x99, 0x53, 0xcf, 0xb2, 0x90, 0x4d,
-       0x0a, 0xba, 0x34, 0x86, 0xb5, 0x72, 0x02, 0x38, 0x18, 0x87, 0x1d, 0x3d,
-       0x13, 0x97, 0x82, 0xc5, 0x7c, 0x41, 0xe5, 0x7a, 0x59, 0xfa, 0x01, 0x3d,
-       0xd3, 0x86, 0x39, 0xf6, 0x1f, 0xee, 0x0e, 0x64, 0xdd, 0xc9, 0xf1, 0xb8,
-       0x9e, 0xe9, 0xde, 0x32, 0xff, 0x7a, 0x67, 0x40, 0x9b, 0x1a, 0x63, 0xfe,
-       0x5f, 0xb6, 0x8c, 0xbf, 0x1e, 0xdf, 0x3c, 0x7e, 0x60, 0x67, 0xa4, 0x0f,
-       0x7a, 0xe6, 0x89, 0x90, 0x5e, 0xea, 0xe9, 0x56, 0x5a, 0x7f, 0x13, 0x7d,
-       0x79, 0x0e, 0x38, 0x95, 0x8e, 0xff, 0x06, 0xfa, 0xb2, 0x0e, 0xfb, 0x09,
-       0xfa, 0xd2, 0x48, 0xc3, 0x7a, 0x5d, 0x51, 0xd1, 0x91, 0x93, 0xba, 0xa3,
-       0x7b, 0x90, 0x77, 0xa4, 0x24, 0x5f, 0x07, 0xef, 0xd6, 0xe3, 0xea, 0x3a,
-       0x4c, 0x71, 0x03, 0x26, 0x88, 0x3b, 0xf9, 0xba, 0x8f, 0x3c, 0xae, 0x31,
-       0x06, 0x0f, 0xa3, 0x5f, 0xc4, 0x59, 0x57, 0x64, 0xd2, 0x5b, 0xcb, 0xea,
-       0xf6, 0xa9, 0x20, 0x0f, 0xb5, 0xbf, 0xad, 0xe5, 0x17, 0x99, 0xa3, 0xc6,
-       0xd0, 0x57, 0xf5, 0x07, 0x62, 0xdc, 0x33, 0x5a, 0x76, 0x79, 0x0e, 0xf9,
-       0xe9, 0x12, 0x7e, 0x67, 0xf1, 0xab, 0xe1, 0x17, 0xd5, 0x01, 0x2f, 0xa0,
-       0x8e, 0x50, 0xfe, 0x1e, 0xb1, 0x29, 0xd8, 0xff, 0x67, 0x4b, 0xc8, 0x8f,
-       0xe7, 0x12, 0xf2, 0x94, 0xad, 0xf7, 0xea, 0x81, 0x8f, 0xcb, 0x22, 0xb7,
-       0xb6, 0x2e, 0xcb, 0x97, 0xc2, 0x1c, 0x4d, 0xe4, 0x9d, 0x0a, 0x64, 0xb9,
-       0xff, 0x48, 0xe8, 0x9f, 0xbe, 0xf6, 0xa0, 0xab, 0x7c, 0x79, 0x98, 0x83,
-       0xc1, 0xef, 0x64, 0x15, 0xd4, 0x1b, 0xe0, 0x8f, 0x26, 0xef, 0x41, 0x8f,
-       0xdf, 0xa9, 0xb4, 0x83, 0x1e, 0x5b, 0x0a, 0xc7, 0x90, 0xbb, 0x68, 0x83,
-       0xd6, 0x36, 0xad, 0x1d, 0x79, 0x18, 0xfc, 0x8e, 0x1a, 0x93, 0x67, 0x17,
-       0xa7, 0x16, 0xca, 0x3a, 0x60, 0xc1, 0xf3, 0x51, 0xf4, 0xa1, 0x7f, 0x97,
-       0x2a, 0x5c, 0xa7, 0xcb, 0xbb, 0x15, 0x43, 0x7e, 0x8e, 0xbc, 0xee, 0x3d,
-       0xfb, 0xe2, 0x14, 0x6c, 0xb0, 0x0f, 0xf1, 0x0a, 0xb5, 0xd0, 0x1e, 0xc6,
-       0x8c, 0x01, 0x13, 0xcf, 0x3c, 0x7e, 0x87, 0x91, 0xe7, 0x5d, 0x7b, 0xcd,
-       0x27, 0xc1, 0x93, 0xb6, 0x18, 0xd6, 0x10, 0xde, 0x04, 0x6d, 0x5d, 0xd0,
-       0xc1, 0xb4, 0x35, 0x21, 0xdd, 0x96, 0xca, 0x9d, 0x34, 0xce, 0x07, 0x7e,
-       0xf2, 0xe3, 0xf3, 0xe4, 0xb3, 0x01, 0x1d, 0xe2, 0x98, 0xef, 0xe8, 0xcf,
-       0x89, 0x2f, 0x7d, 0x30, 0x8b, 0xc3, 0x5c, 0xaa, 0x04, 0xfd, 0x68, 0x4e,
-       0xb4, 0x28, 0xa6, 0xd2, 0x4f, 0xe7, 0x61, 0xab, 0x1c, 0x8f, 0x8b, 0x92,
-       0xc1, 0x26, 0x79, 0x52, 0x8f, 0x56, 0xa7, 0x66, 0x6c, 0xca, 0xd5, 0x92,
-       0xe9, 0x72, 0x24, 0x57, 0xca, 0x08, 0x75, 0x66, 0xe5, 0xdb, 0x90, 0xab,
-       0x1e, 0xd6, 0x20, 0xf0, 0x03, 0x73, 0x94, 0x2f, 0xea, 0xc4, 0x0a, 0xf2,
-       0xb0, 0x8a, 0xc4, 0x83, 0x1a, 0xea, 0x19, 0xd4, 0x1d, 0x90, 0x5f, 0x79,
-       0x0e, 0x38, 0x12, 0x78, 0x2e, 0xe1, 0x99, 0xc4, 0xf3, 0x2c, 0x9e, 0xfd,
-       0x78, 0xd6, 0x68, 0x1f, 0x61, 0xde, 0xf3, 0x31, 0x7a, 0x60, 0x27, 0x79,
-       0xda, 0xb4, 0x7c, 0xaf, 0x9e, 0x91, 0xbf, 0xad, 0x1f, 0x94, 0xbf, 0xa9,
-       0x8f, 0xca, 0x5f, 0xd7, 0x1d, 0x79, 0xb9, 0xbe, 0x5f, 0xfe, 0xaa, 0x3e,
-       0xcc, 0x9a, 0x10, 0x39, 0x5c, 0x0a, 0xbe, 0xf9, 0xbc, 0x3c, 0xe8, 0xd5,
-       0xe1, 0x73, 0x28, 0xff, 0x8b, 0x53, 0xd9, 0xda, 0x75, 0x52, 0x78, 0xd6,
-       0x42, 0x9e, 0x69, 0xb0, 0x2e, 0x93, 0xc7, 0x9c, 0x3b, 0xe2, 0x94, 0xbd,
-       0x6e, 0xb3, 0x4e, 0x39, 0x49, 0x38, 0xd4, 0xbb, 0x1a, 0xf2, 0x97, 0x16,
-       0x99, 0x48, 0xa4, 0x57, 0x5c, 0x23, 0x19, 0xfa, 0xa3, 0x3b, 0x01, 0x87,
-       0x3d, 0xbd, 0x0e, 0x59, 0x7b, 0x1e, 0xb6, 0xe0, 0xa0, 0x56, 0x4e, 0xc4,
-       0xe0, 0xfb, 0x54, 0x7e, 0xa2, 0x7c, 0x4b, 0xe0, 0x4b, 0xa3, 0x9a, 0x91,
-       0x73, 0xd9, 0x70, 0x8e, 0xf1, 0xd1, 0x02, 0xec, 0x72, 0x18, 0x43, 0xb6,
-       0xe2, 0xa4, 0x6f, 0x3c, 0x16, 0xfa, 0xc7, 0x15, 0x39, 0xe1, 0x0d, 0x66,
-       0xaf, 0x20, 0xf6, 0x68, 0x2d, 0x51, 0x5e, 0xb4, 0x0b, 0xb4, 0xf9, 0xfe,
-       0xdd, 0xac, 0xbf, 0xe3, 0xa6, 0xfc, 0x70, 0x36, 0x6d, 0x3d, 0xa2, 0xcf,
-       0x40, 0xce, 0xbe, 0x7f, 0xd4, 0x4e, 0x9f, 0x9a, 0xd0, 0x3b, 0xe5, 0x27,
-       0xcf, 0x30, 0x26, 0xaf, 0x4e, 0x7d, 0x1f, 0x7a, 0x50, 0x5d, 0x6a, 0x95,
-       0x6a, 0xd5, 0x94, 0x4b, 0x23, 0x83, 0x6a, 0xdf, 0x6a, 0x2d, 0x8e, 0x3c,
-       0xaf, 0x4d, 0xa6, 0xfb, 0x94, 0xb2, 0xc3, 0x6f, 0x0f, 0x2b, 0xbf, 0xed,
-       0xda, 0x78, 0xd6, 0x92, 0xd6, 0x66, 0x5a, 0x5e, 0x96, 0x82, 0x07, 0x1d,
-       0x8b, 0xef, 0x02, 0x4f, 0xd8, 0x1f, 0xb4, 0x0a, 0x3a, 0x62, 0xa0, 0x39,
-       0x68, 0x3d, 0xa8, 0xff, 0xd2, 0xff, 0x1d, 0x93, 0x7c, 0x7c, 0x1b, 0xb1,
-       0x85, 0xb1, 0x52, 0x53, 0x7a, 0xb7, 0xb0, 0xf4, 0x53, 0x8b, 0xfe, 0x65,
-       0xa5, 0xb6, 0x2b, 0x1c, 0xd3, 0xbf, 0x73, 0xdc, 0x2e, 0x2f, 0x57, 0xb7,
-       0xcb, 0x62, 0x95, 0xef, 0x5b, 0x65, 0xa1, 0x3a, 0x78, 0xa5, 0x57, 0xef,
-       0x93, 0xd5, 0xeb, 0x6e, 0xb4, 0xee, 0xd7, 0xc1, 0x93, 0x63, 0x1f, 0xc9,
-       0x07, 0x23, 0xdd, 0xf2, 0xd6, 0x7d, 0xe9, 0x17, 0xfe, 0x44, 0x87, 0x3e,
-       0x8e, 0x74, 0xd0, 0xce, 0xd0, 0xe7, 0x7c, 0xfa, 0x4a, 0x56, 0xa7, 0x9e,
-       0xfd, 0x00, 0xfa, 0x95, 0xae, 0x04, 0x3a, 0x49, 0xdc, 0xc4, 0x0b, 0xf9,
-       0xd8, 0x6f, 0x00, 0x27, 0xde, 0xd5, 0x06, 0x81, 0xeb, 0x0d, 0xc5, 0x8b,
-       0xbb, 0x9d, 0xf4, 0x15, 0x84, 0x28, 0xff, 0x92, 0x3d, 0x38, 0x3c, 0xa0,
-       0xef, 0x92, 0x6a, 0xf2, 0x46, 0xeb, 0xbb, 0x88, 0x07, 0xd9, 0x44, 0xfa,
-       0xd4, 0x45, 0x59, 0x9d, 0xba, 0x60, 0x53, 0x17, 0x69, 0xc3, 0xff, 0x80,
-       0x9c, 0xd4, 0x92, 0x4a, 0x8d, 0xbe, 0x8b, 0xb8, 0x58, 0x17, 0xec, 0xb5,
-       0x4e, 0x80, 0x06, 0x77, 0x3f, 0xde, 0x61, 0xde, 0xf8, 0x3c, 0xe5, 0xd6,
-       0xc2, 0xb5, 0xc3, 0x59, 0xbd, 0x7f, 0x0b, 0x8f, 0x06, 0xad, 0x43, 0x3a,
-       0xf7, 0xfb, 0x2f, 0xec, 0xfb, 0x3e, 0x68, 0x1d, 0xc4, 0x5a, 0xc4, 0xd0,
-       0x64, 0xe3, 0x1e, 0x3f, 0x52, 0x7b, 0x3c, 0x5b, 0x43, 0x0e, 0xb8, 0xbe,
-       0x07, 0xe6, 0x6a, 0x3a, 0xce, 0x69, 0x2a, 0xb9, 0x5c, 0x1a, 0x21, 0x7f,
-       0x6f, 0xef, 0x61, 0x2c, 0x37, 0x32, 0x2f, 0x85, 0x79, 0x46, 0x4c, 0x7e,
-       0x8c, 0xba, 0x6b, 0x12, 0xfe, 0x7f, 0x61, 0xef, 0x20, 0x68, 0x40, 0x7d,
-       0x9a, 0x54, 0xf1, 0x7c, 0xca, 0x05, 0x8e, 0x9c, 0xc2, 0xfd, 0xa6, 0x2c,
-       0x01, 0xf7, 0x38, 0xf9, 0x00, 0xdc, 0x33, 0x9c, 0x57, 0x32, 0xc0, 0x7c,
-       0x2d, 0x05, 0xbc, 0xbd, 0xa1, 0xff, 0x8b, 0x43, 0x57, 0xf7, 0x59, 0x77,
-       0x4b, 0x2c, 0xf4, 0x7f, 0x71, 0x79, 0xeb, 0x79, 0xe8, 0x7d, 0x9c, 0xfa,
-       0x93, 0xe8, 0xd9, 0xd0, 0x9f, 0x46, 0xfc, 0xad, 0x92, 0xaf, 0xc4, 0x80,
-       0x17, 0x39, 0xf7, 0x28, 0xf1, 0x62, 0x5c, 0xa5, 0x2e, 0x17, 0x43, 0x5d,
-       0xee, 0x08, 0x71, 0xaf, 0x41, 0x97, 0xd3, 0xa9, 0x55, 0x9d, 0xf5, 0xd5,
-       0x4e, 0x55, 0xf3, 0x1a, 0xb0, 0xaf, 0x42, 0x99, 0xb1, 0x88, 0xb6, 0x75,
-       0x71, 0x6a, 0x12, 0x35, 0x6c, 0xa1, 0x7c, 0x50, 0x2f, 0xd4, 0x47, 0xf5,
-       0x82, 0x47, 0x7d, 0xdb, 0x6b, 0x2d, 0x28, 0x1e, 0x27, 0x65, 0xa1, 0xfe,
-       0x81, 0x5f, 0xda, 0xbb, 0x0d, 0x7d, 0xe8, 0xfe, 0x38, 0xe5, 0x7b, 0x3d,
-       0xe9, 0x42, 0x50, 0x27, 0xbf, 0x13, 0x72, 0x66, 0xe8, 0x7b, 0xdd, 0xcc,
-       0xd1, 0x96, 0x87, 0x88, 0x1f, 0x74, 0x24, 0x12, 0xb2, 0xe8, 0x71, 0x8f,
-       0xd5, 0x29, 0xf2, 0xb2, 0x30, 0x67, 0xc9, 0x09, 0x25, 0x3f, 0x9e, 0x9b,
-       0xf7, 0x47, 0x86, 0x4c, 0xc6, 0x07, 0xad, 0x47, 0x25, 0x7d, 0x65, 0xcd,
-       0x48, 0xbf, 0x30, 0x81, 0xb8, 0xba, 0x30, 0x6f, 0x88, 0xab, 0xea, 0x30,
-       0xca, 0x28, 0x5d, 0x81, 0x35, 0x86, 0x67, 0xbf, 0xa7, 0xe1, 0xec, 0x5d,
-       0x72, 0xe1, 0xf9, 0xcf, 0xc3, 0xee, 0x5f, 0x81, 0x2c, 0xcc, 0xd4, 0x71,
-       0xe4, 0x19, 0xcf, 0xc9, 0xa0, 0x55, 0x42, 0xfe, 0x0c, 0xbe, 0xa3, 0xbd,
-       0xa2, 0x6c, 0x60, 0x41, 0xc7, 0xb8, 0x9f, 0x7c, 0xe2, 0x78, 0xb7, 0x2c,
-       0xf4, 0x05, 0x36, 0xce, 0x77, 0x03, 0xc0, 0x11, 0xbc, 0xe3, 0xf8, 0xb7,
-       0x64, 0x40, 0xbd, 0xab, 0xaa, 0x75, 0x25, 0xe9, 0x0d, 0xe5, 0xf7, 0x18,
-       0xf6, 0x24, 0x8f, 0xa3, 0xf9, 0x4e, 0x09, 0x6c, 0x29, 0xe2, 0xbb, 0x25,
-       0x47, 0x6b, 0x09, 0xb9, 0xa7, 0x96, 0x94, 0x2f, 0xd7, 0xfa, 0x25, 0x0f,
-       0x39, 0x4e, 0x8e, 0x3e, 0xd9, 0xc3, 0xb3, 0xe5, 0x96, 0xd2, 0x2f, 0x88,
-       0x4e, 0x5a, 0xab, 0x72, 0xdc, 0x8b, 0xe8, 0xe9, 0x08, 0xe9, 0x33, 0xc3,
-       0x71, 0x2c, 0xa4, 0xa1, 0x11, 0x5f, 0x07, 0x70, 0x65, 0x81, 0xe7, 0xa5,
-       0x10, 0x0f, 0xfd, 0x08, 0x68, 0x3d, 0x96, 0x94, 0x25, 0x8f, 0x74, 0x6c,
-       0x97, 0x52, 0x82, 0xfd, 0x57, 0xa0, 0x6f, 0xc4, 0xb3, 0x8d, 0xf9, 0xcd,
-       0x26, 0x1e, 0x3f, 0x5c, 0x2b, 0x82, 0xc7, 0xe4, 0x2f, 0xe1, 0xe0, 0xaf,
-       0xbf, 0x40, 0xf9, 0xed, 0x43, 0x8e, 0x6f, 0x07, 0xba, 0x69, 0x6d, 0xec,
-       0x99, 0x9f, 0xeb, 0x82, 0xac, 0xb8, 0x6f, 0xbb, 0x1c, 0x83, 0xdd, 0xe7,
-       0xaa, 0xdc, 0xff, 0x18, 0xf4, 0xe8, 0x2d, 0xb5, 0x7f, 0x7e, 0xa9, 0x2f,
-       0x5c, 0xcf, 0xb5, 0x5d, 0x5b, 0xd6, 0xb6, 0xca, 0xa1, 0x8a, 0x75, 0x8d,
-       0xf5, 0xbf, 0x8f, 0xf5, 0xba, 0x9c, 0x1e, 0xe5, 0x7a, 0xe2, 0x01, 0x5c,
-       0x35, 0xf1, 0x29, 0x78, 0xe2, 0xaa, 0xde, 0xcf, 0x55, 0x5b, 0x25, 0x57,
-       0x89, 0x70, 0x11, 0xcf, 0x47, 0xa8, 0x87, 0xbf, 0xaa, 0x70, 0x4d, 0x2a,
-       0x5c, 0x78, 0x5f, 0xa5, 0xcf, 0xb9, 0x15, 0xeb, 0x3b, 0xe8, 0xff, 0xa5,
-       0x14, 0xef, 0x94, 0x92, 0xaa, 0xe9, 0xdb, 0x95, 0xaf, 0x29, 0xc5, 0xdb,
-       0xf0, 0xbe, 0x13, 0x36, 0xbf, 0x0f, 0xb9, 0x45, 0x17, 0xeb, 0xdc, 0x2d,
-       0x73, 0x5b, 0xe9, 0x8f, 0x6d, 0xa1, 0x3f, 0x06, 0xb8, 0x5e, 0xec, 0x19,
-       0xc0, 0xe5, 0x01, 0x37, 0x3d, 0x07, 0x3e, 0x3b, 0xf4, 0x2b, 0x8c, 0x93,
-       0xd7, 0x29, 0x5a, 0xa6, 0x97, 0xfe, 0x1b, 0xe7, 0xea, 0xc3, 0xda, 0x68,
-       0x1c, 0xf0, 0xe1, 0x69, 0xe0, 0x99, 0xab, 0xaa, 0xbb, 0x0b, 0xc8, 0x60,
-       0x7b, 0x9c, 0x67, 0x2f, 0x55, 0x3f, 0x8b, 0x67, 0xd7, 0x35, 0xf0, 0x8b,
-       0xbc, 0x22, 0xbd, 0xa4, 0x95, 0xf7, 0x48, 0xb0, 0x37, 0x07, 0x7a, 0x1c,
-       0x37, 0x24, 0x3f, 0x6a, 0x21, 0x3f, 0xe7, 0x3d, 0x2c, 0xed, 0xd2, 0xe2,
-       0xdd, 0x67, 0x4c, 0xb7, 0x19, 0x6b, 0x4d, 0x75, 0xf6, 0xe3, 0x4b, 0xbc,
-       0x8b, 0x4d, 0xf1, 0xee, 0x6e, 0x98, 0xd7, 0x18, 0x8f, 0x2c, 0xd9, 0xf2,
-       0x78, 0x6d, 0x58, 0x1e, 0xad, 0xa5, 0xad, 0xfb, 0xe1, 0x03, 0x0a, 0xeb,
-       0x77, 0xb4, 0x43, 0x71, 0xfa, 0x2f, 0x13, 0x79, 0x60, 0x8b, 0x1d, 0xe4,
-       0x05, 0x25, 0xd6, 0x6c, 0x73, 0x69, 0xde, 0xe3, 0x58, 0x55, 0xd9, 0x9a,
-       0x3b, 0xfc, 0x5f, 0xe6, 0x0d, 0xdc, 0x9f, 0xfe, 0x1a, 0x79, 0x82, 0x87,
-       0x3c, 0xc1, 0x43, 0x9e, 0xe0, 0x21, 0x4f, 0xf0, 0x90, 0x27, 0x78, 0xc8,
-       0x13, 0x3c, 0xe4, 0x09, 0x1e, 0xf2, 0x04, 0xc4, 0xee, 0xa0, 0x5e, 0x18,
-       0x43, 0xfe, 0x0b, 0xff, 0xe5, 0xdd, 0x06, 0x3e, 0xf1, 0xfe, 0x92, 0x31,
-       0x87, 0xb1, 0x99, 0x73, 0xab, 0xdb, 0x5c, 0xca, 0x4d, 0xf9, 0xbe, 0x3b,
-       0x31, 0x37, 0x1e, 0xe6, 0x23, 0x84, 0x89, 0x62, 0x37, 0xe1, 0xe4, 0xa0,
-       0xeb, 0x68, 0xb0, 0x31, 0xe6, 0x2b, 0x41, 0xcc, 0x0a, 0x72, 0xe5, 0xb7,
-       0x91, 0xb3, 0xa4, 0x90, 0xb3, 0xf4, 0x23, 0x3f, 0xe1, 0x9d, 0x75, 0x74,
-       0xc7, 0x94, 0xd5, 0x8e, 0x7a, 0x63, 0xda, 0x3d, 0x1e, 0x73, 0x69, 0x3b,
-       0x55, 0xd0, 0xf5, 0xb9, 0x5e, 0xf1, 0x25, 0x37, 0xf2, 0x4d, 0xe4, 0xad,
-       0xcf, 0xa9, 0xfb, 0xb4, 0xf1, 0x21, 0xca, 0xbc, 0xf2, 0x09, 0xb9, 0x6b,
-       0xc4, 0xdf, 0xe0, 0x1e, 0x50, 0x5f, 0x20, 0xff, 0x44, 0x7a, 0xce, 0x81,
-       0xe1, 0xe7, 0x62, 0x12, 0x3f, 0xb3, 0x1d, 0x73, 0x96, 0xf4, 0xaa, 0xbb,
-       0x24, 0x88, 0xf2, 0xdc, 0x55, 0xc8, 0xcb, 0x16, 0xfd, 0x1c, 0x6f, 0x1c,
-       0x88, 0x97, 0xfe, 0x75, 0x65, 0x2a, 0x57, 0x5d, 0x51, 0x3a, 0x75, 0xb4,
-       0x96, 0x47, 0x7d, 0xd4, 0xd3, 0x2b, 0xed, 0x26, 0x6a, 0xab, 0x08, 0x37,
-       0x71, 0xfe, 0x32, 0xae, 0x6a, 0x9e, 0x73, 0xeb, 0xf2, 0x84, 0xac, 0xb9,
-       0xcf, 0xca, 0x54, 0xa9, 0x92, 0x4e, 0xb2, 0x56, 0xce, 0x5a, 0x2b, 0x53,
-       0x27, 0x81, 0x63, 0x11, 0xb9, 0x81, 0xa1, 0xf6, 0x5e, 0x99, 0x9a, 0xae,
-       0x04, 0xf7, 0x59, 0x01, 0x0d, 0x8c, 0x57, 0xed, 0x62, 0x2c, 0x04, 0xf7,
-       0x5a, 0xba, 0x5a, 0xcb, 0x75, 0x5c, 0x6f, 0x62, 0x1d, 0xe5, 0x36, 0x8c,
-       0xb5, 0x94, 0x1d, 0x69, 0x58, 0x99, 0x2a, 0x56, 0x1b, 0x69, 0x20, 0x1e,
-       0xe2, 0x8d, 0xce, 0xc3, 0xb3, 0xc4, 0x45, 0x3f, 0xe3, 0xfb, 0x85, 0x91,
-       0xfe, 0x30, 0xef, 0x3a, 0x89, 0xfc, 0xce, 0x0c, 0xf4, 0x5c, 0x8d, 0xbf,
-       0xa3, 0xe2, 0x54, 0x4a, 0xe7, 0x3c, 0x9f, 0x78, 0x37, 0xba, 0x80, 0x39,
-       0x8c, 0x17, 0x23, 0x58, 0x3d, 0x84, 0xed, 0x6c, 0xe0, 0x67, 0x4b, 0xb8,
-       0x1f, 0x69, 0xe2, 0x39, 0x2f, 0x61, 0x2f, 0xd2, 0x45, 0x98, 0x38, 0x68,
-       0x83, 0x2c, 0xbd, 0xff, 0x2d, 0xef, 0x1b, 0xcf, 0x44, 0x9e, 0x9a, 0x58,
-       0x43, 0x78, 0xe2, 0x88, 0xd6, 0xe0, 0xc5, 0xb9, 0x60, 0x9d, 0xbe, 0x7e,
-       0xff, 0xf7, 0x69, 0xfb, 0x36, 0xd2, 0x1a, 0xed, 0x1f, 0xe1, 0x19, 0x0e,
-       0xe4, 0xb6, 0xbe, 0x5e, 0xfd, 0x9f, 0x61, 0x78, 0x42, 0x17, 0x3f, 0x76,
-       0x8f, 0x3a, 0xdc, 0x50, 0x87, 0x46, 0xf7, 0x17, 0xbc, 0x0f, 0x60, 0x7d,
-       0xcf, 0x6f, 0x07, 0x8d, 0xb5, 0xe2, 0xcb, 0x61, 0x2c, 0xdb, 0x29, 0x59,
-       0x93, 0x75, 0xc3, 0xf9, 0x70, 0xbc, 0x03, 0xb1, 0x8d, 0xe3, 0x3a, 0xf8,
-       0x0b, 0x5d, 0x76, 0xda, 0xc3, 0xba, 0x25, 0x1e, 0x7c, 0xe3, 0x19, 0xa6,
-       0x1d, 0xb1, 0xee, 0x6b, 0x0b, 0xe7, 0x22, 0x3b, 0xa2, 0x1f, 0x36, 0xc3,
-       0x39, 0xfa, 0x5b, 0x1d, 0xb5, 0x0b, 0xfb, 0xc0, 0xb3, 0xd8, 0x68, 0x4b,
-       0xd1, 0x33, 0x2e, 0x67, 0xe7, 0x23, 0xbf, 0x05, 0x9f, 0x32, 0x64, 0x86,
-       0xbe, 0xbf, 0x03, 0xbe, 0xaf, 0x4b, 0x0e, 0xc1, 0x67, 0x1d, 0x86, 0xcf,
-       0x3a, 0x82, 0x7a, 0x71, 0x6c, 0xa9, 0xf1, 0x9e, 0x97, 0x35, 0x6a, 0x97,
-       0x76, 0x5c, 0xc9, 0xbf, 0xe8, 0x1b, 0xf6, 0x47, 0xd0, 0x01, 0xd6, 0x5d,
-       0x91, 0x4e, 0xc0, 0xdf, 0x3a, 0x71, 0xe8, 0xc4, 0xd6, 0xfb, 0xe4, 0x61,
-       0xd8, 0x46, 0x7b, 0x56, 0xc5, 0x86, 0xa5, 0x80, 0xf7, 0xa5, 0x6a, 0xc0,
-       0x7b, 0xf8, 0x65, 0xe0, 0x37, 0xa5, 0x58, 0xb3, 0xa4, 0x88, 0x7d, 0x8b,
-       0xd8, 0xb7, 0x88, 0x3a, 0x6f, 0xba, 0xd6, 0xf8, 0x1d, 0xab, 0x33, 0xa4,
-       0x9d, 0x6b, 0xa3, 0xbe, 0xd5, 0x70, 0xfe, 0xe8, 0x79, 0x0a, 0xfc, 0x7f,
-       0x0c, 0xfc, 0x3f, 0x81, 0xfa, 0xe6, 0x8f, 0x50, 0xdf, 0x7c, 0x0d, 0xf5,
-       0xcd, 0x71, 0xd4, 0x37, 0x13, 0xa8, 0x6f, 0xbe, 0x0a, 0xff, 0xf1, 0x15,
-       0xf8, 0x8f, 0x63, 0xf0, 0x1f, 0xe3, 0xea, 0xee, 0xe9, 0xa8, 0xb7, 0xf5,
-       0x4e, 0x25, 0xda, 0x8b, 0xed, 0x67, 0x22, 0x76, 0x11, 0x67, 0x1a, 0x93,
-       0x6a, 0x9d, 0xf5, 0x8d, 0x23, 0xee, 0x41, 0xd6, 0x37, 0xc7, 0xb4, 0x09,
-       0xe4, 0xef, 0xf7, 0xef, 0x67, 0xdd, 0x13, 0xd7, 0x72, 0xaa, 0xee, 0x49,
-       0x9f, 0x77, 0x91, 0x22, 0x21, 0xf7, 0xc3, 0x99, 0xd3, 0x67, 0x73, 0xa0,
-       0x25, 0xc8, 0xf9, 0x7a, 0x42, 0xbf, 0xd7, 0x21, 0x8b, 0xb3, 0xa8, 0x19,
-       0xbc, 0x1f, 0x6b, 0x05, 0xe5, 0x1b, 0x2d, 0x8c, 0x51, 0x2b, 0x7b, 0xff,
-       0x1c, 0x8e, 0x47, 0x64, 0x72, 0x1e, 0xb5, 0xed, 0xf3, 0xff, 0xa8, 0xe5,
-       0xd4, 0xd8, 0xc1, 0x18, 0xf9, 0xee, 0xf3, 0x7f, 0x1f, 0x8e, 0x8b, 0xa1,
-       0x3e, 0x84, 0xb4, 0x5a, 0x0e, 0x9e, 0xdd, 0x61, 0xce, 0xf1, 0x6a, 0xef,
-       0xe6, 0xff, 0xd3, 0x8e, 0xad, 0x45, 0x13, 0xfb, 0x1b, 0x3b, 0x82, 0xfa,
-       0xac, 0x71, 0xbe, 0xab, 0x61, 0xfe, 0x8a, 0xfa, 0xce, 0x5a, 0x28, 0xb7,
-       0xfd, 0x0a, 0x1e, 0x58, 0x96, 0x86, 0x98, 0xe7, 0x7d, 0xe4, 0xf3, 0xfb,
-       0x9f, 0xab, 0xb7, 0xab, 0x6f, 0x72, 0xae, 0xca, 0xb7, 0x61, 0xe7, 0x23,
-       0xa5, 0x1d, 0x81, 0x2f, 0x60, 0x3f, 0xa1, 0x05, 0xfe, 0xfd, 0x8f, 0x81,
-       0x07, 0xbc, 0xf6, 0x1a, 0x6b, 0x38, 0x2b, 0xbc, 0x4b, 0xb9, 0x32, 0xc5,
-       0xdc, 0xba, 0xa4, 0x70, 0xb3, 0xd6, 0x63, 0xdd, 0x17, 0xc5, 0x80, 0x08,
-       0xd7, 0xcf, 0x13, 0x01, 0xdd, 0xe3, 0xa8, 0xe9, 0x08, 0x13, 0x8d, 0x1b,
-       0xeb, 0xbf, 0x8e, 0xf0, 0x1e, 0xee, 0x4a, 0x90, 0x57, 0x29, 0x7c, 0x66,
-       0x88, 0xef, 0x3f, 0xfd, 0xc0, 0xf7, 0x70, 0xbd, 0xd5, 0xb0, 0xfe, 0x3c,
-       0x72, 0x3d, 0xde, 0x99, 0xec, 0x52, 0xdf, 0x19, 0xdf, 0x9f, 0xed, 0x94,
-       0x5f, 0x3c, 0xe3, 0xfb, 0xe3, 0x4e, 0x7a, 0xf8, 0x4d, 0xd4, 0x1e, 0x67,
-       0x68, 0x27, 0x23, 0xa4, 0x73, 0x30, 0x35, 0x2d, 0x03, 0xbd, 0x41, 0x2e,
-       0xfe, 0x75, 0xed, 0xe3, 0x74, 0xeb, 0xe1, 0x3e, 0x3f, 0x6c, 0xd8, 0x27,
-       0xd5, 0xb0, 0xcf, 0x0a, 0x6d, 0xb6, 0x7a, 0x2f, 0xce, 0x5c, 0xdc, 0x75,
-       0xa3, 0x95, 0x08, 0xeb, 0xb2, 0x47, 0x47, 0xda, 0xa4, 0xd2, 0x97, 0x5e,
-       0xf9, 0x11, 0xf2, 0xf5, 0xc2, 0x08, 0xe6, 0x12, 0x83, 0x78, 0xc7, 0xf9,
-       0x74, 0x15, 0xb9, 0xe8, 0x4a, 0x55, 0x86, 0xb0, 0x3e, 0x5d, 0x14, 0xe1,
-       0x3c, 0xfb, 0x8a, 0xb6, 0x6a, 0xe8, 0x03, 0x92, 0x6b, 0x38, 0xf3, 0x04,
-       0xea, 0xaf, 0x13, 0xeb, 0xf5, 0x30, 0xf7, 0xb9, 0x59, 0x5b, 0x53, 0xb9,
-       0xf1, 0x01, 0xad, 0x98, 0x08, 0xce, 0xf8, 0x87, 0xf0, 0x17, 0x86, 0xce,
-       0xb5, 0xef, 0x03, 0xb7, 0x26, 0x0b, 0xcf, 0x18, 0xea, 0x0e, 0xb6, 0x30,
-       0x42, 0x59, 0xf3, 0x79, 0x2d, 0xde, 0x45, 0x67, 0xfa, 0xf3, 0xf0, 0x4c,
-       0xd9, 0xb0, 0x9e, 0x8e, 0xce, 0x14, 0x93, 0x77, 0x67, 0x2d, 0xac, 0xfd,
-       0x1c, 0xf8, 0x91, 0x97, 0xa5, 0x7a, 0xea, 0x33, 0xf0, 0x94, 0x1b, 0x78,
-       0x63, 0x6e, 0x91, 0x61, 0x71, 0xa3, 0x86, 0x1f, 0x4f, 0xc2, 0x0e, 0xbf,
-       0xd1, 0x1b, 0xdd, 0x0d, 0x1b, 0xb6, 0xcf, 0xba, 0x07, 0x8d, 0xf3, 0xfd,
-       0xb0, 0xc5, 0x14, 0xec, 0x93, 0x39, 0x53, 0x9e, 0xb5, 0x0a, 0xed, 0xc9,
-       0x72, 0x8d, 0xb4, 0x75, 0x4c, 0x86, 0x51, 0xef, 0xf0, 0xfc, 0x19, 0x59,
-       0xac, 0x47, 0x34, 0x8c, 0xc2, 0x1e, 0x0f, 0xe2, 0xb7, 0x1f, 0xef, 0x1c,
-       0xfc, 0x58, 0x2b, 0xad, 0xc8, 0xe3, 0x2a, 0x17, 0x47, 0xae, 0x3d, 0x44,
-       0xfa, 0xee, 0x04, 0x3c, 0xf5, 0x99, 0x7a, 0x7a, 0xa7, 0xb8, 0x7d, 0xf4,
-       0x15, 0x49, 0xe0, 0xc6, 0x1a, 0xef, 0x22, 0x6c, 0xbd, 0x1f, 0xcf, 0xb4,
-       0x55, 0x20, 0x6f, 0x15, 0x7e, 0xdf, 0x37, 0x46, 0xf9, 0x8d, 0xe2, 0x7c,
-       0x38, 0x1e, 0xb4, 0xbe, 0x4c, 0xdd, 0x4b, 0xee, 0x96, 0x95, 0xf9, 0x28,
-       0x0e, 0x9e, 0x86, 0x0d, 0xf2, 0xce, 0x76, 0x0c, 0x7c, 0xe1, 0x58, 0x0b,
-       0xe3, 0x21, 0xe6, 0x17, 0x97, 0x71, 0xee, 0x8c, 0x9c, 0x41, 0xfd, 0x2f,
-       0x7d, 0x7c, 0xa6, 0x80, 0x7f, 0x7b, 0xa8, 0xef, 0x9b, 0xd7, 0x1b, 0x36,
-       0xfb, 0x63, 0xa0, 0xcf, 0x6c, 0x58, 0xcf, 0x35, 0x41, 0x7d, 0xb2, 0x26,
-       0x88, 0xc7, 0x49, 0xff, 0x76, 0x3d, 0xf3, 0xa2, 0x3c, 0xa0, 0xce, 0x54,
-       0x93, 0xe3, 0xf3, 0xbe, 0xef, 0x8e, 0x0e, 0x0e, 0x2f, 0x4a, 0x7a, 0xf8,
-       0xa4, 0xec, 0xb3, 0x0e, 0xb1, 0x1e, 0xb3, 0x88, 0xc7, 0xbf, 0xbd, 0x25,
-       0xe3, 0xfb, 0xa7, 0x41, 0xfb, 0xf7, 0xd5, 0x3e, 0x2f, 0x82, 0x7e, 0xf0,
-       0x4a, 0xd5, 0x24, 0xa4, 0x15, 0xcf, 0x04, 0xe9, 0x2d, 0xcb, 0xf1, 0xfa,
-       0x85, 0x50, 0x36, 0x8f, 0x89, 0xeb, 0x5d, 0x36, 0x5c, 0xbb, 0x0c, 0xd8,
-       0x85, 0x90, 0xb6, 0x0c, 0xe8, 0xc5, 0xfe, 0xf5, 0xb7, 0x13, 0xf4, 0x0d,
-       0x94, 0xb9, 0x8b, 0xac, 0xd1, 0x1d, 0x41, 0x1e, 0x95, 0xf8, 0x24, 0x3f,
-       0x10, 0x97, 0xcd, 0x7e, 0x80, 0xeb, 0xe2, 0xd7, 0xd0, 0x15, 0xd2, 0x51,
-       0x54, 0xfe, 0x53, 0xc5, 0x2d, 0x85, 0xcf, 0xd8, 0xe2, 0x0b, 0x2a, 0xea,
-       0xb9, 0x6a, 0xd0, 0x37, 0x31, 0xfe, 0x51, 0x87, 0xbb, 0xe0, 0xff, 0xa0,
-       0x83, 0xb0, 0xe3, 0xdc, 0x3c, 0xef, 0x27, 0x86, 0x78, 0xaf, 0x74, 0x36,
-       0x0f, 0xd9, 0x2e, 0xf0, 0xfb, 0x63, 0x22, 0xa8, 0x31, 0x83, 0xfa, 0x2b,
-       0x45, 0x5f, 0x88, 0xb6, 0xa4, 0xfc, 0x64, 0x5e, 0x7d, 0x6f, 0x8c, 0x03,
-       0xc6, 0xa7, 0xef, 0x6c, 0xf8, 0x9b, 0x89, 0x1f, 0x64, 0x83, 0xbf, 0x99,
-       0x08, 0xbf, 0xfd, 0x56, 0x83, 0x3c, 0xe2, 0xe1, 0x9a, 0x29, 0x13, 0xb5,
-       0xe8, 0x6f, 0x28, 0x28, 0x07, 0xf8, 0xe6, 0x5a, 0x94, 0x3b, 0xf8, 0x41,
-       0x4d, 0xb3, 0x49, 0x96, 0x4b, 0x61, 0x4e, 0xc4, 0x1a, 0x80, 0x3c, 0xc4,
-       0x78, 0x31, 0xaa, 0x2f, 0x07, 0x20, 0x3f, 0xf0, 0x1c, 0x74, 0xbd, 0x3b,
-       0x1b, 0xd4, 0xb9, 0x25, 0xfa, 0xc5, 0xfe, 0xa8, 0xee, 0xdd, 0x25, 0xa5,
-       0x63, 0x7c, 0x1f, 0x93, 0x77, 0x66, 0x63, 0xea, 0x7d, 0x41, 0x62, 0xe1,
-       0x7b, 0x8e, 0xe3, 0x52, 0x50, 0xef, 0xab, 0x21, 0x3e, 0xd4, 0x69, 0x5f,
-       0x89, 0xc6, 0xa6, 0x76, 0xbc, 0x1e, 0xac, 0x9b, 0xac, 0x57, 0xe5, 0xf1,
-       0xfa, 0x2a, 0xce, 0xaf, 0x49, 0x6e, 0xbc, 0x28, 0xbb, 0x6d, 0x4b, 0xc5,
-       0x7d, 0x37, 0x4e, 0x1d, 0xa3, 0x7e, 0x8d, 0xa9, 0xba, 0xb3, 0x88, 0x7c,
-       0xa1, 0x30, 0xc2, 0x6f, 0x3c, 0xbf, 0xba, 0xab, 0x50, 0x4e, 0x5b, 0x59,
-       0xf9, 0xd0, 0x77, 0x4d, 0x8e, 0x45, 0x47, 0x3d, 0x74, 0xd7, 0xc3, 0xb5,
-       0x0b, 0x77, 0x05, 0x67, 0xc5, 0xfb, 0x1a, 0x61, 0x0d, 0xf5, 0x6d, 0xf6,
-       0x5f, 0x6f, 0x35, 0x65, 0xed, 0x56, 0xdf, 0xbf, 0xdf, 0xb1, 0xc4, 0x0d,
-       0x6b, 0x57, 0x4b, 0xd5, 0xae, 0xed, 0x2a, 0x07, 0x71, 0x47, 0x52, 0x5a,
-       0x1e, 0xf6, 0x7a, 0xc6, 0x43, 0x9d, 0xa3, 0xa7, 0x0f, 0xae, 0xea, 0x16,
-       0x62, 0x6e, 0x3a, 0x35, 0x27, 0x6e, 0x2f, 0xbf, 0x37, 0xcf, 0x38, 0x84,
-       0xd9, 0x19, 0xdc, 0x75, 0xdd, 0x34, 0xae, 0xfc, 0xac, 0x48, 0x18, 0x7b,
-       0x6e, 0x6a, 0xb4, 0x89, 0xc6, 0xdc, 0x92, 0xb6, 0x20, 0x13, 0x26, 0x68,
-       0x29, 0x95, 0xa3, 0x3c, 0x8d, 0x7f, 0x1b, 0xb0, 0x7a, 0xd7, 0xd3, 0xa0,
-       0x73, 0x1a, 0x74, 0xf2, 0x1c, 0xd3, 0xb5, 0x48, 0xe7, 0xa2, 0x5a, 0x81,
-       0x7d, 0xc4, 0x7c, 0x0f, 0x31, 0xdf, 0x43, 0xcc, 0xf7, 0x10, 0xf3, 0x3d,
-       0xc4, 0x7c, 0x0f, 0x31, 0xdf, 0x43, 0xcc, 0xf7, 0x10, 0xf3, 0xbd, 0xf1,
-       0x30, 0x4f, 0x7b, 0x62, 0x3d, 0x4f, 0x5b, 0xa9, 0xf3, 0x3b, 0x94, 0xa2,
-       0xa5, 0x58, 0x94, 0x20, 0xcf, 0x15, 0x9d, 0x39, 0x4d, 0x94, 0xe7, 0x5e,
-       0xfb, 0x9b, 0x48, 0xb0, 0x8e, 0x39, 0x1e, 0xd7, 0x15, 0x35, 0xdd, 0xe6,
-       0xba, 0x20, 0xcf, 0x63, 0x6d, 0xb5, 0x79, 0x0d, 0xf2, 0xb5, 0x0c, 0xfd,
-       0x19, 0xed, 0x22, 0x11, 0xd4, 0x8b, 0x99, 0xf3, 0xf7, 0xba, 0x88, 0xbf,
-       0x85, 0x9a, 0x8a, 0xc1, 0xbc, 0x17, 0xbc, 0x97, 0x7f, 0xb7, 0x00, 0x39,
-       0xf0, 0xdd, 0x7d, 0xac, 0x27, 0x0a, 0xb5, 0xa4, 0x14, 0x17, 0xa3, 0xfc,
-       0x07, 0xeb, 0xbc, 0x7d, 0x5a, 0xbe, 0x42, 0xd9, 0xea, 0x32, 0x9d, 0x00,
-       0x53, 0xec, 0xc6, 0xbc, 0xee, 0x4d, 0x55, 0x23, 0xad, 0xd4, 0x49, 0xcf,
-       0x7e, 0xd0, 0x16, 0xdd, 0xe3, 0x8a, 0x18, 0xb3, 0x09, 0xd1, 0x67, 0x91,
-       0xd3, 0xda, 0x43, 0xea, 0x6f, 0x1d, 0x7a, 0xb0, 0x8f, 0x3e, 0x3b, 0x10,
-       0xfd, 0x2d, 0x06, 0xeb, 0xae, 0xec, 0xc6, 0xfd, 0x2b, 0xcf, 0x91, 0x80,
-       0xbd, 0x7e, 0x69, 0x27, 0xce, 0x06, 0xb9, 0x5e, 0xde, 0xa1, 0xf2, 0x6e,
-       0xf8, 0xce, 0xd3, 0x43, 0xe9, 0x3e, 0xe9, 0xda, 0x25, 0x67, 0x86, 0x58,
-       0xa3, 0xb5, 0x01, 0x1f, 0x61, 0x79, 0xe7, 0xb4, 0x4b, 0x96, 0xe7, 0xe1,
-       0x5b, 0xe7, 0xd3, 0x0e, 0xff, 0xbe, 0x60, 0x01, 0x21, 0x6d, 0xa1, 0x3e,
-       0xd6, 0xc7, 0x98, 0xbc, 0x58, 0xa7, 0xae, 0xf4, 0x60, 0x7d, 0x3f, 0x74,
-       0x71, 0x1b, 0x6c, 0x48, 0xc7, 0xfe, 0x11, 0xee, 0xf7, 0x14, 0xee, 0x1e,
-       0xfb, 0xb7, 0x77, 0x2a, 0xdd, 0xd0, 0xd3, 0x56, 0x4a, 0x07, 0xed, 0x1f,
-       0xab, 0x2d, 0x1d, 0xe1, 0xf7, 0xc2, 0x69, 0xaf, 0xf1, 0xbb, 0xe1, 0x3e,
-       0xad, 0x50, 0xe1, 0xdf, 0x38, 0x0c, 0xc9, 0x21, 0x8b, 0x7f, 0xff, 0xb3,
-       0x4f, 0x7b, 0xa0, 0x4a, 0x18, 0x1b, 0x7d, 0xd6, 0xe1, 0xcb, 0xb0, 0xe5,
-       0xff, 0x29, 0xdc, 0xea, 0x62, 0xdb, 0x3a, 0xcb, 0xf0, 0xfb, 0x1d, 0xe7,
-       0xc7, 0x4d, 0xdd, 0xe4, 0x34, 0x71, 0x12, 0x27, 0xca, 0xc0, 0xc7, 0x39,
-       0x49, 0x3d, 0x39, 0xd5, 0x4e, 0xa2, 0x14, 0x22, 0x88, 0x84, 0xe5, 0xfc,
-       0xcc, 0x63, 0x14, 0x3c, 0xc8, 0xa6, 0x4e, 0x42, 0x55, 0x94, 0x74, 0x5b,
-       0x27, 0xee, 0xb8, 0x40, 0x5c, 0x80, 0x6a, 0x39, 0x69, 0xe9, 0x86, 0x3d,
-       0xa7, 0x5b, 0xba, 0x00, 0x57, 0x9e, 0xe3, 0xa4, 0x4d, 0xe7, 0xcc, 0x1a,
-       0x03, 0x69, 0x70, 0x41, 0x23, 0x33, 0x6d, 0xe3, 0x66, 0x37, 0x48, 0x5c,
-       0x57, 0x29, 0x83, 0x02, 0x6b, 0x2b, 0xb8, 0xe1, 0xef, 0xe2, 0xf0, 0x3c,
-       0xdf, 0x39, 0x76, 0xd3, 0xc0, 0x44, 0x24, 0xeb, 0x7c, 0xe7, 0x3b, 0xdf,
-       0xff, 0xf7, 0xbe, 0xcf, 0xfb, 0x9b, 0x6e, 0xb9, 0x08, 0x3a, 0xce, 0x8d,
-       0xb5, 0xfa, 0xfe, 0xd6, 0x0e, 0x9f, 0x87, 0x07, 0xfb, 0x7c, 0x19, 0xa5,
-       0x75, 0xc9, 0x9c, 0xd6, 0xa7, 0xbb, 0x0e, 0x7d, 0x7b, 0x16, 0x6b, 0x8a,
-       0xe0, 0x1c, 0x1e, 0xe9, 0xd3, 0x78, 0x64, 0xf0, 0xbd, 0xff, 0xd0, 0x7b,
-       0xdf, 0xa1, 0xf7, 0xde, 0xff, 0xd1, 0x9e, 0xe5, 0xc3, 0xf4, 0xc0, 0x75,
-       0x5a, 0x53, 0x1a, 0xfd, 0xf2, 0x93, 0x6a, 0x39, 0x6f, 0x25, 0xa9, 0x0b,
-       0xcc, 0x88, 0xab, 0x66, 0x9c, 0x36, 0x60, 0x5c, 0x9b, 0xac, 0xae, 0x83,
-       0xe6, 0xb1, 0x8f, 0x76, 0x9b, 0xf1, 0xf2, 0x89, 0x3e, 0xf2, 0x4c, 0x10,
-       0xd7, 0x60, 0xd8, 0xc3, 0x11, 0xb4, 0x73, 0x5f, 0x74, 0x12, 0xe6, 0x39,
-       0xed, 0xbf, 0xa1, 0x0e, 0xe3, 0xaa, 0x9c, 0xce, 0xfd, 0x60, 0x9b, 0x16,
-       0xb9, 0x6d, 0xa7, 0xba, 0xfd, 0xdc, 0x20, 0xd8, 0xbb, 0xa9, 0x3e, 0xea,
-       0x17, 0x2f, 0x38, 0xcd, 0x3a, 0x73, 0x5f, 0x98, 0x77, 0x05, 0xa2, 0x79,
-       0x4a, 0xa4, 0x54, 0x11, 0xb9, 0x86, 0xdf, 0x6f, 0x2a, 0x7e, 0xfc, 0x42,
-       0xd1, 0xd6, 0x9e, 0x96, 0x1b, 0xc5, 0x2f, 0x48, 0x15, 0x32, 0x67, 0xc7,
-       0x71, 0xdd, 0x3b, 0x4e, 0x54, 0x9f, 0xf9, 0x0f, 0xf2, 0x4a, 0x62, 0xe3,
-       0x94, 0x69, 0x6d, 0xf2, 0xc3, 0x75, 0xe6, 0xd5, 0x59, 0xe6, 0x1d, 0x61,
-       0x7e, 0x5b, 0x44, 0xd2, 0xe1, 0x80, 0xd6, 0x4b, 0xe5, 0x69, 0x68, 0x12,
-       0xf8, 0xf6, 0x87, 0xf5, 0xb3, 0x7d, 0xf4, 0xb9, 0x7c, 0xbc, 0xce, 0x77,
-       0x03, 0x4f, 0x43, 0xea, 0x76, 0x00, 0xfa, 0x2b, 0x80, 0xc7, 0xe4, 0xb9,
-       0x73, 0xbf, 0xcf, 0x73, 0x6d, 0xa8, 0xa3, 0x0d, 0xdb, 0x26, 0xb9, 0x11,
-       0xe0, 0xa0, 0x1a, 0xd6, 0xf9, 0x47, 0xf5, 0xb0, 0xc6, 0xe5, 0x40, 0x99,
-       0x7e, 0x7b, 0xf3, 0xa8, 0xc6, 0xe8, 0xd4, 0xee, 0xf7, 0xf4, 0x5e, 0x50,
-       0xce, 0x96, 0x1d, 0xd2, 0xaa, 0x29, 0x3b, 0xe0, 0xb5, 0xeb, 0xb5, 0x37,
-       0xfa, 0x79, 0x57, 0x37, 0x6a, 0xdf, 0xef, 0xf3, 0x6c, 0x34, 0xd6, 0x5d,
-       0xe8, 0xf3, 0xea, 0xa2, 0xbe, 0xcd, 0x45, 0xdb, 0xac, 0x84, 0xbd, 0x7d,
-       0x5b, 0x6a, 0x1b, 0xdf, 0x95, 0x77, 0x8b, 0xdf, 0x91, 0x5f, 0x6c, 0x9c,
-       0x81, 0xce, 0x61, 0x95, 0xb2, 0x90, 0x27, 0x6f, 0xd7, 0x5c, 0xf7, 0x6d,
-       0x67, 0x01, 0xf6, 0x81, 0xeb, 0xfe, 0xd6, 0xd9, 0x93, 0xd8, 0xc4, 0x37,
-       0xb1, 0xe7, 0x0c, 0x78, 0x88, 0x58, 0x98, 0x06, 0xbd, 0x7d, 0xb1, 0x5f,
-       0x3a, 0x42, 0x9a, 0x4e, 0x86, 0x27, 0x5a, 0xb1, 0x07, 0xc3, 0xd7, 0xc3,
-       0xb9, 0x97, 0xe9, 0x7e, 0xd2, 0x8c, 0x51, 0xfb, 0x09, 0xe6, 0x6f, 0x05,
-       0x5f, 0x1c, 0xc5, 0x4f, 0xc9, 0x9d, 0x71, 0xac, 0x75, 0x9c, 0xb4, 0xd7,
-       0x2a, 0xb1, 0xc7, 0xb0, 0x8f, 0x4c, 0x8b, 0xdc, 0xcb, 0x6f, 0xf6, 0xd1,
-       0x9f, 0x77, 0x2f, 0xcf, 0xb2, 0xf1, 0xb9, 0x4e, 0x71, 0xa5, 0x05, 0xf2,
-       0x7b, 0x75, 0xd2, 0xd3, 0x95, 0x7e, 0xad, 0x4e, 0xa0, 0xbd, 0x9d, 0x7d,
-       0x4f, 0x51, 0xb7, 0xcb, 0xba, 0xad, 0xd0, 0xc5, 0xe7, 0xa0, 0x03, 0xa5,
-       0x6a, 0x17, 0xa4, 0x3e, 0x1e, 0x42, 0x1b, 0xea, 0x28, 0x1a, 0x4b, 0x64,
-       0x26, 0xcf, 0x7c, 0x2d, 0xe6, 0x4e, 0x61, 0x8d, 0x0b, 0xc4, 0x0d, 0xae,
-       0xb1, 0x8d, 0x31, 0x38, 0xbf, 0xce, 0x06, 0x8d, 0xb0, 0x8e, 0xf4, 0x9d,
-       0x04, 0x4f, 0x26, 0x29, 0x37, 0x31, 0xde, 0x18, 0xc6, 0x63, 0xb9, 0x13,
-       0xe3, 0x5d, 0x90, 0x94, 0xd3, 0x18, 0x73, 0x0a, 0x6d, 0x88, 0x33, 0x53,
-       0xd0, 0x1f, 0x86, 0xd4, 0xec, 0x7a, 0x18, 0xf2, 0xbb, 0x4f, 0x66, 0xcd,
-       0x23, 0x07, 0xf6, 0x98, 0xd5, 0xf6, 0x81, 0x61, 0x8c, 0xf9, 0x6b, 0xea,
-       0x3c, 0xb0, 0x26, 0xf6, 0xc7, 0x0f, 0xb6, 0x71, 0x6a, 0x7d, 0x0d, 0x38,
-       0xb5, 0xf6, 0x61, 0xca, 0x39, 0x2b, 0x33, 0x61, 0xae, 0x89, 0xf5, 0x61,
-       0xac, 0x99, 0x7e, 0xac, 0x67, 0x81, 0x43, 0x47, 0xfc, 0x3a, 0xb6, 0x15,
-       0x23, 0x85, 0xb3, 0xf7, 0xec, 0x5a, 0xd6, 0x7d, 0x56, 0x52, 0x6b, 0x19,
-       0x99, 0xd7, 0xfd, 0x78, 0x86, 0x83, 0x5a, 0xf7, 0x20, 0xaf, 0xc6, 0x7a,
-       0x70, 0x96, 0x89, 0x07, 0x36, 0x70, 0xb4, 0x47, 0xcb, 0xcc, 0x7e, 0x8f,
-       0x67, 0xf1, 0xad, 0x87, 0x77, 0xd4, 0x26, 0xb1, 0x6f, 0x40, 0x46, 0xe6,
-       0x1b, 0xf5, 0x21, 0xf9, 0x24, 0xdf, 0xd1, 0xcf, 0x38, 0xcb, 0xdd, 0xbc,
-       0x29, 0x1f, 0xe7, 0x75, 0x2c, 0x74, 0x31, 0x20, 0xd6, 0x79, 0xcf, 0x3e,
-       0x1f, 0x59, 0x5c, 0x55, 0xfc, 0x3e, 0x72, 0x7e, 0x4b, 0x05, 0xd1, 0x36,
-       0x84, 0x76, 0x5c, 0x87, 0x29, 0x73, 0xf9, 0xbf, 0xb9, 0x4b, 0xa3, 0xae,
-       0x3b, 0xaf, 0xf3, 0xc3, 0x12, 0xe6, 0xaa, 0x6a, 0xe8, 0xe4, 0x71, 0xc9,
-       0x87, 0xdb, 0x31, 0x57, 0xc2, 0xdc, 0x52, 0x23, 0x58, 0x0f, 0xcb, 0x3d,
-       0xe4, 0x89, 0xc8, 0x9e, 0x70, 0x7c, 0x2b, 0xbd, 0xa9, 0x12, 0xd1, 0x61,
-       0x65, 0x25, 0x73, 0xf8, 0xb5, 0x28, 0x1d, 0x47, 0x8c, 0x44, 0x15, 0x78,
-       0x17, 0x7b, 0xb2, 0x4f, 0xba, 0x6e, 0xda, 0x66, 0x7d, 0xc2, 0x0c, 0x29,
-       0xfa, 0x5b, 0x3a, 0x74, 0xbc, 0xf1, 0x72, 0x6f, 0xc2, 0x3c, 0xa9, 0x8e,
-       0xfb, 0xef, 0x53, 0xc0, 0xcc, 0xe6, 0x78, 0x67, 0x36, 0x95, 0x29, 0x2f,
-       0xe5, 0x13, 0xd1, 0x65, 0x65, 0x65, 0x30, 0x66, 0x66, 0x56, 0x11, 0x37,
-       0x12, 0x66, 0x87, 0xa2, 0x4f, 0xb4, 0x5d, 0xef, 0x3b, 0x8d, 0xfe, 0x09,
-       0xd5, 0xe2, 0xaf, 0x87, 0xf7, 0xf5, 0xe3, 0x7e, 0x8f, 0x67, 0x88, 0x39,
-       0xa3, 0xc0, 0x4c, 0xe6, 0x9a, 0xe9, 0xdc, 0x86, 0x64, 0x6c, 0x62, 0x54,
-       0x63, 0xe8, 0xfd, 0x53, 0x7f, 0x47, 0x1d, 0xca, 0x25, 0xd6, 0xc5, 0x7d,
-       0x7e, 0x1b, 0xd5, 0x3a, 0xf3, 0xfd, 0x53, 0x59, 0x9d, 0xc7, 0x58, 0x57,
-       0x31, 0x7f, 0xdf, 0xcd, 0x3b, 0x8b, 0xa6, 0x9c, 0x47, 0x38, 0xce, 0x5a,
-       0x60, 0xba, 0x5d, 0x98, 0x23, 0x3a, 0x57, 0x6c, 0xd0, 0x06, 0xfd, 0x01,
-       0xcc, 0x17, 0x68, 0xc4, 0xbd, 0x2f, 0x88, 0x31, 0x11, 0x3c, 0x40, 0x27,
-       0xd0, 0x35, 0xa1, 0xa3, 0x56, 0x30, 0x4e, 0x6e, 0x5d, 0xb2, 0x5e, 0x7f,
-       0x09, 0x32, 0x27, 0x35, 0x57, 0xf9, 0xb4, 0x31, 0x38, 0x37, 0xe6, 0xc0,
-       0xfb, 0xfd, 0x53, 0xa4, 0x4f, 0x9e, 0x4d, 0x54, 0xcd, 0x6d, 0x70, 0x3d,
-       0x83, 0x32, 0xbf, 0x3e, 0x24, 0xcb, 0xf8, 0xad, 0xae, 0x7b, 0xf7, 0xb6,
-       0x0d, 0xdd, 0x7a, 0x3e, 0x6f, 0x6a, 0x7e, 0x5d, 0x76, 0x18, 0x33, 0x01,
-       0xaf, 0xe8, 0x9c, 0x2a, 0xf6, 0x65, 0x5e, 0xe1, 0x10, 0xe5, 0xa3, 0x53,
-       0x87, 0x5c, 0xdd, 0xae, 0x51, 0x4f, 0x65, 0xbd, 0x35, 0x15, 0x0d, 0x74,
-       0xc9, 0x2a, 0xf0, 0xae, 0x0c, 0xd9, 0x99, 0x7b, 0x25, 0x24, 0xcb, 0x79,
-       0x1d, 0x4f, 0x8e, 0xfe, 0x5e, 0x39, 0x52, 0xad, 0x4d, 0xca, 0x6e, 0x2d,
-       0xae, 0xbf, 0x51, 0xae, 0xe5, 0x5e, 0x37, 0xe4, 0xf9, 0x51, 0x9d, 0x57,
-       0x17, 0x2f, 0x4b, 0xef, 0x00, 0x75, 0x9e, 0x2d, 0x9d, 0x63, 0x07, 0xec,
-       0x80, 0xce, 0xf1, 0x33, 0xe8, 0x1c, 0xef, 0x40, 0xe7, 0xf8, 0x69, 0x11,
-       0xf8, 0x52, 0x4c, 0xfb, 0xf8, 0xbf, 0x08, 0x1c, 0xa2, 0xac, 0xb6, 0xce,
-       0xe0, 0x4e, 0x17, 0xb3, 0xa0, 0xc1, 0x5b, 0x92, 0x06, 0xde, 0xa6, 0xe4,
-       0xfa, 0xc6, 0xbc, 0xec, 0x6c, 0x78, 0x79, 0xc8, 0x1f, 0x30, 0x07, 0x6c,
-       0x9c, 0xf7, 0x14, 0x07, 0x0e, 0x1d, 0x91, 0xd8, 0x49, 0xe2, 0x47, 0x50,
-       0x36, 0x0b, 0xef, 0x68, 0x1c, 0xda, 0x2c, 0xb0, 0x1c, 0x10, 0x9d, 0x4f,
-       0xb6, 0xb0, 0x27, 0x65, 0xe7, 0x97, 0xa8, 0x3f, 0xa6, 0x7d, 0x40, 0x9e,
-       0x4f, 0x9e, 0x78, 0xf9, 0x67, 0xff, 0xee, 0x95, 0xce, 0xb3, 0x5b, 0x32,
-       0xbb, 0xd0, 0xae, 0x81, 0x5d, 0xc3, 0x5e, 0xcc, 0x5b, 0xfd, 0x05, 0x6d,
-       0x30, 0x47, 0xb1, 0x4b, 0xb6, 0x21, 0x43, 0xea, 0xf1, 0x2e, 0xad, 0xfb,
-       0xd5, 0xe3, 0x43, 0x3a, 0x17, 0x97, 0xe3, 0xe4, 0x0a, 0xb6, 0xac, 0x14,
-       0xac, 0x68, 0x16, 0xf4, 0xb7, 0x0b, 0x5b, 0xed, 0x3a, 0xee, 0x60, 0x07,
-       0x67, 0x70, 0xa3, 0x46, 0x39, 0x7f, 0x57, 0x63, 0xef, 0x66, 0xed, 0x4f,
-       0x18, 0xc7, 0x3a, 0x93, 0x94, 0x3f, 0xf6, 0x13, 0x03, 0xe9, 0x8f, 0x9a,
-       0xd1, 0xfd, 0xbd, 0x7e, 0xd7, 0xd1, 0x76, 0xa7, 0x46, 0x3c, 0x16, 0xb9,
-       0x94, 0xb7, 0x21, 0x4b, 0x5e, 0x8f, 0x50, 0x07, 0x28, 0xa9, 0x46, 0x3f,
-       0xd7, 0x5f, 0xb3, 0xeb, 0x1e, 0xb5, 0xb9, 0xae, 0xb8, 0x8f, 0xdb, 0x94,
-       0xfd, 0x7b, 0x5a, 0xee, 0xe7, 0x8b, 0x67, 0xe5, 0x2d, 0xdc, 0xb7, 0xa7,
-       0xe3, 0x64, 0xe4, 0x4d, 0xe8, 0x78, 0xb5, 0x62, 0x23, 0x6f, 0x7b, 0x1a,
-       0xe7, 0x64, 0xa9, 0x95, 0x2b, 0x2f, 0xcb, 0xe5, 0xab, 0xfb, 0xea, 0xa5,
-       0xab, 0x31, 0xf5, 0xf2, 0x95, 0x61, 0x95, 0xbb, 0xe2, 0xba, 0xff, 0x74,
-       0x96, 0xe4, 0xdd, 0x0d, 0x57, 0x4e, 0x3b, 0xc6, 0x40, 0x40, 0x1a, 0xb9,
-       0x75, 0xae, 0x1b, 0x04, 0x36, 0xdf, 0xe8, 0x75, 0xdd, 0x47, 0xc7, 0xc7,
-       0x25, 0xde, 0x4b, 0x1d, 0xe5, 0xf3, 0x11, 0xe6, 0xbb, 0x12, 0x73, 0x52,
-       0xb6, 0x7d, 0xbe, 0xac, 0x14, 0xf0, 0xad, 0xcb, 0xd3, 0x5f, 0x1e, 0x3b,
-       0xe6, 0xc7, 0x4a, 0x7e, 0xf4, 0x22, 0x7d, 0xc9, 0x91, 0xff, 0xf2, 0x25,
-       0x9b, 0x72, 0xae, 0xf0, 0x19, 0xf4, 0x0f, 0xcb, 0xb7, 0x0a, 0xa1, 0x43,
-       0x65, 0x13, 0xcf, 0x31, 0x95, 0x2b, 0xdc, 0x73, 0x87, 0x75, 0xcc, 0x00,
-       0x3a, 0x89, 0xe9, 0xba, 0xcb, 0x0e, 0xe7, 0xeb, 0xc2, 0x7c, 0x7b, 0xe6,
-       0x31, 0xc8, 0xff, 0xd3, 0x5a, 0x3e, 0x9f, 0x53, 0xb0, 0x7d, 0xc1, 0xdf,
-       0x61, 0x99, 0x2d, 0x40, 0xc6, 0x2b, 0xe6, 0x9c, 0x52, 0x57, 0xb0, 0x22,
-       0xcb, 0xc0, 0x8e, 0x25, 0xe0, 0xcd, 0x93, 0x3a, 0xb6, 0xda, 0xa3, 0xb1,
-       0x67, 0x85, 0xe5, 0x8c, 0x24, 0xcb, 0x4e, 0xb7, 0x3e, 0xbf, 0xfd, 0xdd,
-       0x57, 0x23, 0xde, 0x9d, 0x83, 0x8f, 0x33, 0x4a, 0xda, 0x60, 0x03, 0xcd,
-       0x6c, 0x2d, 0x80, 0x27, 0x22, 0x38, 0xdb, 0x56, 0xcd, 0x0f, 0x75, 0xc8,
-       0xef, 0xba, 0xf6, 0x23, 0x7a, 0xf1, 0x8a, 0xba, 0xc9, 0x76, 0xcf, 0xa0,
-       0x5f, 0xbb, 0xa4, 0xae, 0xb4, 0x69, 0x5c, 0x7d, 0xb8, 0x2e, 0x09, 0x3d,
-       0xe4, 0x69, 0x94, 0x03, 0xa8, 0x8b, 0xfa, 0x65, 0x03, 0xe5, 0x45, 0x94,
-       0x5b, 0xf0, 0x64, 0x9b, 0x11, 0xe8, 0x15, 0x78, 0xbe, 0x81, 0xf1, 0xc6,
-       0xb1, 0xe6, 0x8c, 0x29, 0x1f, 0x9d, 0xa2, 0x2c, 0x19, 0x53, 0xcc, 0x4b,
-       0x5e, 0xb6, 0xf1, 0xac, 0x0e, 0xab, 0x99, 0x35, 0x96, 0xf1, 0x2c, 0x79,
-       0xdf, 0x1f, 0xc2, 0x24, 0xf4, 0x49, 0x5d, 0xf5, 0x30, 0xe9, 0xa3, 0x26,
-       0x26, 0xb1, 0xae, 0x5d, 0x66, 0xaf, 0x90, 0xd7, 0x4d, 0xd0, 0x5b, 0x87,
-       0xcc, 0x5c, 0x0d, 0x6b, 0x7d, 0xb4, 0x0c, 0x5a, 0xdc, 0x06, 0x5d, 0x6d,
-       0x82, 0xa6, 0x52, 0x05, 0x6b, 0x6a, 0x51, 0x45, 0xb5, 0x2f, 0xe0, 0x09,
-       0xd0, 0x6b, 0xf0, 0x15, 0xea, 0xa2, 0xe4, 0xe5, 0x38, 0x68, 0x4f, 0xdc,
-       0xa0, 0x6d, 0xa7, 0xe3, 0xca, 0x06, 0x0d, 0x82, 0x2e, 0x0b, 0x1e, 0x4f,
-       0xbf, 0xa7, 0x34, 0xae, 0x4e, 0xdd, 0x96, 0x44, 0xf2, 0xb6, 0x58, 0xc0,
-       0x02, 0xcb, 0xf9, 0x50, 0x1c, 0x8c, 0x39, 0x29, 0xd7, 0x30, 0x8f, 0x01,
-       0xfe, 0x1e, 0x3d, 0xa1, 0xf9, 0x7b, 0x4a, 0x02, 0x87, 0x79, 0x1c, 0xf4,
-       0x06, 0x0c, 0xf2, 0x78, 0x3a, 0xe9, 0xd3, 0xe8, 0xd7, 0xc1, 0xbf, 0x16,
-       0x2c, 0xb1, 0xb0, 0xac, 0x82, 0xff, 0xb7, 0xf1, 0xfd, 0x66, 0x6d, 0x44,
-       0xad, 0xac, 0x29, 0x3f, 0x97, 0xe4, 0x19, 0xe8, 0xc9, 0xb7, 0x70, 0x76,
-       0x9d, 0x5a, 0x77, 0x8f, 0x8d, 0x33, 0x7e, 0x96, 0x56, 0x97, 0xed, 0x93,
-       0xb2, 0x3f, 0x36, 0x89, 0xf2, 0x31, 0x3c, 0x0d, 0x9c, 0x43, 0x48, 0xc7,
-       0xbf, 0x37, 0xf3, 0x8e, 0xf2, 0xfe, 0x67, 0x61, 0x42, 0xe7, 0xe7, 0x1b,
-       0x76, 0x2f, 0xbe, 0xd3, 0x17, 0xc3, 0xbd, 0x41, 0x67, 0x52, 0x11, 0x9d,
-       0x6f, 0x5a, 0x86, 0x2e, 0xb1, 0x85, 0xf1, 0xde, 0xa7, 0x2f, 0xaf, 0x0a,
-       0x1e, 0x1e, 0xfb, 0x97, 0x9b, 0x0c, 0x33, 0x47, 0xfd, 0x6e, 0xc4, 0x93,
-       0x7f, 0x9f, 0xb8, 0xfb, 0xf6, 0xca, 0x94, 0x81, 0x97, 0x5b, 0x66, 0x18,
-       0x6d, 0x21, 0xcb, 0x20, 0x8b, 0x4a, 0x9a, 0x7e, 0xd9, 0xce, 0xeb, 0x9b,
-       0xab, 0x26, 0xcc, 0x0f, 0xc4, 0xeb, 0xbb, 0x6a, 0x53, 0xee, 0xb4, 0x03,
-       0x5f, 0xa2, 0x5a, 0xaf, 0x7c, 0xdf, 0xce, 0x02, 0x15, 0xac, 0x68, 0x1a,
-       0x34, 0xda, 0x26, 0x56, 0x7c, 0x4e, 0x1e, 0xcc, 0xbb, 0xac, 0xfb, 0xb2,
-       0x6d, 0xa3, 0x6f, 0x63, 0x5e, 0xae, 0x9f, 0x7b, 0xe1, 0x1e, 0xe8, 0x9b,
-       0x36, 0x35, 0x8d, 0xd6, 0xab, 0xdd, 0x03, 0x1e, 0x8d, 0x36, 0xf6, 0x11,
-       0xfe, 0x3f, 0xfb, 0x20, 0x9d, 0x38, 0xca, 0xcb, 0xbb, 0xc0, 0xb3, 0xca,
-       0xf3, 0x1c, 0x01, 0x6d, 0x1c, 0xa4, 0x9f, 0x86, 0x6f, 0xd1, 0xa3, 0x9f,
-       0x47, 0x9b, 0xf4, 0x43, 0xba, 0xe9, 0x90, 0xd9, 0xab, 0xb6, 0xcc, 0x17,
-       0xf4, 0x7d, 0x43, 0xd7, 0xa4, 0xcf, 0x68, 0x12, 0x74, 0x43, 0x5a, 0x27,
-       0x6f, 0x99, 0x52, 0x02, 0x1d, 0x95, 0x80, 0x4f, 0x25, 0xd0, 0x54, 0x19,
-       0xf8, 0x56, 0x02, 0xbe, 0x95, 0x6a, 0x56, 0xbc, 0x82, 0x3d, 0x53, 0x66,
-       0x6f, 0x81, 0x8e, 0xb6, 0x6b, 0xbc, 0x7f, 0xbd, 0x66, 0x93, 0x72, 0xf0,
-       0x66, 0xf3, 0xee, 0xff, 0x81, 0xbb, 0x1f, 0x92, 0x5d, 0xd8, 0x2d, 0x6f,
-       0x15, 0xc7, 0x80, 0x49, 0x02, 0x8c, 0x72, 0x40, 0x1b, 0x53, 0x72, 0xbd,
-       0x38, 0x2d, 0x3b, 0x90, 0x4f, 0x37, 0x36, 0x62, 0xd0, 0xa7, 0x23, 0xb2,
-       0xf2, 0xda, 0xa8, 0xbc, 0xb9, 0xa1, 0x64, 0x09, 0xf4, 0x9b, 0xdb, 0xa4,
-       0xdf, 0x1d, 0xf4, 0x5c, 0xea, 0xd0, 0x71, 0xfa, 0xd9, 0x8a, 0xe7, 0x7f,
-       0x9f, 0xab, 0x74, 0xca, 0x7c, 0xc5, 0x94, 0xc7, 0x2b, 0xdd, 0xf2, 0xe5,
-       0x4a, 0x58, 0x4e, 0xc3, 0x0e, 0xfc, 0x4a, 0x65, 0x50, 0x9e, 0xac, 0x0c,
-       0xc9, 0x57, 0xab, 0x51, 0xf9, 0x5a, 0xd5, 0x96, 0x4c, 0x35, 0x2e, 0xe9,
-       0xea, 0x98, 0x3c, 0x51, 0xa5, 0x5f, 0x1d, 0xf3, 0xe1, 0x37, 0xd3, 0xf4,
-       0x57, 0x70, 0x5d, 0x41, 0xac, 0x2b, 0xae, 0xe6, 0x74, 0x9c, 0x52, 0x32,
-       0x9e, 0xcf, 0x43, 0xe4, 0x39, 0x8c, 0x75, 0xf1, 0x35, 0x25, 0x65, 0x3d,
-       0x7f, 0xe3, 0xff, 0x46, 0x42, 0xda, 0x36, 0x7a, 0xae, 0x34, 0x88, 0x36,
-       0x90, 0x7b, 0xf9, 0x86, 0xef, 0xa3, 0xe1, 0xf3, 0x6f, 0xd8, 0x5e, 0x86,
-       0xf6, 0x5b, 0xdf, 0xa4, 0xed, 0xa5, 0xcf, 0x9e, 0xf8, 0x41, 0x3b, 0xe7,
-       0x9a, 0xf6, 0x9b, 0x3c, 0x88, 0x6d, 0x34, 0xe6, 0xbd, 0x98, 0x79, 0xf8,
-       0xff, 0x53, 0xbc, 0x18, 0xd5, 0xb9, 0xea, 0x20, 0xff, 0x4f, 0x05, 0x6b,
-       0xf9, 0xf4, 0xdc, 0xf1, 0xf9, 0xe2, 0xac, 0x7a, 0xbc, 0x48, 0x8d, 0xc6,
-       0x95, 0x8b, 0xcd, 0x9c, 0xb8, 0x2f, 0xc9, 0xa6, 0x13, 0xd2, 0x6b, 0xf0,
-       0xf3, 0x1f, 0x75, 0x7e, 0xdc, 0xec, 0x09, 0xd2, 0x1f, 0x63, 0x6f, 0x9d,
-       0x7e, 0x3c, 0x01, 0xba, 0xad, 0x63, 0xca, 0xa5, 0x8a, 0xe7, 0xb3, 0x5a,
-       0xd1, 0xf4, 0xf2, 0x2b, 0xd0, 0x1c, 0x63, 0x0e, 0xde, 0x33, 0x5b, 0xf2,
-       0xfa, 0xce, 0xe0, 0xde, 0x60, 0x8f, 0x63, 0xbf, 0x46, 0x37, 0xe7, 0xe2,
-       0xff, 0xe9, 0xa0, 0xec, 0xaf, 0x97, 0xb9, 0xc6, 0xb6, 0xa6, 0x45, 0x2f,
-       0xae, 0x1b, 0x97, 0x17, 0x70, 0x7e, 0x65, 0x93, 0xeb, 0x0f, 0x4a, 0x39,
-       0x4e, 0xdb, 0x96, 0xf8, 0x7d, 0x42, 0x4a, 0x98, 0xa7, 0x1c, 0x6f, 0xf8,
-       0xc3, 0x3c, 0x9c, 0x2d, 0x9b, 0x0f, 0xe6, 0x5d, 0x2c, 0x1d, 0xc7, 0x3b,
-       0xea, 0xe2, 0xd0, 0x99, 0x16, 0xf8, 0x7e, 0x11, 0x65, 0xfa, 0x46, 0x56,
-       0xf0, 0x8c, 0xf8, 0x75, 0xd5, 0x01, 0xad, 0xab, 0x4f, 0x3f, 0xe8, 0xb7,
-       0x54, 0xb2, 0xb2, 0xa9, 0x40, 0x42, 0x19, 0xaf, 0xfe, 0x7c, 0x80, 0x98,
-       0x7b, 0xdc, 0xe6, 0x2f, 0x24, 0x7f, 0x35, 0xb5, 0x4f, 0xc1, 0xff, 0x76,
-       0x44, 0x9e, 0x32, 0x99, 0xc7, 0x9e, 0x54, 0xb3, 0xc5, 0x9c, 0x9f, 0xe3,
-       0x9b, 0x50, 0xc7, 0xcb, 0x37, 0x07, 0xbc, 0x9c, 0x77, 0x8e, 0x7d, 0x30,
-       0xcf, 0xfd, 0x20, 0x9d, 0x30, 0xdf, 0xbd, 0xbd, 0xf9, 0x3f, 0x52, 0xe5,
-       0x3c, 0xf0, 0xce, 0x6e, 0xd1, 0xfc, 0x98, 0xab, 0xfe, 0xdb, 0xdd, 0xd3,
-       0xfc, 0xdc, 0xf0, 0x31, 0xfc, 0x6e, 0x80, 0xb6, 0x2d, 0x71, 0xe3, 0x92,
-       0x97, 0x3b, 0xaa, 0x6d, 0x68, 0x60, 0x05, 0xea, 0xc8, 0xab, 0xe0, 0x93,
-       0x66, 0x5b, 0xfe, 0xfd, 0x07, 0x69, 0x3f, 0x51, 0x42, 0x6c, 0x67, 0x00,
-       0x00, 0x00 };
+       0xec, 0x5c, 0x7d, 0x6c, 0x1c, 0xc7, 0x75, 0x7f, 0x3b, 0xbb, 0xa4, 0x8e,
+       0xd4, 0x91, 0x5c, 0x1e, 0x4f, 0xcc, 0x51, 0xa6, 0xed, 0x5b, 0x71, 0x25,
+       0x9e, 0x4d, 0xc6, 0x59, 0xd1, 0x07, 0x9b, 0x28, 0x0e, 0xc9, 0x66, 0xef,
+       0x24, 0xb1, 0x86, 0x5b, 0x53, 0x35, 0x1d, 0x1b, 0x6d, 0xea, 0xb2, 0x47,
+       0xb5, 0x29, 0x8c, 0x06, 0x90, 0xbf, 0x00, 0x17, 0xa8, 0xe4, 0xcb, 0x91,
+       0x8a, 0x55, 0xf7, 0xc0, 0xbd, 0xc8, 0x8c, 0x18, 0x20, 0x6e, 0x7d, 0x25,
+       0x29, 0x4a, 0x08, 0x0e, 0x3a, 0xa6, 0x71, 0x1a, 0xfd, 0x61, 0xd7, 0x04,
+       0x2b, 0x1b, 0x6e, 0x91, 0xd6, 0x72, 0xe3, 0xb6, 0x46, 0x50, 0x04, 0x84,
+       0xec, 0x34, 0x6e, 0xd0, 0x0f, 0xa1, 0x2e, 0x6c, 0x03, 0x96, 0xbd, 0xfd,
+       0xbd, 0xd9, 0x5d, 0xf2, 0x48, 0x5b, 0x76, 0xd0, 0x3f, 0xfa, 0x4f, 0x77,
+       0x80, 0xc3, 0xce, 0xcc, 0xbe, 0xf7, 0xe6, 0xcd, 0x9b, 0xf7, 0x39, 0x4b,
+       0xe9, 0xb7, 0xe3, 0xd4, 0x4e, 0x41, 0xeb, 0xc0, 0x2f, 0x7d, 0xf4, 0xb1,
+       0x87, 0x6e, 0xb9, 0xfd, 0x96, 0x5b, 0xd1, 0xdd, 0xaf, 0x2a, 0x3b, 0xd4,
+       0x70, 0x3e, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45,
+       0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45, 0x2d,
+       0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45, 0x2d, 0x6a,
+       0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45, 0x2d, 0x6a, 0x51,
+       0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45, 0x2d, 0x6a, 0x51, 0x8b,
+       0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45, 0xed, 0xff, 0x7b, 0x53, 0x89,
+       0x74, 0x7e, 0x76, 0x04, 0x3f, 0x8a, 0x89, 0x5c, 0xfa, 0x01, 0xc7, 0xa4,
+       0x98, 0x9a, 0xeb, 0x3f, 0x3e, 0x65, 0x12, 0xd9, 0xf5, 0xa1, 0x74, 0x9e,
+       0x3e, 0xf0, 0x4a, 0x49, 0x8d, 0x78, 0xfe, 0xfa, 0xdc, 0xd5, 0x67, 0x9e,
+       0xbf, 0xdd, 0xb8, 0x52, 0x53, 0x29, 0xa6, 0xe7, 0x66, 0xf6, 0xeb, 0xfb,
+       0x28, 0xd6, 0x0f, 0x9c, 0xa7, 0x07, 0xff, 0xb1, 0x93, 0x3a, 0x43, 0x5a,
+       0x44, 0x0b, 0x15, 0xc3, 0x3a, 0x88, 0xe7, 0x72, 0x7d, 0xc8, 0x5a, 0x23,
+       0x8d, 0x56, 0x75, 0x7f, 0xc5, 0x72, 0x45, 0x61, 0x3a, 0x54, 0xae, 0xc7,
+       0x68, 0x5d, 0xfe, 0x3b, 0x0f, 0xac, 0x69, 0x72, 0xff, 0x82, 0xe2, 0x34,
+       0x3c, 0xef, 0x8c, 0xe5, 0x79, 0x2f, 0xe1, 0xf7, 0x33, 0x0b, 0x63, 0xf7,
+       0x43, 0xcf, 0xd6, 0x54, 0x12, 0xe6, 0x1f, 0x2b, 0xce, 0x62, 0x2b, 0x95,
+       0xe7, 0x89, 0xa6, 0xdd, 0x18, 0x9d, 0x74, 0x4b, 0x4a, 0xa1, 0x51, 0x51,
+       0x0e, 0x9c, 0x9d, 0x55, 0x0e, 0x9e, 0x3d, 0xa9, 0x1c, 0x3a, 0x5b, 0x55,
+       0x9c, 0xb3, 0x54, 0x12, 0xfb, 0xe3, 0x64, 0xeb, 0xe7, 0x94, 0x7c, 0xa3,
+       0x57, 0x71, 0xe6, 0xaf, 0x7a, 0x8e, 0x65, 0xe8, 0xbf, 0x4e, 0x9a, 0xcd,
+       0xeb, 0x39, 0x15, 0x0f, 0x63, 0x8d, 0xec, 0xa4, 0xe7, 0x89, 0x9c, 0xf7,
+       0xb8, 0x93, 0x35, 0x75, 0xa1, 0xc4, 0xa8, 0xdc, 0x68, 0x07, 0x5d, 0x4d,
+       0xc9, 0xbb, 0xde, 0x0b, 0x8e, 0xb5, 0x0c, 0x3a, 0x75, 0xe0, 0x93, 0x2e,
+       0x72, 0xcc, 0x4f, 0xc8, 0x63, 0x49, 0xc9, 0x0f, 0x86, 0xfc, 0x50, 0x9a,
+       0xf9, 0x2d, 0x2e, 0x09, 0xf0, 0xb5, 0x93, 0x8a, 0x35, 0x9d, 0x26, 0x97,
+       0xb6, 0xc3, 0xaf, 0x7b, 0xcf, 0x0f, 0xea, 0xb4, 0xd2, 0x30, 0x4a, 0x25,
+       0xec, 0x7d, 0xc6, 0x4d, 0x93, 0xc8, 0x91, 0xed, 0x64, 0xfb, 0xe9, 0x85,
+       0x46, 0x8a, 0xfe, 0xbc, 0x61, 0xa6, 0xca, 0xb4, 0x83, 0x8a, 0xc9, 0x24,
+       0x7d, 0x17, 0x38, 0xd3, 0x58, 0x5b, 0x98, 0xa6, 0x5e, 0x06, 0x6c, 0xb9,
+       0xf1, 0x23, 0xfe, 0xb7, 0x31, 0xfa, 0x54, 0x56, 0xe2, 0x94, 0xc0, 0x67,
+       0x00, 0xcb, 0x7c, 0x4b, 0x58, 0xc9, 0xbb, 0x0f, 0x4b, 0xa5, 0xa9, 0x2c,
+       0xe6, 0x1a, 0x4e, 0x20, 0xfb, 0x56, 0xec, 0x8f, 0x9f, 0x37, 0x28, 0xf9,
+       0xf9, 0x1b, 0x20, 0x03, 0x4a, 0x0a, 0xda, 0x9b, 0x2a, 0x62, 0x66, 0xba,
+       0x11, 0xc7, 0x98, 0x79, 0xf1, 0xbc, 0x43, 0x16, 0xe9, 0x65, 0xab, 0x0b,
+       0xb2, 0x4a, 0x53, 0xd9, 0xea, 0x04, 0x4e, 0x0b, 0x75, 0x9b, 0xbc, 0x07,
+       0xa6, 0xdb, 0x86, 0x79, 0xaf, 0x43, 0xcd, 0x79, 0xde, 0x54, 0x96, 0x3a,
+       0xfd, 0xb9, 0x21, 0xd0, 0xd0, 0x68, 0x72, 0x5c, 0x01, 0xdc, 0xdb, 0xcc,
+       0x5f, 0x2c, 0x91, 0xe3, 0x3e, 0x3f, 0xb3, 0xe4, 0xcc, 0xa6, 0x83, 0x75,
+       0xe3, 0x54, 0x76, 0xaf, 0x0f, 0xfa, 0x90, 0xad, 0x8b, 0x3d, 0x5b, 0x7d,
+       0x18, 0x2b, 0x37, 0x82, 0x8e, 0x55, 0x26, 0x5e, 0x63, 0x17, 0xad, 0x25,
+       0x49, 0x5c, 0xb6, 0x7a, 0x02, 0xb8, 0x4e, 0xf0, 0x1a, 0x9e, 0x71, 0x3b,
+       0xcd, 0xcc, 0xb7, 0xd2, 0x89, 0x79, 0x96, 0x6d, 0x05, 0x67, 0x21, 0x68,
+       0xcf, 0x6d, 0x25, 0xc5, 0x6e, 0x9c, 0x44, 0x5f, 0xa3, 0x29, 0xd3, 0x7b,
+       0x61, 0xc6, 0x9a, 0x55, 0xf2, 0x67, 0x97, 0x95, 0x02, 0xce, 0xfc, 0xc0,
+       0xd9, 0x0b, 0xca, 0xc1, 0xc6, 0xcb, 0x1d, 0xd4, 0x6e, 0x40, 0xbb, 0x34,
+       0x3a, 0xe1, 0x2a, 0xc4, 0xfc, 0x2e, 0x40, 0x5e, 0xb6, 0x0e, 0xc9, 0x9b,
+       0x9d, 0xca, 0x41, 0xd0, 0x6a, 0x31, 0xbf, 0x1e, 0xa7, 0x4e, 0x95, 0x76,
+       0x98, 0x21, 0x6c, 0x8c, 0xbe, 0x0e, 0xde, 0xd6, 0xac, 0x24, 0xe0, 0xa8,
+       0xcb, 0xc7, 0xe9, 0x0e, 0xf8, 0x61, 0xdd, 0x61, 0xbd, 0x11, 0x76, 0x61,
+       0xee, 0x8f, 0x7a, 0xca, 0xc3, 0x3b, 0x19, 0x06, 0xf6, 0x60, 0x3f, 0x30,
+       0x65, 0x3a, 0xdd, 0x1a, 0x95, 0x74, 0x41, 0x86, 0x9e, 0xa7, 0x1b, 0x69,
+       0xc6, 0x22, 0xca, 0x43, 0x9f, 0x85, 0xa9, 0x41, 0x46, 0x26, 0x64, 0xb4,
+       0xb7, 0xa4, 0x8a, 0x7b, 0x41, 0xa2, 0xa4, 0x68, 0x81, 0x3c, 0x17, 0xe8,
+       0x0e, 0x89, 0x2f, 0x72, 0x16, 0x74, 0xb0, 0x9d, 0xfb, 0x58, 0x37, 0x26,
+       0xd7, 0x55, 0x73, 0x66, 0x6a, 0x91, 0x48, 0x11, 0xb9, 0x21, 0xd0, 0x63,
+       0xdd, 0x64, 0x38, 0x17, 0x3c, 0x32, 0xef, 0xdc, 0x37, 0x81, 0x13, 0x23,
+       0xc7, 0xea, 0x68, 0xe2, 0x13, 0xfc, 0x24, 0x59, 0xe6, 0x2c, 0x43, 0xb9,
+       0x4f, 0x65, 0x73, 0x9f, 0xef, 0x7b, 0x83, 0x23, 0x1a, 0xbd, 0x24, 0xf7,
+       0xcb, 0x76, 0xc4, 0x70, 0x72, 0x8f, 0xc4, 0xf2, 0x99, 0x76, 0x49, 0x29,
+       0x5a, 0xfa, 0x06, 0x2d, 0xe8, 0x85, 0x50, 0x73, 0x71, 0xca, 0x4b, 0xfe,
+       0x46, 0xb1, 0x16, 0xdb, 0x17, 0xec, 0xc4, 0xe4, 0xbd, 0xf0, 0x5c, 0x0e,
+       0xb6, 0x6a, 0x48, 0xfd, 0x29, 0x56, 0xd9, 0xfe, 0x99, 0xb7, 0x55, 0x43,
+       0x50, 0x48, 0x4f, 0xf4, 0xaa, 0xd4, 0x45, 0xe3, 0xd6, 0x55, 0x4f, 0xec,
+       0xc3, 0xfb, 0xe1, 0x14, 0x78, 0x33, 0xd2, 0xb0, 0xb6, 0x84, 0x4a, 0xb0,
+       0x73, 0x6b, 0x28, 0xa5, 0x93, 0x89, 0xbd, 0x25, 0xc8, 0x1e, 0x5f, 0x85,
+       0xe0, 0xaf, 0xc5, 0xa7, 0x4f, 0x17, 0x6c, 0xda, 0x0e, 0x78, 0x74, 0xac,
+       0x5b, 0xa5, 0xcc, 0x74, 0xec, 0x5f, 0x9d, 0x65, 0xf9, 0xb6, 0x43, 0xff,
+       0x15, 0x2a, 0x5a, 0x4c, 0x3b, 0xa4, 0x21, 0x68, 0xf0, 0xb6, 0x66, 0x1a,
+       0xe1, 0xd9, 0xb2, 0xfe, 0x6a, 0x34, 0x32, 0xc2, 0xb0, 0x0c, 0xc7, 0xf0,
+       0xc6, 0x68, 0x5a, 0xbc, 0xef, 0xed, 0xdf, 0xb2, 0xa6, 0x49, 0x62, 0x16,
+       0x3c, 0xfb, 0x67, 0x01, 0x19, 0x7e, 0x1a, 0x2c, 0x9f, 0xc3, 0x76, 0x79,
+       0x33, 0x6c, 0x33, 0x1c, 0x74, 0xa8, 0x97, 0x79, 0xa8, 0xc7, 0x7d, 0x7b,
+       0x0c, 0x79, 0x0a, 0xcf, 0x52, 0x09, 0x68, 0x7c, 0xd2, 0x3e, 0x18, 0x1e,
+       0x7e, 0xc2, 0x85, 0x9f, 0x70, 0xe1, 0x1f, 0x5c, 0xf8, 0x11, 0x97, 0xfd,
+       0x4a, 0x9a, 0x9e, 0x1f, 0x84, 0xdf, 0xdb, 0xf4, 0x43, 0x68, 0x63, 0xe8,
+       0x0b, 0x52, 0xe1, 0x87, 0xa6, 0x6b, 0x02, 0xb6, 0x0e, 0x9b, 0x5b, 0xe2,
+       0x39, 0x1d, 0xcf, 0x02, 0x9e, 0x26, 0xfc, 0x2c, 0xeb, 0x61, 0xe8, 0x5f,
+       0xd9, 0x2f, 0xa5, 0xe0, 0x83, 0xd8, 0xef, 0xb0, 0x7f, 0x62, 0x58, 0xcf,
+       0x2b, 0x58, 0x8c, 0xeb, 0xe1, 0x1c, 0xd9, 0xee, 0xe2, 0x24, 0x12, 0x25,
+       0xe5, 0xf0, 0x20, 0x6c, 0xf2, 0xe6, 0x16, 0xf0, 0xca, 0xb6, 0x79, 0x1d,
+       0xbb, 0x16, 0xb4, 0xf7, 0x3b, 0xfc, 0x7f, 0xb7, 0xb7, 0x03, 0x30, 0xd2,
+       0xc6, 0x3b, 0xfd, 0x71, 0x77, 0xe0, 0x7f, 0xf8, 0xbd, 0x91, 0xb6, 0x69,
+       0x5f, 0x30, 0xe6, 0xfe, 0x06, 0xbf, 0x96, 0xb8, 0x2d, 0x46, 0x7b, 0x96,
+       0x7d, 0xbf, 0xb9, 0x67, 0x01, 0x9a, 0xb1, 0xec, 0xf3, 0xb8, 0xe7, 0x7c,
+       0xe8, 0x3f, 0x3b, 0x40, 0x0f, 0xfc, 0xb9, 0x9b, 0x71, 0x84, 0xe8, 0xbf,
+       0x14, 0x98, 0x16, 0xe6, 0xb6, 0xcb, 0xc2, 0xf3, 0x66, 0x2c, 0xb6, 0x4f,
+       0xbd, 0xd9, 0x3e, 0xf7, 0xc3, 0x3e, 0xad, 0x56, 0x32, 0xac, 0xbf, 0x82,
+       0x7d, 0x3e, 0x61, 0x29, 0x90, 0x0d, 0xd1, 0xc5, 0x4a, 0x1c, 0xbe, 0x41,
+       0x4b, 0xbd, 0x41, 0x7b, 0xd3, 0xd3, 0xd0, 0xcb, 0x33, 0x3c, 0x87, 0x23,
+       0x3a, 0x21, 0xfd, 0xb5, 0xef, 0x0f, 0xd6, 0xd5, 0x6f, 0x80, 0x2f, 0xcf,
+       0x9b, 0x06, 0xcd, 0xe2, 0xb0, 0x1a, 0xd8, 0x62, 0x38, 0x6f, 0x23, 0x26,
+       0x3a, 0x37, 0xa9, 0x54, 0xca, 0xb4, 0x90, 0x91, 0x59, 0x00, 0xed, 0x29,
+       0xcb, 0xb7, 0x7b, 0xb6, 0x8d, 0x45, 0xd0, 0x9f, 0x71, 0x07, 0xe1, 0x17,
+       0xd8, 0x6e, 0xc0, 0x17, 0xe8, 0x2f, 0x82, 0xfe, 0x4c, 0xa3, 0x85, 0xbe,
+       0xa6, 0x85, 0xb1, 0x36, 0xdc, 0x0f, 0x44, 0x6d, 0x86, 0xeb, 0x1e, 0xa5,
+       0x3b, 0xdc, 0x84, 0xe2, 0x3c, 0xc5, 0x7e, 0xb9, 0x9c, 0x81, 0x5d, 0x29,
+       0x65, 0x8b, 0xd7, 0x56, 0x69, 0x71, 0x03, 0x86, 0xec, 0xb2, 0x6f, 0xb3,
+       0xb6, 0x33, 0x58, 0x4a, 0xa9, 0xd2, 0xf7, 0x10, 0x1d, 0xac, 0x68, 0x80,
+       0xe1, 0x31, 0xcf, 0xfb, 0x73, 0x63, 0x95, 0x5e, 0xf8, 0x52, 0x1e, 0x5f,
+       0xf5, 0xa6, 0x2c, 0x7f, 0xee, 0x97, 0x2b, 0x0f, 0xf0, 0x19, 0x61, 0x2f,
+       0x94, 0x2e, 0x5b, 0x3f, 0xf7, 0xa0, 0xbf, 0x5b, 0x70, 0x3e, 0x9e, 0x8e,
+       0x31, 0xe6, 0xeb, 0x2c, 0x29, 0x87, 0x4c, 0xd1, 0xdb, 0x1a, 0xf8, 0xbc,
+       0x43, 0x98, 0x3c, 0x50, 0x29, 0xf7, 0xb4, 0xd2, 0x55, 0x95, 0x63, 0xeb,
+       0x65, 0x38, 0x01, 0xa7, 0xb2, 0x0f, 0xf2, 0x28, 0x77, 0x37, 0xcd, 0xc5,
+       0x0a, 0x15, 0x8f, 0xd6, 0x2c, 0x1f, 0x07, 0xe3, 0x78, 0xbe, 0x22, 0x7a,
+       0x63, 0xb4, 0x31, 0xd6, 0x19, 0x67, 0x89, 0xf6, 0x65, 0x16, 0x49, 0xe2,
+       0xf6, 0xc4, 0x36, 0x71, 0x93, 0x85, 0x4a, 0xb9, 0xbb, 0x69, 0x9c, 0xca,
+       0x83, 0x96, 0xd8, 0xbf, 0x81, 0xdb, 0xbf, 0x89, 0xbb, 0x8b, 0xd2, 0xdd,
+       0x8c, 0x2f, 0x7a, 0xdb, 0x36, 0x69, 0xa7, 0x03, 0x7e, 0x7a, 0xda, 0x36,
+       0x69, 0x98, 0x4c, 0xb3, 0x69, 0x9c, 0x61, 0x9a, 0x7b, 0x36, 0x69, 0x0e,
+       0x6f, 0xe5, 0xe7, 0x28, 0xc1, 0x07, 0xc5, 0x5a, 0x73, 0xb4, 0xff, 0x62,
+       0x65, 0x60, 0xfc, 0x0e, 0x42, 0x8c, 0x1c, 0xde, 0x11, 0xf8, 0x70, 0x6d,
+       0xbf, 0x03, 0x59, 0x69, 0xc4, 0x3e, 0x51, 0xa1, 0x32, 0xce, 0xf9, 0x81,
+       0x3a, 0xed, 0x5f, 0xab, 0x53, 0xa0, 0x4b, 0xac, 0x13, 0x6f, 0xc1, 0xc6,
+       0xa8, 0xb4, 0x3b, 0x17, 0x9f, 0xd4, 0x72, 0x3a, 0x6c, 0x8d, 0xc6, 0xcb,
+       0xf0, 0xe1, 0x6a, 0x6e, 0xef, 0xeb, 0x79, 0xf5, 0x71, 0x4f, 0x35, 0xd9,
+       0x1f, 0xc6, 0x47, 0x9d, 0x2c, 0xe6, 0xeb, 0x6c, 0x5b, 0xf0, 0x2b, 0x0d,
+       0xa6, 0xfd, 0x4c, 0x17, 0x75, 0x22, 0x8e, 0xd6, 0xcf, 0xec, 0xf2, 0x6d,
+       0x87, 0x34, 0x0d, 0xbe, 0x79, 0x26, 0xcb, 0x71, 0xbf, 0x35, 0x06, 0xf8,
+       0x49, 0x35, 0x37, 0xd6, 0x77, 0xa4, 0x7e, 0x67, 0x5f, 0xb1, 0x5e, 0xea,
+       0x2b, 0x56, 0x74, 0xb6, 0x13, 0xe1, 0x64, 0xd1, 0x97, 0xb9, 0x54, 0x0a,
+       0x36, 0xc1, 0x6b, 0x27, 0xb1, 0xe6, 0x0f, 0x60, 0x7f, 0x6c, 0xdf, 0x44,
+       0xe3, 0x2e, 0xd6, 0x18, 0xf9, 0x00, 0xe7, 0x0e, 0xde, 0xe0, 0xd3, 0x6c,
+       0xec, 0x5a, 0x8c, 0xfc, 0x6b, 0x60, 0x9f, 0xdc, 0x7f, 0xc7, 0xf3, 0xe3,
+       0xc3, 0xdd, 0x5d, 0xfe, 0xdc, 0x8f, 0x03, 0x9b, 0x0e, 0x69, 0x31, 0x9d,
+       0x8c, 0x32, 0x8e, 0x1c, 0x66, 0xbc, 0xa1, 0x29, 0xec, 0x9f, 0xf3, 0x2e,
+       0xe7, 0x1e, 0x9c, 0x77, 0x4c, 0x07, 0x7e, 0x8e, 0x6c, 0xe4, 0x4f, 0x9e,
+       0x40, 0x2e, 0x52, 0x84, 0xdd, 0x68, 0xb9, 0x2b, 0x34, 0x23, 0x7d, 0x24,
+       0xc5, 0x5a, 0x72, 0x8f, 0x01, 0xe6, 0xdf, 0x60, 0x73, 0xdd, 0x5d, 0x81,
+       0x1e, 0x06, 0x3e, 0x5e, 0xfa, 0x5d, 0xc0, 0xbe, 0xb5, 0x0d, 0xf6, 0xcd,
+       0x66, 0x58, 0xbc, 0x5f, 0xdf, 0xf6, 0xfe, 0x9f, 0xd9, 0x7e, 0xf1, 0x6e,
+       0x15, 0xfe, 0xb4, 0x35, 0xb0, 0xfd, 0x8b, 0x54, 0x84, 0x6f, 0xd5, 0x4c,
+       0xce, 0x2d, 0x0f, 0x02, 0x17, 0xe3, 0x3a, 0x78, 0x84, 0xbf, 0x40, 0x8c,
+       0x85, 0xbc, 0x11, 0x13, 0x92, 0x37, 0x72, 0x3e, 0x05, 0xd8, 0x34, 0x60,
+       0xd9, 0xff, 0x32, 0xec, 0x85, 0x38, 0xcb, 0xbc, 0x58, 0x67, 0x1c, 0xf6,
+       0x55, 0xe4, 0x39, 0xd9, 0x36, 0x68, 0x94, 0xf7, 0x82, 0x6a, 0x86, 0xb0,
+       0x21, 0xdd, 0xed, 0xb0, 0x9c, 0xdf, 0x30, 0xed, 0xae, 0x20, 0x6f, 0x18,
+       0x23, 0xbb, 0x61, 0xe3, 0x57, 0xa2, 0xa9, 0xa7, 0x90, 0xbb, 0x99, 0x2d,
+       0x2c, 0x0b, 0x9e, 0xd7, 0x7d, 0x19, 0x85, 0x78, 0xa5, 0x9e, 0xad, 0xe3,
+       0xdf, 0x4a, 0x6c, 0xfa, 0x4a, 0xb6, 0x34, 0xb2, 0x11, 0x2b, 0x20, 0xe3,
+       0xf4, 0xa4, 0xc8, 0x25, 0x29, 0x5f, 0xf7, 0xe5, 0x8b, 0xf8, 0x0c, 0xff,
+       0x28, 0xfd, 0x07, 0xce, 0x3d, 0xf4, 0x83, 0xe1, 0x99, 0xb3, 0x9e, 0xd9,
+       0x38, 0x9b, 0x34, 0x74, 0x69, 0x0c, 0xb8, 0x74, 0x14, 0x34, 0x38, 0x6e,
+       0x5b, 0x22, 0x97, 0xa0, 0xa2, 0xce, 0xf9, 0x85, 0xcc, 0x0d, 0x6d, 0xf6,
+       0x03, 0x22, 0xd7, 0x86, 0x39, 0xee, 0xff, 0x41, 0x97, 0x7f, 0xd6, 0x1d,
+       0x3c, 0x1e, 0x17, 0xb9, 0xae, 0x6d, 0xf3, 0x7f, 0xd7, 0xe1, 0xf3, 0x26,
+       0xc7, 0x98, 0xff, 0xc9, 0xb6, 0xf1, 0xa3, 0x89, 0xad, 0xe3, 0xaf, 0xf6,
+       0x85, 0xfa, 0x20, 0x72, 0x8f, 0x05, 0xfc, 0xb2, 0x9e, 0x6e, 0xe7, 0xf5,
+       0x17, 0xd1, 0x97, 0x3f, 0x01, 0x4d, 0xa9, 0xe3, 0xbf, 0x80, 0xbe, 0x6c,
+       0xc0, 0x5e, 0x43, 0x5f, 0x9a, 0x79, 0xd8, 0xa8, 0x3b, 0xaa, 0x02, 0x39,
+       0xac, 0x93, 0xdd, 0x9b, 0x2e, 0xc3, 0xc6, 0x0b, 0x0d, 0xc8, 0x6e, 0x23,
+       0xae, 0x6e, 0xc0, 0x94, 0x36, 0x61, 0xfc, 0xb8, 0x53, 0x68, 0x78, 0xc8,
+       0xfb, 0x9a, 0x63, 0x70, 0x06, 0xfd, 0x12, 0xf6, 0xba, 0x42, 0x53, 0xee,
+       0x9a, 0x2d, 0xcc, 0x93, 0x32, 0x6f, 0x15, 0xe6, 0x93, 0x4a, 0x61, 0x91,
+       0x73, 0xda, 0x18, 0xfa, 0xb2, 0x3e, 0x41, 0x8c, 0x3b, 0xa5, 0xd8, 0x67,
+       0xe7, 0x90, 0xcf, 0x2e, 0xe1, 0x77, 0x0e, 0xbf, 0x3a, 0x7e, 0x61, 0xdd,
+       0xf0, 0x2d, 0xd4, 0x1d, 0xd2, 0xdf, 0x23, 0x36, 0xf9, 0xeb, 0xff, 0x74,
+       0x09, 0xf9, 0xf4, 0x5c, 0x92, 0x9e, 0x30, 0x45, 0x8f, 0xf0, 0x7d, 0x9c,
+       0x8d, 0x5c, 0x5c, 0x7f, 0x8b, 0x7e, 0x25, 0xc8, 0xe9, 0x88, 0xde, 0xa8,
+       0xe2, 0x2c, 0x87, 0x0f, 0x05, 0xfe, 0xe9, 0xe4, 0x57, 0x1c, 0xe9, 0xcb,
+       0x83, 0x9c, 0x0d, 0x7e, 0xc7, 0x96, 0x50, 0xaf, 0x40, 0x3e, 0x0a, 0xfd,
+       0x0c, 0x7a, 0xfc, 0x46, 0xb5, 0x1d, 0xfc, 0x98, 0x54, 0x9c, 0x30, 0x46,
+       0x49, 0x19, 0xd0, 0x77, 0x28, 0xed, 0xc8, 0xdb, 0xe0, 0x77, 0xe4, 0x98,
+       0x65, 0x46, 0xc7, 0x17, 0x2a, 0x02, 0xb0, 0x90, 0x79, 0x16, 0x7d, 0xe8,
+       0xdf, 0xe5, 0x2a, 0xe3, 0x09, 0x7a, 0xb3, 0xaa, 0xd2, 0xbf, 0x20, 0x0f,
+       0xc4, 0xbb, 0xe3, 0xb0, 0xc1, 0x5e, 0xc4, 0xab, 0x7e, 0x95, 0xf6, 0x72,
+       0xcc, 0xd8, 0xa3, 0xe1, 0x59, 0xc0, 0xef, 0x20, 0xf2, 0xc2, 0x6b, 0xe0,
+       0x5c, 0x03, 0x9e, 0x79, 0x8b, 0x01, 0x87, 0xe1, 0x35, 0xf0, 0xd6, 0x09,
+       0x1d, 0x34, 0xf4, 0x49, 0xfa, 0x8c, 0x2e, 0x73, 0x27, 0x85, 0xe7, 0x7d,
+       0x3f, 0xf9, 0xd1, 0x79, 0x96, 0xb3, 0x0a, 0x1d, 0xe2, 0x31, 0xbf, 0x63,
+       0x7f, 0xce, 0xf4, 0x8c, 0x51, 0x1b, 0x9b, 0xb9, 0x5c, 0xf5, 0xfb, 0xe1,
+       0x1c, 0x29, 0x61, 0x4c, 0x65, 0x3f, 0x5d, 0x80, 0xad, 0xf2, 0x78, 0x9c,
+       0xe4, 0x19, 0x6c, 0x39, 0x4f, 0xa9, 0x47, 0xc7, 0x66, 0x4c, 0x3e, 0x57,
+       0x9d, 0xa6, 0x2b, 0xe1, 0xb9, 0xf2, 0x19, 0xa1, 0x0e, 0xad, 0x3e, 0x89,
+       0x73, 0x15, 0x41, 0xcd, 0x02, 0x3f, 0x30, 0xc7, 0xe7, 0x8b, 0x3a, 0xb2,
+       0x8a, 0x3c, 0xac, 0x4a, 0x09, 0xbf, 0xe6, 0x3a, 0x85, 0x3a, 0x05, 0xe7,
+       0x57, 0x99, 0x03, 0x8d, 0x24, 0x9e, 0x4b, 0x78, 0xa6, 0xf0, 0x3c, 0x87,
+       0x67, 0x3f, 0x9e, 0x75, 0xb6, 0x8f, 0x20, 0xef, 0xf9, 0x08, 0x3f, 0xb0,
+       0x93, 0x02, 0xdb, 0x34, 0xfd, 0x65, 0x23, 0x47, 0x3f, 0x68, 0x8c, 0xd2,
+       0x5f, 0x34, 0xb2, 0xf4, 0xfd, 0x86, 0x45, 0xcf, 0x36, 0x86, 0xe9, 0x7b,
+       0x8d, 0x0c, 0xd7, 0x90, 0xc8, 0xe1, 0xd2, 0xf0, 0xcd, 0x17, 0xe8, 0x2b,
+       0x6e, 0x03, 0x3e, 0x47, 0xfa, 0xcb, 0xe3, 0x76, 0xfd, 0x3a, 0x2a, 0x3e,
+       0xa5, 0x23, 0xcf, 0x54, 0xb9, 0x8e, 0xa3, 0x47, 0xad, 0xbb, 0x13, 0x7c,
+       0xf6, 0xc2, 0xe4, 0xba, 0xe6, 0x04, 0xc3, 0xa1, 0x1e, 0x56, 0x90, 0xbf,
+       0xb4, 0xd0, 0x64, 0xd2, 0x58, 0x71, 0xd4, 0x74, 0xe0, 0x8f, 0x26, 0x00,
+       0x87, 0x35, 0xdd, 0x38, 0xad, 0x9d, 0x86, 0x2d, 0x58, 0xa8, 0xa5, 0x93,
+       0x31, 0xf8, 0x3e, 0x99, 0x9f, 0x48, 0xdf, 0xe2, 0xfb, 0xd2, 0xb0, 0xc6,
+       0xe4, 0x39, 0x3b, 0x98, 0xe3, 0xf8, 0xa8, 0x03, 0xb6, 0x11, 0xc4, 0x90,
+       0xed, 0x34, 0xd9, 0x37, 0x4e, 0x04, 0xfe, 0x71, 0x85, 0x1e, 0x76, 0x07,
+       0xec, 0xb7, 0x11, 0x7b, 0x94, 0x96, 0x30, 0x2f, 0xda, 0x0d, 0xde, 0x3c,
+       0xef, 0x30, 0xea, 0xf3, 0x74, 0x42, 0xa3, 0xbf, 0x9f, 0x35, 0xf4, 0xc3,
+       0x02, 0x01, 0xae, 0xdd, 0xf3, 0xc6, 0x4d, 0xa3, 0x64, 0x8b, 0x0e, 0xfa,
+       0xa7, 0x53, 0x1c, 0x93, 0xd7, 0x8f, 0xbd, 0x08, 0x3d, 0xa8, 0x2d, 0xb5,
+       0x52, 0xad, 0xa6, 0xd1, 0xe5, 0x91, 0x01, 0xb9, 0x6e, 0xad, 0x9e, 0x40,
+       0x9e, 0xd7, 0x46, 0x8b, 0xbd, 0x52, 0xd9, 0xe1, 0xb7, 0x33, 0xd2, 0x6f,
+       0x3b, 0x26, 0x9e, 0xf5, 0xb4, 0xbe, 0x95, 0x97, 0x67, 0xa9, 0xe8, 0x76,
+       0xa2, 0x42, 0xd9, 0x0d, 0x99, 0x70, 0x7f, 0x40, 0x77, 0x04, 0x62, 0xa0,
+       0x36, 0xa0, 0x1f, 0x12, 0xff, 0xed, 0x7d, 0x51, 0x63, 0x39, 0xbe, 0x8e,
+       0xd8, 0xc2, 0xb1, 0x52, 0x91, 0x7a, 0xb7, 0xb0, 0xf4, 0xa6, 0xce, 0xfe,
+       0xe5, 0x7b, 0xf5, 0xdd, 0xc1, 0x98, 0xfd, 0x3b, 0x8f, 0xdb, 0xe9, 0xfb,
+       0xb5, 0x9d, 0xb4, 0x58, 0xe3, 0xf7, 0xad, 0xb4, 0x50, 0x1b, 0xb8, 0xf2,
+       0x90, 0xe8, 0xa5, 0xd5, 0xeb, 0x6e, 0xd6, 0x3f, 0x2f, 0x20, 0x93, 0x89,
+       0x0f, 0xe9, 0xdd, 0x91, 0x2e, 0x7a, 0xf5, 0x5e, 0xa3, 0x7a, 0xbf, 0x80,
+       0x3e, 0x8e, 0xc4, 0xd9, 0xce, 0xd0, 0xe7, 0x79, 0xe3, 0x4a, 0x5a, 0xb0,
+       0x9e, 0xbd, 0x0c, 0xfd, 0x32, 0x4e, 0xfa, 0x3a, 0xc9, 0xb4, 0x99, 0x2e,
+       0xce, 0xc7, 0x7c, 0x05, 0x34, 0xf1, 0xae, 0x3e, 0x00, 0x5a, 0xaf, 0x48,
+       0x59, 0x1c, 0xb6, 0x8c, 0x2b, 0x08, 0x51, 0xde, 0x65, 0x73, 0x20, 0x23,
+       0xc4, 0x6e, 0xaa, 0xa5, 0x6e, 0xd6, 0xbf, 0x8b, 0x78, 0x80, 0x9a, 0xab,
+       0xb4, 0x4e, 0xeb, 0xc7, 0x2e, 0x9a, 0xac, 0x8b, 0x6c, 0xc3, 0x3f, 0x44,
+       0x4e, 0xaa, 0xd3, 0x53, 0x75, 0xf6, 0x5d, 0x4c, 0x8b, 0xeb, 0x82, 0x7d,
+       0xfa, 0xdd, 0xe0, 0xc1, 0x19, 0xc6, 0x3b, 0xcc, 0xab, 0x9f, 0xe5, 0x73,
+       0x6b, 0x61, 0xdc, 0x4c, 0x9a, 0x37, 0xb3, 0x45, 0x46, 0x03, 0xfa, 0x5e,
+       0xc1, 0xeb, 0xbd, 0x8b, 0x75, 0xdf, 0x01, 0xaf, 0x03, 0xc0, 0x45, 0x0c,
+       0x4d, 0x35, 0xaf, 0xf1, 0x9a, 0x5c, 0xe3, 0x54, 0x1d, 0x39, 0xe0, 0xc6,
+       0x1a, 0x98, 0xab, 0x0b, 0xec, 0xf3, 0x57, 0x65, 0xfe, 0xac, 0x22, 0xff,
+       0xb9, 0x3c, 0xf2, 0x4c, 0x90, 0x5f, 0x3c, 0x07, 0x59, 0xc7, 0xe8, 0xb5,
+       0x59, 0xae, 0x2f, 0x0f, 0x51, 0x39, 0xb1, 0x7e, 0x6c, 0xca, 0x44, 0x4d,
+       0x8f, 0x38, 0x50, 0xde, 0x37, 0xe0, 0xeb, 0x55, 0x3f, 0xe3, 0x3c, 0x27,
+       0xcf, 0xa4, 0x2c, 0x5a, 0xe9, 0x8b, 0x5a, 0x1a, 0xf8, 0x3c, 0x77, 0x29,
+       0x38, 0xcf, 0x6f, 0x83, 0x1f, 0xf4, 0xeb, 0x3d, 0x81, 0xff, 0x4b, 0x40,
+       0x57, 0x87, 0xf4, 0xc3, 0x14, 0x0b, 0xfc, 0x5f, 0x82, 0x5e, 0x3d, 0xad,
+       0x42, 0x87, 0x58, 0x7f, 0xfa, 0xbb, 0x37, 0xf5, 0x87, 0xdf, 0xad, 0x1f,
+       0x73, 0xc0, 0x63, 0x7e, 0xae, 0x95, 0x0a, 0xd5, 0x18, 0x4d, 0x65, 0x91,
+       0x73, 0x23, 0xfe, 0xe4, 0xa1, 0x4b, 0x85, 0x1a, 0xeb, 0x72, 0x29, 0xd0,
+       0xe5, 0x78, 0x40, 0xfb, 0x6f, 0xa0, 0xcb, 0x46, 0x7a, 0x55, 0x70, 0x7d,
+       0xd5, 0x27, 0x6b, 0x64, 0x15, 0xf6, 0x55, 0xac, 0x70, 0x2c, 0x62, 0xdb,
+       0xa2, 0xe3, 0xcc, 0x7f, 0xb1, 0x32, 0x2a, 0x8a, 0x8d, 0xac, 0x28, 0xba,
+       0xcc, 0xdf, 0x3e, 0xf0, 0xad, 0xc8, 0x3a, 0x78, 0xa1, 0xf1, 0xae, 0xb7,
+       0xb0, 0x6f, 0x07, 0xfa, 0xd0, 0xfd, 0x71, 0x3e, 0xdf, 0xeb, 0x99, 0xaf,
+       0xb4, 0x2d, 0x58, 0xde, 0x49, 0x5a, 0x1e, 0x7c, 0xa9, 0x8b, 0x73, 0xb4,
+       0xb3, 0x83, 0x4c, 0x1f, 0x7c, 0x24, 0x93, 0xb4, 0xe8, 0xf2, 0x1a, 0x2c,
+       0x17, 0xf8, 0xba, 0x39, 0x9d, 0x1e, 0x96, 0xe7, 0xc7, 0xba, 0xc5, 0xf7,
+       0x4d, 0x2a, 0xe5, 0x13, 0x03, 0xfa, 0x43, 0x64, 0x5c, 0x59, 0x53, 0x8d,
+       0xea, 0x24, 0xe2, 0xea, 0xc2, 0xbc, 0x4a, 0x7b, 0x64, 0x1d, 0xc6, 0x67,
+       0x64, 0x9c, 0x84, 0x35, 0x06, 0x7b, 0xff, 0x8d, 0xa6, 0xbd, 0x77, 0xd2,
+       0xc5, 0xd3, 0x9f, 0x85, 0xdd, 0xb3, 0x5c, 0xb5, 0xf4, 0x11, 0xe4, 0x19,
+       0x73, 0x04, 0xf9, 0x22, 0x7f, 0xb6, 0x53, 0xe1, 0xb9, 0xb0, 0xbc, 0x77,
+       0x49, 0xf9, 0x0b, 0x29, 0xff, 0x1b, 0xa8, 0xdc, 0xeb, 0xdb, 0x38, 0xbf,
+       0x13, 0xa0, 0xe1, 0xbf, 0xe3, 0xf1, 0x67, 0x90, 0x1f, 0xf1, 0xbb, 0x9a,
+       0x8f, 0x47, 0x3d, 0x4c, 0x07, 0xef, 0xfe, 0x10, 0x6b, 0xb2, 0x8c, 0xc3,
+       0xf9, 0x0e, 0xf2, 0x6d, 0x29, 0x94, 0x3b, 0x12, 0x8c, 0x7a, 0x92, 0x7e,
+       0xad, 0x9e, 0xa2, 0x89, 0x7a, 0x3f, 0x15, 0xea, 0x69, 0x9c, 0xc1, 0x13,
+       0xdd, 0xbc, 0xb7, 0xfc, 0x12, 0xf6, 0x23, 0x98, 0xd7, 0x1a, 0x1d, 0x71,
+       0x43, 0x7e, 0xe2, 0x01, 0x7f, 0x5a, 0x30, 0x8e, 0x05, 0x3c, 0x34, 0xd3,
+       0x8b, 0x83, 0x96, 0x0d, 0x3a, 0x67, 0x02, 0x3a, 0xec, 0x47, 0xc0, 0xeb,
+       0x44, 0x8a, 0x96, 0x5c, 0xe6, 0x63, 0x27, 0x95, 0x93, 0xdc, 0x7f, 0x0e,
+       0x7a, 0xc6, 0x74, 0x76, 0x70, 0x7e, 0xb3, 0x45, 0xc6, 0x47, 0xeb, 0x25,
+       0xc8, 0x98, 0xe5, 0xcb, 0x70, 0x71, 0x5a, 0xf8, 0x25, 0x3e, 0xbf, 0x21,
+       0xe4, 0xf8, 0xac, 0x0b, 0x3b, 0x03, 0xbd, 0xf2, 0xd7, 0x2c, 0xcc, 0x75,
+       0xe2, 0xac, 0x78, 0xdd, 0x76, 0xba, 0x07, 0x76, 0x9f, 0xaf, 0xf1, 0xfa,
+       0x13, 0xd0, 0xa3, 0x1f, 0xcb, 0xf5, 0x0b, 0x4b, 0xbd, 0x01, 0x3e, 0xe3,
+       0x76, 0x6e, 0xc3, 0x6d, 0xa5, 0x03, 0x55, 0xfd, 0x63, 0xf0, 0x7f, 0x13,
+       0xf8, 0x82, 0xce, 0x64, 0x19, 0x9f, 0xe9, 0x00, 0xae, 0x96, 0xfc, 0x04,
+       0x3a, 0x09, 0x59, 0xef, 0xe7, 0x6b, 0xad, 0x94, 0xaf, 0x86, 0xb4, 0x98,
+       0xce, 0x87, 0xa8, 0x87, 0xbf, 0x2c, 0x69, 0x4d, 0x49, 0x5a, 0x78, 0x5f,
+       0x63, 0x9f, 0x73, 0x3b, 0xf0, 0xe3, 0xec, 0xff, 0x69, 0x21, 0xd1, 0x41,
+       0x0b, 0xb2, 0xa6, 0x6f, 0xf7, 0x7d, 0x4d, 0xa2, 0x0d, 0xef, 0x77, 0xc1,
+       0xe6, 0x87, 0x90, 0x5b, 0x74, 0x62, 0x2e, 0xbd, 0x6d, 0x6e, 0x3b, 0xff,
+       0xb1, 0x6d, 0xfc, 0xeb, 0x80, 0xeb, 0xc1, 0x9a, 0x3e, 0x5c, 0x01, 0x70,
+       0xd3, 0x73, 0x90, 0xb3, 0xc5, 0x7e, 0x85, 0xe3, 0xe4, 0x75, 0x92, 0x97,
+       0xe9, 0x25, 0x05, 0x70, 0xbd, 0xc0, 0x0d, 0xc7, 0xbe, 0x1c, 0xaa, 0xa0,
+       0xf3, 0xcd, 0x9a, 0xbc, 0xbb, 0xc0, 0x19, 0xf4, 0x24, 0x78, 0xef, 0xe5,
+       0xda, 0xa7, 0xc9, 0xec, 0xba, 0x26, 0x79, 0xb1, 0xac, 0x98, 0x5f, 0xe6,
+       0x15, 0x7a, 0x8a, 0x38, 0xe4, 0x58, 0xa8, 0x0b, 0x13, 0x2a, 0x15, 0xb2,
+       0x3a, 0xf2, 0x73, 0xbe, 0xb7, 0x65, 0xbb, 0xd4, 0xf9, 0xae, 0x34, 0x26,
+       0x4c, 0x8e, 0xb5, 0x9a, 0xdc, 0xfb, 0x91, 0x25, 0xbe, 0xbb, 0x4d, 0xf3,
+       0x5d, 0x5f, 0x86, 0xb0, 0xf7, 0x07, 0x97, 0x4c, 0x7a, 0xa4, 0x9e, 0xa1,
+       0x87, 0xea, 0x86, 0x7e, 0x3f, 0x7c, 0x40, 0x71, 0xe3, 0x4e, 0xf7, 0x73,
+       0x09, 0xae, 0x45, 0x34, 0xe4, 0x81, 0x2d, 0xa6, 0x9f, 0x17, 0x94, 0xb9,
+       0x66, 0x9b, 0x33, 0xf8, 0x1e, 0x47, 0xaf, 0xd1, 0xf6, 0xdc, 0xe1, 0xff,
+       0x32, 0x6f, 0xe0, 0xf5, 0xd9, 0x5f, 0x23, 0x4f, 0x70, 0x91, 0x27, 0xb8,
+       0xc8, 0x13, 0x5c, 0xe4, 0x09, 0x2e, 0xf2, 0x04, 0x17, 0x79, 0x82, 0x8b,
+       0x3c, 0xc1, 0x45, 0x9e, 0x80, 0xd8, 0xed, 0xd7, 0x0b, 0x63, 0xc8, 0x7f,
+       0xe1, 0xbf, 0xdc, 0xcf, 0x43, 0x4e, 0x7c, 0xdf, 0xc9, 0x31, 0x87, 0x63,
+       0x33, 0xcf, 0xad, 0xee, 0x70, 0xf8, 0xdc, 0xa4, 0xef, 0xbb, 0x13, 0x73,
+       0xe3, 0x41, 0x3e, 0xc2, 0x30, 0x61, 0xec, 0x66, 0x38, 0x1a, 0x75, 0x2c,
+       0x05, 0x36, 0xc6, 0xf9, 0x8a, 0x1f, 0xb3, 0xfc, 0x5c, 0xf9, 0x75, 0xe4,
+       0x2c, 0x69, 0xe4, 0x2c, 0xfd, 0xc8, 0x4f, 0xf8, 0x8e, 0x3b, 0xbc, 0x63,
+       0xb2, 0x95, 0xc3, 0xee, 0x98, 0x72, 0xb7, 0xcb, 0xb9, 0xb4, 0x99, 0x2e,
+       0x0a, 0x31, 0xd7, 0x43, 0x1e, 0xe5, 0x47, 0xbe, 0x86, 0xbc, 0xf5, 0x9b,
+       0xf2, 0x3e, 0x6d, 0x7c, 0x90, 0xcf, 0x7c, 0xe5, 0x1a, 0xb9, 0x6b, 0x28,
+       0x5f, 0xff, 0x1e, 0x50, 0x2c, 0xb0, 0xfc, 0x88, 0xba, 0xcf, 0x43, 0xe0,
+       0xe7, 0x63, 0x94, 0x58, 0xde, 0x89, 0x39, 0x9d, 0x7a, 0xe4, 0x5d, 0x12,
+       0x8e, 0xf2, 0xbc, 0xd6, 0x43, 0xed, 0x26, 0x89, 0xf3, 0x7c, 0xe3, 0xc0,
+       0x74, 0xd9, 0xbf, 0x5e, 0x3a, 0x96, 0xaf, 0x5d, 0x92, 0x3a, 0x75, 0xb8,
+       0x5e, 0x40, 0x7d, 0xd4, 0x07, 0x18, 0x0d, 0xb5, 0x55, 0x48, 0x9b, 0x69,
+       0x5e, 0x4d, 0xc8, 0x9a, 0xe7, 0xfc, 0xc6, 0x79, 0xe2, 0xac, 0x79, 0x9d,
+       0x4b, 0xc7, 0xca, 0x55, 0x23, 0xc5, 0xb5, 0xb2, 0xad, 0x5f, 0x3a, 0x76,
+       0x02, 0x34, 0x16, 0x91, 0x1b, 0xa8, 0x72, 0xed, 0x4b, 0xc7, 0xa6, 0xab,
+       0xfe, 0x7d, 0x96, 0xcf, 0x03, 0xe2, 0x60, 0xb6, 0x9d, 0xd4, 0x05, 0xff,
+       0x5e, 0x4b, 0x48, 0x5c, 0xc6, 0x63, 0x7c, 0x0d, 0x78, 0x7c, 0x6e, 0x19,
+       0xe0, 0xf2, 0xd9, 0x31, 0x0f, 0x97, 0x8e, 0x95, 0x6a, 0xcd, 0x3c, 0x30,
+       0x1d, 0xa6, 0x1b, 0xee, 0x87, 0xf7, 0x92, 0x20, 0xb1, 0xec, 0x79, 0xc5,
+       0x91, 0xfe, 0x20, 0xef, 0x3a, 0x81, 0xfc, 0x4e, 0x93, 0x7a, 0xee, 0x8f,
+       0xff, 0x4c, 0xc6, 0xa9, 0xb4, 0xe0, 0x79, 0x7e, 0xe2, 0x5d, 0xf6, 0x3b,
+       0x98, 0xc3, 0x78, 0x31, 0x84, 0x15, 0x01, 0x6c, 0x47, 0x93, 0x3c, 0x5b,
+       0x82, 0xf5, 0x98, 0x27, 0xde, 0xe7, 0xcf, 0xb1, 0x7f, 0x79, 0x07, 0xc7,
+       0xf9, 0x18, 0xd6, 0xc5, 0x59, 0xba, 0xff, 0x5b, 0xd9, 0x37, 0xef, 0x89,
+       0x65, 0xaa, 0x01, 0x87, 0xe1, 0x99, 0x46, 0x88, 0x83, 0x17, 0xe7, 0x7d,
+       0x3c, 0xb1, 0x71, 0xff, 0xf7, 0x49, 0xeb, 0x36, 0xf3, 0x1a, 0xae, 0x1f,
+       0xd2, 0xc9, 0xf8, 0xe7, 0xb6, 0x81, 0x2f, 0xff, 0x4f, 0x31, 0x3c, 0xa1,
+       0x8b, 0x1f, 0xb9, 0x47, 0xcd, 0x34, 0xd5, 0xa1, 0xe1, 0xfd, 0x05, 0xdf,
+       0x07, 0x70, 0x7d, 0xcf, 0xdf, 0x1a, 0x9a, 0x6b, 0xc5, 0x67, 0x83, 0x58,
+       0xd6, 0x47, 0xb6, 0xc6, 0x75, 0xc3, 0x85, 0x60, 0xbc, 0x0b, 0xb1, 0x8d,
+       0xc7, 0x0d, 0xc8, 0x17, 0xba, 0x6c, 0xb5, 0x07, 0x75, 0x4b, 0xc2, 0xff,
+       0x26, 0x94, 0x61, 0x3b, 0xe2, 0xba, 0xaf, 0x2d, 0x98, 0x0b, 0xed, 0x88,
+       0xfd, 0xb0, 0x16, 0xcc, 0xb1, 0xbf, 0x15, 0xa8, 0x5d, 0xb8, 0x0f, 0x3a,
+       0x8b, 0xcd, 0xb6, 0x14, 0x3e, 0x13, 0x74, 0x6e, 0x3e, 0xf4, 0x5b, 0xf0,
+       0x29, 0x83, 0x5a, 0xe0, 0xfb, 0xe3, 0xf0, 0x7d, 0x9d, 0x74, 0x00, 0x3e,
+       0xeb, 0x20, 0x7c, 0xd6, 0x21, 0xd4, 0x8b, 0x63, 0x4b, 0xcd, 0xf7, 0xbc,
+       0x5c, 0xa3, 0x76, 0x2a, 0x47, 0xe4, 0xf9, 0x97, 0x3c, 0xd5, 0xfc, 0x10,
+       0x3a, 0xc0, 0x75, 0x57, 0xa8, 0x13, 0xf0, 0xb7, 0x56, 0x02, 0x3a, 0xb1,
+       0xfd, 0x3e, 0x39, 0x03, 0xdb, 0x68, 0xb7, 0x85, 0xcc, 0xe5, 0x7c, 0xd9,
+       0x97, 0x6b, 0xbe, 0xec, 0xe1, 0x97, 0x41, 0x5f, 0xa3, 0x52, 0x5d, 0xa7,
+       0x12, 0xd6, 0x2d, 0x61, 0xdd, 0x12, 0xea, 0xbc, 0xe9, 0x7a, 0xf3, 0x77,
+       0xaf, 0x8e, 0x80, 0x77, 0xc6, 0x0d, 0xfb, 0x7a, 0xd3, 0xfe, 0xc3, 0xe7,
+       0x49, 0xc8, 0xff, 0x11, 0xc8, 0xff, 0x28, 0xea, 0x9b, 0xdf, 0x47, 0x7d,
+       0xf3, 0x7b, 0xa8, 0x6f, 0x8e, 0xa0, 0xbe, 0x99, 0x44, 0x7d, 0xf3, 0x65,
+       0xf8, 0x8f, 0xfb, 0xe0, 0x3f, 0x26, 0xe0, 0x3f, 0xc6, 0xe5, 0xdd, 0xd3,
+       0x61, 0x77, 0xfb, 0x9d, 0x4a, 0xb8, 0x16, 0xb7, 0x9f, 0x12, 0x99, 0x25,
+       0xec, 0x69, 0x8c, 0x6a, 0x0d, 0xae, 0x6f, 0x2c, 0x72, 0x46, 0xb9, 0xbe,
+       0x99, 0x50, 0x26, 0x91, 0xbf, 0xdf, 0x3f, 0xcc, 0x75, 0x4f, 0x42, 0xc9,
+       0xcb, 0xba, 0xc7, 0xb8, 0xe0, 0x20, 0x75, 0x43, 0xee, 0x87, 0x3d, 0x1b,
+       0xe7, 0xf2, 0xe0, 0xc5, 0xcf, 0xf9, 0xba, 0x03, 0xbf, 0x17, 0xa7, 0xc5,
+       0x59, 0xd4, 0x0c, 0xee, 0x3f, 0x28, 0x45, 0xe9, 0x1b, 0x75, 0x8c, 0x51,
+       0x2b, 0xbb, 0xaf, 0x06, 0xe3, 0x11, 0x9a, 0x9a, 0x47, 0x6d, 0x7b, 0xfa,
+       0x6f, 0x95, 0xbc, 0x1c, 0x5b, 0x18, 0x23, 0xdf, 0x3d, 0xfd, 0xd7, 0xc1,
+       0xb8, 0x14, 0xe8, 0x43, 0xc0, 0xab, 0x6e, 0xe1, 0xd9, 0x15, 0xe4, 0x1c,
+       0x2f, 0xf6, 0x6c, 0xfd, 0x3f, 0xef, 0xb8, 0xb5, 0x28, 0x64, 0x1e, 0xdf,
+       0xe5, 0xd7, 0x67, 0xcd, 0xf3, 0x9d, 0x4d, 0xf3, 0xba, 0xfc, 0x0e, 0x5b,
+       0xac, 0xb4, 0xbd, 0x07, 0x0f, 0x4c, 0x4b, 0x83, 0x46, 0xd5, 0xa6, 0x0f,
+       0x3d, 0xfe, 0x5e, 0xe8, 0x88, 0x76, 0xf9, 0x0d, 0xcf, 0x91, 0xf7, 0x7a,
+       0xb0, 0xf3, 0x91, 0x27, 0x77, 0xf9, 0xbe, 0x80, 0xfb, 0x49, 0xc5, 0xf7,
+       0xef, 0x8f, 0x83, 0x0e, 0x64, 0xed, 0x36, 0xd7, 0x70, 0x7a, 0x70, 0x97,
+       0xa2, 0x1f, 0x9f, 0xe1, 0xb3, 0x96, 0xb4, 0xb9, 0xd6, 0xe3, 0xba, 0x2f,
+       0x8c, 0x01, 0x21, 0xad, 0xff, 0x48, 0xfa, 0x7c, 0xdf, 0x87, 0x9a, 0x8e,
+       0x61, 0xc2, 0x71, 0x73, 0xfd, 0x17, 0x0f, 0xee, 0xe1, 0x98, 0xd7, 0x58,
+       0xc0, 0xab, 0x16, 0xd0, 0xfb, 0x77, 0xcf, 0xf7, 0x3d, 0x8c, 0xaf, 0x37,
+       0xe1, 0x5f, 0x40, 0xae, 0xc7, 0x77, 0x26, 0xbb, 0xe5, 0x77, 0xc9, 0x77,
+       0x66, 0x3b, 0xe8, 0xed, 0x53, 0xc8, 0x59, 0x2d, 0x23, 0x73, 0x09, 0xb5,
+       0xc7, 0x32, 0xdb, 0xc9, 0x08, 0xf3, 0x39, 0x90, 0x9e, 0xa6, 0x9b, 0x7b,
+       0xfc, 0x5c, 0xfc, 0xab, 0xca, 0x47, 0xf9, 0x16, 0xc1, 0x3a, 0x3f, 0x6a,
+       0x5a, 0x27, 0xdd, 0xb4, 0xce, 0x0a, 0xdb, 0x6c, 0xed, 0x4b, 0xd8, 0x73,
+       0x69, 0xf7, 0xcd, 0x7a, 0x32, 0xa8, 0xcb, 0x1e, 0x1e, 0x69, 0xa3, 0x6a,
+       0xaf, 0xb1, 0xf2, 0x1a, 0xf2, 0xf5, 0xe2, 0x08, 0xe6, 0x92, 0x03, 0x78,
+       0xc7, 0xf3, 0x46, 0x8d, 0x84, 0xb1, 0x52, 0xa3, 0xcf, 0x01, 0xdf, 0x28,
+       0x11, 0xf1, 0x3c, 0xf7, 0x25, 0x6f, 0xb5, 0xc0, 0x07, 0xa4, 0xd6, 0xb0,
+       0xe7, 0x49, 0xd4, 0x5f, 0x47, 0x37, 0xea, 0x61, 0x5e, 0xe7, 0x56, 0x65,
+       0x4d, 0xe6, 0xc6, 0xfb, 0x95, 0x52, 0xd2, 0xdf, 0xe3, 0xef, 0xc2, 0x5f,
+       0xa8, 0x82, 0x71, 0xdf, 0x01, 0x6d, 0x85, 0x16, 0x4e, 0xa9, 0xf2, 0x0e,
+       0xb6, 0x38, 0xc2, 0x67, 0xcd, 0xcf, 0x8f, 0x93, 0x5d, 0xb8, 0xa7, 0x3f,
+       0x0d, 0xf6, 0x34, 0x16, 0xd4, 0xd3, 0xe1, 0x9e, 0x62, 0xf4, 0xe6, 0xac,
+       0x0e, 0xdc, 0x9b, 0x20, 0x8f, 0x02, 0x2d, 0x35, 0xd2, 0x9f, 0x42, 0xa7,
+       0xd2, 0x24, 0x1b, 0x6d, 0xdb, 0x19, 0x96, 0x36, 0x6b, 0xf8, 0xf1, 0x14,
+       0xec, 0xf0, 0x78, 0x4f, 0x78, 0x37, 0xac, 0x9a, 0x1e, 0xd7, 0x3d, 0x68,
+       0x3c, 0xdf, 0x0f, 0x5b, 0x4c, 0xc3, 0x3e, 0x39, 0x67, 0x2a, 0x70, 0xad,
+       0xc2, 0xf6, 0xa4, 0x3b, 0xaa, 0xa1, 0x4f, 0x50, 0x06, 0xf5, 0x0e, 0xef,
+       0x3f, 0x47, 0x8b, 0x8d, 0x90, 0x87, 0x2c, 0xec, 0x71, 0x14, 0xbf, 0x61,
+       0xbc, 0xb3, 0xf0, 0xe3, 0x5a, 0x69, 0x85, 0x1e, 0x95, 0xb9, 0x38, 0x72,
+       0xed, 0x41, 0xe6, 0xef, 0x4e, 0xc0, 0xb3, 0x3e, 0xb3, 0x9e, 0xde, 0x49,
+       0x4e, 0x2f, 0xfb, 0x8a, 0x14, 0x68, 0x03, 0xc7, 0x5d, 0x87, 0xad, 0xf7,
+       0xe3, 0x69, 0xe8, 0x45, 0x96, 0xad, 0xa4, 0xef, 0x79, 0x6a, 0x96, 0xbf,
+       0x51, 0x5c, 0x08, 0xc6, 0x03, 0xfa, 0x3d, 0xac, 0x7b, 0xa9, 0x1b, 0x68,
+       0x65, 0x3e, 0x8c, 0x83, 0x67, 0x60, 0x83, 0x7c, 0x67, 0x3b, 0x06, 0xb9,
+       0xf0, 0x58, 0x09, 0xe2, 0x21, 0xe6, 0x17, 0x91, 0x94, 0xb4, 0xe7, 0x68,
+       0x19, 0xf5, 0x3f, 0xf5, 0xf2, 0x13, 0xf9, 0xae, 0xbb, 0x33, 0xd0, 0xf7,
+       0xad, 0xf8, 0xaa, 0xc9, 0xfd, 0x31, 0xf0, 0xa7, 0x35, 0xe1, 0x33, 0x8e,
+       0x5f, 0x9f, 0xac, 0x11, 0xe2, 0x71, 0xca, 0xfb, 0x82, 0xc8, 0x3d, 0x4d,
+       0xbf, 0x23, 0xf7, 0x54, 0xa7, 0x23, 0xf3, 0xa8, 0x6d, 0xb3, 0x03, 0x99,
+       0x45, 0x32, 0x32, 0x27, 0x68, 0x48, 0x3f, 0x40, 0xaa, 0xfc, 0xd6, 0x97,
+       0x16, 0xde, 0x17, 0x5a, 0x72, 0x9e, 0x77, 0x06, 0xbc, 0xbf, 0x28, 0xd7,
+       0x79, 0x1a, 0xfc, 0x43, 0x56, 0xb2, 0x26, 0x61, 0x5e, 0xf1, 0x4c, 0x32,
+       0xbf, 0x15, 0x3a, 0xd2, 0xf8, 0x61, 0x70, 0x36, 0x8f, 0x90, 0xe3, 0xbe,
+       0xa5, 0x3a, 0x66, 0x05, 0xb0, 0xdf, 0x09, 0x78, 0xcb, 0x81, 0x5f, 0xac,
+       0xdf, 0x58, 0x4f, 0xb2, 0x6f, 0xe0, 0x33, 0x77, 0x90, 0x35, 0x3a, 0x23,
+       0xc8, 0xa3, 0x92, 0xd7, 0xf2, 0x03, 0x09, 0xda, 0xea, 0x07, 0x18, 0x2f,
+       0xf1, 0x31, 0xba, 0xc2, 0x7c, 0x94, 0xa4, 0xff, 0x94, 0x71, 0x4b, 0xd2,
+       0x53, 0xb7, 0xf9, 0x82, 0x6f, 0xc9, 0xe7, 0xaa, 0xca, 0xbe, 0x89, 0xe3,
+       0x1f, 0xeb, 0x70, 0x27, 0xfc, 0x1f, 0x74, 0x10, 0x76, 0x9c, 0x9f, 0xe7,
+       0xfb, 0x89, 0x41, 0xbe, 0x57, 0x3a, 0x57, 0xc0, 0xd9, 0x2e, 0xf0, 0xf7,
+       0xc7, 0xa4, 0x5f, 0x63, 0xfa, 0xf5, 0x57, 0x9a, 0x7d, 0x21, 0xda, 0x92,
+       0xf4, 0x93, 0x05, 0xf9, 0xbd, 0x31, 0x01, 0x18, 0x8f, 0x7d, 0x67, 0xd3,
+       0xdf, 0x58, 0xbc, 0x6c, 0xfb, 0x7f, 0x63, 0x11, 0x7c, 0xfb, 0xad, 0xf9,
+       0x79, 0xc4, 0x83, 0x75, 0x8d, 0x26, 0xeb, 0xe1, 0xdf, 0x5c, 0xf0, 0x39,
+       0xc0, 0x37, 0xd7, 0xc3, 0xdc, 0xc1, 0x93, 0xf1, 0xa5, 0xbc, 0xe5, 0x2c,
+       0x97, 0x82, 0x9c, 0x88, 0x6b, 0x00, 0x96, 0x21, 0xc6, 0x8b, 0xfe, 0xf9,
+       0x2d, 0x88, 0x3d, 0x38, 0x3f, 0xc8, 0x1c, 0x7c, 0xbd, 0x39, 0xeb, 0xd7,
+       0xb9, 0x65, 0xf6, 0x8b, 0xfd, 0x61, 0xdd, 0xbb, 0x9b, 0xca, 0x13, 0xfc,
+       0x3e, 0x46, 0x6f, 0xcc, 0xc6, 0xe4, 0xfb, 0x22, 0xc5, 0x82, 0xf7, 0x3c,
+       0x4e, 0x50, 0x51, 0xbe, 0xaf, 0x05, 0xf4, 0x50, 0xa7, 0xdd, 0x17, 0x8e,
+       0x35, 0xe5, 0x48, 0xc3, 0xc7, 0x9b, 0x6a, 0xd4, 0xe8, 0xd1, 0xc6, 0x2a,
+       0xf6, 0xaf, 0x50, 0x7e, 0xbc, 0x44, 0x37, 0x98, 0xba, 0x8c, 0xfb, 0x4e,
+       0x82, 0x75, 0x8c, 0xf5, 0x6b, 0x4c, 0xd6, 0x9d, 0x25, 0xe4, 0x0b, 0xc5,
+       0x11, 0xfe, 0xc6, 0xf3, 0xde, 0x5d, 0xc5, 0x8a, 0xa1, 0xdb, 0xf4, 0x81,
+       0xe7, 0x68, 0x3c, 0x26, 0x21, 0x72, 0xab, 0x77, 0x3d, 0x58, 0xbf, 0x78,
+       0x97, 0xbf, 0x57, 0xbc, 0xaf, 0x33, 0xac, 0x2a, 0xbf, 0xcd, 0xfe, 0xe4,
+       0x76, 0x8d, 0xd6, 0x6e, 0xf7, 0xbc, 0xfb, 0x2d, 0x9d, 0x9c, 0xa0, 0x76,
+       0xf5, 0xbf, 0xb9, 0xb7, 0xcb, 0x1c, 0xc4, 0x19, 0x49, 0x2b, 0x05, 0xd8,
+       0xeb, 0xb2, 0x8b, 0x3a, 0x47, 0x18, 0xa3, 0xab, 0x42, 0x47, 0xcc, 0xe5,
+       0x3b, 0x80, 0x3b, 0x7a, 0xf8, 0x7b, 0xf3, 0x8c, 0xc5, 0x30, 0x7d, 0xfe,
+       0x5d, 0xd7, 0x2d, 0xf7, 0x49, 0x3f, 0x4b, 0x14, 0xc4, 0x9e, 0x5b, 0x9a,
+       0x6d, 0xa2, 0x39, 0xb7, 0x64, 0x5b, 0xa0, 0x49, 0x0d, 0xbc, 0x94, 0x2b,
+       0x61, 0x9e, 0xc6, 0x7f, 0x4b, 0xb0, 0x7a, 0xd7, 0x37, 0xc0, 0xe7, 0x34,
+       0xf8, 0xe4, 0x7d, 0x4c, 0xd7, 0x43, 0x9d, 0x0b, 0x6b, 0x05, 0xee, 0x23,
+       0xe6, 0xbb, 0x88, 0xf9, 0x2e, 0x62, 0xbe, 0x8b, 0x98, 0xef, 0x22, 0xe6,
+       0xbb, 0x88, 0xf9, 0x2e, 0x62, 0xbe, 0x8b, 0x98, 0xef, 0x8e, 0x07, 0x79,
+       0xda, 0x63, 0x1b, 0x79, 0xda, 0x4a, 0x83, 0xbf, 0x43, 0x49, 0x5e, 0x4a,
+       0x25, 0xf2, 0xf3, 0x5c, 0x12, 0x9c, 0xd3, 0x84, 0x79, 0xee, 0xc7, 0x7f,
+       0x13, 0xf1, 0xf1, 0x38, 0xc7, 0x63, 0xbc, 0x92, 0x22, 0x4c, 0xc6, 0xf3,
+       0xf3, 0x3c, 0xae, 0xad, 0xb6, 0xe2, 0x20, 0x5f, 0xcb, 0xb1, 0x3f, 0x63,
+       0xbb, 0x48, 0xfa, 0xf5, 0x62, 0xee, 0xf5, 0x2f, 0xa1, 0x76, 0x3c, 0x5e,
+       0xac, 0xcb, 0x18, 0x8c, 0xf1, 0x7b, 0x18, 0x6b, 0xac, 0x73, 0xfc, 0xee,
+       0x5e, 0xae, 0x27, 0x8a, 0xf5, 0x14, 0x95, 0x16, 0xc3, 0xfc, 0x07, 0x78,
+       0xee, 0x90, 0x52, 0xa8, 0xf2, 0xd9, 0x0a, 0x9a, 0x4e, 0x42, 0x28, 0x66,
+       0x73, 0x5e, 0x77, 0x49, 0xd6, 0x48, 0xfe, 0xdf, 0x05, 0x0d, 0x83, 0xb7,
+       0xf0, 0x1e, 0x97, 0x48, 0x9d, 0x4d, 0xca, 0xbf, 0x31, 0x48, 0x98, 0x83,
+       0xf2, 0x6f, 0x1d, 0xba, 0xb1, 0x8e, 0x98, 0xdd, 0x13, 0xfe, 0xed, 0x06,
+       0xd7, 0x5d, 0xf6, 0xe6, 0xfd, 0x2b, 0xef, 0x23, 0x09, 0x7b, 0xbd, 0xa7,
+       0x0f, 0x7b, 0xc3, 0xb9, 0x5e, 0xd9, 0x25, 0xf3, 0x6e, 0xf8, 0xce, 0x33,
+       0x83, 0x37, 0xf5, 0x52, 0xe7, 0x6e, 0x5a, 0x1e, 0xe4, 0x1a, 0xad, 0x0d,
+       0xf4, 0x18, 0xd6, 0xc8, 0xd8, 0x62, 0x37, 0x9d, 0x9d, 0x87, 0x6f, 0x9d,
+       0x37, 0x2c, 0xfe, 0xfb, 0x82, 0x85, 0xc1, 0x24, 0x7c, 0xf2, 0x78, 0x2f,
+       0xc7, 0xe4, 0xc5, 0x06, 0xeb, 0x4a, 0x37, 0xf0, 0xfb, 0xa1, 0x8b, 0x3b,
+       0x60, 0x43, 0x02, 0xeb, 0x87, 0xb4, 0xff, 0x53, 0xd2, 0xee, 0x36, 0xf3,
+       0x7d, 0x52, 0x37, 0x84, 0xa1, 0xa7, 0x05, 0x78, 0xff, 0x48, 0x6d, 0x69,
+       0x11, 0x7f, 0x2f, 0x9c, 0x76, 0x9b, 0xbf, 0x1b, 0x0e, 0x29, 0xc5, 0x2a,
+       0xff, 0x8d, 0xc3, 0x20, 0xfd, 0x4f, 0xe1, 0x56, 0x17, 0xd3, 0xd6, 0x79,
+       0x86, 0xdf, 0xcf, 0xe6, 0x2f, 0xc4, 0x81, 0x13, 0xe2, 0x80, 0x41, 0x54,
+       0xf3, 0x31, 0x07, 0xe2, 0xca, 0x44, 0x3d, 0x20, 0x32, 0x59, 0x15, 0x52,
+       0x2d, 0xdb, 0x50, 0xb7, 0x5d, 0x36, 0x77, 0xcb, 0xa6, 0x4c, 0xda, 0x22,
+       0x06, 0x49, 0x9b, 0x6a, 0xd2, 0x2e, 0x76, 0x31, 0xed, 0x2e, 0x96, 0x81,
+       0x34, 0xcd, 0xec, 0x1a, 0x56, 0x32, 0xa4, 0x5d, 0x4c, 0xae, 0x31, 0x04,
+       0x88, 0x53, 0xab, 0x5b, 0x2f, 0x32, 0x4d, 0x53, 0x90, 0x57, 0x25, 0xdd,
+       0x4d, 0x6f, 0x76, 0x3f, 0x55, 0x64, 0xad, 0x72, 0xd1, 0x25, 0x6a, 0xa7,
+       0x6a, 0x7f, 0x17, 0x67, 0xcf, 0xf3, 0x9d, 0x63, 0x20, 0x6c, 0xd5, 0x90,
+       0xac, 0xf3, 0x9d, 0xef, 0x7c, 0xff, 0xdf, 0xfb, 0x3e, 0xef, 0x2f, 0x53,
+       0xa0, 0x2f, 0xc3, 0x8a, 0xa9, 0x4b, 0x65, 0xb6, 0xb1, 0x50, 0xa6, 0x1d,
+       0x7e, 0x13, 0xbc, 0xdc, 0x23, 0x8b, 0xa0, 0xe3, 0xfc, 0x68, 0xab, 0xe7,
+       0x6f, 0xed, 0xf4, 0x78, 0x38, 0xd2, 0xeb, 0xc9, 0x28, 0xad, 0x4b, 0xe6,
+       0xb5, 0x3e, 0xdd, 0x7d, 0xe8, 0xdb, 0x0f, 0xb0, 0xa6, 0x10, 0xce, 0x61,
+       0xb8, 0x57, 0xe3, 0x91, 0x8f, 0xef, 0x7d, 0x87, 0xde, 0x7b, 0x0f, 0xbd,
+       0x9f, 0xfc, 0x1f, 0xed, 0x59, 0x3e, 0x4c, 0x0f, 0x5c, 0xa7, 0x19, 0xe7,
+       0x2c, 0xf9, 0xc2, 0x84, 0x9a, 0x2b, 0x98, 0x09, 0xea, 0x02, 0x29, 0x71,
+       0x54, 0xca, 0x6e, 0x03, 0xc6, 0xb5, 0xc9, 0xc2, 0x0a, 0x68, 0x1e, 0xfb,
+       0x68, 0xb7, 0x18, 0x2f, 0x7f, 0xb6, 0x97, 0x3c, 0xd3, 0x81, 0x6b, 0xf0,
+       0x59, 0x43, 0x21, 0xb4, 0x73, 0x5e, 0xb3, 0x63, 0xc6, 0x45, 0xed, 0xbf,
+       0xa1, 0x0e, 0xe3, 0xa8, 0xbc, 0xce, 0xfd, 0x60, 0x9b, 0x16, 0x79, 0x60,
+       0x25, 0x7b, 0xbc, 0x5c, 0x22, 0xd8, 0xbb, 0x2f, 0xf6, 0x52, 0xbf, 0x78,
+       0xd5, 0xde, 0xab, 0x33, 0x76, 0x85, 0x79, 0x5a, 0x20, 0x9a, 0x97, 0x45,
+       0xca, 0x55, 0x91, 0x9b, 0xf8, 0xfd, 0xb1, 0xea, 0xc5, 0x2f, 0x14, 0x6d,
+       0xed, 0x49, 0xd9, 0x2e, 0x3d, 0x2b, 0x35, 0xc8, 0x9c, 0x2d, 0xdb, 0x71,
+       0x1e, 0xda, 0x61, 0x7d, 0xe6, 0xaf, 0x17, 0x94, 0x44, 0xc6, 0x28, 0xd3,
+       0xda, 0xe4, 0x67, 0x2b, 0xcc, 0xbb, 0x33, 0x8d, 0x87, 0xc2, 0xfc, 0xb7,
+       0x90, 0x64, 0x82, 0x7e, 0xad, 0x97, 0xca, 0xb7, 0x45, 0x3e, 0xc1, 0xb7,
+       0x4f, 0x56, 0x5e, 0xe9, 0xa5, 0xcf, 0xe5, 0xe3, 0x15, 0xbe, 0xfb, 0xf0,
+       0xf4, 0x49, 0xc3, 0xf2, 0x43, 0x7f, 0x05, 0xf0, 0x18, 0x3c, 0x77, 0xee,
+       0xf7, 0x47, 0x5c, 0x1b, 0xea, 0x68, 0xc3, 0xb6, 0x49, 0x7e, 0x18, 0x38,
+       0xa8, 0x86, 0x74, 0xbe, 0x52, 0x23, 0xa8, 0x71, 0xd9, 0x5f, 0x61, 0x5e,
+       0x9d, 0x71, 0x54, 0x63, 0x74, 0xf2, 0xf6, 0x82, 0xde, 0x0b, 0xca, 0xb9,
+       0x8a, 0x4d, 0x5a, 0x35, 0x64, 0x0b, 0xbc, 0xb6, 0x59, 0xdf, 0xea, 0xe3,
+       0x5d, 0x6d, 0xd7, 0x17, 0x7b, 0x5d, 0x1b, 0x8d, 0x75, 0xaf, 0xf7, 0xba,
+       0x75, 0x61, 0xcf, 0xe6, 0xa2, 0x6d, 0x56, 0xc6, 0xde, 0x7e, 0x2c, 0xf5,
+       0xd5, 0x9f, 0xca, 0x9d, 0xd2, 0x4f, 0xe4, 0xb7, 0xab, 0xe7, 0xa1, 0x73,
+       0x98, 0xe5, 0x1c, 0xe4, 0xc9, 0xbb, 0x75, 0xc7, 0x79, 0xd7, 0x3e, 0x07,
+       0xfb, 0xc0, 0x71, 0xfe, 0x64, 0xef, 0x48, 0x64, 0xfc, 0x7b, 0xd8, 0x73,
+       0x16, 0x3c, 0x44, 0x2c, 0xcc, 0x80, 0xde, 0x52, 0x7d, 0xd2, 0x19, 0xd0,
+       0x74, 0x32, 0x34, 0xde, 0x8a, 0x3d, 0xf8, 0x3c, 0x3d, 0x9c, 0x7b, 0x49,
+       0xf7, 0x91, 0x66, 0x7c, 0xf5, 0x0a, 0xe6, 0x6f, 0x05, 0x5f, 0x1c, 0xc5,
+       0x4f, 0xc9, 0xc3, 0x31, 0xac, 0x75, 0x8c, 0xb4, 0xd7, 0x2a, 0x91, 0x67,
+       0xb0, 0x8f, 0x6c, 0x8b, 0x3c, 0x2a, 0xdc, 0xea, 0xa5, 0x3f, 0xef, 0x51,
+       0x81, 0x65, 0xdf, 0x57, 0xbb, 0xc4, 0x91, 0x16, 0xc8, 0xef, 0x85, 0x09,
+       0x57, 0x57, 0xfa, 0x83, 0x3a, 0x85, 0xf6, 0x56, 0xee, 0x7d, 0x45, 0xdd,
+       0x2e, 0xe7, 0xb4, 0x42, 0x17, 0x9f, 0x82, 0x0e, 0x94, 0xac, 0x5f, 0x91,
+       0xc6, 0x58, 0x00, 0x6d, 0xa8, 0xa3, 0x68, 0x2c, 0x91, 0x54, 0x81, 0xf9,
+       0x5d, 0xcc, 0xb5, 0xc2, 0x1a, 0xcf, 0x11, 0x37, 0xb8, 0xc6, 0x36, 0xc6,
+       0xe0, 0xbc, 0x3a, 0x0b, 0x34, 0xc2, 0x3a, 0xd2, 0x77, 0x02, 0x3c, 0x99,
+       0xa0, 0xdc, 0xc4, 0x78, 0xa3, 0x18, 0x8f, 0xe5, 0x2e, 0x8c, 0x77, 0x45,
+       0x92, 0x76, 0x73, 0xcc, 0x38, 0xda, 0x10, 0x67, 0xe2, 0xd0, 0x1f, 0x06,
+       0x55, 0x7a, 0x25, 0x08, 0xf9, 0xdd, 0x2b, 0x69, 0xe3, 0xc8, 0x81, 0x3d,
+       0xe6, 0xb4, 0x7d, 0xe0, 0xf3, 0x8d, 0x7a, 0x6b, 0xea, 0x3a, 0xb0, 0x26,
+       0xf6, 0xc7, 0x0f, 0xb6, 0x71, 0x72, 0x65, 0x09, 0x38, 0xb5, 0xf4, 0x41,
+       0xd2, 0xbe, 0x20, 0xa9, 0x20, 0xd7, 0xc4, 0xfa, 0x20, 0xd6, 0x4c, 0x3f,
+       0xd6, 0x77, 0x81, 0x43, 0x47, 0xbc, 0x3a, 0xb6, 0x15, 0x5f, 0x12, 0x67,
+       0xef, 0xda, 0xb5, 0xac, 0xfb, 0x8a, 0x24, 0x97, 0xb2, 0x32, 0xad, 0xfb,
+       0xf1, 0x0c, 0x07, 0xb4, 0xee, 0x41, 0x5e, 0x8d, 0x9c, 0xc0, 0x59, 0xc6,
+       0xf6, 0x6d, 0xe0, 0xf0, 0x09, 0x72, 0x91, 0xd1, 0xe7, 0xf2, 0x2c, 0xbe,
+       0x9d, 0xe0, 0x1d, 0xb5, 0x49, 0xe4, 0x5b, 0x90, 0x91, 0x85, 0x66, 0x7d,
+       0x40, 0x3e, 0x2d, 0xf4, 0xf4, 0x31, 0xce, 0xf2, 0xd7, 0x82, 0x21, 0x1f,
+       0x17, 0x74, 0x2c, 0x74, 0xc6, 0x2f, 0xe6, 0x65, 0xd7, 0x3e, 0x1f, 0x9e,
+       0x59, 0x50, 0xfc, 0x3e, 0x7c, 0x79, 0x5d, 0x75, 0xa0, 0x6d, 0x00, 0xed,
+       0xb8, 0x0e, 0x43, 0xa6, 0x0a, 0x9f, 0x3b, 0xb3, 0x23, 0x8e, 0x33, 0xad,
+       0xf3, 0xc3, 0x62, 0xc6, 0x82, 0x6a, 0xea, 0xe4, 0x51, 0x29, 0x04, 0xdb,
+       0x31, 0x57, 0xcc, 0x58, 0x57, 0xc3, 0x58, 0x0f, 0xcb, 0x27, 0xc8, 0x13,
+       0xa1, 0x1d, 0xe1, 0xf8, 0x66, 0x66, 0x4d, 0xc5, 0xc2, 0x43, 0xca, 0x4c,
+       0xe4, 0xf1, 0x6b, 0x51, 0x3a, 0x8e, 0x18, 0x0a, 0x2b, 0xf0, 0x2e, 0xf6,
+       0x64, 0x9d, 0x76, 0x9c, 0x8c, 0xc5, 0xfa, 0x98, 0x11, 0x50, 0xf4, 0xb7,
+       0x74, 0xea, 0x78, 0xe3, 0xb5, 0x93, 0x31, 0xe3, 0xb4, 0x3a, 0xee, 0xbd,
+       0xc7, 0x81, 0x99, 0x7b, 0xe3, 0x9d, 0x5f, 0x53, 0x86, 0xbc, 0x51, 0x88,
+       0x85, 0xe7, 0x94, 0x99, 0xc5, 0x98, 0xd9, 0xb4, 0x22, 0x6e, 0xc4, 0x8c,
+       0x4e, 0x45, 0x9f, 0x68, 0xbb, 0xde, 0x77, 0x06, 0xfd, 0x63, 0xaa, 0xc5,
+       0x5b, 0x0f, 0xef, 0xeb, 0xed, 0x3e, 0x97, 0x67, 0x88, 0x39, 0x23, 0xc0,
+       0x4c, 0xe6, 0x9a, 0xe9, 0xdc, 0x86, 0x44, 0x64, 0x7c, 0x44, 0x63, 0xe8,
+       0xe3, 0x33, 0x7f, 0x47, 0x1d, 0xca, 0x65, 0xd6, 0x45, 0x3d, 0x7e, 0x1b,
+       0xd1, 0x3a, 0xf3, 0xe3, 0x33, 0x39, 0x9d, 0xf7, 0xd8, 0x50, 0x11, 0x6f,
+       0xdf, 0x7b, 0x77, 0x16, 0x4e, 0xda, 0x4f, 0x71, 0x9c, 0x25, 0xff, 0x64,
+       0xbb, 0x30, 0xa7, 0x74, 0xaa, 0xd4, 0xa4, 0x0d, 0xfa, 0x03, 0x98, 0x2f,
+       0xd0, 0x8c, 0x7b, 0x5f, 0x11, 0xdf, 0x78, 0xc7, 0x01, 0x3a, 0x81, 0xae,
+       0x09, 0x1d, 0xb5, 0x8a, 0x71, 0xf2, 0x2b, 0x92, 0x73, 0xfb, 0x4b, 0x07,
+       0x73, 0x58, 0xf3, 0xd5, 0x2f, 0x1b, 0x83, 0x73, 0x63, 0x0e, 0xbc, 0x3f,
+       0x3e, 0x43, 0xfa, 0xe4, 0xd9, 0x84, 0xd5, 0xd4, 0x2a, 0xd7, 0x33, 0x20,
+       0xd3, 0x2b, 0x83, 0x32, 0x87, 0xdf, 0xc2, 0x8a, 0x7b, 0x6f, 0x1b, 0xd0,
+       0xad, 0xa7, 0x0b, 0x86, 0xe6, 0xd7, 0x39, 0x9b, 0x31, 0x13, 0xf0, 0x8a,
+       0xce, 0xa9, 0x62, 0x5f, 0xc6, 0x89, 0x06, 0x29, 0x1f, 0xed, 0x06, 0xe4,
+       0xea, 0x46, 0x9d, 0x7a, 0x2a, 0xeb, 0xcd, 0x78, 0xd8, 0xdf, 0x2d, 0x0b,
+       0xc0, 0xbb, 0x0a, 0x64, 0x67, 0xfe, 0xcd, 0x80, 0xcc, 0x15, 0x74, 0x3c,
+       0x39, 0xfc, 0x17, 0x65, 0x4b, 0xad, 0x3e, 0x21, 0xb7, 0xeb, 0x51, 0xfd,
+       0x8d, 0x72, 0x2d, 0xff, 0x0b, 0x9f, 0xbc, 0x32, 0xa2, 0xf3, 0xea, 0xa2,
+       0x15, 0x79, 0xaa, 0x9f, 0x3a, 0xcf, 0xba, 0xce, 0xb1, 0x03, 0x76, 0x40,
+       0xe7, 0x78, 0x0f, 0x3a, 0xc7, 0x6f, 0xa0, 0x73, 0xfc, 0xba, 0x04, 0x7c,
+       0x29, 0x65, 0x3c, 0xfc, 0x9f, 0x01, 0x0e, 0x51, 0x56, 0x9b, 0xe7, 0x71,
+       0xa7, 0x33, 0x39, 0xd0, 0xe0, 0x47, 0x92, 0x01, 0xde, 0x26, 0x65, 0x73,
+       0x75, 0x5a, 0xb6, 0x56, 0xdd, 0x3c, 0xe5, 0xfb, 0xcc, 0x01, 0x1b, 0xe3,
+       0x3d, 0x45, 0x81, 0x43, 0x47, 0x24, 0x72, 0x9a, 0xf8, 0xd1, 0x21, 0x6b,
+       0xc5, 0xdf, 0x69, 0x1c, 0x5a, 0x2b, 0xb2, 0xec, 0x17, 0x9d, 0x4f, 0x76,
+       0x6e, 0x47, 0x2a, 0x76, 0x03, 0xf5, 0xc7, 0xb4, 0x0f, 0xc8, 0xf5, 0xc9,
+       0x13, 0x2f, 0x3f, 0xf7, 0xee, 0x5e, 0xe9, 0x3c, 0xbb, 0x59, 0xa3, 0x1b,
+       0xed, 0x9a, 0xd8, 0x35, 0xe4, 0xc6, 0xbc, 0xd5, 0xdf, 0xd0, 0x06, 0x73,
+       0x94, 0xba, 0x65, 0x03, 0x32, 0xa4, 0x11, 0xed, 0xd6, 0xba, 0x5f, 0x23,
+       0x3a, 0xa8, 0x73, 0x77, 0x39, 0x4e, 0xbe, 0x68, 0xc9, 0x7c, 0xd1, 0x0c,
+       0xe7, 0x40, 0x7f, 0xb7, 0x61, 0xab, 0x6d, 0xe2, 0x0e, 0xb6, 0x70, 0x06,
+       0xdb, 0x75, 0xca, 0xf9, 0x2f, 0x34, 0xf6, 0xae, 0xd5, 0x3f, 0xc3, 0x38,
+       0xe6, 0xf9, 0x84, 0x3c, 0xee, 0x23, 0x06, 0xd2, 0x1f, 0x95, 0xd2, 0xfd,
+       0xdd, 0x7e, 0x9b, 0x68, 0xbb, 0x55, 0x27, 0x1e, 0x8b, 0x5c, 0x2d, 0x58,
+       0x90, 0x25, 0xbf, 0x0a, 0x51, 0x07, 0x28, 0xab, 0x66, 0x3f, 0xc7, 0x5b,
+       0xb3, 0xe3, 0x1c, 0xb5, 0xb8, 0xae, 0xa8, 0x87, 0xdb, 0x94, 0xfd, 0x3b,
+       0x5a, 0xee, 0x17, 0x4a, 0x17, 0xe4, 0x1d, 0xdc, 0xb7, 0xab, 0xe3, 0x64,
+       0xe5, 0x16, 0x74, 0xbc, 0x7a, 0xa9, 0x99, 0xd7, 0x3d, 0x89, 0x73, 0x32,
+       0xd5, 0xfc, 0xf2, 0x75, 0xb9, 0x76, 0x63, 0x57, 0xbd, 0x71, 0x23, 0xa2,
+       0xae, 0x2f, 0x0f, 0xa9, 0xfc, 0xb2, 0xe3, 0xfc, 0xd3, 0x9e, 0x95, 0x3b,
+       0xab, 0x8e, 0x9c, 0xb5, 0x7d, 0xfd, 0x7e, 0x69, 0xe6, 0xd6, 0x39, 0x4e,
+       0x07, 0xb0, 0x79, 0xfb, 0xa4, 0xe3, 0x3c, 0x3d, 0x36, 0x26, 0xd1, 0x93,
+       0xd4, 0x51, 0x9e, 0x0b, 0x31, 0x3f, 0x96, 0x98, 0x93, 0xb4, 0xac, 0xcb,
+       0x15, 0xa5, 0x80, 0x6f, 0xdd, 0xae, 0xfe, 0xf2, 0xcc, 0x31, 0x2f, 0x56,
+       0x72, 0xe7, 0x35, 0xfa, 0x92, 0x43, 0xff, 0xe5, 0x4b, 0x36, 0xe4, 0x62,
+       0x71, 0x04, 0xfd, 0x83, 0xf2, 0xc3, 0x62, 0xe0, 0x50, 0xd9, 0xc0, 0x73,
+       0x54, 0xe5, 0x8b, 0x8f, 0x9c, 0x21, 0x1d, 0x33, 0x80, 0x4e, 0x62, 0x38,
+       0xce, 0x9c, 0xcd, 0xf9, 0xba, 0x31, 0xdf, 0x8e, 0x71, 0x0c, 0xf2, 0xff,
+       0xac, 0x96, 0xcf, 0x17, 0x15, 0x6c, 0x5f, 0xf0, 0x77, 0x50, 0xd2, 0x45,
+       0xc8, 0x78, 0xc5, 0x9c, 0x53, 0xea, 0x0a, 0x66, 0x68, 0x0e, 0xd8, 0x31,
+       0x0b, 0xbc, 0x79, 0x49, 0xc7, 0x56, 0x4f, 0x68, 0xec, 0x99, 0x67, 0x39,
+       0x2b, 0x89, 0x8a, 0xdd, 0xa3, 0xcf, 0x6f, 0xf7, 0xf6, 0x2f, 0x43, 0xee,
+       0x9d, 0x83, 0x8f, 0xb3, 0x4a, 0xda, 0x60, 0x03, 0xa5, 0xd6, 0xcf, 0x81,
+       0x27, 0x42, 0x38, 0xdb, 0x56, 0xcd, 0x0f, 0x0d, 0xc8, 0xef, 0x86, 0xf6,
+       0x23, 0xba, 0xf1, 0x8a, 0x86, 0xc1, 0x76, 0x17, 0xd0, 0xaf, 0x5d, 0x92,
+       0xcb, 0x6d, 0x1a, 0x57, 0x9f, 0xac, 0x4b, 0x40, 0x0f, 0xf9, 0x3e, 0xca,
+       0x7e, 0xd4, 0x85, 0xbd, 0xb2, 0x0f, 0xe5, 0x19, 0x94, 0x5b, 0xf0, 0x64,
+       0x9b, 0x61, 0xe8, 0x15, 0x78, 0xbe, 0x8d, 0xf1, 0xc6, 0xb0, 0xe6, 0xac,
+       0x21, 0x1f, 0x9e, 0xa1, 0x2c, 0x19, 0x55, 0xcc, 0x63, 0x9e, 0xb3, 0xf0,
+       0xac, 0x0d, 0xa9, 0xd4, 0x12, 0xcb, 0x78, 0x96, 0xdd, 0xef, 0x4f, 0x60,
+       0x12, 0xfa, 0x24, 0x6f, 0xb8, 0x98, 0xf4, 0xe1, 0x1e, 0x26, 0xb1, 0xae,
+       0x5d, 0xd2, 0xcb, 0xe4, 0x75, 0x03, 0xf4, 0xd6, 0x29, 0xa9, 0x1b, 0x41,
+       0xad, 0x8f, 0x56, 0x40, 0x8b, 0x1b, 0xa0, 0xab, 0x35, 0xd0, 0x54, 0xb2,
+       0x68, 0xc6, 0x67, 0x54, 0x58, 0xfb, 0x02, 0x5e, 0x00, 0xbd, 0x76, 0xbc,
+       0x49, 0x5d, 0x94, 0xbc, 0x1c, 0x05, 0xed, 0x89, 0xd3, 0x61, 0x59, 0x99,
+       0xa8, 0xb2, 0x40, 0x83, 0xa0, 0xcb, 0xa2, 0xcb, 0xd3, 0xef, 0x2b, 0x8d,
+       0xab, 0xf1, 0x07, 0x12, 0x4b, 0x3c, 0x10, 0x13, 0x58, 0x60, 0xda, 0x1f,
+       0x88, 0x8d, 0x31, 0x27, 0xe4, 0x26, 0xe6, 0xf1, 0x81, 0xbf, 0x47, 0x4e,
+       0x69, 0xfe, 0x8e, 0x8b, 0xff, 0x30, 0x8f, 0x83, 0xde, 0x80, 0x41, 0x2e,
+       0x4f, 0x27, 0x3c, 0x1a, 0xfd, 0x26, 0xf8, 0xd7, 0x84, 0x25, 0x16, 0x94,
+       0x05, 0xf0, 0xff, 0x06, 0xbe, 0xdf, 0xad, 0x0f, 0xab, 0xf9, 0x25, 0xe5,
+       0xe5, 0x92, 0x7c, 0x07, 0x7a, 0xf2, 0x43, 0x9c, 0x5d, 0x97, 0xd6, 0xdd,
+       0x23, 0x63, 0x8c, 0x9f, 0x65, 0xd4, 0x35, 0xeb, 0xb4, 0xec, 0x8e, 0x4e,
+       0xa0, 0x7c, 0x0c, 0x4f, 0x1f, 0xce, 0x21, 0xa0, 0xe3, 0xdf, 0x6b, 0x05,
+       0x5b, 0xb9, 0xff, 0xd3, 0x30, 0x8e, 0xbe, 0xc4, 0xb2, 0x93, 0xf8, 0x4e,
+       0x5f, 0x0c, 0xf7, 0x06, 0x9d, 0x49, 0x85, 0x74, 0xbe, 0x69, 0x05, 0xba,
+       0xc4, 0x3a, 0xc6, 0xbb, 0x47, 0x5f, 0x5e, 0x0d, 0x3c, 0x3c, 0xfa, 0x2f,
+       0x27, 0x11, 0x64, 0x4e, 0xfb, 0x17, 0x21, 0x57, 0xfe, 0x7d, 0xea, 0xec,
+       0x5a, 0xf3, 0x71, 0x1f, 0x5e, 0x3e, 0x32, 0x82, 0x68, 0x0b, 0x59, 0x06,
+       0x59, 0x54, 0xd6, 0xf4, 0xcb, 0x76, 0x6e, 0xdf, 0x7c, 0x2d, 0x66, 0xdc,
+       0x17, 0xb7, 0xef, 0x82, 0x45, 0xb9, 0xd3, 0x0e, 0x7c, 0x09, 0x6b, 0xbd,
+       0xf2, 0x9e, 0x95, 0x03, 0x2a, 0x98, 0xe1, 0x0c, 0x68, 0xb4, 0x4d, 0xcc,
+       0xe8, 0x94, 0xec, 0xcf, 0x3b, 0xa7, 0xfb, 0xb2, 0x6d, 0xb3, 0x6f, 0x73,
+       0x5e, 0xae, 0x9f, 0x7b, 0xe1, 0x1e, 0xe8, 0x9b, 0x36, 0x34, 0x8d, 0x36,
+       0x6a, 0x03, 0xfd, 0x2e, 0x8d, 0x36, 0xf7, 0x11, 0xfc, 0x3f, 0xfb, 0x20,
+       0x9d, 0xd8, 0xca, 0x8d, 0xd3, 0xe3, 0x59, 0xe3, 0x79, 0x0e, 0x83, 0x36,
+       0x0e, 0xd2, 0x4f, 0xd3, 0xb7, 0xe8, 0xd2, 0xcf, 0xd3, 0x7b, 0xf4, 0x43,
+       0xba, 0xe9, 0x94, 0xf4, 0x0d, 0x4b, 0xa6, 0x8b, 0xfa, 0xbe, 0xa1, 0x6b,
+       0xd2, 0x67, 0x34, 0x01, 0xba, 0x21, 0xad, 0x93, 0xb7, 0x0c, 0x29, 0x83,
+       0x8e, 0xca, 0xc0, 0xa7, 0x32, 0x68, 0xaa, 0x02, 0x7c, 0x2b, 0x03, 0xdf,
+       0xca, 0x75, 0x33, 0x5a, 0xc5, 0x9e, 0x29, 0xb3, 0xd7, 0x41, 0x47, 0x1b,
+       0x75, 0xde, 0xbf, 0x5e, 0xb3, 0x41, 0x39, 0x78, 0x77, 0xef, 0xee, 0xff,
+       0x81, 0xbb, 0x1f, 0x94, 0xdb, 0xb0, 0x5b, 0xde, 0x29, 0x8d, 0x02, 0x93,
+       0x04, 0x18, 0x65, 0x83, 0x36, 0xe2, 0xb2, 0x59, 0x9a, 0x94, 0x2d, 0xc8,
+       0xa7, 0xed, 0xd5, 0x08, 0xf4, 0xe9, 0x90, 0xcc, 0xbf, 0x35, 0x22, 0xb7,
+       0x56, 0x95, 0xcc, 0x82, 0x7e, 0xf3, 0x6b, 0xf4, 0xbb, 0x83, 0x9e, 0xcb,
+       0x9d, 0x3a, 0x4e, 0x9f, 0xae, 0xba, 0xfe, 0xf7, 0xa9, 0x6a, 0x97, 0x4c,
+       0x57, 0x0d, 0x79, 0xbe, 0xda, 0x23, 0x2f, 0x56, 0x83, 0x72, 0x16, 0x76,
+       0xe0, 0xd7, 0xaa, 0x03, 0xf2, 0x52, 0x75, 0x50, 0xbe, 0x5e, 0x0b, 0xcb,
+       0x37, 0x6a, 0x96, 0x64, 0x6b, 0x51, 0xc9, 0xd4, 0x46, 0xe5, 0x85, 0x1a,
+       0xfd, 0xea, 0x98, 0x0f, 0xbf, 0xd4, 0x9e, 0xbf, 0x82, 0xeb, 0xea, 0xc0,
+       0xba, 0xa2, 0x6a, 0x4a, 0xc7, 0x29, 0x25, 0xeb, 0xfa, 0x3c, 0x44, 0x2e,
+       0x61, 0xac, 0xc5, 0xb7, 0x94, 0x54, 0xf4, 0xfc, 0xcd, 0xff, 0x33, 0x09,
+       0x68, 0xdb, 0xe8, 0x52, 0x79, 0x00, 0x6d, 0x20, 0xf7, 0x0a, 0x4d, 0xdf,
+       0x47, 0xd3, 0xe7, 0xdf, 0xb4, 0xbd, 0x7c, 0xda, 0x6f, 0x7d, 0x97, 0xb6,
+       0x97, 0x3e, 0x7b, 0xe2, 0x07, 0xed, 0x9c, 0x9b, 0xda, 0x6f, 0xb2, 0x1f,
+       0xdb, 0x68, 0xce, 0xbb, 0x98, 0x7d, 0xf2, 0xff, 0x59, 0xdc, 0x18, 0xd5,
+       0xc5, 0xda, 0x00, 0xff, 0xaf, 0x05, 0x6b, 0xf9, 0xf2, 0xdc, 0xf1, 0xe9,
+       0x52, 0x5a, 0x3d, 0x5f, 0xa2, 0x46, 0xe3, 0xc8, 0xe2, 0x5e, 0x4e, 0xdc,
+       0x73, 0xb2, 0x66, 0x07, 0xf4, 0x1a, 0x5c, 0x5f, 0x7d, 0x42, 0xe7, 0xc7,
+       0xa5, 0x4f, 0x91, 0xfe, 0x18, 0x7b, 0xeb, 0xf2, 0xe2, 0x09, 0xd0, 0x6d,
+       0x6d, 0x43, 0xae, 0x56, 0x5d, 0x9f, 0xd5, 0xbc, 0xa6, 0x97, 0x7b, 0xa0,
+       0x39, 0xc6, 0x1c, 0xdc, 0x67, 0xae, 0xec, 0xf6, 0x4d, 0xe1, 0xde, 0x60,
+       0x8f, 0x63, 0xbf, 0xbe, 0x1e, 0xce, 0xc5, 0xff, 0xe3, 0x41, 0xd9, 0x5b,
+       0x2f, 0x73, 0x8d, 0x2d, 0x4d, 0x8b, 0x6e, 0x5c, 0x37, 0x2a, 0xaf, 0xe2,
+       0xfc, 0x2a, 0x06, 0xd7, 0xdf, 0x21, 0x95, 0x28, 0x6d, 0x5b, 0xe2, 0xf7,
+       0x29, 0x29, 0x63, 0x9e, 0x4a, 0xb4, 0xe9, 0x0f, 0x73, 0x71, 0xb6, 0x62,
+       0xec, 0xcf, 0x3b, 0x53, 0x3e, 0x8e, 0x77, 0xd4, 0x45, 0xa1, 0x33, 0x9d,
+       0xe3, 0xfb, 0x22, 0xca, 0xf4, 0x8d, 0xcc, 0xe3, 0x19, 0xf2, 0xea, 0xde,
+       0xeb, 0xd7, 0xba, 0xfa, 0xe4, 0x7e, 0xbf, 0xd9, 0xb2, 0x99, 0x4b, 0xfa,
+       0x63, 0xca, 0xf7, 0xf3, 0xdf, 0xf7, 0x13, 0x73, 0x8f, 0x5b, 0xfc, 0x05,
+       0xe4, 0x33, 0x43, 0xfb, 0x14, 0xbc, 0x6f, 0x47, 0xe4, 0x65, 0x83, 0x79,
+       0xec, 0x09, 0x95, 0x2e, 0x5d, 0xf7, 0x72, 0x7c, 0x63, 0xea, 0x78, 0xe5,
+       0x7e, 0xbf, 0x9b, 0xf3, 0xce, 0xb1, 0x0f, 0xe6, 0xb9, 0x1f, 0xa4, 0x13,
+       0xe6, 0xbb, 0xb7, 0xef, 0xfd, 0x0f, 0x55, 0xa5, 0x00, 0xbc, 0xb3, 0x5a,
+       0x34, 0x3f, 0xe6, 0x6b, 0xff, 0x76, 0x76, 0x34, 0x3f, 0x37, 0x7d, 0x0c,
+       0x7f, 0xee, 0xa7, 0x6d, 0x4b, 0xdc, 0xb8, 0xea, 0xe6, 0x8e, 0x6a, 0x1b,
+       0x1a, 0x58, 0x81, 0x3a, 0xf2, 0x2a, 0xf8, 0x64, 0xaf, 0x2d, 0xff, 0xfe,
+       0x03, 0x9a, 0xb8, 0x8a, 0x6c, 0x8c, 0x67, 0x00, 0x00, 0x00 };
 
 static const u32 bnx2_RXP_b09FwData[(0x0/4) + 1] = { 0x0 };
 static const u32 bnx2_RXP_b09FwRodata[(0x278/4) + 1] = {
-       0x08004050, 0x08003f50, 0x08003ff4, 0x0800400c, 0x08004024, 0x08004044,
-       0x08004050, 0x08004050, 0x08003f58, 0x00000000, 0x08004a0c, 0x08004a44,
-       0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004a7c, 0x08004c40,
-       0x08004b88, 0x08004bc0, 0x08004c40, 0x08004b10, 0x08004c40, 0x08004c40,
-       0x08004bc0, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-       0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c00,
-       0x08004c40, 0x08004c00, 0x08004b88, 0x08004c40, 0x08004c40, 0x08004c00,
-       0x08004c00, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-       0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-       0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-       0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-       0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-       0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-       0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-       0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-       0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-       0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-       0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-       0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-       0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-       0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-       0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-       0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-       0x08004aec, 0x00000000, 0x08006058, 0x08006070, 0x08006070, 0x08006070,
-       0x08006058, 0x08006070, 0x08006070, 0x08006070, 0x08006058, 0x08006070,
-       0x08006070, 0x08006070, 0x08006058, 0x08006070, 0x08006070, 0x08006070,
-       0x08006064, 0x00000000, 0x00000000 };
+       0x08004070, 0x08003f70, 0x08004014, 0x0800402c, 0x08004044, 0x08004064,
+       0x08004070, 0x08004070, 0x08003f78, 0x00000000, 0x08004a2c, 0x08004a64,
+       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004a9c, 0x08004c60,
+       0x08004ba8, 0x08004be0, 0x08004c60, 0x08004b30, 0x08004c60, 0x08004c60,
+       0x08004be0, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c20,
+       0x08004c60, 0x08004c20, 0x08004ba8, 0x08004c60, 0x08004c60, 0x08004c20,
+       0x08004c20, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+       0x08004b0c, 0x00000000, 0x08006078, 0x08006090, 0x08006090, 0x08006090,
+       0x08006078, 0x08006090, 0x08006090, 0x08006090, 0x08006078, 0x08006090,
+       0x08006090, 0x08006090, 0x08006078, 0x08006090, 0x08006090, 0x08006090,
+       0x08006084, 0x00000000, 0x00000000 };
 
 static struct fw_info bnx2_rxp_fw_09 = {
+       /* Firmware version:  3.7.1 */
        .ver_major                      = 0x3,
-       .ver_minor                      = 0x4,
-       .ver_fix                        = 0x3,
+       .ver_minor                      = 0x7,
+       .ver_fix                        = 0x1,
 
        .start_addr                     = 0x08003184,
 
        .text_addr                      = 0x08000000,
-       .text_len                       = 0x6768,
+       .text_len                       = 0x6788,
        .text_index                     = 0x0,
        .gz_text                        = bnx2_RXP_b09FwText,
        .gz_text_len                    = sizeof(bnx2_RXP_b09FwText),
 
-       .data_addr                      = 0x08006a00,
+       .data_addr                      = 0x08006a20,
        .data_len                       = 0x0,
        .data_index                     = 0x0,
        .data                           = bnx2_RXP_b09FwData,
 
-       .sbss_addr                      = 0x08006a00,
+       .sbss_addr                      = 0x08006a20,
        .sbss_len                       = 0x20,
        .sbss_index                     = 0x0,
 
-       .bss_addr                       = 0x08006a20,
+       .bss_addr                       = 0x08006a40,
        .bss_len                        = 0x13dc,
        .bss_index                      = 0x0,
 
-       .rodata_addr                    = 0x08006768,
+       .rodata_addr                    = 0x08006788,
        .rodata_len                     = 0x278,
        .rodata_index                   = 0x0,
        .rodata                         = bnx2_RXP_b09FwRodata,
 };
 
 static u8 bnx2_TPAT_b09FwText[] = {
-/*     0x1f, 0x8b, 0x08, 0x00, 0x0e, 0x34, 0xe7, 0x45, 0x00, 0x03, */
-                                                                   0xcd, 0x58,
-       0x5d, 0x68, 0x1c, 0xd7, 0x15, 0x3e, 0xf3, 0xb7, 0x3b, 0x52, 0x24, 0xeb,
-       0x5a, 0xd9, 0xa6, 0xeb, 0xa0, 0x34, 0x33, 0xda, 0x91, 0xac, 0x22, 0x13,
-       0x4f, 0x9d, 0x25, 0x16, 0x65, 0x21, 0x93, 0xd9, 0x91, 0xac, 0x98, 0x3c,
-       0x28, 0xc5, 0x90, 0x87, 0x52, 0x50, 0x57, 0x32, 0x09, 0x79, 0x69, 0xda,
-       0xc6, 0x90, 0x3e, 0x79, 0x3b, 0x2b, 0xc7, 0x0e, 0x6c, 0xbc, 0x8d, 0x52,
-       0xe4, 0x52, 0xfa, 0x60, 0xd6, 0xb1, 0x05, 0xcd, 0x46, 0x93, 0xd4, 0x7e,
-       0x35, 0x36, 0x4e, 0x93, 0xa7, 0x42, 0x9f, 0x52, 0xf4, 0x18, 0xd2, 0x12,
-       0xda, 0x52, 0x8a, 0x69, 0xa1, 0x09, 0x8d, 0xeb, 0xdb, 0xef, 0xdc, 0x99,
-       0x91, 0x57, 0xb6, 0xec, 0xa4, 0x25, 0x85, 0x0a, 0x56, 0x77, 0xe6, 0xce,
-       0x3d, 0xe7, 0x9e, 0x7b, 0xee, 0x77, 0xbe, 0x73, 0xee, 0x2d, 0xeb, 0x34,
-       0x48, 0xd9, 0xdf, 0x30, 0x7e, 0x2f, 0x7e, 0xf7, 0x85, 0x17, 0xab, 0x8f,
-       0x3c, 0xea, 0x10, 0x3d, 0xfa, 0x88, 0x66, 0x98, 0x06, 0x7d, 0x09, 0x7f,
-       0x50, 0x22, 0x72, 0xfd, 0xfc, 0x23, 0x5b, 0xaf, 0x9d, 0x72, 0x42, 0x8f,
-       0x6c, 0xa3, 0x26, 0xbe, 0xbe, 0xe4, 0x11, 0x05, 0xbd, 0x69, 0xa7, 0x4e,
-       0xff, 0x92, 0xcd, 0x92, 0x49, 0xdc, 0xff, 0x50, 0xed, 0xc6, 0xfe, 0xcb,
-       0x07, 0xdd, 0xeb, 0x67, 0x0d, 0xb2, 0x45, 0x6d, 0xd1, 0x16, 0x93, 0x64,
-       0x8f, 0xd5, 0x9a, 0xce, 0x2f, 0xf6, 0x1e, 0x28, 0xd0, 0xae, 0x5c, 0x97,
-       0xa0, 0xb8, 0x43, 0x4d, 0xab, 0x66, 0x53, 0xd4, 0x7e, 0x49, 0x0b, 0x3b,
-       0x9e, 0x98, 0x85, 0x8e, 0xa0, 0x04, 0xfd, 0x1e, 0xde, 0x13, 0x53, 0x8b,
-       0xce, 0xd8, 0xa4, 0xd7, 0x02, 0x3c, 0x4f, 0x51, 0xab, 0x23, 0xe5, 0x2b,
-       0xbe, 0x46, 0x4b, 0xbe, 0x4d, 0x8b, 0xc2, 0x0d, 0x1c, 0xed, 0xa6, 0xac,
-       0x4c, 0x48, 0xf9, 0x9c, 0xaf, 0x93, 0xee, 0xcd, 0x69, 0xe1, 0xfa, 0xbc,
-       0x56, 0x5f, 0x9f, 0x67, 0x7f, 0xc0, 0xbe, 0x39, 0x2d, 0x58, 0xe7, 0xb6,
-       0x66, 0xd7, 0xdb, 0xbb, 0x68, 0xb1, 0x44, 0x23, 0xba, 0x37, 0x85, 0xf9,
-       0x4a, 0xd0, 0xe3, 0x50, 0xe8, 0x4f, 0x0b, 0x9d, 0x2a, 0xf8, 0x0d, 0xd0,
-       0xac, 0x4f, 0x03, 0xba, 0xa7, 0x53, 0xa3, 0xa4, 0xd1, 0x1b, 0x55, 0x0b,
-       0xbf, 0xc3, 0x5a, 0xb4, 0xfe, 0x7c, 0xa6, 0x87, 0xc7, 0xdb, 0xf8, 0xc6,
-       0x36, 0xb3, 0x7c, 0xbf, 0xec, 0x30, 0x9e, 0x9f, 0xc3, 0x38, 0x8b, 0xc2,
-       0xea, 0xed, 0xdf, 0x06, 0xf0, 0xac, 0xa1, 0xff, 0x30, 0xec, 0x62, 0x3d,
-       0x0e, 0xec, 0x28, 0xd3, 0x4a, 0x67, 0x1e, 0xeb, 0x29, 0x50, 0x53, 0x4c,
-       0x4c, 0x35, 0xc8, 0x84, 0x8c, 0x41, 0x41, 0xe9, 0x8a, 0xd4, 0x6b, 0x52,
-       0x86, 0x55, 0x6f, 0xaa, 0xab, 0xe6, 0xd0, 0xc9, 0xf0, 0x0a, 0x14, 0xf9,
-       0xc3, 0xd4, 0x12, 0x06, 0xc5, 0xfb, 0x2c, 0x0a, 0x16, 0x4c, 0xac, 0x71,
-       0x14, 0x72, 0x1a, 0xe4, 0x5f, 0xcb, 0xf6, 0xbc, 0x48, 0xb1, 0x28, 0xa0,
-       0x7f, 0x84, 0xe2, 0xd2, 0x6e, 0x4d, 0xaf, 0xbd, 0x82, 0xfe, 0x09, 0xd1,
-       0xa5, 0x53, 0x68, 0x35, 0xbc, 0xef, 0xc6, 0x58, 0x7e, 0xd7, 0xa0, 0x8f,
-       0x44, 0x98, 0x78, 0xd4, 0x4a, 0x72, 0x59, 0xee, 0x4f, 0xfb, 0x9a, 0xc9,
-       0xed, 0xfb, 0xed, 0xc1, 0x4e, 0x41, 0x27, 0x3a, 0xb3, 0x98, 0x8f, 0x9a,
-       0x46, 0x0d, 0xe3, 0xb0, 0x37, 0xbc, 0xbf, 0x81, 0xc2, 0xc1, 0xe3, 0xdc,
-       0xcf, 0x7f, 0xe8, 0x77, 0xc8, 0xa8, 0xf1, 0xb7, 0x6f, 0x52, 0xfa, 0x2d,
-       0xb5, 0x3f, 0xf4, 0x1f, 0xcb, 0xde, 0x4b, 0x22, 0x3c, 0xf3, 0x28, 0xd6,
-       0xa8, 0x60, 0x83, 0xe7, 0x02, 0xf0, 0x11, 0xcf, 0xe8, 0xd4, 0x2c, 0x17,
-       0xc9, 0xf5, 0x8f, 0xa2, 0xf7, 0xd7, 0x6d, 0x83, 0xea, 0xec, 0x2b, 0xdf,
-       0xcc, 0x64, 0x18, 0x1b, 0x1f, 0x64, 0x76, 0x0a, 0x5a, 0x3c, 0x22, 0xe5,
-       0x8a, 0x2f, 0xa5, 0x55, 0xf3, 0x9c, 0x13, 0x34, 0x5d, 0x36, 0x69, 0x52,
-       0xa0, 0x85, 0x8f, 0xbd, 0x72, 0x83, 0x2c, 0x60, 0xa1, 0x1f, 0xff, 0xfc,
-       0xf7, 0xa6, 0x86, 0x25, 0xd0, 0xb5, 0x36, 0xeb, 0x98, 0x70, 0x66, 0x95,
-       0x8c, 0x94, 0xf1, 0xcc, 0xbd, 0x64, 0x2e, 0x65, 0x32, 0x52, 0x46, 0x55,
-       0x81, 0x3d, 0x6f, 0x0a, 0xd8, 0x87, 0x75, 0x31, 0xc6, 0x89, 0xa2, 0x9e,
-       0x6f, 0x37, 0xda, 0xb0, 0xd1, 0x43, 0xdb, 0x13, 0xf0, 0x0f, 0x51, 0x0b,
-       0x63, 0xf5, 0xea, 0x7d, 0x8c, 0x0d, 0xec, 0xef, 0x82, 0x1d, 0xb5, 0xdd,
-       0xf2, 0x29, 0x5a, 0xb0, 0xeb, 0xbd, 0xe9, 0xf2, 0x32, 0x3d, 0xc4, 0x73,
-       0xd8, 0x56, 0xed, 0x88, 0xdd, 0x55, 0x72, 0x88, 0xc4, 0x41, 0x3c, 0xf7,
-       0x88, 0xe2, 0x36, 0x69, 0xa1, 0x7f, 0x1f, 0xaf, 0x15, 0x72, 0xf3, 0x99,
-       0xdc, 0x7c, 0x26, 0x37, 0x92, 0xc9, 0x3d, 0xd5, 0x27, 0xf7, 0x14, 0xcb,
-       0x61, 0x6c, 0x90, 0x8d, 0x0d, 0xb2, 0xb1, 0x66, 0x36, 0x36, 0xca, 0xc6,
-       0xa2, 0xed, 0x8d, 0xc1, 0x36, 0x77, 0xca, 0xd1, 0x6c, 0x8a, 0x3d, 0xf9,
-       0x70, 0xe8, 0x53, 0x50, 0xf7, 0xdc, 0xcd, 0xba, 0x31, 0x42, 0xe7, 0xfc,
-       0x21, 0x5a, 0x49, 0xc6, 0x28, 0x4e, 0x56, 0x28, 0x4c, 0x74, 0xc8, 0x8e,
-       0x50, 0xd7, 0xbb, 0x2e, 0x67, 0x7d, 0x1f, 0x7b, 0x66, 0xb3, 0x5c, 0x79,
-       0x96, 0x1c, 0x7c, 0x9f, 0x16, 0xcb, 0xe4, 0x03, 0x2b, 0x3a, 0xf6, 0xad,
-       0xa2, 0x9e, 0xe3, 0xc4, 0xe7, 0x35, 0x37, 0xf5, 0xaa, 0x2b, 0x62, 0x72,
-       0xcb, 0xa1, 0x41, 0x42, 0xaf, 0xc1, 0x4f, 0x49, 0x93, 0xa2, 0xc4, 0xa6,
-       0x0f, 0x8d, 0x97, 0x54, 0x8c, 0xc6, 0x9d, 0x4d, 0x79, 0x79, 0xaf, 0x43,
-       0x57, 0x30, 0xcf, 0xc5, 0xa4, 0x4c, 0xbf, 0x4a, 0x4a, 0xf4, 0x4e, 0x42,
-       0x7a, 0xe8, 0x03, 0xc3, 0x25, 0x41, 0x6f, 0x27, 0xfd, 0x3e, 0xff, 0x88,
-       0x7d, 0x6e, 0xdf, 0x5f, 0x23, 0x7b, 0xb4, 0xc6, 0x38, 0x4b, 0x39, 0xa0,
-       0x9e, 0x72, 0x80, 0xc2, 0x52, 0xab, 0x13, 0x3f, 0x68, 0x80, 0x7f, 0x96,
-       0xfc, 0x60, 0xb7, 0xa1, 0xf6, 0xa3, 0x89, 0x3d, 0xcc, 0x5b, 0xde, 0x9b,
-       0xab, 0xce, 0x92, 0xe7, 0x9e, 0xaa, 0x33, 0x6a, 0x4f, 0x5b, 0x39, 0x2e,
-       0xfb, 0xe6, 0xf8, 0x33, 0xe6, 0x18, 0xa2, 0x06, 0xe2, 0xec, 0x09, 0x13,
-       0xb1, 0xe3, 0xfd, 0xdd, 0x60, 0x5c, 0x39, 0x1b, 0x8c, 0x6f, 0xa2, 0xf1,
-       0x0d, 0x9b, 0xd6, 0xdb, 0x45, 0x72, 0xba, 0x43, 0xb4, 0xd4, 0x19, 0xa4,
-       0xca, 0x05, 0x13, 0x63, 0xef, 0xa3, 0xca, 0xaa, 0x5e, 0xe2, 0x38, 0xae,
-       0xc3, 0xc7, 0xe3, 0x5d, 0x09, 0x7c, 0x0e, 0xd2, 0xf8, 0x9a, 0xab, 0xb0,
-       0xb3, 0xe4, 0xb5, 0x7c, 0x83, 0x7e, 0x4c, 0xd7, 0xf6, 0x15, 0xb0, 0xa6,
-       0x12, 0xf9, 0x93, 0xfd, 0xf3, 0xe9, 0x80, 0x18, 0xf7, 0xc5, 0x45, 0xda,
-       0xe5, 0x3a, 0xa4, 0xb3, 0x3e, 0x9b, 0xc6, 0x2f, 0xd8, 0x5a, 0xbd, 0xc3,
-       0x3e, 0x63, 0xfc, 0xd9, 0x19, 0xfe, 0x4c, 0x2d, 0x3c, 0x53, 0xc4, 0x5c,
-       0x7f, 0x91, 0xa1, 0x27, 0xb1, 0x0f, 0x3a, 0x2d, 0x55, 0x7f, 0x04, 0xfb,
-       0xd0, 0xd7, 0xe5, 0x6f, 0xd7, 0xb3, 0x7e, 0xd6, 0x01, 0x7e, 0xf0, 0xef,
-       0xa7, 0x90, 0xb9, 0xe0, 0x08, 0xcb, 0x14, 0x69, 0x7c, 0x95, 0xf9, 0x05,
-       0x6d, 0x97, 0xdf, 0x79, 0x6d, 0x03, 0xd4, 0x80, 0x57, 0x1a, 0x53, 0x25,
-       0xd8, 0xa5, 0x2b, 0xbe, 0x68, 0x80, 0x3f, 0x74, 0x6f, 0x10, 0x2d, 0xcf,
-       0xf7, 0x73, 0x23, 0x8f, 0xa9, 0xb8, 0x33, 0x44, 0x75, 0xe0, 0xd7, 0x84,
-       0x3d, 0xcb, 0x34, 0x51, 0x3e, 0xaa, 0xbe, 0xa1, 0xaf, 0xc7, 0xdf, 0xc4,
-       0x6d, 0xdf, 0xf0, 0xde, 0xcb, 0x6d, 0x40, 0x6c, 0x7b, 0x2d, 0xcc, 0x62,
-       0x65, 0x7e, 0xe1, 0xf1, 0xcd, 0x32, 0xf6, 0x06, 0x7c, 0x46, 0xf0, 0x25,
-       0x51, 0xb7, 0x6d, 0x82, 0x6f, 0xf4, 0xaf, 0xea, 0x2c, 0x57, 0x62, 0x3d,
-       0x58, 0xff, 0x9a, 0xa9, 0xd5, 0xcf, 0x78, 0xce, 0x1f, 0x88, 0xe5, 0x2b,
-       0xf0, 0xc1, 0xc4, 0x4c, 0x8b, 0xc7, 0xf7, 0x2c, 0xf2, 0x56, 0x9b, 0xc2,
-       0xc4, 0x9e, 0xc2, 0x73, 0x54, 0xff, 0xc9, 0x08, 0xf6, 0xda, 0x75, 0x5a,
-       0xf4, 0x5b, 0xd8, 0x53, 0x20, 0xaf, 0x6b, 0xd2, 0x1b, 0x6d, 0xf6, 0x85,
-       0x4d, 0x95, 0x35, 0x29, 0x4f, 0xfa, 0xbc, 0x27, 0xbf, 0x83, 0x5f, 0x08,
-       0x2b, 0x9c, 0x98, 0xf9, 0x08, 0xfb, 0xb3, 0xde, 0xe3, 0xbd, 0xb1, 0x94,
-       0x4f, 0xbc, 0xd5, 0x29, 0xec, 0xeb, 0x54, 0x66, 0x23, 0xef, 0x97, 0x49,
-       0x2b, 0x55, 0x9d, 0xce, 0x57, 0x3f, 0x93, 0xba, 0xc7, 0xfc, 0x5a, 0x80,
-       0x6f, 0x31, 0xae, 0x8b, 0x71, 0x49, 0x01, 0x3e, 0xfc, 0x07, 0x78, 0x45,
-       0xca, 0xf3, 0x55, 0xf4, 0xaf, 0x1e, 0x87, 0xad, 0x06, 0x64, 0x53, 0x8c,
-       0xb1, 0x3d, 0x73, 0xed, 0x7c, 0x7d, 0xde, 0xcc, 0x7b, 0x4a, 0xdf, 0x10,
-       0x4d, 0x6e, 0x0c, 0xd1, 0xb3, 0xbd, 0x21, 0x1a, 0x3f, 0xcd, 0x32, 0xe0,
-       0xa6, 0xaa, 0x27, 0x22, 0xc6, 0xa8, 0xa7, 0xfc, 0x50, 0x36, 0x74, 0x5e,
-       0x27, 0xbe, 0x6f, 0x10, 0x2d, 0xf7, 0x78, 0x0e, 0xb3, 0x4f, 0xa7, 0x4e,
-       0x87, 0x7e, 0x4a, 0x74, 0xa8, 0xc7, 0xb2, 0x5b, 0xbe, 0x83, 0x5e, 0x01,
-       0x9d, 0x82, 0x38, 0x0f, 0x19, 0x1e, 0xf2, 0xdd, 0x7a, 0x88, 0xfc, 0x15,
-       0xe1, 0x37, 0x87, 0x9c, 0xc6, 0xeb, 0x9f, 0x42, 0xfc, 0x31, 0x8f, 0xdf,
-       0xc4, 0xda, 0x0b, 0xb4, 0xe2, 0xcf, 0x63, 0x0c, 0xef, 0xf1, 0x61, 0x7c,
-       0x1f, 0x46, 0x1e, 0xc8, 0xf2, 0x84, 0xe0, 0x3c, 0xb1, 0x1b, 0x71, 0x30,
-       0x00, 0xee, 0xdf, 0x63, 0x6e, 0xcf, 0x13, 0x18, 0x57, 0xda, 0x83, 0xbc,
-       0x70, 0x3f, 0xfa, 0x59, 0xd7, 0x28, 0xda, 0x01, 0xbc, 0xef, 0xc1, 0xd8,
-       0xfe, 0x1c, 0x91, 0xcb, 0xdd, 0x2d, 0x3f, 0x20, 0x26, 0x56, 0x11, 0x2b,
-       0x6b, 0x9c, 0x27, 0x38, 0x16, 0x79, 0x4f, 0x8b, 0xe0, 0x6f, 0x1b, 0x3a,
-       0x78, 0x6f, 0x8b, 0xd8, 0x43, 0xce, 0x71, 0x82, 0x2a, 0x1b, 0x3b, 0xe5,
-       0x0f, 0x5e, 0x0f, 0x38, 0xec, 0x34, 0xaf, 0xc5, 0x15, 0x0d, 0xf0, 0x59,
-       0xb8, 0x31, 0x8d, 0xef, 0xc8, 0x85, 0x22, 0xb2, 0x1b, 0xa7, 0x53, 0x2e,
-       0x6b, 0x6c, 0x8c, 0x29, 0x9c, 0xc6, 0x89, 0xc0, 0x3b, 0x73, 0x59, 0xce,
-       0x5d, 0x8c, 0x25, 0x0a, 0x20, 0xbb, 0x19, 0x1a, 0x52, 0x2e, 0xf9, 0x23,
-       0xd4, 0x00, 0x2e, 0x03, 0xf0, 0x59, 0x03, 0x7c, 0x56, 0xef, 0xe3, 0xb3,
-       0xfa, 0xe7, 0xf2, 0x19, 0xb8, 0xaa, 0x03, 0xae, 0xea, 0x80, 0xab, 0x50,
-       0x1b, 0xbc, 0x03, 0xec, 0xbf, 0xdd, 0xd9, 0x89, 0xe3, 0x98, 0xdf, 0x98,
-       0xe7, 0xa6, 0xe8, 0xf2, 0xde, 0xff, 0x94, 0xe7, 0x8e, 0x83, 0x13, 0x6c,
-       0xfa, 0xfe, 0xde, 0x7b, 0x73, 0xdd, 0x09, 0x70, 0x9d, 0xf5, 0xf9, 0x5c,
-       0xd7, 0x64, 0xae, 0x33, 0x81, 0xbd, 0x26, 0x78, 0x40, 0x5f, 0xed, 0x9f,
-       0xe7, 0x24, 0xe6, 0xe1, 0x3e, 0x33, 0xcb, 0xa5, 0x3a, 0x75, 0x81, 0x7b,
-       0xc3, 0xe3, 0x79, 0x60, 0x73, 0x92, 0x72, 0xd1, 0x13, 0x66, 0x89, 0xac,
-       0x49, 0xe0, 0x61, 0x75, 0x88, 0x8c, 0xd3, 0xb7, 0xf0, 0x8e, 0x7a, 0x00,
-       0x71, 0x8e, 0x7f, 0x1b, 0xb9, 0x8e, 0x41, 0x70, 0x8d, 0x49, 0x85, 0x55,
-       0x0b, 0xef, 0xda, 0xb6, 0x71, 0x87, 0x90, 0x6f, 0x8c, 0x9a, 0x3b, 0xf3,
-       0x7b, 0x7e, 0xee, 0xf1, 0x98, 0x41, 0xd2, 0xd7, 0x5c, 0xc7, 0xd1, 0x5d,
-       0xff, 0x1a, 0xb8, 0xe1, 0x7d, 0x8f, 0xf9, 0x2f, 0x06, 0x0a, 0x0a, 0x64,
-       0xae, 0xca, 0xe3, 0x56, 0x8d, 0xe7, 0x6e, 0x3a, 0x88, 0x73, 0xe7, 0x35,
-       0xe0, 0x87, 0x73, 0xe7, 0xf9, 0x2a, 0xd7, 0x7b, 0x69, 0x8c, 0xb6, 0x7a,
-       0xf9, 0x9c, 0xa3, 0xb0, 0xdb, 0x82, 0x4c, 0xff, 0x58, 0xc6, 0x8b, 0x94,
-       0xcf, 0x62, 0x4d, 0x06, 0xe6, 0xb1, 0xd6, 0x6c, 0x2a, 0xac, 0xb1, 0x5f,
-       0x5c, 0xc8, 0x57, 0xc4, 0x1c, 0x6d, 0x6e, 0xe3, 0x83, 0x93, 0xbd, 0x0f,
-       0x4c, 0xe6, 0x50, 0x03, 0xb1, 0x59, 0xc4, 0xbc, 0xd6, 0x96, 0x2e, 0xca,
-       0x74, 0xb1, 0xbc, 0x57, 0x7e, 0x76, 0x4b, 0x9e, 0x79, 0x6d, 0xa2, 0xcc,
-       0xfc, 0xc5, 0x76, 0x18, 0x8a, 0x4b, 0x07, 0x33, 0x2e, 0xad, 0x60, 0x3f,
-       0x07, 0x55, 0x5c, 0xea, 0xde, 0xc3, 0x19, 0x9f, 0xee, 0x46, 0xcb, 0x7d,
-       0x37, 0xb2, 0x38, 0x31, 0x61, 0x2f, 0xeb, 0x1d, 0x24, 0x03, 0x76, 0x45,
-       0x6a, 0x4d, 0x7f, 0x93, 0x4b, 0x1e, 0x73, 0x04, 0xe3, 0x53, 0x71, 0x29,
-       0xfa, 0x27, 0x60, 0x33, 0xf3, 0x02, 0xcb, 0xb1, 0xfc, 0x4e, 0x72, 0x7f,
-       0x85, 0x9c, 0xd8, 0x41, 0x0e, 0x7d, 0x1b, 0x2c, 0xc3, 0xdc, 0x30, 0x8a,
-       0xf1, 0x21, 0xf3, 0x02, 0x7c, 0xc6, 0xb2, 0xe5, 0x2c, 0x0e, 0x23, 0x7c,
-       0xe3, 0xba, 0x97, 0xe3, 0x23, 0x20, 0xab, 0xc6, 0xeb, 0xe0, 0x9a, 0x98,
-       0xf3, 0x22, 0xd7, 0xa1, 0x5c, 0x6f, 0xe6, 0xf5, 0xa9, 0x37, 0x35, 0x7b,
-       0xb7, 0x5a, 0x53, 0xf4, 0xd7, 0x9a, 0xe8, 0xd8, 0xb1, 0xd6, 0xf4, 0xac,
-       0xb4, 0xd6, 0xac, 0x58, 0x77, 0xaf, 0x35, 0x73, 0xd9, 0x7b, 0xd7, 0x9a,
-       0x71, 0x87, 0xf7, 0x08, 0xb9, 0x54, 0xf0, 0x5a, 0xa8, 0x69, 0x66, 0x7c,
-       0x11, 0xdd, 0xc6, 0x17, 0xd1, 0x69, 0xb7, 0x7c, 0x8e, 0x38, 0xa6, 0xdd,
-       0x72, 0x8b, 0x6b, 0xa0, 0x0d, 0xae, 0x81, 0x0c, 0xe4, 0xd2, 0x7e, 0xce,
-       0xc8, 0x7d, 0xc2, 0xbe, 0x1c, 0x04, 0x27, 0xb3, 0x1f, 0x8b, 0x19, 0x3f,
-       0xa0, 0xf5, 0x3e, 0x05, 0x3f, 0xe4, 0xbc, 0xc2, 0x3e, 0xfb, 0x7f, 0xe2,
-       0x15, 0xb2, 0x07, 0xc0, 0x0f, 0x36, 0xea, 0xcd, 0x46, 0x47, 0xd9, 0x02,
-       0x5f, 0x48, 0x39, 0xe7, 0x33, 0xf6, 0x53, 0xbe, 0x50, 0x3e, 0x51, 0x78,
-       0x2c, 0xd2, 0xbb, 0x3e, 0x63, 0x01, 0xe7, 0x23, 0x8f, 0x73, 0x22, 0xf3,
-       0xef, 0x4d, 0xf9, 0xae, 0x17, 0xa2, 0x2f, 0xc2, 0x9e, 0x33, 0x0e, 0xe6,
-       0xb5, 0x43, 0xeb, 0x36, 0xe4, 0x18, 0x0b, 0xe5, 0x3b, 0xce, 0x3d, 0xe9,
-       0xf9, 0x84, 0x6b, 0xe1, 0xff, 0x16, 0x1b, 0x17, 0xef, 0x82, 0x8d, 0x37,
-       0x33, 0x6c, 0xfc, 0xf2, 0x1e, 0xd8, 0xb8, 0xf8, 0x05, 0xb1, 0xe1, 0x3a,
-       0x1f, 0xa3, 0x5e, 0x7a, 0xcf, 0x63, 0x7c, 0x48, 0xf9, 0xb1, 0xbf, 0x53,
-       0x3e, 0x09, 0x6c, 0xe3, 0xd5, 0x9b, 0x32, 0xce, 0x72, 0x89, 0xfe, 0xd6,
-       0xad, 0x5c, 0x32, 0xfe, 0x6a, 0x8a, 0x8b, 0xf1, 0xb7, 0xa4, 0x3c, 0xb7,
-       0x03, 0x0e, 0xb8, 0x56, 0xbe, 0x0a, 0x1e, 0x68, 0xd1, 0xff, 0xa2, 0x56,
-       0x66, 0xce, 0xae, 0xda, 0x47, 0xdb, 0xf9, 0xbe, 0xe7, 0x7b, 0x5e, 0xa0,
-       0xb3, 0x62, 0x17, 0xfc, 0xb5, 0x9f, 0x5a, 0xaf, 0x9b, 0x7c, 0x7e, 0x00,
-       0x1e, 0x1e, 0x37, 0x39, 0x56, 0x71, 0x56, 0xc4, 0x73, 0x7f, 0x3d, 0x0d,
-       0x3c, 0xfa, 0xbc, 0x76, 0xb5, 0xee, 0x3e, 0xae, 0xff, 0x1e, 0x4a, 0x92,
-       0x3b, 0xf2, 0xc8, 0xb6, 0x73, 0xb3, 0x81, 0x73, 0x73, 0x5d, 0xe9, 0xe0,
-       0xb3, 0x55, 0xea, 0xbf, 0x13, 0xea, 0xac, 0x7c, 0x53, 0x9e, 0x53, 0xe7,
-       0xe5, 0xd1, 0x02, 0x0d, 0xce, 0x67, 0x58, 0x61, 0x5f, 0x0c, 0xab, 0x7a,
-       0x82, 0x31, 0xd5, 0x42, 0xbe, 0x5d, 0x82, 0x3f, 0x1a, 0x2a, 0x16, 0xb0,
-       0xf6, 0xcc, 0x1f, 0x2d, 0xf8, 0xa3, 0x9e, 0xa4, 0x31, 0xf1, 0xe5, 0x9e,
-       0x1d, 0xfe, 0x88, 0x7c, 0x6a, 0x2f, 0x9a, 0x38, 0x6f, 0x5f, 0x49, 0x54,
-       0xfe, 0x5c, 0x68, 0xb5, 0xa9, 0xf9, 0x60, 0xed, 0x38, 0xd7, 0x6d, 0x5c,
-       0x77, 0xcd, 0x2c, 0x55, 0xd1, 0xd7, 0xb3, 0x29, 0x84, 0x4f, 0xbe, 0x7d,
-       0x90, 0x16, 0x8d, 0x1a, 0xe3, 0x17, 0xef, 0x09, 0x35, 0xc3, 0x83, 0xa8,
-       0xa5, 0x92, 0xb1, 0x45, 0xbd, 0x36, 0x06, 0x1c, 0x35, 0x29, 0x80, 0x9d,
-       0x01, 0x74, 0xcf, 0xb5, 0x6d, 0x7b, 0xb9, 0xcd, 0x67, 0xa4, 0x26, 0xf1,
-       0x19, 0xbc, 0xdb, 0xbb, 0x0e, 0x7d, 0x03, 0xcf, 0xe0, 0xcc, 0xea, 0xc4,
-       0xc0, 0xd5, 0xcb, 0x89, 0x45, 0xad, 0x12, 0xdf, 0x51, 0x30, 0x57, 0x96,
-       0xa1, 0xe3, 0x99, 0x42, 0x8a, 0xcb, 0x32, 0xf4, 0x70, 0xcc, 0x10, 0xe6,
-       0x63, 0xff, 0xe5, 0x58, 0x2b, 0xf7, 0xd5, 0xee, 0x85, 0xec, 0xbc, 0x4a,
-       0xca, 0x07, 0xec, 0xdf, 0xd0, 0x7b, 0xbe, 0x90, 0xdf, 0xc7, 0xb4, 0x10,
-       0xf3, 0x8d, 0x7d, 0x8c, 0x43, 0x0d, 0x78, 0xc3, 0x98, 0x84, 0xfb, 0x90,
-       0x57, 0xf6, 0x21, 0x37, 0x97, 0x8a, 0xaa, 0x6d, 0x26, 0xc7, 0xb2, 0xf1,
-       0xba, 0x1a, 0xc7, 0x39, 0x21, 0x4e, 0xd4, 0x59, 0x41, 0x8b, 0x3a, 0xe4,
-       0x34, 0x7c, 0x9c, 0x81, 0x50, 0x5b, 0xac, 0x24, 0x9c, 0xcf, 0xf7, 0xd9,
-       0xba, 0xe2, 0xb9, 0x4d, 0xc8, 0xe0, 0x79, 0x83, 0xf4, 0x86, 0xcf, 0xf7,
-       0x07, 0xd9, 0xdd, 0x46, 0x89, 0x86, 0x21, 0x0f, 0xbb, 0xc6, 0xd8, 0xae,
-       0xa0, 0xa1, 0x6a, 0x11, 0xd6, 0xbd, 0x5f, 0x4f, 0xef, 0x5c, 0x7e, 0x93,
-       0xcd, 0x65, 0x83, 0x5f, 0x08, 0xe7, 0x1d, 0x9f, 0xf3, 0xda, 0xd7, 0x0c,
-       0xba, 0x4e, 0x8a, 0x23, 0xc5, 0x37, 0x90, 0xef, 0x0e, 0x42, 0x26, 0x50,
-       0xfc, 0x92, 0x9e, 0x19, 0x72, 0x99, 0x8a, 0xb1, 0x5d, 0xc7, 0x77, 0xcc,
-       0xed, 0xef, 0x01, 0x62, 0xab, 0x9a, 0xcd, 0xd7, 0x8f, 0xd3, 0x4d, 0xe0,
-       0x74, 0xb3, 0xb0, 0x75, 0xee, 0x28, 0x15, 0x30, 0x8e, 0x6d, 0x64, 0x2e,
-       0x61, 0x99, 0x4f, 0xac, 0xed, 0x7a, 0x2a, 0x3b, 0xe8, 0xf8, 0x53, 0x9f,
-       0x8e, 0x12, 0xaf, 0x4d, 0x34, 0xd2, 0xf3, 0xb3, 0xfa, 0x6b, 0xc0, 0xcf,
-       0x38, 0x6f, 0x3c, 0xa0, 0x63, 0x1d, 0x5c, 0x7f, 0xd5, 0x55, 0x3f, 0x0e,
-       0x56, 0xdb, 0xf4, 0xfe, 0x30, 0x9b, 0x67, 0x5f, 0x1a, 0x0f, 0x1e, 0xda,
-       0x64, 0xb3, 0xcf, 0x76, 0x6b, 0x87, 0x79, 0x91, 0xd8, 0xbd, 0x19, 0x8d,
-       0xf1, 0x66, 0xd4, 0x38, 0x07, 0xe3, 0x79, 0x0b, 0x1f, 0x8c, 0xd5, 0xcf,
-       0xc7, 0xa8, 0xf5, 0x05, 0x31, 0xfa, 0x46, 0x9b, 0xb9, 0x22, 0xc5, 0x68,
-       0xe3, 0x0e, 0x8c, 0xa2, 0x06, 0x2a, 0xe5, 0xf8, 0xe4, 0x78, 0xc9, 0xf1,
-       0x99, 0x3f, 0xf3, 0xfd, 0x08, 0x38, 0x38, 0xe3, 0xb6, 0x18, 0xdc, 0x16,
-       0xa9, 0x1c, 0xe7, 0x96, 0x23, 0x4a, 0xe3, 0x78, 0x19, 0x71, 0x1c, 0x19,
-       0x9c, 0xf3, 0x38, 0x86, 0x59, 0x8e, 0xe3, 0x98, 0xe5, 0x46, 0x32, 0x39,
-       0xb4, 0x88, 0xe7, 0x28, 0x8b, 0xe7, 0x16, 0x78, 0x37, 0xca, 0xe2, 0xb9,
-       0x85, 0x18, 0x5e, 0xc9, 0xe2, 0xb9, 0x95, 0xc5, 0x33, 0xdf, 0xdb, 0x19,
-       0x55, 0x95, 0x8b, 0x9d, 0x3a, 0x78, 0x6d, 0x45, 0xe9, 0x6c, 0x62, 0x9d,
-       0xb0, 0xb1, 0x93, 0xc7, 0xc5, 0x1d, 0xf7, 0x5b, 0x58, 0xcf, 0xad, 0xbc,
-       0x32, 0x8b, 0xbc, 0x72, 0x0e, 0x79, 0xa5, 0xdb, 0x77, 0xbf, 0x75, 0x56,
-       0xe5, 0x95, 0x27, 0x8b, 0x79, 0x5e, 0xe9, 0x66, 0x79, 0xa5, 0xab, 0xf2,
-       0xca, 0x13, 0x45, 0xce, 0x2b, 0x31, 0x05, 0xc5, 0xfe, 0xbc, 0x12, 0x6f,
-       0xcb, 0x2b, 0xb9, 0x2c, 0xf7, 0xef, 0x94, 0x57, 0x72, 0x9f, 0x71, 0x6e,
-       0xb1, 0x72, 0x5e, 0xbd, 0x2d, 0x9f, 0xe4, 0x63, 0xd8, 0x56, 0xe6, 0x25,
-       0xe6, 0xe0, 0xb4, 0xae, 0xbf, 0x92, 0xe4, 0xb1, 0x74, 0x0c, 0xf3, 0xe0,
-       0xbd, 0xb3, 0x53, 0x2c, 0xd9, 0x59, 0x2c, 0x0d, 0xa7, 0x32, 0x9d, 0xfe,
-       0x78, 0x3a, 0x56, 0xdc, 0x1e, 0x4f, 0xb9, 0x9e, 0x3c, 0x9e, 0x52, 0x9d,
-       0x1f, 0x1a, 0x65, 0xae, 0x07, 0x70, 0x96, 0x76, 0xfd, 0x39, 0xf4, 0x5e,
-       0xe8, 0x4d, 0xa3, 0xae, 0x36, 0xe9, 0x6a, 0xce, 0x37, 0xea, 0xbe, 0x07,
-       0x6d, 0x2f, 0xb7, 0xb5, 0xb8, 0xf5, 0xad, 0x8b, 0xda, 0xfa, 0x7d, 0xf0,
-       0xc8, 0x79, 0xf5, 0xfd, 0x33, 0x79, 0xb5, 0x84, 0x33, 0xb0, 0x97, 0x8f,
-       0x7b, 0x1d, 0xf3, 0xb9, 0xe2, 0x2c, 0x9e, 0x5e, 0xee, 0xdd, 0x82, 0xf9,
-       0x8a, 0xc7, 0x7d, 0xff, 0x44, 0x0e, 0x41, 0x5d, 0xbe, 0x35, 0x96, 0xcf,
-       0x38, 0x1e, 0xd6, 0xec, 0xd0, 0xa5, 0x6d, 0xe7, 0x9c, 0xf4, 0x7c, 0x83,
-       0x75, 0xa3, 0x3e, 0xe1, 0x3a, 0x25, 0xfc, 0x8a, 0x4e, 0x2f, 0xd1, 0xb7,
-       0x7c, 0xee, 0xd3, 0x69, 0xf6, 0x31, 0x29, 0x5f, 0x40, 0xcd, 0xf2, 0xf4,
-       0xb6, 0x9a, 0xa5, 0x48, 0xe3, 0x07, 0xfa, 0xcf, 0x87, 0x37, 0xe5, 0xf8,
-       0xa4, 0x7b, 0x36, 0xa0, 0x40, 0x9b, 0x5d, 0xe7, 0x5a, 0x76, 0xab, 0x76,
-       0x25, 0x1a, 0xbd, 0x21, 0xf5, 0x49, 0xce, 0x85, 0x57, 0x33, 0x5f, 0xe1,
-       0xdb, 0x99, 0x1b, 0xe0, 0xd6, 0x48, 0xdd, 0xf1, 0x06, 0xeb, 0x3c, 0x0f,
-       0xbf, 0xa3, 0x4d, 0xb8, 0xbe, 0xb9, 0xdb, 0xbd, 0xab, 0x89, 0x7d, 0x71,
-       0x9d, 0xa3, 0x06, 0xa9, 0xbb, 0x8b, 0x25, 0xdf, 0xfd, 0x59, 0x8b, 0x52,
-       0x9e, 0x88, 0xfc, 0x05, 0xd8, 0x02, 0x9c, 0x8b, 0x45, 0xec, 0xcd, 0x24,
-       0x78, 0xc9, 0x75, 0x0e, 0xe8, 0x42, 0x61, 0x7f, 0x19, 0xba, 0x8d, 0x03,
-       0x5c, 0x3f, 0x7e, 0x2a, 0x97, 0x7b, 0x2a, 0x07, 0xfb, 0x8c, 0x91, 0x7a,
-       0xb2, 0x5b, 0xe7, 0x36, 0x48, 0xf8, 0xb9, 0x80, 0x79, 0x9c, 0xbb, 0xe0,
-       0xa7, 0x24, 0xa2, 0x33, 0x8e, 0x98, 0xed, 0x38, 0x62, 0xae, 0xa3, 0x03,
-       0xdd, 0xb6, 0x4d, 0xbb, 0xb0, 0x27, 0xc8, 0xc1, 0xf4, 0x00, 0x6c, 0xb9,
-       0xe0, 0x88, 0x3a, 0x6a, 0xc1, 0x1f, 0x18, 0xae, 0x78, 0x9a, 0x3e, 0xc1,
-       0x1a, 0x6f, 0xc8, 0xf4, 0xde, 0xc5, 0x11, 0xd1, 0xd6, 0xdc, 0x37, 0x30,
-       0x37, 0xdb, 0xc4, 0x31, 0xca, 0xf9, 0x72, 0x5e, 0x5b, 0x80, 0x8f, 0x8e,
-       0xac, 0x6b, 0xe0, 0x35, 0xce, 0x97, 0x23, 0xd9, 0xfd, 0x12, 0xf6, 0x07,
-       0xeb, 0xbf, 0x74, 0x47, 0xad, 0x99, 0xd7, 0x94, 0xe9, 0xdd, 0x69, 0x3c,
-       0xc3, 0xf3, 0x13, 0x6c, 0x99, 0x98, 0xba, 0xa0, 0xce, 0x3d, 0xd3, 0xa8,
-       0xf1, 0xb8, 0x95, 0xa8, 0x83, 0xf8, 0xae, 0x8b, 0x6b, 0x27, 0x89, 0xf8,
-       0x4f, 0x9f, 0x63, 0x3e, 0x13, 0xcd, 0xb0, 0x0e, 0x3e, 0x1b, 0x71, 0xfc,
-       0xfc, 0x1b, 0x2f, 0xf3, 0x0a, 0xbd, 0x68, 0x18, 0x00, 0x00, 0x00 };
+       0xcd, 0x58, 0x5d, 0x6c, 0x1c, 0x57, 0x15, 0x3e, 0xf3, 0xb7, 0x3b, 0xde,
+       0x38, 0xf1, 0x24, 0x19, 0xca, 0xa6, 0x72, 0xe9, 0x8c, 0x3d, 0x76, 0x8c,
+       0x6c, 0x35, 0xd3, 0x76, 0xd5, 0x58, 0x68, 0xa4, 0x4e, 0x67, 0x76, 0x1d,
+       0x2b, 0xf4, 0xc1, 0x85, 0x48, 0x3c, 0xf0, 0xe2, 0xae, 0x1d, 0x05, 0x78,
+       0x2a, 0x28, 0x0f, 0x11, 0x2f, 0x59, 0x76, 0x37, 0xfd, 0x41, 0xdb, 0x2c,
+       0x35, 0xc8, 0x41, 0x02, 0xa4, 0xb0, 0x69, 0xe2, 0x97, 0xad, 0x27, 0x2d,
+       0x45, 0xea, 0x4b, 0x95, 0x28, 0x55, 0x2b, 0xc4, 0x13, 0x2f, 0x54, 0x79,
+       0xac, 0x52, 0x5a, 0xf1, 0x00, 0x28, 0x42, 0x15, 0xaa, 0x68, 0xf0, 0xe5,
+       0x3b, 0x77, 0x66, 0xdc, 0xdd, 0xc4, 0x49, 0xcb, 0x9f, 0x84, 0xa5, 0xf5,
+       0x9d, 0xb9, 0xf7, 0x9e, 0x73, 0xcf, 0x3d, 0x3f, 0xdf, 0x39, 0x67, 0xca,
+       0x2a, 0x95, 0x28, 0xfb, 0xdb, 0x8d, 0xdf, 0xc9, 0xa7, 0x9f, 0x39, 0x79,
+       0xf8, 0xa1, 0x47, 0x1d, 0xa2, 0x87, 0x1f, 0x52, 0x94, 0xa2, 0x46, 0xff,
+       0x85, 0x3f, 0x30, 0xb1, 0x72, 0xfe, 0xfc, 0x23, 0x53, 0x0d, 0x7e, 0xe3,
+       0x44, 0x1e, 0x99, 0x5a, 0xb0, 0xf4, 0xe5, 0x15, 0x8f, 0x28, 0xec, 0xcf,
+       0x3a, 0x31, 0xfd, 0x43, 0x34, 0x6c, 0x9d, 0x78, 0xfe, 0x81, 0xe0, 0xd6,
+       0xa1, 0x37, 0x0f, 0xbb, 0x37, 0xcf, 0x6b, 0x64, 0x5a, 0xc1, 0xb2, 0x69,
+       0x4d, 0x93, 0x39, 0x1e, 0x5c, 0x75, 0x7e, 0x7e, 0x30, 0x28, 0xd0, 0x9e,
+       0x9c, 0x97, 0x4d, 0xcd, 0x2e, 0x35, 0xf4, 0xc0, 0xa4, 0x5a, 0xe7, 0x94,
+       0x12, 0x75, 0x3d, 0xab, 0x0a, 0x1e, 0xa1, 0x0d, 0xfe, 0x1e, 0xde, 0x13,
+       0x5d, 0xa9, 0x9e, 0x33, 0x49, 0x0d, 0x42, 0x3c, 0xcf, 0x51, 0xab, 0x2b,
+       0xc4, 0x0f, 0x7d, 0x85, 0x56, 0x7c, 0x93, 0x96, 0x2d, 0x77, 0x31, 0x54,
+       0xb6, 0x44, 0x3c, 0x25, 0xc4, 0xb7, 0x7d, 0x95, 0x54, 0x6f, 0x41, 0x89,
+       0x36, 0x16, 0x95, 0x78, 0x63, 0x91, 0xf5, 0x01, 0xf9, 0x16, 0x94, 0x70,
+       0x83, 0xc7, 0xc0, 0x8c, 0x3b, 0x7b, 0x68, 0xd9, 0xa6, 0x31, 0xd5, 0x9b,
+       0xc3, 0x79, 0x65, 0xf0, 0x71, 0x28, 0xf2, 0x67, 0x2d, 0x95, 0x26, 0xf1,
+       0x1b, 0xa1, 0x9a, 0x4f, 0x23, 0xaa, 0xa7, 0x52, 0xdd, 0x56, 0xe8, 0xe5,
+       0x8a, 0x81, 0xdf, 0x51, 0xa5, 0xba, 0xf1, 0x9d, 0x8c, 0x0f, 0xef, 0x37,
+       0xb1, 0xc6, 0x32, 0x33, 0xfd, 0x20, 0xed, 0x6e, 0x3c, 0x7f, 0x0b, 0xfb,
+       0x0c, 0x8a, 0x2a, 0xb7, 0xaf, 0x8d, 0xe0, 0x59, 0xc1, 0xfc, 0x51, 0xc8,
+       0xc5, 0x7c, 0x1c, 0xc8, 0x31, 0x4e, 0xed, 0xee, 0x22, 0xee, 0x53, 0xa0,
+       0x86, 0x35, 0x35, 0x53, 0x27, 0x1d, 0x34, 0x1a, 0x85, 0xf6, 0x15, 0xa1,
+       0x06, 0x42, 0x44, 0x15, 0x6f, 0xa6, 0x27, 0xcf, 0x50, 0x49, 0xf3, 0x0a,
+       0x54, 0xf5, 0x77, 0x53, 0xcb, 0xd2, 0xa8, 0x39, 0x67, 0x50, 0xb8, 0xa4,
+       0xe3, 0x8e, 0xfb, 0x40, 0xa7, 0x80, 0xfe, 0xa5, 0xcc, 0xe6, 0x45, 0x6a,
+       0x5a, 0x05, 0xcc, 0x8f, 0x51, 0xd3, 0xde, 0xab, 0xa8, 0xc1, 0x0b, 0x98,
+       0x9f, 0xb2, 0x7a, 0xf4, 0x3c, 0x46, 0x05, 0xef, 0x7b, 0xb1, 0x97, 0xdf,
+       0x15, 0xf0, 0x23, 0x2b, 0x4a, 0x66, 0xa8, 0x95, 0xe4, 0xb4, 0x3c, 0x9f,
+       0xce, 0x35, 0x92, 0xdb, 0xed, 0x8d, 0x7d, 0xdd, 0x1a, 0x74, 0xcc, 0xb6,
+       0xc1, 0x9e, 0xdc, 0x2e, 0xd2, 0x07, 0x1e, 0xe7, 0x79, 0xfe, 0xc3, 0xbc,
+       0x43, 0x5a, 0xe0, 0x59, 0x31, 0x7d, 0x85, 0xd2, 0xb5, 0x54, 0xf6, 0xc8,
+       0x7f, 0x2c, 0x7b, 0xb7, 0xad, 0xe8, 0xdc, 0xa3, 0xb8, 0x9f, 0x74, 0x19,
+       0x3c, 0xdb, 0xb8, 0x7f, 0x01, 0xfe, 0xd1, 0x0c, 0x55, 0x6a, 0x94, 0x4d,
+       0x72, 0xe7, 0x57, 0xb1, 0xf2, 0x41, 0x47, 0xa3, 0x98, 0x75, 0xe5, 0xeb,
+       0x19, 0x1d, 0xfb, 0xc6, 0xbb, 0x90, 0xb3, 0x61, 0x99, 0x70, 0xbc, 0xe5,
+       0x63, 0x42, 0x5c, 0xf4, 0x85, 0x28, 0x04, 0xde, 0xcc, 0x25, 0x9a, 0x2d,
+       0x1b, 0x34, 0x6d, 0x61, 0x84, 0x8e, 0xbd, 0x72, 0x9d, 0x8c, 0x5c, 0x9e,
+       0xdc, 0x37, 0xf1, 0xd7, 0x57, 0x08, 0x3e, 0x79, 0xa3, 0xf3, 0x7b, 0xd6,
+       0xc7, 0xcc, 0x82, 0xa4, 0x11, 0xa2, 0x37, 0x7f, 0x2f, 0x9a, 0x5f, 0x67,
+       0x34, 0x42, 0xd4, 0x2a, 0x7c, 0xae, 0x8b, 0x3b, 0xb3, 0x7f, 0x13, 0xd5,
+       0xfa, 0xbe, 0x59, 0xef, 0x40, 0x3e, 0x0f, 0x63, 0x9f, 0xa8, 0xde, 0xe5,
+       0x7b, 0x98, 0xd4, 0x84, 0xde, 0x5a, 0xd8, 0xaf, 0x56, 0x76, 0xb1, 0x7f,
+       0xc0, 0xc6, 0x4b, 0x66, 0xb5, 0xe3, 0x96, 0x5f, 0xa0, 0x25, 0x33, 0xee,
+       0xcf, 0x96, 0x57, 0xe9, 0x01, 0x3e, 0xc7, 0x34, 0x82, 0x63, 0x66, 0x4f,
+       0xd2, 0x1b, 0x1a, 0x95, 0xf0, 0x0c, 0x1e, 0xcd, 0x0e, 0x29, 0x91, 0xbf,
+       0x8b, 0xef, 0x0b, 0xba, 0xc5, 0x8c, 0x6e, 0x31, 0xa3, 0x1b, 0xcb, 0xe8,
+       0x9e, 0x1c, 0xa0, 0x7b, 0x92, 0xe9, 0xb0, 0x37, 0xcc, 0xf6, 0x86, 0xd9,
+       0x5e, 0x3d, 0xdb, 0x5b, 0xcd, 0xf6, 0x62, 0xec, 0x3b, 0x90, 0xcf, 0x9d,
+       0x09, 0x15, 0xc8, 0xe8, 0x89, 0x07, 0x23, 0x9f, 0xc2, 0xd8, 0x73, 0xaf,
+       0xc7, 0xda, 0x18, 0x5d, 0xf0, 0x2d, 0x6a, 0x27, 0x0e, 0x64, 0x6f, 0x53,
+       0x94, 0xa8, 0xa0, 0x1d, 0xa3, 0x9e, 0x77, 0x53, 0xd4, 0xfc, 0x0a, 0x6c,
+       0x37, 0xca, 0x74, 0xe5, 0x1a, 0x14, 0xd1, 0x4c, 0x66, 0xad, 0x55, 0xaa,
+       0xc0, 0x5f, 0x54, 0xd8, 0x6f, 0x52, 0x3e, 0x37, 0x93, 0x0a, 0xd6, 0xa9,
+       0xa1, 0x56, 0x5c, 0xab, 0x49, 0x6e, 0x39, 0xd2, 0xc8, 0x52, 0x03, 0x1b,
+       0x7b, 0x1a, 0x54, 0x4d, 0x4c, 0x7a, 0x4f, 0x3b, 0x25, 0xe3, 0xb4, 0xd9,
+       0xbd, 0x2e, 0xde, 0x3c, 0xe8, 0xd0, 0x95, 0x64, 0x9c, 0x7e, 0x95, 0x94,
+       0xe9, 0xb5, 0xc4, 0xa6, 0x57, 0x13, 0x52, 0x23, 0x1f, 0x7e, 0x6c, 0x5b,
+       0x74, 0x39, 0x19, 0xd4, 0xfb, 0x07, 0xac, 0x77, 0x73, 0x7f, 0x40, 0xe6,
+       0xbe, 0x80, 0x1a, 0x5a, 0x90, 0xe2, 0x40, 0x9c, 0xe2, 0x80, 0xf4, 0xa9,
+       0x56, 0xb7, 0x79, 0xbf, 0x06, 0x0c, 0x5a, 0xf1, 0xc3, 0xbd, 0x1a, 0xec,
+       0x12, 0x23, 0x0a, 0xd4, 0xed, 0x51, 0xda, 0xc8, 0x5d, 0xf1, 0xdc, 0xe7,
+       0x63, 0xec, 0xf6, 0xce, 0x1a, 0x98, 0xbd, 0xdd, 0xb6, 0x7f, 0xc6, 0x19,
+       0xa3, 0xb0, 0x9b, 0x46, 0x4f, 0xe8, 0x88, 0x1f, 0xef, 0x23, 0x8d, 0x63,
+       0xc0, 0xd9, 0xb4, 0xe9, 0x4c, 0x97, 0x68, 0x62, 0xd3, 0xa4, 0x8d, 0x4e,
+       0x91, 0x9c, 0xde, 0x28, 0xad, 0x74, 0x4b, 0x34, 0x79, 0x49, 0xc7, 0xde,
+       0x5d, 0x34, 0xb9, 0xa6, 0xda, 0x1c, 0xcb, 0x31, 0x74, 0x3c, 0xd1, 0x13,
+       0xf0, 0xd1, 0x12, 0x4d, 0xac, 0xbb, 0xd2, 0x7f, 0x56, 0xbc, 0x96, 0xaf,
+       0xd1, 0x0f, 0xe8, 0xda, 0x5c, 0x01, 0x77, 0xb2, 0xc9, 0x9f, 0x1e, 0x3c,
+       0xcf, 0x80, 0x9b, 0xf1, 0x1c, 0x98, 0xee, 0x71, 0x1d, 0x52, 0x99, 0x9f,
+       0x49, 0x13, 0x97, 0x4c, 0x25, 0xee, 0xb2, 0xce, 0xd8, 0x07, 0xcd, 0xcc,
+       0x07, 0x75, 0x25, 0x3a, 0x57, 0xc4, 0x59, 0x7f, 0x12, 0x91, 0x07, 0xdf,
+       0x03, 0x96, 0xad, 0x54, 0xbe, 0x0f, 0xf9, 0x30, 0xd7, 0xe3, 0xb5, 0x9b,
+       0xd9, 0x3c, 0xf3, 0x00, 0x46, 0xf8, 0xfb, 0x29, 0x62, 0x3c, 0x38, 0xc6,
+       0x34, 0x45, 0x9a, 0x58, 0x63, 0x8c, 0xc1, 0xd8, 0xe3, 0x77, 0xbe, 0xdb,
+       0x08, 0xd5, 0xa1, 0x95, 0xfa, 0x8c, 0x0d, 0xb9, 0x54, 0x89, 0x19, 0x75,
+       0x60, 0x88, 0xea, 0x95, 0x30, 0xf2, 0x79, 0x3f, 0xd3, 0xd2, 0xf8, 0xb7,
+       0xa5, 0xbd, 0x63, 0xf8, 0xaf, 0x0e, 0x79, 0x56, 0x69, 0xaa, 0x7c, 0x5c,
+       0xae, 0x61, 0xae, 0xcf, 0x6b, 0xd6, 0x6d, 0x6b, 0x78, 0xef, 0xe7, 0x32,
+       0x20, 0xc6, 0xbd, 0x16, 0x4e, 0x31, 0x32, 0xbd, 0xf0, 0xfe, 0x46, 0x19,
+       0xb6, 0x01, 0xa6, 0x11, 0x74, 0x49, 0xd4, 0xeb, 0xe8, 0xc0, 0x1c, 0xf5,
+       0x8b, 0x2a, 0xd3, 0xd9, 0xcc, 0x07, 0xf7, 0x5f, 0xd7, 0x95, 0xf8, 0x9c,
+       0xe7, 0xfc, 0x81, 0x98, 0x7e, 0x12, 0x3a, 0x98, 0x9a, 0x6f, 0xf1, 0xfe,
+       0xbe, 0x41, 0xde, 0x5a, 0xc3, 0xd2, 0x61, 0x53, 0x15, 0x06, 0x8d, 0x7f,
+       0x34, 0x06, 0x5b, 0xbb, 0x4e, 0x8b, 0x7e, 0x07, 0x79, 0x0a, 0xe4, 0xf5,
+       0x74, 0x7a, 0xb9, 0xc3, 0xba, 0x30, 0x69, 0x72, 0x5d, 0x88, 0xe7, 0x7c,
+       0xb6, 0xc9, 0xbb, 0xd0, 0x0b, 0xe1, 0x86, 0x53, 0xf3, 0x37, 0x60, 0x9f,
+       0x8d, 0x3e, 0xdb, 0xc6, 0x90, 0x3a, 0xf1, 0xd6, 0xe6, 0x60, 0xd7, 0x99,
+       0x4c, 0x46, 0xb6, 0x97, 0x4e, 0xed, 0x8a, 0x4a, 0x17, 0x2b, 0x9f, 0x08,
+       0xd5, 0x63, 0x8c, 0x2d, 0x40, 0xb7, 0xd8, 0xd7, 0xc3, 0xbe, 0xa4, 0x00,
+       0x1d, 0xfe, 0x4d, 0x18, 0xc0, 0xdf, 0x8b, 0x15, 0xcc, 0xaf, 0x9d, 0x86,
+       0xac, 0x1a, 0x68, 0x53, 0x1f, 0x63, 0x79, 0x16, 0x3a, 0xf9, 0xfd, 0xbc,
+       0xf9, 0xb7, 0x25, 0xbf, 0x51, 0x9a, 0xde, 0x1c, 0xa5, 0x13, 0xfd, 0x51,
+       0x9a, 0x38, 0xcb, 0x34, 0x42, 0xb4, 0x2b, 0x8c, 0x91, 0xf0, 0x51, 0x4f,
+       0xea, 0xa1, 0xac, 0xa9, 0x7c, 0x4f, 0xac, 0x6f, 0x12, 0xad, 0xf6, 0xf9,
+       0x0c, 0x7d, 0x80, 0xa7, 0x4a, 0x47, 0x7e, 0x42, 0x74, 0xa4, 0xcf, 0xb4,
+       0xdb, 0xba, 0x03, 0x5f, 0x0b, 0x3c, 0x2d, 0xe2, 0x5c, 0xa4, 0x79, 0xc8,
+       0x79, 0x1b, 0x11, 0x72, 0x58, 0x15, 0xbf, 0x05, 0xe4, 0x35, 0xbe, 0xff,
+       0x1c, 0xe2, 0x8f, 0xb1, 0x7c, 0x0b, 0x77, 0x2f, 0x50, 0xdb, 0x5f, 0xc4,
+       0x1e, 0xb6, 0xf1, 0x51, 0xac, 0xef, 0x46, 0x2e, 0xc8, 0x72, 0x85, 0xc5,
+       0xb9, 0x62, 0x2f, 0xe2, 0x60, 0x04, 0xf8, 0x7f, 0xbf, 0x3e, 0x9c, 0x2b,
+       0xb0, 0xcf, 0x3e, 0x80, 0xdc, 0x80, 0x44, 0x5d, 0x62, 0x5e, 0xfb, 0x31,
+       0x8e, 0xe0, 0xfd, 0x00, 0xf6, 0x0e, 0xe6, 0x89, 0x9c, 0xee, 0x6e, 0x39,
+       0x02, 0x31, 0xb1, 0x86, 0x58, 0x59, 0x9f, 0x61, 0xcc, 0x80, 0x3d, 0xd8,
+       0xa6, 0x45, 0x60, 0xb8, 0x09, 0x1e, 0x6c, 0xdb, 0x22, 0x6c, 0xc8, 0x79,
+       0xce, 0xa2, 0xc9, 0x4d, 0x8e, 0xeb, 0x34, 0x8f, 0xc4, 0xdb, 0x79, 0x84,
+       0x64, 0x4c, 0x34, 0x13, 0xf6, 0x89, 0xd0, 0x8c, 0xce, 0x6e, 0x09, 0xc4,
+       0x70, 0x39, 0x66, 0x5c, 0xdb, 0x9c, 0x05, 0xbd, 0x86, 0xf8, 0xa8, 0x9a,
+       0xf5, 0xb3, 0x29, 0xa6, 0xd5, 0x37, 0x1d, 0xe9, 0x93, 0xcd, 0xc4, 0xc2,
+       0x3b, 0x63, 0x5a, 0x8e, 0x61, 0x4c, 0x4f, 0x61, 0x04, 0x7c, 0x8b, 0x34,
+       0x21, 0x56, 0xfc, 0x31, 0xaa, 0xc3, 0x3f, 0x43, 0xe0, 0x5a, 0x1d, 0xb8,
+       0x16, 0x0f, 0xe0, 0x5a, 0xfc, 0x99, 0xb8, 0x06, 0xcc, 0xea, 0x02, 0xb3,
+       0x50, 0x23, 0xbc, 0x06, 0x8c, 0x7f, 0x15, 0xe7, 0x5d, 0xee, 0xee, 0x84,
+       0x75, 0x8c, 0x73, 0x8c, 0x77, 0x33, 0xf4, 0xe6, 0xc1, 0x7f, 0x15, 0xef,
+       0xda, 0xc0, 0x06, 0x93, 0xbe, 0x7b, 0xf0, 0xde, 0x98, 0x77, 0x06, 0x98,
+       0x67, 0x7c, 0x36, 0xe6, 0x35, 0x18, 0xf3, 0x74, 0xf8, 0x60, 0x03, 0x78,
+       0xa0, 0xae, 0x0d, 0x9e, 0xd3, 0xc1, 0x39, 0x3c, 0xa7, 0x67, 0x79, 0x55,
+       0xa5, 0x1e, 0xfc, 0x5f, 0xf3, 0xf8, 0x9c, 0x39, 0xd6, 0xbb, 0xd4, 0xff,
+       0x13, 0xba, 0x4d, 0xc6, 0x34, 0xfc, 0x62, 0x6d, 0x94, 0xb4, 0xb3, 0x9f,
+       0xfa, 0x3d, 0x6a, 0x03, 0xc4, 0x3b, 0xfe, 0x6d, 0xe6, 0x3c, 0x4a, 0xc0,
+       0x1c, 0x9d, 0x0a, 0x6b, 0x06, 0xde, 0x95, 0xa1, 0x7d, 0x47, 0x90, 0x77,
+       0xb4, 0xc0, 0x9d, 0x7f, 0x9f, 0x9f, 0xfb, 0xbc, 0xa7, 0x44, 0xea, 0xba,
+       0xeb, 0x38, 0xaa, 0xeb, 0x5f, 0x03, 0x46, 0xbc, 0xe3, 0x31, 0x0e, 0x36,
+       0xe1, 0x0d, 0x05, 0xd2, 0xd7, 0xc4, 0x69, 0x23, 0xe0, 0xb3, 0x1b, 0x0e,
+       0xe2, 0xdd, 0x79, 0x09, 0x7e, 0xc4, 0x39, 0xf4, 0x22, 0xe2, 0xa7, 0x96,
+       0xc5, 0x6a, 0xab, 0x9f, 0x9f, 0xb9, 0x0f, 0x72, 0x1b, 0xa0, 0x19, 0xdc,
+       0xcb, 0x71, 0x20, 0xc4, 0x09, 0xdc, 0x49, 0xc3, 0x39, 0xc6, 0xba, 0x49,
+       0x85, 0x75, 0xd6, 0x8b, 0x0b, 0xfa, 0x49, 0x6b, 0x81, 0xae, 0x0f, 0xe1,
+       0xc2, 0x73, 0xfd, 0xeb, 0x3a, 0x63, 0xa9, 0x86, 0x18, 0x2d, 0xe2, 0x5c,
+       0x63, 0x9b, 0x17, 0x65, 0xbc, 0x98, 0xde, 0x2b, 0x9f, 0xd8, 0xa6, 0x67,
+       0x7c, 0x9b, 0x2a, 0x33, 0x8e, 0xb1, 0x1c, 0x9a, 0xc4, 0xd4, 0x52, 0x86,
+       0xa9, 0x93, 0xb0, 0x67, 0x49, 0xc6, 0xa7, 0xea, 0x3d, 0x98, 0xe1, 0xea,
+       0x5e, 0x8c, 0x3c, 0x27, 0xb2, 0x78, 0xd1, 0x21, 0x2f, 0xf3, 0x2d, 0x91,
+       0xb6, 0xce, 0x35, 0x04, 0xdf, 0xe9, 0xaf, 0xf0, 0x6d, 0xc6, 0x0a, 0xf6,
+       0x4f, 0x89, 0xa9, 0x98, 0x9f, 0x82, 0xcc, 0x8c, 0x0f, 0x4c, 0xc7, 0xf4,
+       0x3b, 0xd1, 0xfd, 0x05, 0x74, 0xd6, 0x0e, 0x74, 0x98, 0xdb, 0x64, 0x1a,
+       0xc6, 0x88, 0x7d, 0xd8, 0x1f, 0x31, 0x3e, 0x40, 0x67, 0x4c, 0x3b, 0x9e,
+       0xc5, 0x63, 0x15, 0x6b, 0x5c, 0x03, 0xcb, 0xf8, 0x22, 0x23, 0xe0, 0x7b,
+       0x70, 0x7d, 0xcc, 0xf9, 0x91, 0x6b, 0x52, 0xae, 0x3d, 0xf3, 0x5a, 0xd5,
+       0x9b, 0xa9, 0xdd, 0xad, 0xee, 0xb4, 0x06, 0xeb, 0xce, 0x43, 0xc6, 0xce,
+       0x75, 0xe7, 0x41, 0x23, 0xad, 0x3b, 0xa7, 0x8d, 0xbb, 0xd7, 0x9d, 0x39,
+       0xed, 0xbd, 0xeb, 0xce, 0x66, 0x97, 0xcf, 0xdc, 0x19, 0x2f, 0x56, 0xe0,
+       0xaf, 0xad, 0x24, 0xbf, 0x27, 0xf7, 0x06, 0xa1, 0x59, 0x3b, 0x9b, 0xda,
+       0xbe, 0x29, 0x7d, 0x11, 0x38, 0xb2, 0x39, 0x0b, 0x3b, 0xa2, 0xa6, 0x1e,
+       0xc2, 0x8e, 0x9c, 0x86, 0x75, 0x5a, 0x02, 0x46, 0xb3, 0x3e, 0x8b, 0x19,
+       0x4e, 0x60, 0xf4, 0x3e, 0x06, 0x4e, 0xe4, 0xf8, 0xc2, 0xfc, 0xfe, 0x9f,
+       0xf0, 0x85, 0xcc, 0x11, 0xe0, 0x84, 0x19, 0x30, 0x5e, 0x4a, 0x59, 0x50,
+       0x93, 0x0b, 0xb1, 0xe0, 0x73, 0x0c, 0x0c, 0xf6, 0x4c, 0xec, 0x0f, 0x45,
+       0x7a, 0xcb, 0x67, 0x9f, 0x40, 0xcf, 0xe4, 0x71, 0x8e, 0x64, 0x3c, 0xde,
+       0x12, 0x6f, 0x79, 0x11, 0xe6, 0xaa, 0xb0, 0x3d, 0xfb, 0xc3, 0xa2, 0x72,
+       0x64, 0xc3, 0x04, 0x1d, 0xfb, 0xc4, 0xf8, 0x1d, 0xbd, 0x50, 0xda, 0xb3,
+       0x70, 0x7d, 0xfc, 0xef, 0xfa, 0xc8, 0x1b, 0x77, 0xf1, 0x91, 0xcb, 0x99,
+       0x8f, 0x24, 0xf7, 0xf0, 0x91, 0x37, 0x3e, 0xa7, 0x8f, 0xb8, 0xe5, 0x0f,
+       0x51, 0x3f, 0xbd, 0x0d, 0x39, 0x42, 0x4b, 0x88, 0x0f, 0xfd, 0x9d, 0xfa,
+       0x94, 0xd0, 0xd4, 0x5f, 0x64, 0x9d, 0xa5, 0x79, 0xa5, 0x85, 0x77, 0xed,
+       0x15, 0xae, 0x97, 0x39, 0xe7, 0xa4, 0xb9, 0x65, 0xe2, 0xc5, 0xd4, 0x3f,
+       0x26, 0x5e, 0x11, 0xe2, 0xc2, 0x0e, 0xfe, 0xc0, 0x35, 0xf4, 0x55, 0xf8,
+       0x55, 0x8b, 0xfe, 0x17, 0x35, 0x34, 0x63, 0x78, 0xc5, 0x3c, 0xde, 0xc9,
+       0xed, 0x9f, 0xdb, 0xbe, 0x40, 0xe7, 0xad, 0x3d, 0xd0, 0xdb, 0xa3, 0xd4,
+       0xfa, 0xb1, 0xce, 0x7d, 0x05, 0xfc, 0xe2, 0x71, 0x9d, 0x63, 0x17, 0x7d,
+       0x24, 0x9e, 0x07, 0xeb, 0x6c, 0xf8, 0xa5, 0x5f, 0xc8, 0xe3, 0x65, 0x00,
+       0xfb, 0x4f, 0xa1, 0x54, 0xb9, 0x23, 0xaf, 0x0c, 0xf5, 0xd4, 0x1a, 0x7a,
+       0xea, 0x58, 0xf2, 0xe0, 0xbe, 0x2b, 0xd5, 0x63, 0x5b, 0xf6, 0xd1, 0x5b,
+       0xa2, 0x25, 0x7b, 0xe9, 0x03, 0x05, 0x2a, 0x2d, 0x66, 0x3e, 0xe3, 0x20,
+       0x1f, 0xb9, 0x7e, 0x03, 0xfc, 0xb9, 0xd6, 0x80, 0x1c, 0xb4, 0x8a, 0x58,
+       0xbc, 0x80, 0x3c, 0xbc, 0x02, 0xbd, 0xd4, 0x65, 0x6c, 0x8c, 0xd1, 0x35,
+       0xe4, 0xfe, 0x36, 0xf2, 0xf3, 0x19, 0xe8, 0xa6, 0x05, 0xdd, 0xc4, 0x49,
+       0x1a, 0x27, 0xd7, 0xa0, 0x9b, 0x85, 0x01, 0xdd, 0x2c, 0xfc, 0x47, 0xfd,
+       0xc5, 0x1f, 0x91, 0x6b, 0xcd, 0x65, 0x1d, 0xf3, 0x57, 0x12, 0x99, 0x5b,
+       0x97, 0x5a, 0x1d, 0x6a, 0xdc, 0x1f, 0x9c, 0xe6, 0xda, 0x8e, 0x6b, 0xb3,
+       0xf9, 0x95, 0x0a, 0xe6, 0xfa, 0x26, 0x45, 0xd0, 0xcf, 0x37, 0x0f, 0xd3,
+       0xb2, 0x16, 0xb0, 0x4f, 0xe3, 0x3d, 0xa1, 0x46, 0x74, 0x18, 0xf5, 0x56,
+       0x32, 0xbe, 0x8c, 0x7e, 0x1c, 0xbe, 0xd5, 0xa0, 0x10, 0x72, 0x86, 0xe0,
+       0xbd, 0xd0, 0x31, 0xcd, 0xd5, 0x0e, 0xf7, 0x51, 0x0d, 0xe2, 0x5e, 0xbd,
+       0xd7, 0xbf, 0x09, 0x7e, 0x23, 0xdf, 0x40, 0x7f, 0xeb, 0x34, 0x81, 0xd3,
+       0xcf, 0xc2, 0x6d, 0x5b, 0x36, 0x7f, 0xcb, 0x60, 0x1c, 0x1d, 0x07, 0x8f,
+       0xa7, 0x0b, 0xa9, 0xaf, 0x8e, 0x83, 0x0f, 0xc7, 0x11, 0xe1, 0x3c, 0xd6,
+       0x65, 0xee, 0x7f, 0xe5, 0x81, 0xfa, 0xbe, 0x40, 0x39, 0x86, 0x35, 0xa1,
+       0x37, 0xd6, 0x75, 0xe4, 0x9d, 0x2c, 0xe4, 0xdf, 0x6d, 0x5a, 0xc0, 0x81,
+       0xfa, 0x1c, 0x63, 0x96, 0x02, 0xdf, 0xa3, 0xb4, 0xaf, 0x44, 0x1f, 0x52,
+       0x9f, 0x43, 0xde, 0xb6, 0x8b, 0x72, 0x6c, 0x24, 0xa7, 0xb3, 0xfd, 0xaa,
+       0xdc, 0xc7, 0xf9, 0xa2, 0x99, 0xc8, 0x7e, 0x42, 0xa9, 0x76, 0xc9, 0xa9,
+       0xfb, 0xe8, 0x93, 0x50, 0x7b, 0xb4, 0x13, 0xce, 0xf5, 0x73, 0xa6, 0x2a,
+       0xb1, 0xef, 0x06, 0x68, 0xf0, 0xbc, 0x49, 0x6a, 0xdd, 0xe7, 0xef, 0x0c,
+       0xfc, 0x0d, 0x04, 0xf1, 0x63, 0xd3, 0x6e, 0xd0, 0x43, 0xae, 0x71, 0x96,
+       0x2b, 0xac, 0xcb, 0x3a, 0x85, 0x79, 0x1f, 0x52, 0xd3, 0x6f, 0x33, 0xef,
+       0x66, 0x67, 0x99, 0x88, 0x1f, 0xc6, 0x5d, 0x9f, 0x73, 0xde, 0x97, 0x34,
+       0xba, 0x49, 0x12, 0x37, 0xad, 0x87, 0x91, 0x0b, 0x0f, 0x83, 0x26, 0x94,
+       0x98, 0x93, 0xf6, 0x15, 0x39, 0x8d, 0xa7, 0x0d, 0xf3, 0x58, 0xd6, 0x87,
+       0xdf, 0x43, 0xc4, 0x59, 0x25, 0x3b, 0x6f, 0xd0, 0x67, 0xdf, 0x87, 0xcf,
+       0xde, 0xc8, 0xf6, 0x00, 0x87, 0xed, 0x02, 0xf6, 0xb1, 0x8c, 0x8c, 0x2f,
+       0x4c, 0xb3, 0x65, 0x0c, 0xf3, 0x99, 0xdc, 0x81, 0xc7, 0x47, 0x03, 0x3c,
+       0x6c, 0xbe, 0x9b, 0x55, 0x4f, 0x7b, 0x6c, 0xf9, 0x57, 0x87, 0x9e, 0xd1,
+       0x93, 0xdc, 0xa7, 0xe2, 0x1e, 0x5c, 0x9b, 0xc5, 0x72, 0xfe, 0x97, 0xc5,
+       0x61, 0xbe, 0xa7, 0xb2, 0x73, 0xfc, 0x34, 0x36, 0x3c, 0x8c, 0xc9, 0x8d,
+       0x01, 0xd9, 0x8d, 0x1d, 0xce, 0xdd, 0xa5, 0xa3, 0x35, 0x50, 0xd8, 0xdf,
+       0xb4, 0x80, 0xf3, 0x33, 0x9e, 0xb7, 0xfd, 0x83, 0x7d, 0xf5, 0xb3, 0x7d,
+       0xd4, 0xf8, 0x9c, 0x3e, 0xfa, 0x72, 0x87, 0x71, 0x23, 0xf5, 0xd1, 0xfa,
+       0x1d, 0x3e, 0x8a, 0xfa, 0xc8, 0xce, 0xfd, 0x93, 0xe3, 0x25, 0xf7, 0xcf,
+       0xfc, 0x99, 0x63, 0x1c, 0xb8, 0x9c, 0xe1, 0x5c, 0x13, 0x38, 0x57, 0x95,
+       0x79, 0xcf, 0x2d, 0x57, 0x29, 0x8d, 0xe5, 0x55, 0xc4, 0x72, 0x55, 0xe3,
+       0x3c, 0xc8, 0x31, 0xcc, 0x74, 0x1c, 0xc7, 0x4c, 0x37, 0x96, 0xd1, 0x61,
+       0x44, 0x3c, 0x57, 0xb3, 0x78, 0x6e, 0x75, 0x5d, 0xa7, 0x9a, 0xc5, 0x73,
+       0x0b, 0x31, 0xdc, 0xce, 0xe2, 0xb9, 0x95, 0xc5, 0x33, 0x7f, 0xdf, 0xd3,
+       0x2a, 0x9c, 0x1b, 0x5d, 0x27, 0x06, 0xc6, 0xb5, 0x25, 0xcf, 0x06, 0xee,
+       0x09, 0x19, 0xbb, 0x79, 0x5c, 0xdc, 0xf1, 0x1d, 0x0c, 0xf7, 0xf9, 0x34,
+       0xd7, 0xd4, 0x90, 0x6b, 0x2e, 0x20, 0xd7, 0xf4, 0x06, 0xbe, 0x83, 0x9d,
+       0x97, 0xb9, 0xe6, 0xeb, 0xc5, 0x3c, 0xd7, 0xf4, 0xb2, 0x5c, 0xd3, 0x93,
+       0xb9, 0xe6, 0xab, 0x45, 0xce, 0x35, 0x4d, 0x3a, 0x5a, 0x1c, 0xcc, 0x35,
+       0xcd, 0xa1, 0x5c, 0x93, 0xd3, 0xf2, 0xfc, 0x4e, 0xb9, 0x26, 0xd7, 0xd9,
+       0xbd, 0x6a, 0x92, 0x7c, 0x0f, 0xcb, 0xca, 0xb8, 0xc4, 0x78, 0x9c, 0xd6,
+       0xfc, 0x57, 0x92, 0x3c, 0x96, 0x4e, 0xe3, 0x1c, 0xbc, 0x77, 0x77, 0x8a,
+       0x25, 0x33, 0x8b, 0xa5, 0xdd, 0x29, 0x4d, 0x77, 0x30, 0x9e, 0x4e, 0x17,
+       0x87, 0xe3, 0x29, 0xe7, 0x93, 0xc7, 0x53, 0xca, 0xf3, 0x3d, 0xad, 0xcc,
+       0x35, 0x02, 0xfa, 0x6d, 0xd7, 0x5f, 0xc0, 0xec, 0xa5, 0xfe, 0x2c, 0x6a,
+       0x6e, 0x9d, 0xae, 0xe6, 0x78, 0x23, 0xbf, 0x09, 0x61, 0xec, 0xe7, 0xb2,
+       0x16, 0xb7, 0xd7, 0x7a, 0xa8, 0xbb, 0xdf, 0x01, 0x8e, 0x5c, 0x94, 0xeb,
+       0x9f, 0x88, 0xab, 0x68, 0x09, 0xdb, 0x5e, 0xbe, 0xef, 0x17, 0x38, 0xcf,
+       0xb5, 0xce, 0xe3, 0xe9, 0xd9, 0x7e, 0xae, 0x13, 0x5e, 0xe7, 0xb9, 0xbf,
+       0x23, 0x9f, 0xa0, 0x66, 0xdf, 0xde, 0xcb, 0xfd, 0x8f, 0x87, 0x3b, 0x3b,
+       0xf4, 0xfa, 0x50, 0x0f, 0x94, 0xf6, 0x3e, 0x75, 0xf9, 0x8d, 0x97, 0x6b,
+       0x97, 0xe8, 0x0b, 0x2a, 0x9d, 0xa2, 0xaf, 0xf9, 0x3c, 0xa7, 0x52, 0xed,
+       0x31, 0x21, 0x9e, 0x41, 0x1d, 0xf3, 0xd4, 0x50, 0x1d, 0x53, 0xa4, 0x89,
+       0x47, 0x06, 0x7b, 0xc8, 0x2d, 0x31, 0x31, 0xed, 0x9e, 0x0f, 0x29, 0x54,
+       0x6a, 0x1b, 0x5c, 0xe7, 0x6e, 0xd7, 0xb5, 0x44, 0xfb, 0x6e, 0x09, 0x75,
+       0x9a, 0xf3, 0xe2, 0x6f, 0x33, 0x5d, 0x61, 0xed, 0xdc, 0x2d, 0x60, 0x6b,
+       0x55, 0x7e, 0x0b, 0x0e, 0x37, 0xf8, 0x1c, 0x7e, 0xc7, 0x98, 0x70, 0xcd,
+       0x73, 0xb7, 0xef, 0xb3, 0x3a, 0xec, 0xe2, 0x3a, 0xc7, 0x35, 0x92, 0xdf,
+       0x37, 0x56, 0x7c, 0xf7, 0xa7, 0x2d, 0x4a, 0x71, 0xa2, 0xea, 0x2f, 0x41,
+       0x16, 0xd4, 0x9d, 0xd6, 0x32, 0x6c, 0x33, 0x0d, 0x5c, 0x72, 0x9d, 0x47,
+       0x54, 0x5b, 0xe2, 0xf8, 0x2a, 0x78, 0x6b, 0x8f, 0x70, 0x4d, 0xf9, 0xb1,
+       0x58, 0xed, 0xcb, 0x7c, 0xec, 0xb3, 0x8f, 0xc4, 0xc9, 0x5e, 0x95, 0xc7,
+       0x30, 0xe1, 0xe7, 0x02, 0x71, 0x2d, 0xb9, 0xb3, 0xff, 0xd8, 0x56, 0xf5,
+       0x9c, 0x63, 0xd5, 0xba, 0x8e, 0xb5, 0xd0, 0x55, 0xe1, 0xdd, 0xfb, 0x4c,
+       0xda, 0x03, 0x9b, 0x20, 0x1f, 0xd3, 0x7d, 0x90, 0xe5, 0x92, 0x63, 0xc5,
+       0xa8, 0x0f, 0xbf, 0xa7, 0xb9, 0xd6, 0x53, 0xa4, 0x98, 0x54, 0xba, 0x25,
+       0xd2, 0x6f, 0x33, 0x8e, 0x55, 0xdd, 0x3e, 0xfb, 0x16, 0xce, 0x66, 0x99,
+       0x38, 0x46, 0x39, 0x5f, 0x2e, 0x2a, 0x4b, 0xd0, 0xd1, 0xb1, 0x8d, 0x5d,
+       0xc0, 0x35, 0xce, 0x97, 0x07, 0xb2, 0x6f, 0x50, 0xb0, 0x0f, 0xee, 0xff,
+       0xfa, 0x1d, 0xf5, 0x67, 0x5e, 0x67, 0x32, 0xbd, 0x10, 0xcd, 0x79, 0x3e,
+       0x9f, 0x20, 0xcb, 0xd4, 0xcc, 0x25, 0xd9, 0x13, 0xcd, 0xa2, 0xee, 0xe3,
+       0x51, 0xa0, 0x26, 0xe2, 0xef, 0x61, 0xae, 0x55, 0xc7, 0x73, 0x35, 0x7b,
+       0x6e, 0x72, 0xbf, 0x34, 0xcf, 0x3c, 0xb8, 0x6f, 0xe2, 0xf8, 0xf9, 0x27,
+       0x6e, 0xb7, 0x92, 0x82, 0x90, 0x18, 0x00, 0x00, 0x00 };
 
 static const u32 bnx2_TPAT_b09FwData[(0x0/4) + 1] = { 0x0 };
 static const u32 bnx2_TPAT_b09FwRodata[(0x0/4) + 1] = { 0x0 };
 
 static struct fw_info bnx2_tpat_fw_09 = {
+       /* Firmware version:  3.7.1 */
        .ver_major                      = 0x3,
-       .ver_minor                      = 0x4,
-       .ver_fix                        = 0x3,
+       .ver_minor                      = 0x7,
+       .ver_fix                        = 0x1,
 
        .start_addr                     = 0x08000860,
 
        .text_addr                      = 0x08000800,
-       .text_len                       = 0x1864,
+       .text_len                       = 0x188c,
        .text_index                     = 0x0,
        .gz_text                        = bnx2_TPAT_b09FwText,
        .gz_text_len                    = sizeof(bnx2_TPAT_b09FwText),
 
-       .data_addr                      = 0x08002080,
+       .data_addr                      = 0x080020c0,
        .data_len                       = 0x0,
        .data_index                     = 0x0,
        .data                           = bnx2_TPAT_b09FwData,
 
-       .sbss_addr                      = 0x08002088,
-       .sbss_len                       = 0x2c,
+       .sbss_addr                      = 0x080020c8,
+       .sbss_len                       = 0x30,
        .sbss_index                     = 0x0,
 
-       .bss_addr                       = 0x080020c0,
+       .bss_addr                       = 0x08002100,
        .bss_len                        = 0x850,
        .bss_index                      = 0x0,
 
@@ -3267,768 +3289,770 @@ static struct fw_info bnx2_tpat_fw_09 = {
 };
 
 static u8 bnx2_TXP_b09FwText[] = {
-/*     0x1f, 0x8b, 0x08, 0x00, 0x0e, 0x34, 0xe7, 0x45, 0x00, 0x03, */
-                                                                   0xcd, 0x7c,
-       0x6f, 0x70, 0x5b, 0xd7, 0x95, 0xdf, 0x79, 0xef, 0x81, 0x24, 0x48, 0xd1,
-       0xd4, 0x13, 0x17, 0x56, 0x60, 0x87, 0x71, 0x00, 0xf1, 0x81, 0x66, 0x42,
-       0xae, 0x04, 0x2b, 0x4c, 0xc2, 0x6d, 0xd1, 0xf8, 0x05, 0x00, 0x29, 0x48,
-       0xd1, 0x6c, 0x68, 0x95, 0x49, 0x94, 0x54, 0xe3, 0x62, 0x41, 0x52, 0xf1,
-       0xb6, 0xce, 0x54, 0x9b, 0x78, 0x5a, 0x4d, 0xeb, 0xad, 0x11, 0x90, 0xfa,
-       0xe7, 0x85, 0x04, 0xda, 0x62, 0x44, 0x7f, 0xc8, 0x07, 0x18, 0x80, 0x24,
-       0x6f, 0xf2, 0x44, 0x28, 0x9b, 0x7f, 0xfd, 0xd0, 0xac, 0x50, 0x4a, 0xd6,
-       0xba, 0x9b, 0xb4, 0xa3, 0xed, 0x66, 0x67, 0x3b, 0xd3, 0x2f, 0x1c, 0x49,
-       0xf6, 0x7a, 0x77, 0x67, 0x36, 0xda, 0x6e, 0xb6, 0xab, 0xb6, 0xb2, 0xd1,
-       0xdf, 0xef, 0xbe, 0xf7, 0x28, 0x90, 0xa6, 0x6c, 0xcb, 0xb3, 0xed, 0x94,
-       0x33, 0x18, 0xe0, 0xdd, 0x77, 0xdf, 0xb9, 0xe7, 0x9e, 0x73, 0xee, 0x39,
-       0xe7, 0x77, 0xee, 0x7d, 0x0c, 0x8b, 0x74, 0x89, 0xf7, 0xf7, 0x00, 0x3e,
-       0x91, 0x43, 0x87, 0x9f, 0xd9, 0x3e, 0xb2, 0xfd, 0x13, 0xf8, 0xf9, 0x09,
-       0x31, 0x02, 0x06, 0x6f, 0xbe, 0x69, 0x88, 0x64, 0xff, 0x42, 0x3e, 0xf0,
-       0x1f, 0x1e, 0x37, 0x7d, 0xfa, 0xfc, 0x48, 0x50, 0x4f, 0x4c, 0xec, 0x4a,
-       0x5a, 0x12, 0x34, 0x12, 0xb2, 0x6f, 0xca, 0x12, 0xb1, 0x9d, 0xa1, 0x48,
-       0x4a, 0xde, 0x6a, 0xe6, 0x43, 0x01, 0x61, 0xfb, 0x47, 0x12, 0x77, 0x9e,
-       0xfb, 0xc9, 0xa7, 0xa3, 0xb7, 0xca, 0x86, 0x04, 0xcd, 0x44, 0x56, 0xcc,
-       0x01, 0x09, 0xf6, 0xe1, 0x99, 0x6f, 0x3f, 0x6a, 0x18, 0xd2, 0xb3, 0xca,
-       0xab, 0xcc, 0x95, 0x56, 0x9a, 0x3f, 0x79, 0x34, 0x2c, 0xbf, 0x57, 0x0f,
-       0xc9, 0xf7, 0xea, 0xa6, 0x5c, 0xac, 0x07, 0xb4, 0xf1, 0x92, 0x29, 0xb3,
-       0xa5, 0x69, 0xfd, 0x48, 0x31, 0x2f, 0xa9, 0x7a, 0x56, 0x2f, 0x2c, 0x98,
-       0x3d, 0xc9, 0xf3, 0x39, 0x7d, 0x76, 0xa1, 0xb7, 0x27, 0x75, 0x7e, 0x5a,
-       0x2f, 0x14, 0xc3, 0x3d, 0xc9, 0xba, 0xd9, 0x93, 0x5a, 0x0c, 0xe1, 0xba,
-       0xb7, 0x27, 0xb9, 0x18, 0x9d, 0x17, 0xd9, 0x8a, 0x3e, 0xe1, 0x9e, 0x54,
-       0x29, 0x9a, 0x15, 0xe9, 0x8f, 0xbf, 0x2a, 0x7d, 0x3d, 0xa9, 0xfa, 0x3f,
-       0xd1, 0x1b, 0xa6, 0x26, 0x85, 0x5f, 0x15, 0x33, 0x9c, 0xb8, 0xd5, 0x7c,
-       0xc8, 0xd2, 0xc4, 0xb4, 0x6e, 0x37, 0xb7, 0x58, 0x41, 0xc9, 0x9d, 0xee,
-       0x14, 0x5b, 0xcd, 0xc9, 0x94, 0xdc, 0xe2, 0x90, 0xb9, 0x2c, 0x6d, 0x62,
-       0x87, 0xfc, 0xeb, 0x66, 0x33, 0x19, 0xff, 0x32, 0xe5, 0x8a, 0x71, 0xa4,
-       0x67, 0xbc, 0x2e, 0x92, 0x2c, 0x05, 0x25, 0x19, 0x7f, 0xab, 0xe9, 0x3e,
-       0x13, 0xc4, 0x98, 0x81, 0x9e, 0xb1, 0x52, 0xb3, 0x99, 0x8e, 0x83, 0x7e,
-       0xdc, 0x7f, 0xb6, 0x4d, 0xca, 0x21, 0xbb, 0x3c, 0x1b, 0xff, 0x6f, 0xba,
-       0xab, 0x13, 0xce, 0x91, 0xd7, 0xb6, 0xe8, 0x56, 0x5e, 0x72, 0x21, 0x29,
-       0x17, 0xe2, 0x9f, 0x92, 0x13, 0xf1, 0x30, 0xe6, 0x17, 0x94, 0x63, 0x71,
-       0xc8, 0xd1, 0x3a, 0xac, 0x25, 0xeb, 0xd1, 0x48, 0x56, 0x9e, 0x97, 0xe4,
-       0x62, 0xbf, 0x99, 0x16, 0x8c, 0x6d, 0x35, 0x3f, 0x9a, 0x8c, 0x63, 0xbc,
-       0xe1, 0xff, 0xd5, 0xb4, 0x43, 0xd1, 0x6c, 0x59, 0x06, 0xa5, 0x50, 0xea,
-       0x8f, 0xff, 0x4c, 0x34, 0x09, 0x5a, 0x62, 0x4f, 0x59, 0x26, 0xe4, 0x16,
-       0x1d, 0x4c, 0x19, 0x4d, 0xd9, 0x83, 0xf1, 0x93, 0x16, 0xee, 0xd7, 0x65,
-       0xb3, 0x6e, 0xb5, 0x4b, 0xc1, 0x94, 0x50, 0x97, 0x3c, 0x22, 0x85, 0xd3,
-       0x68, 0x8f, 0xdb, 0xbd, 0x3a, 0x9e, 0xc9, 0x8c, 0xb0, 0x4d, 0x34, 0x23,
-       0x11, 0x33, 0x53, 0xe0, 0xa8, 0xe2, 0x0c, 0x62, 0xfc, 0x98, 0xdd, 0xa9,
-       0x99, 0xb2, 0x62, 0x06, 0xa4, 0xea, 0xc4, 0xec, 0xb0, 0xd6, 0x2e, 0xc7,
-       0x62, 0x5d, 0x90, 0x69, 0x18, 0xb4, 0xe5, 0x9b, 0x7a, 0x22, 0x16, 0xce,
-       0x41, 0x51, 0x3a, 0x64, 0x35, 0x07, 0x7e, 0xe6, 0xe2, 0x59, 0x2d, 0x55,
-       0xff, 0x8a, 0x96, 0x3c, 0xbf, 0x5f, 0xdb, 0x75, 0x1e, 0x7d, 0xea, 0xe7,
-       0x3c, 0xbb, 0x0b, 0x83, 0x37, 0x1d, 0xcf, 0xb2, 0x1d, 0x3c, 0x2b, 0xde,
-       0xd1, 0x06, 0x5d, 0x36, 0x26, 0x43, 0x3d, 0x49, 0xa5, 0x4b, 0xf2, 0xa6,
-       0x4b, 0x6e, 0x42, 0x93, 0x5e, 0xcb, 0x96, 0xe0, 0x27, 0xa1, 0xcf, 0x45,
-       0xe8, 0x72, 0x31, 0x22, 0x47, 0x4a, 0x12, 0xd2, 0x85, 0x63, 0x65, 0xf5,
-       0xaa, 0x43, 0x7b, 0x80, 0x6e, 0xa1, 0xfb, 0x82, 0xc3, 0x67, 0xa1, 0xc3,
-       0x52, 0x1a, 0xf2, 0xc9, 0x60, 0xec, 0x7d, 0xda, 0x9e, 0xea, 0xa4, 0x96,
-       0x81, 0x9d, 0x14, 0x4e, 0x0f, 0x41, 0x77, 0xd1, 0xc8, 0x8a, 0x6c, 0x96,
-       0x82, 0x65, 0x45, 0xbe, 0x2c, 0xdd, 0x72, 0x6c, 0xd1, 0x92, 0x23, 0x8b,
-       0x21, 0xc9, 0x9b, 0x51, 0xb3, 0x26, 0x7d, 0xd9, 0x4d, 0x89, 0x1e, 0x79,
-       0xfe, 0x74, 0x34, 0x53, 0x96, 0x7e, 0xfb, 0x75, 0xdc, 0xcf, 0x9d, 0xa4,
-       0x4e, 0x25, 0x9f, 0x8a, 0x1b, 0x92, 0x85, 0x4d, 0x18, 0xd6, 0x1f, 0x81,
-       0xff, 0xe6, 0x73, 0xc9, 0x78, 0x34, 0x2c, 0xa2, 0x4b, 0xea, 0x0b, 0xfd,
-       0xe6, 0x6e, 0x89, 0x9a, 0x19, 0xca, 0x3f, 0x3e, 0x04, 0x3d, 0xfc, 0x77,
-       0xca, 0x1e, 0xb4, 0xa8, 0xe3, 0xa1, 0xf0, 0x31, 0xe8, 0x32, 0xab, 0x74,
-       0xdc, 0x83, 0xf1, 0x03, 0x9e, 0xed, 0xf4, 0x48, 0xbe, 0x7a, 0xc3, 0x93,
-       0x43, 0x8f, 0xcc, 0x57, 0xbb, 0xa5, 0x00, 0x1d, 0x16, 0xc4, 0x92, 0xc2,
-       0xf9, 0x3f, 0xf7, 0xda, 0x2d, 0x99, 0x3b, 0xff, 0x32, 0xec, 0xe1, 0xb0,
-       0xb6, 0xbf, 0xfe, 0x0b, 0xcd, 0xb3, 0x1f, 0xd8, 0x5f, 0x50, 0xec, 0x89,
-       0xa0, 0x9c, 0xab, 0xbb, 0xf6, 0x57, 0xc1, 0x1a, 0xb3, 0x4d, 0x1b, 0xb6,
-       0xf4, 0xc6, 0x6a, 0x9f, 0x73, 0xf5, 0x3e, 0x3c, 0x1b, 0x94, 0x23, 0x75,
-       0xf6, 0xcf, 0xc3, 0xc6, 0x82, 0xb2, 0xf4, 0x68, 0xb7, 0x64, 0xd1, 0x5e,
-       0x58, 0x14, 0x3b, 0x19, 0xd7, 0xf1, 0x4c, 0x0f, 0xe6, 0xb2, 0x15, 0x9f,
-       0x2e, 0x99, 0xaa, 0x76, 0xd8, 0x86, 0x15, 0x92, 0xa9, 0x3a, 0xf5, 0x8f,
-       0xef, 0x92, 0x6f, 0x03, 0x94, 0x2f, 0xdb, 0xf9, 0x1c, 0xdb, 0x4d, 0xb4,
-       0xb7, 0xb6, 0xd1, 0xb6, 0x37, 0x53, 0xa6, 0x83, 0x82, 0xb6, 0x5c, 0x29,
-       0x66, 0xee, 0xe7, 0x77, 0x9d, 0xf6, 0xd0, 0x6a, 0x0b, 0x01, 0xf4, 0x87,
-       0x1e, 0xab, 0x18, 0xeb, 0xf4, 0x9d, 0x66, 0xdb, 0x08, 0xae, 0x2d, 0x2c,
-       0xaa, 0x2e, 0x8e, 0x1d, 0x00, 0x5f, 0xba, 0x64, 0xab, 0x8a, 0xb7, 0x08,
-       0x6d, 0xc0, 0x9d, 0x47, 0x9f, 0xcc, 0x2e, 0x76, 0xf7, 0xa4, 0x17, 0xd9,
-       0x9e, 0x0c, 0x1b, 0x98, 0xe7, 0x54, 0x5c, 0x1a, 0x73, 0x71, 0xbd, 0x3f,
-       0x00, 0xbe, 0xa6, 0xb1, 0xe0, 0x30, 0x0f, 0x8f, 0xc7, 0x06, 0xee, 0xf7,
-       0xca, 0xd4, 0x79, 0xf6, 0xe5, 0x18, 0x85, 0x2d, 0xba, 0x24, 0xc0, 0x1b,
-       0x3e, 0x56, 0x14, 0xf7, 0x3b, 0x31, 0x4e, 0x37, 0x6c, 0x27, 0x83, 0x31,
-       0x9b, 0x8f, 0x27, 0xe3, 0xbd, 0x92, 0x5d, 0xed, 0x2b, 0xb0, 0x3b, 0xf6,
-       0x1f, 0x5c, 0xd7, 0x17, 0xf2, 0x3d, 0x0f, 0x9a, 0x8b, 0x9d, 0x90, 0x21,
-       0xdb, 0x75, 0xf0, 0xdc, 0x01, 0x1e, 0x82, 0x98, 0x4f, 0x3f, 0xd6, 0x43,
-       0x07, 0xe8, 0x6f, 0xc2, 0x9c, 0x3a, 0x65, 0xfa, 0x74, 0x2f, 0x74, 0x61,
-       0xa2, 0x6f, 0x50, 0x9e, 0x2f, 0x45, 0x61, 0x03, 0xec, 0x0f, 0x1d, 0x2c,
-       0x46, 0xc3, 0x55, 0xb1, 0x65, 0x2e, 0xde, 0x01, 0xfb, 0x6a, 0x36, 0x67,
-       0x60, 0x1f, 0xdf, 0x51, 0xfe, 0x62, 0xc8, 0x1c, 0xd3, 0x24, 0xdf, 0x91,
-       0x38, 0x0c, 0x7e, 0xa2, 0x4f, 0x89, 0xf0, 0x7a, 0x87, 0xc6, 0x35, 0x0b,
-       0x39, 0x72, 0x6c, 0xf8, 0xa4, 0xad, 0x90, 0x21, 0xfd, 0x56, 0x1f, 0xec,
-       0x39, 0xac, 0xfc, 0xc9, 0xd8, 0x86, 0xfe, 0x24, 0x3a, 0x51, 0xc6, 0x58,
-       0x85, 0xf3, 0x01, 0xfa, 0xb0, 0x51, 0x2c, 0x57, 0x79, 0x00, 0x6b, 0x6f,
-       0x56, 0xd9, 0xc7, 0x09, 0xce, 0xb7, 0xf9, 0xf9, 0x38, 0xf9, 0xe2, 0x7c,
-       0x6d, 0x3c, 0x4b, 0x1b, 0x8c, 0x1e, 0xb6, 0xd5, 0xf8, 0x27, 0xbc, 0xf1,
-       0x5d, 0xde, 0x0b, 0xa5, 0x1e, 0x2d, 0xa5, 0x78, 0xf0, 0xe9, 0x88, 0x2c,
-       0x9f, 0xec, 0x37, 0xf7, 0xc0, 0x86, 0xe9, 0xa7, 0x96, 0x2f, 0x50, 0xc7,
-       0xa0, 0x31, 0x42, 0x1d, 0x9b, 0x8a, 0xbf, 0xe4, 0x22, 0xd7, 0x9e, 0xf4,
-       0x19, 0x42, 0x1f, 0x01, 0x9f, 0x8b, 0xb5, 0x38, 0xeb, 0xad, 0xc5, 0x9c,
-       0x43, 0xfb, 0x7b, 0x06, 0xcf, 0xea, 0x32, 0x16, 0xa3, 0x7f, 0x78, 0x5e,
-       0x52, 0xf0, 0x91, 0xd0, 0xa3, 0x54, 0x31, 0x97, 0x4a, 0xa9, 0xd5, 0x6f,
-       0xc1, 0xb6, 0x86, 0xff, 0xae, 0xe9, 0xfa, 0x43, 0xfa, 0x06, 0xfa, 0x9a,
-       0x82, 0xa9, 0x43, 0x72, 0x3a, 0x9c, 0x21, 0x74, 0x13, 0x4f, 0x1a, 0xd1,
-       0x4c, 0x16, 0x7c, 0x4d, 0x59, 0x4d, 0xb1, 0x1e, 0x13, 0x44, 0x0c, 0xf4,
-       0xa9, 0xcb, 0x4e, 0xdf, 0x3f, 0x2d, 0x3b, 0xbe, 0x2e, 0xa8, 0x57, 0xea,
-       0xc1, 0xf7, 0x11, 0x01, 0xb9, 0x0c, 0xdf, 0x35, 0x57, 0xea, 0x96, 0x06,
-       0x78, 0xba, 0xe2, 0xf8, 0xb6, 0x66, 0x78, 0xb6, 0xc6, 0x67, 0xba, 0xf1,
-       0x7c, 0x00, 0x7e, 0x4d, 0xf2, 0x46, 0x02, 0xbf, 0x8b, 0xa4, 0xc9, 0x36,
-       0xdf, 0xce, 0xb9, 0x66, 0xa2, 0x76, 0x59, 0xda, 0x25, 0x13, 0x43, 0xfc,
-       0x58, 0xd4, 0x31, 0x56, 0x1f, 0x7c, 0x79, 0x40, 0x0e, 0x96, 0x42, 0xf2,
-       0xd5, 0x12, 0xe7, 0x95, 0xd6, 0x52, 0xd0, 0x5b, 0x72, 0xb1, 0x09, 0x9d,
-       0x8f, 0xc3, 0xe7, 0x65, 0xb4, 0x31, 0xf8, 0x9f, 0xdd, 0xd5, 0xaf, 0x68,
-       0xe9, 0xf3, 0x59, 0x6d, 0xbc, 0xbe, 0x5f, 0xcb, 0x9c, 0x9f, 0xd4, 0x76,
-       0xb5, 0xf8, 0x22, 0xd1, 0xde, 0xdd, 0x17, 0x9d, 0x38, 0xcd, 0x31, 0xfb,
-       0xe3, 0x1b, 0xfb, 0xa2, 0x5f, 0x6a, 0xad, 0xbe, 0xa8, 0x1f, 0xbe, 0x28,
-       0x03, 0x5f, 0x34, 0x7e, 0xdf, 0xbe, 0xa8, 0x5d, 0xdf, 0xd8, 0x17, 0x75,
-       0xeb, 0x77, 0x7d, 0x11, 0x63, 0xcf, 0xbf, 0xc6, 0xb5, 0x29, 0xdb, 0x76,
-       0xfa, 0x72, 0x0e, 0xc3, 0x0f, 0x6f, 0x82, 0xac, 0xbb, 0xb8, 0x76, 0x22,
-       0x05, 0xd8, 0xfd, 0x34, 0xc6, 0xfa, 0x4d, 0xd8, 0xfb, 0xb6, 0x98, 0x65,
-       0x3e, 0xa1, 0xc6, 0x7d, 0xa7, 0xce, 0xc7, 0x56, 0x75, 0x4e, 0x1e, 0xdf,
-       0x53, 0xe7, 0xb6, 0xab, 0x73, 0xea, 0xba, 0x53, 0x66, 0xd4, 0xb8, 0x4d,
-       0x09, 0x3c, 0x26, 0xf0, 0x2a, 0xf2, 0x59, 0x23, 0x11, 0x05, 0x3d, 0x1d,
-       0xe3, 0x53, 0x5f, 0x31, 0xf0, 0x20, 0xd0, 0x6f, 0xb7, 0xf2, 0x45, 0xbb,
-       0xa0, 0xf7, 0x65, 0xe7, 0xfe, 0x74, 0x95, 0x69, 0xd1, 0xd5, 0x9e, 0x35,
-       0xba, 0xea, 0x90, 0xe1, 0x98, 0xaf, 0xa3, 0xcd, 0x92, 0x8c, 0x51, 0x67,
-       0xf7, 0xa3, 0xab, 0x7f, 0xaa, 0xff, 0xfd, 0xe8, 0xea, 0xb7, 0xee, 0xa1,
-       0xab, 0x7f, 0xb5, 0x4e, 0x57, 0x96, 0xf9, 0x82, 0x46, 0xda, 0x8c, 0x1f,
-       0xf4, 0x47, 0xcd, 0x8f, 0x4e, 0x31, 0x7f, 0xa8, 0x73, 0x4d, 0xfb, 0x79,
-       0x07, 0xd7, 0xf3, 0xa5, 0xa6, 0x61, 0x59, 0x90, 0x1d, 0xd7, 0x34, 0xe5,
-       0x16, 0x35, 0x3f, 0x4f, 0xfe, 0x11, 0x3b, 0xa6, 0x10, 0x6b, 0x5c, 0x1e,
-       0xda, 0xa5, 0xbc, 0xc5, 0xed, 0x3f, 0x55, 0x6a, 0xfe, 0x42, 0x4f, 0xbc,
-       0xdd, 0x4c, 0x8e, 0x58, 0x5e, 0x1c, 0x08, 0xca, 0xd7, 0xaa, 0xd1, 0xac,
-       0xad, 0x75, 0x4b, 0xfe, 0x41, 0xc4, 0x9e, 0x12, 0xfd, 0xd7, 0xd6, 0x7b,
-       0xc4, 0xe8, 0x3e, 0x2f, 0x46, 0x57, 0xc1, 0x2b, 0xf3, 0xab, 0xef, 0xbe,
-       0xd5, 0x08, 0xf1, 0x3b, 0x66, 0xee, 0x93, 0x2f, 0x73, 0x8e, 0x88, 0xf7,
-       0x8c, 0xfb, 0x16, 0x73, 0x9e, 0x7c, 0x20, 0xd1, 0x25, 0xf9, 0x2d, 0x5c,
-       0x8f, 0xf4, 0x73, 0xf4, 0x5d, 0xed, 0x1e, 0xdf, 0x7e, 0x8e, 0xa4, 0x78,
-       0x33, 0x30, 0x65, 0xf4, 0x41, 0x3e, 0x54, 0xe2, 0x3c, 0xde, 0xf2, 0xec,
-       0x89, 0xb9, 0x82, 0xb4, 0xb9, 0xbe, 0x61, 0x2f, 0x72, 0x01, 0xda, 0x81,
-       0xaf, 0x73, 0xea, 0x9b, 0x39, 0x82, 0x44, 0x74, 0x8b, 0x39, 0x82, 0x98,
-       0x46, 0x62, 0x9f, 0x66, 0x43, 0xf7, 0x36, 0x74, 0x6f, 0x43, 0xf7, 0x36,
-       0x74, 0x9f, 0xac, 0x1f, 0xc6, 0x3d, 0x95, 0x87, 0x80, 0x17, 0x97, 0x7e,
-       0xda, 0xa5, 0x0f, 0x3e, 0xb7, 0x4a, 0x4e, 0xe9, 0x84, 0xf3, 0x45, 0xae,
-       0xa1, 0xfc, 0xf5, 0xb8, 0xe6, 0xfa, 0x6b, 0xd2, 0xcb, 0xe0, 0xf9, 0xdb,
-       0x98, 0xa7, 0xad, 0xeb, 0xd6, 0x5d, 0x99, 0xcc, 0xb5, 0xc8, 0x64, 0xd6,
-       0xa1, 0x8c, 0xd8, 0x9f, 0x3e, 0x77, 0x5a, 0xaf, 0xac, 0xca, 0x65, 0x2f,
-       0x78, 0xe8, 0xe0, 0xdc, 0xbd, 0x79, 0x90, 0x7e, 0xaf, 0x47, 0xff, 0x6f,
-       0xd1, 0x87, 0xfe, 0x75, 0xa3, 0x71, 0x39, 0x26, 0x73, 0xc6, 0x77, 0x9b,
-       0x0f, 0x72, 0x66, 0xac, 0x81, 0xef, 0x21, 0x96, 0x5f, 0x44, 0x2c, 0x59,
-       0x31, 0x22, 0xf2, 0x93, 0x47, 0xaf, 0x21, 0x97, 0x96, 0xfc, 0xc3, 0x89,
-       0x66, 0x24, 0x90, 0x78, 0xab, 0x39, 0x37, 0x82, 0x18, 0x97, 0x88, 0x86,
-       0x93, 0xc6, 0xb0, 0x5c, 0xaa, 0x0f, 0xca, 0x8f, 0xea, 0x96, 0xfc, 0xb0,
-       0x1e, 0x91, 0x1f, 0x20, 0xe6, 0x7f, 0xbf, 0xde, 0x9a, 0x73, 0x47, 0x68,
-       0x4f, 0x3d, 0xe9, 0xfa, 0x46, 0xb9, 0x7f, 0x13, 0x34, 0xde, 0x82, 0x9d,
-       0x04, 0xb2, 0xc8, 0xf5, 0x19, 0xbf, 0x26, 0x0e, 0x15, 0x9f, 0x6b, 0x82,
-       0xb7, 0x6c, 0x5b, 0xc2, 0xca, 0xeb, 0x7a, 0xf7, 0xa8, 0xf9, 0x29, 0xb4,
-       0x39, 0xa3, 0x81, 0x6a, 0xb1, 0x53, 0xe5, 0x8b, 0xd0, 0x91, 0xd8, 0xf5,
-       0x60, 0xb0, 0x56, 0xbc, 0x85, 0x7e, 0xcd, 0xe6, 0xa1, 0xf8, 0x6f, 0xed,
-       0x30, 0xff, 0x81, 0x85, 0x35, 0xdd, 0xf9, 0x25, 0x23, 0xb1, 0x49, 0x66,
-       0x43, 0xdf, 0x6f, 0x98, 0x03, 0x7d, 0x59, 0x3d, 0x11, 0x94, 0x74, 0x91,
-       0x6b, 0x2a, 0x24, 0xb3, 0x55, 0x28, 0xff, 0x3c, 0xd7, 0x85, 0x3c, 0x3b,
-       0x17, 0xef, 0x86, 0xed, 0xff, 0x9a, 0xe1, 0xae, 0x03, 0x18, 0x50, 0x75,
-       0x50, 0xf2, 0xe0, 0x37, 0x5f, 0x7f, 0xcb, 0xc3, 0x0e, 0xf0, 0x2a, 0x5b,
-       0x21, 0xf8, 0xc4, 0x70, 0xda, 0x76, 0xfe, 0x30, 0x88, 0xb6, 0xe0, 0x56,
-       0xeb, 0xce, 0x26, 0x7c, 0x3f, 0x10, 0xb2, 0x88, 0x4d, 0x24, 0xf3, 0x05,
-       0x7c, 0xff, 0x4a, 0x42, 0x36, 0xf7, 0xe2, 0x7b, 0x4b, 0x02, 0x26, 0x99,
-       0x60, 0xcc, 0xd5, 0x5a, 0x62, 0xae, 0x68, 0x69, 0xc8, 0x6e, 0x0e, 0x73,
-       0x4f, 0x43, 0x9e, 0x5f, 0xac, 0x07, 0xb5, 0xd4, 0xe9, 0x47, 0xc0, 0x87,
-       0x9f, 0x3b, 0x23, 0x3f, 0x33, 0x97, 0xb7, 0x04, 0xe4, 0x16, 0x7c, 0x5c,
-       0x12, 0x7e, 0xcc, 0x46, 0x6e, 0xb1, 0x03, 0xcb, 0x35, 0xfa, 0x5f, 0xbf,
-       0x20, 0x5f, 0xf3, 0x78, 0x6b, 0x93, 0x05, 0x65, 0xa3, 0x6c, 0xcf, 0x67,
-       0xfe, 0xcd, 0xc0, 0xdd, 0xf6, 0x17, 0x57, 0xdb, 0xcb, 0x99, 0x7f, 0xb8,
-       0xda, 0xde, 0xdb, 0xe6, 0xf2, 0x3f, 0xaa, 0x4d, 0xd4, 0xf7, 0x78, 0x6d,
-       0xb7, 0xa1, 0xb3, 0x66, 0x93, 0xb9, 0x45, 0x01, 0xd8, 0x24, 0x1d, 0xa7,
-       0x2f, 0xbe, 0x1f, 0x5f, 0xbb, 0xc6, 0xcf, 0x9a, 0x49, 0x83, 0xb6, 0x10,
-       0x14, 0x97, 0x26, 0xef, 0x77, 0x20, 0x7f, 0xbf, 0x8d, 0xdf, 0x8c, 0xa3,
-       0x7e, 0x6e, 0xce, 0x3e, 0x7c, 0xfe, 0xcd, 0x7b, 0xd8, 0x4b, 0x08, 0xf6,
-       0xf2, 0xff, 0xab, 0x5d, 0x5c, 0xba, 0x1f, 0xbb, 0xc0, 0x9f, 0xb2, 0x0b,
-       0xd5, 0xff, 0xd2, 0xea, 0x5a, 0x09, 0x43, 0x3e, 0x8c, 0x07, 0x83, 0xd0,
-       0xf1, 0x66, 0x99, 0xb5, 0xc8, 0x8f, 0x15, 0xc9, 0xc1, 0x5f, 0x9e, 0x58,
-       0x17, 0xbb, 0xbb, 0x10, 0x0f, 0x8e, 0x9f, 0x8e, 0x8e, 0x32, 0x1e, 0xc4,
-       0xe0, 0x1b, 0x93, 0xef, 0x88, 0x07, 0x37, 0x8c, 0xd6, 0x78, 0x60, 0x20,
-       0x1e, 0xec, 0x7a, 0x97, 0x78, 0x70, 0xe2, 0x1d, 0xf1, 0x40, 0x83, 0x6c,
-       0x38, 0xbf, 0xbf, 0x35, 0xfc, 0x78, 0x50, 0x58, 0x13, 0x0f, 0x7c, 0x5d,
-       0x59, 0x0a, 0x0b, 0xdc, 0xd5, 0x5b, 0x97, 0xa7, 0x2b, 0x09, 0x06, 0x12,
-       0x8d, 0xcc, 0x9c, 0xf5, 0xb0, 0xb4, 0xc1, 0xe7, 0x5e, 0xaa, 0x8f, 0x40,
-       0x67, 0x97, 0x30, 0xf7, 0x68, 0x9c, 0x89, 0x65, 0x5b, 0x82, 0xeb, 0xe1,
-       0xcd, 0x08, 0x30, 0xe2, 0x6e, 0xe0, 0xbe, 0xdd, 0x67, 0xd5, 0xfa, 0x78,
-       0x33, 0xea, 0x61, 0xf7, 0x6d, 0xc0, 0xee, 0x78, 0x3e, 0x00, 0x4c, 0xc8,
-       0xf6, 0x2b, 0x66, 0x12, 0x7a, 0xaa, 0x3a, 0xf6, 0xee, 0x02, 0x3e, 0x73,
-       0xaa, 0xef, 0xad, 0x08, 0xfb, 0x76, 0x24, 0x12, 0xd1, 0x3f, 0xc3, 0x77,
-       0x7b, 0x22, 0xbc, 0xed, 0xaa, 0x45, 0xba, 0x87, 0xa2, 0x67, 0x15, 0x8d,
-       0x80, 0x14, 0xd4, 0xb3, 0x91, 0x6d, 0x7c, 0xf6, 0x18, 0x62, 0xf6, 0x51,
-       0xc7, 0x94, 0x23, 0x4e, 0x76, 0x77, 0x0e, 0x1f, 0x62, 0xd5, 0x4b, 0x25,
-       0xde, 0x1f, 0xc5, 0xfd, 0x80, 0x30, 0x97, 0xfc, 0x2a, 0xfa, 0x1c, 0x44,
-       0x9f, 0x19, 0xc7, 0xd7, 0x05, 0xef, 0x37, 0x32, 0x29, 0xdc, 0x9f, 0x29,
-       0x36, 0x32, 0xe9, 0x22, 0xf3, 0xd6, 0xa1, 0xf0, 0x11, 0xc8, 0x33, 0x8b,
-       0x5c, 0xcd, 0x96, 0xe8, 0x60, 0x5e, 0x9e, 0xee, 0x1c, 0x07, 0x4e, 0x3a,
-       0x87, 0x1c, 0xc2, 0x9e, 0x8c, 0xc6, 0xcb, 0xf2, 0xe1, 0xce, 0xe4, 0x69,
-       0xe4, 0x0b, 0xf1, 0xed, 0x90, 0x61, 0x23, 0xa3, 0xc7, 0x04, 0xb6, 0x1e,
-       0x87, 0x5f, 0x1e, 0xd1, 0x53, 0xc5, 0x7e, 0x73, 0x56, 0x1e, 0x95, 0x86,
-       0x19, 0x0d, 0x8f, 0xcb, 0x26, 0x49, 0x05, 0xd0, 0x6f, 0xf0, 0x43, 0x92,
-       0x0d, 0x53, 0xd6, 0x0f, 0xc2, 0xdf, 0x6b, 0xd2, 0x61, 0xb5, 0xc6, 0x9e,
-       0x5b, 0x10, 0x6f, 0x2e, 0x40, 0x9f, 0xdd, 0x61, 0x75, 0x7a, 0x3a, 0xd9,
-       0x24, 0xcb, 0xef, 0xe8, 0x77, 0xbb, 0xa5, 0x5f, 0x6b, 0xfb, 0xdb, 0x68,
-       0xdf, 0x84, 0x9c, 0xb3, 0x91, 0x09, 0xc4, 0x20, 0x7f, 0xcc, 0xa1, 0x0d,
-       0x76, 0x72, 0x15, 0xf3, 0x61, 0x1c, 0x2c, 0x94, 0x99, 0xf7, 0x18, 0x52,
-       0x36, 0x71, 0xcf, 0x69, 0x36, 0x2b, 0x16, 0xf8, 0xbd, 0x40, 0x9e, 0x83,
-       0x32, 0xee, 0x0c, 0x88, 0x5d, 0xa3, 0x1c, 0xa2, 0xf0, 0x4a, 0x0f, 0x77,
-       0xa5, 0x16, 0xa3, 0x76, 0x1e, 0x14, 0x8d, 0x0b, 0x7d, 0x5d, 0x49, 0xe4,
-       0x39, 0xfa, 0x85, 0x48, 0x57, 0x0a, 0x36, 0x6b, 0x5c, 0x78, 0xa8, 0x2b,
-       0x7d, 0x9a, 0x7c, 0x19, 0xc8, 0x73, 0x3e, 0x0a, 0x9c, 0xdf, 0x94, 0xdf,
-       0x45, 0x2e, 0x5b, 0x18, 0x44, 0x0e, 0x80, 0xd5, 0xaf, 0x83, 0xef, 0xbc,
-       0x29, 0xc1, 0xae, 0xc4, 0xab, 0xe0, 0x6f, 0x18, 0xb2, 0xd9, 0x84, 0x3e,
-       0x06, 0xda, 0x07, 0x58, 0x13, 0x68, 0x69, 0xb7, 0xba, 0x10, 0x4f, 0x11,
-       0xbb, 0x24, 0x98, 0x1c, 0xe9, 0x06, 0xfd, 0x2b, 0x01, 0xe6, 0x82, 0xc1,
-       0xd8, 0x6a, 0xfb, 0x37, 0xdd, 0xf6, 0x41, 0xf0, 0xc2, 0xe7, 0x88, 0x09,
-       0x24, 0x38, 0x35, 0x62, 0x82, 0x07, 0xf6, 0x0d, 0xa9, 0xbe, 0xe9, 0x45,
-       0xda, 0x40, 0x23, 0x53, 0xb1, 0x1e, 0x91, 0xd4, 0xc2, 0x56, 0x19, 0x5f,
-       0xe8, 0x95, 0x5d, 0x0b, 0xc4, 0x30, 0xac, 0x69, 0x60, 0x2a, 0xc0, 0x18,
-       0xfa, 0x05, 0xe6, 0x76, 0xd1, 0xf0, 0x41, 0xe9, 0x0f, 0x7f, 0x15, 0xeb,
-       0x60, 0xca, 0x8a, 0x45, 0x66, 0xb1, 0xc6, 0x02, 0x8a, 0x4e, 0xd8, 0x1f,
-       0x93, 0x36, 0xba, 0x66, 0xdc, 0xf4, 0xe2, 0xbd, 0xe8, 0x62, 0xe1, 0x5c,
-       0x08, 0xaf, 0xa3, 0xfb, 0x57, 0x1e, 0x5d, 0x13, 0x74, 0xfb, 0x40, 0x93,
-       0x73, 0x7c, 0xa8, 0x73, 0xec, 0xb4, 0xd8, 0x1d, 0xe0, 0x2f, 0x1d, 0x7b,
-       0x58, 0x66, 0x41, 0xe7, 0xe8, 0x02, 0xfd, 0xa4, 0x6c, 0xc5, 0x67, 0xb8,
-       0x4d, 0x62, 0x83, 0xe7, 0x81, 0x73, 0xc6, 0x14, 0x0d, 0x17, 0x73, 0xe8,
-       0x17, 0x12, 0xc0, 0xa9, 0x1f, 0x07, 0x3f, 0xcc, 0xb1, 0x38, 0xe7, 0x00,
-       0xe6, 0x9b, 0xc0, 0x3a, 0x64, 0x7d, 0x85, 0xeb, 0x1b, 0xbf, 0xcf, 0x87,
-       0x3b, 0x53, 0xa7, 0xdb, 0xb1, 0xee, 0xe4, 0x11, 0x43, 0xc5, 0x7e, 0xea,
-       0xc5, 0xea, 0x4c, 0x96, 0x14, 0xdf, 0x9d, 0xa9, 0x12, 0x65, 0x14, 0xef,
-       0x4c, 0x97, 0x28, 0x23, 0x01, 0x3f, 0x71, 0xd8, 0x64, 0x40, 0x22, 0x5b,
-       0xa8, 0xc7, 0x43, 0xe8, 0xf7, 0x57, 0x01, 0xe2, 0xb8, 0xa4, 0xc5, 0xdf,
-       0xf0, 0xb5, 0x17, 0x0e, 0xa3, 0x2f, 0x7f, 0x6f, 0x07, 0xdd, 0xfe, 0xc1,
-       0x82, 0xb4, 0x0f, 0xce, 0xc0, 0x4f, 0xe8, 0x23, 0xc0, 0x91, 0xca, 0xce,
-       0x9b, 0xc0, 0xd8, 0x3b, 0x30, 0x1f, 0xac, 0x8d, 0x98, 0x25, 0xd3, 0xf3,
-       0x94, 0xab, 0x7c, 0x08, 0x73, 0xc0, 0xfc, 0x63, 0xf0, 0x2d, 0x9c, 0x03,
-       0xc7, 0x16, 0xe4, 0x36, 0x4b, 0x92, 0x9b, 0x0f, 0x2a, 0x2c, 0x6b, 0x9b,
-       0x1c, 0x5f, 0xd3, 0xf4, 0x44, 0x17, 0x74, 0xcc, 0xb9, 0xcd, 0x81, 0xb7,
-       0x67, 0x10, 0xff, 0xa2, 0x0a, 0x43, 0x19, 0x17, 0xb8, 0x56, 0x46, 0xb1,
-       0x4e, 0xc8, 0xbf, 0x67, 0x7b, 0x5a, 0x03, 0x3e, 0x45, 0xf9, 0x7f, 0xe4,
-       0xea, 0x09, 0xf8, 0x91, 0x51, 0xf9, 0x7d, 0xf8, 0x92, 0x1f, 0xd7, 0xe3,
-       0xc8, 0x1b, 0x86, 0x91, 0x37, 0x0c, 0x22, 0x6f, 0xb0, 0x90, 0x37, 0x44,
-       0x90, 0x37, 0xf4, 0x21, 0x6f, 0x08, 0x23, 0x3e, 0x88, 0x1c, 0xad, 0xe7,
-       0x61, 0x63, 0x0d, 0xf8, 0x41, 0x33, 0x68, 0xd7, 0x43, 0xc1, 0x64, 0x3d,
-       0x1c, 0x4c, 0xd5, 0x03, 0x98, 0xd3, 0x01, 0x8e, 0x89, 0xf9, 0xe5, 0x3b,
-       0xc7, 0x4a, 0xc3, 0x88, 0x39, 0x36, 0xfc, 0x52, 0x1a, 0xf1, 0x36, 0x2e,
-       0x47, 0xf0, 0xcc, 0xf2, 0x7c, 0x04, 0xcf, 0x34, 0x25, 0x1d, 0x6f, 0x93,
-       0x59, 0x33, 0x0e, 0x1a, 0x5b, 0x94, 0x9d, 0x22, 0xdf, 0x6a, 0x83, 0x9d,
-       0x4a, 0xae, 0xc8, 0x7c, 0xab, 0x0f, 0xf4, 0x3a, 0x11, 0x97, 0xe9, 0x1f,
-       0xe8, 0x0b, 0xec, 0xdd, 0x5f, 0xb2, 0xb8, 0xe6, 0xba, 0xb4, 0xe4, 0xe9,
-       0xbc, 0x10, 0x6b, 0x22, 0x0e, 0xc2, 0x2e, 0xd8, 0x36, 0x81, 0xe7, 0xf8,
-       0xfb, 0x6d, 0xcf, 0xef, 0x7f, 0x24, 0x28, 0x30, 0xde, 0x4b, 0x8c, 0xf9,
-       0x16, 0xe8, 0x39, 0xad, 0xeb, 0xb5, 0xa6, 0x8b, 0xe5, 0xdf, 0x67, 0xfd,
-       0x8d, 0x35, 0xc7, 0xd7, 0xc0, 0x73, 0xbf, 0xb9, 0x8c, 0x1c, 0xd9, 0xde,
-       0xbf, 0x82, 0xdf, 0xad, 0xfd, 0xeb, 0xe8, 0xaf, 0xda, 0x82, 0x66, 0x22,
-       0xce, 0x7c, 0x18, 0x3e, 0x73, 0x10, 0xfe, 0xf1, 0x56, 0x46, 0x5f, 0xba,
-       0x89, 0x79, 0x42, 0x9e, 0xc5, 0x5b, 0x99, 0xc0, 0xc0, 0xb5, 0xe6, 0x8b,
-       0xc0, 0x37, 0x63, 0x4b, 0x23, 0x92, 0x5a, 0xea, 0x0f, 0x5f, 0x96, 0xce,
-       0xdb, 0xb6, 0x5c, 0x6b, 0xce, 0x3a, 0xd1, 0xe3, 0xb6, 0x10, 0x6f, 0x99,
-       0x52, 0x01, 0xa9, 0x6d, 0x3b, 0x3b, 0x88, 0x19, 0x2f, 0x8a, 0x1e, 0x91,
-       0xe4, 0x29, 0x5b, 0x46, 0x76, 0xfa, 0xb9, 0xfb, 0x9d, 0x0e, 0xe9, 0x42,
-       0xdb, 0x52, 0x04, 0x7d, 0x88, 0x53, 0x39, 0xef, 0x2c, 0xe6, 0xac, 0xb9,
-       0xcf, 0x78, 0xf5, 0xc9, 0x42, 0x09, 0x73, 0xaf, 0xdf, 0xca, 0x5c, 0x3e,
-       0x05, 0xec, 0x0e, 0x1d, 0x25, 0x4f, 0xb1, 0xae, 0xb0, 0x09, 0x72, 0x1a,
-       0x83, 0xad, 0xd0, 0x06, 0xfa, 0xf1, 0x6c, 0x53, 0xbe, 0x11, 0xa7, 0x5d,
-       0xbc, 0x04, 0x59, 0x82, 0x56, 0xc0, 0x9f, 0x0f, 0x70, 0xde, 0x3c, 0xe5,
-       0x17, 0x46, 0x6e, 0xce, 0xb1, 0x25, 0xd8, 0x99, 0x58, 0x9f, 0x77, 0xdf,
-       0xca, 0x2c, 0x9f, 0x02, 0xfd, 0x01, 0xd6, 0xde, 0xe0, 0xb3, 0x8b, 0xac,
-       0x1d, 0x32, 0x27, 0xdd, 0x05, 0x3d, 0xed, 0x55, 0xb5, 0xb8, 0x64, 0x35,
-       0x2e, 0xd6, 0x49, 0xfa, 0x2c, 0x89, 0x18, 0xd6, 0x7e, 0xe4, 0xaf, 0x62,
-       0xea, 0x89, 0x49, 0xdc, 0xa3, 0x3c, 0x35, 0xe4, 0x1c, 0xb8, 0x7f, 0x61,
-       0x45, 0xe9, 0xc4, 0x80, 0xee, 0x72, 0x3b, 0x99, 0x84, 0xc9, 0xbc, 0x91,
-       0x80, 0x2f, 0x1c, 0xe1, 0x1c, 0xd4, 0xd8, 0xc8, 0xc7, 0xb9, 0xfe, 0x30,
-       0x67, 0xd8, 0x55, 0x4b, 0x5e, 0xae, 0xfe, 0x66, 0x4b, 0x47, 0x60, 0xd3,
-       0x92, 0x6f, 0x43, 0x3e, 0x90, 0x1c, 0xc1, 0x6f, 0x38, 0x81, 0xa3, 0xd0,
-       0xe7, 0xd9, 0x11, 0xd6, 0x3f, 0x5f, 0x02, 0xb6, 0x27, 0xdf, 0xb1, 0xc8,
-       0x11, 0xb5, 0x86, 0x71, 0xed, 0x30, 0x97, 0xdb, 0x24, 0x97, 0xd5, 0xfc,
-       0x1e, 0x22, 0xf6, 0x80, 0x9e, 0xee, 0x67, 0x7e, 0xe3, 0xf7, 0x39, 0x3f,
-       0x97, 0x3e, 0x63, 0x57, 0xd2, 0x8a, 0x48, 0xaa, 0x78, 0xa9, 0x19, 0xb0,
-       0x2c, 0x60, 0x67, 0x57, 0x8f, 0x29, 0x27, 0x08, 0x3e, 0x58, 0x6b, 0xdb,
-       0xa9, 0x74, 0x09, 0x3e, 0x68, 0x3b, 0xf9, 0x60, 0x62, 0xb3, 0x9c, 0x9b,
-       0xef, 0x91, 0xca, 0xfc, 0xcf, 0xa5, 0x3a, 0xdf, 0x25, 0xe7, 0xe7, 0x9b,
-       0x72, 0x35, 0xae, 0x7c, 0x93, 0xd5, 0xae, 0xd6, 0xb5, 0x3c, 0xec, 0xd6,
-       0x61, 0x62, 0xa3, 0xd7, 0xe5, 0x79, 0x39, 0x57, 0x76, 0x79, 0xcf, 0xb4,
-       0xf0, 0x7e, 0x15, 0xb6, 0xf6, 0xaa, 0x45, 0xfe, 0x47, 0xa4, 0x52, 0x24,
-       0xef, 0xfb, 0x14, 0xef, 0xbb, 0x56, 0x79, 0x97, 0xac, 0x61, 0x91, 0xff,
-       0x8d, 0x78, 0xef, 0x90, 0xec, 0x56, 0xf2, 0x1f, 0xc1, 0xb3, 0xef, 0xb4,
-       0xbf, 0x8a, 0x73, 0xad, 0xb9, 0x5c, 0x6c, 0x53, 0x3c, 0x1b, 0x89, 0x11,
-       0xc8, 0xe7, 0x5a, 0xb3, 0xe1, 0x70, 0x1d, 0xe1, 0xb7, 0xf3, 0x2f, 0xe0,
-       0xab, 0x7a, 0x55, 0xce, 0x92, 0x9b, 0xec, 0xee, 0x4c, 0x2e, 0x8e, 0x42,
-       0xb7, 0x9d, 0x6a, 0x1d, 0xc2, 0x6d, 0x40, 0x67, 0xff, 0x1e, 0xfd, 0xbf,
-       0xcd, 0xf5, 0xa6, 0xe4, 0x92, 0x86, 0x5c, 0x0a, 0xc5, 0xf1, 0x76, 0xe0,
-       0x27, 0x8c, 0xd3, 0xc8, 0x64, 0x1d, 0x3e, 0xd3, 0x07, 0xdf, 0xc6, 0xef,
-       0xf7, 0x6d, 0x0f, 0x79, 0xf8, 0x5c, 0xe8, 0x1c, 0x79, 0x05, 0xd7, 0xf3,
-       0x48, 0x03, 0x31, 0x36, 0x36, 0x58, 0x51, 0xfb, 0x10, 0x71, 0x85, 0x85,
-       0x67, 0x9d, 0x6f, 0xe3, 0xe3, 0x8e, 0x37, 0x56, 0xe7, 0x98, 0x6b, 0xe7,
-       0x54, 0x70, 0x1a, 0xc8, 0xdf, 0x2d, 0xd0, 0xe5, 0xb8, 0x79, 0x31, 0x12,
-       0x06, 0xc6, 0x65, 0x5b, 0x37, 0x7c, 0x4c, 0x04, 0x3e, 0x6b, 0x18, 0xbe,
-       0x9f, 0x6b, 0x99, 0x7e, 0xde, 0xe7, 0x7d, 0x18, 0x34, 0xe9, 0x7f, 0x87,
-       0x31, 0x67, 0xe6, 0xd8, 0xf4, 0x9f, 0x88, 0x27, 0xb5, 0x70, 0x57, 0xf2,
-       0xb4, 0x5b, 0x1b, 0x74, 0x7f, 0xf3, 0xbe, 0x04, 0x1f, 0x49, 0x44, 0xcb,
-       0x79, 0xe4, 0x7e, 0x29, 0xac, 0xd1, 0xa4, 0x85, 0x3c, 0xbb, 0x16, 0x7d,
-       0x85, 0x98, 0x5b, 0xa7, 0x0c, 0x96, 0x28, 0x27, 0xd6, 0xa9, 0x4c, 0xc9,
-       0x57, 0xbe, 0x0b, 0x79, 0x04, 0x65, 0x8b, 0x95, 0x85, 0x4f, 0x01, 0xff,
-       0x98, 0xfb, 0x5c, 0x89, 0xb5, 0xc8, 0x7e, 0xc4, 0x31, 0x03, 0x42, 0x40,
-       0x4e, 0xb5, 0x64, 0xc8, 0x67, 0x03, 0x43, 0xc8, 0x01, 0x9f, 0x45, 0xdf,
-       0x80, 0xe4, 0x97, 0x18, 0x0f, 0x02, 0x32, 0xb7, 0x24, 0x72, 0xfd, 0x14,
-       0xfd, 0x8a, 0xfa, 0x83, 0xcc, 0x1b, 0x99, 0x69, 0x62, 0xed, 0x79, 0xfa,
-       0x18, 0xfa, 0x89, 0x07, 0xa1, 0x8b, 0xd8, 0x4b, 0xdf, 0x40, 0x6c, 0x9a,
-       0x2d, 0xf6, 0xc3, 0x67, 0x4a, 0x43, 0x87, 0x4c, 0x11, 0xd3, 0x98, 0xa3,
-       0x6f, 0x50, 0x77, 0xf4, 0x6b, 0x8e, 0x41, 0x29, 0x9c, 0x62, 0xbd, 0x31,
-       0x08, 0x5e, 0x98, 0xb7, 0x1a, 0x2a, 0x0f, 0x7a, 0x50, 0xf9, 0x56, 0x7e,
-       0x07, 0x5a, 0xc6, 0x8d, 0x1d, 0xdf, 0xa6, 0xd3, 0x8f, 0x3d, 0x22, 0xf6,
-       0xc4, 0xa1, 0xce, 0x5d, 0xa5, 0x76, 0x29, 0xf7, 0xd2, 0x2e, 0xa9, 0xff,
-       0xac, 0x4e, 0x5f, 0x8b, 0x3c, 0x0c, 0xf4, 0x58, 0x23, 0x08, 0xa0, 0x5f,
-       0xc8, 0xeb, 0x47, 0xb9, 0xfe, 0xb6, 0x4c, 0xed, 0xfc, 0x3b, 0xf0, 0xe5,
-       0xfa, 0xb5, 0xdc, 0x4e, 0xf8, 0xdb, 0x09, 0x5d, 0x1e, 0xfb, 0x54, 0x1a,
-       0xcf, 0x32, 0x16, 0xde, 0xf2, 0xf0, 0x38, 0xdb, 0x58, 0xa3, 0x45, 0x9e,
-       0x7e, 0xce, 0xc4, 0x77, 0xaf, 0xe4, 0xcf, 0x05, 0x21, 0x07, 0xe4, 0xc4,
-       0x15, 0x97, 0x16, 0xf3, 0xde, 0xe3, 0xd0, 0x91, 0x7e, 0x32, 0x28, 0x6d,
-       0x27, 0x7b, 0x25, 0xf0, 0xad, 0x2e, 0x69, 0xff, 0xd6, 0x80, 0x18, 0xdf,
-       0x62, 0x2d, 0x29, 0x1a, 0x39, 0xaa, 0xea, 0x58, 0x69, 0x39, 0x86, 0xf8,
-       0xa5, 0x23, 0x16, 0x2b, 0x3b, 0x35, 0xb7, 0x8a, 0x81, 0xc4, 0x55, 0x7f,
-       0xc1, 0x96, 0xaf, 0xef, 0xfc, 0x85, 0xaa, 0xa3, 0x26, 0x47, 0x70, 0xfd,
-       0x72, 0x06, 0xd8, 0x44, 0x83, 0xad, 0x34, 0x32, 0xd7, 0x1e, 0xf5, 0x73,
-       0xcb, 0x41, 0x55, 0x93, 0xff, 0xfa, 0x4e, 0x37, 0xb7, 0x9c, 0x45, 0x6e,
-       0x99, 0x56, 0xb9, 0x25, 0xfc, 0x6b, 0x80, 0xfd, 0xb6, 0x8a, 0x8e, 0xb1,
-       0x72, 0xc2, 0x5c, 0xfd, 0xa3, 0x62, 0x1f, 0xc0, 0xba, 0x38, 0x23, 0xf3,
-       0x7a, 0x42, 0x53, 0x34, 0x8d, 0x17, 0xe8, 0xa7, 0xe8, 0xbf, 0x68, 0xe3,
-       0xac, 0x69, 0xa1, 0xed, 0x65, 0xfa, 0x28, 0xd7, 0xb6, 0xc7, 0x5a, 0x7c,
-       0xdd, 0x5c, 0xa9, 0x0e, 0x1d, 0x22, 0xa7, 0xb7, 0xda, 0x30, 0x7f, 0xc4,
-       0x74, 0x8b, 0xd7, 0x9c, 0x3f, 0x7c, 0x67, 0x28, 0xa4, 0xae, 0x0b, 0x65,
-       0xb7, 0x86, 0xe1, 0xd2, 0x67, 0xfe, 0x01, 0x1f, 0x53, 0x27, 0x1f, 0x1c,
-       0xb7, 0x4f, 0x8c, 0x33, 0x21, 0x09, 0x9c, 0xa1, 0xfd, 0x45, 0x23, 0x69,
-       0xc8, 0x6f, 0xce, 0x22, 0x06, 0x3c, 0x04, 0x6c, 0xf4, 0x88, 0xe8, 0xe7,
-       0x06, 0xb1, 0x76, 0xa2, 0xe1, 0xb2, 0xc4, 0xc4, 0xa8, 0x04, 0xe5, 0x8d,
-       0x53, 0xd1, 0x08, 0xed, 0xe5, 0x2c, 0xe2, 0xd5, 0x91, 0x7a, 0xe7, 0xed,
-       0x86, 0xe2, 0x82, 0x6d, 0xdf, 0x08, 0x00, 0x3b, 0x0c, 0xda, 0x7a, 0xb7,
-       0xdc, 0x80, 0xbe, 0xb3, 0xaa, 0xed, 0x11, 0xd0, 0x05, 0x0f, 0x67, 0x58,
-       0x1b, 0x24, 0xdd, 0xa3, 0xa0, 0x49, 0xda, 0x8d, 0xcc, 0x32, 0x73, 0xd3,
-       0x53, 0xb4, 0xdd, 0x5e, 0xd8, 0x1d, 0xae, 0xeb, 0xed, 0x92, 0x9d, 0x8c,
-       0x88, 0x7e, 0x6a, 0x8f, 0xf4, 0xef, 0xd4, 0xdd, 0xf9, 0xa8, 0x39, 0xb2,
-       0x8d, 0x35, 0xe7, 0x11, 0xb5, 0x1e, 0xf5, 0x25, 0xd8, 0xcc, 0x3e, 0xea,
-       0x18, 0xb1, 0x1f, 0x71, 0x8c, 0x7e, 0xcc, 0x40, 0x1c, 0x4b, 0xd5, 0x5d,
-       0xbd, 0x97, 0xf7, 0x6d, 0x95, 0x63, 0x67, 0x68, 0x4f, 0xb8, 0xb7, 0x6a,
-       0x53, 0xfe, 0xde, 0x10, 0xef, 0x59, 0x72, 0xfc, 0x45, 0xe6, 0x1e, 0xcc,
-       0x39, 0x98, 0x67, 0x45, 0xc3, 0xbb, 0x30, 0x1f, 0xfd, 0x31, 0xfa, 0x03,
-       0x5d, 0xd9, 0x6e, 0x0e, 0x3e, 0xba, 0x50, 0xa7, 0xde, 0x86, 0xb9, 0x7f,
-       0x66, 0x32, 0x5f, 0xb3, 0xc3, 0xae, 0xbc, 0x0b, 0x68, 0x9b, 0x85, 0xef,
-       0x4f, 0x39, 0x6d, 0xb2, 0x32, 0x69, 0x43, 0xf7, 0x5f, 0x02, 0x5f, 0x07,
-       0x3a, 0x59, 0x23, 0x58, 0x99, 0x4c, 0xe3, 0xfa, 0x80, 0xca, 0xd1, 0x8c,
-       0xc7, 0x6c, 0xd0, 0xd8, 0xca, 0x75, 0xe4, 0xe9, 0x29, 0xae, 0x17, 0xe6,
-       0x1f, 0xd3, 0x67, 0xe1, 0xb3, 0xc7, 0xe3, 0x8c, 0xf1, 0xdc, 0x4b, 0xe8,
-       0x00, 0x1f, 0xdd, 0x0a, 0x57, 0xe8, 0xd6, 0x4e, 0xbd, 0x50, 0xa6, 0x9f,
-       0xcf, 0x87, 0xdb, 0x85, 0x78, 0xc4, 0xd4, 0x2b, 0x16, 0x75, 0xa2, 0xc9,
-       0x65, 0xb5, 0xef, 0x20, 0x92, 0x76, 0x0e, 0x61, 0xac, 0xb8, 0x5e, 0x2d,
-       0xef, 0xd4, 0xf3, 0x65, 0x43, 0x56, 0x42, 0xe4, 0x3b, 0xa2, 0xf2, 0xf8,
-       0x9d, 0xca, 0xd6, 0x8a, 0x88, 0x25, 0xb0, 0x99, 0xf8, 0x87, 0x31, 0xae,
-       0x6a, 0x83, 0x4d, 0x51, 0xf7, 0xd4, 0xbb, 0xf2, 0x91, 0x9e, 0xee, 0x37,
-       0x8a, 0x99, 0x45, 0xf8, 0x5f, 0xd6, 0x2f, 0x3a, 0xbc, 0x5a, 0xe3, 0x4b,
-       0x5e, 0x3e, 0xf4, 0x8c, 0x30, 0x4f, 0x99, 0x2b, 0x91, 0x97, 0x22, 0xfc,
-       0xe1, 0x46, 0xb6, 0x44, 0x39, 0xba, 0x3e, 0xe5, 0x10, 0xec, 0x42, 0x5f,
-       0x32, 0x3d, 0x1b, 0xe0, 0xdf, 0x28, 0xee, 0x31, 0x06, 0xe0, 0xbb, 0xde,
-       0x86, 0xf5, 0xbe, 0x17, 0x32, 0xa2, 0x6e, 0xa0, 0xbf, 0x25, 0xee, 0xbb,
-       0x42, 0x7f, 0x4b, 0x57, 0xde, 0xb6, 0x7b, 0xe9, 0xf3, 0x46, 0xe4, 0x18,
-       0xfc, 0xe8, 0xd1, 0x45, 0xf2, 0x93, 0xf6, 0x70, 0xd9, 0x30, 0x64, 0x42,
-       0x1f, 0x3f, 0x2c, 0x6f, 0xd4, 0x7e, 0xa0, 0x70, 0xe0, 0xb6, 0x9d, 0x0d,
-       0x99, 0x86, 0x7f, 0x98, 0x71, 0x20, 0x7f, 0x33, 0x82, 0xf5, 0x19, 0x56,
-       0xfe, 0x71, 0xe6, 0xfd, 0xe5, 0x24, 0x01, 0x37, 0x66, 0x7f, 0xf6, 0x3e,
-       0x63, 0xf6, 0x03, 0xc0, 0x61, 0xef, 0x8b, 0xbe, 0xe1, 0xd2, 0xff, 0x33,
-       0xe8, 0xea, 0xd7, 0x55, 0xfd, 0x22, 0xb7, 0x73, 0x2b, 0x65, 0xfa, 0x5e,
-       0xcf, 0xe9, 0xee, 0x73, 0x9f, 0xbb, 0x4f, 0xbe, 0x4c, 0xa9, 0x01, 0x2b,
-       0xe4, 0x55, 0x1c, 0x65, 0xae, 0xd8, 0xe6, 0xe9, 0x6f, 0x10, 0x18, 0x9a,
-       0x74, 0x7d, 0xdf, 0xdb, 0x21, 0xf9, 0x5e, 0x3f, 0xff, 0x84, 0xcf, 0x5e,
-       0x6d, 0xf7, 0xf3, 0x59, 0x3e, 0xbf, 0x92, 0x41, 0xfe, 0x0c, 0x1b, 0x60,
-       0x2c, 0x60, 0x5b, 0x5c, 0xf9, 0xa1, 0x77, 0xe7, 0x9b, 0xf5, 0x0b, 0xf2,
-       0xbd, 0x5b, 0xf1, 0x9d, 0x56, 0x7c, 0xb3, 0x06, 0xb9, 0x5f, 0x4b, 0x9d,
-       0x67, 0x1d, 0xd2, 0xaf, 0x3b, 0x92, 0x1e, 0xb0, 0x01, 0xf4, 0xfd, 0x63,
-       0xd0, 0xfd, 0x11, 0xf4, 0xfa, 0xc3, 0x12, 0xb0, 0x41, 0x09, 0xd8, 0xa0,
-       0x04, 0x6c, 0x50, 0x02, 0x36, 0x28, 0x85, 0xbd, 0x3a, 0x8b, 0x4d, 0x6c,
-       0xff, 0x3e, 0x6d, 0xd7, 0xaf, 0x6d, 0xac, 0xb7, 0x4b, 0xb7, 0xb6, 0x99,
-       0xaa, 0xfb, 0x18, 0x39, 0xc8, 0x5a, 0x2b, 0xb0, 0x9a, 0x5f, 0xf7, 0xf0,
-       0x62, 0x44, 0x8d, 0xfb, 0x5e, 0x88, 0x11, 0x35, 0x1b, 0xeb, 0x66, 0x28,
-       0x6c, 0x00, 0x1b, 0x1a, 0x12, 0xc6, 0x6f, 0x13, 0xbe, 0x17, 0xb4, 0x86,
-       0xfb, 0xb1, 0x92, 0xda, 0x55, 0x5d, 0xef, 0x88, 0xaa, 0x3b, 0x58, 0x32,
-       0x5b, 0xf6, 0x73, 0xb7, 0x98, 0x8c, 0xcd, 0x13, 0x6f, 0xca, 0x16, 0x3d,
-       0x01, 0x1d, 0x38, 0xc4, 0x88, 0xdc, 0x27, 0xe4, 0xf8, 0xb1, 0xc1, 0x2a,
-       0xc6, 0x2c, 0x58, 0x2e, 0x7f, 0x47, 0x9c, 0xbb, 0xcf, 0xec, 0x82, 0x7f,
-       0xce, 0x14, 0x23, 0x32, 0x5e, 0x74, 0x31, 0x01, 0xf2, 0x9f, 0x75, 0xf5,
-       0xe5, 0x5b, 0xd0, 0xc3, 0xad, 0xcc, 0x94, 0xb5, 0x6a, 0x1b, 0x91, 0xcb,
-       0x71, 0xca, 0x98, 0xfa, 0xdf, 0xab, 0xf6, 0x29, 0x76, 0x55, 0xdd, 0xbd,
-       0xa4, 0x71, 0x65, 0x0b, 0x01, 0xfa, 0x19, 0xd0, 0x89, 0xbb, 0x6b, 0x18,
-       0x76, 0x91, 0x73, 0x7c, 0xb9, 0xb4, 0xe2, 0x91, 0x2f, 0x6a, 0x62, 0x6d,
-       0xd4, 0xfe, 0x1b, 0x2d, 0xed, 0xab, 0xf7, 0x3d, 0x7e, 0xe1, 0xfb, 0x56,
-       0x6b, 0x0d, 0xf4, 0x53, 0x77, 0xdb, 0x81, 0xdd, 0x24, 0xa0, 0xee, 0xc3,
-       0x87, 0xd7, 0x42, 0x92, 0xaa, 0x59, 0x92, 0x2e, 0xb3, 0x1f, 0xeb, 0x17,
-       0xf4, 0x47, 0x7f, 0x22, 0x29, 0xe4, 0xab, 0xd9, 0x50, 0x34, 0x6e, 0xcb,
-       0x7f, 0x96, 0xe5, 0x85, 0x7c, 0x84, 0xe7, 0x0a, 0xf2, 0x13, 0x1a, 0x9e,
-       0xfb, 0x19, 0xae, 0xc9, 0xb3, 0x25, 0x33, 0x45, 0xc6, 0x9d, 0xa1, 0x70,
-       0x0d, 0xf7, 0xb2, 0x93, 0xac, 0xd9, 0x7c, 0x07, 0x36, 0x19, 0x8d, 0x94,
-       0xa1, 0xef, 0x2b, 0x45, 0x8e, 0x07, 0x6c, 0x54, 0x64, 0x5d, 0xc7, 0xbf,
-       0xff, 0x27, 0xc0, 0x81, 0xf0, 0xd5, 0x21, 0xaf, 0x8f, 0x9a, 0xab, 0x6d,
-       0x06, 0x60, 0xe3, 0x0d, 0xcf, 0xdf, 0x56, 0x8a, 0x6e, 0x1d, 0xe5, 0x2c,
-       0xf9, 0x70, 0xfe, 0x77, 0xb3, 0x11, 0x42, 0x0e, 0xb4, 0x3a, 0xc7, 0xab,
-       0xa4, 0x6f, 0xc2, 0xdd, 0xca, 0x51, 0xc7, 0x97, 0x05, 0xef, 0xb3, 0x8d,
-       0x67, 0x27, 0x9a, 0xcd, 0xb3, 0xd6, 0x07, 0xad, 0x99, 0xf5, 0x6d, 0x4f,
-       0x5a, 0xf9, 0xdd, 0x15, 0x27, 0xef, 0xd5, 0xcc, 0xbe, 0xbd, 0xc3, 0xad,
-       0x99, 0xd5, 0x76, 0xac, 0xad, 0x99, 0x59, 0xdb, 0xdd, 0x9a, 0xd9, 0xfc,
-       0xee, 0x02, 0x3e, 0x6e, 0xcd, 0x2c, 0xbb, 0xdd, 0xad, 0x99, 0x95, 0xb7,
-       0xbb, 0x35, 0x33, 0x67, 0x87, 0x5b, 0x33, 0xfb, 0xf9, 0xf6, 0xb5, 0x35,
-       0xb3, 0x1f, 0xec, 0x58, 0x5b, 0x33, 0xbb, 0xb8, 0x3b, 0x87, 0xcf, 0xdd,
-       0x9a, 0xd9, 0xcf, 0x76, 0xdc, 0xbb, 0x66, 0xf6, 0x9a, 0x8f, 0xd7, 0x31,
-       0x9f, 0x11, 0xcc, 0x21, 0x0e, 0xbc, 0x3e, 0x0c, 0xbc, 0xfe, 0x6e, 0x75,
-       0xfe, 0x00, 0xe6, 0x39, 0xe8, 0xc5, 0x83, 0x0f, 0x82, 0xdb, 0x47, 0xbc,
-       0x67, 0x6d, 0xe4, 0xbb, 0x11, 0x2f, 0x57, 0x21, 0x76, 0xdf, 0xec, 0xe5,
-       0x6c, 0xff, 0xa8, 0xf3, 0xee, 0xb9, 0x97, 0xd6, 0xef, 0x0f, 0x21, 0xf5,
-       0xf6, 0xf1, 0x3c, 0xe7, 0x95, 0x47, 0xee, 0x47, 0x39, 0xd8, 0xe8, 0x3f,
-       0xbf, 0xfb, 0x1b, 0x16, 0x31, 0xfe, 0x73, 0x58, 0xab, 0xf6, 0x16, 0x43,
-       0x9d, 0x01, 0x60, 0x8c, 0x3a, 0x2e, 0x29, 0xf4, 0x4f, 0xa9, 0xfe, 0xd7,
-       0x5a, 0xfa, 0xaf, 0xa0, 0x3f, 0xe9, 0x46, 0xff, 0x1d, 0x3e, 0x2f, 0x29,
-       0xfb, 0xb6, 0x5c, 0x0c, 0x9f, 0x2e, 0xf9, 0x78, 0x2b, 0xe0, 0x61, 0xe7,
-       0x46, 0xc6, 0x76, 0x3e, 0x8f, 0x67, 0xa2, 0x17, 0x6d, 0xb9, 0xa9, 0xf0,
-       0xbb, 0x91, 0x88, 0x5e, 0xcc, 0xaa, 0x7c, 0xad, 0x91, 0xc9, 0x39, 0x7e,
-       0xfe, 0x8d, 0x1c, 0x6a, 0x80, 0x39, 0x0c, 0xec, 0x7d, 0x69, 0x10, 0x71,
-       0xac, 0x35, 0xc7, 0x66, 0x5e, 0xad, 0x7b, 0x79, 0xb5, 0x29, 0x9f, 0xd9,
-       0xd9, 0x8a, 0xcd, 0x2f, 0xee, 0xfe, 0xc7, 0x0a, 0x9b, 0x6f, 0x42, 0x6e,
-       0x4e, 0xec, 0x4d, 0x1c, 0x43, 0x0c, 0x41, 0x7c, 0xce, 0x7a, 0x01, 0xf3,
-       0x19, 0xc6, 0x46, 0xe6, 0x37, 0x21, 0x7c, 0x78, 0x26, 0xc9, 0xc7, 0xe8,
-       0xed, 0x9e, 0x7f, 0x67, 0x5e, 0xe4, 0x63, 0x95, 0xe4, 0x26, 0x37, 0x37,
-       0xda, 0xa4, 0xb9, 0xf9, 0x67, 0xc4, 0xeb, 0x13, 0x58, 0xc5, 0xc2, 0x81,
-       0x55, 0x2c, 0xbc, 0x66, 0x1f, 0x4b, 0xd4, 0xf9, 0x27, 0xb5, 0x1f, 0xc6,
-       0xfd, 0xb1, 0x46, 0xe6, 0xca, 0x80, 0x68, 0x7a, 0x82, 0xfb, 0x64, 0xc0,
-       0x3a, 0x16, 0xf7, 0xcd, 0xe8, 0x3b, 0xf7, 0x69, 0xa9, 0x2a, 0xe3, 0x0f,
-       0xf1, 0x91, 0xbf, 0x17, 0xee, 0xeb, 0x89, 0xb2, 0x63, 0xdb, 0x1f, 0x6b,
-       0xc8, 0x79, 0xe3, 0xed, 0xd6, 0x53, 0xe0, 0x25, 0x83, 0x6f, 0x5f, 0xa6,
-       0x9f, 0x55, 0xb1, 0xaf, 0x03, 0xb6, 0x7b, 0xa4, 0x44, 0xec, 0xba, 0x59,
-       0x6a, 0x1e, 0x7e, 0x3d, 0x37, 0xef, 0x62, 0xd7, 0xc0, 0x5a, 0xec, 0x1a,
-       0x5f, 0x16, 0x97, 0xc7, 0x5d, 0x1b, 0xf2, 0x48, 0xbc, 0x4a, 0xfe, 0x18,
-       0x77, 0xf6, 0xc2, 0xff, 0x35, 0x80, 0x69, 0x19, 0x73, 0x18, 0x6f, 0x22,
-       0xc0, 0xf6, 0xf7, 0xe2, 0x4f, 0xb5, 0x1d, 0xea, 0xb0, 0x82, 0xf8, 0x4c,
-       0xc3, 0x7f, 0x4c, 0xe0, 0x99, 0x8c, 0xcc, 0x9e, 0xfe, 0x1a, 0xe6, 0x36,
-       0x2d, 0x57, 0xe6, 0x27, 0xc1, 0xdf, 0x73, 0x32, 0x17, 0xcf, 0xc3, 0x8f,
-       0x70, 0xcf, 0x83, 0xb8, 0xad, 0xdf, 0xfb, 0x9e, 0xd6, 0xcf, 0x5a, 0x51,
-       0xe2, 0x46, 0xa9, 0x16, 0xe9, 0x83, 0xb9, 0x67, 0xc8, 0xbd, 0x61, 0xda,
-       0x0f, 0xeb, 0x27, 0xc8, 0x5d, 0x99, 0xc3, 0x9e, 0xe2, 0xf8, 0x6b, 0x75,
-       0xb2, 0xec, 0x10, 0x7f, 0x35, 0x32, 0x8d, 0x25, 0xe2, 0xc7, 0xf7, 0x8b,
-       0x25, 0xa9, 0x07, 0xe2, 0xc9, 0xfb, 0xc1, 0x91, 0xd1, 0x79, 0x60, 0xc8,
-       0x57, 0x1a, 0x7a, 0x2b, 0x8e, 0x74, 0x31, 0x64, 0x72, 0x29, 0x0b, 0x9a,
-       0x71, 0x85, 0x95, 0x91, 0xc7, 0xc1, 0xed, 0xf5, 0xe3, 0xd9, 0x7e, 0xe4,
-       0xe4, 0x2e, 0x66, 0x4c, 0x01, 0x33, 0xfe, 0x06, 0x30, 0xe3, 0xac, 0x74,
-       0x76, 0x11, 0x33, 0xda, 0x1e, 0x66, 0x4c, 0xc3, 0x9e, 0x73, 0x6b, 0xec,
-       0x59, 0x53, 0xb5, 0x28, 0xde, 0xcb, 0x01, 0xf3, 0xa5, 0x4e, 0x45, 0xef,
-       0x03, 0x27, 0x6a, 0x12, 0x52, 0xe7, 0x52, 0x02, 0x2d, 0x34, 0x7d, 0x3c,
-       0xb8, 0x4d, 0xe1, 0xbc, 0xdd, 0xa5, 0x4d, 0xc8, 0x51, 0x14, 0xee, 0xf3,
-       0xf6, 0x4b, 0x03, 0xeb, 0xf6, 0x90, 0x03, 0x2d, 0x7b, 0xc8, 0x77, 0xf1,
-       0x21, 0x9e, 0xf3, 0x6a, 0x7d, 0x6d, 0xf0, 0x05, 0xff, 0x13, 0x3c, 0x71,
-       0x7d, 0x71, 0x2d, 0x68, 0xee, 0x7a, 0x59, 0x83, 0x13, 0xff, 0x7a, 0x1d,
-       0x4e, 0x44, 0xec, 0x3a, 0x17, 0x92, 0x24, 0x30, 0xa2, 0xbd, 0x44, 0x5a,
-       0x5c, 0xd3, 0xc3, 0xd2, 0x8e, 0xf9, 0x75, 0x9c, 0xea, 0x05, 0x36, 0xea,
-       0x92, 0x20, 0x30, 0x52, 0x9b, 0xc2, 0x48, 0x03, 0xc4, 0x32, 0x83, 0x33,
-       0xc0, 0x36, 0xb5, 0x55, 0x9c, 0x14, 0x8d, 0xff, 0x01, 0xf4, 0xf2, 0x94,
-       0xf2, 0x3d, 0x69, 0x39, 0x01, 0x5f, 0xda, 0xbe, 0x04, 0x7c, 0x77, 0xce,
-       0xc5, 0x4f, 0x6d, 0xeb, 0xf0, 0xd3, 0xc1, 0x0d, 0xf1, 0x93, 0xaa, 0xdf,
-       0x8f, 0x52, 0x26, 0x37, 0x1c, 0xb7, 0x7e, 0x7f, 0xdd, 0x71, 0xeb, 0xf7,
-       0x37, 0x9c, 0xd6, 0xfa, 0xfd, 0x47, 0xa4, 0x60, 0x46, 0xed, 0x15, 0x59,
-       0x57, 0xbf, 0x9f, 0x60, 0x3d, 0xdc, 0xe9, 0x72, 0xeb, 0xf4, 0x5d, 0x5e,
-       0xfd, 0x3e, 0x2a, 0x85, 0x35, 0xed, 0xa6, 0xbc, 0x69, 0xf9, 0xf5, 0xfb,
-       0xef, 0xa2, 0xad, 0x1b, 0x63, 0xac, 0xad, 0xdd, 0x5f, 0x77, 0x58, 0xbb,
-       0x0f, 0xb1, 0x9f, 0x57, 0xbb, 0x67, 0x3f, 0xe4, 0xf2, 0x0e, 0xeb, 0xf6,
-       0x8f, 0x40, 0x16, 0x5b, 0x21, 0x87, 0x5e, 0x69, 0x3f, 0x13, 0x66, 0x1f,
-       0x55, 0xaf, 0x5f, 0x71, 0x42, 0x78, 0xce, 0xad, 0xab, 0xcf, 0xc0, 0xae,
-       0x0e, 0xae, 0xd6, 0xeb, 0xdd, 0x31, 0x6e, 0x3a, 0x6b, 0xe9, 0xaf, 0xa5,
-       0xd3, 0xe7, 0xd1, 0x09, 0x81, 0x4e, 0x78, 0x1d, 0x9d, 0xbb, 0xf5, 0xf9,
-       0x9b, 0x8e, 0x5b, 0x9b, 0x4f, 0x9f, 0x16, 0xbb, 0x1d, 0xbe, 0xf9, 0xe2,
-       0xc0, 0xc3, 0x1e, 0x8d, 0xd5, 0xda, 0x3c, 0x7d, 0x08, 0x70, 0x7b, 0x4c,
-       0x9d, 0xbd, 0x9a, 0xf9, 0x7f, 0x50, 0x9b, 0x67, 0x5d, 0xde, 0xdd, 0x5f,
-       0xe1, 0xfa, 0x04, 0x3e, 0x7f, 0xd1, 0xad, 0xc9, 0x8f, 0x95, 0xfc, 0x5a,
-       0x3b, 0xf3, 0x47, 0xff, 0x5c, 0x54, 0x7f, 0xe4, 0x88, 0xd0, 0x56, 0xc8,
-       0x1f, 0xe9, 0x76, 0xcb, 0x94, 0xc2, 0x47, 0xb0, 0xa9, 0xd8, 0xbd, 0x31,
-       0x72, 0xe5, 0x94, 0x8f, 0x91, 0x43, 0x0a, 0x23, 0x57, 0x96, 0x7c, 0x8c,
-       0x9c, 0xbc, 0x07, 0x46, 0x6e, 0x76, 0xb9, 0x71, 0x20, 0x28, 0x79, 0x85,
-       0x91, 0xef, 0x75, 0x96, 0x8c, 0xf7, 0xba, 0x88, 0x07, 0xc4, 0x3d, 0x5f,
-       0xd0, 0x7b, 0x8f, 0xb5, 0xe6, 0xe3, 0x66, 0xc6, 0xfe, 0xad, 0x32, 0x71,
-       0xe6, 0x2e, 0x6e, 0x76, 0xb1, 0x71, 0x34, 0x72, 0x48, 0xc5, 0x44, 0xe0,
-       0x84, 0x3a, 0xeb, 0xdf, 0xc4, 0xbe, 0x8c, 0x39, 0x01, 0x85, 0xcf, 0x72,
-       0x45, 0xe6, 0x01, 0x6c, 0x23, 0x16, 0xee, 0xe4, 0x31, 0x2b, 0x2f, 0x26,
-       0xf9, 0x58, 0xd3, 0x3f, 0xd7, 0xc2, 0x3d, 0x86, 0x37, 0x8d, 0xa4, 0x85,
-       0x76, 0xc7, 0xcf, 0x15, 0xe2, 0xea, 0x3c, 0x50, 0x12, 0x58, 0x72, 0x6a,
-       0x15, 0x4b, 0xd2, 0x57, 0xfc, 0xf4, 0x6d, 0xdb, 0xa4, 0x5f, 0xf3, 0xb1,
-       0x22, 0x72, 0xa2, 0x12, 0xd7, 0xb6, 0x8f, 0x15, 0x5d, 0x9c, 0x98, 0x72,
-       0x1a, 0xc0, 0xcb, 0x01, 0x19, 0x03, 0x4e, 0x6f, 0x7c, 0x89, 0x35, 0x28,
-       0x1f, 0x1b, 0xd9, 0xf8, 0x6e, 0xad, 0x49, 0xf1, 0xba, 0x5d, 0xed, 0x05,
-       0x5e, 0x1e, 0x08, 0xb6, 0xb4, 0x3f, 0x0b, 0xff, 0x8d, 0xfc, 0x08, 0xd8,
-       0xc4, 0xc5, 0x44, 0x3b, 0xa0, 0x83, 0x91, 0x7b, 0x60, 0xa2, 0xf5, 0x31,
-       0x8a, 0x31, 0xf3, 0x6e, 0x8c, 0x4a, 0xd7, 0xe9, 0xcf, 0xef, 0xc6, 0xa8,
-       0x7b, 0xc7, 0x50, 0xb6, 0x61, 0x76, 0x56, 0x06, 0x9f, 0x69, 0x29, 0xac,
-       0x8b, 0x51, 0x73, 0x1f, 0x20, 0x46, 0xb9, 0xf8, 0xc0, 0xe5, 0xfb, 0xf7,
-       0x21, 0x9b, 0x1f, 0x43, 0xa6, 0x3f, 0x02, 0xe6, 0xfa, 0x21, 0xe6, 0xf5,
-       0x03, 0xe0, 0xa1, 0xef, 0x97, 0xd6, 0x9f, 0x07, 0x19, 0x15, 0xe6, 0x87,
-       0x2e, 0x66, 0x72, 0x31, 0xfd, 0x0c, 0x56, 0x57, 0xad, 0xd8, 0xc8, 0x4c,
-       0x15, 0x87, 0xcc, 0x69, 0x77, 0x1f, 0x35, 0x92, 0x95, 0xa7, 0x3b, 0x53,
-       0x8b, 0x8c, 0x19, 0xea, 0x3a, 0xcc, 0xfa, 0x25, 0xb1, 0x43, 0x55, 0xe5,
-       0x99, 0x03, 0x52, 0xae, 0xb9, 0x78, 0x6b, 0x6e, 0xd1, 0xa5, 0x31, 0xe5,
-       0xe1, 0xad, 0x9c, 0x87, 0xb7, 0xb2, 0xb5, 0xe5, 0x48, 0x00, 0xfd, 0xe7,
-       0xe2, 0x6b, 0x31, 0xd6, 0x8c, 0x87, 0xb1, 0xa6, 0x3f, 0x20, 0xc6, 0xe2,
-       0x58, 0x39, 0x3c, 0x33, 0x3e, 0x1f, 0x91, 0x5d, 0x90, 0xf3, 0x58, 0x91,
-       0xfa, 0xe2, 0x19, 0xb2, 0xf7, 0xd2, 0x19, 0xf5, 0xe5, 0xea, 0x2a, 0x10,
-       0xdb, 0xa7, 0x8d, 0x43, 0x57, 0x63, 0xef, 0xa9, 0x2b, 0x31, 0xdf, 0x18,
-       0x09, 0xe2, 0xf3, 0xf7, 0xa5, 0x2b, 0xce, 0x83, 0xfa, 0x5a, 0x8f, 0xc5,
-       0xee, 0x07, 0x93, 0xad, 0xc5, 0x63, 0xb6, 0xc2, 0x63, 0xed, 0x5e, 0x1f,
-       0xd9, 0x33, 0x0e, 0x5d, 0xfe, 0x27, 0xf4, 0xf9, 0x99, 0xd5, 0x2d, 0x3f,
-       0x85, 0xff, 0xfe, 0x43, 0xe8, 0xe4, 0x3f, 0x22, 0x57, 0x78, 0xcd, 0xea,
-       0x93, 0x3f, 0x40, 0xdb, 0x5d, 0x9c, 0xc3, 0xfe, 0xc1, 0xc7, 0x92, 0xd6,
-       0x35, 0xe0, 0x93, 0x6b, 0x1e, 0x3e, 0x79, 0x3a, 0x99, 0xb4, 0x26, 0x59,
-       0x37, 0x87, 0x9c, 0x0f, 0xa4, 0xa6, 0x14, 0x36, 0xf1, 0x31, 0xc9, 0xed,
-       0x34, 0xc7, 0x9f, 0x75, 0x56, 0x80, 0x7d, 0x56, 0x3c, 0xec, 0x73, 0x60,
-       0xcc, 0xc5, 0x3e, 0xc1, 0xcf, 0x50, 0xff, 0x2e, 0xee, 0x59, 0xb1, 0x93,
-       0x18, 0xa7, 0x0a, 0x4c, 0x52, 0x71, 0x0e, 0x48, 0xbe, 0xbe, 0x57, 0x7d,
-       0x8e, 0x94, 0xec, 0x68, 0x1b, 0xe4, 0xc4, 0xda, 0xeb, 0x49, 0xae, 0x4a,
-       0x27, 0x6a, 0x16, 0xf1, 0x9d, 0x75, 0xa2, 0xe1, 0xdf, 0xf1, 0xae, 0x9f,
-       0xf7, 0xae, 0x4f, 0x78, 0xd7, 0xc7, 0x11, 0x87, 0x8f, 0xa9, 0x58, 0xca,
-       0x76, 0xb6, 0x41, 0xc9, 0x0e, 0x68, 0x01, 0x7b, 0x9c, 0x1d, 0xfe, 0x8b,
-       0x66, 0x59, 0xe9, 0x98, 0xf4, 0x27, 0xf0, 0x39, 0x8e, 0xcf, 0x34, 0x3e,
-       0xfb, 0xf1, 0xc9, 0xe3, 0xb3, 0x2a, 0x53, 0x2d, 0x55, 0x9a, 0x84, 0x8d,
-       0x0c, 0x4a, 0xaa, 0xfe, 0x12, 0xf4, 0xf8, 0x1c, 0x74, 0x7b, 0x58, 0x0a,
-       0xd5, 0x3f, 0x95, 0xd9, 0x79, 0x4d, 0xba, 0x2c, 0xe8, 0xb4, 0x0a, 0x5b,
-       0x9e, 0x77, 0xf7, 0x13, 0x3b, 0x13, 0x7b, 0xd1, 0xb7, 0x29, 0x4f, 0xc5,
-       0x9f, 0x13, 0xfd, 0xb1, 0x39, 0xf4, 0x13, 0xbd, 0x30, 0xfc, 0x31, 0xb5,
-       0x6f, 0x56, 0x8d, 0xbb, 0x32, 0xde, 0x65, 0xd9, 0x51, 0xe8, 0x7c, 0xf0,
-       0x18, 0x68, 0x27, 0xd5, 0xd9, 0xd8, 0x8c, 0x1c, 0x3d, 0xbd, 0xbc, 0xc5,
-       0xf5, 0xad, 0x51, 0xf3, 0x26, 0xf5, 0x8e, 0x79, 0xd8, 0xf0, 0x85, 0x19,
-       0xd8, 0xfb, 0x41, 0x27, 0xa0, 0x8d, 0x21, 0xde, 0x8c, 0x39, 0x37, 0x55,
-       0xbc, 0x81, 0xef, 0xca, 0xc4, 0x4e, 0x86, 0x70, 0xcd, 0xb3, 0x45, 0x88,
-       0x8b, 0xea, 0x6c, 0xe5, 0x32, 0xf0, 0x8d, 0xa6, 0xea, 0x80, 0xb3, 0xab,
-       0xfb, 0x43, 0x86, 0xf2, 0x5b, 0xb1, 0x98, 0x2e, 0xb9, 0x11, 0xe2, 0xdc,
-       0xbd, 0x2a, 0x36, 0xd5, 0x8a, 0xf6, 0x43, 0xcc, 0x15, 0x6f, 0x08, 0xe3,
-       0xdc, 0xe3, 0xe8, 0xd7, 0x07, 0x7f, 0x8c, 0x7b, 0x75, 0xda, 0x27, 0xe7,
-       0xca, 0x67, 0xa6, 0xa5, 0x5a, 0x1e, 0xc5, 0x7c, 0xbd, 0x1c, 0x49, 0xe5,
-       0x12, 0x11, 0xd8, 0xa3, 0xbf, 0x17, 0xe5, 0xd6, 0x4f, 0xaa, 0x8e, 0x8f,
-       0x29, 0xba, 0xd1, 0x87, 0x79, 0x05, 0x64, 0xe4, 0xee, 0x9f, 0xa9, 0xbd,
-       0xb3, 0x82, 0x33, 0x0a, 0x39, 0x25, 0xd1, 0xce, 0x5a, 0x35, 0x7e, 0x97,
-       0x75, 0x55, 0x13, 0x58, 0x31, 0x66, 0xa4, 0x56, 0x6e, 0x82, 0x5f, 0xc4,
-       0xdc, 0x2d, 0x33, 0x52, 0x29, 0x4f, 0xcb, 0x2b, 0xe5, 0x9f, 0x77, 0x03,
-       0x53, 0x41, 0xa6, 0xe4, 0xbf, 0x5b, 0xee, 0x9e, 0xbf, 0xf5, 0xdb, 0x21,
-       0xcf, 0xd3, 0xf9, 0xb0, 0x9b, 0xe7, 0xe6, 0x55, 0x2d, 0xc6, 0xfd, 0xb6,
-       0xf5, 0x29, 0x2b, 0x1a, 0x9e, 0x45, 0xcf, 0x83, 0x0b, 0xb4, 0xcd, 0xfc,
-       0xf8, 0x9c, 0xb5, 0x43, 0xae, 0xc6, 0x37, 0xcb, 0x72, 0x5c, 0xe5, 0xc5,
-       0xc4, 0x0f, 0x58, 0xeb, 0x51, 0xb3, 0x21, 0x7b, 0xe4, 0x28, 0xd6, 0xed,
-       0xd5, 0xf8, 0xd3, 0xb0, 0xd3, 0x67, 0x61, 0x0b, 0xac, 0x01, 0x1c, 0x62,
-       0xae, 0x25, 0x0d, 0x55, 0x23, 0x6b, 0x36, 0xc7, 0xd5, 0x19, 0xee, 0x76,
-       0x59, 0x56, 0x58, 0xcc, 0xad, 0x9d, 0x2f, 0x4f, 0xba, 0x6b, 0xc4, 0x50,
-       0x76, 0xff, 0xc7, 0xe0, 0xc7, 0x84, 0xed, 0xb6, 0xa9, 0x3e, 0x46, 0xa2,
-       0xc3, 0xeb, 0xa3, 0xf4, 0xdb, 0xd2, 0xe7, 0x95, 0x44, 0xd2, 0xda, 0xff,
-       0x89, 0xa4, 0x75, 0x73, 0xb7, 0x5b, 0x6f, 0x89, 0x9a, 0xb6, 0xc6, 0xf7,
-       0x52, 0xdc, 0xf5, 0x98, 0xc1, 0xba, 0xba, 0xb4, 0x8a, 0xa1, 0x61, 0xa4,
-       0x2f, 0x5f, 0x81, 0x7e, 0x03, 0xd2, 0x7e, 0xb2, 0xf9, 0xf8, 0x54, 0x7c,
-       0x28, 0x72, 0x50, 0x78, 0x02, 0x8b, 0x79, 0x75, 0x34, 0x9e, 0x95, 0x2b,
-       0x88, 0x93, 0x77, 0x88, 0x1d, 0x06, 0x2f, 0xcb, 0x9d, 0xc7, 0x93, 0xf1,
-       0x51, 0xad, 0x32, 0x89, 0xac, 0xe5, 0xe5, 0x49, 0xc6, 0xd9, 0x43, 0x22,
-       0xc0, 0x97, 0x27, 0x47, 0x24, 0x5d, 0x54, 0xef, 0xa9, 0xf0, 0x9c, 0xad,
-       0x36, 0x0d, 0xf9, 0xe1, 0xf9, 0x09, 0x06, 0x46, 0xdd, 0xea, 0x8f, 0xa4,
-       0xe5, 0x69, 0xd6, 0xc0, 0x24, 0xb7, 0x20, 0xdb, 0x92, 0xf0, 0xab, 0xf6,
-       0x44, 0xbb, 0x4c, 0xd7, 0x1a, 0x99, 0xfe, 0x53, 0xcf, 0x82, 0xc6, 0x14,
-       0x68, 0xed, 0x45, 0x6e, 0x92, 0x45, 0xac, 0xa6, 0x7c, 0xe9, 0xbb, 0x9f,
-       0x81, 0x8c, 0x3e, 0xc2, 0x3d, 0xe5, 0xd1, 0xac, 0x44, 0x27, 0xf2, 0x8a,
-       0xee, 0x5b, 0x5a, 0x6e, 0xf8, 0x57, 0x10, 0xeb, 0x02, 0xb2, 0x2b, 0x26,
-       0xfa, 0xde, 0x58, 0xe0, 0xed, 0x29, 0x8b, 0x6d, 0x41, 0xb6, 0xe9, 0x68,
-       0x0b, 0xfc, 0x7a, 0x2c, 0xa8, 0x27, 0x63, 0xd1, 0x51, 0x9e, 0x8f, 0x36,
-       0xac, 0x29, 0xee, 0x4d, 0x3c, 0x20, 0x5d, 0x7b, 0xa5, 0xe7, 0x42, 0x74,
-       0xf4, 0x06, 0x78, 0x09, 0x28, 0x5f, 0x3f, 0x25, 0xba, 0xd7, 0xde, 0xbd,
-       0xda, 0x1e, 0xf0, 0xda, 0xf7, 0x4a, 0xd7, 0x85, 0x21, 0xf3, 0x75, 0x99,
-       0x01, 0x4d, 0x43, 0xae, 0x23, 0xd7, 0xb1, 0x06, 0xa6, 0x60, 0x8b, 0x4f,
-       0x92, 0x97, 0xfd, 0xc0, 0x1a, 0x58, 0x1b, 0xc8, 0xbf, 0xad, 0x0f, 0xcb,
-       0x57, 0xcd, 0x4e, 0xc9, 0xa9, 0x5c, 0x37, 0xe0, 0xd6, 0x52, 0x61, 0xef,
-       0x8f, 0x0e, 0x1c, 0xec, 0x71, 0xeb, 0x05, 0xdc, 0xef, 0x18, 0x46, 0xdb,
-       0x9d, 0xe6, 0x39, 0x8b, 0x6d, 0xbc, 0x77, 0xa7, 0x59, 0xb5, 0x86, 0xcc,
-       0x94, 0x16, 0xf4, 0xf6, 0xbd, 0x0f, 0xa9, 0xb9, 0xe7, 0xcb, 0xfd, 0x66,
-       0x45, 0x1e, 0xd5, 0x52, 0x0f, 0x22, 0x5e, 0x38, 0xd3, 0xe8, 0x7b, 0x87,
-       0xe7, 0x29, 0x54, 0x7d, 0xbf, 0x22, 0xfe, 0x35, 0xe9, 0x0c, 0x99, 0xe3,
-       0xea, 0xd9, 0x21, 0xf3, 0xa8, 0xd6, 0xfa, 0x6c, 0x58, 0x1b, 0x5f, 0xf3,
-       0x6c, 0x97, 0x92, 0x91, 0x61, 0xb9, 0x7d, 0x66, 0xcb, 0x7b, 0xe5, 0x79,
-       0x87, 0xfd, 0xee, 0x34, 0x53, 0xd6, 0x03, 0xda, 0xd1, 0x07, 0xe9, 0x0b,
-       0xd9, 0xf7, 0xf6, 0xba, 0x71, 0x78, 0x7d, 0xaf, 0x31, 0x9a, 0xb2, 0x76,
-       0x8c, 0x4d, 0xaa, 0xcf, 0x55, 0xd5, 0x27, 0xa0, 0x64, 0xbd, 0x76, 0x9c,
-       0xbf, 0x91, 0xb5, 0xe3, 0x74, 0xad, 0xce, 0x79, 0x16, 0x34, 0x8f, 0xa1,
-       0x6f, 0xd1, 0xe9, 0x0f, 0x57, 0xe5, 0x76, 0x33, 0x67, 0xbd, 0x29, 0x57,
-       0x57, 0x69, 0xff, 0x12, 0xd7, 0xad, 0x3c, 0xfd, 0xd2, 0xe3, 0x91, 0xbf,
-       0xd9, 0xf6, 0x2f, 0x95, 0xbc, 0x1f, 0xb0, 0xfa, 0xf7, 0x57, 0xb4, 0xe8,
-       0xe8, 0x5f, 0x0a, 0x75, 0xf5, 0xcf, 0x94, 0xaf, 0xf9, 0x18, 0xf4, 0xb4,
-       0xed, 0x05, 0xac, 0xdd, 0xe1, 0xa4, 0xea, 0x73, 0xdd, 0xda, 0x2b, 0xdb,
-       0x4e, 0xf6, 0x9b, 0xd7, 0xe5, 0x33, 0x92, 0x0e, 0xf1, 0x1a, 0x39, 0x94,
-       0xc5, 0xf7, 0x52, 0x3e, 0xc1, 0xbc, 0x00, 0xba, 0xec, 0x1f, 0xfc, 0x4b,
-       0x79, 0x56, 0x8e, 0x96, 0xe6, 0xe0, 0x7b, 0xa6, 0x64, 0xf0, 0x05, 0xfa,
-       0x9f, 0xbc, 0xe9, 0xd6, 0x6a, 0xdc, 0x98, 0x98, 0xf2, 0x62, 0xe2, 0x9c,
-       0xf2, 0x73, 0xaf, 0x79, 0xe7, 0x22, 0xfa, 0x07, 0xcf, 0xe1, 0xd9, 0x57,
-       0x94, 0x0f, 0xf8, 0x3d, 0xa9, 0x62, 0x2d, 0x44, 0x5e, 0xde, 0x2c, 0x0f,
-       0x3c, 0x41, 0x9b, 0x44, 0x06, 0xf0, 0xb1, 0x36, 0xf5, 0x1e, 0x8c, 0x6e,
-       0x75, 0x88, 0x6c, 0xa1, 0xfd, 0x5c, 0x86, 0xad, 0x4d, 0xb9, 0x7b, 0x5f,
-       0x6b, 0xae, 0xa3, 0x13, 0x2b, 0xf2, 0x1f, 0x94, 0x1d, 0x7e, 0xfc, 0x82,
-       0xfb, 0x3d, 0x7c, 0x01, 0xe9, 0x72, 0x6c, 0xaf, 0x6c, 0xbf, 0xe0, 0xda,
-       0xdd, 0xec, 0xfc, 0xb3, 0x4a, 0xbe, 0x53, 0x4a, 0xbe, 0x4d, 0x99, 0x89,
-       0x53, 0xf6, 0x9c, 0x13, 0xcf, 0x4f, 0xba, 0x32, 0xf9, 0x9c, 0x67, 0x47,
-       0xfd, 0x2f, 0xf0, 0x3d, 0x35, 0xca, 0x88, 0x7c, 0xcf, 0xf4, 0x70, 0x3f,
-       0x76, 0xdb, 0x05, 0xce, 0xb7, 0x6f, 0xcd, 0x7c, 0x4f, 0xc0, 0xc7, 0x0e,
-       0x0c, 0xb8, 0x73, 0x7e, 0x6d, 0xfe, 0xfd, 0xcf, 0xf9, 0x77, 0x57, 0xe7,
-       0x6c, 0x48, 0x55, 0xe5, 0xb9, 0xb1, 0xcd, 0xd2, 0x95, 0x93, 0x06, 0xec,
-       0xe3, 0xcf, 0x85, 0x67, 0xc6, 0xc9, 0x8b, 0x3b, 0xee, 0xb2, 0x43, 0x9e,
-       0xfc, 0x39, 0x90, 0xaf, 0x29, 0x4f, 0x7f, 0xe4, 0xe3, 0xd9, 0x0d, 0xef,
-       0x5d, 0x97, 0x46, 0x66, 0x10, 0x6d, 0xba, 0xd2, 0xe1, 0x98, 0xb7, 0xde,
-       0xf6, 0x8a, 0xae, 0x74, 0x98, 0x5c, 0xd5, 0xe1, 0x0d, 0xe8, 0xb0, 0x2a,
-       0x9f, 0xc6, 0x9c, 0xb0, 0xbe, 0x5f, 0x18, 0x32, 0x67, 0x64, 0xab, 0xd2,
-       0xbf, 0x35, 0x00, 0x9f, 0xea, 0xe9, 0xb2, 0xfd, 0x3e, 0x74, 0xf9, 0xba,
-       0x28, 0x7d, 0xaa, 0x73, 0x44, 0x55, 0x45, 0x87, 0xbe, 0x8d, 0x73, 0x6b,
-       0x57, 0x3e, 0x81, 0x3c, 0xaa, 0xb3, 0x01, 0x13, 0xae, 0x7e, 0xd5, 0x9a,
-       0xf7, 0xf4, 0x9b, 0x9d, 0xa0, 0x0e, 0x7f, 0xad, 0xc7, 0xd5, 0x67, 0x87,
-       0xea, 0x73, 0x2a, 0x36, 0xaa, 0xd6, 0xbb, 0x35, 0xf0, 0xe9, 0x1e, 0xea,
-       0xf4, 0x79, 0xc7, 0xfd, 0x2e, 0x22, 0xce, 0x9d, 0x72, 0xde, 0x4b, 0xaf,
-       0xae, 0x4e, 0xc7, 0xc4, 0x5d, 0x57, 0xeb, 0xf5, 0xa9, 0x5f, 0x08, 0x28,
-       0x1b, 0x1e, 0x83, 0x0c, 0x8f, 0x97, 0x1e, 0xf4, 0xec, 0xde, 0x9d, 0xf3,
-       0xc0, 0xfb, 0x9c, 0xf3, 0x91, 0x62, 0xbf, 0xf9, 0x26, 0xee, 0x8d, 0x63,
-       0xce, 0x33, 0xd2, 0x26, 0x29, 0x6f, 0xce, 0x91, 0xd5, 0x39, 0xfb, 0x3c,
-       0xba, 0xfd, 0x52, 0xcc, 0x63, 0x1d, 0xfa, 0xaf, 0x7f, 0xab, 0xde, 0x37,
-       0xb9, 0x59, 0xa4, 0xdf, 0x06, 0x56, 0x0a, 0xf5, 0xca, 0xf5, 0x5a, 0x44,
-       0xae, 0x13, 0x83, 0x8c, 0xe0, 0xdb, 0x99, 0xf3, 0x62, 0x78, 0x50, 0x5e,
-       0x2f, 0x6e, 0xc4, 0xc7, 0xb0, 0xdc, 0x28, 0xfa, 0xbc, 0x10, 0x0b, 0x33,
-       0x5f, 0x98, 0x92, 0x37, 0xe6, 0xfb, 0xa5, 0x31, 0x81, 0xb8, 0x3f, 0x40,
-       0x99, 0x0c, 0x99, 0x7b, 0xd4, 0x7b, 0x48, 0x77, 0x9a, 0x97, 0x2d, 0xd0,
-       0x5f, 0x68, 0xca, 0x41, 0xee, 0x67, 0xf3, 0x77, 0xed, 0x21, 0x69, 0x30,
-       0xa7, 0x18, 0xe8, 0x95, 0xca, 0x02, 0xf2, 0xf9, 0x22, 0xe9, 0x53, 0x6e,
-       0x7b, 0xd5, 0xef, 0x71, 0x8c, 0xf7, 0x39, 0xbe, 0x1f, 0x10, 0xa2, 0x6e,
-       0xee, 0x34, 0x97, 0x2d, 0xee, 0x67, 0x4e, 0x49, 0x0d, 0xfa, 0xfb, 0xe7,
-       0x31, 0xee, 0xb7, 0xe7, 0xd4, 0xf9, 0xdb, 0x4a, 0x6d, 0x02, 0xb9, 0xc3,
-       0x9d, 0xe6, 0x9c, 0x75, 0x56, 0xe9, 0xad, 0x56, 0x7e, 0xc2, 0x6b, 0xe7,
-       0x35, 0xef, 0x35, 0x32, 0xdb, 0x06, 0x98, 0xaf, 0x3e, 0x81, 0x7c, 0x81,
-       0xb9, 0xea, 0x04, 0xf0, 0x1a, 0x65, 0x12, 0x91, 0xd9, 0x22, 0x69, 0x49,
-       0x68, 0x13, 0xf2, 0xfb, 0x9c, 0x8c, 0x83, 0x9f, 0x08, 0x72, 0x7b, 0xc6,
-       0x87, 0x47, 0x65, 0x39, 0xe4, 0xc6, 0x01, 0x9e, 0xfb, 0x5a, 0x46, 0x6c,
-       0x58, 0x5e, 0x8d, 0x0d, 0x5b, 0x71, 0xdd, 0xc8, 0xc4, 0x07, 0xfe, 0x06,
-       0xf4, 0x59, 0xb7, 0x61, 0x6c, 0x18, 0x45, 0x7f, 0xb6, 0xf5, 0xca, 0xec,
-       0x02, 0x92, 0x08, 0xe4, 0x2c, 0x15, 0xe1, 0x99, 0x8e, 0xac, 0x9c, 0xaa,
-       0xf5, 0x87, 0x2f, 0x6b, 0x69, 0x75, 0xf6, 0x23, 0x36, 0xc0, 0xf3, 0x2c,
-       0xbd, 0x52, 0x5b, 0x90, 0x88, 0x91, 0x78, 0x52, 0x9c, 0x9a, 0x8b, 0xd9,
-       0xe7, 0x34, 0x9e, 0x69, 0xb1, 0xa5, 0xb6, 0xb6, 0x8f, 0x89, 0xdc, 0x57,
-       0xbe, 0xe3, 0xf5, 0x49, 0xab, 0x3e, 0x7f, 0xdd, 0xc3, 0x3d, 0xb4, 0x9a,
-       0xd3, 0x03, 0x1e, 0xc8, 0xdb, 0xc3, 0xad, 0xe3, 0x46, 0xee, 0x8e, 0xcb,
-       0x31, 0x91, 0xcd, 0x6c, 0xb1, 0x31, 0xee, 0x4d, 0x3c, 0xf3, 0x24, 0xf8,
-       0xb8, 0x63, 0xe8, 0xd6, 0x93, 0x52, 0xa8, 0xad, 0x1f, 0xa3, 0x95, 0x07,
-       0x3e, 0x43, 0xfa, 0x1c, 0xe7, 0x00, 0xf8, 0xbb, 0xa3, 0xe9, 0xd6, 0x01,
-       0xc8, 0xd2, 0x1d, 0xc3, 0x38, 0x13, 0x35, 0x7f, 0x2a, 0x03, 0xa2, 0x9f,
-       0xd3, 0x94, 0xfc, 0xf5, 0xca, 0x30, 0x16, 0x48, 0x46, 0xba, 0x96, 0x26,
-       0xc5, 0x58, 0x62, 0x0d, 0xe1, 0xb5, 0xce, 0xb4, 0xda, 0xbf, 0xdd, 0x84,
-       0xf5, 0x2d, 0x76, 0xc0, 0x62, 0xbd, 0x80, 0xf5, 0xe0, 0x9f, 0x6e, 0x96,
-       0x1e, 0xd6, 0x0b, 0x98, 0x37, 0xec, 0xc7, 0x37, 0x73, 0x87, 0x4b, 0x4d,
-       0xe4, 0x7a, 0x9b, 0x19, 0x5f, 0x73, 0x35, 0xde, 0x8f, 0x46, 0x44, 0x78,
-       0x8f, 0x7e, 0xa3, 0x57, 0xda, 0xbe, 0x35, 0x08, 0x5f, 0xf1, 0x34, 0xb0,
-       0x37, 0xe8, 0x9e, 0x1c, 0x90, 0x80, 0x7b, 0x66, 0x42, 0xd5, 0x5b, 0xde,
-       0x58, 0x88, 0x7a, 0xef, 0x73, 0xc9, 0xb6, 0xcb, 0x71, 0xd6, 0x44, 0xfb,
-       0x58, 0xf3, 0x41, 0x3f, 0xd1, 0x97, 0x91, 0x9f, 0x5e, 0xaf, 0x59, 0x9b,
-       0x79, 0x7e, 0xf3, 0x86, 0x83, 0x6b, 0x62, 0xff, 0x90, 0xc2, 0x98, 0xde,
-       0x3d, 0xfe, 0x46, 0xbe, 0xf4, 0x8e, 0x77, 0x13, 0x98, 0x4f, 0x4d, 0x7a,
-       0x67, 0xe7, 0x1a, 0x99, 0xa3, 0x6b, 0x72, 0xaa, 0x41, 0x55, 0xef, 0x6d,
-       0x38, 0x16, 0xfc, 0xe3, 0x08, 0xec, 0x93, 0x6b, 0xa0, 0xa9, 0x3d, 0x01,
-       0x6c, 0x16, 0xe9, 0x55, 0x39, 0xd1, 0xf1, 0x27, 0xc4, 0xb5, 0x77, 0x58,
-       0x99, 0xf2, 0x65, 0x8d, 0xb2, 0x9b, 0x83, 0x2c, 0x97, 0x33, 0xf2, 0x47,
-       0xce, 0x15, 0x55, 0x6b, 0x9d, 0x47, 0x5e, 0x12, 0x38, 0xa5, 0x72, 0xb2,
-       0x16, 0x7c, 0x0b, 0xbf, 0xf7, 0xe2, 0xd7, 0xb1, 0x16, 0xa3, 0xea, 0x8c,
-       0x82, 0x7e, 0xae, 0xd9, 0x4c, 0xc1, 0x7f, 0xe8, 0x96, 0x65, 0x16, 0x10,
-       0x0f, 0x53, 0xea, 0x9c, 0x0b, 0xd7, 0xf1, 0x6f, 0x2b, 0xff, 0x2c, 0x15,
-       0xc8, 0xe6, 0x4c, 0x04, 0x74, 0x34, 0x65, 0x9f, 0x86, 0xd2, 0xc3, 0x13,
-       0x0a, 0xf3, 0x1a, 0xe7, 0xe0, 0xb0, 0x96, 0x06, 0x44, 0xce, 0x65, 0x64,
-       0x0e, 0x6b, 0x38, 0xb0, 0x44, 0x1d, 0x50, 0xb6, 0x93, 0xd2, 0x06, 0xd9,
-       0x1f, 0x01, 0xf6, 0x30, 0x4e, 0x51, 0xc6, 0x61, 0xac, 0x8b, 0x5e, 0x09,
-       0x9c, 0x81, 0x8c, 0x4f, 0x01, 0x23, 0x2c, 0xb4, 0xcb, 0xf7, 0x6a, 0xbe,
-       0x4c, 0x2f, 0xf1, 0x5c, 0xbf, 0x3e, 0x35, 0xd2, 0x47, 0x1c, 0x25, 0xd5,
-       0xda, 0x9c, 0xcc, 0x9d, 0x66, 0xce, 0x3e, 0xa9, 0xce, 0x0c, 0x04, 0xd4,
-       0x99, 0x15, 0x37, 0x67, 0x76, 0xbf, 0x5d, 0x8c, 0x59, 0x15, 0xee, 0xb5,
-       0x09, 0x6c, 0x67, 0x18, 0xe3, 0x6e, 0x24, 0x5f, 0x37, 0x57, 0x1d, 0x07,
-       0xbf, 0x97, 0xe7, 0xa3, 0x99, 0xbc, 0xc4, 0x79, 0x76, 0x7a, 0xc2, 0xc6,
-       0xfc, 0x97, 0xe1, 0x3f, 0xe7, 0x4a, 0x3c, 0x27, 0x5d, 0xc0, 0x0a, 0xcb,
-       0xc8, 0xe5, 0x22, 0x73, 0xc6, 0x8f, 0x43, 0x6f, 0xbc, 0x2e, 0x8c, 0x1a,
-       0xf0, 0x03, 0x2b, 0xea, 0xdd, 0xcf, 0xa8, 0xdd, 0x40, 0x0e, 0x1b, 0xd1,
-       0xf6, 0x43, 0xd7, 0x79, 0xb3, 0xcd, 0xb3, 0x07, 0x9e, 0xc5, 0x3f, 0x0b,
-       0x3f, 0x7a, 0x5e, 0xf8, 0x4e, 0xd6, 0xed, 0x26, 0xf3, 0xa5, 0xab, 0xf0,
-       0x7b, 0x99, 0x58, 0x06, 0x36, 0x94, 0x0f, 0x77, 0x80, 0xe7, 0xdf, 0xc4,
-       0xbd, 0x9c, 0xc3, 0x71, 0xa2, 0xf1, 0x15, 0x29, 0x44, 0x02, 0x32, 0x14,
-       0xb9, 0x22, 0x9b, 0xe1, 0xc9, 0x34, 0x79, 0xdd, 0x8a, 0x8e, 0x8a, 0xa6,
-       0xe8, 0x0d, 0xee, 0x86, 0x0d, 0xde, 0x84, 0xbf, 0x6b, 0xf7, 0x72, 0xfd,
-       0x54, 0x91, 0x18, 0xea, 0x59, 0x75, 0xb6, 0xe0, 0xaa, 0xc5, 0x3a, 0x20,
-       0xdf, 0xc5, 0xfe, 0x1f, 0x6a, 0x8c, 0xbb, 0x7b, 0x77, 0xac, 0x43, 0x93,
-       0x3f, 0x77, 0x8e, 0xbb, 0x2c, 0x97, 0x47, 0xd2, 0x69, 0x6b, 0xa1, 0x73,
-       0xd9, 0xa3, 0x73, 0xd6, 0xa3, 0x53, 0xf1, 0xe8, 0x5c, 0x5d, 0xa5, 0xb3,
-       0x07, 0x76, 0xd0, 0x6c, 0x9e, 0x00, 0xde, 0x48, 0xc6, 0x9b, 0xcd, 0x34,
-       0xf2, 0xb2, 0xd9, 0xe1, 0x69, 0xb5, 0xe7, 0xaa, 0x27, 0x46, 0xc7, 0x93,
-       0x96, 0x2b, 0x7f, 0x58, 0x81, 0x4c, 0xc3, 0x1e, 0xf3, 0xe2, 0x62, 0x75,
-       0xee, 0x07, 0xba, 0xfb, 0x85, 0x5d, 0xf0, 0x03, 0x4f, 0x23, 0x96, 0x5c,
-       0x1c, 0x3f, 0x6f, 0x49, 0x7e, 0xdb, 0x27, 0x75, 0xd8, 0x7b, 0x0f, 0xdf,
-       0x27, 0x35, 0xa5, 0xeb, 0xe2, 0x78, 0xb5, 0xf6, 0x34, 0xf2, 0x23, 0xf6,
-       0xdf, 0x4e, 0x0c, 0xb6, 0xab, 0x52, 0x8b, 0xec, 0x3a, 0xcb, 0xfd, 0x21,
-       0xf4, 0xab, 0xd4, 0xba, 0x21, 0xf7, 0x6e, 0x55, 0x57, 0xb9, 0x52, 0x0c,
-       0x41, 0x8f, 0x26, 0x6c, 0x3e, 0x84, 0xb6, 0x30, 0xec, 0xa0, 0x0f, 0xed,
-       0x3f, 0xc7, 0xda, 0x8e, 0xa0, 0x7d, 0xa5, 0x73, 0x5c, 0xe1, 0x58, 0x4b,
-       0xce, 0x39, 0x37, 0x11, 0x73, 0xdf, 0x84, 0x1f, 0x1d, 0x44, 0x9f, 0x61,
-       0xf4, 0xf9, 0x14, 0xc6, 0xe1, 0x3b, 0xcd, 0x1b, 0xf1, 0xd4, 0x00, 0x4f,
-       0x7a, 0x0b, 0x4f, 0x0d, 0xf0, 0x03, 0xdf, 0x79, 0x92, 0x35, 0xe8, 0x61,
-       0x39, 0x5a, 0xe4, 0x19, 0x29, 0xbe, 0x17, 0x6f, 0x4a, 0x00, 0x98, 0xb4,
-       0xed, 0x64, 0x34, 0xdc, 0x50, 0xb5, 0x1e, 0xda, 0xd6, 0x50, 0xbc, 0x2a,
-       0x2a, 0xce, 0x44, 0x8e, 0x22, 0x7e, 0xdd, 0x74, 0xba, 0xe5, 0x75, 0x6f,
-       0xac, 0x15, 0xe1, 0xfe, 0xe5, 0xda, 0xb1, 0x8e, 0x95, 0xae, 0x8d, 0xbf,
-       0x6a, 0x19, 0xde, 0xbc, 0x7a, 0x31, 0xd6, 0xaf, 0xa2, 0xef, 0xb5, 0xf1,
-       0xcb, 0xb5, 0x8d, 0xfa, 0xde, 0x44, 0xdf, 0xb6, 0x96, 0xbe, 0x37, 0xd1,
-       0xaf, 0x1b, 0x71, 0xb0, 0x5b, 0xcd, 0x69, 0x16, 0x7c, 0x5d, 0x2f, 0xaa,
-       0xf7, 0xb4, 0x21, 0x77, 0x8e, 0x69, 0x12, 0x53, 0x67, 0xdc, 0x5a, 0x49,
-       0xd4, 0x8c, 0x68, 0xef, 0xa8, 0xf7, 0x28, 0x1b, 0x18, 0xb3, 0x80, 0x7b,
-       0xe7, 0x27, 0xb4, 0x54, 0x35, 0x87, 0x98, 0xf5, 0x30, 0xf1, 0x53, 0xdc,
-       0x46, 0xcc, 0xac, 0x80, 0x5e, 0xad, 0xd8, 0xe0, 0x79, 0x6a, 0xd8, 0xc5,
-       0x2d, 0xe2, 0xec, 0x87, 0x0d, 0x75, 0xae, 0x21, 0xad, 0x6a, 0x76, 0x95,
-       0xa2, 0x98, 0xc9, 0x11, 0x9e, 0x65, 0xf8, 0x0c, 0xd6, 0xe5, 0x57, 0xd0,
-       0x96, 0x44, 0x7c, 0x3c, 0xa0, 0x25, 0xcf, 0x8f, 0xe3, 0xfa, 0x49, 0x5c,
-       0xc3, 0x1f, 0x2f, 0x64, 0x71, 0xff, 0x49, 0x5c, 0x4f, 0x6b, 0xa9, 0x7a,
-       0x16, 0xd7, 0x4f, 0xe1, 0x7a, 0xca, 0x64, 0x9e, 0xf2, 0xaa, 0x95, 0xd1,
-       0x6c, 0xd0, 0xb2, 0xcf, 0x8f, 0xe3, 0xd3, 0x4a, 0x8f, 0xf7, 0xa0, 0xa7,
-       0x22, 0xf7, 0xda, 0x62, 0xe0, 0x69, 0x9f, 0x96, 0xae, 0x76, 0x81, 0xc6,
-       0x00, 0x9e, 0xa7, 0x4d, 0xed, 0xf7, 0xc6, 0x67, 0xcd, 0xe9, 0x63, 0xaa,
-       0xe6, 0x64, 0x24, 0x32, 0xc0, 0xc9, 0x87, 0x91, 0x07, 0x68, 0x92, 0xb6,
-       0x9e, 0x93, 0x42, 0x1c, 0x7e, 0xa5, 0x6a, 0x48, 0x2a, 0x94, 0xc7, 0xef,
-       0xbc, 0x24, 0x47, 0x71, 0xbf, 0x4a, 0x5b, 0x60, 0xbf, 0x3f, 0x95, 0x42,
-       0x99, 0xb8, 0x9f, 0x75, 0x26, 0xd6, 0xa6, 0x58, 0x5f, 0xca, 0x41, 0x06,
-       0x21, 0xda, 0xef, 0x06, 0x35, 0x31, 0xf7, 0x8c, 0x34, 0xe2, 0xb2, 0x96,
-       0xac, 0x72, 0xdf, 0xaf, 0x91, 0xb9, 0x6c, 0xf1, 0xfd, 0xb1, 0x69, 0xee,
-       0x23, 0x16, 0x8c, 0x04, 0xeb, 0x23, 0xaa, 0xbe, 0x1e, 0x77, 0xf7, 0x07,
-       0x5b, 0xcf, 0xa4, 0xf8, 0xeb, 0x85, 0xe3, 0x7e, 0x0d, 0xcf, 0xbb, 0xf5,
-       0xac, 0x54, 0xfd, 0x9d, 0xba, 0xe0, 0x3b, 0x00, 0xe7, 0xa0, 0x8b, 0xcb,
-       0x2a, 0x37, 0xe6, 0x1e, 0xee, 0xbb, 0xe5, 0x54, 0xc8, 0x61, 0x8a, 0xac,
-       0x91, 0xf9, 0xfb, 0x76, 0xbe, 0x1c, 0xd7, 0xf3, 0x4a, 0x3e, 0x67, 0x40,
-       0x53, 0xe2, 0xf4, 0xbb, 0xd9, 0x10, 0xf7, 0xdf, 0xf8, 0x8c, 0x7c, 0xf3,
-       0x2e, 0xdf, 0xe4, 0x99, 0xf2, 0x38, 0x0c, 0xff, 0xc9, 0xf7, 0x2b, 0x9e,
-       0x93, 0x5c, 0x9c, 0x35, 0x1e, 0x03, 0xb1, 0x31, 0x8f, 0xdf, 0x77, 0xe5,
-       0x37, 0xeb, 0xc9, 0x2f, 0x57, 0xfe, 0x2f, 0x4a, 0x87, 0x15, 0x8b, 0xe3,
-       0xf9, 0xb5, 0x8f, 0xbd, 0x4a, 0x77, 0x15, 0x75, 0x7e, 0xd7, 0x97, 0x81,
-       0x5f, 0xbf, 0xdb, 0xd8, 0xf6, 0xc6, 0x2d, 0xf2, 0xf6, 0x10, 0xcf, 0x43,
-       0x0c, 0xda, 0x42, 0xfe, 0x39, 0x0f, 0xc6, 0x30, 0x7f, 0xaf, 0xd5, 0x9f,
-       0x83, 0x3f, 0xcf, 0xfb, 0x95, 0x0f, 0xf9, 0xfd, 0xe4, 0x16, 0xe9, 0xca,
-       0x98, 0x86, 0xc5, 0xd8, 0xf0, 0xb8, 0xb7, 0x3f, 0xf0, 0x7f, 0x43, 0xce,
-       0xae, 0x2c, 0x02, 0x09, 0x99, 0xf5, 0xde, 0xbf, 0xde, 0xc0, 0x1e, 0xd6,
-       0xef, 0x35, 0x37, 0x32, 0x67, 0xad, 0xbb, 0xf3, 0xae, 0x6c, 0x30, 0xef,
-       0x8a, 0x37, 0xef, 0xea, 0x7d, 0xf2, 0x5b, 0x99, 0xb7, 0x31, 0x67, 0xda,
-       0xdc, 0x46, 0xf6, 0x28, 0xea, 0xdd, 0xb0, 0x15, 0x23, 0x18, 0xb4, 0x9d,
-       0x7b, 0xd5, 0x50, 0x99, 0x57, 0xbb, 0x76, 0x79, 0x16, 0xb1, 0xb0, 0x5c,
-       0x76, 0x73, 0xec, 0xb2, 0xc3, 0x5a, 0xf6, 0xbb, 0xf1, 0xc0, 0x77, 0xb9,
-       0xbe, 0xa8, 0xce, 0xbb, 0xcc, 0x3a, 0x6e, 0xdd, 0xab, 0x5c, 0x6e, 0x8d,
-       0xa9, 0x0f, 0x32, 0x9e, 0x0e, 0xe6, 0x65, 0x82, 0xef, 0x94, 0xe3, 0xfa,
-       0x11, 0xb9, 0xb2, 0xa0, 0xf6, 0xac, 0xbc, 0xbd, 0x21, 0xee, 0xf9, 0xa8,
-       0xfd, 0x6f, 0xf8, 0xb5, 0x49, 0xe5, 0xd7, 0x97, 0x17, 0xd4, 0x3d, 0x17,
-       0x2b, 0x39, 0x13, 0xf0, 0xfb, 0xc8, 0x25, 0xac, 0x07, 0xa4, 0x80, 0x9c,
-       0xfb, 0xac, 0x75, 0x78, 0x0b, 0x71, 0x0e, 0x69, 0x2d, 0x83, 0xd6, 0xe5,
-       0x05, 0xd9, 0xc2, 0x33, 0x25, 0x65, 0xb5, 0xcf, 0xe6, 0xd6, 0xc5, 0xa7,
-       0xc5, 0xff, 0x7f, 0x1d, 0x41, 0x2f, 0x16, 0xf2, 0x5c, 0x0b, 0xdf, 0x73,
-       0xa6, 0xaf, 0x40, 0x1e, 0x34, 0xc1, 0x7d, 0x9c, 0x66, 0xd3, 0xad, 0x9b,
-       0x37, 0xb1, 0x2e, 0xda, 0xf8, 0x0e, 0x05, 0xfe, 0x0e, 0xc3, 0x7e, 0xb0,
-       0x4e, 0x56, 0xdb, 0x79, 0xcd, 0xdc, 0xc3, 0xbf, 0x66, 0x60, 0xfb, 0x3f,
-       0xe8, 0xf3, 0x49, 0x14, 0x38, 0x46, 0x00, 0x00, 0x00 };
+       0xbd, 0x7c, 0x7d, 0x70, 0x1c, 0xe7, 0x79, 0xdf, 0xb3, 0xbb, 0x07, 0xe0,
+       0x00, 0x82, 0xe0, 0x12, 0x39, 0x52, 0x27, 0x0a, 0xa6, 0x6e, 0x89, 0x3d,
+       0x08, 0x32, 0x20, 0x71, 0xc5, 0x20, 0x36, 0x26, 0xb9, 0xca, 0xab, 0xbb,
+       0x03, 0x78, 0x94, 0x31, 0x31, 0xc4, 0xc2, 0x16, 0xed, 0x70, 0xd4, 0xeb,
+       0x01, 0xa4, 0x95, 0x54, 0x9e, 0xb2, 0xb6, 0xda, 0x72, 0x5a, 0x35, 0x3a,
+       0x1f, 0xc0, 0x0f, 0x29, 0x47, 0x1c, 0x24, 0xc0, 0x84, 0xfe, 0x70, 0x93,
+       0x13, 0x0e, 0x24, 0x64, 0xf7, 0x88, 0x93, 0xfc, 0xd9, 0x3f, 0x62, 0x0b,
+       0x03, 0xd2, 0xb4, 0x5a, 0xbb, 0xb5, 0xda, 0x28, 0x13, 0xcf, 0xf4, 0x63,
+       0x30, 0x14, 0xa5, 0x28, 0x71, 0xa7, 0x56, 0x9b, 0x4c, 0xa2, 0x36, 0x94,
+       0xaf, 0xbf, 0xdf, 0xbb, 0xbb, 0xe0, 0x01, 0x22, 0x65, 0x51, 0x93, 0x14,
+       0x33, 0x37, 0x77, 0xfb, 0xee, 0xbb, 0xef, 0xfb, 0x7c, 0xbd, 0xcf, 0xf3,
+       0xfc, 0x9e, 0xf7, 0x5d, 0x44, 0x45, 0xda, 0xc4, 0xff, 0xdb, 0x8a, 0x4f,
+       0xec, 0xd8, 0xf1, 0xc7, 0xef, 0xfd, 0xf8, 0xbd, 0xbf, 0x8a, 0x9f, 0xf7,
+       0x89, 0xd6, 0x62, 0xf0, 0xe6, 0x5b, 0x86, 0x48, 0xf6, 0xcf, 0xe5, 0x43,
+       0xff, 0xe1, 0x71, 0x33, 0x18, 0x9f, 0x1f, 0x09, 0xeb, 0x89, 0x57, 0x87,
+       0x93, 0xb6, 0x84, 0x8d, 0x44, 0xfe, 0xa1, 0x71, 0x5b, 0xc4, 0xad, 0xf6,
+       0xc5, 0x52, 0xf2, 0x6e, 0x3d, 0x1f, 0x09, 0x09, 0xdb, 0x3f, 0x92, 0xb8,
+       0xf6, 0xe4, 0xf7, 0x3e, 0x6e, 0xbd, 0x5d, 0x36, 0x24, 0x6c, 0x26, 0xb2,
+       0x62, 0xf6, 0x48, 0xb8, 0x0b, 0xcf, 0x7c, 0xf5, 0xae, 0x47, 0x0d, 0xe9,
+       0x08, 0xc6, 0x7a, 0xab, 0xfe, 0xbd, 0xbb, 0x24, 0xbf, 0x2b, 0x51, 0x8f,
+       0x85, 0x12, 0xef, 0xd6, 0xa7, 0x06, 0xc2, 0xa2, 0x27, 0xac, 0x68, 0xd2,
+       0x88, 0xc8, 0xcb, 0x35, 0x53, 0x5e, 0xac, 0xc5, 0x64, 0xb2, 0x26, 0x1d,
+       0xe9, 0xda, 0x8d, 0x68, 0xaa, 0xa3, 0xef, 0xbb, 0xf5, 0xe4, 0x40, 0x28,
+       0x6b, 0x24, 0xa4, 0x23, 0x59, 0x93, 0xd1, 0x63, 0xc5, 0xd6, 0x87, 0x9b,
+       0x12, 0x4f, 0xd6, 0x75, 0x5b, 0xb2, 0xa1, 0x84, 0x9d, 0xd7, 0xf5, 0xf6,
+       0x41, 0xf3, 0x63, 0x68, 0xaf, 0x0e, 0x86, 0x26, 0x8b, 0xa6, 0x9c, 0x1b,
+       0x68, 0x15, 0xdd, 0x0e, 0x4b, 0xb2, 0xd6, 0xfa, 0xb0, 0x9e, 0x88, 0x88,
+       0x5b, 0xab, 0xd7, 0x8f, 0x39, 0xff, 0x64, 0xaf, 0xf9, 0xeb, 0xe1, 0xf0,
+       0x64, 0x51, 0xde, 0x0e, 0xd9, 0x76, 0x74, 0x42, 0x7a, 0xcc, 0x9c, 0x68,
+       0x92, 0xec, 0xef, 0x89, 0x1e, 0xc1, 0xf7, 0x78, 0x7f, 0xdc, 0x4c, 0xc9,
+       0x16, 0x71, 0xcd, 0x6f, 0xae, 0x98, 0x3d, 0x5d, 0x59, 0x3d, 0x11, 0x96,
+       0x74, 0x51, 0x13, 0xc3, 0x8e, 0xc8, 0x64, 0xc5, 0x96, 0xfc, 0x52, 0x87,
+       0xe4, 0x2b, 0xf2, 0xc4, 0x94, 0xd3, 0x2e, 0x53, 0x4b, 0x47, 0x7d, 0x5d,
+       0x44, 0xd0, 0xd6, 0x2b, 0xf9, 0x5a, 0x14, 0x9f, 0x9f, 0xf8, 0xfc, 0xea,
+       0x22, 0x3b, 0x05, 0xcf, 0xf7, 0xa7, 0xdd, 0xea, 0xd7, 0xc2, 0x5e, 0xdb,
+       0x7f, 0xd9, 0xe2, 0x7d, 0x83, 0xdf, 0x12, 0xf8, 0x2d, 0x85, 0x65, 0xcd,
+       0x88, 0xca, 0xf7, 0xee, 0x8a, 0xc9, 0x54, 0x69, 0x0d, 0xb2, 0x89, 0xca,
+       0x37, 0x6a, 0x11, 0x79, 0x49, 0xc9, 0x22, 0xa4, 0x0d, 0xa3, 0xcf, 0x64,
+       0x69, 0x42, 0x3f, 0x51, 0xcc, 0x4b, 0xaa, 0x96, 0xd5, 0x0b, 0x73, 0x66,
+       0x47, 0x72, 0x29, 0xa7, 0x4f, 0xce, 0x75, 0x76, 0xa4, 0x96, 0x26, 0xf4,
+       0x42, 0x31, 0x0a, 0x39, 0x98, 0x1d, 0xa9, 0xf9, 0x08, 0xae, 0x3b, 0x3b,
+       0x92, 0xf3, 0xd6, 0x0c, 0x26, 0x45, 0x9f, 0x68, 0x47, 0xaa, 0x64, 0x65,
+       0x45, 0xba, 0x9d, 0x1f, 0x48, 0x57, 0x47, 0xaa, 0xf6, 0x5b, 0xfa, 0x8a,
+       0xa9, 0x49, 0xe1, 0x1e, 0x31, 0xa3, 0x89, 0xb7, 0xeb, 0xb7, 0xdb, 0x9a,
+       0x98, 0xf6, 0x3b, 0xf5, 0xed, 0x90, 0x4d, 0x6e, 0xb6, 0x15, 0xbc, 0x92,
+       0x26, 0x53, 0x72, 0xf3, 0x7d, 0xe6, 0xaa, 0x34, 0x89, 0x1b, 0x09, 0xae,
+       0xeb, 0xf5, 0xa4, 0xf3, 0x07, 0xe4, 0x91, 0xf2, 0xee, 0x18, 0x86, 0x5e,
+       0x92, 0xa0, 0x39, 0xe9, 0xbc, 0x5b, 0xf7, 0x9e, 0x09, 0x63, 0xce, 0x50,
+       0xc7, 0x50, 0xa9, 0x5e, 0x4f, 0x3b, 0x18, 0xdf, 0x09, 0x9e, 0x6d, 0x92,
+       0x72, 0xc4, 0x2d, 0x4f, 0x3a, 0x96, 0xe1, 0xc9, 0x87, 0xba, 0xe7, 0xb5,
+       0x0b, 0x7d, 0xe4, 0x25, 0x17, 0x91, 0x72, 0xc1, 0xf9, 0x98, 0x3c, 0xe5,
+       0x44, 0xc1, 0x5f, 0x58, 0x4e, 0x39, 0xb0, 0x2f, 0xfb, 0xb8, 0x96, 0xac,
+       0x59, 0xb1, 0xac, 0x3c, 0x2d, 0xc9, 0xf9, 0x6e, 0x33, 0x2d, 0x98, 0xdb,
+       0xae, 0xdf, 0x99, 0x74, 0x30, 0x5f, 0xff, 0xff, 0xad, 0xbb, 0x11, 0x2b,
+       0x5b, 0x96, 0x5e, 0x29, 0x94, 0xba, 0x9d, 0x1f, 0x43, 0x4f, 0x61, 0x5b,
+       0xdc, 0x71, 0xdb, 0x84, 0xdc, 0xac, 0xde, 0x94, 0x51, 0x97, 0x07, 0x31,
+       0x7f, 0xd2, 0xc6, 0xfd, 0x9a, 0x6c, 0xd3, 0xed, 0x66, 0x29, 0x98, 0x12,
+       0x69, 0x93, 0xdd, 0x52, 0x98, 0x45, 0xbb, 0xe3, 0x76, 0xea, 0x78, 0x26,
+       0x33, 0xc0, 0x36, 0xd1, 0x8c, 0x04, 0x75, 0x2c, 0xb2, 0x50, 0xed, 0xc5,
+       0xfc, 0x71, 0xb7, 0x55, 0x33, 0x65, 0xcd, 0x0c, 0x49, 0xa5, 0x1a, 0x77,
+       0xa3, 0x5a, 0xb3, 0x9c, 0x8a, 0xb7, 0x41, 0xa6, 0x51, 0x8c, 0x2d, 0x5f,
+       0xd6, 0x13, 0xf1, 0x68, 0x0e, 0x4a, 0xa3, 0x1d, 0x4d, 0x81, 0x9e, 0x29,
+       0x27, 0xab, 0xa5, 0x6a, 0x9f, 0xd3, 0x92, 0x4b, 0x87, 0xb4, 0xfd, 0x4b,
+       0xe8, 0x53, 0xfb, 0x1f, 0xbe, 0x0d, 0x44, 0x41, 0x9b, 0x8e, 0x67, 0xd9,
+       0x0e, 0x9a, 0x15, 0xed, 0x68, 0x83, 0x2e, 0x57, 0xc6, 0x22, 0x1d, 0x49,
+       0xa5, 0x4b, 0xd2, 0xa6, 0x4b, 0x6e, 0x54, 0x93, 0x4e, 0xdb, 0x95, 0xf0,
+       0xaf, 0x41, 0x9f, 0xf3, 0xd0, 0xe5, 0x7c, 0x4c, 0x4e, 0x94, 0x24, 0xa2,
+       0x0b, 0xe7, 0xca, 0xea, 0x95, 0x2a, 0xed, 0x01, 0xba, 0x85, 0xee, 0x0b,
+       0x55, 0x3e, 0x0b, 0x1d, 0x96, 0xd2, 0x90, 0x4f, 0x06, 0x73, 0x1f, 0xd4,
+       0x1e, 0xac, 0x8c, 0x69, 0x19, 0xd8, 0x49, 0x61, 0xb6, 0x0f, 0xba, 0xb3,
+       0x62, 0x6b, 0xb2, 0x4d, 0x0a, 0xb6, 0x1d, 0xfb, 0xac, 0xb4, 0xcb, 0xa9,
+       0x79, 0x5b, 0x4e, 0xcc, 0xc3, 0x1e, 0x4d, 0xcb, 0x5c, 0x94, 0xae, 0xec,
+       0x96, 0x44, 0x87, 0x3c, 0x3d, 0x6b, 0x65, 0xca, 0xd2, 0xed, 0xbe, 0x81,
+       0xfb, 0xb9, 0x33, 0xd4, 0xa9, 0xe4, 0x53, 0x8e, 0x21, 0x59, 0x93, 0x76,
+       0x7d, 0x9b, 0x26, 0x6d, 0xf5, 0x27, 0x93, 0x8e, 0x15, 0xa5, 0xcd, 0xa6,
+       0x3e, 0xdd, 0x6d, 0x1e, 0x10, 0xcb, 0xcc, 0x50, 0xfe, 0x4e, 0x1f, 0xf4,
+       0xf0, 0xbf, 0x29, 0x7b, 0x8c, 0x45, 0x1d, 0xf7, 0x45, 0x4f, 0x41, 0x97,
+       0x59, 0xa5, 0xe3, 0x0e, 0xcc, 0x1f, 0xf2, 0x6d, 0x87, 0x6b, 0xe2, 0x6e,
+       0xcd, 0x93, 0x43, 0x87, 0xcc, 0x54, 0xda, 0xa5, 0x00, 0x1d, 0x16, 0xc4,
+       0x96, 0xc2, 0xd2, 0x5e, 0xbf, 0xdd, 0xc6, 0x7a, 0xf9, 0x53, 0x5d, 0xda,
+       0x8e, 0x6b, 0x87, 0x6a, 0x3f, 0xd7, 0x7c, 0xfb, 0x81, 0xfd, 0x85, 0xc5,
+       0x1d, 0x0d, 0xcb, 0xf9, 0x9a, 0x67, 0x7f, 0x0b, 0xf0, 0x3d, 0xae, 0xe9,
+       0xc2, 0x96, 0xde, 0x5c, 0xef, 0x73, 0xbe, 0xd6, 0x85, 0x67, 0xc3, 0x72,
+       0xa2, 0xc6, 0xfe, 0x79, 0xd8, 0x58, 0x58, 0x96, 0xef, 0x6a, 0x97, 0x2c,
+       0xda, 0x0b, 0xf3, 0xe2, 0x26, 0x1d, 0x1d, 0xcf, 0x74, 0x80, 0x97, 0x9d,
+       0xf8, 0xb4, 0xc9, 0x78, 0xa5, 0xc5, 0xe5, 0x7a, 0x1d, 0xaf, 0x51, 0xff,
+       0xf8, 0x2e, 0x05, 0x36, 0x40, 0xf9, 0xb2, 0x9d, 0xcf, 0xb1, 0xdd, 0x44,
+       0x7b, 0x63, 0x1b, 0x6d, 0x7b, 0x1b, 0x65, 0xda, 0xcb, 0x35, 0x9a, 0x2b,
+       0xc5, 0xcd, 0x43, 0xfc, 0xae, 0xd1, 0x1e, 0x1a, 0x6d, 0x21, 0x84, 0xfe,
+       0xd0, 0x63, 0x05, 0x73, 0xcd, 0x5e, 0xab, 0x37, 0x0d, 0xe0, 0xda, 0xfe,
+       0x1d, 0xf0, 0xc9, 0xb9, 0x43, 0xa0, 0x4b, 0x97, 0x6c, 0x45, 0xd1, 0x16,
+       0xa3, 0x0d, 0x78, 0x7c, 0x74, 0xc9, 0xe4, 0x7c, 0x7b, 0x47, 0x7a, 0x9e,
+       0xed, 0xc9, 0xa8, 0x01, 0x3e, 0xc7, 0x1d, 0x59, 0x99, 0x72, 0xf4, 0xee,
+       0x10, 0xe8, 0x9a, 0xc0, 0x82, 0x03, 0x1f, 0x3e, 0x8d, 0x2b, 0xb8, 0xdf,
+       0x29, 0xe3, 0x4b, 0xec, 0xcb, 0x39, 0x0a, 0xdb, 0x75, 0x49, 0x80, 0x36,
+       0x7c, 0x6c, 0x0b, 0xf7, 0x5b, 0x31, 0x4f, 0x3b, 0x6c, 0x67, 0x9a, 0xba,
+       0xfb, 0x44, 0xd2, 0xe9, 0x94, 0xec, 0x7a, 0x5f, 0x81, 0xdd, 0xb1, 0x7f,
+       0xef, 0xa6, 0xbe, 0x90, 0xef, 0x12, 0xc6, 0x9c, 0x6f, 0x85, 0x0c, 0xd9,
+       0xae, 0x83, 0xe6, 0x16, 0xd0, 0x00, 0x1f, 0x6c, 0x77, 0x63, 0x3d, 0xb4,
+       0x60, 0xfc, 0x2d, 0xe0, 0xa9, 0x55, 0x26, 0x66, 0x3b, 0xa1, 0x0b, 0x13,
+       0x7d, 0xc3, 0xf2, 0x74, 0xc9, 0x82, 0x0d, 0xb0, 0x3f, 0x74, 0x30, 0x6f,
+       0x45, 0x2b, 0xe2, 0xca, 0x94, 0xd3, 0x02, 0xfb, 0xaa, 0xd7, 0x8f, 0xc0,
+       0x3e, 0xbe, 0xae, 0xfc, 0x45, 0x9f, 0x39, 0xa4, 0x49, 0xbe, 0x25, 0xf1,
+       0x7d, 0xd0, 0x63, 0x3d, 0x2a, 0xc2, 0xeb, 0xbd, 0x1a, 0xd7, 0x2c, 0xe4,
+       0xc8, 0xb9, 0xe1, 0x93, 0x76, 0x42, 0x86, 0xf4, 0x5b, 0x5d, 0xb0, 0xe7,
+       0xa8, 0xf2, 0x27, 0x43, 0x37, 0xf4, 0x27, 0xd6, 0x68, 0x19, 0x73, 0x15,
+       0x96, 0x42, 0xf4, 0x61, 0x83, 0x58, 0xae, 0xb2, 0x15, 0x6b, 0x6f, 0x52,
+       0xd9, 0xc7, 0x4f, 0xc8, 0x6f, 0xfd, 0x53, 0x0e, 0xe9, 0x22, 0xbf, 0x2e,
+       0x9e, 0xa5, 0x0d, 0x5a, 0xc7, 0x5d, 0x35, 0xff, 0x4f, 0xfc, 0xf9, 0x3d,
+       0xda, 0x0b, 0xa5, 0x0e, 0x2d, 0xa5, 0x68, 0x08, 0xc6, 0x11, 0x59, 0x3d,
+       0xd3, 0x6d, 0x3e, 0x08, 0x1b, 0xa6, 0x9f, 0x5a, 0xbd, 0x40, 0x1d, 0x63,
+       0x8c, 0x01, 0xea, 0xd8, 0x54, 0xf4, 0x25, 0xe7, 0xb9, 0xf6, 0xa4, 0xcb,
+       0x10, 0xfa, 0x08, 0xf8, 0x5c, 0xac, 0xc5, 0x49, 0x7f, 0x2d, 0xe6, 0xaa,
+       0xb4, 0xbf, 0xc7, 0xf1, 0xac, 0x2e, 0x43, 0x71, 0xfa, 0x87, 0xa7, 0x25,
+       0x05, 0x1f, 0x09, 0x3d, 0x4a, 0x05, 0xbc, 0x2c, 0x94, 0x1a, 0xfd, 0x16,
+       0x6c, 0xab, 0xff, 0xaf, 0xeb, 0x9e, 0x3f, 0xa4, 0x6f, 0xa0, 0xaf, 0x29,
+       0x98, 0x3a, 0x24, 0x87, 0xc8, 0xe0, 0x42, 0x37, 0x4e, 0xd2, 0xb0, 0x32,
+       0x59, 0xc6, 0x1c, 0xbb, 0x2e, 0xf6, 0x7d, 0x82, 0x48, 0xda, 0xcb, 0xf8,
+       0xb7, 0x2f, 0xf0, 0x4f, 0xab, 0xd5, 0x40, 0x17, 0xd4, 0x2b, 0xf5, 0x10,
+       0xf8, 0x88, 0x90, 0x5c, 0x84, 0xef, 0x9a, 0x2a, 0xb5, 0xcb, 0x0a, 0x68,
+       0xba, 0x54, 0x0d, 0x6c, 0xcd, 0xf0, 0x6d, 0x8d, 0xcf, 0xb4, 0xe3, 0xf9,
+       0x10, 0xfc, 0x9a, 0xe4, 0x8d, 0x04, 0x7e, 0x17, 0x39, 0x26, 0xdb, 0x02,
+       0x3b, 0xe7, 0x9a, 0xb1, 0xdc, 0xb2, 0x34, 0x4b, 0x26, 0x8e, 0xf8, 0x31,
+       0xaf, 0x63, 0xae, 0x2e, 0xf8, 0xf2, 0x90, 0x1c, 0x2d, 0x45, 0xe4, 0xf3,
+       0x25, 0xf2, 0x95, 0xd6, 0x52, 0xd0, 0x5b, 0x72, 0xbe, 0x0e, 0x9d, 0x0f,
+       0xc3, 0xe7, 0x65, 0xb4, 0x21, 0xf8, 0x9f, 0x03, 0x95, 0xcf, 0x69, 0xe9,
+       0xa5, 0xac, 0x36, 0x5c, 0x3b, 0xa4, 0x65, 0x96, 0xc6, 0xb4, 0xfd, 0x0d,
+       0xbe, 0x48, 0xb4, 0xf7, 0xf7, 0x45, 0x4f, 0xcd, 0x72, 0xce, 0x6e, 0xe7,
+       0xc6, 0xbe, 0xe8, 0xd7, 0xf5, 0x46, 0x5f, 0xd4, 0x0d, 0x5f, 0x94, 0x81,
+       0x2f, 0x1a, 0xbe, 0x65, 0x5f, 0x34, 0xa2, 0xdf, 0xd8, 0x17, 0x1d, 0xd4,
+       0xaf, 0xfb, 0x22, 0xc6, 0x9e, 0x15, 0x5c, 0x9b, 0xb2, 0x67, 0x5f, 0x20,
+       0xe7, 0x28, 0xfc, 0xf0, 0x16, 0xc8, 0xba, 0x8d, 0x6b, 0x27, 0x56, 0x80,
+       0xdd, 0x4f, 0x60, 0xae, 0xdf, 0x86, 0xbd, 0xef, 0x89, 0xdb, 0xe6, 0x43,
+       0x6a, 0xde, 0xf7, 0xea, 0x7c, 0x68, 0x5d, 0xe7, 0xa4, 0xf1, 0x97, 0xea,
+       0xdc, 0xf5, 0x74, 0x4e, 0x5d, 0xb7, 0xca, 0x11, 0x35, 0x6f, 0x5d, 0x42,
+       0xf7, 0x09, 0xbc, 0x8a, 0x3c, 0x60, 0x24, 0x2c, 0x8c, 0xa7, 0x63, 0x7e,
+       0xea, 0x2b, 0x0e, 0x1a, 0x04, 0xfa, 0x6d, 0x57, 0xbe, 0x68, 0x3f, 0xf4,
+       0xbe, 0x5a, 0xbd, 0x35, 0x5d, 0x65, 0x1a, 0x74, 0xf5, 0xe0, 0x06, 0x5d,
+       0xb5, 0x48, 0x7f, 0x3c, 0xd0, 0xd1, 0x36, 0x49, 0xc6, 0xa9, 0xb3, 0x5b,
+       0xd1, 0xd5, 0xb9, 0xbf, 0x25, 0x5d, 0x7d, 0xf7, 0x26, 0xba, 0xfa, 0xde,
+       0x26, 0x5d, 0xd9, 0xe6, 0x33, 0x1a, 0xc7, 0x66, 0xfc, 0xa0, 0x3f, 0xaa,
+       0xdf, 0x39, 0xce, 0xfc, 0xa1, 0xc6, 0x35, 0x1d, 0xe4, 0x1d, 0x5c, 0xcf,
+       0x2f, 0xd7, 0x0d, 0xdb, 0x86, 0xec, 0xb8, 0xa6, 0x29, 0x37, 0xcb, 0xfc,
+       0x14, 0xe9, 0x47, 0xec, 0x18, 0x47, 0xac, 0xf1, 0x68, 0x68, 0x96, 0xf2,
+       0x76, 0xaf, 0xff, 0x78, 0xa9, 0xfe, 0x73, 0x3d, 0xf1, 0x0b, 0xe4, 0x95,
+       0xb6, 0x1f, 0x07, 0xc2, 0xf2, 0x85, 0x8a, 0x95, 0x75, 0xb5, 0x76, 0xc9,
+       0xef, 0x40, 0xec, 0x29, 0xd1, 0x7f, 0xed, 0xbc, 0x49, 0x8c, 0xee, 0xf2,
+       0x63, 0xf4, 0x9f, 0x81, 0x56, 0xe6, 0x57, 0xff, 0xe6, 0xdd, 0x95, 0x08,
+       0xbf, 0xe3, 0xe6, 0x41, 0xf9, 0x2c, 0x79, 0x44, 0xbc, 0x67, 0xdc, 0xb7,
+       0x99, 0xf3, 0xe4, 0x43, 0x89, 0x36, 0xc9, 0x6f, 0xe7, 0x7a, 0xa4, 0x9f,
+       0xa3, 0xef, 0x6a, 0xf6, 0xe9, 0x0e, 0x72, 0x24, 0xfe, 0xb5, 0x18, 0x60,
+       0x19, 0x7d, 0x90, 0x0f, 0x95, 0xc8, 0xc7, 0xbb, 0xbe, 0x3d, 0x31, 0x57,
+       0x90, 0x26, 0xcf, 0x37, 0x8c, 0x20, 0x17, 0xa0, 0x1d, 0x04, 0x3a, 0xa7,
+       0xbe, 0x99, 0x23, 0x48, 0x4c, 0xb7, 0x99, 0x23, 0x88, 0x69, 0x24, 0x0e,
+       0x6a, 0x2e, 0x74, 0xef, 0x42, 0xf7, 0x2e, 0x74, 0xef, 0x42, 0xf7, 0xc9,
+       0xda, 0x71, 0xdc, 0x53, 0x79, 0x08, 0x68, 0xf1, 0xc6, 0x4f, 0x7b, 0xe3,
+       0x83, 0xce, 0x9d, 0x92, 0x53, 0x3a, 0x21, 0xbf, 0xc8, 0x35, 0x94, 0xbf,
+       0x1e, 0xd6, 0x3c, 0x7f, 0xcd, 0xf1, 0x32, 0x78, 0xfe, 0x7e, 0xe4, 0x73,
+       0xae, 0xae, 0xdb, 0xd7, 0x65, 0x32, 0xd5, 0x20, 0x93, 0xc9, 0x2a, 0x65,
+       0xc4, 0xfe, 0xf4, 0xb9, 0x13, 0xfa, 0xc2, 0xba, 0x5c, 0x46, 0x40, 0x43,
+       0x0b, 0x79, 0xf7, 0xf9, 0xe0, 0xf8, 0x9d, 0xfe, 0xf8, 0xbf, 0x81, 0x31,
+       0xe9, 0x5f, 0x6f, 0x34, 0x2f, 0xe7, 0x64, 0xce, 0xf8, 0x7e, 0xfc, 0x20,
+       0x67, 0xc6, 0x1a, 0x78, 0x69, 0x3d, 0x9f, 0x8e, 0x21, 0x9f, 0x7e, 0x07,
+       0xb9, 0x74, 0xbd, 0xce, 0x38, 0x55, 0x40, 0x9e, 0x9b, 0x76, 0xb8, 0xae,
+       0x6f, 0x65, 0xdd, 0x6e, 0x58, 0xb3, 0x66, 0xd2, 0xe0, 0xb8, 0x61, 0xf1,
+       0xc6, 0xe4, 0xfd, 0x16, 0xe4, 0x82, 0xef, 0xe0, 0x37, 0x7d, 0x72, 0x90,
+       0xe7, 0xb1, 0x0f, 0x9f, 0x7f, 0x15, 0x73, 0xf7, 0x03, 0xcf, 0xf4, 0xca,
+       0x77, 0x6a, 0xb6, 0x7c, 0x1b, 0x98, 0xe6, 0x5b, 0xc8, 0x2d, 0xbe, 0x59,
+       0x0b, 0x72, 0xfb, 0xbd, 0x30, 0x75, 0xe6, 0xf7, 0x12, 0xde, 0x69, 0x13,
+       0x57, 0xe5, 0xf7, 0x7f, 0xda, 0x96, 0xad, 0x11, 0xfc, 0xfe, 0x95, 0x84,
+       0x6c, 0xeb, 0xc4, 0xf7, 0xf6, 0x04, 0x4c, 0x27, 0xc1, 0xd8, 0xa8, 0x35,
+       0xc4, 0x46, 0xd1, 0xd2, 0xe0, 0x71, 0x0a, 0xe3, 0xa5, 0xc1, 0xf7, 0x67,
+       0x6a, 0x61, 0x2d, 0x35, 0xbb, 0x1b, 0x98, 0x24, 0xc8, 0x71, 0x91, 0x47,
+       0x99, 0xab, 0xdb, 0x43, 0xf2, 0x36, 0x78, 0x4a, 0x82, 0x76, 0x17, 0x39,
+       0xc0, 0x3f, 0xc5, 0x5c, 0xd6, 0x4f, 0x3f, 0x2d, 0xff, 0xda, 0xcf, 0xc3,
+       0x9b, 0x64, 0x4e, 0xf1, 0xc8, 0x76, 0xc9, 0xfc, 0xcb, 0x9e, 0xeb, 0xed,
+       0xcf, 0xae, 0xb7, 0xc7, 0x32, 0xbf, 0xb1, 0xde, 0x7e, 0x35, 0xe4, 0xe1,
+       0x95, 0x41, 0x6d, 0xb4, 0xf6, 0x2f, 0x8c, 0x00, 0xeb, 0x14, 0x66, 0x7b,
+       0x31, 0xd7, 0x36, 0x99, 0xb4, 0xdf, 0x06, 0xf6, 0xb2, 0x63, 0x39, 0xac,
+       0xaf, 0xa7, 0x36, 0xf9, 0xfa, 0x36, 0xf8, 0x8f, 0xd3, 0xb3, 0xd6, 0x20,
+       0xfd, 0x47, 0x1c, 0x6b, 0x29, 0xf9, 0x1e, 0xff, 0xf1, 0x6d, 0xa3, 0xd1,
+       0x7f, 0x18, 0xf0, 0x1f, 0xfb, 0xdf, 0xc7, 0x7f, 0x3c, 0xf5, 0x1e, 0xff,
+       0xa1, 0xc1, 0x2e, 0xe8, 0x3f, 0x7e, 0x68, 0x04, 0xfe, 0xa3, 0xb0, 0xc1,
+       0x7f, 0x04, 0xfa, 0xb0, 0x55, 0xee, 0xe8, 0xfd, 0x26, 0xfe, 0x6c, 0xf3,
+       0x31, 0xa7, 0x84, 0x43, 0x09, 0x37, 0x33, 0x65, 0xef, 0x92, 0x26, 0xac,
+       0xd1, 0x97, 0x6b, 0x03, 0xf0, 0x25, 0xbf, 0x0f, 0x9c, 0x66, 0x39, 0x4c,
+       0x44, 0x9a, 0x12, 0xd4, 0xcd, 0x48, 0x2c, 0x69, 0xbf, 0x90, 0x59, 0xa8,
+       0xbe, 0x90, 0x39, 0xa7, 0x74, 0x35, 0x61, 0x79, 0x18, 0xf8, 0x09, 0x0b,
+       0x18, 0x18, 0xcf, 0x87, 0x80, 0x21, 0xd8, 0xde, 0x6e, 0x26, 0x91, 0xa3,
+       0x54, 0xaa, 0x2b, 0x99, 0x02, 0x3e, 0x53, 0xaa, 0xef, 0x58, 0x8c, 0x7d,
+       0x5b, 0x12, 0xe5, 0xd8, 0x9f, 0xe2, 0xbb, 0x39, 0x31, 0x67, 0x5d, 0xb6,
+       0x39, 0xee, 0x6b, 0xb1, 0x73, 0x6a, 0x8c, 0x90, 0x14, 0xd4, 0xb3, 0x5f,
+       0xb5, 0xf8, 0xec, 0x29, 0xf8, 0xf8, 0x93, 0x55, 0x53, 0x4e, 0x54, 0xd7,
+       0x32, 0x39, 0x7c, 0x88, 0x6d, 0x5e, 0x2e, 0xf1, 0xfe, 0xb7, 0x70, 0x3f,
+       0x24, 0xcc, 0x3d, 0x3e, 0x8f, 0x3e, 0x47, 0xd1, 0xe7, 0x48, 0x35, 0xc0,
+       0x8d, 0xbc, 0xef, 0x66, 0x52, 0xb8, 0x7f, 0xa4, 0xe8, 0x66, 0xd2, 0x45,
+       0xe6, 0x39, 0x7d, 0xd1, 0x13, 0x90, 0x67, 0x16, 0xb1, 0xdd, 0x15, 0xab,
+       0x37, 0x2f, 0x8f, 0xb5, 0x0e, 0x23, 0xaf, 0x3e, 0x8f, 0x98, 0xe3, 0x8e,
+       0x59, 0x4e, 0x19, 0xcc, 0x4d, 0x95, 0xee, 0x90, 0xc2, 0x0c, 0x62, 0x8c,
+       0x73, 0x0f, 0x73, 0xed, 0x8c, 0x1e, 0x77, 0xe0, 0x13, 0x06, 0x80, 0x27,
+       0xbb, 0x81, 0x85, 0xef, 0x92, 0x15, 0xd3, 0x8a, 0x0e, 0x03, 0x03, 0xa7,
+       0x42, 0xe8, 0xd3, 0x7b, 0x9b, 0x64, 0xa3, 0x94, 0xf5, 0x0e, 0xf8, 0x07,
+       0x4d, 0x5a, 0xec, 0x46, 0x5f, 0xf5, 0x17, 0x10, 0x2f, 0x92, 0xdf, 0x36,
+       0xb6, 0xb7, 0xfa, 0x3a, 0xd9, 0x22, 0xab, 0xef, 0xe9, 0xf7, 0x37, 0x0d,
+       0xfd, 0x1a, 0xdb, 0x35, 0x4d, 0xd0, 0x7f, 0x0d, 0x34, 0x84, 0xe2, 0x90,
+       0x3f, 0x78, 0x68, 0x82, 0x9d, 0x5c, 0x06, 0x3f, 0xf4, 0x9b, 0x85, 0x32,
+       0xe3, 0xa4, 0x21, 0x65, 0x13, 0xf7, 0xaa, 0xf5, 0xfa, 0x82, 0x0d, 0x5a,
+       0x2f, 0x90, 0xde, 0xb0, 0x0c, 0x57, 0x7b, 0xc4, 0x5d, 0xa4, 0x1c, 0x2c,
+       0xac, 0x8e, 0x5d, 0x6d, 0xa9, 0x79, 0xcb, 0xcd, 0x63, 0x44, 0xe3, 0x42,
+       0x57, 0x5b, 0x12, 0x71, 0x51, 0xbf, 0x10, 0x6b, 0x4b, 0xc1, 0x1f, 0x18,
+       0x17, 0x6e, 0x6f, 0x4b, 0xcf, 0x92, 0x2e, 0x03, 0x71, 0xf1, 0x4e, 0xe0,
+       0xc2, 0xba, 0x7c, 0x0d, 0xb9, 0x4f, 0xa1, 0x17, 0x31, 0x03, 0xab, 0x44,
+       0x07, 0xdd, 0x79, 0x53, 0xc2, 0x6d, 0x89, 0x79, 0xd0, 0xd7, 0xdf, 0x9a,
+       0x9c, 0xdd, 0x82, 0x3e, 0x06, 0xda, 0x7b, 0x88, 0x21, 0x1b, 0xda, 0xed,
+       0x36, 0xf8, 0x5f, 0xf8, 0x3a, 0x09, 0x27, 0x07, 0xda, 0x31, 0xfe, 0xd9,
+       0x10, 0x73, 0x87, 0x70, 0x7c, 0xbd, 0xfd, 0xcb, 0x5e, 0x7b, 0x2f, 0x68,
+       0xe1, 0x73, 0xcc, 0x21, 0x25, 0x3c, 0x3e, 0x60, 0x82, 0x06, 0xf6, 0x8d,
+       0xa8, 0xbe, 0xe9, 0x79, 0xda, 0x80, 0x9b, 0x59, 0xb0, 0x77, 0x4b, 0x6a,
+       0x6e, 0xa7, 0x0c, 0xcf, 0x75, 0xca, 0xfe, 0x39, 0xe6, 0xbc, 0xc4, 0xc0,
+       0x60, 0x05, 0x39, 0xa9, 0x7e, 0x81, 0xb9, 0x80, 0x15, 0x3d, 0x2a, 0xdd,
+       0xd1, 0xcf, 0x63, 0x1d, 0x8c, 0xdb, 0xf1, 0xd8, 0x24, 0xd6, 0x58, 0x48,
+       0x8d, 0x13, 0x0d, 0xe6, 0xa4, 0x8d, 0x6e, 0x98, 0x37, 0x3d, 0x7f, 0xb3,
+       0x71, 0xb1, 0x70, 0x2e, 0x44, 0x37, 0x8d, 0xfb, 0x3f, 0xfd, 0x71, 0x4d,
+       0x8c, 0xdb, 0x85, 0x31, 0xc9, 0xe3, 0xed, 0xad, 0x43, 0xb3, 0xe2, 0xb6,
+       0x80, 0xbe, 0x74, 0x7c, 0x97, 0x4c, 0x62, 0x9c, 0x93, 0x73, 0xf4, 0x85,
+       0xb2, 0x13, 0x9f, 0xfe, 0x26, 0x89, 0xf7, 0x2e, 0x21, 0x2f, 0x1e, 0x52,
+       0x63, 0x78, 0x39, 0xaa, 0x7e, 0x21, 0x01, 0x5c, 0xf3, 0x51, 0xd0, 0xc3,
+       0x98, 0x4c, 0x9e, 0x43, 0xe0, 0x37, 0x81, 0x75, 0x48, 0x3c, 0xce, 0xf5,
+       0x8d, 0xdf, 0x4b, 0xd1, 0xd6, 0xd4, 0x6c, 0x33, 0xd6, 0x9d, 0xec, 0x36,
+       0x54, 0xac, 0xa0, 0x5e, 0xec, 0xd6, 0x64, 0x49, 0xd1, 0xdd, 0x9a, 0x2a,
+       0x51, 0x46, 0x4e, 0x6b, 0xba, 0x44, 0x19, 0x09, 0xe8, 0x71, 0xe0, 0x63,
+       0x43, 0x12, 0xdb, 0x4e, 0x3d, 0x1e, 0x43, 0xbf, 0x95, 0x10, 0xf3, 0xfe,
+       0xa4, 0xcd, 0xdf, 0xc0, 0x2b, 0x17, 0x8e, 0xa3, 0x2f, 0x7f, 0xdf, 0x8b,
+       0x71, 0xbb, 0x7b, 0x0b, 0xd2, 0xdc, 0x7b, 0x04, 0x7e, 0x42, 0x1f, 0x00,
+       0xee, 0x50, 0x76, 0x5e, 0x07, 0x26, 0xdb, 0x0b, 0x7e, 0xb0, 0x36, 0xe2,
+       0xb6, 0x4c, 0xcc, 0x50, 0xae, 0x72, 0x1b, 0x78, 0x00, 0xff, 0x71, 0xf8,
+       0x16, 0xf2, 0xc0, 0xb9, 0x05, 0x76, 0xbf, 0x2c, 0xb9, 0x99, 0xb0, 0xc2,
+       0x3e, 0xae, 0xc9, 0xf9, 0x35, 0x4d, 0x4f, 0xb4, 0x41, 0xc7, 0xe4, 0x6d,
+       0x0a, 0xb4, 0x3d, 0x0e, 0x3f, 0x6c, 0xa9, 0x9c, 0xdb, 0x40, 0xff, 0x42,
+       0x69, 0x50, 0x4f, 0x15, 0x49, 0xbf, 0x6f, 0x7b, 0xda, 0x0a, 0x7c, 0x8a,
+       0xaa, 0x63, 0x21, 0xb7, 0x4b, 0xc0, 0x8f, 0x0c, 0xca, 0xf7, 0xe1, 0x4b,
+       0xbe, 0x5b, 0x73, 0xe0, 0xff, 0xfb, 0xe1, 0xff, 0x7b, 0xe1, 0xff, 0x6d,
+       0xf8, 0xff, 0x18, 0xfc, 0x7f, 0x17, 0xfc, 0x7f, 0x94, 0xbe, 0x5f, 0x4e,
+       0xd6, 0xf2, 0xb0, 0xb1, 0x15, 0xf8, 0x41, 0x33, 0xec, 0xd6, 0x22, 0xe1,
+       0x64, 0x2d, 0x1a, 0x4e, 0xd5, 0x42, 0xe0, 0xe9, 0x30, 0xe7, 0x04, 0x7f,
+       0xf9, 0xd6, 0xa1, 0x52, 0x3f, 0xe2, 0x8a, 0x0b, 0xbf, 0x94, 0x86, 0xdf,
+       0x77, 0x80, 0x7f, 0xf3, 0xb2, 0x3a, 0x13, 0xc3, 0x33, 0x75, 0x49, 0x3b,
+       0x4d, 0x32, 0x69, 0x3a, 0x18, 0x63, 0xbb, 0xb2, 0x53, 0x23, 0xb1, 0xab,
+       0x09, 0x76, 0x2a, 0xb9, 0x22, 0xe3, 0x73, 0x17, 0xc6, 0x6b, 0x45, 0x7c,
+       0xa0, 0x7f, 0xa0, 0x2f, 0x58, 0xc9, 0x3c, 0x6c, 0x73, 0xcd, 0xb5, 0x69,
+       0x49, 0xe0, 0x67, 0x62, 0x13, 0xc4, 0x3a, 0xd8, 0x05, 0xdb, 0xf6, 0xe0,
+       0x39, 0xfe, 0xfe, 0x6f, 0x7e, 0x8d, 0xea, 0xaf, 0x5a, 0x04, 0xc6, 0xfb,
+       0x32, 0x63, 0x8f, 0x8d, 0xf1, 0xaa, 0x8d, 0xeb, 0x75, 0x49, 0x17, 0x3b,
+       0xb8, 0xcf, 0x7a, 0x0d, 0x6b, 0x54, 0xaf, 0x80, 0xde, 0x7a, 0x7d, 0x55,
+       0x61, 0x48, 0xe4, 0x33, 0x87, 0xd6, 0xc0, 0x43, 0xe3, 0x33, 0xdf, 0xc0,
+       0x33, 0xaa, 0x2d, 0x6c, 0x26, 0x1c, 0xe6, 0x50, 0xf0, 0x9b, 0x2f, 0xc0,
+       0x47, 0x1e, 0xcb, 0xe8, 0xcb, 0x57, 0xf1, 0x2c, 0x64, 0x5a, 0x3c, 0x96,
+       0x09, 0xf5, 0xbc, 0x5a, 0x7f, 0x16, 0x39, 0xf1, 0xd0, 0xf2, 0x80, 0xa4,
+       0x96, 0xbb, 0xa3, 0x17, 0xa5, 0xf5, 0x1d, 0x17, 0xb1, 0x74, 0xb2, 0x6a,
+       0x9d, 0x76, 0x85, 0x39, 0xba, 0x29, 0x0b, 0xc0, 0xd5, 0x7b, 0xf6, 0x3d,
+       0x0f, 0xda, 0xad, 0x17, 0x45, 0x8f, 0xe1, 0x37, 0x31, 0x0c, 0x79, 0x5c,
+       0x03, 0x7f, 0x1a, 0xae, 0x5b, 0xd6, 0x6b, 0x57, 0x85, 0x12, 0xf8, 0xac,
+       0x1d, 0xcb, 0x5c, 0x9c, 0x06, 0xae, 0x83, 0x3e, 0x92, 0xd3, 0xc4, 0x9c,
+       0x5b, 0x20, 0x93, 0x21, 0xd8, 0x05, 0xf5, 0x1d, 0xc7, 0xb3, 0x75, 0xf9,
+       0x92, 0x43, 0x1b, 0x78, 0x0e, 0x72, 0xc3, 0x58, 0xa1, 0x80, 0x6e, 0x60,
+       0x80, 0x19, 0xca, 0x6a, 0x17, 0xf2, 0x36, 0x57, 0x06, 0xf6, 0x49, 0x78,
+       0x47, 0x62, 0x73, 0x4e, 0x76, 0x2c, 0xb3, 0x3a, 0x8d, 0xf1, 0x7b, 0x80,
+       0x79, 0x84, 0xb5, 0x19, 0xfa, 0x60, 0x81, 0xed, 0xec, 0x87, 0x7e, 0x98,
+       0x7b, 0x33, 0x47, 0xa3, 0x6f, 0x3a, 0xa8, 0xa5, 0x2a, 0x65, 0x43, 0x3a,
+       0x0e, 0x21, 0xb7, 0x71, 0x64, 0x71, 0x9a, 0x39, 0x1a, 0xf3, 0x99, 0x20,
+       0x7f, 0xd1, 0x90, 0x4b, 0xa0, 0x7d, 0xf9, 0x25, 0xa5, 0x07, 0x03, 0xfa,
+       0xca, 0xed, 0xbb, 0x9f, 0x7c, 0xcd, 0x18, 0x09, 0xf8, 0xbf, 0x01, 0xf2,
+       0xa2, 0x68, 0x40, 0xce, 0xc6, 0x35, 0x17, 0x03, 0x5f, 0xf8, 0x5c, 0xcf,
+       0xdd, 0xd4, 0xdf, 0x64, 0xe9, 0x04, 0xec, 0x58, 0xf2, 0x4d, 0x09, 0xf0,
+       0x36, 0x80, 0xdf, 0x58, 0xf8, 0x27, 0xa1, 0xc3, 0x73, 0x03, 0xac, 0x91,
+       0x3d, 0x07, 0xfc, 0x47, 0xfa, 0xe3, 0xb1, 0x13, 0x6a, 0xdd, 0xe2, 0xba,
+       0xca, 0x3c, 0x62, 0x8b, 0x5c, 0x54, 0x7c, 0xde, 0xc1, 0xfc, 0x14, 0x7a,
+       0xb9, 0x15, 0x3e, 0x87, 0x3f, 0x24, 0x9f, 0xde, 0x3c, 0x8c, 0x5b, 0x49,
+       0x3b, 0x26, 0xa9, 0xe2, 0xcb, 0x75, 0xaf, 0x0e, 0xfb, 0x47, 0xb0, 0x2b,
+       0x5c, 0x57, 0xc3, 0xa0, 0x87, 0x75, 0x99, 0x01, 0xa5, 0x5b, 0xd0, 0x43,
+       0x9b, 0xc9, 0x87, 0x13, 0xdb, 0xe4, 0xfc, 0x4c, 0x87, 0x2c, 0xcc, 0xbc,
+       0x26, 0x95, 0x99, 0x36, 0x59, 0x9a, 0xa9, 0xcb, 0x65, 0x47, 0xf9, 0x25,
+       0xbb, 0x59, 0xad, 0x69, 0xd9, 0xe5, 0x61, 0xf6, 0xf8, 0xe0, 0x15, 0x79,
+       0x5a, 0xce, 0x97, 0x3d, 0x1e, 0x32, 0x0d, 0x3c, 0xbc, 0x0a, 0x1b, 0xeb,
+       0xec, 0x21, 0x0f, 0xb4, 0x07, 0xf2, 0xc3, 0xdc, 0x83, 0x39, 0xe6, 0x41,
+       0xac, 0xa3, 0x11, 0x60, 0xa3, 0x83, 0x5a, 0xd2, 0xe7, 0x21, 0xe5, 0xf1,
+       0x90, 0x7d, 0x2f, 0x0f, 0x2d, 0x92, 0xdd, 0x49, 0x3e, 0xa0, 0x83, 0x69,
+       0xea, 0x25, 0xc0, 0x1b, 0x1e, 0xfd, 0xc9, 0xe5, 0x57, 0xeb, 0xfa, 0x74,
+       0x93, 0xa2, 0xdd, 0x48, 0x0c, 0xc0, 0xae, 0x5e, 0xad, 0xcb, 0x32, 0xd7,
+       0x12, 0x7e, 0x57, 0xff, 0x31, 0xfc, 0x55, 0xa7, 0xca, 0x5b, 0x72, 0x63,
+       0xed, 0xad, 0xc9, 0xf9, 0x41, 0xe8, 0xba, 0x55, 0xad, 0x45, 0xb8, 0x0e,
+       0xe8, 0xf0, 0x0f, 0xd1, 0xff, 0xab, 0x5c, 0x73, 0x4a, 0x3e, 0x69, 0xc8,
+       0xa7, 0x50, 0xbc, 0xbd, 0x19, 0x39, 0x37, 0xe6, 0x71, 0x33, 0xd9, 0x2a,
+       0x9f, 0xe9, 0x82, 0x7f, 0xe3, 0xf7, 0x07, 0xb6, 0x8f, 0x3c, 0xfc, 0x2e,
+       0x6c, 0x00, 0xb9, 0x05, 0xd7, 0xf4, 0xc0, 0x0a, 0xe2, 0x6c, 0xbc, 0x77,
+       0x41, 0xd5, 0xf4, 0x1d, 0x85, 0x9f, 0x26, 0xab, 0x5f, 0xc5, 0xc7, 0x9b,
+       0x6f, 0xa8, 0xc6, 0x39, 0x37, 0xf2, 0x84, 0x9c, 0x06, 0xb9, 0xa4, 0x8d,
+       0x71, 0x39, 0x6f, 0x5e, 0x8c, 0x84, 0x81, 0x79, 0xd9, 0xd6, 0x0e, 0x3f,
+       0x13, 0x83, 0xdf, 0xea, 0x87, 0xff, 0xe7, 0x5a, 0xa6, 0xaf, 0x0f, 0x68,
+       0xef, 0xc7, 0x98, 0xf4, 0xc1, 0xfd, 0xe0, 0x99, 0xb9, 0x34, 0x7d, 0x28,
+       0x62, 0xca, 0x62, 0xb4, 0x2d, 0x39, 0xeb, 0xd5, 0x93, 0xbc, 0xdf, 0xbc,
+       0x2f, 0xe1, 0xdd, 0x09, 0xab, 0x9c, 0x47, 0xfe, 0x97, 0xc2, 0xda, 0x4d,
+       0xda, 0xc8, 0xa7, 0x17, 0xad, 0x17, 0x88, 0xd3, 0x74, 0xca, 0x60, 0x99,
+       0x72, 0x62, 0x6d, 0xc3, 0x94, 0xfc, 0xc2, 0xef, 0x42, 0x1e, 0x61, 0xd9,
+       0x6e, 0x67, 0xe1, 0x53, 0x98, 0xb7, 0xb8, 0xe0, 0x8d, 0xbe, 0xa7, 0x1b,
+       0xb1, 0xcc, 0x80, 0x10, 0x90, 0x57, 0x2d, 0x1b, 0xf2, 0x40, 0xa8, 0x0f,
+       0x79, 0xe0, 0xa7, 0xd0, 0x37, 0x24, 0xf9, 0x65, 0xc6, 0x84, 0x90, 0x4c,
+       0x2d, 0x8b, 0x5c, 0x99, 0xa6, 0x5f, 0x51, 0x7f, 0x90, 0xb9, 0x9b, 0x99,
+       0x20, 0x3e, 0x9b, 0xa1, 0x8f, 0xa1, 0xff, 0xd8, 0x01, 0x5d, 0xc4, 0x9f,
+       0xfb, 0x12, 0xe2, 0xd3, 0x64, 0xb1, 0x1b, 0x7e, 0x53, 0x56, 0x74, 0xc8,
+       0x14, 0x71, 0x8d, 0xf5, 0xaa, 0x1b, 0xd4, 0xaa, 0x82, 0x3a, 0x55, 0x58,
+       0x0a, 0xd3, 0xac, 0x51, 0x85, 0x41, 0x0b, 0x73, 0x57, 0x43, 0xe5, 0x42,
+       0x3b, 0x94, 0x7f, 0xe5, 0x77, 0xa8, 0x61, 0xde, 0xf8, 0xe9, 0x3d, 0x3a,
+       0xfd, 0xd8, 0x6e, 0x71, 0x47, 0x8f, 0xb5, 0xee, 0x2f, 0x01, 0x8b, 0x76,
+       0xd2, 0x3e, 0xa9, 0xff, 0xac, 0x4e, 0x7f, 0x3b, 0x55, 0x1a, 0xc0, 0x78,
+       0xc4, 0x95, 0x21, 0xf4, 0x8b, 0xf8, 0xfd, 0x28, 0xd7, 0x7f, 0x25, 0xe3,
+       0xfb, 0xfe, 0x1a, 0x74, 0x79, 0xfe, 0x8e, 0x75, 0xee, 0xdc, 0x67, 0x74,
+       0xb9, 0xef, 0x63, 0x69, 0x3c, 0xcb, 0x78, 0xf8, 0xb6, 0x8f, 0xe1, 0xd8,
+       0xc6, 0xba, 0x1e, 0x72, 0xf5, 0xf3, 0x26, 0xbe, 0x3b, 0x25, 0x7f, 0x3e,
+       0x0c, 0x39, 0x20, 0x2f, 0x5e, 0xf0, 0xc6, 0x62, 0xee, 0x7b, 0x1a, 0x3a,
+       0xd2, 0xcf, 0x84, 0xa5, 0xe9, 0x4c, 0xa7, 0x84, 0xbe, 0xd2, 0x26, 0xcd,
+       0x5f, 0xe9, 0x11, 0xe3, 0x2b, 0xac, 0x3f, 0x58, 0xb1, 0x93, 0xaa, 0xf6,
+       0x91, 0x96, 0x53, 0x88, 0x61, 0x3a, 0xe2, 0xb1, 0xb2, 0x53, 0x73, 0xa7,
+       0x18, 0x48, 0x5e, 0xf5, 0x67, 0x5c, 0xf9, 0xe2, 0xbe, 0x9f, 0xab, 0xda,
+       0x1b, 0x70, 0xb3, 0xe8, 0xcf, 0x67, 0xc4, 0xad, 0xbd, 0x46, 0x3b, 0xcd,
+       0xbc, 0x7a, 0xd7, 0x1d, 0xd0, 0x39, 0x73, 0xcb, 0x5e, 0x55, 0xc7, 0xfd,
+       0xe2, 0x3e, 0xc6, 0x4c, 0x2f, 0xbf, 0x4c, 0x23, 0xbf, 0x9c, 0x94, 0x6e,
+       0xf8, 0x59, 0xf6, 0xdb, 0x29, 0x3a, 0xe6, 0xca, 0x09, 0xf3, 0xf5, 0x3b,
+       0xc5, 0x3d, 0x8c, 0x75, 0x71, 0x56, 0x66, 0xf4, 0x84, 0xa6, 0xc6, 0x34,
+       0x9e, 0xa1, 0xdf, 0xa2, 0x3f, 0xa3, 0x8d, 0xb3, 0x0e, 0x82, 0xb6, 0xe7,
+       0xe9, 0xb3, 0x3c, 0xdb, 0x1e, 0x6a, 0xf0, 0x7d, 0x53, 0xa5, 0x1a, 0x74,
+       0x88, 0xbc, 0xde, 0x6e, 0x02, 0xff, 0x88, 0xeb, 0x36, 0xaf, 0xc9, 0x3f,
+       0x7c, 0x69, 0x24, 0xa2, 0xae, 0x0b, 0x65, 0x0f, 0xf7, 0x7a, 0xe3, 0x33,
+       0x07, 0x81, 0xaf, 0xa9, 0x91, 0x0e, 0xce, 0xdb, 0x25, 0xc6, 0xd9, 0x88,
+       0x84, 0xce, 0xd2, 0xfe, 0xac, 0x58, 0x1a, 0xf2, 0x9b, 0xb2, 0x89, 0xf5,
+       0x0e, 0xc0, 0x17, 0xec, 0x16, 0xfd, 0x7c, 0x2f, 0xd6, 0x8e, 0x15, 0x2d,
+       0x4b, 0x5c, 0x8c, 0x85, 0xb0, 0xbc, 0x09, 0xdf, 0x41, 0x7b, 0x39, 0x87,
+       0x78, 0x75, 0xa2, 0xd6, 0xfa, 0xce, 0x8a, 0xa2, 0x82, 0x6d, 0x43, 0xc0,
+       0x4b, 0x56, 0xaf, 0xab, 0xb7, 0xcb, 0xeb, 0xd0, 0x77, 0x56, 0xb5, 0xed,
+       0xc6, 0xb8, 0xa0, 0xe1, 0x2c, 0xeb, 0x49, 0x1c, 0xf7, 0x1f, 0x60, 0x4c,
+       0x8e, 0xed, 0x66, 0x56, 0x99, 0x9f, 0x4e, 0xd3, 0x76, 0x3b, 0x61, 0x77,
+       0xb8, 0xae, 0x35, 0x4b, 0x76, 0x2c, 0x26, 0xfa, 0xf4, 0x83, 0xd2, 0xbd,
+       0x4f, 0xf7, 0xf8, 0x51, 0x3c, 0xb2, 0x8d, 0x75, 0xca, 0x16, 0xb5, 0x1e,
+       0xf5, 0x65, 0xd8, 0xcc, 0x41, 0xea, 0x18, 0xf1, 0x1f, 0xf1, 0x8d, 0xfe,
+       0xcc, 0x40, 0x7c, 0x4b, 0xd5, 0x3c, 0xbd, 0x97, 0x0f, 0xee, 0x94, 0x53,
+       0x67, 0x69, 0x4f, 0xb8, 0xb7, 0x6e, 0x53, 0xc1, 0x7e, 0x02, 0xef, 0xd9,
+       0x72, 0xfa, 0x59, 0xe6, 0x1f, 0xcc, 0x3b, 0x98, 0x6b, 0x59, 0xd1, 0xfd,
+       0xe0, 0x47, 0xbf, 0x8f, 0xfe, 0x40, 0x57, 0xb6, 0x9b, 0x83, 0xaf, 0x2e,
+       0xd4, 0xa8, 0xb7, 0x7e, 0xee, 0xb9, 0x98, 0xcc, 0xd9, 0xdc, 0xa8, 0x27,
+       0xef, 0x02, 0xda, 0x26, 0x11, 0x07, 0x52, 0xd5, 0x26, 0x59, 0x1b, 0x73,
+       0xa1, 0xfb, 0x8f, 0x82, 0xae, 0xc3, 0xad, 0xc4, 0xab, 0x6b, 0x63, 0x69,
+       0x5c, 0x1f, 0x56, 0x79, 0x9a, 0x71, 0x9f, 0x8b, 0x31, 0x76, 0x72, 0x1d,
+       0xf9, 0x7a, 0x72, 0xf4, 0xc2, 0xcc, 0x7d, 0xfa, 0x24, 0x7c, 0xf7, 0xb0,
+       0xc3, 0x18, 0xcf, 0xfa, 0x73, 0x0b, 0xe8, 0x68, 0x57, 0xd8, 0x42, 0xb7,
+       0xf7, 0xe9, 0x85, 0x32, 0xfd, 0x7d, 0x3e, 0xda, 0x2c, 0x0e, 0x7d, 0x96,
+       0xbe, 0x60, 0x53, 0x27, 0x9a, 0x5c, 0x54, 0xb5, 0x6a, 0x44, 0xa0, 0x6a,
+       0x0a, 0x73, 0x39, 0x7a, 0xa5, 0xbc, 0x4f, 0xcf, 0xc3, 0x55, 0xaf, 0x45,
+       0x48, 0x77, 0x4c, 0xe5, 0xf2, 0xfb, 0x94, 0xad, 0x15, 0x11, 0x53, 0x60,
+       0x33, 0xce, 0x1d, 0x98, 0x57, 0xb5, 0xc1, 0xa6, 0xa8, 0x7b, 0xea, 0x5d,
+       0xf9, 0x48, 0x5f, 0xf7, 0x37, 0x8a, 0xa1, 0x45, 0xf8, 0x5f, 0x62, 0xe9,
+       0x16, 0xbf, 0x3e, 0xf5, 0xcf, 0xfd, 0x9c, 0xe8, 0x71, 0x61, 0x9e, 0x32,
+       0x55, 0x22, 0x2d, 0x45, 0xf8, 0xc3, 0x1b, 0xd9, 0x12, 0xe5, 0xe8, 0xf9,
+       0x94, 0x63, 0xb0, 0x0b, 0x7d, 0xd9, 0xf4, 0x6d, 0x40, 0xe1, 0x67, 0xdc,
+       0x63, 0x0c, 0xc0, 0x77, 0xad, 0x09, 0xeb, 0x7d, 0x04, 0x32, 0xa2, 0x6e,
+       0xa0, 0xbf, 0x65, 0xee, 0xd5, 0x41, 0x7f, 0xcb, 0x97, 0x7e, 0xe1, 0x76,
+       0xd2, 0xe7, 0x0d, 0xc8, 0x29, 0xf8, 0xd1, 0x93, 0xf3, 0xa4, 0x27, 0xad,
+       0xd6, 0xce, 0x14, 0xe4, 0x7d, 0x42, 0xf9, 0xf8, 0x7e, 0x79, 0x73, 0xf1,
+       0x5b, 0x0a, 0x0b, 0xee, 0xd9, 0xb7, 0x22, 0x13, 0xf0, 0x0f, 0x47, 0xaa,
+       0x90, 0xb7, 0x19, 0xc3, 0xfa, 0xdc, 0xa5, 0xfc, 0xe3, 0x17, 0x3f, 0x78,
+       0xae, 0x12, 0xd2, 0x13, 0x0f, 0x7c, 0xc8, 0x18, 0xbe, 0x55, 0xdc, 0xce,
+       0x0f, 0x3c, 0x8f, 0xa1, 0x27, 0xfe, 0x10, 0x3a, 0xfb, 0x4d, 0xcc, 0x15,
+       0x06, 0x9d, 0x6a, 0x3f, 0xe4, 0x83, 0x3c, 0xa7, 0xeb, 0x89, 0x4f, 0x7e,
+       0x48, 0xfa, 0x4c, 0x59, 0x04, 0x7e, 0xc8, 0xab, 0xb8, 0xca, 0xdc, 0xb1,
+       0xc9, 0xd7, 0xe7, 0x0b, 0xc0, 0xd5, 0xc0, 0xd2, 0xc5, 0xc0, 0x17, 0xb7,
+       0x48, 0xbe, 0x33, 0xc8, 0x47, 0xe1, 0xc3, 0xd7, 0xdb, 0x83, 0x1c, 0x97,
+       0xcf, 0x67, 0x33, 0xc8, 0xa9, 0x61, 0x13, 0xb7, 0x61, 0x8d, 0xb2, 0x4d,
+       0xe5, 0xb0, 0x37, 0xa1, 0xdf, 0xa3, 0x3d, 0x57, 0x6c, 0xcc, 0x2d, 0x0e,
+       0xa8, 0xdc, 0x62, 0x68, 0x43, 0x6e, 0x11, 0xd4, 0xb4, 0x02, 0xba, 0x39,
+       0x2e, 0x70, 0x03, 0xec, 0xe0, 0xbb, 0x18, 0xff, 0x3b, 0xd0, 0xf7, 0xb7,
+       0x4b, 0xc0, 0x0d, 0x25, 0xe0, 0x86, 0x12, 0x70, 0x43, 0x09, 0xb8, 0xa1,
+       0x14, 0xf5, 0xeb, 0x5b, 0x2e, 0x71, 0xff, 0x07, 0xb4, 0xe9, 0xa0, 0xee,
+       0xb1, 0xd9, 0x5e, 0xbd, 0x3a, 0x59, 0xaa, 0x16, 0xe0, 0xe7, 0x30, 0xeb,
+       0x76, 0xc0, 0x71, 0x41, 0x4d, 0xc4, 0x8f, 0x1d, 0x8b, 0xdc, 0x43, 0x41,
+       0xec, 0x58, 0x74, 0xb1, 0x9e, 0xfa, 0xa2, 0x06, 0x70, 0xa3, 0x21, 0x51,
+       0xfc, 0x36, 0xe1, 0x93, 0xb9, 0x67, 0xde, 0x8d, 0x15, 0xd6, 0xac, 0x6a,
+       0x4f, 0x27, 0x54, 0x4d, 0xc2, 0x96, 0xc9, 0x72, 0x90, 0xdb, 0xc5, 0x65,
+       0x68, 0x86, 0x58, 0x54, 0xb6, 0xeb, 0x09, 0xe8, 0xa2, 0x4a, 0xfc, 0xc8,
+       0x3d, 0x27, 0xce, 0x1f, 0xef, 0xad, 0x60, 0xce, 0x82, 0xed, 0xd1, 0x77,
+       0xa2, 0xaa, 0xce, 0x05, 0xf8, 0xcf, 0x05, 0x67, 0x01, 0xe2, 0xb2, 0x7f,
+       0x86, 0x7b, 0xef, 0x31, 0x19, 0x2d, 0x3a, 0xc8, 0x65, 0x55, 0x8e, 0x84,
+       0x78, 0xe0, 0xc9, 0x7d, 0xc8, 0x97, 0x7b, 0x0e, 0xd8, 0x61, 0xdc, 0x0e,
+       0xe4, 0x4e, 0x79, 0x8f, 0x68, 0xc3, 0x90, 0xf5, 0x7e, 0x5f, 0xd6, 0xe9,
+       0x25, 0x31, 0x91, 0xff, 0xc4, 0x8c, 0x7d, 0x63, 0xda, 0x68, 0x4d, 0x61,
+       0x16, 0xfa, 0x23, 0x8c, 0xe5, 0x78, 0x6b, 0x1d, 0xf6, 0x92, 0xab, 0x6e,
+       0xde, 0x8f, 0x6f, 0xc4, 0x2f, 0x9f, 0xd5, 0xc4, 0x0e, 0xe4, 0xd8, 0xd8,
+       0x3e, 0xd1, 0xd0, 0xbe, 0x7e, 0xdf, 0xe7, 0x01, 0xbe, 0x72, 0xbd, 0x3e,
+       0x41, 0xbf, 0x76, 0xbd, 0x1d, 0x78, 0x4f, 0x42, 0xea, 0x3e, 0x7c, 0xfe,
+       0x62, 0x44, 0x52, 0x8b, 0xb6, 0xa4, 0xcb, 0xec, 0xc7, 0x9a, 0x07, 0xfd,
+       0xd7, 0x1f, 0x4b, 0x0a, 0x79, 0x6e, 0x36, 0x62, 0x39, 0xae, 0xfc, 0x47,
+       0x59, 0x9d, 0xcb, 0xc7, 0xb8, 0x77, 0x9d, 0x1f, 0xd5, 0xf0, 0xdc, 0x8f,
+       0x71, 0x4d, 0xda, 0x6d, 0xac, 0x0f, 0xc6, 0xa9, 0xbe, 0xe8, 0x22, 0xee,
+       0x65, 0xc7, 0x58, 0xe7, 0x79, 0x2a, 0x2c, 0x6d, 0x56, 0xac, 0x0c, 0x3b,
+       0xb8, 0x54, 0xe4, 0x7c, 0xc0, 0x52, 0x45, 0xd6, 0x82, 0x82, 0xfb, 0x7f,
+       0x0c, 0xec, 0xa8, 0x13, 0x3b, 0x79, 0x7d, 0x94, 0xbe, 0x5c, 0x33, 0x84,
+       0x35, 0xb0, 0xe2, 0xfb, 0xe7, 0x85, 0xa2, 0x57, 0x7b, 0x39, 0x47, 0x3a,
+       0xaa, 0x7f, 0x53, 0x5f, 0x89, 0x20, 0x67, 0x5a, 0xe7, 0xf1, 0x1c, 0xc7,
+       0x37, 0xe1, 0x9e, 0xe5, 0x64, 0x35, 0x90, 0x05, 0xef, 0xb3, 0x8d, 0xfb,
+       0xf3, 0xf5, 0xfa, 0x39, 0xfb, 0xc3, 0xd6, 0xd9, 0x9e, 0xbb, 0x27, 0x69,
+       0xcb, 0x81, 0x85, 0xaa, 0x1c, 0xf0, 0xea, 0x6c, 0xd1, 0xbd, 0x5e, 0x9d,
+       0x2d, 0xb6, 0x77, 0x63, 0x9d, 0xad, 0x7c, 0x8f, 0x57, 0x67, 0x33, 0x0f,
+       0xc0, 0x07, 0x1f, 0xf0, 0xea, 0x6c, 0xff, 0xf5, 0x1e, 0xaf, 0xce, 0xd6,
+       0x75, 0xaf, 0x57, 0x67, 0xeb, 0xdd, 0xeb, 0xd5, 0xd9, 0x46, 0xef, 0xdd,
+       0x58, 0x67, 0x73, 0xf6, 0x6e, 0xac, 0xb3, 0x39, 0x07, 0x72, 0xf8, 0x5c,
+       0xaf, 0xb3, 0x65, 0xf6, 0xde, 0xbc, 0xce, 0xf6, 0x4a, 0x80, 0xf1, 0xc1,
+       0xcf, 0x00, 0x78, 0x70, 0x80, 0xf1, 0xfb, 0x81, 0xf1, 0x6f, 0x56, 0xe3,
+       0x55, 0xe7, 0x37, 0xc0, 0xa7, 0xe6, 0xc7, 0x8f, 0x0f, 0x83, 0xf5, 0xb7,
+       0xfa, 0xcf, 0xba, 0xc8, 0x8f, 0x63, 0x7e, 0x6e, 0x43, 0xbc, 0xbf, 0xcd,
+       0xcf, 0xf1, 0xba, 0x5a, 0xaf, 0x9f, 0xad, 0x68, 0xfc, 0xbe, 0x0d, 0xa9,
+       0x7a, 0x50, 0x03, 0x20, 0x5f, 0x72, 0xe0, 0x61, 0x25, 0x87, 0x3b, 0xd1,
+       0xdf, 0x3c, 0xf0, 0x25, 0x9b, 0x75, 0x81, 0x27, 0xb1, 0x86, 0xdd, 0xed,
+       0x86, 0xda, 0x67, 0x66, 0x4c, 0x3b, 0x2d, 0x29, 0xf4, 0x4f, 0xa9, 0xfe,
+       0xa3, 0x0d, 0xfd, 0xb3, 0xe8, 0xcf, 0x71, 0xad, 0x7f, 0x8b, 0xcf, 0x73,
+       0xca, 0xbe, 0x6d, 0x0f, 0xf7, 0xa7, 0x4b, 0x01, 0x4e, 0x0b, 0xf9, 0x18,
+       0xdc, 0xcd, 0xb8, 0xd5, 0x7b, 0xf1, 0x8c, 0xf5, 0xa2, 0x2b, 0x57, 0x15,
+       0xde, 0x37, 0x12, 0xd6, 0x8b, 0x59, 0x95, 0xdf, 0xb9, 0x99, 0x5c, 0x75,
+       0x3d, 0x5f, 0x07, 0x0e, 0x63, 0xce, 0x03, 0x7b, 0x5f, 0xee, 0x45, 0xdc,
+       0x6b, 0xcc, 0xc9, 0x99, 0x87, 0xeb, 0x7e, 0x1e, 0x6e, 0xca, 0xfd, 0xfb,
+       0x1a, 0x31, 0xbe, 0x73, 0xe0, 0xef, 0x2b, 0x8c, 0xbf, 0x05, 0xb9, 0x3c,
+       0x31, 0x3c, 0x71, 0x0f, 0x31, 0x07, 0x71, 0x3e, 0xeb, 0x0b, 0xcc, 0x7f,
+       0x18, 0x4b, 0x99, 0x0f, 0x45, 0xf0, 0xe1, 0xb9, 0x97, 0x00, 0xeb, 0x37,
+       0xfb, 0xfe, 0x9f, 0x79, 0x54, 0x80, 0x6d, 0xac, 0x2d, 0x5e, 0x2e, 0xb5,
+       0x45, 0xf3, 0xf2, 0xd5, 0x98, 0xdf, 0x27, 0xb4, 0x8e, 0xa5, 0x43, 0xeb,
+       0x58, 0x7a, 0xc3, 0x5e, 0x89, 0xa8, 0x33, 0x36, 0x6a, 0xcf, 0x85, 0x7b,
+       0x30, 0x6e, 0xe6, 0x52, 0x0f, 0xf1, 0x30, 0xf7, 0x62, 0x80, 0x8d, 0xec,
+       0xc6, 0x58, 0xc5, 0x38, 0x45, 0x3c, 0x15, 0xec, 0xb7, 0x06, 0x7a, 0xa2,
+       0xec, 0xd8, 0xf6, 0x47, 0x1a, 0x72, 0x64, 0xa7, 0xd9, 0xde, 0x0f, 0x5a,
+       0x32, 0xf8, 0x0e, 0x64, 0xfa, 0x80, 0x8a, 0x91, 0x2d, 0xb0, 0xdd, 0x13,
+       0x25, 0x62, 0xde, 0x6d, 0xb2, 0xe8, 0xe3, 0xde, 0xf3, 0x33, 0x1e, 0xe6,
+       0x0d, 0x6d, 0xc4, 0xbc, 0xce, 0xaa, 0x78, 0x34, 0xee, 0xbf, 0x21, 0x8d,
+       0xc4, 0xb7, 0xa4, 0x8f, 0x31, 0x89, 0xfe, 0xd1, 0xcd, 0x5c, 0xee, 0x61,
+       0x3c, 0x62, 0x2c, 0x8a, 0xc9, 0xea, 0x4d, 0xe9, 0x53, 0x6d, 0xc7, 0x5a,
+       0xec, 0x30, 0x3e, 0x13, 0xf0, 0x1f, 0xa3, 0x78, 0x26, 0x23, 0x93, 0xb3,
+       0x5f, 0x00, 0x6f, 0x13, 0x72, 0x69, 0x66, 0x0c, 0xf4, 0x3d, 0x29, 0x53,
+       0x4e, 0x1e, 0x7e, 0x84, 0x7b, 0x21, 0xc4, 0x79, 0xdd, 0xfe, 0xf7, 0x84,
+       0x7e, 0xce, 0xb6, 0x88, 0x33, 0xa5, 0x52, 0xa4, 0x0f, 0xe6, 0xbe, 0x14,
+       0xf7, 0x1f, 0x69, 0x3f, 0xac, 0xc3, 0x20, 0xd7, 0x65, 0xce, 0x3b, 0xcd,
+       0xf9, 0x37, 0xea, 0x64, 0xb5, 0x4a, 0xbc, 0xe6, 0x66, 0x56, 0x96, 0x89,
+       0x37, 0x3f, 0x28, 0xf6, 0xa4, 0x1e, 0x88, 0x3f, 0x6f, 0x05, 0x77, 0x5a,
+       0x33, 0xc0, 0x9c, 0x2f, 0xac, 0xe8, 0x8d, 0xb8, 0xd3, 0xc3, 0x9c, 0xc9,
+       0xe5, 0x2c, 0xc6, 0x74, 0x14, 0xb6, 0x46, 0xde, 0x07, 0xb7, 0xd7, 0x8d,
+       0x67, 0xbb, 0x91, 0xc3, 0x7b, 0x18, 0x33, 0x05, 0x8c, 0xf9, 0x0f, 0x81,
+       0x31, 0x27, 0xe5, 0xad, 0x56, 0x62, 0x4c, 0xd7, 0xc7, 0x98, 0x69, 0xd8,
+       0x73, 0x6e, 0x83, 0x3d, 0x6b, 0xaa, 0x76, 0xc5, 0x7b, 0x39, 0x60, 0xc4,
+       0xd4, 0xb4, 0x75, 0x0b, 0xb8, 0x52, 0x93, 0x88, 0x3a, 0xfb, 0x10, 0x6a,
+       0x18, 0x33, 0xc0, 0x8f, 0x7b, 0x14, 0x2e, 0x3c, 0x50, 0xda, 0x82, 0x1c,
+       0x46, 0xe1, 0x44, 0x7f, 0x4f, 0x2e, 0xb4, 0x69, 0x9f, 0x32, 0xd4, 0xb0,
+       0x4f, 0x79, 0x1d, 0x4f, 0xe2, 0x39, 0xbf, 0x3e, 0xd8, 0x04, 0x5f, 0xf0,
+       0x7f, 0x40, 0x13, 0xd7, 0x17, 0xd7, 0x82, 0xe6, 0xad, 0x97, 0xd1, 0x46,
+       0x5c, 0xf9, 0xbf, 0x36, 0xe1, 0x4a, 0xc4, 0xae, 0xf3, 0x11, 0x49, 0x02,
+       0x53, 0xba, 0xcb, 0x1c, 0x8b, 0x6b, 0xba, 0x5f, 0x9a, 0xc1, 0x5f, 0xcb,
+       0x74, 0x27, 0xb0, 0x54, 0x9b, 0x84, 0x81, 0xa9, 0x9a, 0x14, 0xa6, 0xea,
+       0x21, 0xf6, 0xe9, 0x3d, 0x02, 0x2c, 0xb4, 0xb8, 0x8e, 0xab, 0x2c, 0xe7,
+       0x87, 0xd0, 0xcb, 0xa3, 0xca, 0xf7, 0xa4, 0xe5, 0x29, 0xf8, 0xd2, 0xe6,
+       0x65, 0xe0, 0xc1, 0xf3, 0x1e, 0xde, 0x6a, 0xda, 0x84, 0xb7, 0x8e, 0xde,
+       0x10, 0x6f, 0xa9, 0x9a, 0xff, 0x20, 0x65, 0xf2, 0x7a, 0xd5, 0xab, 0xf9,
+       0x5f, 0xa9, 0x7a, 0x35, 0xff, 0xd7, 0xab, 0x8d, 0x35, 0xff, 0x8f, 0x48,
+       0xc1, 0xb4, 0xdc, 0x35, 0xd9, 0x54, 0xf3, 0x1f, 0x65, 0x0d, 0xfd, 0xf7,
+       0xda, 0xbc, 0xda, 0x7e, 0x9b, 0x5f, 0xf3, 0xb7, 0xa4, 0xb0, 0xa1, 0xdd,
+       0x94, 0xb7, 0xec, 0xa0, 0xe6, 0xff, 0x34, 0xda, 0xda, 0x31, 0xc7, 0xc6,
+       0x7a, 0xff, 0x95, 0x2a, 0xeb, 0xfd, 0x11, 0xf6, 0xf3, 0xeb, 0xfd, 0xec,
+       0x87, 0xdc, 0xbf, 0xca, 0x5a, 0xff, 0x6e, 0xc8, 0x62, 0x27, 0xe4, 0xd0,
+       0x29, 0xcd, 0x67, 0xa3, 0xec, 0xa3, 0x6a, 0xfc, 0x6b, 0xc8, 0x37, 0xae,
+       0x54, 0xbd, 0x5a, 0xfc, 0x11, 0xd8, 0xd5, 0xd1, 0xf5, 0x1a, 0xbf, 0x37,
+       0xc7, 0xd5, 0xea, 0xc6, 0xf1, 0x37, 0x8e, 0xd3, 0xe5, 0x8f, 0x13, 0xc1,
+       0x38, 0xd1, 0x4d, 0xe3, 0x5c, 0xaf, 0xe9, 0x5f, 0xad, 0x7a, 0xf5, 0xfc,
+       0xf4, 0xac, 0xb8, 0xcd, 0xf0, 0xcd, 0x2f, 0xf6, 0xec, 0xf2, 0xc7, 0x58,
+       0xaf, 0xe7, 0xd3, 0x87, 0x00, 0xe7, 0xc7, 0xd5, 0xf9, 0x9e, 0x23, 0xff,
+       0x1f, 0xea, 0xf9, 0xac, 0xe5, 0x7b, 0x7b, 0x32, 0x5c, 0x9f, 0xc0, 0xf3,
+       0xcf, 0x7a, 0x75, 0xfc, 0xa1, 0x52, 0x50, 0x9f, 0x67, 0x5e, 0x19, 0x9c,
+       0xbd, 0xe9, 0x8e, 0x9d, 0x10, 0xda, 0x0a, 0xe9, 0xe3, 0xb8, 0xed, 0x32,
+       0xae, 0xf0, 0x14, 0x6c, 0x2a, 0x7e, 0x73, 0x4c, 0xbd, 0x30, 0x1d, 0x60,
+       0xea, 0x88, 0xc2, 0xd4, 0x0b, 0xcb, 0x01, 0xa6, 0x4e, 0xde, 0x04, 0x53,
+       0xff, 0xf7, 0x36, 0x2f, 0x0e, 0x84, 0x25, 0xaf, 0x30, 0xf5, 0xcd, 0xce,
+       0x2b, 0xf1, 0x5e, 0x1b, 0xf1, 0x82, 0x78, 0x7b, 0xd8, 0x9d, 0x37, 0x59,
+       0x6b, 0x01, 0xce, 0x66, 0xec, 0xdf, 0x29, 0xa3, 0x67, 0xaf, 0xe3, 0x6c,
+       0x0f, 0x4b, 0x5b, 0xb1, 0x63, 0x2a, 0x26, 0x02, 0xd7, 0xd5, 0x58, 0x2f,
+       0x27, 0x56, 0x66, 0xcc, 0x09, 0x29, 0x3c, 0x97, 0x2b, 0x32, 0x0f, 0x60,
+       0x1b, 0xb1, 0x73, 0x2b, 0x8f, 0xf2, 0xf8, 0x31, 0x29, 0xc0, 0xa6, 0xc1,
+       0xd9, 0x09, 0xee, 0x4b, 0xbc, 0x65, 0x24, 0x6d, 0xb4, 0x57, 0x83, 0x5c,
+       0xc1, 0x51, 0x67, 0x4e, 0x92, 0xc0, 0x3f, 0xe3, 0xeb, 0xd8, 0x93, 0xbe,
+       0xe2, 0x47, 0xbf, 0x70, 0x4d, 0xfa, 0xb5, 0x00, 0x5b, 0x22, 0x27, 0x2a,
+       0x71, 0x6d, 0x07, 0xd8, 0xd2, 0xc3, 0x95, 0xa9, 0xea, 0x0a, 0xf0, 0x75,
+       0x48, 0x86, 0x80, 0xeb, 0x57, 0x1e, 0x66, 0xcd, 0x2a, 0xc0, 0x4e, 0x2e,
+       0xbe, 0x1b, 0x6b, 0x58, 0xbc, 0x6e, 0x56, 0x7b, 0x87, 0x17, 0x7b, 0xc2,
+       0x0d, 0xed, 0xbf, 0x05, 0xff, 0x8d, 0xfc, 0x08, 0x98, 0xc5, 0xc3, 0x4c,
+       0x7b, 0xa1, 0x83, 0x01, 0x85, 0x99, 0xa6, 0xde, 0x83, 0x99, 0x36, 0xc7,
+       0x28, 0xc6, 0xcc, 0xeb, 0x31, 0x2a, 0x5d, 0xa3, 0x3f, 0xbf, 0x1e, 0xa3,
+       0x6e, 0x1e, 0x43, 0xd9, 0x06, 0xee, 0xec, 0x0c, 0x3e, 0x13, 0x52, 0xd8,
+       0x14, 0xa3, 0xa6, 0x3e, 0x44, 0x8c, 0x1a, 0x56, 0x31, 0xca, 0xa3, 0xfb,
+       0xfb, 0x90, 0xcd, 0x77, 0x21, 0xd3, 0xef, 0x00, 0x8b, 0x7d, 0x1b, 0x7c,
+       0x7d, 0x0b, 0x38, 0xe9, 0x9b, 0xa5, 0xcd, 0x67, 0x0e, 0x06, 0x85, 0xf9,
+       0xa1, 0x87, 0xa5, 0xbc, 0x1a, 0xc0, 0x11, 0xac, 0xae, 0xc5, 0xa2, 0x9b,
+       0x19, 0x2f, 0xf6, 0x99, 0x13, 0xde, 0xde, 0x6b, 0x2c, 0x2b, 0x8f, 0xb5,
+       0xa6, 0xe6, 0x19, 0x33, 0xd4, 0x75, 0x94, 0xf5, 0x4e, 0x62, 0x87, 0x8a,
+       0xca, 0x33, 0x7b, 0xa4, 0xbc, 0xe8, 0xe1, 0xb0, 0xa9, 0x79, 0x6f, 0x8c,
+       0x71, 0x1f, 0x87, 0xe5, 0x7c, 0x1c, 0x96, 0x5d, 0x5c, 0x8d, 0x85, 0xd0,
+       0x7f, 0xca, 0xd9, 0x88, 0xbd, 0x8e, 0xf8, 0xd8, 0x6b, 0xe2, 0x43, 0x61,
+       0x2f, 0x6f, 0xae, 0x1c, 0x9e, 0x19, 0x9e, 0x89, 0xc9, 0x7e, 0xc8, 0x79,
+       0xa8, 0x48, 0x7d, 0xf1, 0x9c, 0xd2, 0x2f, 0xd3, 0x19, 0xf5, 0xe5, 0xe9,
+       0x2a, 0x14, 0x3f, 0xa8, 0x0d, 0x43, 0x57, 0x43, 0xbf, 0x54, 0x57, 0x62,
+       0xbe, 0x39, 0x10, 0xc6, 0xe7, 0x6f, 0x4b, 0x57, 0xe4, 0x83, 0xfa, 0xda,
+       0x8c, 0xc5, 0x6e, 0x05, 0x93, 0x6d, 0xc4, 0x63, 0xae, 0xc2, 0x63, 0xcd,
+       0x7e, 0x9f, 0xfc, 0x81, 0x61, 0xe8, 0xf2, 0x3f, 0xa0, 0xcf, 0x8f, 0xed,
+       0x76, 0xf9, 0x11, 0xfc, 0xf7, 0xbf, 0x87, 0x4e, 0xfe, 0x1d, 0x72, 0x85,
+       0x57, 0xec, 0x2e, 0xf9, 0x21, 0xda, 0xae, 0xe3, 0x1c, 0xf6, 0x9f, 0x72,
+       0x92, 0xf6, 0x28, 0xf0, 0xc9, 0xa8, 0x8f, 0x4f, 0xde, 0x7a, 0x20, 0x69,
+       0x8f, 0xb1, 0xce, 0x0e, 0x39, 0xff, 0x34, 0x39, 0xae, 0xb0, 0x49, 0x80,
+       0x49, 0x1e, 0x4f, 0x73, 0xfe, 0xc9, 0x6a, 0x16, 0xd8, 0x27, 0xeb, 0x63,
+       0x9f, 0x9f, 0xa6, 0x3d, 0xec, 0x33, 0xf5, 0xf7, 0xa8, 0x7f, 0x0f, 0xf7,
+       0x1c, 0x76, 0x93, 0x98, 0x07, 0xb8, 0x07, 0xd7, 0x87, 0x25, 0x5f, 0x1b,
+       0x51, 0x9f, 0x13, 0x25, 0xd7, 0x6a, 0x82, 0x9c, 0x58, 0xab, 0x3d, 0xc3,
+       0x55, 0x59, 0xb5, 0xcc, 0x22, 0xbe, 0xb3, 0x55, 0x2b, 0xfa, 0x7b, 0xfe,
+       0xf5, 0xd3, 0xfe, 0xf5, 0x53, 0xfe, 0xf5, 0x69, 0xc4, 0xe1, 0x53, 0x2a,
+       0x96, 0xb2, 0x9d, 0x6d, 0x50, 0x72, 0x15, 0x63, 0x01, 0x7b, 0x9c, 0xeb,
+       0xff, 0xf3, 0x7a, 0x59, 0xe9, 0x98, 0xe3, 0x8f, 0xe2, 0x73, 0x1a, 0x9f,
+       0x09, 0x7c, 0x0e, 0xe1, 0x93, 0xc7, 0x67, 0x5d, 0xa6, 0x5a, 0xaa, 0x34,
+       0x06, 0x1b, 0xe9, 0x95, 0x54, 0xed, 0x39, 0xe8, 0xf1, 0x49, 0xe8, 0xf6,
+       0xb8, 0x14, 0x2a, 0x7f, 0x22, 0x93, 0x33, 0x9a, 0xb4, 0xd9, 0xd0, 0x69,
+       0x05, 0xb6, 0x3c, 0xe3, 0xed, 0x41, 0xb6, 0x26, 0x46, 0xd0, 0xb7, 0x2e,
+       0x8f, 0x3a, 0x4f, 0x8a, 0x7e, 0xdf, 0x14, 0xfa, 0x89, 0x5e, 0xe8, 0xbf,
+       0x5b, 0xed, 0xbf, 0x55, 0x1c, 0x4f, 0xc6, 0xfb, 0x6d, 0xd7, 0x82, 0xce,
+       0x7b, 0x4f, 0x61, 0xec, 0xa4, 0x3a, 0x7f, 0x99, 0x91, 0x93, 0xb3, 0xab,
+       0xdb, 0x3d, 0xdf, 0x6a, 0x99, 0x57, 0xa9, 0x77, 0xf0, 0xe1, 0xc2, 0x17,
+       0x66, 0x60, 0xef, 0x47, 0xab, 0x21, 0x6d, 0x08, 0xf1, 0x66, 0xa8, 0x7a,
+       0x55, 0xc5, 0x9b, 0x54, 0xd5, 0xcd, 0xc4, 0xcf, 0x44, 0x70, 0xcd, 0x73,
+       0x31, 0x88, 0x8b, 0xea, 0xfc, 0xde, 0x2a, 0xf0, 0x8d, 0xa6, 0xea, 0x86,
+       0x93, 0xeb, 0xfb, 0x4a, 0xea, 0x7c, 0x71, 0x26, 0x1e, 0xd7, 0x25, 0x37,
+       0x40, 0x9c, 0x3b, 0xa2, 0x62, 0x13, 0xd6, 0xea, 0xed, 0xcc, 0x15, 0x5f,
+       0xe7, 0xbb, 0x00, 0xf6, 0x27, 0xd0, 0xaf, 0x0b, 0xfe, 0x18, 0xf7, 0x6a,
+       0xb4, 0x4f, 0xf2, 0xca, 0x67, 0x26, 0xa4, 0x52, 0x1e, 0x04, 0xbf, 0x7e,
+       0x8e, 0xa4, 0x72, 0x89, 0x18, 0xec, 0x31, 0xd8, 0xc3, 0xf2, 0xea, 0x2a,
+       0x95, 0x6a, 0x80, 0x29, 0xda, 0xd1, 0x87, 0x79, 0x05, 0x64, 0xe4, 0xed,
+       0xbf, 0xa9, 0xbd, 0xb7, 0x42, 0x75, 0x10, 0x72, 0x4a, 0xa2, 0x9d, 0xb5,
+       0x6d, 0xfc, 0x2e, 0xeb, 0xaa, 0x26, 0xb0, 0x66, 0x1c, 0x91, 0xc5, 0x72,
+       0x1d, 0xf4, 0x22, 0xe6, 0x6e, 0x3f, 0x22, 0x0b, 0xe5, 0x09, 0x79, 0xa1,
+       0xfc, 0xcd, 0x76, 0x60, 0x2a, 0xc8, 0x94, 0xf4, 0xb7, 0xcb, 0xf5, 0x33,
+       0x9e, 0x41, 0x3b, 0xe4, 0x39, 0x9b, 0x8f, 0x7a, 0x79, 0x6e, 0x5e, 0xd5,
+       0x68, 0xbc, 0x6f, 0x57, 0x1f, 0xb7, 0xad, 0xe8, 0x24, 0x7a, 0x1e, 0x9d,
+       0x53, 0xb6, 0x39, 0x3c, 0x65, 0xef, 0x95, 0xcb, 0xce, 0x36, 0x59, 0x75,
+       0x54, 0x5e, 0x4c, 0xfc, 0x80, 0xb5, 0x6e, 0x99, 0x2b, 0xf2, 0xa0, 0x9c,
+       0xc4, 0xba, 0xbd, 0xec, 0x3c, 0x06, 0x3b, 0x7d, 0x02, 0xb6, 0xc0, 0x1a,
+       0xc0, 0x31, 0xe6, 0x5a, 0xb2, 0xa2, 0x6a, 0x68, 0xf5, 0xfa, 0xb0, 0x3a,
+       0x27, 0xdc, 0x2c, 0xab, 0x0a, 0x8b, 0x79, 0xb5, 0xf6, 0xd5, 0x31, 0x6f,
+       0x8d, 0x18, 0xca, 0xee, 0xbf, 0x01, 0x7a, 0x8a, 0xb0, 0xdd, 0x26, 0xd5,
+       0xc7, 0x48, 0xb4, 0xf8, 0x7d, 0x14, 0x06, 0x6d, 0xe8, 0x63, 0x27, 0x92,
+       0xf6, 0x6b, 0xfb, 0x92, 0xf6, 0xc4, 0x81, 0x5c, 0xd5, 0xf3, 0x99, 0xae,
+       0xb6, 0xb6, 0x5e, 0xff, 0xc9, 0x60, 0x5d, 0xbd, 0xbc, 0x8e, 0xa1, 0x61,
+       0xa4, 0xcf, 0x5f, 0x82, 0x7e, 0x43, 0xd2, 0x7c, 0xa6, 0xfe, 0x89, 0x71,
+       0xa7, 0x2f, 0x76, 0x54, 0x78, 0x32, 0x8b, 0x79, 0xb5, 0xe5, 0x64, 0xe5,
+       0x12, 0xe2, 0xe4, 0x35, 0x62, 0x87, 0xde, 0x8b, 0x72, 0xed, 0x13, 0x49,
+       0x67, 0x50, 0x5b, 0x18, 0x43, 0xd6, 0xf2, 0xfc, 0x18, 0xe3, 0xec, 0x31,
+       0x11, 0xe0, 0xcb, 0x33, 0x03, 0x92, 0x2e, 0xaa, 0x77, 0x21, 0x78, 0x96,
+       0x53, 0x9b, 0x80, 0xfc, 0xf0, 0xfc, 0x28, 0x03, 0xa3, 0x6e, 0x77, 0xc7,
+       0xd2, 0xf2, 0x18, 0x6b, 0x63, 0x92, 0x9b, 0x93, 0x3d, 0x49, 0xf8, 0x55,
+       0x77, 0xb4, 0x59, 0x26, 0x16, 0xdd, 0x4c, 0xf7, 0xf4, 0x13, 0x18, 0x63,
+       0x1c, 0x63, 0x8d, 0x20, 0x37, 0xc9, 0x22, 0x56, 0x53, 0xbe, 0xf4, 0xdd,
+       0x8f, 0x43, 0x46, 0x1f, 0xe1, 0x59, 0xd7, 0xc1, 0xac, 0x58, 0xa3, 0x79,
+       0x35, 0xee, 0xbb, 0x5a, 0xae, 0xff, 0x57, 0x10, 0xeb, 0x42, 0xb2, 0x3f,
+       0x2e, 0xfa, 0x48, 0x3c, 0xf4, 0x8b, 0x71, 0x9b, 0x6d, 0x61, 0xb6, 0xe9,
+       0x68, 0x0b, 0xfd, 0x66, 0x3c, 0xac, 0x27, 0xe3, 0xd6, 0x20, 0xcf, 0xe0,
+       0x1a, 0xf6, 0xb8, 0x18, 0xcf, 0xd7, 0x21, 0x8b, 0x11, 0xe9, 0xb8, 0x60,
+       0x0d, 0xbe, 0x0e, 0x5a, 0x42, 0xca, 0xd7, 0x8f, 0x8b, 0xee, 0xb7, 0xb7,
+       0xaf, 0xb7, 0x87, 0xfc, 0xf6, 0x11, 0x69, 0xbb, 0xd0, 0x67, 0xbe, 0x21,
+       0x47, 0x30, 0xa6, 0x21, 0x57, 0x90, 0xeb, 0xd8, 0x3d, 0xe3, 0xb0, 0xc5,
+       0x47, 0x48, 0xcb, 0x21, 0xd6, 0x1b, 0x5d, 0xd8, 0x5f, 0x8b, 0x7d, 0x87,
+       0x7c, 0xde, 0x6c, 0x95, 0x9c, 0xca, 0x75, 0x43, 0xea, 0xbd, 0x85, 0x1c,
+       0xec, 0xfd, 0xae, 0x9e, 0xa1, 0x0e, 0xaf, 0x5e, 0xc0, 0xfd, 0x91, 0x7e,
+       0xb4, 0x5d, 0xab, 0x9f, 0xb7, 0xd9, 0xc6, 0x7b, 0xd7, 0xea, 0x15, 0xbb,
+       0xcf, 0x4c, 0x69, 0x61, 0x7f, 0xff, 0xfc, 0x98, 0xe2, 0x3d, 0x5f, 0xee,
+       0x36, 0x17, 0xe4, 0x2e, 0x2d, 0xb5, 0x03, 0xf1, 0xa2, 0x9a, 0x42, 0xdf,
+       0x6b, 0x3c, 0x83, 0xa1, 0xf6, 0x03, 0x16, 0x24, 0xb8, 0xe6, 0x38, 0x7d,
+       0xe6, 0xb0, 0x7a, 0xb6, 0xcf, 0x3c, 0xa9, 0x35, 0x3e, 0x1b, 0xd5, 0x86,
+       0x37, 0x3c, 0xdb, 0xa6, 0x64, 0x64, 0xd8, 0x5e, 0x9f, 0xc9, 0xf2, 0x88,
+       0x3c, 0x5d, 0x65, 0xbf, 0x6b, 0xf5, 0x94, 0xbd, 0x55, 0x3b, 0xb9, 0x83,
+       0xbe, 0x90, 0x7d, 0xdf, 0xd9, 0x34, 0x0f, 0xaf, 0x6f, 0x36, 0x47, 0x5d,
+       0x36, 0xce, 0xb1, 0x45, 0xf5, 0xb9, 0xac, 0xfa, 0x84, 0x94, 0xac, 0x37,
+       0xce, 0xf3, 0x17, 0xb2, 0x71, 0x9e, 0xb6, 0x75, 0x9e, 0x27, 0x31, 0xe6,
+       0x29, 0xf4, 0x2d, 0x56, 0xbb, 0xa3, 0x15, 0x79, 0xa7, 0x9e, 0xb3, 0xdf,
+       0x92, 0xcb, 0xeb, 0x63, 0xff, 0x25, 0xae, 0x1b, 0x69, 0xfa, 0x4b, 0x9f,
+       0x46, 0xfe, 0x66, 0xdb, 0x3f, 0x53, 0xf2, 0xde, 0x6a, 0x77, 0x1f, 0x5a,
+       0xd0, 0xac, 0xc1, 0x9f, 0x09, 0x75, 0xf5, 0x3b, 0xca, 0xd7, 0xdc, 0x0d,
+       0x3d, 0xed, 0x79, 0x06, 0x6b, 0xb7, 0x3f, 0xa9, 0xfa, 0x5c, 0xb1, 0x47,
+       0x64, 0xcf, 0x99, 0x6e, 0xf3, 0x8a, 0xdc, 0x2f, 0xe9, 0x08, 0xaf, 0x91,
+       0x43, 0xd9, 0x7c, 0xf7, 0xe1, 0x57, 0x99, 0x17, 0x40, 0x97, 0xdd, 0xbd,
+       0x3f, 0x93, 0x27, 0xe4, 0x64, 0x69, 0x0a, 0xbe, 0x67, 0x5c, 0x7a, 0x9f,
+       0xa1, 0xff, 0xc9, 0x9b, 0x5e, 0xad, 0xc6, 0x8b, 0x89, 0x29, 0x3f, 0x26,
+       0x4e, 0x29, 0x3f, 0xf7, 0x8a, 0x7f, 0x8e, 0xa2, 0xbb, 0xf7, 0x3c, 0x9e,
+       0x7d, 0x41, 0xf9, 0x80, 0x6f, 0x48, 0x05, 0x6b, 0x21, 0xf6, 0xfc, 0x36,
+       0xd9, 0xfa, 0x10, 0x6d, 0x12, 0x19, 0xc0, 0xdd, 0x4d, 0xea, 0x5d, 0x0b,
+       0xdd, 0x6e, 0x11, 0xd9, 0x4e, 0xfb, 0x59, 0xd8, 0x2a, 0x6d, 0xe3, 0xde,
+       0x5e, 0xd9, 0x86, 0x6b, 0x6b, 0x74, 0x4d, 0xca, 0x5b, 0x69, 0x87, 0x1f,
+       0xbd, 0xe0, 0x7d, 0xf7, 0x5f, 0x40, 0xba, 0x1c, 0x1f, 0x91, 0x7b, 0x2f,
+       0x78, 0x76, 0x37, 0x39, 0xf3, 0x84, 0x92, 0xef, 0xb8, 0x92, 0x6f, 0x5d,
+       0x8e, 0x38, 0x94, 0x3d, 0x79, 0xe2, 0xb9, 0x4a, 0x4f, 0x26, 0x9f, 0xf4,
+       0xed, 0xa8, 0xfb, 0x19, 0xbe, 0x23, 0x46, 0x19, 0x91, 0xee, 0x74, 0x07,
+       0xf7, 0x6f, 0xf7, 0x5c, 0x20, 0xbf, 0x5d, 0x1b, 0xf8, 0x7d, 0x0a, 0x3e,
+       0xb6, 0xa7, 0xc7, 0xe3, 0xf9, 0x95, 0x99, 0x0f, 0xce, 0xf3, 0xd7, 0xd6,
+       0x79, 0x36, 0xa4, 0xa2, 0xf2, 0xdc, 0xd0, 0x36, 0x69, 0xcb, 0xc9, 0x0a,
+       0xec, 0xe3, 0xcf, 0x84, 0xe7, 0x92, 0x49, 0x8b, 0x37, 0xef, 0x6a, 0x95,
+       0x34, 0x05, 0x3c, 0x90, 0xae, 0xa4, 0xaf, 0x3f, 0xd2, 0xf1, 0xc4, 0x0d,
+       0xef, 0x5d, 0x11, 0x37, 0xd3, 0x8b, 0x36, 0x5d, 0xe9, 0x70, 0xc8, 0x5f,
+       0x6f, 0x23, 0xa2, 0x2b, 0x1d, 0x26, 0xd7, 0x75, 0xf8, 0x3a, 0x74, 0x58,
+       0x91, 0x8f, 0x83, 0x27, 0xac, 0xef, 0x67, 0xfa, 0xcc, 0x23, 0xb2, 0x53,
+       0xe9, 0xdf, 0xee, 0x81, 0x4f, 0xf5, 0x75, 0xd9, 0x7c, 0x0b, 0xba, 0x7c,
+       0x43, 0x94, 0x3e, 0xd5, 0xd9, 0xa3, 0x8a, 0x1a, 0x87, 0xbe, 0x8d, 0xbc,
+       0x35, 0x2b, 0x9f, 0x40, 0x1a, 0xd5, 0x59, 0x82, 0x51, 0x4f, 0xbf, 0x6a,
+       0xcd, 0xfb, 0xfa, 0xcd, 0x8e, 0x52, 0x87, 0xd1, 0x0e, 0x4f, 0x9f, 0x2d,
+       0xaa, 0xcf, 0x74, 0xfc, 0x36, 0xb5, 0xde, 0xed, 0x9e, 0x9d, 0x1d, 0xd4,
+       0xe9, 0xd3, 0x55, 0xef, 0xbb, 0x88, 0x38, 0x37, 0x5d, 0xfd, 0x65, 0x7a,
+       0xf5, 0x74, 0x3a, 0x24, 0xde, 0xba, 0xda, 0xac, 0x4f, 0xfd, 0x42, 0x48,
+       0xd9, 0xf0, 0x10, 0x64, 0x78, 0xba, 0xb4, 0xc3, 0xb7, 0x7b, 0x8f, 0xe7,
+       0x9e, 0x0f, 0xc8, 0xf3, 0x89, 0x62, 0xb7, 0xf9, 0x16, 0xee, 0x0d, 0x83,
+       0xe7, 0x23, 0xd2, 0x24, 0x29, 0x9f, 0xe7, 0xd8, 0x3a, 0xcf, 0x01, 0x8d,
+       0x5e, 0xbf, 0x14, 0xf3, 0xd8, 0x2a, 0xfd, 0xd7, 0xef, 0xaa, 0x77, 0x1a,
+       0xae, 0x16, 0xe9, 0xb7, 0x81, 0x95, 0x22, 0x9d, 0x72, 0x65, 0x31, 0x26,
+       0x57, 0x88, 0x41, 0x06, 0xf0, 0x5d, 0x9d, 0xf2, 0x63, 0x78, 0x58, 0xde,
+       0x28, 0xde, 0x88, 0x8e, 0x7e, 0x79, 0xbd, 0x18, 0xd0, 0x42, 0x2c, 0xcc,
+       0x7c, 0x61, 0x5c, 0xde, 0x9c, 0xe9, 0x96, 0x95, 0x51, 0xc4, 0xfd, 0x1e,
+       0xca, 0xa4, 0xcf, 0x7c, 0x50, 0xbd, 0xeb, 0x72, 0xad, 0x7e, 0xd1, 0xc6,
+       0xf8, 0x73, 0x75, 0x39, 0xca, 0xfd, 0x6f, 0xfe, 0x5e, 0xbc, 0x5d, 0x56,
+       0x98, 0x53, 0xf4, 0x74, 0xca, 0xc2, 0x1c, 0xf2, 0xf9, 0x22, 0xc7, 0xa7,
+       0xdc, 0x46, 0xd4, 0xef, 0x61, 0xcc, 0xf7, 0x49, 0x9e, 0x41, 0x8f, 0x50,
+       0x37, 0xd7, 0xea, 0xab, 0x36, 0xf7, 0x3f, 0xc7, 0x65, 0x11, 0xfa, 0xfb,
+       0x47, 0x71, 0xee, 0xcf, 0xe7, 0xd4, 0xfb, 0x85, 0x0b, 0x8b, 0xa3, 0xc8,
+       0x1d, 0xae, 0xd5, 0xa7, 0xec, 0x29, 0xa5, 0xb7, 0xc5, 0xf2, 0x43, 0x7e,
+       0x3b, 0xaf, 0x79, 0xcf, 0xcd, 0xec, 0xe9, 0x61, 0xbe, 0xfa, 0x10, 0xf2,
+       0x05, 0xe6, 0xaa, 0xa3, 0xc0, 0x6b, 0x94, 0x49, 0x4c, 0x26, 0x8b, 0x1c,
+       0x4b, 0x22, 0x5b, 0x90, 0xdf, 0xe7, 0x64, 0x18, 0xf4, 0xc4, 0x90, 0xdb,
+       0x33, 0x3e, 0xdc, 0x25, 0xab, 0x11, 0x2f, 0x0e, 0xf0, 0xac, 0xd8, 0x2a,
+       0x62, 0xc3, 0xea, 0x7a, 0x6c, 0xd8, 0x89, 0x6b, 0x37, 0xe3, 0xf4, 0xfc,
+       0x67, 0x8c, 0xcf, 0xba, 0x0d, 0x63, 0xc3, 0x20, 0xfa, 0xb3, 0xad, 0x53,
+       0x26, 0xe7, 0x90, 0x44, 0x20, 0x67, 0x59, 0x10, 0x9e, 0x01, 0xc9, 0xca,
+       0xf4, 0x62, 0x77, 0xf4, 0xa2, 0x96, 0x56, 0x67, 0x45, 0xe2, 0x98, 0x73,
+       0xa1, 0xd8, 0x29, 0x8b, 0x73, 0x12, 0x33, 0x12, 0x8f, 0x48, 0x75, 0xd1,
+       0xc3, 0xec, 0x53, 0x1a, 0xda, 0xab, 0xae, 0x2c, 0x6e, 0xec, 0x63, 0x1a,
+       0x89, 0xc3, 0xf2, 0x75, 0xbf, 0x4f, 0x5a, 0xf5, 0x79, 0xb5, 0x83, 0x7b,
+       0x6c, 0x8b, 0xd5, 0x0e, 0xd0, 0x40, 0xda, 0x76, 0x35, 0xce, 0x1b, 0xbb,
+       0x3e, 0x2f, 0xe7, 0x44, 0x36, 0xb3, 0xdd, 0xc5, 0xbc, 0x17, 0xf1, 0xcc,
+       0x23, 0xa0, 0xe3, 0x9a, 0xa1, 0xdb, 0x8f, 0x48, 0x61, 0x71, 0xf3, 0x1c,
+       0x8d, 0x34, 0xf0, 0x19, 0x8e, 0xcf, 0x79, 0x0e, 0x83, 0xbe, 0x6b, 0x9a,
+       0x6e, 0x1f, 0x86, 0x2c, 0xbd, 0x39, 0x8c, 0xb3, 0x96, 0xf9, 0x23, 0xe9,
+       0x11, 0xfd, 0xbc, 0xa6, 0xe4, 0xaf, 0x2f, 0xf4, 0x63, 0x81, 0x64, 0xa4,
+       0x6d, 0x79, 0x4c, 0x8c, 0x65, 0xd6, 0x10, 0x5e, 0x69, 0x4d, 0xab, 0xfd,
+       0xde, 0x2d, 0x58, 0xdf, 0xe2, 0x86, 0x6c, 0xd6, 0x0b, 0x58, 0x0f, 0xfe,
+       0xfa, 0x36, 0xe9, 0x60, 0xbd, 0x80, 0x79, 0xc3, 0x21, 0x7c, 0x33, 0x77,
+       0x78, 0xb9, 0x9e, 0x74, 0x7e, 0xa6, 0xe2, 0x6b, 0x6e, 0x91, 0xf7, 0xad,
+       0x98, 0x08, 0xef, 0xd1, 0x6f, 0x74, 0x4a, 0xd3, 0x57, 0x7a, 0xe1, 0x2b,
+       0x1e, 0x03, 0xf6, 0xc6, 0xb8, 0x67, 0x7a, 0x24, 0xe4, 0x9d, 0xb1, 0x50,
+       0xf5, 0x96, 0x37, 0xe7, 0x2c, 0xff, 0x9d, 0x21, 0xd9, 0x73, 0xd1, 0x61,
+       0x4d, 0xb4, 0x8b, 0x35, 0x1f, 0xf4, 0x13, 0x7d, 0x15, 0xf9, 0xe9, 0x95,
+       0x45, 0x63, 0x1b, 0xcf, 0x7c, 0xbe, 0x5e, 0xc5, 0x35, 0xb1, 0x7f, 0x44,
+       0x61, 0x4c, 0xff, 0x1e, 0x7f, 0x23, 0x5f, 0x7a, 0xcf, 0xf9, 0x77, 0xe6,
+       0x53, 0x63, 0xfe, 0x59, 0x3b, 0x37, 0x73, 0x72, 0x43, 0x4e, 0xd5, 0xab,
+       0xea, 0xbd, 0x2b, 0x55, 0x1b, 0xfe, 0x71, 0x00, 0xf6, 0xc9, 0x35, 0x50,
+       0xd7, 0x1e, 0x02, 0x36, 0x8b, 0x75, 0xaa, 0x9c, 0xe8, 0xf4, 0x43, 0xe2,
+       0xd9, 0x3b, 0xac, 0x4c, 0xf9, 0xb2, 0x95, 0xb2, 0x97, 0x83, 0xac, 0x96,
+       0x33, 0xf2, 0x9f, 0xaa, 0x97, 0x54, 0xad, 0x75, 0x06, 0x79, 0x49, 0x68,
+       0x5a, 0xe5, 0x64, 0x0d, 0xf8, 0x16, 0x7e, 0xef, 0xd9, 0x2f, 0x62, 0x2d,
+       0x5a, 0xea, 0x4c, 0x83, 0x7e, 0xbe, 0x5e, 0x4f, 0xc1, 0x7f, 0xe8, 0xb6,
+       0x6d, 0x16, 0x10, 0x0f, 0x53, 0xea, 0x5c, 0x0c, 0xd7, 0xf1, 0x61, 0xe5,
+       0x9f, 0x65, 0x01, 0xb2, 0x39, 0x1b, 0xc3, 0x38, 0x9a, 0xb2, 0x4f, 0x43,
+       0xe9, 0xe1, 0x21, 0x85, 0x79, 0x8d, 0xf3, 0x70, 0x58, 0xcb, 0x3d, 0x22,
+       0xe7, 0x33, 0x32, 0x85, 0x35, 0x1c, 0x5a, 0xa6, 0x0e, 0x28, 0xdb, 0x31,
+       0x69, 0x82, 0xec, 0x4f, 0x00, 0x7b, 0x18, 0xd3, 0x94, 0x71, 0x14, 0xeb,
+       0xa2, 0x53, 0x42, 0x67, 0x21, 0xe3, 0x69, 0x60, 0x84, 0xb9, 0x66, 0x79,
+       0x69, 0x31, 0x90, 0xe9, 0xcb, 0x3c, 0xef, 0xaf, 0x8f, 0x0f, 0x74, 0x11,
+       0x47, 0x49, 0x65, 0x71, 0x4a, 0xa6, 0x66, 0x99, 0xb3, 0x8f, 0xa9, 0x33,
+       0x06, 0x21, 0x75, 0xc6, 0xc5, 0xcb, 0x99, 0xbd, 0x6f, 0x0f, 0x63, 0x56,
+       0x84, 0x7b, 0x6d, 0x02, 0xdb, 0xe9, 0xc7, 0xbc, 0x37, 0x92, 0xaf, 0x97,
+       0xab, 0x0e, 0x83, 0xde, 0x8b, 0x33, 0x56, 0x26, 0x2f, 0x0e, 0xcf, 0x5b,
+       0x8f, 0xba, 0xe0, 0x7f, 0x15, 0xfe, 0x73, 0xaa, 0x74, 0x2f, 0xf8, 0x2c,
+       0x60, 0x85, 0x65, 0xe4, 0x62, 0x91, 0x39, 0xe3, 0x47, 0xa1, 0x37, 0x5e,
+       0x17, 0x06, 0x0d, 0xf8, 0x81, 0x35, 0xf5, 0x7e, 0xa1, 0xe5, 0xae, 0x20,
+       0x87, 0x8d, 0x69, 0x87, 0xa0, 0xeb, 0xbc, 0xd9, 0xe4, 0xdb, 0x03, 0xdf,
+       0x35, 0x3e, 0x07, 0x3f, 0xba, 0x24, 0x7c, 0xef, 0xe7, 0x9d, 0x3a, 0xf3,
+       0xa5, 0xcb, 0xf0, 0x7b, 0x99, 0x78, 0x06, 0x36, 0x94, 0x8f, 0xb6, 0x80,
+       0xe6, 0xdf, 0xc6, 0xbd, 0x5c, 0x95, 0xf3, 0x58, 0xce, 0x9a, 0x14, 0x62,
+       0x21, 0xe9, 0x8b, 0x5d, 0x92, 0x6d, 0xf0, 0x64, 0x9a, 0xbc, 0x61, 0x5b,
+       0x83, 0xa2, 0xa9, 0xf1, 0x7a, 0x0f, 0xc0, 0x06, 0xaf, 0xc2, 0xdf, 0x35,
+       0xfb, 0xb9, 0x7e, 0xaa, 0x48, 0x0c, 0xf5, 0x84, 0x3a, 0x8b, 0x70, 0xd9,
+       0x66, 0x1d, 0x90, 0xef, 0xfb, 0xfe, 0x95, 0x9a, 0xe3, 0xfa, 0xde, 0x1d,
+       0xeb, 0xd0, 0xa4, 0xcf, 0xe3, 0x71, 0xbf, 0xed, 0xd1, 0xc8, 0x71, 0x9a,
+       0x1a, 0xc6, 0xb9, 0xe8, 0x8f, 0x73, 0xce, 0x1f, 0x67, 0xc1, 0x1f, 0xe7,
+       0xf2, 0xfa, 0x38, 0x0f, 0xc2, 0x0e, 0xea, 0xf5, 0xa7, 0x80, 0x37, 0x92,
+       0x4e, 0xbd, 0x9e, 0x46, 0x5e, 0x36, 0xd9, 0x3f, 0xa1, 0xf6, 0x5e, 0xf5,
+       0xc4, 0x8b, 0x43, 0x49, 0xdb, 0x93, 0x3f, 0xac, 0x40, 0x26, 0x60, 0x8f,
+       0x79, 0xf1, 0xb0, 0x3a, 0xf7, 0x03, 0xbd, 0xfd, 0xc2, 0x36, 0xf8, 0x81,
+       0xc7, 0x10, 0x4b, 0x9c, 0xe1, 0x25, 0x5b, 0xf2, 0x7b, 0x7e, 0x4d, 0x87,
+       0xbd, 0x77, 0x20, 0x2e, 0xbd, 0x09, 0xdb, 0x71, 0x86, 0x2b, 0x8b, 0x8f,
+       0xa9, 0x3d, 0xe1, 0xa6, 0xc4, 0xbd, 0xd0, 0x67, 0x79, 0x78, 0x61, 0xb1,
+       0x3c, 0x7c, 0x8e, 0xfb, 0x43, 0xe8, 0xb7, 0xb0, 0xd8, 0x0e, 0xb9, 0xb7,
+       0xab, 0xba, 0xca, 0xa5, 0x62, 0x04, 0x7a, 0x34, 0x61, 0xf3, 0x11, 0xb4,
+       0x45, 0x61, 0x07, 0x5d, 0x68, 0x7f, 0x0d, 0x6b, 0x3b, 0x86, 0xf6, 0xb5,
+       0xd6, 0x61, 0x85, 0x63, 0x6d, 0x39, 0x5f, 0xbd, 0x8a, 0x98, 0xfb, 0x16,
+       0xfc, 0x68, 0x2f, 0xfa, 0xf4, 0xa3, 0xcf, 0x0e, 0x13, 0xf8, 0x2a, 0x53,
+       0xbe, 0x21, 0x4d, 0x2e, 0x68, 0xd2, 0x1b, 0x68, 0x72, 0x41, 0x0f, 0x7c,
+       0xe7, 0x19, 0xd6, 0xa0, 0xfb, 0xe5, 0x64, 0x91, 0x67, 0xaa, 0xf8, 0xee,
+       0xb5, 0x29, 0x21, 0x60, 0xd2, 0xa6, 0x33, 0x56, 0x74, 0x45, 0xd5, 0x7a,
+       0x68, 0x5b, 0x7d, 0x4e, 0x45, 0x54, 0x9c, 0x89, 0x9d, 0x44, 0xfc, 0xba,
+       0x5a, 0x6d, 0x97, 0x37, 0xfc, 0xb9, 0xd6, 0x84, 0xfb, 0x97, 0x1b, 0xe7,
+       0x3a, 0x55, 0x1a, 0x1d, 0xfe, 0x81, 0x6d, 0xf8, 0x7c, 0x75, 0x62, 0xae,
+       0x76, 0xf4, 0x1d, 0x1d, 0xbe, 0xb8, 0x78, 0xa3, 0xbe, 0x13, 0xe8, 0xdb,
+       0xd4, 0xd0, 0x77, 0x02, 0xfd, 0xda, 0x11, 0x07, 0xdb, 0x15, 0x4f, 0x93,
+       0xa0, 0xeb, 0x4a, 0x51, 0xbd, 0x0b, 0x0c, 0xb9, 0x73, 0x4e, 0x93, 0x98,
+       0x3a, 0xe3, 0xd5, 0x4a, 0x2c, 0x33, 0xa6, 0xbd, 0xa7, 0xde, 0xa3, 0x6c,
+       0x60, 0xc8, 0x06, 0xee, 0x9d, 0x19, 0xd5, 0x52, 0x95, 0x1c, 0x62, 0xd6,
+       0x2e, 0xe2, 0x27, 0xc7, 0x45, 0xcc, 0x5c, 0xc0, 0x78, 0x8b, 0xc5, 0x15,
+       0x9e, 0xc1, 0x86, 0x5d, 0xbc, 0x4d, 0x9c, 0xbd, 0xcb, 0x50, 0x67, 0x1e,
+       0xd2, 0xaa, 0x66, 0xb7, 0x50, 0x14, 0x33, 0x39, 0xc0, 0x33, 0x0e, 0xf7,
+       0x63, 0x5d, 0x7e, 0x0e, 0x6d, 0x49, 0xc4, 0xc7, 0xc3, 0x5a, 0x72, 0x69,
+       0x18, 0xd7, 0x8f, 0xe0, 0x1a, 0xfe, 0x78, 0x2e, 0x8b, 0xfb, 0x8f, 0xe0,
+       0x7a, 0x42, 0x4b, 0xd5, 0xb2, 0xb8, 0x7e, 0x14, 0xd7, 0x49, 0x93, 0x79,
+       0xca, 0x0f, 0xec, 0x8c, 0xe6, 0x62, 0x2c, 0x77, 0x69, 0x18, 0x9f, 0xc6,
+       0xf1, 0x78, 0x0f, 0x7a, 0x2a, 0x72, 0xaf, 0x2d, 0x0e, 0x9a, 0x0e, 0x6a,
+       0xe9, 0x4a, 0x1b, 0xc6, 0xe8, 0xc1, 0xf3, 0xb4, 0xa9, 0x43, 0xfe, 0xfc,
+       0xac, 0x39, 0xdd, 0xad, 0x6a, 0x4e, 0x46, 0x22, 0x03, 0x9c, 0x7c, 0x1c,
+       0x79, 0x80, 0x26, 0x69, 0xfb, 0x49, 0x29, 0x38, 0xf0, 0x2b, 0x15, 0x43,
+       0x52, 0x91, 0x3c, 0x7e, 0xe7, 0x25, 0x39, 0x88, 0xfb, 0x15, 0xda, 0x02,
+       0xfb, 0xfd, 0x89, 0x14, 0xca, 0xc4, 0xfd, 0xac, 0x33, 0xb1, 0x36, 0xc5,
+       0xfa, 0x52, 0x0e, 0x32, 0x88, 0xd0, 0x7e, 0x6f, 0x50, 0x13, 0xf3, 0xce,
+       0x55, 0x23, 0x2e, 0x6b, 0xc9, 0x0a, 0xf7, 0xfd, 0xdc, 0xcc, 0x45, 0x9b,
+       0xef, 0x28, 0x4d, 0x70, 0x1f, 0xb1, 0x60, 0x24, 0x58, 0x1f, 0x51, 0xf5,
+       0x75, 0xc7, 0xdb, 0x1f, 0xe4, 0xb8, 0x63, 0xe0, 0xb7, 0xb1, 0x6e, 0xc5,
+       0x79, 0xbf, 0x80, 0xe7, 0xbd, 0x7a, 0x56, 0xaa, 0xf6, 0x5e, 0x5d, 0xf0,
+       0xbd, 0x81, 0xf3, 0xd0, 0xc5, 0x45, 0x95, 0x1b, 0x73, 0x0f, 0xf7, 0xfd,
+       0x72, 0x2a, 0xe4, 0x30, 0x45, 0xd6, 0xc8, 0x82, 0x7d, 0xbb, 0x40, 0x8e,
+       0x9b, 0x69, 0x25, 0x9d, 0x47, 0x30, 0xa6, 0x38, 0xf4, 0xbb, 0xd9, 0x08,
+       0xf7, 0xdf, 0xf8, 0x8c, 0x7c, 0xf9, 0x3a, 0xdd, 0xa4, 0x99, 0xf2, 0x38,
+       0x0e, 0xff, 0xc9, 0x77, 0x32, 0x9e, 0x94, 0x9c, 0xc3, 0x1a, 0x8f, 0x81,
+       0xd8, 0x98, 0xc7, 0xef, 0xeb, 0xf2, 0x9b, 0xf4, 0xe5, 0x97, 0x2b, 0xbf,
+       0xa4, 0x74, 0xb8, 0x60, 0x73, 0xbe, 0xa0, 0xf6, 0x31, 0xa2, 0x74, 0xb7,
+       0xa0, 0xce, 0xfd, 0x06, 0x32, 0x08, 0xea, 0x77, 0x37, 0xb6, 0xbd, 0x61,
+       0x9b, 0xb4, 0xdd, 0xce, 0xf3, 0x10, 0xbd, 0xae, 0x90, 0x7e, 0xf2, 0xc1,
+       0x18, 0x16, 0xec, 0xb5, 0x06, 0x3c, 0x04, 0x7c, 0xde, 0xaa, 0x7c, 0x48,
+       0x6f, 0x64, 0xbb, 0xb4, 0x65, 0x4c, 0xc3, 0x66, 0x6c, 0xf8, 0x84, 0xbf,
+       0x3f, 0xf0, 0x77, 0x21, 0x67, 0x4f, 0x16, 0xa1, 0x84, 0x4c, 0xfa, 0xef,
+       0xf8, 0xde, 0xc0, 0x1e, 0x36, 0xef, 0x35, 0xbb, 0x99, 0x73, 0xf6, 0x75,
+       0xbe, 0x17, 0x6e, 0xc0, 0xf7, 0x82, 0xcf, 0x77, 0xe5, 0x16, 0xe9, 0x5d,
+       0x98, 0x71, 0xc1, 0x33, 0x6d, 0xee, 0x46, 0xf6, 0x28, 0xea, 0x7f, 0x5f,
+       0xac, 0x19, 0xe1, 0xb0, 0x5b, 0xbd, 0x59, 0x0d, 0x95, 0x79, 0xb5, 0x67,
+       0x97, 0xe7, 0x10, 0x0b, 0xcb, 0x65, 0x2f, 0xc7, 0x2e, 0x57, 0x59, 0xcb,
+       0x7e, 0x3f, 0x1a, 0xf8, 0xfe, 0xd7, 0x67, 0xd4, 0x79, 0x97, 0xc9, 0xaa,
+       0x57, 0xf7, 0x2a, 0x97, 0x1b, 0x63, 0xea, 0x0e, 0xc6, 0xd3, 0xde, 0xbc,
+       0x8c, 0xf2, 0xbd, 0x65, 0x5c, 0xef, 0x96, 0x4b, 0x73, 0x6a, 0xcf, 0xca,
+       0xdf, 0x1b, 0xe2, 0x9e, 0x8f, 0xda, 0xff, 0x86, 0x5f, 0x1b, 0x53, 0x7e,
+       0x7d, 0x75, 0x4e, 0xdd, 0xf3, 0xb0, 0x52, 0x75, 0x14, 0x7e, 0x1f, 0xb9,
+       0x84, 0xbd, 0x55, 0x0a, 0xc8, 0xb9, 0xcf, 0xd9, 0x0f, 0x6f, 0x27, 0xce,
+       0xe1, 0x58, 0xab, 0x18, 0xeb, 0xe2, 0x9c, 0x6c, 0xe7, 0x99, 0x92, 0xb2,
+       0xda, 0x67, 0xf3, 0xea, 0xe2, 0x13, 0x12, 0xfc, 0x4f, 0x88, 0xb0, 0x1f,
+       0x0b, 0x79, 0xae, 0x85, 0xef, 0xd2, 0xd2, 0x57, 0x20, 0x0f, 0x1a, 0xe5,
+       0x3e, 0x4e, 0xbd, 0xee, 0xd5, 0xcd, 0xeb, 0x58, 0x17, 0x4d, 0x7c, 0xef,
+       0x02, 0x7f, 0xc7, 0x61, 0x3f, 0x58, 0x27, 0xeb, 0xed, 0xbc, 0x66, 0xee,
+       0x11, 0x5c, 0x33, 0xb0, 0xfd, 0x3f, 0xd4, 0x46, 0x90, 0x7c, 0xb4, 0x45,
+       0x00, 0x00, 0x00 };
 
 static const u32 bnx2_TXP_b09FwData[(0xd0/4) + 1] = {
        0x00000000, 0x00000014, 0x00000014, 0x00000014, 0x00000014, 0x00000010,
@@ -4041,37 +4065,38 @@ static const u32 bnx2_TXP_b09FwData[(0xd0/4) + 1] = {
        0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
        0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
 static const u32 bnx2_TXP_b09FwRodata[(0x30/4) + 1] = {
-       0x08004060, 0x0800408c, 0x080040d4, 0x080040d4, 0x08003f60, 0x08003f8c,
-       0x08003f8c, 0x080040d4, 0x080040d4, 0x080040d4, 0x08003ff4, 0x00000000,
+       0x08003fdc, 0x08004008, 0x08004050, 0x08004050, 0x08003edc, 0x08003f08,
+       0x08003f08, 0x08004050, 0x08004050, 0x08004050, 0x08003f70, 0x00000000,
        0x00000000 };
 
 static struct fw_info bnx2_txp_fw_09 = {
+       /* Firmware version:  3.7.1 */
        .ver_major                      = 0x3,
-       .ver_minor                      = 0x4,
-       .ver_fix                        = 0x3,
+       .ver_minor                      = 0x7,
+       .ver_fix                        = 0x1,
 
        .start_addr                     = 0x08000060,
 
        .text_addr                      = 0x08000000,
-       .text_len                       = 0x4634,
+       .text_len                       = 0x45b0,
        .text_index                     = 0x0,
        .gz_text                        = bnx2_TXP_b09FwText,
        .gz_text_len                    = sizeof(bnx2_TXP_b09FwText),
 
-       .data_addr                      = 0x08004680,
+       .data_addr                      = 0x08004600,
        .data_len                       = 0xd0,
        .data_index                     = 0x0,
        .data                           = bnx2_TXP_b09FwData,
 
-       .sbss_addr                      = 0x08004750,
+       .sbss_addr                      = 0x080046d0,
        .sbss_len                       = 0x8c,
        .sbss_index                     = 0x0,
 
-       .bss_addr                       = 0x080047e0,
+       .bss_addr                       = 0x08004760,
        .bss_len                        = 0xa20,
        .bss_index                      = 0x0,
 
-       .rodata_addr                    = 0x08004638,
+       .rodata_addr                    = 0x080045b0,
        .rodata_len                     = 0x30,
        .rodata_index                   = 0x0,
        .rodata                         = bnx2_TXP_b09FwRodata,
index 7a045a37056e0de7a93e6d44d296e1801f48db6b..084f0292ea6e13d029244564b112b1a0582a8c34 100644 (file)
@@ -126,7 +126,7 @@ static struct aggregator *__get_active_agg(struct aggregator *aggregator);
 
 // ================= main 802.3ad protocol functions ==================
 static int ad_lacpdu_send(struct port *port);
-static int ad_marker_send(struct port *port, struct marker *marker);
+static int ad_marker_send(struct port *port, struct bond_marker *marker);
 static void ad_mux_machine(struct port *port);
 static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port);
 static void ad_tx_machine(struct port *port);
@@ -139,8 +139,8 @@ static void ad_initialize_port(struct port *port, int lacp_fast);
 static void ad_initialize_lacpdu(struct lacpdu *Lacpdu);
 static void ad_enable_collecting_distributing(struct port *port);
 static void ad_disable_collecting_distributing(struct port *port);
-static void ad_marker_info_received(struct marker *marker_info, struct port *port);
-static void ad_marker_response_received(struct marker *marker, struct port *port);
+static void ad_marker_info_received(struct bond_marker *marker_info, struct port *port);
+static void ad_marker_response_received(struct bond_marker *marker, struct port *port);
 
 
 /////////////////////////////////////////////////////////////////////////////////
@@ -889,12 +889,12 @@ static int ad_lacpdu_send(struct port *port)
  * Returns:   0 on success
  *          < 0 on error
  */
-static int ad_marker_send(struct port *port, struct marker *marker)
+static int ad_marker_send(struct port *port, struct bond_marker *marker)
 {
        struct slave *slave = port->slave;
        struct sk_buff *skb;
-       struct marker_header *marker_header;
-       int length = sizeof(struct marker_header);
+       struct bond_marker_header *marker_header;
+       int length = sizeof(struct bond_marker_header);
        struct mac_addr lacpdu_multicast_address = AD_MULTICAST_LACPDU_ADDR;
 
        skb = dev_alloc_skb(length + 16);
@@ -909,7 +909,7 @@ static int ad_marker_send(struct port *port, struct marker *marker)
        skb->network_header = skb->mac_header + ETH_HLEN;
        skb->protocol = PKT_TYPE_LACPDU;
 
-       marker_header = (struct marker_header *)skb_put(skb, length);
+       marker_header = (struct bond_marker_header *)skb_put(skb, length);
 
        marker_header->ad_header.destination_address = lacpdu_multicast_address;
        /* Note: source addres is set to be the member's PERMANENT address, because we use it
@@ -1709,7 +1709,7 @@ static void ad_disable_collecting_distributing(struct port *port)
  */
 static void ad_marker_info_send(struct port *port)
 {
-       struct marker marker;
+       struct bond_marker marker;
        u16 index;
 
        // fill the marker PDU with the appropriate values
@@ -1742,13 +1742,14 @@ static void ad_marker_info_send(struct port *port)
  * @port: the port we're looking at
  *
  */
-static void ad_marker_info_received(struct marker *marker_info,struct port *port)
+static void ad_marker_info_received(struct bond_marker *marker_info,
+       struct port *port)
 {
-       struct marker marker;
+       struct bond_marker marker;
 
        // copy the received marker data to the response marker
        //marker = *marker_info;
-       memcpy(&marker, marker_info, sizeof(struct marker));
+       memcpy(&marker, marker_info, sizeof(struct bond_marker));
        // change the marker subtype to marker response
        marker.tlv_type=AD_MARKER_RESPONSE_SUBTYPE;
        // send the marker response
@@ -1767,7 +1768,8 @@ static void ad_marker_info_received(struct marker *marker_info,struct port *port
  * response for marker PDU's, in this stage, but only to respond to marker
  * information.
  */
-static void ad_marker_response_received(struct marker *marker, struct port *port)
+static void ad_marker_response_received(struct bond_marker *marker,
+       struct port *port)
 {
        marker=NULL; // just to satisfy the compiler
        port=NULL;  // just to satisfy the compiler
@@ -2164,15 +2166,15 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u
                case AD_TYPE_MARKER:
                        // No need to convert fields to Little Endian since we don't use the marker's fields.
 
-                       switch (((struct marker *)lacpdu)->tlv_type) {
+                       switch (((struct bond_marker *)lacpdu)->tlv_type) {
                        case AD_MARKER_INFORMATION_SUBTYPE:
                                dprintk("Received Marker Information on port %d\n", port->actor_port_number);
-                               ad_marker_info_received((struct marker *)lacpdu, port);
+                               ad_marker_info_received((struct bond_marker *)lacpdu, port);
                                break;
 
                        case AD_MARKER_RESPONSE_SUBTYPE:
                                dprintk("Received Marker Response on port %d\n", port->actor_port_number);
-                               ad_marker_response_received((struct marker *)lacpdu, port);
+                               ad_marker_response_received((struct bond_marker *)lacpdu, port);
                                break;
 
                        default:
index 862952fa6fd99e84962d2187699c2c1255f1684d..f16557264944eab308bd7d778e035de1f6bf6cac 100644 (file)
@@ -92,7 +92,7 @@ typedef enum {
 typedef enum {
        AD_MARKER_INFORMATION_SUBTYPE = 1, // marker imformation subtype
        AD_MARKER_RESPONSE_SUBTYPE     // marker response subtype
-} marker_subtype_t;
+} bond_marker_subtype_t;
 
 // timers types(43.4.9 in the 802.3ad standard)
 typedef enum {
@@ -148,7 +148,7 @@ typedef struct lacpdu_header {
 } lacpdu_header_t;
 
 // Marker Protocol Data Unit(PDU) structure(43.5.3.2 in the 802.3ad standard)
-typedef struct marker {
+typedef struct bond_marker {
        u8 subtype;              //  = 0x02  (marker PDU)
        u8 version_number;       //  = 0x01
        u8 tlv_type;             //  = 0x01  (marker information)
@@ -161,12 +161,12 @@ typedef struct marker {
        u8 tlv_type_terminator;      //  = 0x00
        u8 terminator_length;        //  = 0x00
        u8 reserved_90[90];          //  = 0
-} marker_t;
+} bond_marker_t;
 
-typedef struct marker_header {
+typedef struct bond_marker_header {
        struct ad_header ad_header;
-       struct marker marker;
-} marker_header_t;
+       struct bond_marker marker;
+} bond_marker_header_t;
 
 #pragma pack()
 
index 80c0c8c415ed527c470dd371a27a4669cd3afcc0..855dc10ffa1b8aea624816bd299e0689b314309d 100644 (file)
@@ -55,7 +55,7 @@ static int expected_refcount = -1;
 static struct class *netdev_class;
 /*--------------------------- Data Structures -----------------------------*/
 
-/* Bonding sysfs lock.  Why can't we just use the subsytem lock?
+/* Bonding sysfs lock.  Why can't we just use the subsystem lock?
  * Because kobject_register tries to acquire the subsystem lock.  If
  * we already hold the lock (which we would if the user was creating
  * a new bond through the sysfs interface), we deadlock.
index ed53aaab4c027a209d90a0b337d8e36bc3bd15c7..ae419736158eda973e556c81fa1be8c586947503 100644 (file)
@@ -471,7 +471,7 @@ static int cpmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
        }
 
        len = max(skb->len, ETH_ZLEN);
-       queue = skb->queue_mapping;
+       queue = skb_get_queue_mapping(skb);
 #ifdef CONFIG_NETDEVICES_MULTIQUEUE
        netif_stop_subqueue(dev, queue);
 #else
index 314b2f68f78fc14f6140aa743aca4910c1da7a93..edd6828f0a78c594649b3f354836cffe56066939 100644 (file)
 #include <linux/spinlock.h>
 #include <linux/errno.h>
 #include <linux/init.h>
+#include <linux/bitops.h>
 
 #include <linux/if.h>
 #include <linux/mii.h>
 #include <asm/irq.h>
 #include <asm/dma.h>
 #include <asm/system.h>
-#include <asm/bitops.h>
 #include <asm/ethernet.h>
 #include <asm/cache.h>
 
index 044261703381a86439adcdab0f4808834cd1aa09..2a3df145850d8e5004a6485b1be976fe93b5fa8d 100644 (file)
@@ -41,9 +41,9 @@
 #include <linux/timer.h>
 #include <linux/cache.h>
 #include <linux/mutex.h>
+#include <linux/bitops.h>
 #include "t3cdev.h"
 #include <asm/semaphore.h>
-#include <asm/bitops.h>
 #include <asm/io.h>
 
 typedef irqreturn_t(*intr_handler_t) (int, void *);
index 27ac010900abd7ffce88ee26973569161606f567..3286d2a0a870568c3cb8f857be65526bfa4a8d20 100644 (file)
@@ -542,7 +542,8 @@ dm9000_probe(struct platform_device *pdev)
 
        if (id_val != DM9000_ID) {
                printk("%s: wrong id: 0x%08x\n", CARDNAME, id_val);
-               goto release;
+               ret = -ENODEV;
+               goto out;
        }
 
        /* from this point we assume that we have found a DM9000 */
@@ -602,8 +603,7 @@ dm9000_probe(struct platform_device *pdev)
        }
        return 0;
 
- release:
- out:
+out:
        printk("%s: not found (%d).\n", CARDNAME, ret);
 
        dm9000_release_board(pdev, db);
index 64f35e20fd48f60a9a31b70e34b1df69e25d64c1..3dbaec680b462de47ff738ed5ab14cbf8cedf111 100644 (file)
@@ -1324,7 +1324,7 @@ static inline int e100_exec_cb_wait(struct nic *nic, struct sk_buff *skb,
                if (!--counter) break;
        }
 
-       /* ack any interupts, something could have been set */
+       /* ack any interrupts, something could have been set */
        iowrite8(~0, &nic->csr->scb.stat_ack);
 
        /* if the command failed, or is not OK, notify and return */
index 047263830e6a36c5c73921f25da4d23deb0253a5..f1ce348470cc14afa6e8ea68eeb0875d4b927094 100644 (file)
@@ -3590,7 +3590,7 @@ e1000_update_stats(struct e1000_adapter *adapter)
 
        spin_lock_irqsave(&adapter->stats_lock, flags);
 
-       /* these counters are modified from e1000_adjust_tbi_stats,
+       /* these counters are modified from e1000_tbi_adjust_stats,
         * called from the interrupt context, so they must only
         * be written while holding adapter->stats_lock
         */
index fe5ffac7ac5746acc2798759c44f2cbb62bdaf81..2809c99906e093682f91d0f8e7cfc765905cd94f 100644 (file)
@@ -3218,7 +3218,7 @@ static int __devinit ehea_probe_adapter(struct of_device *dev,
        /* get adapter properties */
        ret = ehea_sense_adapter_attr(adapter);
        if (ret) {
-               dev_err(&dev->dev, "sense_adapter_attr failed: %d", ret);
+               dev_err(&dev->dev, "sense_adapter_attr failed: %d\n", ret);
                goto out_free_ad;
        }
 
@@ -3226,7 +3226,7 @@ static int __devinit ehea_probe_adapter(struct of_device *dev,
                                      EHEA_NEQ, EHEA_MAX_ENTRIES_EQ, 1);
        if (!adapter->neq) {
                ret = -EIO;
-               dev_err(&dev->dev, "NEQ creation failed");
+               dev_err(&dev->dev, "NEQ creation failed\n");
                goto out_free_ad;
        }
 
@@ -3237,7 +3237,7 @@ static int __devinit ehea_probe_adapter(struct of_device *dev,
                                  ehea_interrupt_neq, IRQF_DISABLED,
                                  "ehea_neq", adapter);
        if (ret) {
-               dev_err(&dev->dev, "requesting NEQ IRQ failed");
+               dev_err(&dev->dev, "requesting NEQ IRQ failed\n");
                goto out_kill_eq;
        }
 
@@ -3247,7 +3247,7 @@ static int __devinit ehea_probe_adapter(struct of_device *dev,
 
        ret = ehea_setup_ports(adapter);
        if (ret) {
-               dev_err(&dev->dev, "setup_ports failed");
+               dev_err(&dev->dev, "setup_ports failed\n");
                goto out_rem_dev_sysfs;
        }
 
index 243fc6b354b5effd99030e2fee51efaf9dc9b78b..e3dd8b1369086369f10f30be29a6b716ff2ec552 100644 (file)
@@ -170,7 +170,6 @@ static char *version =
 
 
 /* Few macros */
-#define BIT(a)                ( (1 << (a)) )
 #define BITSET(ioaddr, bnum)   ((outb(((inb(ioaddr)) | (bnum)), ioaddr)))
 #define BITCLR(ioaddr, bnum)   ((outb(((inb(ioaddr)) & (~(bnum))), ioaddr)))
 
index 43f7647ff24631f2142ac6e68be404a4fc723eab..7bb9c728a1d311367e07a0ddc611a24cf059c77c 100644 (file)
@@ -111,7 +111,6 @@ MODULE_AUTHOR("Myson or whoever");
 MODULE_DESCRIPTION("Myson MTD-8xx 100/10M Ethernet PCI Adapter Driver");
 MODULE_LICENSE("GPL");
 module_param(max_interrupt_work, int, 0);
-//MODULE_PARM(min_pci_latency, "i");
 module_param(debug, int, 0);
 module_param(rx_copybreak, int, 0);
 module_param(multicast_filter_limit, int, 0);
index 2b5782056ddae658343fd0f280ee05b38d2420d5..0fbf1bbbaee9972a56ab6f4d13eb31f00ed40c2c 100644 (file)
@@ -751,13 +751,11 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi
                if (mii_head) {
                        mii_tail->mii_next = mip;
                        mii_tail = mip;
-               }
-               else {
+               } else {
                        mii_head = mii_tail = mip;
                        fep->hwp->fec_mii_data = regval;
                }
-       }
-       else {
+       } else {
                retval = 1;
        }
 
@@ -768,14 +766,11 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi
 
 static void mii_do_cmd(struct net_device *dev, const phy_cmd_t *c)
 {
-       int k;
-
        if(!c)
                return;
 
-       for(k = 0; (c+k)->mii_data != mk_mii_end; k++) {
-               mii_queue(dev, (c+k)->mii_data, (c+k)->funct);
-       }
+       for (; c->mii_data != mk_mii_end; c++)
+               mii_queue(dev, c->mii_data, c->funct);
 }
 
 static void mii_parse_sr(uint mii_reg, struct net_device *dev)
@@ -792,7 +787,6 @@ static void mii_parse_sr(uint mii_reg, struct net_device *dev)
                status |= PHY_STAT_FAULT;
        if (mii_reg & 0x0020)
                status |= PHY_STAT_ANC;
-
        *s = status;
 }
 
@@ -1239,7 +1233,6 @@ mii_link_interrupt(int irq, void * dev_id);
 #endif
 
 #if defined(CONFIG_M5272)
-
 /*
  *     Code specific to Coldfire 5272 setup.
  */
@@ -2020,8 +2013,7 @@ static void mii_relink(struct work_struct *work)
                    & (PHY_STAT_100FDX | PHY_STAT_10FDX))
                        duplex = 1;
                fec_restart(dev, duplex);
-       }
-       else
+       } else
                fec_stop(dev);
 
 #if 0
@@ -2119,8 +2111,7 @@ mii_discover_phy(uint mii_reg, struct net_device *dev)
                        fep->phy_id = phytype << 16;
                        mii_queue(dev, mk_mii_read(MII_REG_PHYIR2),
                                                        mii_discover_phy3);
-               }
-               else {
+               } else {
                        fep->phy_addr++;
                        mii_queue(dev, mk_mii_read(MII_REG_PHYIR1),
                                                        mii_discover_phy);
@@ -2574,8 +2565,7 @@ fec_restart(struct net_device *dev, int duplex)
        if (duplex) {
                fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;/* MII enable */
                fecp->fec_x_cntrl = 0x04;                 /* FD enable */
-       }
-       else {
+       } else {
                /* MII enable|No Rcv on Xmit */
                fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x06;
                fecp->fec_x_cntrl = 0x00;
index cfbb7aacfe94bc5f46a1d0da4fbdb7349a1633a5..70ddf1acfd88f1382e40f42b3e029dafb8b80045 100644 (file)
@@ -992,7 +992,7 @@ static void nv_enable_irq(struct net_device *dev)
                if (np->msi_flags & NV_MSI_X_ENABLED)
                        enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
                else
-                       enable_irq(dev->irq);
+                       enable_irq(np->pci_dev->irq);
        } else {
                enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
                enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector);
@@ -1008,7 +1008,7 @@ static void nv_disable_irq(struct net_device *dev)
                if (np->msi_flags & NV_MSI_X_ENABLED)
                        disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
                else
-                       disable_irq(dev->irq);
+                       disable_irq(np->pci_dev->irq);
        } else {
                disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
                disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector);
@@ -1607,7 +1607,7 @@ static void nv_do_rx_refill(unsigned long data)
                if (np->msi_flags & NV_MSI_X_ENABLED)
                        disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
                else
-                       disable_irq(dev->irq);
+                       disable_irq(np->pci_dev->irq);
        } else {
                disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
        }
@@ -1625,7 +1625,7 @@ static void nv_do_rx_refill(unsigned long data)
                if (np->msi_flags & NV_MSI_X_ENABLED)
                        enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
                else
-                       enable_irq(dev->irq);
+                       enable_irq(np->pci_dev->irq);
        } else {
                enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
        }
@@ -2408,13 +2408,13 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit)
        struct fe_priv *np = netdev_priv(dev);
        u32 flags;
        u32 vlanflags = 0;
-       u32 rx_processed_cnt = 0;
+       int rx_work = 0;
        struct sk_buff *skb;
        int len;
 
        while((np->get_rx.ex != np->put_rx.ex) &&
              !((flags = le32_to_cpu(np->get_rx.ex->flaglen)) & NV_RX2_AVAIL) &&
-             (rx_processed_cnt++ < limit)) {
+             (rx_work < limit)) {
 
                dprintk(KERN_DEBUG "%s: nv_rx_process_optimized: flags 0x%x.\n",
                                        dev->name, flags);
@@ -2517,9 +2517,11 @@ next_pkt:
                        np->get_rx.ex = np->first_rx.ex;
                if (unlikely(np->get_rx_ctx++ == np->last_rx_ctx))
                        np->get_rx_ctx = np->first_rx_ctx;
+
+               rx_work++;
        }
 
-       return rx_processed_cnt;
+       return rx_work;
 }
 
 static void set_bufsize(struct net_device *dev)
@@ -3558,10 +3560,12 @@ static int nv_request_irq(struct net_device *dev, int intr_test)
        if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) {
                if ((ret = pci_enable_msi(np->pci_dev)) == 0) {
                        np->msi_flags |= NV_MSI_ENABLED;
+                       dev->irq = np->pci_dev->irq;
                        if (request_irq(np->pci_dev->irq, handler, IRQF_SHARED, dev->name, dev) != 0) {
                                printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret);
                                pci_disable_msi(np->pci_dev);
                                np->msi_flags &= ~NV_MSI_ENABLED;
+                               dev->irq = np->pci_dev->irq;
                                goto out_err;
                        }
 
@@ -3624,7 +3628,7 @@ static void nv_do_nic_poll(unsigned long data)
                if (np->msi_flags & NV_MSI_X_ENABLED)
                        disable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
                else
-                       disable_irq_lockdep(dev->irq);
+                       disable_irq_lockdep(np->pci_dev->irq);
                mask = np->irqmask;
        } else {
                if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) {
@@ -3642,6 +3646,8 @@ static void nv_do_nic_poll(unsigned long data)
        }
        np->nic_poll_irq = 0;
 
+       /* disable_irq() contains synchronize_irq, thus no irq handler can run now */
+
        if (np->recover_error) {
                np->recover_error = 0;
                printk(KERN_INFO "forcedeth: MAC in recoverable error state\n");
@@ -3678,7 +3684,6 @@ static void nv_do_nic_poll(unsigned long data)
                }
        }
 
-       /* FIXME: Do we need synchronize_irq(dev->irq) here? */
 
        writel(mask, base + NvRegIrqMask);
        pci_push(base);
@@ -3691,7 +3696,7 @@ static void nv_do_nic_poll(unsigned long data)
                if (np->msi_flags & NV_MSI_X_ENABLED)
                        enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
                else
-                       enable_irq_lockdep(dev->irq);
+                       enable_irq_lockdep(np->pci_dev->irq);
        } else {
                if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) {
                        nv_nic_irq_rx(0, dev);
@@ -4948,7 +4953,7 @@ static int nv_close(struct net_device *dev)
 #ifdef CONFIG_FORCEDETH_NAPI
        napi_disable(&np->napi);
 #endif
-       synchronize_irq(dev->irq);
+       synchronize_irq(np->pci_dev->irq);
 
        del_timer_sync(&np->oom_kick);
        del_timer_sync(&np->nic_poll);
index 04c6faec88d2e5154007adce7c5e0cf0906e3e05..f2a4d399a6e5137f63fab69a52677317d6d7c9c9 100644 (file)
@@ -88,7 +88,7 @@ static void skb_align(struct sk_buff *skb, int align)
 static int fs_enet_rx_napi(struct napi_struct *napi, int budget)
 {
        struct fs_enet_private *fep = container_of(napi, struct fs_enet_private, napi);
-       struct net_device *dev = to_net_dev(fep->dev);
+       struct net_device *dev = fep->ndev;
        const struct fs_platform_info *fpi = fep->fpi;
        cbd_t __iomem *bdp;
        struct sk_buff *skb, *skbn, *skbt;
@@ -217,7 +217,7 @@ static int fs_enet_rx_napi(struct napi_struct *napi, int budget)
 
        fep->cur_rx = bdp;
 
-       if (received >= budget) {
+       if (received < budget) {
                /* done */
                netif_rx_complete(dev, napi);
                (*fep->ops->napi_enable_rx)(dev);
@@ -807,20 +807,23 @@ static int fs_enet_open(struct net_device *dev)
        int r;
        int err;
 
-       napi_enable(&fep->napi);
+       if (fep->fpi->use_napi)
+               napi_enable(&fep->napi);
 
        /* Install our interrupt handler. */
        r = fs_request_irq(dev, fep->interrupt, "fs_enet-mac", fs_enet_interrupt);
        if (r != 0) {
                printk(KERN_ERR DRV_MODULE_NAME
                       ": %s Could not allocate FS_ENET IRQ!", dev->name);
-               napi_disable(&fep->napi);
+               if (fep->fpi->use_napi)
+                       napi_disable(&fep->napi);
                return -EINVAL;
        }
 
        err = fs_init_phy(dev);
-       if(err) {
-               napi_disable(&fep->napi);
+       if (err) {
+               if (fep->fpi->use_napi)
+                       napi_disable(&fep->napi);
                return err;
        }
        phy_start(fep->phydev);
@@ -1232,7 +1235,7 @@ static int __devinit fs_enet_probe(struct of_device *ofdev,
        fpi->rx_ring = 32;
        fpi->tx_ring = 32;
        fpi->rx_copybreak = 240;
-       fpi->use_napi = 0;
+       fpi->use_napi = 1;
        fpi->napi_weight = 17;
 
        ret = find_phy(ofdev->node, fpi);
@@ -1249,11 +1252,11 @@ static int __devinit fs_enet_probe(struct of_device *ofdev,
                goto out_free_fpi;
        }
 
-       SET_MODULE_OWNER(ndev);
        dev_set_drvdata(&ofdev->dev, ndev);
 
        fep = netdev_priv(ndev);
        fep->dev = &ofdev->dev;
+       fep->ndev = ndev;
        fep->fpi = fpi;
        fep->ops = match->data;
 
@@ -1288,10 +1291,11 @@ static int __devinit fs_enet_probe(struct of_device *ofdev,
        ndev->stop = fs_enet_close;
        ndev->get_stats = fs_enet_get_stats;
        ndev->set_multicast_list = fs_set_multicast_list;
-       if (fpi->use_napi) {
-               ndev->poll = fs_enet_rx_napi;
-               ndev->weight = fpi->napi_weight;
-       }
+
+       if (fpi->use_napi)
+               netif_napi_add(ndev, &fep->napi, fs_enet_rx_napi,
+                              fpi->napi_weight);
+
        ndev->ethtool_ops = &fs_ethtool_ops;
        ndev->do_ioctl = fs_ioctl;
 
index baf6477165af182450adb1cad6037456676ef416..c675e29aadcc39c9e4e1abf3727a5a3a952064c8 100644 (file)
@@ -75,6 +75,7 @@ struct phy_info {
 struct fs_enet_private {
        struct napi_struct napi;
        struct device *dev;     /* pointer back to the device (must be initialized first) */
+       struct net_device *ndev;
        spinlock_t lock;        /* during all ops except TX pckt processing */
        spinlock_t tx_lock;     /* during fs_start_xmit and fs_tx         */
        struct fs_platform_info *fpi;
index cc288d8f6a53cc936882c49c19920cc4590ba1c2..38268d7335a8803914a2adb9c59b84a5a9246e5f 100644 (file)
@@ -956,10 +956,12 @@ static int gfar_enet_open(struct net_device *dev)
        }
 
        err = startup_gfar(dev);
-       if (err)
+       if (err) {
 #ifdef CONFIG_GFAR_NAPI
                napi_disable(&priv->napi);
 #endif
+               return err;
+       }
 
        netif_start_queue(dev);
 
index c16cc8b946a92be6a762495b5b7c0c4cf0eb521a..46cd7735e6fe39f1671b80a0df321217ffb603f7 100644 (file)
@@ -749,7 +749,6 @@ struct gfar_private {
        uint32_t msg_enable;
 
        /* Network Statistics */
-       struct net_device_stats stats;
        struct gfar_extra_stats extra_stats;
 };
 
index ad9e327c3b0366a99cd670d8be71dbdc64af6b12..e0119f6a3319b2fca40af251d7bd3bf09dcde038 100644 (file)
@@ -3,7 +3,7 @@
  *             devices like TTY. It interfaces between a raw TTY and the
  *             kernel's AX.25 protocol layers.
  *
- * Authors:    Andreas Könsgen <ajk@iehk.rwth-aachen.de>
+ * Authors:    Andreas Könsgen <ajk@iehk.rwth-aachen.de>
  *              Ralf Baechle DL5RB <ralf@linux-mips.org>
  *
  * Quite a lot of stuff "stolen" by Joerg Reuter from slip.c, written by
index 36d2c7d4f4d089ab3e22ab559ef5a00a336a2e16..62d5d5cfd6a60de74a241d4ad76bf1cfbc03e600 100644 (file)
@@ -64,7 +64,7 @@ config DMASCC
          dmascc. If you don't pass any parameter to the driver, all
          possible I/O addresses are probed. This could irritate other devices
          that are currently not in use. You may specify the list of addresses
-         to be probed by "dmascc=addr1,addr2,..." (when compiled into the
+         to be probed by "dmascc.io=addr1,addr2,..." (when compiled into the
          kernel image) or "io=addr1,addr2,..." (when loaded as a module). The
          network interfaces will be called dmascc0 and dmascc1 for the board
          detected first, dmascc2 and dmascc3 for the second one, and so on.
index bc02e469480401274cee6e7f771f9ab62afe3c0e..11b83dae00ac762f8732ccefaf92ab92716a9959 100644 (file)
@@ -21,6 +21,7 @@
 
 
 #include <linux/module.h>
+#include <linux/bitops.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/if_arp.h>
@@ -35,7 +36,6 @@
 #include <linux/sockios.h>
 #include <linux/workqueue.h>
 #include <asm/atomic.h>
-#include <asm/bitops.h>
 #include <asm/dma.h>
 #include <asm/io.h>
 #include <asm/irq.h>
index a680eb05ba60149fe7fa7dc870d16885758abddf..9a88f71db004ee0e328027e4bd5864271a4050a8 100644 (file)
@@ -322,7 +322,7 @@ void mal_poll_disable(struct mal_instance *mal, struct mal_commac *commac)
                msleep(1);
 
        /* Synchronize with the MAL NAPI poller */
-       __napi_synchronize(&mal->napi);
+       napi_synchronize(&mal->napi);
 }
 
 void mal_poll_enable(struct mal_instance *mal, struct mal_commac *commac)
index ccf6ec548a6464a3e51c1945796a0f7842d5977d..736d2473b7e164c3d16d3b61bf8179eac2321078 100644 (file)
@@ -21,7 +21,7 @@
  *     published by the Free Software Foundation; either version 2 of 
  *     the License, or (at your option) any later version.
  *  
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is 
  *     provided "AS-IS" and at no charge.
  *     
index b2e31f4a384c96153cadeb9a6be48b35577a58b4..ae0b80a5680c77fb4c40d3fcf9ae8a52f4f30163 100644 (file)
@@ -19,7 +19,7 @@
  *     published by the Free Software Foundation; either version 2 of 
  *     the License, or (at your option) any later version.
  *  
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is 
  *     provided "AS-IS" and at no charge.
  *     
index a82d8f98383d82160d6548549b9def1c7071472c..1257e1a7e819f74411b5e5b7010fa9bb7ea25b2f 100644 (file)
@@ -595,7 +595,7 @@ toshoboe_startchip (struct toshoboe_cb *self)
   OUTB ((physaddr >> 18) & 0xff, OBOE_RING_BASE1);
   OUTB ((physaddr >> 26) & 0x3f, OBOE_RING_BASE2);
 
-  /*Enable DMA controler in byte mode and RX */
+  /*Enable DMA controller in byte mode and RX */
   OUTB (CONFIG0H_DMA_ON, OBOE_CONFIG0H);
 
   /* Start up the clocks */
index 0d2fe87fb9b78661757408a945fcd3bafb8e6cc0..738531b16bd327c72df5d0bde0a3458e6443b46d 100644 (file)
@@ -16,7 +16,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  * 
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
index 248aeb0c726ca8befa21bf1e9c63f21dce0c9ae6..1f57391a618b3e14ebe6c9ed56059739a1252ebd 100644 (file)
@@ -16,7 +16,7 @@
  *     published by the Free Software Foundation; either version 2 of 
  *     the License, or (at your option) any later version.
  *  
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is 
  *     provided "AS-IS" and at no charge.
  *     
index 3f46b84c6c85cd96063e812a7be370b9a05ac08d..66fc2433e97d37377d7c554cb673d5aba2d688c8 100644 (file)
@@ -17,7 +17,7 @@
  *     published by the Free Software Foundation; either version 2 of 
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is 
  *     provided "AS-IS" and at no charge.
  *
index 6f5f697ec9f891ef557c2d4c35342a987d6978b7..2c6f7be36e8aa8eb9d712c44fd7c84be92b9530a 100644 (file)
@@ -20,7 +20,7 @@
  *     published by the Free Software Foundation; either version 2 of 
  *     the License, or (at your option) any later version.
  *  
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is 
  *     provided "AS-IS" and at no charge.
  *     
index 12b9378c587f890c090bb807a3cf7191cdcfd9fa..a873d2b315ca33e21cfc1c3ced4e3c48f6cce273 100644 (file)
@@ -20,7 +20,7 @@
  *     published by the Free Software Foundation; either version 2 of 
  *     the License, or (at your option) any later version.
  *  
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is 
  *     provided "AS-IS" and at no charge.
  *
index dacf671abcd6c01d49aa12a4585cb9ba9dc19a3a..bbdc97ff83cae11df92933f9cb7cb4b55cef2f5e 100644 (file)
@@ -19,7 +19,7 @@
  *     published by the Free Software Foundation; either version 2 of 
  *     the License, or (at your option) any later version.
  *  
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is 
  *     provided "AS-IS" and at no charge.
  *     
index 0dd6bc7af3f2b953f278d70f00cd15bd4e3be76d..d1ce5ae6a17243d37ed61ff6cfa675c1929bec02 100644 (file)
@@ -18,7 +18,7 @@
  *     published by the Free Software Foundation; either version 2 of 
  *     the License, or (at your option) any later version.
  *  
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is 
  *     provided "AS-IS" and at no charge.
  *     
index 8f6258221cb03bcb932a4855289f15b964373a28..9bfd2441adbf9a2a240c70773581d3d2c003bd17 100644 (file)
@@ -16,7 +16,7 @@
  *     published by the Free Software Foundation; either version 2 of 
  *     the License, or (at your option) any later version.
  *  
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is 
  *     provided "AS-IS" and at no charge.
  *     
index 0b7661deafee8d4c36f7ae0c7340458d98c55e04..87c3975baf62fa7c6888be0ca543c4bf8730b3ad 100644 (file)
@@ -16,7 +16,7 @@
  *     published by the Free Software Foundation; either version 2 of 
  *     the License, or (at your option) any later version.
  *  
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is 
  *     provided "AS-IS" and at no charge.
  *     
diff --git a/drivers/net/lguest_net.c b/drivers/net/lguest_net.c
deleted file mode 100644 (file)
index abce2ee..0000000
+++ /dev/null
@@ -1,555 +0,0 @@
-/*D:500
- * The Guest network driver.
- *
- * This is very simple a virtual network driver, and our last Guest driver.
- * The only trick is that it can talk directly to multiple other recipients
- * (ie. other Guests on the same network).  It can also be used with only the
- * Host on the network.
- :*/
-
-/* Copyright 2006 Rusty Russell <rusty@rustcorp.com.au> 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
- */
-//#define DEBUG
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/module.h>
-#include <linux/mm_types.h>
-#include <linux/io.h>
-#include <linux/lguest_bus.h>
-
-#define SHARED_SIZE            PAGE_SIZE
-#define MAX_LANS               4
-#define NUM_SKBS               8
-
-/*M:011 Network code master Jeff Garzik points out numerous shortcomings in
- * this driver if it aspires to greatness.
- *
- * Firstly, it doesn't use "NAPI": the networking's New API, and is poorer for
- * it.  As he says "NAPI means system-wide load leveling, across multiple
- * network interfaces.  Lack of NAPI can mean competition at higher loads."
- *
- * He also points out that we don't implement set_mac_address, so users cannot
- * change the devices hardware address.  When I asked why one would want to:
- * "Bonding, and situations where you /do/ want the MAC address to "leak" out
- * of the host onto the wider net."
- *
- * Finally, he would like module unloading: "It is not unrealistic to think of
- * [un|re|]loading the net support module in an lguest guest.  And, adding
- * module support makes the programmer more responsible, because they now have
- * to learn to clean up after themselves.  Any driver that cannot clean up
- * after itself is an incomplete driver in my book."
- :*/
-
-/*D:530 The "struct lguestnet_info" contains all the information we need to
- * know about the network device. */
-struct lguestnet_info
-{
-       /* The mapped device page(s) (an array of "struct lguest_net"). */
-       struct lguest_net *peer;
-       /* The physical address of the device page(s) */
-       unsigned long peer_phys;
-       /* The size of the device page(s). */
-       unsigned long mapsize;
-
-       /* The lguest_device I come from */
-       struct lguest_device *lgdev;
-
-       /* My peerid (ie. my slot in the array). */
-       unsigned int me;
-
-       /* Receive queue: the network packets waiting to be filled. */
-       struct sk_buff *skb[NUM_SKBS];
-       struct lguest_dma dma[NUM_SKBS];
-};
-/*:*/
-
-/* How many bytes left in this page. */
-static unsigned int rest_of_page(void *data)
-{
-       return PAGE_SIZE - ((unsigned long)data % PAGE_SIZE);
-}
-
-/*D:570 Each peer (ie. Guest or Host) on the network binds their receive
- * buffers to a different key: we simply use the physical address of the
- * device's memory page plus the peer number.  The Host insists that all keys
- * be a multiple of 4, so we multiply the peer number by 4. */
-static unsigned long peer_key(struct lguestnet_info *info, unsigned peernum)
-{
-       return info->peer_phys + 4 * peernum;
-}
-
-/* This is the routine which sets up a "struct lguest_dma" to point to a
- * network packet, similar to req_to_dma() in lguest_blk.c.  The structure of a
- * "struct sk_buff" has grown complex over the years: it consists of a "head"
- * linear section pointed to by "skb->data", and possibly an array of
- * "fragments" in the case of a non-linear packet.
- *
- * Our receive buffers don't use fragments at all but outgoing skbs might, so
- * we handle it. */
-static void skb_to_dma(const struct sk_buff *skb, unsigned int headlen,
-                      struct lguest_dma *dma)
-{
-       unsigned int i, seg;
-
-       /* First, we put the linear region into the "struct lguest_dma".  Each
-        * entry can't go over a page boundary, so even though all our packets
-        * are 1514 bytes or less, we might need to use two entries here: */
-       for (i = seg = 0; i < headlen; seg++, i += rest_of_page(skb->data+i)) {
-               dma->addr[seg] = virt_to_phys(skb->data + i);
-               dma->len[seg] = min((unsigned)(headlen - i),
-                                   rest_of_page(skb->data + i));
-       }
-
-       /* Now we handle the fragments: at least they're guaranteed not to go
-        * over a page.  skb_shinfo(skb) returns a pointer to the structure
-        * which tells us about the number of fragments and the fragment
-        * array. */
-       for (i = 0; i < skb_shinfo(skb)->nr_frags; i++, seg++) {
-               const skb_frag_t *f = &skb_shinfo(skb)->frags[i];
-               /* Should not happen with MTU less than 64k - 2 * PAGE_SIZE. */
-               if (seg == LGUEST_MAX_DMA_SECTIONS) {
-                       /* We will end up sending a truncated packet should
-                        * this ever happen.  Plus, a cool log message! */
-                       printk("Woah dude!  Megapacket!\n");
-                       break;
-               }
-               dma->addr[seg] = page_to_phys(f->page) + f->page_offset;
-               dma->len[seg] = f->size;
-       }
-
-       /* If after all that we didn't use the entire "struct lguest_dma"
-        * array, we terminate it with a 0 length. */
-       if (seg < LGUEST_MAX_DMA_SECTIONS)
-               dma->len[seg] = 0;
-}
-
-/*
- * Packet transmission.
- *
- * Our packet transmission is a little unusual.  A real network card would just
- * send out the packet and leave the receivers to decide if they're interested.
- * Instead, we look through the network device memory page and see if any of
- * the ethernet addresses match the packet destination, and if so we send it to
- * that Guest.
- *
- * This is made a little more complicated in two cases.  The first case is
- * broadcast packets: for that we send the packet to all Guests on the network,
- * one at a time.  The second case is "promiscuous" mode, where a Guest wants
- * to see all the packets on the network.  We need a way for the Guest to tell
- * us it wants to see all packets, so it sets the "multicast" bit on its
- * published MAC address, which is never valid in a real ethernet address.
- */
-#define PROMISC_BIT            0x01
-
-/* This is the callback which is summoned whenever the network device's
- * multicast or promiscuous state changes.  If the card is in promiscuous mode,
- * we advertise that in our ethernet address in the device's memory.  We do the
- * same if Linux wants any or all multicast traffic.  */
-static void lguestnet_set_multicast(struct net_device *dev)
-{
-       struct lguestnet_info *info = netdev_priv(dev);
-
-       if ((dev->flags & (IFF_PROMISC|IFF_ALLMULTI)) || dev->mc_count)
-               info->peer[info->me].mac[0] |= PROMISC_BIT;
-       else
-               info->peer[info->me].mac[0] &= ~PROMISC_BIT;
-}
-
-/* A simple test function to see if a peer wants to see all packets.*/
-static int promisc(struct lguestnet_info *info, unsigned int peer)
-{
-       return info->peer[peer].mac[0] & PROMISC_BIT;
-}
-
-/* Another simple function to see if a peer's advertised ethernet address
- * matches a packet's destination ethernet address. */
-static int mac_eq(const unsigned char mac[ETH_ALEN],
-                 struct lguestnet_info *info, unsigned int peer)
-{
-       /* Ignore multicast bit, which peer turns on to mean promisc. */
-       if ((info->peer[peer].mac[0] & (~PROMISC_BIT)) != mac[0])
-               return 0;
-       return memcmp(mac+1, info->peer[peer].mac+1, ETH_ALEN-1) == 0;
-}
-
-/* This is the function which actually sends a packet once we've decided a
- * peer wants it: */
-static void transfer_packet(struct net_device *dev,
-                           struct sk_buff *skb,
-                           unsigned int peernum)
-{
-       struct lguestnet_info *info = netdev_priv(dev);
-       struct lguest_dma dma;
-
-       /* We use our handy "struct lguest_dma" packing function to prepare
-        * the skb for sending. */
-       skb_to_dma(skb, skb_headlen(skb), &dma);
-       pr_debug("xfer length %04x (%u)\n", htons(skb->len), skb->len);
-
-       /* This is the actual send call which copies the packet. */
-       lguest_send_dma(peer_key(info, peernum), &dma);
-
-       /* Check that the entire packet was transmitted.  If not, it could mean
-        * that the other Guest registered a short receive buffer, but this
-        * driver should never do that.  More likely, the peer is dead. */
-       if (dma.used_len != skb->len) {
-               dev->stats.tx_carrier_errors++;
-               pr_debug("Bad xfer to peer %i: %i of %i (dma %p/%i)\n",
-                        peernum, dma.used_len, skb->len,
-                        (void *)dma.addr[0], dma.len[0]);
-       } else {
-               /* On success we update the stats. */
-               dev->stats.tx_bytes += skb->len;
-               dev->stats.tx_packets++;
-       }
-}
-
-/* Another helper function to tell is if a slot in the device memory is unused.
- * Since we always set the Local Assignment bit in the ethernet address, the
- * first byte can never be 0. */
-static int unused_peer(const struct lguest_net peer[], unsigned int num)
-{
-       return peer[num].mac[0] == 0;
-}
-
-/* Finally, here is the routine which handles an outgoing packet.  It's called
- * "start_xmit" for traditional reasons. */
-static int lguestnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-       unsigned int i;
-       int broadcast;
-       struct lguestnet_info *info = netdev_priv(dev);
-       /* Extract the destination ethernet address from the packet. */
-       const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest;
-       DECLARE_MAC_BUF(mac);
-
-       pr_debug("%s: xmit %s\n", dev->name, print_mac(mac, dest));
-
-       /* If it's a multicast packet, we broadcast to everyone.  That's not
-        * very efficient, but there are very few applications which actually
-        * use multicast, which is a shame really.
-        *
-        * As etherdevice.h points out: "By definition the broadcast address is
-        * also a multicast address."  So we don't have to test for broadcast
-        * packets separately. */
-       broadcast = is_multicast_ether_addr(dest);
-
-       /* Look through all the published ethernet addresses to see if we
-        * should send this packet. */
-       for (i = 0; i < info->mapsize/sizeof(struct lguest_net); i++) {
-               /* We don't send to ourselves (we actually can't SEND_DMA to
-                * ourselves anyway), and don't send to unused slots.*/
-               if (i == info->me || unused_peer(info->peer, i))
-                       continue;
-
-               /* If it's broadcast we send it.  If they want every packet we
-                * send it.  If the destination matches their address we send
-                * it.  Otherwise we go to the next peer. */
-               if (!broadcast && !promisc(info, i) && !mac_eq(dest, info, i))
-                       continue;
-
-               pr_debug("lguestnet %s: sending from %i to %i\n",
-                        dev->name, info->me, i);
-               /* Our routine which actually does the transfer. */
-               transfer_packet(dev, skb, i);
-       }
-
-       /* An xmit routine is expected to dispose of the packet, so we do. */
-       dev_kfree_skb(skb);
-
-       /* As per kernel convention, 0 means success.  This is why I love
-        * networking: even if we never sent to anyone, that's still
-        * success! */
-       return 0;
-}
-
-/*D:560
- * Packet receiving.
- *
- * First, here's a helper routine which fills one of our array of receive
- * buffers: */
-static int fill_slot(struct net_device *dev, unsigned int slot)
-{
-       struct lguestnet_info *info = netdev_priv(dev);
-
-       /* We can receive ETH_DATA_LEN (1500) byte packets, plus a standard
-        * ethernet header of ETH_HLEN (14) bytes. */
-       info->skb[slot] = netdev_alloc_skb(dev, ETH_HLEN + ETH_DATA_LEN);
-       if (!info->skb[slot]) {
-               printk("%s: could not fill slot %i\n", dev->name, slot);
-               return -ENOMEM;
-       }
-
-       /* skb_to_dma() is a helper which sets up the "struct lguest_dma" to
-        * point to the data in the skb: we also use it for sending out a
-        * packet. */
-       skb_to_dma(info->skb[slot], ETH_HLEN + ETH_DATA_LEN, &info->dma[slot]);
-
-       /* This is a Write Memory Barrier: it ensures that the entry in the
-        * receive buffer array is written *before* we set the "used_len" entry
-        * to 0.  If the Host were looking at the receive buffer array from a
-        * different CPU, it could potentially see "used_len = 0" and not see
-        * the updated receive buffer information.  This would be a horribly
-        * nasty bug, so make sure the compiler and CPU know this has to happen
-        * first. */
-       wmb();
-       /* Writing 0 to "used_len" tells the Host it can use this receive
-        * buffer now. */
-       info->dma[slot].used_len = 0;
-       return 0;
-}
-
-/* This is the actual receive routine.  When we receive an interrupt from the
- * Host to tell us a packet has been delivered, we arrive here: */
-static irqreturn_t lguestnet_rcv(int irq, void *dev_id)
-{
-       struct net_device *dev = dev_id;
-       struct lguestnet_info *info = netdev_priv(dev);
-       unsigned int i, done = 0;
-
-       /* Look through our entire receive array for an entry which has data
-        * in it. */
-       for (i = 0; i < ARRAY_SIZE(info->dma); i++) {
-               unsigned int length;
-               struct sk_buff *skb;
-
-               length = info->dma[i].used_len;
-               if (length == 0)
-                       continue;
-
-               /* We've found one!  Remember the skb (we grabbed the length
-                * above), and immediately refill the slot we've taken it
-                * from. */
-               done++;
-               skb = info->skb[i];
-               fill_slot(dev, i);
-
-               /* This shouldn't happen: micropackets could be sent by a
-                * badly-behaved Guest on the network, but the Host will never
-                * stuff more data in the buffer than the buffer length. */
-               if (length < ETH_HLEN || length > ETH_HLEN + ETH_DATA_LEN) {
-                       pr_debug(KERN_WARNING "%s: unbelievable skb len: %i\n",
-                                dev->name, length);
-                       dev_kfree_skb(skb);
-                       continue;
-               }
-
-               /* skb_put(), what a great function!  I've ranted about this
-                * function before (http://lkml.org/lkml/1999/9/26/24).  You
-                * call it after you've added data to the end of an skb (in
-                * this case, it was the Host which wrote the data). */
-               skb_put(skb, length);
-
-               /* The ethernet header contains a protocol field: we use the
-                * standard helper to extract it, and place the result in
-                * skb->protocol.  The helper also sets up skb->pkt_type and
-                * eats up the ethernet header from the front of the packet. */
-               skb->protocol = eth_type_trans(skb, dev);
-
-               /* If this device doesn't need checksums for sending, we also
-                * don't need to check the packets when they come in. */
-               if (dev->features & NETIF_F_NO_CSUM)
-                       skb->ip_summed = CHECKSUM_UNNECESSARY;
-
-               /* As a last resort for debugging the driver or the lguest I/O
-                * subsystem, you can uncomment the "#define DEBUG" at the top
-                * of this file, which turns all the pr_debug() into printk()
-                * and floods the logs. */
-               pr_debug("Receiving skb proto 0x%04x len %i type %i\n",
-                        ntohs(skb->protocol), skb->len, skb->pkt_type);
-
-               /* Update the packet and byte counts (visible from ifconfig,
-                * and good for debugging). */
-               dev->stats.rx_bytes += skb->len;
-               dev->stats.rx_packets++;
-
-               /* Hand our fresh network packet into the stack's "network
-                * interface receive" routine.  That will free the packet
-                * itself when it's finished. */
-               netif_rx(skb);
-       }
-
-       /* If we found any packets, we assume the interrupt was for us. */
-       return done ? IRQ_HANDLED : IRQ_NONE;
-}
-
-/*D:550 This is where we start: when the device is brought up by dhcpd or
- * ifconfig.  At this point we advertise our MAC address to the rest of the
- * network, and register receive buffers ready for incoming packets. */
-static int lguestnet_open(struct net_device *dev)
-{
-       int i;
-       struct lguestnet_info *info = netdev_priv(dev);
-
-       /* Copy our MAC address into the device page, so others on the network
-        * can find us. */
-       memcpy(info->peer[info->me].mac, dev->dev_addr, ETH_ALEN);
-
-       /* We might already be in promisc mode (dev->flags & IFF_PROMISC).  Our
-        * set_multicast callback handles this already, so we call it now. */
-       lguestnet_set_multicast(dev);
-
-       /* Allocate packets and put them into our "struct lguest_dma" array.
-        * If we fail to allocate all the packets we could still limp along,
-        * but it's a sign of real stress so we should probably give up now. */
-       for (i = 0; i < ARRAY_SIZE(info->dma); i++) {
-               if (fill_slot(dev, i) != 0)
-                       goto cleanup;
-       }
-
-       /* Finally we tell the Host where our array of "struct lguest_dma"
-        * receive buffers is, binding it to the key corresponding to the
-        * device's physical memory plus our peerid. */
-       if (lguest_bind_dma(peer_key(info,info->me), info->dma,
-                           NUM_SKBS, lgdev_irq(info->lgdev)) != 0)
-               goto cleanup;
-       return 0;
-
-cleanup:
-       while (--i >= 0)
-               dev_kfree_skb(info->skb[i]);
-       return -ENOMEM;
-}
-/*:*/
-
-/* The close routine is called when the device is no longer in use: we clean up
- * elegantly. */
-static int lguestnet_close(struct net_device *dev)
-{
-       unsigned int i;
-       struct lguestnet_info *info = netdev_priv(dev);
-
-       /* Clear all trace of our existence out of the device memory by setting
-        * the slot which held our MAC address to 0 (unused). */
-       memset(&info->peer[info->me], 0, sizeof(info->peer[info->me]));
-
-       /* Unregister our array of receive buffers */
-       lguest_unbind_dma(peer_key(info, info->me), info->dma);
-       for (i = 0; i < ARRAY_SIZE(info->dma); i++)
-               dev_kfree_skb(info->skb[i]);
-       return 0;
-}
-
-/*D:510 The network device probe function is basically a standard ethernet
- * device setup.  It reads the "struct lguest_device_desc" and sets the "struct
- * net_device".  Oh, the line-by-line excitement!  Let's skip over it. :*/
-static int lguestnet_probe(struct lguest_device *lgdev)
-{
-       int err, irqf = IRQF_SHARED;
-       struct net_device *dev;
-       struct lguestnet_info *info;
-       struct lguest_device_desc *desc = &lguest_devices[lgdev->index];
-
-       pr_debug("lguest_net: probing for device %i\n", lgdev->index);
-
-       dev = alloc_etherdev(sizeof(struct lguestnet_info));
-       if (!dev)
-               return -ENOMEM;
-
-       /* Ethernet defaults with some changes */
-       ether_setup(dev);
-       dev->set_mac_address = NULL;
-
-       dev->dev_addr[0] = 0x02; /* set local assignment bit (IEEE802) */
-       dev->dev_addr[1] = 0x00;
-       memcpy(&dev->dev_addr[2], &lguest_data.guestid, 2);
-       dev->dev_addr[4] = 0x00;
-       dev->dev_addr[5] = 0x00;
-
-       dev->open = lguestnet_open;
-       dev->stop = lguestnet_close;
-       dev->hard_start_xmit = lguestnet_start_xmit;
-
-       /* We don't actually support multicast yet, but turning on/off
-        * promisc also calls dev->set_multicast_list. */
-       dev->set_multicast_list = lguestnet_set_multicast;
-       SET_NETDEV_DEV(dev, &lgdev->dev);
-
-       /* The network code complains if you have "scatter-gather" capability
-        * if you don't also handle checksums (it seem that would be
-        * "illogical").  So we use a lie of omission and don't tell it that we
-        * can handle scattered packets unless we also don't want checksums,
-        * even though to us they're completely independent. */
-       if (desc->features & LGUEST_NET_F_NOCSUM)
-               dev->features = NETIF_F_SG|NETIF_F_NO_CSUM;
-
-       info = netdev_priv(dev);
-       info->mapsize = PAGE_SIZE * desc->num_pages;
-       info->peer_phys = ((unsigned long)desc->pfn << PAGE_SHIFT);
-       info->lgdev = lgdev;
-       info->peer = lguest_map(info->peer_phys, desc->num_pages);
-       if (!info->peer) {
-               err = -ENOMEM;
-               goto free;
-       }
-
-       /* This stores our peerid (upper bits reserved for future). */
-       info->me = (desc->features & (info->mapsize-1));
-
-       err = register_netdev(dev);
-       if (err) {
-               pr_debug("lguestnet: registering device failed\n");
-               goto unmap;
-       }
-
-       if (lguest_devices[lgdev->index].features & LGUEST_DEVICE_F_RANDOMNESS)
-               irqf |= IRQF_SAMPLE_RANDOM;
-       if (request_irq(lgdev_irq(lgdev), lguestnet_rcv, irqf, "lguestnet",
-                       dev) != 0) {
-               pr_debug("lguestnet: cannot get irq %i\n", lgdev_irq(lgdev));
-               goto unregister;
-       }
-
-       pr_debug("lguestnet: registered device %s\n", dev->name);
-       /* Finally, we put the "struct net_device" in the generic "struct
-        * lguest_device"s private pointer.  Again, it's not necessary, but
-        * makes sure the cool kernel kids don't tease us. */
-       lgdev->private = dev;
-       return 0;
-
-unregister:
-       unregister_netdev(dev);
-unmap:
-       lguest_unmap(info->peer);
-free:
-       free_netdev(dev);
-       return err;
-}
-
-static struct lguest_driver lguestnet_drv = {
-       .name = "lguestnet",
-       .owner = THIS_MODULE,
-       .device_type = LGUEST_DEVICE_T_NET,
-       .probe = lguestnet_probe,
-};
-
-static __init int lguestnet_init(void)
-{
-       return register_lguest_driver(&lguestnet_drv);
-}
-module_init(lguestnet_init);
-
-MODULE_DESCRIPTION("Lguest network driver");
-MODULE_LICENSE("GPL");
-
-/*D:580
- * This is the last of the Drivers, and with this we have covered the many and
- * wonderous and fine (and boring) details of the Guest.
- *
- * "make Launcher" beckons, where we answer questions like "Where do Guests
- * come from?", and "What do you do when someone asks for optimization?"
- */
index 30854f094965c840fd11e8f8eb1bd55e26449305..a19b5958cee949e89548bbb50acf7768ac44de2f 100644 (file)
@@ -99,9 +99,9 @@ static char *version =
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/delay.h>
+#include <linux/bitops.h>
 
 #include <asm/system.h>
-#include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/hwtest.h>
 #include <asm/macints.h>
index ea3b8fc86d1ef239cef9b6557f1468ad0cdf4a95..a78dc1ca8c29d16324f2fbf1b696e94bf1cef1b4 100644 (file)
@@ -28,9 +28,6 @@
 #define RX_BUFFER_OFFSET (sizeof(rx_status_vector)+2) /* staus vector + 2 bytes of padding */
 #define RX_BUCKET_SIZE 256
 
-#undef BIT
-#define BIT(x) (1UL << (x))
-
 /* For more detailed explanations of what each field menas,
    see Nick's great comments to #defines below (or docs, if
    you are lucky enough toget hold of them :)*/
index 6471d33afb7d8509b927105bcb89280aa4e76ce2..50648738d679b7e60aeb720eb8e6ba161c6d02a2 100644 (file)
@@ -736,7 +736,7 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param)
        MLX4_PUT(inbox, (u8) (PAGE_SHIFT - 12), INIT_HCA_UAR_PAGE_SZ_OFFSET);
        MLX4_PUT(inbox, param->log_uar_sz,      INIT_HCA_LOG_UAR_SZ_OFFSET);
 
-       err = mlx4_cmd(dev, mailbox->dma, 0, 0, MLX4_CMD_INIT_HCA, 1000);
+       err = mlx4_cmd(dev, mailbox->dma, 0, 0, MLX4_CMD_INIT_HCA, 10000);
 
        if (err)
                mlx4_err(dev, "INIT_HCA returns %d\n", err);
index 4b3c109d5eaee2d6f7c73a5a31db57bca749c053..887633b207d9de533000aefa61b9da5a0d7543a6 100644 (file)
@@ -60,7 +60,7 @@ static void mlx4_free_icm_pages(struct mlx4_dev *dev, struct mlx4_icm_chunk *chu
                             PCI_DMA_BIDIRECTIONAL);
 
        for (i = 0; i < chunk->npages; ++i)
-               __free_pages(chunk->mem[i].page,
+               __free_pages(sg_page(&chunk->mem[i]),
                             get_order(chunk->mem[i].length));
 }
 
@@ -70,7 +70,7 @@ static void mlx4_free_icm_coherent(struct mlx4_dev *dev, struct mlx4_icm_chunk *
 
        for (i = 0; i < chunk->npages; ++i)
                dma_free_coherent(&dev->pdev->dev, chunk->mem[i].length,
-                                 lowmem_page_address(chunk->mem[i].page),
+                                 lowmem_page_address(sg_page(&chunk->mem[i])),
                                  sg_dma_address(&chunk->mem[i]));
 }
 
@@ -95,10 +95,13 @@ void mlx4_free_icm(struct mlx4_dev *dev, struct mlx4_icm *icm, int coherent)
 
 static int mlx4_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_mask)
 {
-       mem->page = alloc_pages(gfp_mask, order);
-       if (!mem->page)
+       struct page *page;
+
+       page = alloc_pages(gfp_mask, order);
+       if (!page)
                return -ENOMEM;
 
+       sg_set_page(mem, page);
        mem->length = PAGE_SIZE << order;
        mem->offset = 0;
        return 0;
@@ -145,6 +148,7 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages,
                        if (!chunk)
                                goto fail;
 
+                       sg_init_table(chunk->mem, MLX4_ICM_CHUNK_LEN);
                        chunk->npages = 0;
                        chunk->nsg    = 0;
                        list_add_tail(&chunk->list, &icm->chunk_list);
@@ -334,7 +338,7 @@ void *mlx4_table_find(struct mlx4_icm_table *table, int obj, dma_addr_t *dma_han
                         * been assigned to.
                         */
                        if (chunk->mem[i].length > offset) {
-                               page = chunk->mem[i].page;
+                               page = sg_page(&chunk->mem[i]);
                                goto out;
                        }
                        offset -= chunk->mem[i].length;
index 64c8151f200401aca8bf9d4c21e4c07f82850176..366e62a2b1e5dacea1e1afd7fa0e89870afbf07d 100644 (file)
@@ -3058,7 +3058,8 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (status != 0) {
                dac_enabled = 0;
                dev_err(&pdev->dev,
-                       "64-bit pci address mask was refused, trying 32-bit");
+                       "64-bit pci address mask was refused, "
+                       "trying 32-bit\n");
                status = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
        }
        if (status != 0) {
index 50e1ec67ef9c5f4d0fa9419b03de64961e3c3962..953117152bbd61c84022a4d1747d6fce4a1a3104 100644 (file)
@@ -996,7 +996,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
    a delay.  Note that pre-2.0.34 kernels had a cache-alignment bug that
    made udelay() unreliable.
    The old method of using an ISA access as a delay, __SLOW_DOWN_IO__, is
-   depricated.
+   deprecated.
 */
 #define eeprom_delay(ee_addr)  readl(ee_addr)
 
index 2a1d6d7ec351d37f4a7189f2e3987d76a5a8990c..601051c584e8a3c688358c983d7f09809c111217 100644 (file)
@@ -53,9 +53,6 @@ static char netxen_nic_driver_string[] = "NetXen Network Driver version "
 #define NETXEN_ADAPTER_UP_MAGIC 777
 #define NETXEN_NIC_PEG_TUNE 0
 
-#define DMA_32BIT_MASK 0x00000000ffffffffULL
-#define DMA_35BIT_MASK 0x00000007ffffffffULL
-
 /* Local functions to NetXen NIC driver */
 static int __devinit netxen_nic_probe(struct pci_dev *pdev,
                                      const struct pci_device_id *ent);
index ed1f9bbb2a32e5265e13cca49b46e807b32e9c69..112ab079ce7d19af82403d8e148701470ddc2c17 100644 (file)
@@ -3103,31 +3103,12 @@ static int niu_alloc_tx_ring_info(struct niu *np,
 
 static void niu_size_rbr(struct niu *np, struct rx_ring_info *rp)
 {
-       u16 bs;
+       u16 bss;
 
-       switch (PAGE_SIZE) {
-       case 4 * 1024:
-       case 8 * 1024:
-       case 16 * 1024:
-       case 32 * 1024:
-               rp->rbr_block_size = PAGE_SIZE;
-               rp->rbr_blocks_per_page = 1;
-               break;
+       bss = min(PAGE_SHIFT, 15);
 
-       default:
-               if (PAGE_SIZE % (32 * 1024) == 0)
-                       bs = 32 * 1024;
-               else if (PAGE_SIZE % (16 * 1024) == 0)
-                       bs = 16 * 1024;
-               else if (PAGE_SIZE % (8 * 1024) == 0)
-                       bs = 8 * 1024;
-               else if (PAGE_SIZE % (4 * 1024) == 0)
-                       bs = 4 * 1024;
-               else
-                       BUG();
-               rp->rbr_block_size = bs;
-               rp->rbr_blocks_per_page = PAGE_SIZE / bs;
-       }
+       rp->rbr_block_size = 1 << bss;
+       rp->rbr_blocks_per_page = 1 << (PAGE_SHIFT-bss);
 
        rp->rbr_sizes[0] = 256;
        rp->rbr_sizes[1] = 1024;
@@ -7902,12 +7883,7 @@ static int __init niu_init(void)
 {
        int err = 0;
 
-       BUILD_BUG_ON((PAGE_SIZE < 4 * 1024) ||
-                    ((PAGE_SIZE > 32 * 1024) &&
-                     ((PAGE_SIZE % (32 * 1024)) != 0 &&
-                      (PAGE_SIZE % (16 * 1024)) != 0 &&
-                      (PAGE_SIZE % (8 * 1024)) != 0 &&
-                      (PAGE_SIZE % (4 * 1024)) != 0)));
+       BUILD_BUG_ON(PAGE_SIZE < 4 * 1024);
 
        niu_debug = netif_msg_init(debug, NIU_MSG_DEFAULT);
 
index 5f994b5beda17b1d808372df248a70124ab07395..ff92aca0a7b37ad82daf35a38dfd9190353b356a 100644 (file)
@@ -282,7 +282,6 @@ struct pcnet32_private {
 
        struct net_device       *dev;
        struct napi_struct      napi;
-       struct net_device_stats stats;
        char                    tx_full;
        char                    phycount;       /* number of phys found */
        int                     options;
@@ -442,7 +441,9 @@ static struct pcnet32_access pcnet32_dwio = {
 
 static void pcnet32_netif_stop(struct net_device *dev)
 {
+#ifdef CONFIG_PCNET32_NAPI
        struct pcnet32_private *lp = netdev_priv(dev);
+#endif
        dev->trans_start = jiffies;
 #ifdef CONFIG_PCNET32_NAPI
        napi_disable(&lp->napi);
@@ -452,7 +453,9 @@ static void pcnet32_netif_stop(struct net_device *dev)
 
 static void pcnet32_netif_start(struct net_device *dev)
 {
+#ifdef CONFIG_PCNET32_NAPI
        struct pcnet32_private *lp = netdev_priv(dev);
+#endif
        netif_wake_queue(dev);
 #ifdef CONFIG_PCNET32_NAPI
        napi_enable(&lp->napi);
@@ -1178,15 +1181,15 @@ static void pcnet32_rx_entry(struct net_device *dev,
                 * buffers, with only the last correctly noting the error.
                 */
                if (status & 0x01)      /* Only count a general error at the */
-                       lp->stats.rx_errors++;  /* end of a packet. */
+                       dev->stats.rx_errors++; /* end of a packet. */
                if (status & 0x20)
-                       lp->stats.rx_frame_errors++;
+                       dev->stats.rx_frame_errors++;
                if (status & 0x10)
-                       lp->stats.rx_over_errors++;
+                       dev->stats.rx_over_errors++;
                if (status & 0x08)
-                       lp->stats.rx_crc_errors++;
+                       dev->stats.rx_crc_errors++;
                if (status & 0x04)
-                       lp->stats.rx_fifo_errors++;
+                       dev->stats.rx_fifo_errors++;
                return;
        }
 
@@ -1197,13 +1200,13 @@ static void pcnet32_rx_entry(struct net_device *dev,
                if (netif_msg_drv(lp))
                        printk(KERN_ERR "%s: Impossible packet size %d!\n",
                               dev->name, pkt_len);
-               lp->stats.rx_errors++;
+               dev->stats.rx_errors++;
                return;
        }
        if (pkt_len < 60) {
                if (netif_msg_rx_err(lp))
                        printk(KERN_ERR "%s: Runt packet!\n", dev->name);
-               lp->stats.rx_errors++;
+               dev->stats.rx_errors++;
                return;
        }
 
@@ -1237,7 +1240,7 @@ static void pcnet32_rx_entry(struct net_device *dev,
                        printk(KERN_ERR
                               "%s: Memory squeeze, dropping packet.\n",
                               dev->name);
-               lp->stats.rx_dropped++;
+               dev->stats.rx_dropped++;
                return;
        }
        skb->dev = dev;
@@ -1256,7 +1259,7 @@ static void pcnet32_rx_entry(struct net_device *dev,
                                               pkt_len,
                                               PCI_DMA_FROMDEVICE);
        }
-       lp->stats.rx_bytes += skb->len;
+       dev->stats.rx_bytes += skb->len;
        skb->protocol = eth_type_trans(skb, dev);
 #ifdef CONFIG_PCNET32_NAPI
        netif_receive_skb(skb);
@@ -1264,7 +1267,7 @@ static void pcnet32_rx_entry(struct net_device *dev,
        netif_rx(skb);
 #endif
        dev->last_rx = jiffies;
-       lp->stats.rx_packets++;
+       dev->stats.rx_packets++;
        return;
 }
 
@@ -1312,21 +1315,21 @@ static int pcnet32_tx(struct net_device *dev)
                if (status & 0x4000) {
                        /* There was a major error, log it. */
                        int err_status = le32_to_cpu(lp->tx_ring[entry].misc);
-                       lp->stats.tx_errors++;
+                       dev->stats.tx_errors++;
                        if (netif_msg_tx_err(lp))
                                printk(KERN_ERR
                                       "%s: Tx error status=%04x err_status=%08x\n",
                                       dev->name, status,
                                       err_status);
                        if (err_status & 0x04000000)
-                               lp->stats.tx_aborted_errors++;
+                               dev->stats.tx_aborted_errors++;
                        if (err_status & 0x08000000)
-                               lp->stats.tx_carrier_errors++;
+                               dev->stats.tx_carrier_errors++;
                        if (err_status & 0x10000000)
-                               lp->stats.tx_window_errors++;
+                               dev->stats.tx_window_errors++;
 #ifndef DO_DXSUFLO
                        if (err_status & 0x40000000) {
-                               lp->stats.tx_fifo_errors++;
+                               dev->stats.tx_fifo_errors++;
                                /* Ackk!  On FIFO errors the Tx unit is turned off! */
                                /* Remove this verbosity later! */
                                if (netif_msg_tx_err(lp))
@@ -1337,7 +1340,7 @@ static int pcnet32_tx(struct net_device *dev)
                        }
 #else
                        if (err_status & 0x40000000) {
-                               lp->stats.tx_fifo_errors++;
+                               dev->stats.tx_fifo_errors++;
                                if (!lp->dxsuflo) {     /* If controller doesn't recover ... */
                                        /* Ackk!  On FIFO errors the Tx unit is turned off! */
                                        /* Remove this verbosity later! */
@@ -1351,8 +1354,8 @@ static int pcnet32_tx(struct net_device *dev)
 #endif
                } else {
                        if (status & 0x1800)
-                               lp->stats.collisions++;
-                       lp->stats.tx_packets++;
+                               dev->stats.collisions++;
+                       dev->stats.tx_packets++;
                }
 
                /* We must free the original skb */
@@ -1849,6 +1852,9 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
        lp->mii_if.mdio_read = mdio_read;
        lp->mii_if.mdio_write = mdio_write;
 
+       /* napi.weight is used in both the napi and non-napi cases */
+       lp->napi.weight = lp->rx_ring_size / 2;
+
 #ifdef CONFIG_PCNET32_NAPI
        netif_napi_add(dev, &lp->napi, pcnet32_poll, lp->rx_ring_size / 2);
 #endif
@@ -2471,7 +2477,7 @@ static void pcnet32_tx_timeout(struct net_device *dev)
                       "%s: transmit timed out, status %4.4x, resetting.\n",
                       dev->name, lp->a.read_csr(ioaddr, CSR0));
        lp->a.write_csr(ioaddr, CSR0, CSR0_STOP);
-       lp->stats.tx_errors++;
+       dev->stats.tx_errors++;
        if (netif_msg_tx_err(lp)) {
                int i;
                printk(KERN_DEBUG
@@ -2541,7 +2547,7 @@ static int pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
        lp->tx_ring[entry].status = cpu_to_le16(status);
 
        lp->cur_tx++;
-       lp->stats.tx_bytes += skb->len;
+       dev->stats.tx_bytes += skb->len;
 
        /* Trigger an immediate send poll. */
        lp->a.write_csr(ioaddr, CSR0, CSR0_INTEN | CSR0_TXPOLL);
@@ -2586,7 +2592,7 @@ pcnet32_interrupt(int irq, void *dev_id)
 
                /* Log misc errors. */
                if (csr0 & 0x4000)
-                       lp->stats.tx_errors++;  /* Tx babble. */
+                       dev->stats.tx_errors++; /* Tx babble. */
                if (csr0 & 0x1000) {
                        /*
                         * This happens when our receive ring is full. This
@@ -2599,7 +2605,7 @@ pcnet32_interrupt(int irq, void *dev_id)
                         * don't get a rx interrupt, but a missed frame
                         * interrupt sooner or later.
                         */
-                       lp->stats.rx_errors++;  /* Missed a Rx frame. */
+                       dev->stats.rx_errors++; /* Missed a Rx frame. */
                }
                if (csr0 & 0x0800) {
                        if (netif_msg_drv(lp))
@@ -2661,7 +2667,7 @@ static int pcnet32_close(struct net_device *dev)
 
        spin_lock_irqsave(&lp->lock, flags);
 
-       lp->stats.rx_missed_errors = lp->a.read_csr(ioaddr, 112);
+       dev->stats.rx_missed_errors = lp->a.read_csr(ioaddr, 112);
 
        if (netif_msg_ifdown(lp))
                printk(KERN_DEBUG
@@ -2698,10 +2704,10 @@ static struct net_device_stats *pcnet32_get_stats(struct net_device *dev)
        unsigned long flags;
 
        spin_lock_irqsave(&lp->lock, flags);
-       lp->stats.rx_missed_errors = lp->a.read_csr(ioaddr, 112);
+       dev->stats.rx_missed_errors = lp->a.read_csr(ioaddr, 112);
        spin_unlock_irqrestore(&lp->lock, flags);
 
-       return &lp->stats;
+       return &dev->stats;
 }
 
 /* taken from the sunlance driver, which it took from the depca driver */
index 8cd243d92af3ceeee3e25d74c6f534de9cc853c5..2747b1f89ffe27f372bc819bc25590560b1c15a2 100644 (file)
@@ -185,3 +185,5 @@ void free_mdio_bitbang(struct mii_bus *bus)
        module_put(ctrl->ops->owner);
        kfree(bus);
 }
+
+MODULE_LICENSE("GPL");
index c0b6d19d1457598ba7a83738a194400344725197..bcb0885011c8b1b410e335fa1fd0e8afe0877166 100644 (file)
@@ -55,7 +55,7 @@
 #include <linux/mm.h>
 #include <linux/ppp_defs.h>
 #include <linux/ppp-comp.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 
 #include "ppp_mppe.h"
 
@@ -68,9 +68,7 @@ MODULE_VERSION("1.0.2");
 static unsigned int
 setup_sg(struct scatterlist *sg, const void *address, unsigned int length)
 {
-       sg[0].page = virt_to_page(address);
-       sg[0].offset = offset_in_page(address);
-       sg[0].length = length;
+       sg_init_one(sg, address, length);
        return length;
 }
 
index aef66e2d98d2d36ba3d559f860efba434cb9c200..01f08d726ace1450fc7c1c51cef20e98c4fb420c 100644 (file)
@@ -20,17 +20,17 @@ struct XENA_dev_config {
 
 /* General Control-Status Registers */
        u64 general_int_status;
-#define GEN_INTR_TXPIC             BIT(0)
-#define GEN_INTR_TXDMA             BIT(1)
-#define GEN_INTR_TXMAC             BIT(2)
-#define GEN_INTR_TXXGXS            BIT(3)
-#define GEN_INTR_TXTRAFFIC         BIT(8)
-#define GEN_INTR_RXPIC             BIT(32)
-#define GEN_INTR_RXDMA             BIT(33)
-#define GEN_INTR_RXMAC             BIT(34)
-#define GEN_INTR_MC                BIT(35)
-#define GEN_INTR_RXXGXS            BIT(36)
-#define GEN_INTR_RXTRAFFIC         BIT(40)
+#define GEN_INTR_TXPIC             s2BIT(0)
+#define GEN_INTR_TXDMA             s2BIT(1)
+#define GEN_INTR_TXMAC             s2BIT(2)
+#define GEN_INTR_TXXGXS            s2BIT(3)
+#define GEN_INTR_TXTRAFFIC         s2BIT(8)
+#define GEN_INTR_RXPIC             s2BIT(32)
+#define GEN_INTR_RXDMA             s2BIT(33)
+#define GEN_INTR_RXMAC             s2BIT(34)
+#define GEN_INTR_MC                s2BIT(35)
+#define GEN_INTR_RXXGXS            s2BIT(36)
+#define GEN_INTR_RXTRAFFIC         s2BIT(40)
 #define GEN_ERROR_INTR             GEN_INTR_TXPIC | GEN_INTR_RXPIC | \
                                    GEN_INTR_TXDMA | GEN_INTR_RXDMA | \
                                    GEN_INTR_TXMAC | GEN_INTR_RXMAC | \
@@ -54,36 +54,36 @@ struct XENA_dev_config {
 
 
        u64 adapter_status;
-#define ADAPTER_STATUS_TDMA_READY          BIT(0)
-#define ADAPTER_STATUS_RDMA_READY          BIT(1)
-#define ADAPTER_STATUS_PFC_READY           BIT(2)
-#define ADAPTER_STATUS_TMAC_BUF_EMPTY      BIT(3)
-#define ADAPTER_STATUS_PIC_QUIESCENT       BIT(5)
-#define ADAPTER_STATUS_RMAC_REMOTE_FAULT   BIT(6)
-#define ADAPTER_STATUS_RMAC_LOCAL_FAULT    BIT(7)
+#define ADAPTER_STATUS_TDMA_READY          s2BIT(0)
+#define ADAPTER_STATUS_RDMA_READY          s2BIT(1)
+#define ADAPTER_STATUS_PFC_READY           s2BIT(2)
+#define ADAPTER_STATUS_TMAC_BUF_EMPTY      s2BIT(3)
+#define ADAPTER_STATUS_PIC_QUIESCENT       s2BIT(5)
+#define ADAPTER_STATUS_RMAC_REMOTE_FAULT   s2BIT(6)
+#define ADAPTER_STATUS_RMAC_LOCAL_FAULT    s2BIT(7)
 #define ADAPTER_STATUS_RMAC_PCC_IDLE       vBIT(0xFF,8,8)
 #define ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE  vBIT(0x0F,8,8)
 #define ADAPTER_STATUS_RC_PRC_QUIESCENT    vBIT(0xFF,16,8)
-#define ADAPTER_STATUS_MC_DRAM_READY       BIT(24)
-#define ADAPTER_STATUS_MC_QUEUES_READY     BIT(25)
-#define ADAPTER_STATUS_M_PLL_LOCK          BIT(30)
-#define ADAPTER_STATUS_P_PLL_LOCK          BIT(31)
+#define ADAPTER_STATUS_MC_DRAM_READY       s2BIT(24)
+#define ADAPTER_STATUS_MC_QUEUES_READY     s2BIT(25)
+#define ADAPTER_STATUS_M_PLL_LOCK          s2BIT(30)
+#define ADAPTER_STATUS_P_PLL_LOCK          s2BIT(31)
 
        u64 adapter_control;
-#define ADAPTER_CNTL_EN                    BIT(7)
-#define ADAPTER_EOI_TX_ON                  BIT(15)
-#define ADAPTER_LED_ON                     BIT(23)
+#define ADAPTER_CNTL_EN                    s2BIT(7)
+#define ADAPTER_EOI_TX_ON                  s2BIT(15)
+#define ADAPTER_LED_ON                     s2BIT(23)
 #define ADAPTER_UDPI(val)                  vBIT(val,36,4)
-#define ADAPTER_WAIT_INT                   BIT(48)
-#define ADAPTER_ECC_EN                     BIT(55)
+#define ADAPTER_WAIT_INT                   s2BIT(48)
+#define ADAPTER_ECC_EN                     s2BIT(55)
 
        u64 serr_source;
-#define SERR_SOURCE_PIC                        BIT(0)
-#define SERR_SOURCE_TXDMA              BIT(1)
-#define SERR_SOURCE_RXDMA              BIT(2)
-#define SERR_SOURCE_MAC                 BIT(3)
-#define SERR_SOURCE_MC                  BIT(4)
-#define SERR_SOURCE_XGXS                BIT(5)
+#define SERR_SOURCE_PIC                        s2BIT(0)
+#define SERR_SOURCE_TXDMA              s2BIT(1)
+#define SERR_SOURCE_RXDMA              s2BIT(2)
+#define SERR_SOURCE_MAC                 s2BIT(3)
+#define SERR_SOURCE_MC                  s2BIT(4)
+#define SERR_SOURCE_XGXS                s2BIT(5)
 #define        SERR_SOURCE_ANY                 (SERR_SOURCE_PIC        | \
                                        SERR_SOURCE_TXDMA       | \
                                        SERR_SOURCE_RXDMA       | \
@@ -101,41 +101,41 @@ struct XENA_dev_config {
 #define        PCI_MODE_PCIX_M2_66             0x5
 #define        PCI_MODE_PCIX_M2_100            0x6
 #define        PCI_MODE_PCIX_M2_133            0x7
-#define        PCI_MODE_UNSUPPORTED            BIT(0)
-#define        PCI_MODE_32_BITS                BIT(8)
-#define        PCI_MODE_UNKNOWN_MODE           BIT(9)
+#define        PCI_MODE_UNSUPPORTED            s2BIT(0)
+#define        PCI_MODE_32_BITS                s2BIT(8)
+#define        PCI_MODE_UNKNOWN_MODE           s2BIT(9)
 
        u8 unused_0[0x800 - 0x128];
 
 /* PCI-X Controller registers */
        u64 pic_int_status;
        u64 pic_int_mask;
-#define PIC_INT_TX                     BIT(0)
-#define PIC_INT_FLSH                   BIT(1)
-#define PIC_INT_MDIO                   BIT(2)
-#define PIC_INT_IIC                    BIT(3)
-#define PIC_INT_GPIO                   BIT(4)
-#define PIC_INT_RX                     BIT(32)
+#define PIC_INT_TX                     s2BIT(0)
+#define PIC_INT_FLSH                   s2BIT(1)
+#define PIC_INT_MDIO                   s2BIT(2)
+#define PIC_INT_IIC                    s2BIT(3)
+#define PIC_INT_GPIO                   s2BIT(4)
+#define PIC_INT_RX                     s2BIT(32)
 
        u64 txpic_int_reg;
        u64 txpic_int_mask;
-#define PCIX_INT_REG_ECC_SG_ERR                BIT(0)
-#define PCIX_INT_REG_ECC_DB_ERR                BIT(1)
-#define PCIX_INT_REG_FLASHR_R_FSM_ERR          BIT(8)
-#define PCIX_INT_REG_FLASHR_W_FSM_ERR          BIT(9)
-#define PCIX_INT_REG_INI_TX_FSM_SERR           BIT(10)
-#define PCIX_INT_REG_INI_TXO_FSM_ERR           BIT(11)
-#define PCIX_INT_REG_TRT_FSM_SERR              BIT(13)
-#define PCIX_INT_REG_SRT_FSM_SERR              BIT(14)
-#define PCIX_INT_REG_PIFR_FSM_SERR             BIT(15)
-#define PCIX_INT_REG_WRC_TX_SEND_FSM_SERR      BIT(21)
-#define PCIX_INT_REG_RRC_TX_REQ_FSM_SERR       BIT(23)
-#define PCIX_INT_REG_INI_RX_FSM_SERR           BIT(48)
-#define PCIX_INT_REG_RA_RX_FSM_SERR            BIT(50)
+#define PCIX_INT_REG_ECC_SG_ERR                s2BIT(0)
+#define PCIX_INT_REG_ECC_DB_ERR                s2BIT(1)
+#define PCIX_INT_REG_FLASHR_R_FSM_ERR          s2BIT(8)
+#define PCIX_INT_REG_FLASHR_W_FSM_ERR          s2BIT(9)
+#define PCIX_INT_REG_INI_TX_FSM_SERR           s2BIT(10)
+#define PCIX_INT_REG_INI_TXO_FSM_ERR           s2BIT(11)
+#define PCIX_INT_REG_TRT_FSM_SERR              s2BIT(13)
+#define PCIX_INT_REG_SRT_FSM_SERR              s2BIT(14)
+#define PCIX_INT_REG_PIFR_FSM_SERR             s2BIT(15)
+#define PCIX_INT_REG_WRC_TX_SEND_FSM_SERR      s2BIT(21)
+#define PCIX_INT_REG_RRC_TX_REQ_FSM_SERR       s2BIT(23)
+#define PCIX_INT_REG_INI_RX_FSM_SERR           s2BIT(48)
+#define PCIX_INT_REG_RA_RX_FSM_SERR            s2BIT(50)
 /*
-#define PCIX_INT_REG_WRC_RX_SEND_FSM_SERR      BIT(52)
-#define PCIX_INT_REG_RRC_RX_REQ_FSM_SERR       BIT(54)
-#define PCIX_INT_REG_RRC_RX_SPLIT_FSM_SERR     BIT(58)
+#define PCIX_INT_REG_WRC_RX_SEND_FSM_SERR      s2BIT(52)
+#define PCIX_INT_REG_RRC_RX_REQ_FSM_SERR       s2BIT(54)
+#define PCIX_INT_REG_RRC_RX_SPLIT_FSM_SERR     s2BIT(58)
 */
        u64 txpic_alarms;
        u64 rxpic_int_reg;
@@ -144,92 +144,92 @@ struct XENA_dev_config {
 
        u64 flsh_int_reg;
        u64 flsh_int_mask;
-#define PIC_FLSH_INT_REG_CYCLE_FSM_ERR         BIT(63)
-#define PIC_FLSH_INT_REG_ERR                   BIT(62)
+#define PIC_FLSH_INT_REG_CYCLE_FSM_ERR         s2BIT(63)
+#define PIC_FLSH_INT_REG_ERR                   s2BIT(62)
        u64 flash_alarms;
 
        u64 mdio_int_reg;
        u64 mdio_int_mask;
-#define MDIO_INT_REG_MDIO_BUS_ERR              BIT(0)
-#define MDIO_INT_REG_DTX_BUS_ERR               BIT(8)
-#define MDIO_INT_REG_LASI                      BIT(39)
+#define MDIO_INT_REG_MDIO_BUS_ERR              s2BIT(0)
+#define MDIO_INT_REG_DTX_BUS_ERR               s2BIT(8)
+#define MDIO_INT_REG_LASI                      s2BIT(39)
        u64 mdio_alarms;
 
        u64 iic_int_reg;
        u64 iic_int_mask;
-#define IIC_INT_REG_BUS_FSM_ERR                BIT(4)
-#define IIC_INT_REG_BIT_FSM_ERR                BIT(5)
-#define IIC_INT_REG_CYCLE_FSM_ERR              BIT(6)
-#define IIC_INT_REG_REQ_FSM_ERR                BIT(7)
-#define IIC_INT_REG_ACK_ERR                    BIT(8)
+#define IIC_INT_REG_BUS_FSM_ERR                s2BIT(4)
+#define IIC_INT_REG_BIT_FSM_ERR                s2BIT(5)
+#define IIC_INT_REG_CYCLE_FSM_ERR              s2BIT(6)
+#define IIC_INT_REG_REQ_FSM_ERR                s2BIT(7)
+#define IIC_INT_REG_ACK_ERR                    s2BIT(8)
        u64 iic_alarms;
 
        u8 unused4[0x08];
 
        u64 gpio_int_reg;
-#define GPIO_INT_REG_DP_ERR_INT                BIT(0)
-#define GPIO_INT_REG_LINK_DOWN                 BIT(1)
-#define GPIO_INT_REG_LINK_UP                   BIT(2)
+#define GPIO_INT_REG_DP_ERR_INT                s2BIT(0)
+#define GPIO_INT_REG_LINK_DOWN                 s2BIT(1)
+#define GPIO_INT_REG_LINK_UP                   s2BIT(2)
        u64 gpio_int_mask;
-#define GPIO_INT_MASK_LINK_DOWN                BIT(1)
-#define GPIO_INT_MASK_LINK_UP                  BIT(2)
+#define GPIO_INT_MASK_LINK_DOWN                s2BIT(1)
+#define GPIO_INT_MASK_LINK_UP                  s2BIT(2)
        u64 gpio_alarms;
 
        u8 unused5[0x38];
 
        u64 tx_traffic_int;
-#define TX_TRAFFIC_INT_n(n)                    BIT(n)
+#define TX_TRAFFIC_INT_n(n)                    s2BIT(n)
        u64 tx_traffic_mask;
 
        u64 rx_traffic_int;
-#define RX_TRAFFIC_INT_n(n)                    BIT(n)
+#define RX_TRAFFIC_INT_n(n)                    s2BIT(n)
        u64 rx_traffic_mask;
 
 /* PIC Control registers */
        u64 pic_control;
-#define PIC_CNTL_RX_ALARM_MAP_1                BIT(0)
+#define PIC_CNTL_RX_ALARM_MAP_1                s2BIT(0)
 #define PIC_CNTL_SHARED_SPLITS(n)              vBIT(n,11,5)
 
        u64 swapper_ctrl;
-#define SWAPPER_CTRL_PIF_R_FE                  BIT(0)
-#define SWAPPER_CTRL_PIF_R_SE                  BIT(1)
-#define SWAPPER_CTRL_PIF_W_FE                  BIT(8)
-#define SWAPPER_CTRL_PIF_W_SE                  BIT(9)
-#define SWAPPER_CTRL_TXP_FE                    BIT(16)
-#define SWAPPER_CTRL_TXP_SE                    BIT(17)
-#define SWAPPER_CTRL_TXD_R_FE                  BIT(18)
-#define SWAPPER_CTRL_TXD_R_SE                  BIT(19)
-#define SWAPPER_CTRL_TXD_W_FE                  BIT(20)
-#define SWAPPER_CTRL_TXD_W_SE                  BIT(21)
-#define SWAPPER_CTRL_TXF_R_FE                  BIT(22)
-#define SWAPPER_CTRL_TXF_R_SE                  BIT(23)
-#define SWAPPER_CTRL_RXD_R_FE                  BIT(32)
-#define SWAPPER_CTRL_RXD_R_SE                  BIT(33)
-#define SWAPPER_CTRL_RXD_W_FE                  BIT(34)
-#define SWAPPER_CTRL_RXD_W_SE                  BIT(35)
-#define SWAPPER_CTRL_RXF_W_FE                  BIT(36)
-#define SWAPPER_CTRL_RXF_W_SE                  BIT(37)
-#define SWAPPER_CTRL_XMSI_FE                   BIT(40)
-#define SWAPPER_CTRL_XMSI_SE                   BIT(41)
-#define SWAPPER_CTRL_STATS_FE                  BIT(48)
-#define SWAPPER_CTRL_STATS_SE                  BIT(49)
+#define SWAPPER_CTRL_PIF_R_FE                  s2BIT(0)
+#define SWAPPER_CTRL_PIF_R_SE                  s2BIT(1)
+#define SWAPPER_CTRL_PIF_W_FE                  s2BIT(8)
+#define SWAPPER_CTRL_PIF_W_SE                  s2BIT(9)
+#define SWAPPER_CTRL_TXP_FE                    s2BIT(16)
+#define SWAPPER_CTRL_TXP_SE                    s2BIT(17)
+#define SWAPPER_CTRL_TXD_R_FE                  s2BIT(18)
+#define SWAPPER_CTRL_TXD_R_SE                  s2BIT(19)
+#define SWAPPER_CTRL_TXD_W_FE                  s2BIT(20)
+#define SWAPPER_CTRL_TXD_W_SE                  s2BIT(21)
+#define SWAPPER_CTRL_TXF_R_FE                  s2BIT(22)
+#define SWAPPER_CTRL_TXF_R_SE                  s2BIT(23)
+#define SWAPPER_CTRL_RXD_R_FE                  s2BIT(32)
+#define SWAPPER_CTRL_RXD_R_SE                  s2BIT(33)
+#define SWAPPER_CTRL_RXD_W_FE                  s2BIT(34)
+#define SWAPPER_CTRL_RXD_W_SE                  s2BIT(35)
+#define SWAPPER_CTRL_RXF_W_FE                  s2BIT(36)
+#define SWAPPER_CTRL_RXF_W_SE                  s2BIT(37)
+#define SWAPPER_CTRL_XMSI_FE                   s2BIT(40)
+#define SWAPPER_CTRL_XMSI_SE                   s2BIT(41)
+#define SWAPPER_CTRL_STATS_FE                  s2BIT(48)
+#define SWAPPER_CTRL_STATS_SE                  s2BIT(49)
 
        u64 pif_rd_swapper_fb;
 #define IF_RD_SWAPPER_FB                            0x0123456789ABCDEF
 
        u64 scheduled_int_ctrl;
-#define SCHED_INT_CTRL_TIMER_EN                BIT(0)
-#define SCHED_INT_CTRL_ONE_SHOT                BIT(1)
+#define SCHED_INT_CTRL_TIMER_EN                s2BIT(0)
+#define SCHED_INT_CTRL_ONE_SHOT                s2BIT(1)
 #define SCHED_INT_CTRL_INT2MSI(val)            vBIT(val,10,6)
 #define SCHED_INT_PERIOD                       TBD
 
        u64 txreqtimeout;
 #define TXREQTO_VAL(val)                                               vBIT(val,0,32)
-#define TXREQTO_EN                                                             BIT(63)
+#define TXREQTO_EN                                                             s2BIT(63)
 
        u64 statsreqtimeout;
 #define STATREQTO_VAL(n)                       TBD
-#define STATREQTO_EN                           BIT(63)
+#define STATREQTO_EN                           s2BIT(63)
 
        u64 read_retry_delay;
        u64 read_retry_acceleration;
@@ -255,10 +255,10 @@ struct XENA_dev_config {
 
        /* Automated statistics collection */
        u64 stat_cfg;
-#define STAT_CFG_STAT_EN           BIT(0)
-#define STAT_CFG_ONE_SHOT_EN       BIT(1)
-#define STAT_CFG_STAT_NS_EN        BIT(8)
-#define STAT_CFG_STAT_RO           BIT(9)
+#define STAT_CFG_STAT_EN           s2BIT(0)
+#define STAT_CFG_ONE_SHOT_EN       s2BIT(1)
+#define STAT_CFG_STAT_NS_EN        s2BIT(8)
+#define STAT_CFG_STAT_RO           s2BIT(9)
 #define STAT_TRSF_PER(n)           TBD
 #define        PER_SEC                                    0x208d5
 #define        SET_UPDT_PERIOD(n)                 vBIT((PER_SEC*n),32,32)
@@ -290,18 +290,18 @@ struct XENA_dev_config {
 #define        I2C_CONTROL_DEV_ID(id)          vBIT(id,1,3)
 #define        I2C_CONTROL_ADDR(addr)          vBIT(addr,5,11)
 #define        I2C_CONTROL_BYTE_CNT(cnt)       vBIT(cnt,22,2)
-#define        I2C_CONTROL_READ                        BIT(24)
-#define        I2C_CONTROL_NACK                        BIT(25)
+#define        I2C_CONTROL_READ                        s2BIT(24)
+#define        I2C_CONTROL_NACK                        s2BIT(25)
 #define        I2C_CONTROL_CNTL_START          vBIT(0xE,28,4)
 #define        I2C_CONTROL_CNTL_END(val)       (val & vBIT(0x1,28,4))
 #define        I2C_CONTROL_GET_DATA(val)       (u32)(val & 0xFFFFFFFF)
 #define        I2C_CONTROL_SET_DATA(val)       vBIT(val,32,32)
 
        u64 gpio_control;
-#define GPIO_CTRL_GPIO_0               BIT(8)
+#define GPIO_CTRL_GPIO_0               s2BIT(8)
        u64 misc_control;
-#define FAULT_BEHAVIOUR                        BIT(0)
-#define EXT_REQ_EN                     BIT(1)
+#define FAULT_BEHAVIOUR                        s2BIT(0)
+#define EXT_REQ_EN                     s2BIT(1)
 #define MISC_LINK_STABILITY_PRD(val)   vBIT(val,29,3)
 
        u8 unused7_1[0x230 - 0x208];
@@ -317,29 +317,29 @@ struct XENA_dev_config {
 /* TxDMA registers */
        u64 txdma_int_status;
        u64 txdma_int_mask;
-#define TXDMA_PFC_INT                  BIT(0)
-#define TXDMA_TDA_INT                  BIT(1)
-#define TXDMA_PCC_INT                  BIT(2)
-#define TXDMA_TTI_INT                  BIT(3)
-#define TXDMA_LSO_INT                  BIT(4)
-#define TXDMA_TPA_INT                  BIT(5)
-#define TXDMA_SM_INT                   BIT(6)
+#define TXDMA_PFC_INT                  s2BIT(0)
+#define TXDMA_TDA_INT                  s2BIT(1)
+#define TXDMA_PCC_INT                  s2BIT(2)
+#define TXDMA_TTI_INT                  s2BIT(3)
+#define TXDMA_LSO_INT                  s2BIT(4)
+#define TXDMA_TPA_INT                  s2BIT(5)
+#define TXDMA_SM_INT                   s2BIT(6)
        u64 pfc_err_reg;
-#define PFC_ECC_SG_ERR                 BIT(7)
-#define PFC_ECC_DB_ERR                 BIT(15)
-#define PFC_SM_ERR_ALARM               BIT(23)
-#define PFC_MISC_0_ERR                 BIT(31)
-#define PFC_MISC_1_ERR                 BIT(32)
-#define PFC_PCIX_ERR                   BIT(39)
+#define PFC_ECC_SG_ERR                 s2BIT(7)
+#define PFC_ECC_DB_ERR                 s2BIT(15)
+#define PFC_SM_ERR_ALARM               s2BIT(23)
+#define PFC_MISC_0_ERR                 s2BIT(31)
+#define PFC_MISC_1_ERR                 s2BIT(32)
+#define PFC_PCIX_ERR                   s2BIT(39)
        u64 pfc_err_mask;
        u64 pfc_err_alarm;
 
        u64 tda_err_reg;
 #define TDA_Fn_ECC_SG_ERR              vBIT(0xff,0,8)
 #define TDA_Fn_ECC_DB_ERR              vBIT(0xff,8,8)
-#define TDA_SM0_ERR_ALARM              BIT(22)
-#define TDA_SM1_ERR_ALARM              BIT(23)
-#define TDA_PCIX_ERR                   BIT(39)
+#define TDA_SM0_ERR_ALARM              s2BIT(22)
+#define TDA_SM1_ERR_ALARM              s2BIT(23)
+#define TDA_PCIX_ERR                   s2BIT(39)
        u64 tda_err_mask;
        u64 tda_err_alarm;
 
@@ -351,40 +351,40 @@ struct XENA_dev_config {
 #define PCC_SM_ERR_ALARM               vBIT(0xff,32,8)
 #define PCC_WR_ERR_ALARM               vBIT(0xff,40,8)
 #define PCC_N_SERR                     vBIT(0xff,48,8)
-#define PCC_6_COF_OV_ERR               BIT(56)
-#define PCC_7_COF_OV_ERR               BIT(57)
-#define PCC_6_LSO_OV_ERR               BIT(58)
-#define PCC_7_LSO_OV_ERR               BIT(59)
+#define PCC_6_COF_OV_ERR               s2BIT(56)
+#define PCC_7_COF_OV_ERR               s2BIT(57)
+#define PCC_6_LSO_OV_ERR               s2BIT(58)
+#define PCC_7_LSO_OV_ERR               s2BIT(59)
 #define PCC_ENABLE_FOUR                        vBIT(0x0F,0,8)
        u64 pcc_err_mask;
        u64 pcc_err_alarm;
 
        u64 tti_err_reg;
-#define TTI_ECC_SG_ERR                 BIT(7)
-#define TTI_ECC_DB_ERR                 BIT(15)
-#define TTI_SM_ERR_ALARM               BIT(23)
+#define TTI_ECC_SG_ERR                 s2BIT(7)
+#define TTI_ECC_DB_ERR                 s2BIT(15)
+#define TTI_SM_ERR_ALARM               s2BIT(23)
        u64 tti_err_mask;
        u64 tti_err_alarm;
 
        u64 lso_err_reg;
-#define LSO6_SEND_OFLOW                        BIT(12)
-#define LSO7_SEND_OFLOW                        BIT(13)
-#define LSO6_ABORT                     BIT(14)
-#define LSO7_ABORT                     BIT(15)
-#define LSO6_SM_ERR_ALARM              BIT(22)
-#define LSO7_SM_ERR_ALARM              BIT(23)
+#define LSO6_SEND_OFLOW                        s2BIT(12)
+#define LSO7_SEND_OFLOW                        s2BIT(13)
+#define LSO6_ABORT                     s2BIT(14)
+#define LSO7_ABORT                     s2BIT(15)
+#define LSO6_SM_ERR_ALARM              s2BIT(22)
+#define LSO7_SM_ERR_ALARM              s2BIT(23)
        u64 lso_err_mask;
        u64 lso_err_alarm;
 
        u64 tpa_err_reg;
-#define TPA_TX_FRM_DROP                        BIT(7)
-#define TPA_SM_ERR_ALARM               BIT(23)
+#define TPA_TX_FRM_DROP                        s2BIT(7)
+#define TPA_SM_ERR_ALARM               s2BIT(23)
 
        u64 tpa_err_mask;
        u64 tpa_err_alarm;
 
        u64 sm_err_reg;
-#define SM_SM_ERR_ALARM                        BIT(15)
+#define SM_SM_ERR_ALARM                        s2BIT(15)
        u64 sm_err_mask;
        u64 sm_err_alarm;
 
@@ -397,7 +397,7 @@ struct XENA_dev_config {
 #define X_MAX_FIFOS                        8
 #define X_FIFO_MAX_LEN                     0x1FFF      /*8191 */
        u64 tx_fifo_partition_0;
-#define TX_FIFO_PARTITION_EN               BIT(0)
+#define TX_FIFO_PARTITION_EN               s2BIT(0)
 #define TX_FIFO_PARTITION_0_PRI(val)       vBIT(val,5,3)
 #define TX_FIFO_PARTITION_0_LEN(val)       vBIT(val,19,13)
 #define TX_FIFO_PARTITION_1_PRI(val)       vBIT(val,37,3)
@@ -437,16 +437,16 @@ struct XENA_dev_config {
        u64 tx_w_round_robin_4;
 
        u64 tti_command_mem;
-#define TTI_CMD_MEM_WE                     BIT(7)
-#define TTI_CMD_MEM_STROBE_NEW_CMD         BIT(15)
-#define TTI_CMD_MEM_STROBE_BEING_EXECUTED  BIT(15)
+#define TTI_CMD_MEM_WE                     s2BIT(7)
+#define TTI_CMD_MEM_STROBE_NEW_CMD         s2BIT(15)
+#define TTI_CMD_MEM_STROBE_BEING_EXECUTED  s2BIT(15)
 #define TTI_CMD_MEM_OFFSET(n)              vBIT(n,26,6)
 
        u64 tti_data1_mem;
 #define TTI_DATA1_MEM_TX_TIMER_VAL(n)      vBIT(n,6,26)
 #define TTI_DATA1_MEM_TX_TIMER_AC_CI(n)    vBIT(n,38,2)
-#define TTI_DATA1_MEM_TX_TIMER_AC_EN       BIT(38)
-#define TTI_DATA1_MEM_TX_TIMER_CI_EN       BIT(39)
+#define TTI_DATA1_MEM_TX_TIMER_AC_EN       s2BIT(38)
+#define TTI_DATA1_MEM_TX_TIMER_CI_EN       s2BIT(39)
 #define TTI_DATA1_MEM_TX_URNG_A(n)         vBIT(n,41,7)
 #define TTI_DATA1_MEM_TX_URNG_B(n)         vBIT(n,49,7)
 #define TTI_DATA1_MEM_TX_URNG_C(n)         vBIT(n,57,7)
@@ -459,11 +459,11 @@ struct XENA_dev_config {
 
 /* Tx Protocol assist */
        u64 tx_pa_cfg;
-#define TX_PA_CFG_IGNORE_FRM_ERR           BIT(1)
-#define TX_PA_CFG_IGNORE_SNAP_OUI          BIT(2)
-#define TX_PA_CFG_IGNORE_LLC_CTRL          BIT(3)
-#define        TX_PA_CFG_IGNORE_L2_ERR                    BIT(6)
-#define RX_PA_CFG_STRIP_VLAN_TAG               BIT(15)
+#define TX_PA_CFG_IGNORE_FRM_ERR           s2BIT(1)
+#define TX_PA_CFG_IGNORE_SNAP_OUI          s2BIT(2)
+#define TX_PA_CFG_IGNORE_LLC_CTRL          s2BIT(3)
+#define        TX_PA_CFG_IGNORE_L2_ERR                    s2BIT(6)
+#define RX_PA_CFG_STRIP_VLAN_TAG               s2BIT(15)
 
 /* Recent add, used only debug purposes. */
        u64 pcc_enable;
@@ -477,31 +477,31 @@ struct XENA_dev_config {
 /* RxDMA Registers */
        u64 rxdma_int_status;
        u64 rxdma_int_mask;
-#define RXDMA_INT_RC_INT_M             BIT(0)
-#define RXDMA_INT_RPA_INT_M            BIT(1)
-#define RXDMA_INT_RDA_INT_M            BIT(2)
-#define RXDMA_INT_RTI_INT_M            BIT(3)
+#define RXDMA_INT_RC_INT_M             s2BIT(0)
+#define RXDMA_INT_RPA_INT_M            s2BIT(1)
+#define RXDMA_INT_RDA_INT_M            s2BIT(2)
+#define RXDMA_INT_RTI_INT_M            s2BIT(3)
 
        u64 rda_err_reg;
 #define RDA_RXDn_ECC_SG_ERR            vBIT(0xFF,0,8)
 #define RDA_RXDn_ECC_DB_ERR            vBIT(0xFF,8,8)
-#define RDA_FRM_ECC_SG_ERR             BIT(23)
-#define RDA_FRM_ECC_DB_N_AERR          BIT(31)
-#define RDA_SM1_ERR_ALARM              BIT(38)
-#define RDA_SM0_ERR_ALARM              BIT(39)
-#define RDA_MISC_ERR                   BIT(47)
-#define RDA_PCIX_ERR                   BIT(55)
-#define RDA_RXD_ECC_DB_SERR            BIT(63)
+#define RDA_FRM_ECC_SG_ERR             s2BIT(23)
+#define RDA_FRM_ECC_DB_N_AERR          s2BIT(31)
+#define RDA_SM1_ERR_ALARM              s2BIT(38)
+#define RDA_SM0_ERR_ALARM              s2BIT(39)
+#define RDA_MISC_ERR                   s2BIT(47)
+#define RDA_PCIX_ERR                   s2BIT(55)
+#define RDA_RXD_ECC_DB_SERR            s2BIT(63)
        u64 rda_err_mask;
        u64 rda_err_alarm;
 
        u64 rc_err_reg;
 #define RC_PRCn_ECC_SG_ERR             vBIT(0xFF,0,8)
 #define RC_PRCn_ECC_DB_ERR             vBIT(0xFF,8,8)
-#define RC_FTC_ECC_SG_ERR              BIT(23)
-#define RC_FTC_ECC_DB_ERR              BIT(31)
+#define RC_FTC_ECC_SG_ERR              s2BIT(23)
+#define RC_FTC_ECC_DB_ERR              s2BIT(31)
 #define RC_PRCn_SM_ERR_ALARM           vBIT(0xFF,32,8)
-#define RC_FTC_SM_ERR_ALARM            BIT(47)
+#define RC_FTC_SM_ERR_ALARM            s2BIT(47)
 #define RC_RDA_FAIL_WR_Rn              vBIT(0xFF,48,8)
        u64 rc_err_mask;
        u64 rc_err_alarm;
@@ -517,18 +517,18 @@ struct XENA_dev_config {
        u64 prc_pcix_err_alarm;
 
        u64 rpa_err_reg;
-#define RPA_ECC_SG_ERR                 BIT(7)
-#define RPA_ECC_DB_ERR                 BIT(15)
-#define RPA_FLUSH_REQUEST              BIT(22)
-#define RPA_SM_ERR_ALARM               BIT(23)
-#define RPA_CREDIT_ERR                 BIT(31)
+#define RPA_ECC_SG_ERR                 s2BIT(7)
+#define RPA_ECC_DB_ERR                 s2BIT(15)
+#define RPA_FLUSH_REQUEST              s2BIT(22)
+#define RPA_SM_ERR_ALARM               s2BIT(23)
+#define RPA_CREDIT_ERR                 s2BIT(31)
        u64 rpa_err_mask;
        u64 rpa_err_alarm;
 
        u64 rti_err_reg;
-#define RTI_ECC_SG_ERR                 BIT(7)
-#define RTI_ECC_DB_ERR                 BIT(15)
-#define RTI_SM_ERR_ALARM               BIT(23)
+#define RTI_ECC_SG_ERR                 s2BIT(7)
+#define RTI_ECC_DB_ERR                 s2BIT(15)
+#define RTI_SM_ERR_ALARM               s2BIT(23)
        u64 rti_err_mask;
        u64 rti_err_alarm;
 
@@ -568,49 +568,49 @@ struct XENA_dev_config {
 #endif
        u64 prc_rxd0_n[RX_MAX_RINGS];
        u64 prc_ctrl_n[RX_MAX_RINGS];
-#define PRC_CTRL_RC_ENABLED                    BIT(7)
-#define PRC_CTRL_RING_MODE                     (BIT(14)|BIT(15))
+#define PRC_CTRL_RC_ENABLED                    s2BIT(7)
+#define PRC_CTRL_RING_MODE                     (s2BIT(14)|s2BIT(15))
 #define PRC_CTRL_RING_MODE_1                   vBIT(0,14,2)
 #define PRC_CTRL_RING_MODE_3                   vBIT(1,14,2)
 #define PRC_CTRL_RING_MODE_5                   vBIT(2,14,2)
 #define PRC_CTRL_RING_MODE_x                   vBIT(3,14,2)
-#define PRC_CTRL_NO_SNOOP                      (BIT(22)|BIT(23))
-#define PRC_CTRL_NO_SNOOP_DESC                 BIT(22)
-#define PRC_CTRL_NO_SNOOP_BUFF                 BIT(23)
-#define PRC_CTRL_BIMODAL_INTERRUPT             BIT(37)
-#define PRC_CTRL_GROUP_READS                   BIT(38)
+#define PRC_CTRL_NO_SNOOP                      (s2BIT(22)|s2BIT(23))
+#define PRC_CTRL_NO_SNOOP_DESC                 s2BIT(22)
+#define PRC_CTRL_NO_SNOOP_BUFF                 s2BIT(23)
+#define PRC_CTRL_BIMODAL_INTERRUPT             s2BIT(37)
+#define PRC_CTRL_GROUP_READS                   s2BIT(38)
 #define PRC_CTRL_RXD_BACKOFF_INTERVAL(val)     vBIT(val,40,24)
 
        u64 prc_alarm_action;
-#define PRC_ALARM_ACTION_RR_R0_STOP            BIT(3)
-#define PRC_ALARM_ACTION_RW_R0_STOP            BIT(7)
-#define PRC_ALARM_ACTION_RR_R1_STOP            BIT(11)
-#define PRC_ALARM_ACTION_RW_R1_STOP            BIT(15)
-#define PRC_ALARM_ACTION_RR_R2_STOP            BIT(19)
-#define PRC_ALARM_ACTION_RW_R2_STOP            BIT(23)
-#define PRC_ALARM_ACTION_RR_R3_STOP            BIT(27)
-#define PRC_ALARM_ACTION_RW_R3_STOP            BIT(31)
-#define PRC_ALARM_ACTION_RR_R4_STOP            BIT(35)
-#define PRC_ALARM_ACTION_RW_R4_STOP            BIT(39)
-#define PRC_ALARM_ACTION_RR_R5_STOP            BIT(43)
-#define PRC_ALARM_ACTION_RW_R5_STOP            BIT(47)
-#define PRC_ALARM_ACTION_RR_R6_STOP            BIT(51)
-#define PRC_ALARM_ACTION_RW_R6_STOP            BIT(55)
-#define PRC_ALARM_ACTION_RR_R7_STOP            BIT(59)
-#define PRC_ALARM_ACTION_RW_R7_STOP            BIT(63)
+#define PRC_ALARM_ACTION_RR_R0_STOP            s2BIT(3)
+#define PRC_ALARM_ACTION_RW_R0_STOP            s2BIT(7)
+#define PRC_ALARM_ACTION_RR_R1_STOP            s2BIT(11)
+#define PRC_ALARM_ACTION_RW_R1_STOP            s2BIT(15)
+#define PRC_ALARM_ACTION_RR_R2_STOP            s2BIT(19)
+#define PRC_ALARM_ACTION_RW_R2_STOP            s2BIT(23)
+#define PRC_ALARM_ACTION_RR_R3_STOP            s2BIT(27)
+#define PRC_ALARM_ACTION_RW_R3_STOP            s2BIT(31)
+#define PRC_ALARM_ACTION_RR_R4_STOP            s2BIT(35)
+#define PRC_ALARM_ACTION_RW_R4_STOP            s2BIT(39)
+#define PRC_ALARM_ACTION_RR_R5_STOP            s2BIT(43)
+#define PRC_ALARM_ACTION_RW_R5_STOP            s2BIT(47)
+#define PRC_ALARM_ACTION_RR_R6_STOP            s2BIT(51)
+#define PRC_ALARM_ACTION_RW_R6_STOP            s2BIT(55)
+#define PRC_ALARM_ACTION_RR_R7_STOP            s2BIT(59)
+#define PRC_ALARM_ACTION_RW_R7_STOP            s2BIT(63)
 
 /* Receive traffic interrupts */
        u64 rti_command_mem;
-#define RTI_CMD_MEM_WE                          BIT(7)
-#define RTI_CMD_MEM_STROBE                      BIT(15)
-#define RTI_CMD_MEM_STROBE_NEW_CMD              BIT(15)
-#define RTI_CMD_MEM_STROBE_CMD_BEING_EXECUTED   BIT(15)
+#define RTI_CMD_MEM_WE                          s2BIT(7)
+#define RTI_CMD_MEM_STROBE                      s2BIT(15)
+#define RTI_CMD_MEM_STROBE_NEW_CMD              s2BIT(15)
+#define RTI_CMD_MEM_STROBE_CMD_BEING_EXECUTED   s2BIT(15)
 #define RTI_CMD_MEM_OFFSET(n)                   vBIT(n,29,3)
 
        u64 rti_data1_mem;
 #define RTI_DATA1_MEM_RX_TIMER_VAL(n)      vBIT(n,3,29)
-#define RTI_DATA1_MEM_RX_TIMER_AC_EN       BIT(38)
-#define RTI_DATA1_MEM_RX_TIMER_CI_EN       BIT(39)
+#define RTI_DATA1_MEM_RX_TIMER_AC_EN       s2BIT(38)
+#define RTI_DATA1_MEM_RX_TIMER_CI_EN       s2BIT(39)
 #define RTI_DATA1_MEM_RX_URNG_A(n)         vBIT(n,41,7)
 #define RTI_DATA1_MEM_RX_URNG_B(n)         vBIT(n,49,7)
 #define RTI_DATA1_MEM_RX_URNG_C(n)         vBIT(n,57,7)
@@ -622,10 +622,10 @@ struct XENA_dev_config {
 #define RTI_DATA2_MEM_RX_UFC_D(n)          vBIT(n,48,16)
 
        u64 rx_pa_cfg;
-#define RX_PA_CFG_IGNORE_FRM_ERR           BIT(1)
-#define RX_PA_CFG_IGNORE_SNAP_OUI          BIT(2)
-#define RX_PA_CFG_IGNORE_LLC_CTRL          BIT(3)
-#define RX_PA_CFG_IGNORE_L2_ERR            BIT(6)
+#define RX_PA_CFG_IGNORE_FRM_ERR           s2BIT(1)
+#define RX_PA_CFG_IGNORE_SNAP_OUI          s2BIT(2)
+#define RX_PA_CFG_IGNORE_LLC_CTRL          s2BIT(3)
+#define RX_PA_CFG_IGNORE_L2_ERR            s2BIT(6)
 
        u64 unused_11_1;
 
@@ -641,64 +641,64 @@ struct XENA_dev_config {
 /* Media Access Controller Register */
        u64 mac_int_status;
        u64 mac_int_mask;
-#define MAC_INT_STATUS_TMAC_INT            BIT(0)
-#define MAC_INT_STATUS_RMAC_INT            BIT(1)
+#define MAC_INT_STATUS_TMAC_INT            s2BIT(0)
+#define MAC_INT_STATUS_RMAC_INT            s2BIT(1)
 
        u64 mac_tmac_err_reg;
-#define TMAC_ECC_SG_ERR                                BIT(7)
-#define TMAC_ECC_DB_ERR                                BIT(15)
-#define TMAC_TX_BUF_OVRN                       BIT(23)
-#define TMAC_TX_CRI_ERR                                BIT(31)
-#define TMAC_TX_SM_ERR                         BIT(39)
-#define TMAC_DESC_ECC_SG_ERR                   BIT(47)
-#define TMAC_DESC_ECC_DB_ERR                   BIT(55)
+#define TMAC_ECC_SG_ERR                                s2BIT(7)
+#define TMAC_ECC_DB_ERR                                s2BIT(15)
+#define TMAC_TX_BUF_OVRN                       s2BIT(23)
+#define TMAC_TX_CRI_ERR                                s2BIT(31)
+#define TMAC_TX_SM_ERR                         s2BIT(39)
+#define TMAC_DESC_ECC_SG_ERR                   s2BIT(47)
+#define TMAC_DESC_ECC_DB_ERR                   s2BIT(55)
 
        u64 mac_tmac_err_mask;
        u64 mac_tmac_err_alarm;
 
        u64 mac_rmac_err_reg;
-#define RMAC_RX_BUFF_OVRN                      BIT(0)
-#define RMAC_FRM_RCVD_INT                      BIT(1)
-#define RMAC_UNUSED_INT                                BIT(2)
-#define RMAC_RTS_PNUM_ECC_SG_ERR               BIT(5)
-#define RMAC_RTS_DS_ECC_SG_ERR                 BIT(6)
-#define RMAC_RD_BUF_ECC_SG_ERR                 BIT(7)
-#define RMAC_RTH_MAP_ECC_SG_ERR                        BIT(8)
-#define RMAC_RTH_SPDM_ECC_SG_ERR               BIT(9)
-#define RMAC_RTS_VID_ECC_SG_ERR                        BIT(10)
-#define RMAC_DA_SHADOW_ECC_SG_ERR              BIT(11)
-#define RMAC_RTS_PNUM_ECC_DB_ERR               BIT(13)
-#define RMAC_RTS_DS_ECC_DB_ERR                 BIT(14)
-#define RMAC_RD_BUF_ECC_DB_ERR                 BIT(15)
-#define RMAC_RTH_MAP_ECC_DB_ERR                        BIT(16)
-#define RMAC_RTH_SPDM_ECC_DB_ERR               BIT(17)
-#define RMAC_RTS_VID_ECC_DB_ERR                        BIT(18)
-#define RMAC_DA_SHADOW_ECC_DB_ERR              BIT(19)
-#define RMAC_LINK_STATE_CHANGE_INT             BIT(31)
-#define RMAC_RX_SM_ERR                         BIT(39)
-#define RMAC_SINGLE_ECC_ERR                    (BIT(5) | BIT(6) | BIT(7) |\
-                                               BIT(8)  | BIT(9) | BIT(10)|\
-                                               BIT(11))
-#define RMAC_DOUBLE_ECC_ERR                    (BIT(13) | BIT(14) | BIT(15) |\
-                                               BIT(16)  | BIT(17) | BIT(18)|\
-                                               BIT(19))
+#define RMAC_RX_BUFF_OVRN                      s2BIT(0)
+#define RMAC_FRM_RCVD_INT                      s2BIT(1)
+#define RMAC_UNUSED_INT                                s2BIT(2)
+#define RMAC_RTS_PNUM_ECC_SG_ERR               s2BIT(5)
+#define RMAC_RTS_DS_ECC_SG_ERR                 s2BIT(6)
+#define RMAC_RD_BUF_ECC_SG_ERR                 s2BIT(7)
+#define RMAC_RTH_MAP_ECC_SG_ERR                        s2BIT(8)
+#define RMAC_RTH_SPDM_ECC_SG_ERR               s2BIT(9)
+#define RMAC_RTS_VID_ECC_SG_ERR                        s2BIT(10)
+#define RMAC_DA_SHADOW_ECC_SG_ERR              s2BIT(11)
+#define RMAC_RTS_PNUM_ECC_DB_ERR               s2BIT(13)
+#define RMAC_RTS_DS_ECC_DB_ERR                 s2BIT(14)
+#define RMAC_RD_BUF_ECC_DB_ERR                 s2BIT(15)
+#define RMAC_RTH_MAP_ECC_DB_ERR                        s2BIT(16)
+#define RMAC_RTH_SPDM_ECC_DB_ERR               s2BIT(17)
+#define RMAC_RTS_VID_ECC_DB_ERR                        s2BIT(18)
+#define RMAC_DA_SHADOW_ECC_DB_ERR              s2BIT(19)
+#define RMAC_LINK_STATE_CHANGE_INT             s2BIT(31)
+#define RMAC_RX_SM_ERR                         s2BIT(39)
+#define RMAC_SINGLE_ECC_ERR                    (s2BIT(5) | s2BIT(6) | s2BIT(7) |\
+                                               s2BIT(8)  | s2BIT(9) | s2BIT(10)|\
+                                               s2BIT(11))
+#define RMAC_DOUBLE_ECC_ERR                    (s2BIT(13) | s2BIT(14) | s2BIT(15) |\
+                                               s2BIT(16)  | s2BIT(17) | s2BIT(18)|\
+                                               s2BIT(19))
        u64 mac_rmac_err_mask;
        u64 mac_rmac_err_alarm;
 
        u8 unused14[0x100 - 0x40];
 
        u64 mac_cfg;
-#define MAC_CFG_TMAC_ENABLE             BIT(0)
-#define MAC_CFG_RMAC_ENABLE             BIT(1)
-#define MAC_CFG_LAN_NOT_WAN             BIT(2)
-#define MAC_CFG_TMAC_LOOPBACK           BIT(3)
-#define MAC_CFG_TMAC_APPEND_PAD         BIT(4)
-#define MAC_CFG_RMAC_STRIP_FCS          BIT(5)
-#define MAC_CFG_RMAC_STRIP_PAD          BIT(6)
-#define MAC_CFG_RMAC_PROM_ENABLE        BIT(7)
-#define MAC_RMAC_DISCARD_PFRM           BIT(8)
-#define MAC_RMAC_BCAST_ENABLE           BIT(9)
-#define MAC_RMAC_ALL_ADDR_ENABLE        BIT(10)
+#define MAC_CFG_TMAC_ENABLE             s2BIT(0)
+#define MAC_CFG_RMAC_ENABLE             s2BIT(1)
+#define MAC_CFG_LAN_NOT_WAN             s2BIT(2)
+#define MAC_CFG_TMAC_LOOPBACK           s2BIT(3)
+#define MAC_CFG_TMAC_APPEND_PAD         s2BIT(4)
+#define MAC_CFG_RMAC_STRIP_FCS          s2BIT(5)
+#define MAC_CFG_RMAC_STRIP_PAD          s2BIT(6)
+#define MAC_CFG_RMAC_PROM_ENABLE        s2BIT(7)
+#define MAC_RMAC_DISCARD_PFRM           s2BIT(8)
+#define MAC_RMAC_BCAST_ENABLE           s2BIT(9)
+#define MAC_RMAC_ALL_ADDR_ENABLE        s2BIT(10)
 #define MAC_RMAC_INVLD_IPG_THR(val)     vBIT(val,16,8)
 
        u64 tmac_avg_ipg;
@@ -710,14 +710,14 @@ struct XENA_dev_config {
 #define RMAC_MAX_PYLD_LEN_JUMBO_DEF vBIT(9600,2,14)
 
        u64 rmac_err_cfg;
-#define RMAC_ERR_FCS                    BIT(0)
-#define RMAC_ERR_FCS_ACCEPT             BIT(1)
-#define RMAC_ERR_TOO_LONG               BIT(1)
-#define RMAC_ERR_TOO_LONG_ACCEPT        BIT(1)
-#define RMAC_ERR_RUNT                   BIT(2)
-#define RMAC_ERR_RUNT_ACCEPT            BIT(2)
-#define RMAC_ERR_LEN_MISMATCH           BIT(3)
-#define RMAC_ERR_LEN_MISMATCH_ACCEPT    BIT(3)
+#define RMAC_ERR_FCS                    s2BIT(0)
+#define RMAC_ERR_FCS_ACCEPT             s2BIT(1)
+#define RMAC_ERR_TOO_LONG               s2BIT(1)
+#define RMAC_ERR_TOO_LONG_ACCEPT        s2BIT(1)
+#define RMAC_ERR_RUNT                   s2BIT(2)
+#define RMAC_ERR_RUNT_ACCEPT            s2BIT(2)
+#define RMAC_ERR_LEN_MISMATCH           s2BIT(3)
+#define RMAC_ERR_LEN_MISMATCH_ACCEPT    s2BIT(3)
 
        u64 rmac_cfg_key;
 #define RMAC_CFG_KEY(val)               vBIT(val,0,16)
@@ -728,15 +728,15 @@ struct XENA_dev_config {
 #define MAC_MC_ADDR_START_OFFSET    16
 #define MAC_MC_ALL_MC_ADDR_OFFSET   63 /* enables all multicast pkts */
        u64 rmac_addr_cmd_mem;
-#define RMAC_ADDR_CMD_MEM_WE                    BIT(7)
+#define RMAC_ADDR_CMD_MEM_WE                    s2BIT(7)
 #define RMAC_ADDR_CMD_MEM_RD                    0
-#define RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD        BIT(15)
-#define RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING  BIT(15)
+#define RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD        s2BIT(15)
+#define RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING  s2BIT(15)
 #define RMAC_ADDR_CMD_MEM_OFFSET(n)             vBIT(n,26,6)
 
        u64 rmac_addr_data0_mem;
 #define RMAC_ADDR_DATA0_MEM_ADDR(n)    vBIT(n,0,48)
-#define RMAC_ADDR_DATA0_MEM_USER       BIT(48)
+#define RMAC_ADDR_DATA0_MEM_USER       s2BIT(48)
 
        u64 rmac_addr_data1_mem;
 #define RMAC_ADDR_DATA1_MEM_MASK(n)    vBIT(n,0,48)
@@ -753,10 +753,10 @@ struct XENA_dev_config {
        u64 tmac_ipg_cfg;
 
        u64 rmac_pause_cfg;
-#define RMAC_PAUSE_GEN             BIT(0)
-#define RMAC_PAUSE_GEN_ENABLE      BIT(0)
-#define RMAC_PAUSE_RX              BIT(1)
-#define RMAC_PAUSE_RX_ENABLE       BIT(1)
+#define RMAC_PAUSE_GEN             s2BIT(0)
+#define RMAC_PAUSE_GEN_ENABLE      s2BIT(0)
+#define RMAC_PAUSE_RX              s2BIT(1)
+#define RMAC_PAUSE_RX_ENABLE       s2BIT(1)
 #define RMAC_PAUSE_HG_PTIME_DEF    vBIT(0xFFFF,16,16)
 #define RMAC_PAUSE_HG_PTIME(val)    vBIT(val,16,16)
 
@@ -787,29 +787,29 @@ struct XENA_dev_config {
 #define MAX_DIX_MAP                         4
        u64 rts_dix_map_n[MAX_DIX_MAP];
 #define RTS_DIX_MAP_ETYPE(val)             vBIT(val,0,16)
-#define RTS_DIX_MAP_SCW(val)               BIT(val,21)
+#define RTS_DIX_MAP_SCW(val)               s2BIT(val,21)
 
        u64 rts_q_alternates;
        u64 rts_default_q;
 
        u64 rts_ctrl;
-#define RTS_CTRL_IGNORE_SNAP_OUI           BIT(2)
-#define RTS_CTRL_IGNORE_LLC_CTRL           BIT(3)
+#define RTS_CTRL_IGNORE_SNAP_OUI           s2BIT(2)
+#define RTS_CTRL_IGNORE_LLC_CTRL           s2BIT(3)
 
        u64 rts_pn_cam_ctrl;
-#define RTS_PN_CAM_CTRL_WE                 BIT(7)
-#define RTS_PN_CAM_CTRL_STROBE_NEW_CMD     BIT(15)
-#define RTS_PN_CAM_CTRL_STROBE_BEING_EXECUTED   BIT(15)
+#define RTS_PN_CAM_CTRL_WE                 s2BIT(7)
+#define RTS_PN_CAM_CTRL_STROBE_NEW_CMD     s2BIT(15)
+#define RTS_PN_CAM_CTRL_STROBE_BEING_EXECUTED   s2BIT(15)
 #define RTS_PN_CAM_CTRL_OFFSET(n)          vBIT(n,24,8)
        u64 rts_pn_cam_data;
-#define RTS_PN_CAM_DATA_TCP_SELECT         BIT(7)
+#define RTS_PN_CAM_DATA_TCP_SELECT         s2BIT(7)
 #define RTS_PN_CAM_DATA_PORT(val)          vBIT(val,8,16)
 #define RTS_PN_CAM_DATA_SCW(val)           vBIT(val,24,8)
 
        u64 rts_ds_mem_ctrl;
-#define RTS_DS_MEM_CTRL_WE                 BIT(7)
-#define RTS_DS_MEM_CTRL_STROBE_NEW_CMD     BIT(15)
-#define RTS_DS_MEM_CTRL_STROBE_CMD_BEING_EXECUTED   BIT(15)
+#define RTS_DS_MEM_CTRL_WE                 s2BIT(7)
+#define RTS_DS_MEM_CTRL_STROBE_NEW_CMD     s2BIT(15)
+#define RTS_DS_MEM_CTRL_STROBE_CMD_BEING_EXECUTED   s2BIT(15)
 #define RTS_DS_MEM_CTRL_OFFSET(n)          vBIT(n,26,6)
        u64 rts_ds_mem_data;
 #define RTS_DS_MEM_DATA(n)                 vBIT(n,0,8)
@@ -823,23 +823,23 @@ struct XENA_dev_config {
 
 /* memory controller registers */
        u64 mc_int_status;
-#define MC_INT_STATUS_MC_INT               BIT(0)
+#define MC_INT_STATUS_MC_INT               s2BIT(0)
        u64 mc_int_mask;
-#define MC_INT_MASK_MC_INT                 BIT(0)
+#define MC_INT_MASK_MC_INT                 s2BIT(0)
 
        u64 mc_err_reg;
-#define MC_ERR_REG_ECC_DB_ERR_L            BIT(14)
-#define MC_ERR_REG_ECC_DB_ERR_U            BIT(15)
-#define MC_ERR_REG_MIRI_ECC_DB_ERR_0       BIT(18)
-#define MC_ERR_REG_MIRI_ECC_DB_ERR_1       BIT(20)
-#define MC_ERR_REG_MIRI_CRI_ERR_0          BIT(22)
-#define MC_ERR_REG_MIRI_CRI_ERR_1          BIT(23)
-#define MC_ERR_REG_SM_ERR                  BIT(31)
-#define MC_ERR_REG_ECC_ALL_SNG            (BIT(2) | BIT(3) | BIT(4) | BIT(5) |\
-                                       BIT(17) | BIT(19))
-#define MC_ERR_REG_ECC_ALL_DBL            (BIT(10) | BIT(11) | BIT(12) |\
-                                       BIT(13) | BIT(18) | BIT(20))
-#define PLL_LOCK_N                     BIT(39)
+#define MC_ERR_REG_ECC_DB_ERR_L            s2BIT(14)
+#define MC_ERR_REG_ECC_DB_ERR_U            s2BIT(15)
+#define MC_ERR_REG_MIRI_ECC_DB_ERR_0       s2BIT(18)
+#define MC_ERR_REG_MIRI_ECC_DB_ERR_1       s2BIT(20)
+#define MC_ERR_REG_MIRI_CRI_ERR_0          s2BIT(22)
+#define MC_ERR_REG_MIRI_CRI_ERR_1          s2BIT(23)
+#define MC_ERR_REG_SM_ERR                  s2BIT(31)
+#define MC_ERR_REG_ECC_ALL_SNG            (s2BIT(2) | s2BIT(3) | s2BIT(4) | s2BIT(5) |\
+                                       s2BIT(17) | s2BIT(19))
+#define MC_ERR_REG_ECC_ALL_DBL            (s2BIT(10) | s2BIT(11) | s2BIT(12) |\
+                                       s2BIT(13) | s2BIT(18) | s2BIT(20))
+#define PLL_LOCK_N                     s2BIT(39)
        u64 mc_err_mask;
        u64 mc_err_alarm;
 
@@ -857,8 +857,8 @@ struct XENA_dev_config {
 #define RX_QUEUE_CFG_Q7_SZ(n)              vBIT(n,56,8)
 
        u64 mc_rldram_mrs;
-#define        MC_RLDRAM_QUEUE_SIZE_ENABLE                     BIT(39)
-#define        MC_RLDRAM_MRS_ENABLE                            BIT(47)
+#define        MC_RLDRAM_QUEUE_SIZE_ENABLE                     s2BIT(39)
+#define        MC_RLDRAM_MRS_ENABLE                            s2BIT(47)
 
        u64 mc_rldram_interleave;
 
@@ -871,11 +871,11 @@ struct XENA_dev_config {
        u64 mc_rldram_ref_per;
        u8 unused20[0x220 - 0x208];
        u64 mc_rldram_test_ctrl;
-#define MC_RLDRAM_TEST_MODE            BIT(47)
-#define MC_RLDRAM_TEST_WRITE   BIT(7)
-#define MC_RLDRAM_TEST_GO              BIT(15)
-#define MC_RLDRAM_TEST_DONE            BIT(23)
-#define MC_RLDRAM_TEST_PASS            BIT(31)
+#define MC_RLDRAM_TEST_MODE            s2BIT(47)
+#define MC_RLDRAM_TEST_WRITE   s2BIT(7)
+#define MC_RLDRAM_TEST_GO              s2BIT(15)
+#define MC_RLDRAM_TEST_DONE            s2BIT(23)
+#define MC_RLDRAM_TEST_PASS            s2BIT(31)
 
        u8 unused21[0x240 - 0x228];
        u64 mc_rldram_test_add;
@@ -888,7 +888,7 @@ struct XENA_dev_config {
 
        u8 unused24_1[0x360 - 0x308];
        u64 mc_rldram_ctrl;
-#define        MC_RLDRAM_ENABLE_ODT            BIT(7)
+#define        MC_RLDRAM_ENABLE_ODT            s2BIT(7)
 
        u8 unused24_2[0x640 - 0x368];
        u64 mc_rldram_ref_per_herc;
@@ -906,24 +906,24 @@ struct XENA_dev_config {
        /* XGXS control registers */
 
        u64 xgxs_int_status;
-#define XGXS_INT_STATUS_TXGXS              BIT(0)
-#define XGXS_INT_STATUS_RXGXS              BIT(1)
+#define XGXS_INT_STATUS_TXGXS              s2BIT(0)
+#define XGXS_INT_STATUS_RXGXS              s2BIT(1)
        u64 xgxs_int_mask;
-#define XGXS_INT_MASK_TXGXS                BIT(0)
-#define XGXS_INT_MASK_RXGXS                BIT(1)
+#define XGXS_INT_MASK_TXGXS                s2BIT(0)
+#define XGXS_INT_MASK_RXGXS                s2BIT(1)
 
        u64 xgxs_txgxs_err_reg;
-#define TXGXS_ECC_SG_ERR               BIT(7)
-#define TXGXS_ECC_DB_ERR               BIT(15)
-#define TXGXS_ESTORE_UFLOW             BIT(31)
-#define TXGXS_TX_SM_ERR                        BIT(39)
+#define TXGXS_ECC_SG_ERR               s2BIT(7)
+#define TXGXS_ECC_DB_ERR               s2BIT(15)
+#define TXGXS_ESTORE_UFLOW             s2BIT(31)
+#define TXGXS_TX_SM_ERR                        s2BIT(39)
 
        u64 xgxs_txgxs_err_mask;
        u64 xgxs_txgxs_err_alarm;
 
        u64 xgxs_rxgxs_err_reg;
-#define RXGXS_ESTORE_OFLOW             BIT(7)
-#define RXGXS_RX_SM_ERR                        BIT(39)
+#define RXGXS_ESTORE_OFLOW             s2BIT(7)
+#define RXGXS_RX_SM_ERR                        s2BIT(39)
        u64 xgxs_rxgxs_err_mask;
        u64 xgxs_rxgxs_err_alarm;
 
@@ -942,10 +942,10 @@ struct XENA_dev_config {
 #define SPI_CONTROL_BYTECNT(cnt)       vBIT(cnt,29,3)
 #define SPI_CONTROL_CMD(cmd)           vBIT(cmd,32,8)
 #define SPI_CONTROL_ADDR(addr)         vBIT(addr,40,24)
-#define SPI_CONTROL_SEL1               BIT(4)
-#define SPI_CONTROL_REQ                        BIT(7)
-#define SPI_CONTROL_NACK               BIT(5)
-#define SPI_CONTROL_DONE               BIT(6)
+#define SPI_CONTROL_SEL1               s2BIT(4)
+#define SPI_CONTROL_REQ                        s2BIT(7)
+#define SPI_CONTROL_NACK               s2BIT(5)
+#define SPI_CONTROL_DONE               s2BIT(6)
        u64 spi_data;
 #define SPI_DATA_WRITE(data,len)       vBIT(data,0,len)
 };
index 22e4054d4fcb249feac3331eab47b544f85920a8..b8c0e7b4ca1cdd0e0d4d3a9251af47cff784a326 100644 (file)
@@ -1716,7 +1716,7 @@ static int init_nic(struct s2io_nic *nic)
                        MISC_LINK_STABILITY_PRD(3);
                writeq(val64, &bar0->misc_control);
                val64 = readq(&bar0->pic_control2);
-               val64 &= ~(BIT(13)|BIT(14)|BIT(15));
+               val64 &= ~(s2BIT(13)|s2BIT(14)|s2BIT(15));
                writeq(val64, &bar0->pic_control2);
        }
        if (strstr(nic->product_name, "CX4")) {
@@ -2427,7 +2427,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
                }
                if ((rxdp->Control_1 & RXD_OWN_XENA) &&
                        ((nic->rxd_mode == RXD_MODE_3B) &&
-                               (rxdp->Control_2 & BIT(0)))) {
+                               (rxdp->Control_2 & s2BIT(0)))) {
                        mac_control->rings[ring_no].rx_curr_put_info.
                                        offset = off;
                        goto end;
@@ -2540,7 +2540,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
                                rxdp->Control_2 |= SET_BUFFER2_SIZE_3
                                                                (dev->mtu + 4);
                        }
-                       rxdp->Control_2 |= BIT(0);
+                       rxdp->Control_2 |= s2BIT(0);
                }
                rxdp->Host_Control = (unsigned long) (skb);
                if (alloc_tab & ((1 << rxsync_frequency) - 1))
@@ -3377,7 +3377,7 @@ static void s2io_reset(struct s2io_nic * sp)
                pci_write_config_dword(sp->pdev, 0x68, 0x7C);
 
                /* Clearing PCI_STATUS error reflected here */
-               writeq(BIT(62), &bar0->txpic_int_reg);
+               writeq(s2BIT(62), &bar0->txpic_int_reg);
        }
 
        /* Reset device statistics maintained by OS */
@@ -3575,7 +3575,7 @@ static int wait_for_msix_trans(struct s2io_nic *nic, int i)
 
        do {
                val64 = readq(&bar0->xmsi_access);
-               if (!(val64 & BIT(15)))
+               if (!(val64 & s2BIT(15)))
                        break;
                mdelay(1);
                cnt++;
@@ -3597,7 +3597,7 @@ static void restore_xmsi_data(struct s2io_nic *nic)
        for (i=0; i < MAX_REQUESTED_MSI_X; i++) {
                writeq(nic->msix_info[i].addr, &bar0->xmsi_address);
                writeq(nic->msix_info[i].data, &bar0->xmsi_data);
-               val64 = (BIT(7) | BIT(15) | vBIT(i, 26, 6));
+               val64 = (s2BIT(7) | s2BIT(15) | vBIT(i, 26, 6));
                writeq(val64, &bar0->xmsi_access);
                if (wait_for_msix_trans(nic, i)) {
                        DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__);
@@ -3614,7 +3614,7 @@ static void store_xmsi_data(struct s2io_nic *nic)
 
        /* Store and display */
        for (i=0; i < MAX_REQUESTED_MSI_X; i++) {
-               val64 = (BIT(15) | vBIT(i, 26, 6));
+               val64 = (s2BIT(15) | vBIT(i, 26, 6));
                writeq(val64, &bar0->xmsi_access);
                if (wait_for_msix_trans(nic, i)) {
                        DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__);
@@ -4634,7 +4634,7 @@ static void s2io_updt_stats(struct s2io_nic *sp)
                do {
                        udelay(100);
                        val64 = readq(&bar0->stat_cfg);
-                       if (!(val64 & BIT(0)))
+                       if (!(val64 & s2BIT(0)))
                                break;
                        cnt++;
                        if (cnt == 5)
index f6b45565304f07c2bf3b9f3b5b49d50bb50a9a12..cc1797a071aa0822617efa6b96f03a3795d1a25c 100644 (file)
@@ -14,7 +14,7 @@
 #define _S2IO_H
 
 #define TBD 0
-#define BIT(loc)               (0x8000000000000000ULL >> (loc))
+#define s2BIT(loc)             (0x8000000000000000ULL >> (loc))
 #define vBIT(val, loc, sz)     (((u64)val) << (64-loc-sz))
 #define INV(d)  ((d&0xff)<<24) | (((d>>8)&0xff)<<16) | (((d>>16)&0xff)<<8)| ((d>>24)&0xff)
 
@@ -473,42 +473,42 @@ struct TxFIFO_element {
 
        u64 List_Control;
 #define TX_FIFO_LAST_TXD_NUM( val)     vBIT(val,0,8)
-#define TX_FIFO_FIRST_LIST             BIT(14)
-#define TX_FIFO_LAST_LIST              BIT(15)
+#define TX_FIFO_FIRST_LIST             s2BIT(14)
+#define TX_FIFO_LAST_LIST              s2BIT(15)
 #define TX_FIFO_FIRSTNLAST_LIST        vBIT(3,14,2)
-#define TX_FIFO_SPECIAL_FUNC           BIT(23)
-#define TX_FIFO_DS_NO_SNOOP            BIT(31)
-#define TX_FIFO_BUFF_NO_SNOOP          BIT(30)
+#define TX_FIFO_SPECIAL_FUNC           s2BIT(23)
+#define TX_FIFO_DS_NO_SNOOP            s2BIT(31)
+#define TX_FIFO_BUFF_NO_SNOOP          s2BIT(30)
 };
 
 /* Tx descriptor structure */
 struct TxD {
        u64 Control_1;
 /* bit mask */
-#define TXD_LIST_OWN_XENA       BIT(7)
-#define TXD_T_CODE              (BIT(12)|BIT(13)|BIT(14)|BIT(15))
+#define TXD_LIST_OWN_XENA       s2BIT(7)
+#define TXD_T_CODE              (s2BIT(12)|s2BIT(13)|s2BIT(14)|s2BIT(15))
 #define TXD_T_CODE_OK(val)      (|(val & TXD_T_CODE))
 #define GET_TXD_T_CODE(val)     ((val & TXD_T_CODE)<<12)
-#define TXD_GATHER_CODE         (BIT(22) | BIT(23))
-#define TXD_GATHER_CODE_FIRST   BIT(22)
-#define TXD_GATHER_CODE_LAST    BIT(23)
-#define TXD_TCP_LSO_EN          BIT(30)
-#define TXD_UDP_COF_EN          BIT(31)
-#define TXD_UFO_EN             BIT(31) | BIT(30)
+#define TXD_GATHER_CODE         (s2BIT(22) | s2BIT(23))
+#define TXD_GATHER_CODE_FIRST   s2BIT(22)
+#define TXD_GATHER_CODE_LAST    s2BIT(23)
+#define TXD_TCP_LSO_EN          s2BIT(30)
+#define TXD_UDP_COF_EN          s2BIT(31)
+#define TXD_UFO_EN             s2BIT(31) | s2BIT(30)
 #define TXD_TCP_LSO_MSS(val)    vBIT(val,34,14)
 #define TXD_UFO_MSS(val)       vBIT(val,34,14)
 #define TXD_BUFFER0_SIZE(val)   vBIT(val,48,16)
 
        u64 Control_2;
-#define TXD_TX_CKO_CONTROL      (BIT(5)|BIT(6)|BIT(7))
-#define TXD_TX_CKO_IPV4_EN      BIT(5)
-#define TXD_TX_CKO_TCP_EN       BIT(6)
-#define TXD_TX_CKO_UDP_EN       BIT(7)
-#define TXD_VLAN_ENABLE         BIT(15)
+#define TXD_TX_CKO_CONTROL      (s2BIT(5)|s2BIT(6)|s2BIT(7))
+#define TXD_TX_CKO_IPV4_EN      s2BIT(5)
+#define TXD_TX_CKO_TCP_EN       s2BIT(6)
+#define TXD_TX_CKO_UDP_EN       s2BIT(7)
+#define TXD_VLAN_ENABLE         s2BIT(15)
 #define TXD_VLAN_TAG(val)       vBIT(val,16,16)
 #define TXD_INT_NUMBER(val)     vBIT(val,34,6)
-#define TXD_INT_TYPE_PER_LIST   BIT(47)
-#define TXD_INT_TYPE_UTILZ      BIT(46)
+#define TXD_INT_TYPE_PER_LIST   s2BIT(47)
+#define TXD_INT_TYPE_UTILZ      s2BIT(46)
 #define TXD_SET_MARKER         vBIT(0x6,0,4)
 
        u64 Buffer_Pointer;
@@ -525,14 +525,14 @@ struct list_info_hold {
 struct RxD_t {
        u64 Host_Control;       /* reserved for host */
        u64 Control_1;
-#define RXD_OWN_XENA            BIT(7)
-#define RXD_T_CODE              (BIT(12)|BIT(13)|BIT(14)|BIT(15))
+#define RXD_OWN_XENA            s2BIT(7)
+#define RXD_T_CODE              (s2BIT(12)|s2BIT(13)|s2BIT(14)|s2BIT(15))
 #define RXD_FRAME_PROTO         vBIT(0xFFFF,24,8)
-#define RXD_FRAME_PROTO_IPV4    BIT(27)
-#define RXD_FRAME_PROTO_IPV6    BIT(28)
-#define RXD_FRAME_IP_FRAG      BIT(29)
-#define RXD_FRAME_PROTO_TCP     BIT(30)
-#define RXD_FRAME_PROTO_UDP     BIT(31)
+#define RXD_FRAME_PROTO_IPV4    s2BIT(27)
+#define RXD_FRAME_PROTO_IPV6    s2BIT(28)
+#define RXD_FRAME_IP_FRAG      s2BIT(29)
+#define RXD_FRAME_PROTO_TCP     s2BIT(30)
+#define RXD_FRAME_PROTO_UDP     s2BIT(31)
 #define TCP_OR_UDP_FRAME        (RXD_FRAME_PROTO_TCP | RXD_FRAME_PROTO_UDP)
 #define RXD_GET_L3_CKSUM(val)   ((u16)(val>> 16) & 0xFFFF)
 #define RXD_GET_L4_CKSUM(val)   ((u16)(val) & 0xFFFF)
@@ -998,26 +998,26 @@ static inline void SPECIAL_REG_WRITE(u64 val, void __iomem *addr, int order)
 /*  Interrupt masks for the general interrupt mask register */
 #define DISABLE_ALL_INTRS   0xFFFFFFFFFFFFFFFFULL
 
-#define TXPIC_INT_M         BIT(0)
-#define TXDMA_INT_M         BIT(1)
-#define TXMAC_INT_M         BIT(2)
-#define TXXGXS_INT_M        BIT(3)
-#define TXTRAFFIC_INT_M     BIT(8)
-#define PIC_RX_INT_M        BIT(32)
-#define RXDMA_INT_M         BIT(33)
-#define RXMAC_INT_M         BIT(34)
-#define MC_INT_M            BIT(35)
-#define RXXGXS_INT_M        BIT(36)
-#define RXTRAFFIC_INT_M     BIT(40)
+#define TXPIC_INT_M         s2BIT(0)
+#define TXDMA_INT_M         s2BIT(1)
+#define TXMAC_INT_M         s2BIT(2)
+#define TXXGXS_INT_M        s2BIT(3)
+#define TXTRAFFIC_INT_M     s2BIT(8)
+#define PIC_RX_INT_M        s2BIT(32)
+#define RXDMA_INT_M         s2BIT(33)
+#define RXMAC_INT_M         s2BIT(34)
+#define MC_INT_M            s2BIT(35)
+#define RXXGXS_INT_M        s2BIT(36)
+#define RXTRAFFIC_INT_M     s2BIT(40)
 
 /*  PIC level Interrupts TODO*/
 
 /*  DMA level Inressupts */
-#define TXDMA_PFC_INT_M     BIT(0)
-#define TXDMA_PCC_INT_M     BIT(2)
+#define TXDMA_PFC_INT_M     s2BIT(0)
+#define TXDMA_PCC_INT_M     s2BIT(2)
 
 /*  PFC block interrupts */
-#define PFC_MISC_ERR_1      BIT(0)     /* Interrupt to indicate FIFO full */
+#define PFC_MISC_ERR_1      s2BIT(0)   /* Interrupt to indicate FIFO full */
 
 /* PCC block interrupts. */
 #define        PCC_FB_ECC_ERR     vBIT(0xff, 16, 8)    /* Interrupt to indicate
index 7967240534d5b647d97313920c9d5ff7b2455bc0..24cfb6275d9b37a39cd021a45a00f1c7951fc886 100644 (file)
@@ -1384,13 +1384,9 @@ static int sky2_up(struct net_device *dev)
        sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map,
                           TX_RING_SIZE - 1);
 
-       napi_enable(&hw->napi);
-
        err = sky2_rx_start(sky2);
-       if (err) {
-               napi_disable(&hw->napi);
+       if (err)
                goto err_out;
-       }
 
        /* Enable interrupts from phy/mac for port */
        imask = sky2_read32(hw, B0_IMSK);
@@ -1679,13 +1675,13 @@ static int sky2_down(struct net_device *dev)
        /* Stop more packets from being queued */
        netif_stop_queue(dev);
 
-       napi_disable(&hw->napi);
-
        /* Disable port IRQ */
        imask = sky2_read32(hw, B0_IMSK);
        imask &= ~portirq_msk[port];
        sky2_write32(hw, B0_IMSK, imask);
 
+       synchronize_irq(hw->pdev->irq);
+
        sky2_gmac_reset(hw, port);
 
        /* Stop transmitter */
@@ -1699,6 +1695,9 @@ static int sky2_down(struct net_device *dev)
        ctrl &= ~(GM_GPCR_TX_ENA | GM_GPCR_RX_ENA);
        gma_write16(hw, port, GM_GP_CTRL, ctrl);
 
+       /* Make sure no packets are pending */
+       napi_synchronize(&hw->napi);
+
        sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
 
        /* Workaround shared GMAC reset */
@@ -1736,8 +1735,6 @@ static int sky2_down(struct net_device *dev)
        /* turn off LED's */
        sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
 
-       synchronize_irq(hw->pdev->irq);
-
        sky2_tx_clean(dev);
        sky2_rx_clean(sky2);
 
@@ -2048,9 +2045,6 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
        err = sky2_rx_start(sky2);
        sky2_write32(hw, B0_IMSK, imask);
 
-       /* Unconditionally re-enable NAPI because even if we
-        * call dev_close() that will do a napi_disable().
-        */
        napi_enable(&hw->napi);
 
        if (err)
@@ -2915,6 +2909,7 @@ static void sky2_restart(struct work_struct *work)
        rtnl_lock();
        sky2_write32(hw, B0_IMSK, 0);
        sky2_read32(hw, B0_IMSK);
+       napi_disable(&hw->napi);
 
        for (i = 0; i < hw->ports; i++) {
                dev = hw->dev[i];
@@ -2924,6 +2919,7 @@ static void sky2_restart(struct work_struct *work)
 
        sky2_reset(hw);
        sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
+       napi_enable(&hw->napi);
 
        for (i = 0; i < hw->ports; i++) {
                dev = hw->dev[i];
@@ -3961,7 +3957,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
        struct net_device *dev = alloc_etherdev(sizeof(*sky2));
 
        if (!dev) {
-               dev_err(&hw->pdev->dev, "etherdev alloc failed");
+               dev_err(&hw->pdev->dev, "etherdev alloc failed\n");
                return NULL;
        }
 
@@ -4191,7 +4187,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
                err = -ENOMEM;
                goto err_out_free_pci;
        }
-       netif_napi_add(dev, &hw->napi, sky2_poll, NAPI_WEIGHT);
 
        if (!disable_msi && pci_enable_msi(pdev) == 0) {
                err = sky2_test_msi(hw);
@@ -4207,6 +4202,8 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
                goto err_out_free_netdev;
        }
 
+       netif_napi_add(dev, &hw->napi, sky2_poll, NAPI_WEIGHT);
+
        err = request_irq(pdev->irq, sky2_intr,
                          (hw->flags & SKY2_HW_USE_MSI) ? 0 : IRQF_SHARED,
                          dev->name, hw);
@@ -4215,6 +4212,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
                goto err_out_unregister;
        }
        sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
+       napi_enable(&hw->napi);
 
        sky2_show_addr(dev);
 
@@ -4265,23 +4263,18 @@ err_out:
 static void __devexit sky2_remove(struct pci_dev *pdev)
 {
        struct sky2_hw *hw = pci_get_drvdata(pdev);
-       struct net_device *dev0, *dev1;
+       int i;
 
        if (!hw)
                return;
 
        del_timer_sync(&hw->watchdog_timer);
+       cancel_work_sync(&hw->restart_work);
 
-       flush_scheduled_work();
+       for (i = hw->ports; i >= 0; --i)
+               unregister_netdev(hw->dev[i]);
 
        sky2_write32(hw, B0_IMSK, 0);
-       synchronize_irq(hw->pdev->irq);
-
-       dev0 = hw->dev[0];
-       dev1 = hw->dev[1];
-       if (dev1)
-               unregister_netdev(dev1);
-       unregister_netdev(dev0);
 
        sky2_power_aux(hw);
 
@@ -4296,9 +4289,9 @@ static void __devexit sky2_remove(struct pci_dev *pdev)
        pci_release_regions(pdev);
        pci_disable_device(pdev);
 
-       if (dev1)
-               free_netdev(dev1);
-       free_netdev(dev0);
+       for (i = hw->ports; i >= 0; --i)
+               free_netdev(hw->dev[i]);
+
        iounmap(hw->regs);
        kfree(hw);
 
@@ -4328,6 +4321,7 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state)
        }
 
        sky2_write32(hw, B0_IMSK, 0);
+       napi_disable(&hw->napi);
        sky2_power_aux(hw);
 
        pci_save_state(pdev);
@@ -4362,8 +4356,8 @@ static int sky2_resume(struct pci_dev *pdev)
                pci_write_config_dword(pdev, PCI_DEV_REG3, 0);
 
        sky2_reset(hw);
-
        sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
+       napi_enable(&hw->napi);
 
        for (i = 0; i < hw->ports; i++) {
                struct net_device *dev = hw->dev[i];
index 7c60df46fc65c99208d3e539abaeecc7d409fecf..dd18af0ce67616653d815be1c9bc8102ce6c80b8 100644 (file)
@@ -1223,7 +1223,7 @@ static irqreturn_t smc911x_interrupt(int irq, void *dev_id)
                }
 #endif
 
-               /* Handle PHY interupt condition */
+               /* Handle PHY interrupt condition */
                if (status & INT_STS_PHY_INT_) {
                        DBG(SMC_DEBUG_MISC, "%s: PHY irq\n", dev->name);
                        smc911x_phy_interrupt(dev);
index fab055ffcc9037070442469a34cc4d0fa1675237..bccae7e5c6ad5ad6df1b79fc16a9b314275b97c1 100644 (file)
@@ -46,7 +46,7 @@
 #include <linux/vmalloc.h>
 #include <linux/wait.h>
 #include <linux/workqueue.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 #include <asm/pci-bridge.h>
 #include <net/checksum.h>
 
@@ -1639,7 +1639,7 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg)
 
 /**
  * spider_net_interrupt - interrupt handler for spider_net
- * @irq: interupt number
+ * @irq: interrupt number
  * @ptr: pointer to net_device
  * @regs: PU registers
  *
index 8038f2882c9b177ac433476065c8ab6ac501d1e7..d887c05588d5c4504d31699fef3d452645cb1daa 100644 (file)
@@ -1654,7 +1654,7 @@ tc35815_rx(struct net_device *dev)
                                        panic_queues(dev);
                                }
 #endif
-                               /* pass BD to controler */
+                               /* pass BD to controller */
 #ifndef TC35815_USE_PACKEDBUFFER
                                if (!lp->rx_skbs[curid].skb) {
                                        lp->rx_skbs[curid].skb =
@@ -1694,7 +1694,7 @@ tc35815_rx(struct net_device *dev)
                }
 #endif
                for (i = 0; i < (bd_count + 1) / 2 + 1; i++) {
-                       /* pass FD to controler */
+                       /* pass FD to controller */
 #ifdef DEBUG
                        lp->rfd_cur->fd.FDNext = cpu_to_le32(0xdeaddead);
 #else
index 014dc2cfe4d666d191f7a79719b305ded6eb8bf0..09440d783e65542912bac932fa727a288df1891c 100644 (file)
@@ -64,8 +64,8 @@
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "3.84"
-#define DRV_MODULE_RELDATE     "October 12, 2007"
+#define DRV_MODULE_VERSION     "3.85"
+#define DRV_MODULE_RELDATE     "October 18, 2007"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
@@ -200,6 +200,7 @@ static struct pci_device_id tg3_pci_tbl[] = {
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5906M)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5784)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5764)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5723)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5761)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5761E)},
        {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)},
@@ -5028,10 +5029,7 @@ static int tg3_poll_fw(struct tg3 *tp)
 /* Save PCI command register before chip reset */
 static void tg3_save_pci_state(struct tg3 *tp)
 {
-       u32 val;
-
-       pci_read_config_dword(tp->pdev, TG3PCI_COMMAND, &val);
-       tp->pci_cmd = val;
+       pci_read_config_word(tp->pdev, PCI_COMMAND, &tp->pci_cmd);
 }
 
 /* Restore PCI state after chip reset */
@@ -5054,7 +5052,7 @@ static void tg3_restore_pci_state(struct tg3 *tp)
                       PCISTATE_ALLOW_APE_SHMEM_WR;
        pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, val);
 
-       pci_write_config_dword(tp->pdev, TG3PCI_COMMAND, tp->pci_cmd);
+       pci_write_config_word(tp->pdev, PCI_COMMAND, tp->pci_cmd);
 
        if (!(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)) {
                pci_write_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE,
@@ -10820,9 +10818,24 @@ out_not_found:
                strcpy(tp->board_part_number, "none");
 }
 
+static int __devinit tg3_fw_img_is_valid(struct tg3 *tp, u32 offset)
+{
+       u32 val;
+
+       if (tg3_nvram_read_swab(tp, offset, &val) ||
+           (val & 0xfc000000) != 0x0c000000 ||
+           tg3_nvram_read_swab(tp, offset + 4, &val) ||
+           val != 0)
+               return 0;
+
+       return 1;
+}
+
 static void __devinit tg3_read_fw_ver(struct tg3 *tp)
 {
        u32 val, offset, start;
+       u32 ver_offset;
+       int i, bcnt;
 
        if (tg3_nvram_read_swab(tp, 0, &val))
                return;
@@ -10835,29 +10848,71 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp)
                return;
 
        offset = tg3_nvram_logical_addr(tp, offset);
-       if (tg3_nvram_read_swab(tp, offset, &val))
+
+       if (!tg3_fw_img_is_valid(tp, offset) ||
+           tg3_nvram_read_swab(tp, offset + 8, &ver_offset))
                return;
 
-       if ((val & 0xfc000000) == 0x0c000000) {
-               u32 ver_offset, addr;
-               int i;
+       offset = offset + ver_offset - start;
+       for (i = 0; i < 16; i += 4) {
+               if (tg3_nvram_read(tp, offset + i, &val))
+                       return;
 
-               if (tg3_nvram_read_swab(tp, offset + 4, &val) ||
-                   tg3_nvram_read_swab(tp, offset + 8, &ver_offset))
+               val = le32_to_cpu(val);
+               memcpy(tp->fw_ver + i, &val, 4);
+       }
+
+       if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
+            (tp->tg3_flags & TG3_FLG3_ENABLE_APE))
+               return;
+
+       for (offset = TG3_NVM_DIR_START;
+            offset < TG3_NVM_DIR_END;
+            offset += TG3_NVM_DIRENT_SIZE) {
+               if (tg3_nvram_read_swab(tp, offset, &val))
                        return;
 
-               if (val != 0)
+               if ((val >> TG3_NVM_DIRTYPE_SHIFT) == TG3_NVM_DIRTYPE_ASFINI)
+                       break;
+       }
+
+       if (offset == TG3_NVM_DIR_END)
+               return;
+
+       if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+               start = 0x08000000;
+       else if (tg3_nvram_read_swab(tp, offset - 4, &start))
+               return;
+
+       if (tg3_nvram_read_swab(tp, offset + 4, &offset) ||
+           !tg3_fw_img_is_valid(tp, offset) ||
+           tg3_nvram_read_swab(tp, offset + 8, &val))
+               return;
+
+       offset += val - start;
+
+       bcnt = strlen(tp->fw_ver);
+
+       tp->fw_ver[bcnt++] = ',';
+       tp->fw_ver[bcnt++] = ' ';
+
+       for (i = 0; i < 4; i++) {
+               if (tg3_nvram_read(tp, offset, &val))
                        return;
 
-               addr = offset + ver_offset - start;
-               for (i = 0; i < 16; i += 4) {
-                       if (tg3_nvram_read(tp, addr + i, &val))
-                               return;
+               val = le32_to_cpu(val);
+               offset += sizeof(val);
 
-                       val = cpu_to_le32(val);
-                       memcpy(tp->fw_ver + i, &val, 4);
+               if (bcnt > TG3_VER_SIZE - sizeof(val)) {
+                       memcpy(&tp->fw_ver[bcnt], &val, TG3_VER_SIZE - bcnt);
+                       break;
                }
+
+               memcpy(&tp->fw_ver[bcnt], &val, sizeof(val));
+               bcnt += sizeof(val);
        }
+
+       tp->fw_ver[TG3_VER_SIZE - 1] = 0;
 }
 
 static struct pci_dev * __devinit tg3_find_peer(struct tg3 *);
index 6dbdad2b8f88693ffe9f31a9885f9e49059f19bc..1d5b2a3dd29dff6c335f8d8174cdfe3955fd9319 100644 (file)
 #define TG3_EEPROM_MAGIC_HW            0xabcd
 #define TG3_EEPROM_MAGIC_HW_MSK                0xffff
 
+#define TG3_NVM_DIR_START              0x18
+#define TG3_NVM_DIR_END                        0x78
+#define TG3_NVM_DIRENT_SIZE            0xc
+#define TG3_NVM_DIRTYPE_SHIFT          24
+#define TG3_NVM_DIRTYPE_ASFINI         1
+
 /* 32K Window into NIC internal memory */
 #define NIC_SRAM_WIN_BASE              0x00008000
 
@@ -2415,10 +2421,11 @@ struct tg3 {
 #define PHY_REV_BCM5411_X0             0x1 /* Found on Netgear GA302T */
 
        u32                             led_ctrl;
-       u32                             pci_cmd;
+       u16                             pci_cmd;
 
        char                            board_part_number[24];
-       char                            fw_ver[16];
+#define TG3_VER_SIZE 32
+       char                            fw_ver[TG3_VER_SIZE];
        u32                             nic_sram_data_cfg;
        u32                             pci_clock_ctrl;
        struct pci_dev                  *pdev_peer;
index df10af7df7b86a1d1aa708954256d3048d58da6b..35d15e850075f18b4aebc28cf51fcd3095eabf7d 100644 (file)
@@ -1629,7 +1629,7 @@ tsi108_init_one(struct platform_device *pdev)
                goto register_fail;
        }
 
-       printk(KERN_INFO "%s: Tsi108 Gigabit Ethernet, MAC: %s\n"
+       printk(KERN_INFO "%s: Tsi108 Gigabit Ethernet, MAC: %s\n",
               dev->name, print_mac(mac, dev->dev_addr));
 #ifdef DEBUG
        data->msg_enable = DEBUG;
index 1c537d5a30627bbeef1b8aebbd84692a3e08facf..49d7a290dbbcfa93bdb94eba8e147ce5d7b5d406 100644 (file)
@@ -67,7 +67,7 @@ config TULIP_MMIO
          If in doubt, say N.
 
 config TULIP_NAPI
-       bool "Use NAPI RX polling "
+       bool "Use RX polling (NAPI)"
        depends on TULIP
        help
          NAPI is a new driver API designed to reduce CPU and interrupt load
@@ -78,18 +78,16 @@ config TULIP_NAPI
          deployed on potentially unfriendly networks (e.g. in a firewall),
          then say Y here.
 
-         See <file:Documentation/networking/NAPI_HOWTO.txt> for more
-         information.
-
          If in doubt, say N.
 
 config TULIP_NAPI_HW_MITIGATION
-       bool "Use Interrupt Mitigation "
+       bool "Use Interrupt Mitigation"
        depends on TULIP_NAPI
        ---help---
-         Use HW to reduce RX interrupts. Not strict necessary since NAPI reduces
-         RX interrupts but itself. Although this reduces RX interrupts even at
-         low levels traffic at the cost of a small latency.
+         Use HW to reduce RX interrupts. Not strictly necessary since NAPI
+         reduces RX interrupts by itself. Interrupt mitigation reduces RX
+         interrupts even at low levels of traffic at the cost of a small
+         latency.
 
          If in doubt, say Y.
 
index 76e55612430bae38ffc8c352d798bb112fcf61b7..a7afeea156bd5f80229b6b8a55b3952f3c764299 100644 (file)
@@ -34,9 +34,9 @@
 #include <linux/delay.h>
 #include <linux/spinlock.h>
 #include <linux/dma-mapping.h>
+#include <linux/bitops.h>
 
 #include <asm/processor.h>
-#include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <asm/uaccess.h>
index 3c8e3b63be07a74d6d4f807317b9a427f7b27aa0..35d0cfcf8c47aa52ece528e7018cab70cb97bb99 100644 (file)
@@ -483,7 +483,7 @@ err_out_netdev:
    a delay.  Note that pre-2.0.34 kernels had a cache-alignment bug that
    made udelay() unreliable.
    The old method of using an ISA access as a delay, __SLOW_DOWN_IO__, is
-   depricated.
+   deprecated.
 */
 #define eeprom_delay(ee_addr)  ioread32(ee_addr)
 
index 8dc09a3790cb4fe8b15d6595ae8cf0877bf850d7..5a96d74e4ce8b89a2d3e2c5b6276c5e2ce725030 100644 (file)
@@ -71,7 +71,7 @@ config USB_PEGASUS
        select MII
        ---help---
          Say Y here if you know you have Pegasus or Pegasus-II based adapter.
-         If in doubt then look at <file:drivers/usb/net/pegasus.h> for the
+         If in doubt then look at <file:drivers/net/usb/pegasus.h> for the
          complete list of supported devices.
 
          If your particular adapter is not in the list and you are _sure_ it
index 6240b978fe3d94ccbe08ebf489ba75b47c042566..f55a5951733ab56b44aaaae2af0939c71c10c15c 100644 (file)
@@ -114,8 +114,8 @@ static void mcs7830_async_cmd_callback(struct urb *urb)
        struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
 
        if (urb->status < 0)
-               printk(KERN_DEBUG "mcs7830_async_cmd_callback() failed with %d",
-                       urb->status);
+               printk(KERN_DEBUG "%s() failed with %d\n",
+                      __FUNCTION__, urb->status);
 
        kfree(req);
        usb_free_urb(urb);
@@ -129,15 +129,15 @@ static void mcs7830_set_reg_async(struct usbnet *dev, u16 index, u16 size, void
 
        urb = usb_alloc_urb(0, GFP_ATOMIC);
        if (!urb) {
-               dev_dbg(&dev->udev->dev, "Error allocating URB "
-                               "in write_cmd_async!");
+               dev_dbg(&dev->udev->dev,
+                       "Error allocating URB in write_cmd_async!\n");
                return;
        }
 
        req = kmalloc(sizeof *req, GFP_ATOMIC);
        if (!req) {
-               dev_err(&dev->udev->dev, "Failed to allocate memory for "
-                               "control request");
+               dev_err(&dev->udev->dev,
+                       "Failed to allocate memory for control request\n");
                goto out;
        }
        req->bRequestType = MCS7830_WR_BMREQ;
@@ -153,8 +153,8 @@ static void mcs7830_set_reg_async(struct usbnet *dev, u16 index, u16 size, void
 
        ret = usb_submit_urb(urb, GFP_ATOMIC);
        if (ret < 0) {
-               dev_err(&dev->udev->dev, "Error submitting the control "
-                               "message: ret=%d", ret);
+               dev_err(&dev->udev->dev,
+                       "Error submitting the control message: ret=%d\n", ret);
                goto out;
        }
        return;
index 4ae05799ac447b571412990d6fd9c7f2bdfc2ac2..5c4a92de9a076b703fd63708a3793311d8a5cbd1 100644 (file)
@@ -1648,7 +1648,7 @@ static int velocity_alloc_rx_buf(struct velocity_info *vptr, int idx)
  *
  *     Scan the queues looking for transmitted packets that
  *     we can complete and clean up. Update any statistics as
- *     neccessary/
+ *     necessary/
  */
 
 static int velocity_tx_srv(struct velocity_info *vptr, u32 status)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
new file mode 100644 (file)
index 0000000..e396c9d
--- /dev/null
@@ -0,0 +1,435 @@
+/* A simple network driver using virtio.
+ *
+ * Copyright 2007 Rusty Russell <rusty@rustcorp.com.au> 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
+ */
+//#define DEBUG
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/module.h>
+#include <linux/virtio.h>
+#include <linux/virtio_net.h>
+#include <linux/scatterlist.h>
+
+/* FIXME: MTU in config. */
+#define MAX_PACKET_LEN (ETH_HLEN+ETH_DATA_LEN)
+
+struct virtnet_info
+{
+       struct virtio_device *vdev;
+       struct virtqueue *rvq, *svq;
+       struct net_device *dev;
+       struct napi_struct napi;
+
+       /* Number of input buffers, and max we've ever had. */
+       unsigned int num, max;
+
+       /* Receive & send queues. */
+       struct sk_buff_head recv;
+       struct sk_buff_head send;
+};
+
+static inline struct virtio_net_hdr *skb_vnet_hdr(struct sk_buff *skb)
+{
+       return (struct virtio_net_hdr *)skb->cb;
+}
+
+static inline void vnet_hdr_to_sg(struct scatterlist *sg, struct sk_buff *skb)
+{
+       sg_init_one(sg, skb_vnet_hdr(skb), sizeof(struct virtio_net_hdr));
+}
+
+static bool skb_xmit_done(struct virtqueue *rvq)
+{
+       struct virtnet_info *vi = rvq->vdev->priv;
+
+       /* In case we were waiting for output buffers. */
+       netif_wake_queue(vi->dev);
+       return true;
+}
+
+static void receive_skb(struct net_device *dev, struct sk_buff *skb,
+                       unsigned len)
+{
+       struct virtio_net_hdr *hdr = skb_vnet_hdr(skb);
+
+       if (unlikely(len < sizeof(struct virtio_net_hdr) + ETH_HLEN)) {
+               pr_debug("%s: short packet %i\n", dev->name, len);
+               dev->stats.rx_length_errors++;
+               goto drop;
+       }
+       len -= sizeof(struct virtio_net_hdr);
+       BUG_ON(len > MAX_PACKET_LEN);
+
+       skb_trim(skb, len);
+       skb->protocol = eth_type_trans(skb, dev);
+       pr_debug("Receiving skb proto 0x%04x len %i type %i\n",
+                ntohs(skb->protocol), skb->len, skb->pkt_type);
+       dev->stats.rx_bytes += skb->len;
+       dev->stats.rx_packets++;
+
+       if (hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
+               pr_debug("Needs csum!\n");
+               skb->ip_summed = CHECKSUM_PARTIAL;
+               skb->csum_start = hdr->csum_start;
+               skb->csum_offset = hdr->csum_offset;
+               if (skb->csum_start > skb->len - 2
+                   || skb->csum_offset > skb->len - 2) {
+                       if (net_ratelimit())
+                               printk(KERN_WARNING "%s: csum=%u/%u len=%u\n",
+                                      dev->name, skb->csum_start,
+                                      skb->csum_offset, skb->len);
+                       goto frame_err;
+               }
+       }
+
+       if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
+               pr_debug("GSO!\n");
+               switch (hdr->gso_type) {
+               case VIRTIO_NET_HDR_GSO_TCPV4:
+                       skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
+                       break;
+               case VIRTIO_NET_HDR_GSO_TCPV4_ECN:
+                       skb_shinfo(skb)->gso_type = SKB_GSO_TCP_ECN;
+                       break;
+               case VIRTIO_NET_HDR_GSO_UDP:
+                       skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
+                       break;
+               case VIRTIO_NET_HDR_GSO_TCPV6:
+                       skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
+                       break;
+               default:
+                       if (net_ratelimit())
+                               printk(KERN_WARNING "%s: bad gso type %u.\n",
+                                      dev->name, hdr->gso_type);
+                       goto frame_err;
+               }
+
+               skb_shinfo(skb)->gso_size = hdr->gso_size;
+               if (skb_shinfo(skb)->gso_size == 0) {
+                       if (net_ratelimit())
+                               printk(KERN_WARNING "%s: zero gso size.\n",
+                                      dev->name);
+                       goto frame_err;
+               }
+
+               /* Header must be checked, and gso_segs computed. */
+               skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
+               skb_shinfo(skb)->gso_segs = 0;
+       }
+
+       netif_receive_skb(skb);
+       return;
+
+frame_err:
+       dev->stats.rx_frame_errors++;
+drop:
+       dev_kfree_skb(skb);
+}
+
+static void try_fill_recv(struct virtnet_info *vi)
+{
+       struct sk_buff *skb;
+       struct scatterlist sg[1+MAX_SKB_FRAGS];
+       int num, err;
+
+       for (;;) {
+               skb = netdev_alloc_skb(vi->dev, MAX_PACKET_LEN);
+               if (unlikely(!skb))
+                       break;
+
+               skb_put(skb, MAX_PACKET_LEN);
+               vnet_hdr_to_sg(sg, skb);
+               num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1;
+               skb_queue_head(&vi->recv, skb);
+
+               err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, num, skb);
+               if (err) {
+                       skb_unlink(skb, &vi->recv);
+                       kfree_skb(skb);
+                       break;
+               }
+               vi->num++;
+       }
+       if (unlikely(vi->num > vi->max))
+               vi->max = vi->num;
+       vi->rvq->vq_ops->kick(vi->rvq);
+}
+
+static bool skb_recv_done(struct virtqueue *rvq)
+{
+       struct virtnet_info *vi = rvq->vdev->priv;
+       netif_rx_schedule(vi->dev, &vi->napi);
+       /* Suppress further interrupts. */
+       return false;
+}
+
+static int virtnet_poll(struct napi_struct *napi, int budget)
+{
+       struct virtnet_info *vi = container_of(napi, struct virtnet_info, napi);
+       struct sk_buff *skb = NULL;
+       unsigned int len, received = 0;
+
+again:
+       while (received < budget &&
+              (skb = vi->rvq->vq_ops->get_buf(vi->rvq, &len)) != NULL) {
+               __skb_unlink(skb, &vi->recv);
+               receive_skb(vi->dev, skb, len);
+               vi->num--;
+               received++;
+       }
+
+       /* FIXME: If we oom and completely run out of inbufs, we need
+        * to start a timer trying to fill more. */
+       if (vi->num < vi->max / 2)
+               try_fill_recv(vi);
+
+       /* All done? */
+       if (!skb) {
+               netif_rx_complete(vi->dev, napi);
+               if (unlikely(!vi->rvq->vq_ops->restart(vi->rvq))
+                   && netif_rx_reschedule(vi->dev, napi))
+                       goto again;
+       }
+
+       return received;
+}
+
+static void free_old_xmit_skbs(struct virtnet_info *vi)
+{
+       struct sk_buff *skb;
+       unsigned int len;
+
+       while ((skb = vi->svq->vq_ops->get_buf(vi->svq, &len)) != NULL) {
+               pr_debug("Sent skb %p\n", skb);
+               __skb_unlink(skb, &vi->send);
+               vi->dev->stats.tx_bytes += len;
+               vi->dev->stats.tx_packets++;
+               kfree_skb(skb);
+       }
+}
+
+static int start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       struct virtnet_info *vi = netdev_priv(dev);
+       int num, err;
+       struct scatterlist sg[1+MAX_SKB_FRAGS];
+       struct virtio_net_hdr *hdr;
+       const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest;
+       DECLARE_MAC_BUF(mac);
+
+       pr_debug("%s: xmit %p %s\n", dev->name, skb, print_mac(mac, dest));
+
+       free_old_xmit_skbs(vi);
+
+       /* Encode metadata header at front. */
+       hdr = skb_vnet_hdr(skb);
+       if (skb->ip_summed == CHECKSUM_PARTIAL) {
+               hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
+               hdr->csum_start = skb->csum_start - skb_headroom(skb);
+               hdr->csum_offset = skb->csum_offset;
+       } else {
+               hdr->flags = 0;
+               hdr->csum_offset = hdr->csum_start = 0;
+       }
+
+       if (skb_is_gso(skb)) {
+               hdr->gso_size = skb_shinfo(skb)->gso_size;
+               if (skb_shinfo(skb)->gso_type & SKB_GSO_TCP_ECN)
+                       hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4_ECN;
+               else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4)
+                       hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
+               else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
+                       hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+               else if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP)
+                       hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP;
+               else
+                       BUG();
+       } else {
+               hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE;
+               hdr->gso_size = 0;
+       }
+
+       vnet_hdr_to_sg(sg, skb);
+       num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1;
+       __skb_queue_head(&vi->send, skb);
+       err = vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb);
+       if (err) {
+               pr_debug("%s: virtio not prepared to send\n", dev->name);
+               skb_unlink(skb, &vi->send);
+               netif_stop_queue(dev);
+               return NETDEV_TX_BUSY;
+       }
+       vi->svq->vq_ops->kick(vi->svq);
+
+       return 0;
+}
+
+static int virtnet_open(struct net_device *dev)
+{
+       struct virtnet_info *vi = netdev_priv(dev);
+
+       try_fill_recv(vi);
+
+       /* If we didn't even get one input buffer, we're useless. */
+       if (vi->num == 0)
+               return -ENOMEM;
+
+       napi_enable(&vi->napi);
+       return 0;
+}
+
+static int virtnet_close(struct net_device *dev)
+{
+       struct virtnet_info *vi = netdev_priv(dev);
+       struct sk_buff *skb;
+
+       napi_disable(&vi->napi);
+
+       /* networking core has neutered skb_xmit_done/skb_recv_done, so don't
+        * worry about races vs. get(). */
+       vi->rvq->vq_ops->shutdown(vi->rvq);
+       while ((skb = __skb_dequeue(&vi->recv)) != NULL) {
+               kfree_skb(skb);
+               vi->num--;
+       }
+       vi->svq->vq_ops->shutdown(vi->svq);
+       while ((skb = __skb_dequeue(&vi->send)) != NULL)
+               kfree_skb(skb);
+
+       BUG_ON(vi->num != 0);
+       return 0;
+}
+
+static int virtnet_probe(struct virtio_device *vdev)
+{
+       int err;
+       unsigned int len;
+       struct net_device *dev;
+       struct virtnet_info *vi;
+       void *token;
+
+       /* Allocate ourselves a network device with room for our info */
+       dev = alloc_etherdev(sizeof(struct virtnet_info));
+       if (!dev)
+               return -ENOMEM;
+
+       /* Set up network device as normal. */
+       ether_setup(dev);
+       dev->open = virtnet_open;
+       dev->stop = virtnet_close;
+       dev->hard_start_xmit = start_xmit;
+       dev->features = NETIF_F_HIGHDMA;
+       SET_NETDEV_DEV(dev, &vdev->dev);
+
+       /* Do we support "hardware" checksums? */
+       token = vdev->config->find(vdev, VIRTIO_CONFIG_NET_F, &len);
+       if (virtio_use_bit(vdev, token, len, VIRTIO_NET_F_NO_CSUM)) {
+               /* This opens up the world of extra features. */
+               dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
+               if (virtio_use_bit(vdev, token, len, VIRTIO_NET_F_TSO4))
+                       dev->features |= NETIF_F_TSO;
+               if (virtio_use_bit(vdev, token, len, VIRTIO_NET_F_UFO))
+                       dev->features |= NETIF_F_UFO;
+               if (virtio_use_bit(vdev, token, len, VIRTIO_NET_F_TSO4_ECN))
+                       dev->features |= NETIF_F_TSO_ECN;
+               if (virtio_use_bit(vdev, token, len, VIRTIO_NET_F_TSO6))
+                       dev->features |= NETIF_F_TSO6;
+       }
+
+       /* Configuration may specify what MAC to use.  Otherwise random. */
+       token = vdev->config->find(vdev, VIRTIO_CONFIG_NET_MAC_F, &len);
+       if (token) {
+               dev->addr_len = len;
+               vdev->config->get(vdev, token, dev->dev_addr, len);
+       } else
+               random_ether_addr(dev->dev_addr);
+
+       /* Set up our device-specific information */
+       vi = netdev_priv(dev);
+       netif_napi_add(dev, &vi->napi, virtnet_poll, 16);
+       vi->dev = dev;
+       vi->vdev = vdev;
+
+       /* We expect two virtqueues, receive then send. */
+       vi->rvq = vdev->config->find_vq(vdev, skb_recv_done);
+       if (IS_ERR(vi->rvq)) {
+               err = PTR_ERR(vi->rvq);
+               goto free;
+       }
+
+       vi->svq = vdev->config->find_vq(vdev, skb_xmit_done);
+       if (IS_ERR(vi->svq)) {
+               err = PTR_ERR(vi->svq);
+               goto free_recv;
+       }
+
+       /* Initialize our empty receive and send queues. */
+       skb_queue_head_init(&vi->recv);
+       skb_queue_head_init(&vi->send);
+
+       err = register_netdev(dev);
+       if (err) {
+               pr_debug("virtio_net: registering device failed\n");
+               goto free_send;
+       }
+       pr_debug("virtnet: registered device %s\n", dev->name);
+       vdev->priv = vi;
+       return 0;
+
+free_send:
+       vdev->config->del_vq(vi->svq);
+free_recv:
+       vdev->config->del_vq(vi->rvq);
+free:
+       free_netdev(dev);
+       return err;
+}
+
+static void virtnet_remove(struct virtio_device *vdev)
+{
+       unregister_netdev(vdev->priv);
+       free_netdev(vdev->priv);
+}
+
+static struct virtio_device_id id_table[] = {
+       { VIRTIO_ID_NET, VIRTIO_DEV_ANY_ID },
+       { 0 },
+};
+
+static struct virtio_driver virtio_net = {
+       .driver.name =  KBUILD_MODNAME,
+       .driver.owner = THIS_MODULE,
+       .id_table =     id_table,
+       .probe =        virtnet_probe,
+       .remove =       __devexit_p(virtnet_remove),
+};
+
+static int __init init(void)
+{
+       return register_virtio_driver(&virtio_net);
+}
+
+static void __exit fini(void)
+{
+       unregister_virtio_driver(&virtio_net);
+}
+module_init(init);
+module_exit(fini);
+
+MODULE_DEVICE_TABLE(virtio, id_table);
+MODULE_DESCRIPTION("Virtio network driver");
+MODULE_LICENSE("GPL");
index c141a264ac45bfb16e323ee8b1bbb2b08a727666..9d9ff76a9bc664a85191610034ad2640750cca4c 100644 (file)
@@ -49,7 +49,6 @@
 #include "pio.h"
 #include "sysfs.h"
 #include "xmit.h"
-#include "sysfs.h"
 #include "lo.h"
 #include "pcmcia.h"
 
@@ -3495,7 +3494,7 @@ static int b43_start(struct ieee80211_hw *hw)
        struct b43_wl *wl = hw_to_b43_wl(hw);
        struct b43_wldev *dev = wl->current_dev;
        int did_init = 0;
-       int err;
+       int err = 0;
 
        mutex_lock(&wl->mutex);
 
@@ -3521,7 +3520,7 @@ static int b43_start(struct ieee80211_hw *hw)
        return err;
 }
 
-void b43_stop(struct ieee80211_hw *hw)
+static void b43_stop(struct ieee80211_hw *hw)
 {
        struct b43_wl *wl = hw_to_b43_wl(hw);
        struct b43_wldev *dev = wl->current_dev;
index f0749510bcd7a193088194ce6b6e935bcd47a105..d09479e816cdf12b79658cc8ebce0586cfd18d74 100644 (file)
@@ -3306,7 +3306,7 @@ static int b43legacy_start(struct ieee80211_hw *hw)
        struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
        struct b43legacy_wldev *dev = wl->current_dev;
        int did_init = 0;
-       int err;
+       int err = 0;
 
        mutex_lock(&wl->mutex);
 
index 8f198befba390e1f325ee03f77bdc04b5896bc44..cb51dc51cce6d36f73ad2efef9d1672436c48ce3 100644 (file)
@@ -29,7 +29,7 @@
 #include "bcm43xx_radio.h"
 #include "bcm43xx.h"
 
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 
 
 static void bcm43xx_led_changestate(struct bcm43xx_led *led)
index 9ecf2bf0d25ddb100773ba759839180ab10ee367..47c135a7f4dc6136d7f2ce0e698ef204f5c1a3bd 100644 (file)
@@ -87,7 +87,7 @@ void bcm43xx_generate_txhdr(struct bcm43xx_private *bcm,
 
 /* RX header as received from the hardware. */
 struct bcm43xx_rxhdr {
-       /* Frame Length. Must be generated explicitely in PIO mode. */
+       /* Frame Length. Must be generated explicitly in PIO mode. */
        __le16 frame_length;
        PAD_BYTES(2);
        /* Flags field 1 */
index ceb7f1e5e9e096d50012a3999e21f1014ee2e48d..517f8984514411bfddb0c602df00599bcdeb011c 100644 (file)
@@ -4,9 +4,6 @@
 #include <linux/types.h>
 #include <linux/if_ether.h>
 
-#define BIT(x) (1 << (x))
-
-
 /* IEEE 802.11 defines */
 
 /* Information Element IDs */
index 40f516d42c5e39894f4c14f45582852ce116fb7b..d8f5efcfcab96915d0f41ecfb22958ba556a3936 100644 (file)
@@ -2920,7 +2920,7 @@ static int prism2_ioctl_priv_monitor(struct net_device *dev, int *i)
 
        printk(KERN_DEBUG "%s: process %d (%s) used deprecated iwpriv monitor "
               "- update software to use iwconfig mode monitor\n",
-              dev->name, current->pid, current->comm);
+              dev->name, task_pid_nr(current), current->comm);
 
        /* Backward compatibility code - this can be removed at some point */
 
index 2d46a16c09450c73d3ea5121af6f17391eca2fee..a6c7904de2828c48c4886624ced3df1ebb1238cc 100644 (file)
@@ -1858,14 +1858,6 @@ static void ipw2100_down(struct ipw2100_priv *priv)
 
        modify_acceptable_latency("ipw2100", INFINITE_LATENCY);
 
-#ifdef ACPI_CSTATE_LIMIT_DEFINED
-       if (priv->config & CFG_C3_DISABLED) {
-               IPW_DEBUG_INFO(": Resetting C3 transitions.\n");
-               acpi_set_cstate_limit(priv->cstate_limit);
-               priv->config &= ~CFG_C3_DISABLED;
-       }
-#endif
-
        /* We have to signal any supplicant if we are disassociating */
        if (associated)
                wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
@@ -2091,26 +2083,52 @@ static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status)
        /* RF_KILL is now enabled (else we wouldn't be here) */
        priv->status |= STATUS_RF_KILL_HW;
 
-#ifdef ACPI_CSTATE_LIMIT_DEFINED
-       if (priv->config & CFG_C3_DISABLED) {
-               IPW_DEBUG_INFO(": Resetting C3 transitions.\n");
-               acpi_set_cstate_limit(priv->cstate_limit);
-               priv->config &= ~CFG_C3_DISABLED;
-       }
-#endif
-
        /* Make sure the RF Kill check timer is running */
        priv->stop_rf_kill = 0;
        cancel_delayed_work(&priv->rf_kill);
        queue_delayed_work(priv->workqueue, &priv->rf_kill, round_jiffies(HZ));
 }
 
+static void send_scan_event(void *data)
+{
+       struct ipw2100_priv *priv = data;
+       union iwreq_data wrqu;
+
+       wrqu.data.length = 0;
+       wrqu.data.flags = 0;
+       wireless_send_event(priv->net_dev, SIOCGIWSCAN, &wrqu, NULL);
+}
+
+static void ipw2100_scan_event_later(struct work_struct *work)
+{
+       send_scan_event(container_of(work, struct ipw2100_priv,
+                                       scan_event_later.work));
+}
+
+static void ipw2100_scan_event_now(struct work_struct *work)
+{
+       send_scan_event(container_of(work, struct ipw2100_priv,
+                                       scan_event_now));
+}
+
 static void isr_scan_complete(struct ipw2100_priv *priv, u32 status)
 {
        IPW_DEBUG_SCAN("scan complete\n");
        /* Age the scan results... */
        priv->ieee->scans++;
        priv->status &= ~STATUS_SCANNING;
+
+       /* Only userspace-requested scan completion events go out immediately */
+       if (!priv->user_requested_scan) {
+               if (!delayed_work_pending(&priv->scan_event_later))
+                       queue_delayed_work(priv->workqueue,
+                                       &priv->scan_event_later,
+                                       round_jiffies(msecs_to_jiffies(4000)));
+       } else {
+               priv->user_requested_scan = 0;
+               cancel_delayed_work(&priv->scan_event_later);
+               queue_work(priv->workqueue, &priv->scan_event_now);
+       }
 }
 
 #ifdef CONFIG_IPW2100_DEBUG
@@ -2329,23 +2347,10 @@ static void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i)
        u32 match, reg;
        int j;
 #endif
-#ifdef ACPI_CSTATE_LIMIT_DEFINED
-       int limit;
-#endif
 
        IPW_DEBUG_INFO(": PCI latency error detected at 0x%04zX.\n",
                       i * sizeof(struct ipw2100_status));
 
-#ifdef ACPI_CSTATE_LIMIT_DEFINED
-       IPW_DEBUG_INFO(": Disabling C3 transitions.\n");
-       limit = acpi_get_cstate_limit();
-       if (limit > 2) {
-               priv->cstate_limit = limit;
-               acpi_set_cstate_limit(2);
-               priv->config |= CFG_C3_DISABLED;
-       }
-#endif
-
 #ifdef IPW2100_DEBUG_C3
        /* Halt the fimrware so we can get a good image */
        write_register(priv->net_dev, IPW_REG_RESET_REG,
@@ -4378,6 +4383,7 @@ static void ipw2100_kill_workqueue(struct ipw2100_priv *priv)
                cancel_delayed_work(&priv->wx_event_work);
                cancel_delayed_work(&priv->hang_check);
                cancel_delayed_work(&priv->rf_kill);
+               cancel_delayed_work(&priv->scan_event_later);
                destroy_workqueue(priv->workqueue);
                priv->workqueue = NULL;
        }
@@ -6041,7 +6047,7 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
         * ends up causing problems.  So, we just handle
         * the WX extensions through the ipw2100_ioctl interface */
 
-       /* memset() puts everything to 0, so we only have explicitely set
+       /* memset() puts everything to 0, so we only have explicitly set
         * those values that need to be something else */
 
        /* If power management is turned on, default to AUTO mode */
@@ -6121,6 +6127,8 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
        INIT_DELAYED_WORK(&priv->wx_event_work, ipw2100_wx_event_work);
        INIT_DELAYED_WORK(&priv->hang_check, ipw2100_hang_check);
        INIT_DELAYED_WORK(&priv->rf_kill, ipw2100_rf_kill);
+       INIT_WORK(&priv->scan_event_now, ipw2100_scan_event_now);
+       INIT_DELAYED_WORK(&priv->scan_event_later, ipw2100_scan_event_later);
 
        tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
                     ipw2100_irq_tasklet, (unsigned long)priv);
@@ -7425,6 +7433,8 @@ static int ipw2100_wx_set_scan(struct net_device *dev,
        }
 
        IPW_DEBUG_WX("Initiating scan...\n");
+
+       priv->user_requested_scan = 1;
        if (ipw2100_set_scan_options(priv) || ipw2100_start_scan(priv)) {
                IPW_DEBUG_WX("Start scan failed.\n");
 
@@ -7499,7 +7509,7 @@ static int ipw2100_wx_set_power(struct net_device *dev,
        switch (wrqu->power.flags & IW_POWER_MODE) {
        case IW_POWER_ON:       /* If not specified */
        case IW_POWER_MODE:     /* If set all mask */
-       case IW_POWER_ALL_R:    /* If explicitely state all */
+       case IW_POWER_ALL_R:    /* If explicitly state all */
                break;
        default:                /* Otherwise we don't support it */
                IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",
index de7d384d38af353d26082855b656bdaeb06554e9..bbf1ddcafba8f6249f900b51dc8e660f7b043f8b 100644 (file)
@@ -479,7 +479,6 @@ enum {
 #define CFG_ASSOCIATE           (1<<6)
 #define CFG_FIXED_RATE          (1<<7)
 #define CFG_ADHOC_CREATE        (1<<8)
-#define CFG_C3_DISABLED         (1<<9)
 #define CFG_PASSIVE_SCAN        (1<<10)
 #ifdef CONFIG_IPW2100_MONITOR
 #define CFG_CRC_CHECK           (1<<11)
@@ -508,7 +507,6 @@ struct ipw2100_priv {
        u8 bssid[ETH_ALEN];
        u8 channel;
        int last_mode;
-       int cstate_limit;
 
        unsigned long connect_start;
        unsigned long last_reset;
@@ -588,6 +586,10 @@ struct ipw2100_priv {
        struct delayed_work wx_event_work;
        struct delayed_work hang_check;
        struct delayed_work rf_kill;
+       struct work_struct scan_event_now;
+       struct delayed_work scan_event_later;
+
+       int user_requested_scan;
 
        u32 interrupts;
        int tx_interrupts;
index feb8fcbab2d5a35b4c81dbd449c64b5a0dd5a174..e3c828401b9aa5d1ec9e0d7090203530fef46f92 100644 (file)
@@ -9603,7 +9603,7 @@ static int ipw_wx_set_power(struct net_device *dev,
        switch (wrqu->power.flags & IW_POWER_MODE) {
        case IW_POWER_ON:       /* If not specified */
        case IW_POWER_MODE:     /* If set all mask */
-       case IW_POWER_ALL_R:    /* If explicitely state all */
+       case IW_POWER_ALL_R:    /* If explicitly state all */
                break;
        default:                /* Otherwise we don't support it */
                IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",
index f4aabcf480e46636479ebf00fc4f9d70b95f5ebf..262ab0b55824d907048d1081db1a473ad02d4852 100644 (file)
@@ -37,9 +37,6 @@
 
 #include <linux/workqueue.h>
 
-#include <net/mac80211.h>
-#include <linux/wireless.h>
-
 #define IWL 3945
 
 #include "../net/mac80211/ieee80211_rate.h"
index acb38750535f549b72fabfd0ddf2de3e1fc53e56..19bcb01e278429c83053b1dbd891a4307a668c0e 100644 (file)
@@ -38,7 +38,6 @@
 #include <net/mac80211.h>
 
 #include <linux/etherdevice.h>
-#include <linux/delay.h>
 
 #define IWL 3945
 
index 287c75705c44db0a72729dad2f0833294e5ac1ff..8dc78c0bf1ff26d5cff33c31e8e66399930ce225 100644 (file)
@@ -36,9 +36,6 @@
 
 #include <linux/workqueue.h>
 
-#include <net/mac80211.h>
-#include <linux/wireless.h>
-
 #define IWL 4965
 
 #include "../net/mac80211/ieee80211_rate.h"
@@ -2024,12 +2021,18 @@ static int open_file_generic(struct inode *inode, struct file *file)
 static void rs_dbgfs_set_mcs(struct iwl_rate_scale_priv *rs_priv,
                                struct iwl_rate *mcs, int index)
 {
-       const u32 cck_rate = 0x820A;
+       u32 base_rate;
+
+       if (rs_priv->phymode == (u8) MODE_IEEE80211A)
+               base_rate = 0x800D;
+       else
+               base_rate = 0x820A;
+
        if (rs_priv->dbg_fixed.rate_n_flags) {
                if (index < 12)
                        mcs->rate_n_flags = rs_priv->dbg_fixed.rate_n_flags;
                else
-                       mcs->rate_n_flags = cck_rate;
+                       mcs->rate_n_flags = base_rate;
                IWL_DEBUG_RATE("Fixed rate ON\n");
                return;
        }
index b50d20267c8a97a07679d603d17e3693458a3a9e..557deebca1b9f4a4d0cda8ec9f5488d1329bff4a 100644 (file)
@@ -35,9 +35,7 @@
 #include <linux/netdevice.h>
 #include <linux/wireless.h>
 #include <net/mac80211.h>
-#include <linux/netdevice.h>
 #include <linux/etherdevice.h>
-#include <linux/delay.h>
 
 #define IWL 4965
 
index 75e3b5c3f1558bce3ffc32cc99e172f6d2fa7bc4..83019d1d7cccf1cdd5a992c8f819492dac2b5c63 100644 (file)
@@ -48,8 +48,6 @@
 #include <linux/netdevice.h>
 #include <linux/wireless.h>
 #include <linux/firmware.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/if_arp.h>
 
@@ -1749,21 +1747,22 @@ static void iwl_unset_hw_setting(struct iwl_priv *priv)
  * return : set the bit for each supported rate insert in ie
  */
 static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate,
-                                   u16 basic_rate, int max_count)
+                                   u16 basic_rate, int *left)
 {
        u16 ret_rates = 0, bit;
        int i;
-       u8 *rates;
-
-       rates = &(ie[1]);
+       u8 *cnt = ie;
+       u8 *rates = ie + 1;
 
        for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) {
                if (bit & supported_rate) {
                        ret_rates |= bit;
-                       rates[*ie] = iwl_rates[i].ieee |
-                           ((bit & basic_rate) ? 0x80 : 0x00);
-                       *ie = *ie + 1;
-                       if (*ie >= max_count)
+                       rates[*cnt] = iwl_rates[i].ieee |
+                               ((bit & basic_rate) ? 0x80 : 0x00);
+                       (*cnt)++;
+                       (*left)--;
+                       if ((*left <= 0) ||
+                           (*cnt >= IWL_SUPPORTED_RATES_IE_LEN))
                                break;
                }
        }
@@ -1780,7 +1779,7 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv,
 {
        int len = 0;
        u8 *pos = NULL;
-       u16 ret_rates;
+       u16 active_rates, ret_rates, cck_rates;
 
        /* Make sure there is enough space for the probe request,
         * two mandatory IEs and the data */
@@ -1825,19 +1824,27 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv,
        left -= 2;
        if (left < 0)
                return 0;
+
        /* ... fill it in... */
        *pos++ = WLAN_EID_SUPP_RATES;
        *pos = 0;
-       ret_rates = priv->active_rate = priv->rates_mask;
+
+       priv->active_rate = priv->rates_mask;
+       active_rates = priv->active_rate;
        priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
 
-       iwl_supported_rate_to_ie(pos, priv->active_rate,
-                                priv->active_rate_basic, left);
+       cck_rates = IWL_CCK_RATES_MASK & active_rates;
+       ret_rates = iwl_supported_rate_to_ie(pos, cck_rates,
+                       priv->active_rate_basic, &left);
+       active_rates &= ~ret_rates;
+
+       ret_rates = iwl_supported_rate_to_ie(pos, active_rates,
+                                priv->active_rate_basic, &left);
+       active_rates &= ~ret_rates;
+
        len += 2 + *pos;
        pos += (*pos) + 1;
-       ret_rates = ~ret_rates & priv->active_rate;
-
-       if (ret_rates == 0)
+       if (active_rates == 0)
                goto fill_end;
 
        /* fill in supported extended rate */
@@ -1848,7 +1855,8 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv,
        /* ... fill it in... */
        *pos++ = WLAN_EID_EXT_SUPP_RATES;
        *pos = 0;
-       iwl_supported_rate_to_ie(pos, ret_rates, priv->active_rate_basic, left);
+       iwl_supported_rate_to_ie(pos, active_rates,
+                                priv->active_rate_basic, &left);
        if (*pos > 0)
                len += 2 + *pos;
 
index b1a6e39f7821d9cd5888d905737d168856ada18a..5e1279263b2264e74d57e439fc4148156a632d44 100644 (file)
@@ -48,8 +48,6 @@
 #include <linux/netdevice.h>
 #include <linux/wireless.h>
 #include <linux/firmware.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/if_arp.h>
 
@@ -1802,21 +1800,22 @@ static void iwl_unset_hw_setting(struct iwl_priv *priv)
  * return : set the bit for each supported rate insert in ie
  */
 static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate,
-                                   u16 basic_rate, int max_count)
+                                   u16 basic_rate, int *left)
 {
        u16 ret_rates = 0, bit;
        int i;
-       u8 *rates;
-
-       rates = &(ie[1]);
+       u8 *cnt = ie;
+       u8 *rates = ie + 1;
 
        for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) {
                if (bit & supported_rate) {
                        ret_rates |= bit;
-                       rates[*ie] = iwl_rates[i].ieee |
-                           ((bit & basic_rate) ? 0x80 : 0x00);
-                       *ie = *ie + 1;
-                       if (*ie >= max_count)
+                       rates[*cnt] = iwl_rates[i].ieee |
+                               ((bit & basic_rate) ? 0x80 : 0x00);
+                       (*cnt)++;
+                       (*left)--;
+                       if ((*left <= 0) ||
+                           (*cnt >= IWL_SUPPORTED_RATES_IE_LEN))
                                break;
                }
        }
@@ -1839,7 +1838,7 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv,
 {
        int len = 0;
        u8 *pos = NULL;
-       u16 ret_rates;
+       u16 active_rates, ret_rates, cck_rates;
 
        /* Make sure there is enough space for the probe request,
         * two mandatory IEs and the data */
@@ -1884,19 +1883,27 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv,
        left -= 2;
        if (left < 0)
                return 0;
+
        /* ... fill it in... */
        *pos++ = WLAN_EID_SUPP_RATES;
        *pos = 0;
-       ret_rates = priv->active_rate = priv->rates_mask;
+
+       priv->active_rate = priv->rates_mask;
+       active_rates = priv->active_rate;
        priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
 
-       iwl_supported_rate_to_ie(pos, priv->active_rate,
-                                priv->active_rate_basic, left);
+       cck_rates = IWL_CCK_RATES_MASK & active_rates;
+       ret_rates = iwl_supported_rate_to_ie(pos, cck_rates,
+                       priv->active_rate_basic, &left);
+       active_rates &= ~ret_rates;
+
+       ret_rates = iwl_supported_rate_to_ie(pos, active_rates,
+                                priv->active_rate_basic, &left);
+       active_rates &= ~ret_rates;
+
        len += 2 + *pos;
        pos += (*pos) + 1;
-       ret_rates = ~ret_rates & priv->active_rate;
-
-       if (ret_rates == 0)
+       if (active_rates == 0)
                goto fill_end;
 
        /* fill in supported extended rate */
@@ -1907,7 +1914,8 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv,
        /* ... fill it in... */
        *pos++ = WLAN_EID_EXT_SUPP_RATES;
        *pos = 0;
-       iwl_supported_rate_to_ie(pos, ret_rates, priv->active_rate_basic, left);
+       iwl_supported_rate_to_ie(pos, active_rates,
+                                priv->active_rate_basic, &left);
        if (*pos > 0)
                len += 2 + *pos;
 
@@ -4494,13 +4502,13 @@ static u8 ratio2dB[100] = {
  * Conversion assumes that levels are voltages (20*log), not powers (10*log). */
 int iwl_calc_db_from_ratio(int sig_ratio)
 {
-       /* Anything above 1000:1 just report as 60 dB */
-       if (sig_ratio > 1000)
+       /* 1000:1 or higher just report as 60 dB */
+       if (sig_ratio >= 1000)
                return 60;
 
-       /* Above 100:1, divide by 10 and use table,
+       /* 100:1 or higher, divide by 10 and use table,
         *   add 20 dB to make up for divide by 10 */
-       if (sig_ratio > 100)
+       if (sig_ratio >= 100)
                return (20 + (int)ratio2dB[sig_ratio/10]);
 
        /* We shouldn't see this */
index e0b97c3412153fee5f6b729d506d5b9f77b8da08..432ce887807f562ed6786933d9caf751a4dfcc8f 100644 (file)
@@ -39,18 +39,13 @@ struct iwl_priv;
 /* Hardware specific file defines the PCI IDs table for that hardware module */
 extern struct pci_device_id iwl_hw_card_ids[];
 
+#include "iwl-hw.h"
 #if IWL == 3945
-
 #define DRV_NAME       "iwl3945"
-#include "iwl-hw.h"
 #include "iwl-3945-hw.h"
-
 #elif IWL == 4965
-
 #define DRV_NAME        "iwl4965"
-#include "iwl-hw.h"
 #include "iwl-4965-hw.h"
-
 #endif
 
 #include "iwl-prph.h"
index c2d71afd57e5c6196a83cc620f0adb67222dba2a..2402cb8dd3281e07bc636fb4675d114fb5bf2005 100644 (file)
@@ -4,18 +4,18 @@
  * Version:       0.4.1
  * Description:   Netwave AirSurfer Wireless LAN PC Card driver
  * Status:        Experimental.
- * Authors:       John Markus Bjørndalen <johnm@cs.uit.no>
+ * Authors:       John Markus Bjørndalen <johnm@cs.uit.no>
  *                Dag Brattli <dagb@cs.uit.no>
  *                David Hinds <dahinds@users.sourceforge.net>
  * Created at:    A long time ago!
  * Modified at:   Mon Nov 10 11:54:37 1997
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1997 University of Tromsø, Norway
+ *     Copyright (c) 1997 University of Tromsø, Norway
  *
  * Revision History:
  *
- *   08-Nov-97 15:14:47   John Markus Bjørndalen <johnm@cs.uit.no>
+ *   08-Nov-97 15:14:47   John Markus Bjørndalen <johnm@cs.uit.no>
  *    - Fixed some bugs in netwave_rx and cleaned it up a bit. 
  *      (One of the bugs would have destroyed packets when receiving
  *      multiple packets per interrupt). 
@@ -158,7 +158,7 @@ static int pc_debug = PCMCIA_DEBUG;
 module_param(pc_debug, int, 0);
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
 static char *version =
-"netwave_cs.c 0.3.0 Thu Jul 17 14:36:02 1997 (John Markus Bjørndalen)\n";
+"netwave_cs.c 0.3.0 Thu Jul 17 14:36:02 1997 (John Markus Bjørndalen)\n";
 #else
 #define DEBUG(n, args...)
 #endif
index 2c63cf0ad2cdb3cfe11936e40147fd89b390f0da..1437db0cf4b271372d1a96df5164d74725169919 100644 (file)
@@ -577,7 +577,7 @@ static int p54_set_filter(struct ieee80211_hw *dev, u16 filter_type,
        struct p54_tx_control_filter *filter;
 
        hdr = kzalloc(sizeof(*hdr) + sizeof(*filter) +
-                     priv->tx_hdr_len, GFP_KERNEL);
+                     priv->tx_hdr_len, GFP_ATOMIC);
        if (!hdr)
                return -ENOMEM;
 
index bb6f46cfbb9f87e27dc792d52a1aed4ba5218706..ff399f8083e9c9cfcdd179250a0610453afb4885 100644 (file)
@@ -550,7 +550,7 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
                        /*
                         * Check if we need to set the Length Extension
                         */
-                       if (bitrate == 110 && residual <= 3)
+                       if (bitrate == 110 && residual <= 30)
                                desc.service |= 0x80;
                }
 
index 3e42759473c3d1e0041f975ae54656fe8b33f88d..46c8c0840a6531703ed85d31a0604598502f4baf 100644 (file)
@@ -2029,6 +2029,7 @@ static struct usb_device_id rt73usb_device_table[] = {
        { USB_DEVICE(0x050d, 0x7050), USB_DEVICE_DATA(&rt73usb_ops) },
        { USB_DEVICE(0x050d, 0x705a), USB_DEVICE_DATA(&rt73usb_ops) },
        { USB_DEVICE(0x050d, 0x905b), USB_DEVICE_DATA(&rt73usb_ops) },
+       { USB_DEVICE(0x050d, 0x905c), USB_DEVICE_DATA(&rt73usb_ops) },
        /* Billionton */
        { USB_DEVICE(0x1631, 0xc019), USB_DEVICE_DATA(&rt73usb_ops) },
        /* Buffalo */
index 0ef887dd286795fe0cf22a24b019b845362dae48..de61c8fe64924dd52fb2e4e37dd6aacd5d00db04 100644 (file)
@@ -131,7 +131,8 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
        struct rtl8187_tx_hdr *hdr;
        struct rtl8187_tx_info *info;
        struct urb *urb;
-       u32 tmp;
+       __le16 rts_dur = 0;
+       u32 flags;
 
        urb = usb_alloc_urb(0, GFP_ATOMIC);
        if (!urb) {
@@ -139,24 +140,24 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
                return 0;
        }
 
-       hdr = (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr));
-       tmp = skb->len - sizeof(*hdr);
-       tmp |= RTL8187_TX_FLAG_NO_ENCRYPT;
-       tmp |= control->rts_cts_rate << 19;
-       tmp |= control->tx_rate << 24;
-       if (ieee80211_get_morefrag((struct ieee80211_hdr *)skb))
-               tmp |= RTL8187_TX_FLAG_MORE_FRAG;
+       flags = skb->len;
+       flags |= RTL8187_TX_FLAG_NO_ENCRYPT;
+       flags |= control->rts_cts_rate << 19;
+       flags |= control->tx_rate << 24;
+       if (ieee80211_get_morefrag((struct ieee80211_hdr *)skb->data))
+               flags |= RTL8187_TX_FLAG_MORE_FRAG;
        if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) {
-               tmp |= RTL8187_TX_FLAG_RTS;
-               hdr->rts_duration =
-                       ieee80211_rts_duration(dev, priv->if_id, skb->len, control);
+               flags |= RTL8187_TX_FLAG_RTS;
+               rts_dur = ieee80211_rts_duration(dev, priv->if_id, skb->len, control);
        }
        if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
-               tmp |= RTL8187_TX_FLAG_CTS;
-       hdr->flags = cpu_to_le32(tmp);
+               flags |= RTL8187_TX_FLAG_CTS;
+
+       hdr = (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr));
+       hdr->flags = cpu_to_le32(flags);
        hdr->len = 0;
-       tmp = control->retry_limit << 8;
-       hdr->retry = cpu_to_le32(tmp);
+       hdr->rts_duration = rts_dur;
+       hdr->retry = cpu_to_le32(control->retry_limit << 8);
 
        info = (struct rtl8187_tx_info *)skb->cb;
        info->control = kmemdup(control, sizeof(*control), GFP_ATOMIC);
@@ -587,8 +588,6 @@ static void rtl8187_configure_filter(struct ieee80211_hw *dev,
 
        *total_flags = 0;
 
-       if (changed_flags & FIF_PROMISC_IN_BSS)
-               priv->rx_conf ^= RTL818X_RX_CONF_NICMAC;
        if (changed_flags & FIF_ALLMULTI)
                priv->rx_conf ^= RTL818X_RX_CONF_MULTICAST;
        if (changed_flags & FIF_FCSFAIL)
@@ -601,8 +600,6 @@ static void rtl8187_configure_filter(struct ieee80211_hw *dev,
        if (mc_count > 0)
                priv->rx_conf |= RTL818X_RX_CONF_MULTICAST;
 
-       if (priv->rx_conf & RTL818X_RX_CONF_NICMAC)
-               *total_flags |= FIF_PROMISC_IN_BSS;
        if (priv->rx_conf & RTL818X_RX_CONF_MULTICAST)
                *total_flags |= FIF_ALLMULTI;
        if (priv->rx_conf & RTL818X_RX_CONF_FCS)
index 935b144d9b56b419959fd3bd40cf156aa4121ca1..d5c0c66188cad3d146e32e3b0c6ccf0012e3066a 100644 (file)
@@ -327,8 +327,8 @@ static void zd1201_usbrx(struct urb *urb)
                        memcpy(skb_put(skb, 6), &data[datalen-8], 6);
                        memcpy(skb_put(skb, 2), &data[datalen-24], 2);
                        memcpy(skb_put(skb, len), data, len);
-                       skb->dev->last_rx = jiffies;
                        skb->protocol = eth_type_trans(skb, zd->dev);
+                       skb->dev->last_rx = jiffies;
                        zd->stats.rx_packets++;
                        zd->stats.rx_bytes += skb->len;
                        netif_rx(skb);
@@ -384,8 +384,8 @@ static void zd1201_usbrx(struct urb *urb)
                        memcpy(skb_put(skb, 2), &data[6], 2);
                        memcpy(skb_put(skb, len), data+8, len);
                }
-               skb->dev->last_rx = jiffies;
                skb->protocol = eth_type_trans(skb, zd->dev);
+               skb->dev->last_rx = jiffies;
                zd->stats.rx_packets++;
                zd->stats.rx_bytes += skb->len;
                netif_rx(skb);
index b0684f965761fec054bfc2ffeab014c1e329d810..c755b69238123c56cece6d8df9d77b5ed68022a6 100644 (file)
@@ -1044,14 +1044,17 @@ error:
 static void disconnect(struct usb_interface *intf)
 {
        struct net_device *netdev = zd_intf_to_netdev(intf);
-       struct zd_mac *mac = zd_netdev_mac(netdev);
-       struct zd_usb *usb = &mac->chip.usb;
+       struct zd_mac *mac;
+       struct zd_usb *usb;
 
        /* Either something really bad happened, or we're just dealing with
         * a DEVICE_INSTALLER. */
        if (netdev == NULL)
                return;
 
+       mac = zd_netdev_mac(netdev);
+       usb = &mac->chip.usb;
+
        dev_dbg_f(zd_usb_dev(usb), "\n");
 
        zd_netdev_disconnect(netdev);
index 7fd505cc4f7ab3b9a8fb32a8847596bca1d51d19..2a8fc431099f6e1fcd5a652edd043a774629d002 100644 (file)
@@ -1526,7 +1526,7 @@ static int xennet_connect(struct net_device *dev)
 
        if (!feature_rx_copy) {
                dev_info(&dev->dev,
-                        "backend does not support copying recieve path");
+                        "backend does not support copying receive path\n");
                return -ENODEV;
        }
 
index 864f09fd9f86f6978d1bc87710b0fe35c48669a6..b47bb2d7476a82e5618fc50c0772cfea9ddd46ec 100644 (file)
@@ -12,6 +12,7 @@
  *
  */
 #include <linux/errno.h>
+#include <linux/module.h>
 #include <linux/device.h>
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
@@ -94,3 +95,23 @@ int of_bus_type_init(struct bus_type *bus, const char *name)
        bus->resume = of_platform_device_resume;
        return bus_register(bus);
 }
+
+int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus)
+{
+       /* initialize common driver fields */
+       if (!drv->driver.name)
+               drv->driver.name = drv->name;
+       if (!drv->driver.owner)
+               drv->driver.owner = drv->owner;
+       drv->driver.bus = bus;
+
+       /* register with core */
+       return driver_register(&drv->driver);
+}
+EXPORT_SYMBOL(of_register_driver);
+
+void of_unregister_driver(struct of_platform_driver *drv)
+{
+       driver_unregister(&drv->driver);
+}
+EXPORT_SYMBOL(of_unregister_driver);
index b3c4dbff26b84c8797f411aa22d7351b97e388af..7c60cbd85dc8505883e14ad9091f456badfdb427 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/reboot.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/scatterlist.h>
 
 #include <asm/byteorder.h>
 #include <asm/cache.h>         /* for L1_CACHE_BYTES */
index 5b86ee5c1eeb7437d4886aef39735fe6e7aab5b2..5eace9e66e14c9bd86c15414b186061f6f345ab4 100644 (file)
@@ -556,44 +556,6 @@ lba_bios_init(void)
 
 #ifdef CONFIG_64BIT
 
-/*
-** Determine if a device is already configured.
-** If so, reserve it resources.
-**
-** Read PCI cfg command register and see if I/O or MMIO is enabled.
-** PAT has to enable the devices it's using.
-**
-** Note: resources are fixed up before we try to claim them.
-*/
-static void
-lba_claim_dev_resources(struct pci_dev *dev)
-{
-       u16 cmd;
-       int i, srch_flags;
-
-       (void) pci_read_config_word(dev, PCI_COMMAND, &cmd);
-
-       srch_flags  = (cmd & PCI_COMMAND_IO) ? IORESOURCE_IO : 0;
-       if (cmd & PCI_COMMAND_MEMORY)
-               srch_flags |= IORESOURCE_MEM;
-
-       if (!srch_flags)
-               return;
-
-       for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
-               if (dev->resource[i].flags & srch_flags) {
-                       pci_claim_resource(dev, i);
-                       DBG("   claimed %s %d [%lx,%lx]/%lx\n",
-                               pci_name(dev), i,
-                               dev->resource[i].start,
-                               dev->resource[i].end,
-                               dev->resource[i].flags
-                               );
-               }
-       }
-}
-
-
 /*
  * truncate_pat_collision:  Deal with overlaps or outright collisions
  *                     between PAT PDC reported ranges.
@@ -653,7 +615,6 @@ truncate_pat_collision(struct resource *root, struct resource *new)
 }
 
 #else
-#define lba_claim_dev_resources(dev) do { } while (0)
 #define truncate_pat_collision(r,n)  (0)
 #endif
 
@@ -684,8 +645,12 @@ lba_fixup_bus(struct pci_bus *bus)
        ** pci_alloc_primary_bus() mangles this.
        */
        if (bus->self) {
+               int i;
                /* PCI-PCI Bridge */
                pci_read_bridge_bases(bus);
+               for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) {
+                       pci_claim_resource(bus->self, i);
+               }
        } else {
                /* Host-PCI Bridge */
                int err, i;
@@ -803,6 +768,9 @@ lba_fixup_bus(struct pci_bus *bus)
                                DBG("lba_fixup_bus() WTF? 0x%lx [%lx/%lx] XXX",
                                        res->flags, res->start, res->end);
                        }
+                       if ((i != PCI_ROM_RESOURCE) ||
+                           (res->flags & IORESOURCE_ROM_ENABLE))
+                               pci_claim_resource(dev, i);
                }
 
 #ifdef FBB_SUPPORT
@@ -814,11 +782,6 @@ lba_fixup_bus(struct pci_bus *bus)
                bus->bridge_ctl &= ~(status & PCI_STATUS_FAST_BACK);
 #endif
 
-               if (is_pdc_pat()) {
-                       /* Claim resources for PDC's devices */
-                       lba_claim_dev_resources(dev);
-               }
-
                 /*
                ** P2PB's have no IRQs. ignore them.
                */
index fc4bde259dc7a68da93c89640aa36db34f5744e5..ebb09e98d215186201293db11260cc022b2d67c6 100644 (file)
@@ -282,6 +282,7 @@ pdcspath_hwpath_write(struct pdcspath_entry *entry, const char *buf, size_t coun
        unsigned short i;
        char in[count+1], *temp;
        struct device *dev;
+       int ret;
 
        if (!entry || !buf || !count)
                return -EINVAL;
@@ -333,7 +334,9 @@ pdcspath_hwpath_write(struct pdcspath_entry *entry, const char *buf, size_t coun
        
        /* Update the symlink to the real device */
        sysfs_remove_link(&entry->kobj, "device");
-       sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device");
+       ret = sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device");
+       WARN_ON(ret);
+
        write_unlock(&entry->rw_lock);
        
        printk(KERN_INFO PDCS_PREFIX ": changed \"%s\" path to \"%s\"\n",
@@ -1003,8 +1006,10 @@ pdcs_register_pathentries(void)
                entry->ready = 2;
                
                /* Add a nice symlink to the real device */
-               if (entry->dev)
-                       sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device");
+               if (entry->dev) {
+                       err = sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device");
+                       WARN_ON(err);
+               }
 
                write_unlock(&entry->rw_lock);
        }
index d044c48323e662c5130fd23935201754713ad13e..e527a0e1d6c01820c7fa24d911d9e5bacb6e33a4 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/mm.h>
 #include <linux/string.h>
 #include <linux/pci.h>
+#include <linux/scatterlist.h>
 
 #include <asm/byteorder.h>
 #include <asm/io.h>
@@ -1909,8 +1910,8 @@ sba_driver_callback(struct parisc_device *dev)
                        global_ioc_cnt *= 2;
        }
 
-       printk(KERN_INFO "%s found %s at 0x%lx\n",
-               MODULE_NAME, version, dev->hpa.start);
+       printk(KERN_INFO "%s found %s at 0x%llx\n",
+               MODULE_NAME, version, (unsigned long long)dev->hpa.start);
 
        sba_dev = kzalloc(sizeof(struct sba_device), GFP_KERNEL);
        if (!sba_dev) {
index 38cdf9fa36a7b8f20e5f57976220e4b5101e21a3..1e8d2d17f04c63d921fe827402ded98252affa87 100644 (file)
@@ -155,6 +155,7 @@ superio_init(struct pci_dev *pcidev)
        struct superio_device *sio = &sio_dev;
        struct pci_dev *pdev = sio->lio_pdev;
        u16 word;
+       int ret;
 
        if (sio->suckyio_irq_enabled)
                return;
@@ -200,7 +201,8 @@ superio_init(struct pci_dev *pcidev)
        pci_write_config_word (pdev, PCI_COMMAND, word);
 
        pci_set_master (pdev);
-       pci_enable_device(pdev);
+       ret = pci_enable_device(pdev);
+       BUG_ON(ret < 0);        /* not too much we can do about this... */
 
        /*
         * Next project is programming the onboard interrupt controllers.
index ff9f34453530d991d668fb35737c488a107b1c17..5bbff2028f8f52b242d222d1583e95d52fa74d76 100644 (file)
@@ -275,35 +275,6 @@ void parport_close(struct pardevice *dev)
        parport_unregister_device(dev);
 }
 
-/**
- *     parport_device_num - convert device coordinates
- *     @parport: parallel port number
- *     @mux: multiplexor port number (-1 for no multiplexor)
- *     @daisy: daisy chain address (-1 for no daisy chain address)
- *
- *     This tries to locate a device on the given parallel port,
- *     multiplexor port and daisy chain address, and returns its
- *     device number or %-ENXIO if no device with those coordinates
- *     exists.
- **/
-
-int parport_device_num(int parport, int mux, int daisy)
-{
-       int res = -ENXIO;
-       struct daisydev *dev;
-
-       spin_lock(&topology_lock);
-       dev = topology;
-       while (dev && dev->port->portnum != parport &&
-              dev->port->muxport != mux && dev->daisy != daisy)
-               dev = dev->next;
-       if (dev)
-               res = dev->devnum;
-       spin_unlock(&topology_lock);
-
-       return res;
-}
-
 /* Send a daisy-chain-style CPP command packet. */
 static int cpp_daisy(struct parport *port, int cmd)
 {
index bdbdab9285cacfbb6839c24cbbf9f11239e5796f..ed82e41210d1d1e89616105b2b23e7f3322bd292 100644 (file)
@@ -237,7 +237,7 @@ static int do_hardware_modes (ctl_table *table, int write,
 #define PARPORT_PARPORT_DIR(CHILD) { .ctl_name = DEV_PARPORT, .procname = "parport", \
                                      .mode = 0555, .child = CHILD }
 #define PARPORT_DEV_DIR(CHILD) { .ctl_name = CTL_DEV, .procname = "dev", .mode = 0555, .child = CHILD }
-#define PARPORT_DEVICES_ROOT_DIR  { .ctl_name = DEV_PARPORT_DEVICES, .procname = "devices", \
+#define PARPORT_DEVICES_ROOT_DIR  {  .procname = "devices", \
                                     .mode = 0555, .child = NULL }
 
 static const unsigned long parport_min_timeslice_value =
@@ -266,7 +266,6 @@ static const struct parport_sysctl_table parport_sysctl_template = {
        .sysctl_header = NULL,
         {
                {
-                       .ctl_name       = DEV_PARPORT_SPINTIME,
                        .procname       = "spintime",
                        .data           = NULL,
                        .maxlen         = sizeof(int),
@@ -276,7 +275,6 @@ static const struct parport_sysctl_table parport_sysctl_template = {
                        .extra2         = (void*) &parport_max_spintime_value
                },
                {
-                       .ctl_name       = DEV_PARPORT_BASE_ADDR,
                        .procname       = "base-addr",
                        .data           = NULL,
                        .maxlen         = 0,
@@ -284,7 +282,6 @@ static const struct parport_sysctl_table parport_sysctl_template = {
                        .proc_handler   = &do_hardware_base_addr
                },
                {
-                       .ctl_name       = DEV_PARPORT_IRQ,
                        .procname       = "irq",
                        .data           = NULL,
                        .maxlen         = 0,
@@ -292,7 +289,6 @@ static const struct parport_sysctl_table parport_sysctl_template = {
                        .proc_handler   = &do_hardware_irq
                },
                {
-                       .ctl_name       = DEV_PARPORT_DMA,
                        .procname       = "dma",
                        .data           = NULL,
                        .maxlen         = 0,
@@ -300,7 +296,6 @@ static const struct parport_sysctl_table parport_sysctl_template = {
                        .proc_handler   = &do_hardware_dma
                },
                {
-                       .ctl_name       = DEV_PARPORT_MODES,
                        .procname       = "modes",
                        .data           = NULL,
                        .maxlen         = 0,
@@ -310,7 +305,6 @@ static const struct parport_sysctl_table parport_sysctl_template = {
                PARPORT_DEVICES_ROOT_DIR,
 #ifdef CONFIG_PARPORT_1284
                {
-                       .ctl_name       = DEV_PARPORT_AUTOPROBE,
                        .procname       = "autoprobe",
                        .data           = NULL,
                        .maxlen         = 0,
@@ -318,7 +312,6 @@ static const struct parport_sysctl_table parport_sysctl_template = {
                        .proc_handler   = &do_autoprobe
                },
                {
-                       .ctl_name       = DEV_PARPORT_AUTOPROBE + 1,
                        .procname       = "autoprobe0",
                        .data           = NULL,
                        .maxlen         = 0,
@@ -326,7 +319,6 @@ static const struct parport_sysctl_table parport_sysctl_template = {
                        .proc_handler   =  &do_autoprobe
                },
                {
-                       .ctl_name       = DEV_PARPORT_AUTOPROBE + 2,
                        .procname       = "autoprobe1",
                        .data           = NULL,
                        .maxlen         = 0,
@@ -334,7 +326,6 @@ static const struct parport_sysctl_table parport_sysctl_template = {
                        .proc_handler   = &do_autoprobe
                },
                {
-                       .ctl_name       = DEV_PARPORT_AUTOPROBE + 3,
                        .procname       = "autoprobe2",
                        .data           = NULL,
                        .maxlen         = 0,
@@ -342,7 +333,6 @@ static const struct parport_sysctl_table parport_sysctl_template = {
                        .proc_handler   = &do_autoprobe
                },
                {
-                       .ctl_name       = DEV_PARPORT_AUTOPROBE + 4,
                        .procname       = "autoprobe3",
                        .data           = NULL,
                        .maxlen         = 0,
@@ -354,7 +344,6 @@ static const struct parport_sysctl_table parport_sysctl_template = {
        },
        {
                {
-                       .ctl_name       = DEV_PARPORT_DEVICES_ACTIVE,
                        .procname       = "active",
                        .data           = NULL,
                        .maxlen         = 0,
@@ -393,7 +382,6 @@ parport_device_sysctl_template = {
        .sysctl_header = NULL,
        {
                {
-                       .ctl_name       = DEV_PARPORT_DEVICE_TIMESLICE,
                        .procname       = "timeslice",
                        .data           = NULL,
                        .maxlen         = sizeof(int),
@@ -449,7 +437,6 @@ parport_default_sysctl_table = {
        .sysctl_header  = NULL,
        {
                {
-                       .ctl_name       = DEV_PARPORT_DEFAULT_TIMESLICE,
                        .procname       = "timeslice",
                        .data           = &parport_default_timeslice,
                        .maxlen         = sizeof(parport_default_timeslice),
@@ -459,7 +446,6 @@ parport_default_sysctl_table = {
                        .extra2         = (void*) &parport_max_timeslice_value
                },
                {
-                       .ctl_name       = DEV_PARPORT_DEFAULT_SPINTIME,
                        .procname       = "spintime",
                        .data           = &parport_default_spintime,
                        .maxlen         = sizeof(parport_default_spintime),
@@ -502,7 +488,7 @@ int parport_proc_register(struct parport *port)
 
        t->device_dir[0].extra1 = port;
 
-       for (i = 0; i < 8; i++)
+       for (i = 0; i < 5; i++)
                t->vars[i].extra1 = port;
 
        t->vars[0].data = &port->spintime;
@@ -512,7 +498,7 @@ int parport_proc_register(struct parport *port)
                t->vars[6 + i].extra2 = &port->probe_info[i];
 
        t->port_dir[0].procname = port->name;
-       t->port_dir[0].ctl_name = port->number + 1; /* nb 0 isn't legal here */
+       t->port_dir[0].ctl_name = 0;
 
        t->port_dir[0].child = t->vars;
        t->parport_dir[0].child = t->port_dir;
@@ -551,26 +537,12 @@ int parport_device_proc_register(struct pardevice *device)
        t->dev_dir[0].child = t->parport_dir;
        t->parport_dir[0].child = t->port_dir;
        t->port_dir[0].procname = port->name;
-       t->port_dir[0].ctl_name = port->number + 1; /* nb 0 isn't legal here */
+       t->port_dir[0].ctl_name = 0;
        t->port_dir[0].child = t->devices_root_dir;
        t->devices_root_dir[0].child = t->device_dir;
 
-#ifdef CONFIG_PARPORT_1284
-
-       t->device_dir[0].ctl_name =
-               parport_device_num(port->number, port->muxport,
-                                  device->daisy)
-               + 1;  /* nb 0 isn't legal here */ 
-
-#else /* No IEEE 1284 support */
-
-       /* parport_device_num isn't available. */
-       t->device_dir[0].ctl_name = 1;
-       
-#endif /* IEEE 1284 support or not */
-
+       t->device_dir[0].ctl_name = 0;
        t->device_dir[0].procname = device->name;
-       t->device_dir[0].extra1 = device;
        t->device_dir[0].child = t->vars;
        t->vars[0].data = &device->timeslice;
 
index 006054a409958a5f7617f9b1713a0eced9381d68..555055650733999cd10322d0dc64edecabd91dfd 100644 (file)
@@ -20,6 +20,9 @@ obj-$(CONFIG_PCI_MSI) += msi.o
 # Build the Hypertransport interrupt support
 obj-$(CONFIG_HT_IRQ) += htirq.o
 
+# Build Intel IOMMU support
+obj-$(CONFIG_DMAR) += dmar.o iova.o intel-iommu.o
+
 #
 # Some architectures use the generic PCI setup functions
 #
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
new file mode 100644 (file)
index 0000000..5dfdfda
--- /dev/null
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ *     Copyright (C) Ashok Raj <ashok.raj@intel.com>
+ *     Copyright (C) Shaohua Li <shaohua.li@intel.com>
+ *     Copyright (C) Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ *
+ *     This file implements early detection/parsing of DMA Remapping Devices
+ * reported to OS through BIOS via DMA remapping reporting (DMAR) ACPI
+ * tables.
+ */
+
+#include <linux/pci.h>
+#include <linux/dmar.h>
+
+#undef PREFIX
+#define PREFIX "DMAR:"
+
+/* No locks are needed as DMA remapping hardware unit
+ * list is constructed at boot time and hotplug of
+ * these units are not supported by the architecture.
+ */
+LIST_HEAD(dmar_drhd_units);
+LIST_HEAD(dmar_rmrr_units);
+
+static struct acpi_table_header * __initdata dmar_tbl;
+
+static void __init dmar_register_drhd_unit(struct dmar_drhd_unit *drhd)
+{
+       /*
+        * add INCLUDE_ALL at the tail, so scan the list will find it at
+        * the very end.
+        */
+       if (drhd->include_all)
+               list_add_tail(&drhd->list, &dmar_drhd_units);
+       else
+               list_add(&drhd->list, &dmar_drhd_units);
+}
+
+static void __init dmar_register_rmrr_unit(struct dmar_rmrr_unit *rmrr)
+{
+       list_add(&rmrr->list, &dmar_rmrr_units);
+}
+
+static int __init dmar_parse_one_dev_scope(struct acpi_dmar_device_scope *scope,
+                                          struct pci_dev **dev, u16 segment)
+{
+       struct pci_bus *bus;
+       struct pci_dev *pdev = NULL;
+       struct acpi_dmar_pci_path *path;
+       int count;
+
+       bus = pci_find_bus(segment, scope->bus);
+       path = (struct acpi_dmar_pci_path *)(scope + 1);
+       count = (scope->length - sizeof(struct acpi_dmar_device_scope))
+               / sizeof(struct acpi_dmar_pci_path);
+
+       while (count) {
+               if (pdev)
+                       pci_dev_put(pdev);
+               /*
+                * Some BIOSes list non-exist devices in DMAR table, just
+                * ignore it
+                */
+               if (!bus) {
+                       printk(KERN_WARNING
+                       PREFIX "Device scope bus [%d] not found\n",
+                       scope->bus);
+                       break;
+               }
+               pdev = pci_get_slot(bus, PCI_DEVFN(path->dev, path->fn));
+               if (!pdev) {
+                       printk(KERN_WARNING PREFIX
+                       "Device scope device [%04x:%02x:%02x.%02x] not found\n",
+                               segment, bus->number, path->dev, path->fn);
+                       break;
+               }
+               path ++;
+               count --;
+               bus = pdev->subordinate;
+       }
+       if (!pdev) {
+               printk(KERN_WARNING PREFIX
+               "Device scope device [%04x:%02x:%02x.%02x] not found\n",
+               segment, scope->bus, path->dev, path->fn);
+               *dev = NULL;
+               return 0;
+       }
+       if ((scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT && \
+                       pdev->subordinate) || (scope->entry_type == \
+                       ACPI_DMAR_SCOPE_TYPE_BRIDGE && !pdev->subordinate)) {
+               pci_dev_put(pdev);
+               printk(KERN_WARNING PREFIX
+                       "Device scope type does not match for %s\n",
+                        pci_name(pdev));
+               return -EINVAL;
+       }
+       *dev = pdev;
+       return 0;
+}
+
+static int __init dmar_parse_dev_scope(void *start, void *end, int *cnt,
+                                      struct pci_dev ***devices, u16 segment)
+{
+       struct acpi_dmar_device_scope *scope;
+       void * tmp = start;
+       int index;
+       int ret;
+
+       *cnt = 0;
+       while (start < end) {
+               scope = start;
+               if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT ||
+                   scope->entry_type == ACPI_DMAR_SCOPE_TYPE_BRIDGE)
+                       (*cnt)++;
+               else
+                       printk(KERN_WARNING PREFIX
+                               "Unsupported device scope\n");
+               start += scope->length;
+       }
+       if (*cnt == 0)
+               return 0;
+
+       *devices = kcalloc(*cnt, sizeof(struct pci_dev *), GFP_KERNEL);
+       if (!*devices)
+               return -ENOMEM;
+
+       start = tmp;
+       index = 0;
+       while (start < end) {
+               scope = start;
+               if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT ||
+                   scope->entry_type == ACPI_DMAR_SCOPE_TYPE_BRIDGE) {
+                       ret = dmar_parse_one_dev_scope(scope,
+                               &(*devices)[index], segment);
+                       if (ret) {
+                               kfree(*devices);
+                               return ret;
+                       }
+                       index ++;
+               }
+               start += scope->length;
+       }
+
+       return 0;
+}
+
+/**
+ * dmar_parse_one_drhd - parses exactly one DMA remapping hardware definition
+ * structure which uniquely represent one DMA remapping hardware unit
+ * present in the platform
+ */
+static int __init
+dmar_parse_one_drhd(struct acpi_dmar_header *header)
+{
+       struct acpi_dmar_hardware_unit *drhd;
+       struct dmar_drhd_unit *dmaru;
+       int ret = 0;
+       static int include_all;
+
+       dmaru = kzalloc(sizeof(*dmaru), GFP_KERNEL);
+       if (!dmaru)
+               return -ENOMEM;
+
+       drhd = (struct acpi_dmar_hardware_unit *)header;
+       dmaru->reg_base_addr = drhd->address;
+       dmaru->include_all = drhd->flags & 0x1; /* BIT0: INCLUDE_ALL */
+
+       if (!dmaru->include_all)
+               ret = dmar_parse_dev_scope((void *)(drhd + 1),
+                               ((void *)drhd) + header->length,
+                               &dmaru->devices_cnt, &dmaru->devices,
+                               drhd->segment);
+       else {
+               /* Only allow one INCLUDE_ALL */
+               if (include_all) {
+                       printk(KERN_WARNING PREFIX "Only one INCLUDE_ALL "
+                               "device scope is allowed\n");
+                       ret = -EINVAL;
+               }
+               include_all = 1;
+       }
+
+       if (ret || (dmaru->devices_cnt == 0 && !dmaru->include_all))
+               kfree(dmaru);
+       else
+               dmar_register_drhd_unit(dmaru);
+       return ret;
+}
+
+static int __init
+dmar_parse_one_rmrr(struct acpi_dmar_header *header)
+{
+       struct acpi_dmar_reserved_memory *rmrr;
+       struct dmar_rmrr_unit *rmrru;
+       int ret = 0;
+
+       rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL);
+       if (!rmrru)
+               return -ENOMEM;
+
+       rmrr = (struct acpi_dmar_reserved_memory *)header;
+       rmrru->base_address = rmrr->base_address;
+       rmrru->end_address = rmrr->end_address;
+       ret = dmar_parse_dev_scope((void *)(rmrr + 1),
+               ((void *)rmrr) + header->length,
+               &rmrru->devices_cnt, &rmrru->devices, rmrr->segment);
+
+       if (ret || (rmrru->devices_cnt == 0))
+               kfree(rmrru);
+       else
+               dmar_register_rmrr_unit(rmrru);
+       return ret;
+}
+
+static void __init
+dmar_table_print_dmar_entry(struct acpi_dmar_header *header)
+{
+       struct acpi_dmar_hardware_unit *drhd;
+       struct acpi_dmar_reserved_memory *rmrr;
+
+       switch (header->type) {
+       case ACPI_DMAR_TYPE_HARDWARE_UNIT:
+               drhd = (struct acpi_dmar_hardware_unit *)header;
+               printk (KERN_INFO PREFIX
+                       "DRHD (flags: 0x%08x)base: 0x%016Lx\n",
+                       drhd->flags, 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);
+               break;
+       }
+}
+
+/**
+ * parse_dmar_table - parses the DMA reporting table
+ */
+static int __init
+parse_dmar_table(void)
+{
+       struct acpi_table_dmar *dmar;
+       struct acpi_dmar_header *entry_header;
+       int ret = 0;
+
+       dmar = (struct acpi_table_dmar *)dmar_tbl;
+       if (!dmar)
+               return -ENODEV;
+
+       if (!dmar->width) {
+               printk (KERN_WARNING PREFIX "Zero: Invalid DMAR haw\n");
+               return -EINVAL;
+       }
+
+       printk (KERN_INFO PREFIX "Host address width %d\n",
+               dmar->width + 1);
+
+       entry_header = (struct acpi_dmar_header *)(dmar + 1);
+       while (((unsigned long)entry_header) <
+                       (((unsigned long)dmar) + dmar_tbl->length)) {
+               dmar_table_print_dmar_entry(entry_header);
+
+               switch (entry_header->type) {
+               case ACPI_DMAR_TYPE_HARDWARE_UNIT:
+                       ret = dmar_parse_one_drhd(entry_header);
+                       break;
+               case ACPI_DMAR_TYPE_RESERVED_MEMORY:
+                       ret = dmar_parse_one_rmrr(entry_header);
+                       break;
+               default:
+                       printk(KERN_WARNING PREFIX
+                               "Unknown DMAR structure type\n");
+                       ret = 0; /* for forward compatibility */
+                       break;
+               }
+               if (ret)
+                       break;
+
+               entry_header = ((void *)entry_header + entry_header->length);
+       }
+       return ret;
+}
+
+
+int __init dmar_table_init(void)
+{
+
+       parse_dmar_table();
+       if (list_empty(&dmar_drhd_units)) {
+               printk(KERN_INFO PREFIX "No DMAR devices found\n");
+               return -ENODEV;
+       }
+       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);
+}
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
new file mode 100644 (file)
index 0000000..0c4ab3b
--- /dev/null
@@ -0,0 +1,2271 @@
+/*
+ * Copyright (c) 2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Copyright (C) Ashok Raj <ashok.raj@intel.com>
+ * Copyright (C) Shaohua Li <shaohua.li@intel.com>
+ * Copyright (C) Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ */
+
+#include <linux/init.h>
+#include <linux/bitmap.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/sysdev.h>
+#include <linux/spinlock.h>
+#include <linux/pci.h>
+#include <linux/dmar.h>
+#include <linux/dma-mapping.h>
+#include <linux/mempool.h>
+#include "iova.h"
+#include "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 IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
+#define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA)
+
+#define IOAPIC_RANGE_START     (0xfee00000)
+#define IOAPIC_RANGE_END       (0xfeefffff)
+#define IOVA_START_ADDR                (0x1000)
+
+#define DEFAULT_DOMAIN_ADDRESS_WIDTH 48
+
+#define DMAR_OPERATION_TIMEOUT (HZ*60) /* 1m */
+
+#define DOMAIN_MAX_ADDR(gaw) ((((u64)1) << gaw) - 1)
+
+static void domain_remove_dev_info(struct dmar_domain *domain);
+
+static int dmar_disabled;
+static int __initdata dmar_map_gfx = 1;
+static int dmar_forcedac;
+
+#define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1))
+static DEFINE_SPINLOCK(device_domain_lock);
+static LIST_HEAD(device_domain_list);
+
+static int __init intel_iommu_setup(char *str)
+{
+       if (!str)
+               return -EINVAL;
+       while (*str) {
+               if (!strncmp(str, "off", 3)) {
+                       dmar_disabled = 1;
+                       printk(KERN_INFO"Intel-IOMMU: disabled\n");
+               } else if (!strncmp(str, "igfx_off", 8)) {
+                       dmar_map_gfx = 0;
+                       printk(KERN_INFO
+                               "Intel-IOMMU: disable GFX device mapping\n");
+               } else if (!strncmp(str, "forcedac", 8)) {
+                       printk (KERN_INFO
+                               "Intel-IOMMU: Forcing DAC for PCI devices\n");
+                       dmar_forcedac = 1;
+               }
+
+               str += strcspn(str, ",");
+               while (*str == ',')
+                       str++;
+       }
+       return 0;
+}
+__setup("intel_iommu=", intel_iommu_setup);
+
+static struct kmem_cache *iommu_domain_cache;
+static struct kmem_cache *iommu_devinfo_cache;
+static struct kmem_cache *iommu_iova_cache;
+
+static inline void *iommu_kmem_cache_alloc(struct kmem_cache *cachep)
+{
+       unsigned int flags;
+       void *vaddr;
+
+       /* trying to avoid low memory issues */
+       flags = current->flags & PF_MEMALLOC;
+       current->flags |= PF_MEMALLOC;
+       vaddr = kmem_cache_alloc(cachep, GFP_ATOMIC);
+       current->flags &= (~PF_MEMALLOC | flags);
+       return vaddr;
+}
+
+
+static inline void *alloc_pgtable_page(void)
+{
+       unsigned int flags;
+       void *vaddr;
+
+       /* trying to avoid low memory issues */
+       flags = current->flags & PF_MEMALLOC;
+       current->flags |= PF_MEMALLOC;
+       vaddr = (void *)get_zeroed_page(GFP_ATOMIC);
+       current->flags &= (~PF_MEMALLOC | flags);
+       return vaddr;
+}
+
+static inline void free_pgtable_page(void *vaddr)
+{
+       free_page((unsigned long)vaddr);
+}
+
+static inline void *alloc_domain_mem(void)
+{
+       return iommu_kmem_cache_alloc(iommu_domain_cache);
+}
+
+static inline void free_domain_mem(void *vaddr)
+{
+       kmem_cache_free(iommu_domain_cache, vaddr);
+}
+
+static inline void * alloc_devinfo_mem(void)
+{
+       return iommu_kmem_cache_alloc(iommu_devinfo_cache);
+}
+
+static inline void free_devinfo_mem(void *vaddr)
+{
+       kmem_cache_free(iommu_devinfo_cache, vaddr);
+}
+
+struct iova *alloc_iova_mem(void)
+{
+       return iommu_kmem_cache_alloc(iommu_iova_cache);
+}
+
+void free_iova_mem(struct iova *iova)
+{
+       kmem_cache_free(iommu_iova_cache, iova);
+}
+
+static inline void __iommu_flush_cache(
+       struct intel_iommu *iommu, void *addr, int size)
+{
+       if (!ecap_coherent(iommu->ecap))
+               clflush_cache_range(addr, size);
+}
+
+/* Gets context entry for a given bus and devfn */
+static struct context_entry * device_to_context_entry(struct intel_iommu *iommu,
+               u8 bus, u8 devfn)
+{
+       struct root_entry *root;
+       struct context_entry *context;
+       unsigned long phy_addr;
+       unsigned long flags;
+
+       spin_lock_irqsave(&iommu->lock, flags);
+       root = &iommu->root_entry[bus];
+       context = get_context_addr_from_root(root);
+       if (!context) {
+               context = (struct context_entry *)alloc_pgtable_page();
+               if (!context) {
+                       spin_unlock_irqrestore(&iommu->lock, flags);
+                       return NULL;
+               }
+               __iommu_flush_cache(iommu, (void *)context, PAGE_SIZE_4K);
+               phy_addr = virt_to_phys((void *)context);
+               set_root_value(root, phy_addr);
+               set_root_present(root);
+               __iommu_flush_cache(iommu, root, sizeof(*root));
+       }
+       spin_unlock_irqrestore(&iommu->lock, flags);
+       return &context[devfn];
+}
+
+static int device_context_mapped(struct intel_iommu *iommu, u8 bus, u8 devfn)
+{
+       struct root_entry *root;
+       struct context_entry *context;
+       int ret;
+       unsigned long flags;
+
+       spin_lock_irqsave(&iommu->lock, flags);
+       root = &iommu->root_entry[bus];
+       context = get_context_addr_from_root(root);
+       if (!context) {
+               ret = 0;
+               goto out;
+       }
+       ret = context_present(context[devfn]);
+out:
+       spin_unlock_irqrestore(&iommu->lock, flags);
+       return ret;
+}
+
+static void clear_context_table(struct intel_iommu *iommu, u8 bus, u8 devfn)
+{
+       struct root_entry *root;
+       struct context_entry *context;
+       unsigned long flags;
+
+       spin_lock_irqsave(&iommu->lock, flags);
+       root = &iommu->root_entry[bus];
+       context = get_context_addr_from_root(root);
+       if (context) {
+               context_clear_entry(context[devfn]);
+               __iommu_flush_cache(iommu, &context[devfn], \
+                       sizeof(*context));
+       }
+       spin_unlock_irqrestore(&iommu->lock, flags);
+}
+
+static void free_context_table(struct intel_iommu *iommu)
+{
+       struct root_entry *root;
+       int i;
+       unsigned long flags;
+       struct context_entry *context;
+
+       spin_lock_irqsave(&iommu->lock, flags);
+       if (!iommu->root_entry) {
+               goto out;
+       }
+       for (i = 0; i < ROOT_ENTRY_NR; i++) {
+               root = &iommu->root_entry[i];
+               context = get_context_addr_from_root(root);
+               if (context)
+                       free_pgtable_page(context);
+       }
+       free_pgtable_page(iommu->root_entry);
+       iommu->root_entry = NULL;
+out:
+       spin_unlock_irqrestore(&iommu->lock, flags);
+}
+
+/* page table handling */
+#define LEVEL_STRIDE           (9)
+#define LEVEL_MASK             (((u64)1 << LEVEL_STRIDE) - 1)
+
+static inline int agaw_to_level(int agaw)
+{
+       return agaw + 2;
+}
+
+static inline int agaw_to_width(int agaw)
+{
+       return 30 + agaw * LEVEL_STRIDE;
+
+}
+
+static inline int width_to_agaw(int width)
+{
+       return (width - 30) / LEVEL_STRIDE;
+}
+
+static inline unsigned int level_to_offset_bits(int level)
+{
+       return (12 + (level - 1) * LEVEL_STRIDE);
+}
+
+static inline int address_level_offset(u64 addr, int level)
+{
+       return ((addr >> level_to_offset_bits(level)) & LEVEL_MASK);
+}
+
+static inline u64 level_mask(int level)
+{
+       return ((u64)-1 << level_to_offset_bits(level));
+}
+
+static inline u64 level_size(int level)
+{
+       return ((u64)1 << level_to_offset_bits(level));
+}
+
+static inline u64 align_to_level(u64 addr, int level)
+{
+       return ((addr + level_size(level) - 1) & level_mask(level));
+}
+
+static struct dma_pte * addr_to_dma_pte(struct dmar_domain *domain, u64 addr)
+{
+       int addr_width = agaw_to_width(domain->agaw);
+       struct dma_pte *parent, *pte = NULL;
+       int level = agaw_to_level(domain->agaw);
+       int offset;
+       unsigned long flags;
+
+       BUG_ON(!domain->pgd);
+
+       addr &= (((u64)1) << addr_width) - 1;
+       parent = domain->pgd;
+
+       spin_lock_irqsave(&domain->mapping_lock, flags);
+       while (level > 0) {
+               void *tmp_page;
+
+               offset = address_level_offset(addr, level);
+               pte = &parent[offset];
+               if (level == 1)
+                       break;
+
+               if (!dma_pte_present(*pte)) {
+                       tmp_page = alloc_pgtable_page();
+
+                       if (!tmp_page) {
+                               spin_unlock_irqrestore(&domain->mapping_lock,
+                                       flags);
+                               return NULL;
+                       }
+                       __iommu_flush_cache(domain->iommu, tmp_page,
+                                       PAGE_SIZE_4K);
+                       dma_set_pte_addr(*pte, virt_to_phys(tmp_page));
+                       /*
+                        * high level table always sets r/w, last level page
+                        * table control read/write
+                        */
+                       dma_set_pte_readable(*pte);
+                       dma_set_pte_writable(*pte);
+                       __iommu_flush_cache(domain->iommu, pte, sizeof(*pte));
+               }
+               parent = phys_to_virt(dma_pte_addr(*pte));
+               level--;
+       }
+
+       spin_unlock_irqrestore(&domain->mapping_lock, flags);
+       return pte;
+}
+
+/* return address's pte at specific level */
+static struct dma_pte *dma_addr_level_pte(struct dmar_domain *domain, u64 addr,
+               int level)
+{
+       struct dma_pte *parent, *pte = NULL;
+       int total = agaw_to_level(domain->agaw);
+       int offset;
+
+       parent = domain->pgd;
+       while (level <= total) {
+               offset = address_level_offset(addr, total);
+               pte = &parent[offset];
+               if (level == total)
+                       return pte;
+
+               if (!dma_pte_present(*pte))
+                       break;
+               parent = phys_to_virt(dma_pte_addr(*pte));
+               total--;
+       }
+       return NULL;
+}
+
+/* clear one page's page table */
+static void dma_pte_clear_one(struct dmar_domain *domain, u64 addr)
+{
+       struct dma_pte *pte = NULL;
+
+       /* get last level pte */
+       pte = dma_addr_level_pte(domain, addr, 1);
+
+       if (pte) {
+               dma_clear_pte(*pte);
+               __iommu_flush_cache(domain->iommu, pte, sizeof(*pte));
+       }
+}
+
+/* clear last level pte, a tlb flush should be followed */
+static void dma_pte_clear_range(struct dmar_domain *domain, u64 start, u64 end)
+{
+       int addr_width = agaw_to_width(domain->agaw);
+
+       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;
+
+       /* 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;
+       }
+}
+
+/* free page table pages. last level pte should already be cleared */
+static void dma_pte_free_pagetable(struct dmar_domain *domain,
+       u64 start, u64 end)
+{
+       int addr_width = agaw_to_width(domain->agaw);
+       struct dma_pte *pte;
+       int total = agaw_to_level(domain->agaw);
+       int level;
+       u64 tmp;
+
+       start &= (((u64)1) << addr_width) - 1;
+       end &= (((u64)1) << addr_width) - 1;
+
+       /* we don't need lock here, nobody else touches the iova range */
+       level = 2;
+       while (level <= total) {
+               tmp = align_to_level(start, level);
+               if (tmp >= end || (tmp + level_size(level) > end))
+                       return;
+
+               while (tmp < end) {
+                       pte = dma_addr_level_pte(domain, tmp, level);
+                       if (pte) {
+                               free_pgtable_page(
+                                       phys_to_virt(dma_pte_addr(*pte)));
+                               dma_clear_pte(*pte);
+                               __iommu_flush_cache(domain->iommu,
+                                               pte, sizeof(*pte));
+                       }
+                       tmp += level_size(level);
+               }
+               level++;
+       }
+       /* free pgd */
+       if (start == 0 && end >= ((((u64)1) << addr_width) - 1)) {
+               free_pgtable_page(domain->pgd);
+               domain->pgd = NULL;
+       }
+}
+
+/* iommu handling */
+static int iommu_alloc_root_entry(struct intel_iommu *iommu)
+{
+       struct root_entry *root;
+       unsigned long flags;
+
+       root = (struct root_entry *)alloc_pgtable_page();
+       if (!root)
+               return -ENOMEM;
+
+       __iommu_flush_cache(iommu, root, PAGE_SIZE_4K);
+
+       spin_lock_irqsave(&iommu->lock, flags);
+       iommu->root_entry = root;
+       spin_unlock_irqrestore(&iommu->lock, flags);
+
+       return 0;
+}
+
+#define IOMMU_WAIT_OP(iommu, offset, op, cond, sts) \
+{\
+       unsigned long start_time = jiffies;\
+       while (1) {\
+               sts = op (iommu->reg + offset);\
+               if (cond)\
+                       break;\
+               if (time_after(jiffies, start_time + DMAR_OPERATION_TIMEOUT))\
+                       panic("DMAR hardware is malfunctioning\n");\
+               cpu_relax();\
+       }\
+}
+
+static void iommu_set_root_entry(struct intel_iommu *iommu)
+{
+       void *addr;
+       u32 cmd, sts;
+       unsigned long flag;
+
+       addr = iommu->root_entry;
+
+       spin_lock_irqsave(&iommu->register_lock, flag);
+       dmar_writeq(iommu->reg + DMAR_RTADDR_REG, virt_to_phys(addr));
+
+       cmd = iommu->gcmd | DMA_GCMD_SRTP;
+       writel(cmd, iommu->reg + DMAR_GCMD_REG);
+
+       /* Make sure hardware complete it */
+       IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
+               readl, (sts & DMA_GSTS_RTPS), sts);
+
+       spin_unlock_irqrestore(&iommu->register_lock, flag);
+}
+
+static void iommu_flush_write_buffer(struct intel_iommu *iommu)
+{
+       u32 val;
+       unsigned long flag;
+
+       if (!cap_rwbf(iommu->cap))
+               return;
+       val = iommu->gcmd | DMA_GCMD_WBF;
+
+       spin_lock_irqsave(&iommu->register_lock, flag);
+       writel(val, iommu->reg + DMAR_GCMD_REG);
+
+       /* Make sure hardware complete it */
+       IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
+                       readl, (!(val & DMA_GSTS_WBFS)), val);
+
+       spin_unlock_irqrestore(&iommu->register_lock, flag);
+}
+
+/* return value determine if we need a write buffer flush */
+static int __iommu_flush_context(struct intel_iommu *iommu,
+       u16 did, u16 source_id, u8 function_mask, u64 type,
+       int non_present_entry_flush)
+{
+       u64 val = 0;
+       unsigned long flag;
+
+       /*
+        * In the non-present entry flush case, if hardware doesn't cache
+        * non-present entry we do nothing and if hardware cache non-present
+        * entry, we flush entries of domain 0 (the domain id is used to cache
+        * any non-present entries)
+        */
+       if (non_present_entry_flush) {
+               if (!cap_caching_mode(iommu->cap))
+                       return 1;
+               else
+                       did = 0;
+       }
+
+       switch (type) {
+       case DMA_CCMD_GLOBAL_INVL:
+               val = DMA_CCMD_GLOBAL_INVL;
+               break;
+       case DMA_CCMD_DOMAIN_INVL:
+               val = DMA_CCMD_DOMAIN_INVL|DMA_CCMD_DID(did);
+               break;
+       case DMA_CCMD_DEVICE_INVL:
+               val = DMA_CCMD_DEVICE_INVL|DMA_CCMD_DID(did)
+                       | DMA_CCMD_SID(source_id) | DMA_CCMD_FM(function_mask);
+               break;
+       default:
+               BUG();
+       }
+       val |= DMA_CCMD_ICC;
+
+       spin_lock_irqsave(&iommu->register_lock, flag);
+       dmar_writeq(iommu->reg + DMAR_CCMD_REG, val);
+
+       /* Make sure hardware complete it */
+       IOMMU_WAIT_OP(iommu, DMAR_CCMD_REG,
+               dmar_readq, (!(val & DMA_CCMD_ICC)), val);
+
+       spin_unlock_irqrestore(&iommu->register_lock, flag);
+
+       /* flush context entry will implictly flush write buffer */
+       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,
+       int non_present_entry_flush)
+{
+       int tlb_offset = ecap_iotlb_offset(iommu->ecap);
+       u64 val = 0, val_iva = 0;
+       unsigned long flag;
+
+       /*
+        * In the non-present entry flush case, if hardware doesn't cache
+        * non-present entry we do nothing and if hardware cache non-present
+        * entry, we flush entries of domain 0 (the domain id is used to cache
+        * any non-present entries)
+        */
+       if (non_present_entry_flush) {
+               if (!cap_caching_mode(iommu->cap))
+                       return 1;
+               else
+                       did = 0;
+       }
+
+       switch (type) {
+       case DMA_TLB_GLOBAL_FLUSH:
+               /* global flush doesn't need set IVA_REG */
+               val = DMA_TLB_GLOBAL_FLUSH|DMA_TLB_IVT;
+               break;
+       case DMA_TLB_DSI_FLUSH:
+               val = DMA_TLB_DSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
+               break;
+       case DMA_TLB_PSI_FLUSH:
+               val = DMA_TLB_PSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
+               /* Note: always flush non-leaf currently */
+               val_iva = size_order | addr;
+               break;
+       default:
+               BUG();
+       }
+       /* Note: set drain read/write */
+#if 0
+       /*
+        * This is probably to be super secure.. Looks like we can
+        * ignore it without any impact.
+        */
+       if (cap_read_drain(iommu->cap))
+               val |= DMA_TLB_READ_DRAIN;
+#endif
+       if (cap_write_drain(iommu->cap))
+               val |= DMA_TLB_WRITE_DRAIN;
+
+       spin_lock_irqsave(&iommu->register_lock, flag);
+       /* Note: Only uses first TLB reg currently */
+       if (val_iva)
+               dmar_writeq(iommu->reg + tlb_offset, val_iva);
+       dmar_writeq(iommu->reg + tlb_offset + 8, val);
+
+       /* Make sure hardware complete it */
+       IOMMU_WAIT_OP(iommu, tlb_offset + 8,
+               dmar_readq, (!(val & DMA_TLB_IVT)), val);
+
+       spin_unlock_irqrestore(&iommu->register_lock, flag);
+
+       /* check IOTLB invalidation granularity */
+       if (DMA_TLB_IAIG(val) == 0)
+               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));
+       /* flush context entry will implictly 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(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);
+
+       /*
+        * PSI requires page size to be 2 ^ x, and the base address is naturally
+        * aligned to the size
+        */
+       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_iotlb(iommu, did, addr, mask,
+               DMA_TLB_PSI_FLUSH, non_present_entry_flush);
+}
+
+static int iommu_enable_translation(struct intel_iommu *iommu)
+{
+       u32 sts;
+       unsigned long flags;
+
+       spin_lock_irqsave(&iommu->register_lock, flags);
+       writel(iommu->gcmd|DMA_GCMD_TE, iommu->reg + DMAR_GCMD_REG);
+
+       /* Make sure hardware complete it */
+       IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
+               readl, (sts & DMA_GSTS_TES), sts);
+
+       iommu->gcmd |= DMA_GCMD_TE;
+       spin_unlock_irqrestore(&iommu->register_lock, flags);
+       return 0;
+}
+
+static int iommu_disable_translation(struct intel_iommu *iommu)
+{
+       u32 sts;
+       unsigned long flag;
+
+       spin_lock_irqsave(&iommu->register_lock, flag);
+       iommu->gcmd &= ~DMA_GCMD_TE;
+       writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
+
+       /* Make sure hardware complete it */
+       IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
+               readl, (!(sts & DMA_GSTS_TES)), sts);
+
+       spin_unlock_irqrestore(&iommu->register_lock, flag);
+       return 0;
+}
+
+/* iommu interrupt handling. Most stuff are MSI-like. */
+
+static char *fault_reason_strings[] =
+{
+       "Software",
+       "Present bit in root entry is clear",
+       "Present bit in context entry is clear",
+       "Invalid context entry",
+       "Access beyond MGAW",
+       "PTE Write access is not set",
+       "PTE Read access is not set",
+       "Next page table ptr is invalid",
+       "Root table address invalid",
+       "Context table ptr is invalid",
+       "non-zero reserved fields in RTP",
+       "non-zero reserved fields in CTP",
+       "non-zero reserved fields in PTE",
+       "Unknown"
+};
+#define MAX_FAULT_REASON_IDX   ARRAY_SIZE(fault_reason_strings)
+
+char *dmar_get_fault_reason(u8 fault_reason)
+{
+       if (fault_reason > MAX_FAULT_REASON_IDX)
+               return fault_reason_strings[MAX_FAULT_REASON_IDX];
+       else
+               return fault_reason_strings[fault_reason];
+}
+
+void dmar_msi_unmask(unsigned int irq)
+{
+       struct intel_iommu *iommu = get_irq_data(irq);
+       unsigned long flag;
+
+       /* unmask it */
+       spin_lock_irqsave(&iommu->register_lock, flag);
+       writel(0, iommu->reg + DMAR_FECTL_REG);
+       /* Read a reg to force flush the post write */
+       readl(iommu->reg + DMAR_FECTL_REG);
+       spin_unlock_irqrestore(&iommu->register_lock, flag);
+}
+
+void dmar_msi_mask(unsigned int irq)
+{
+       unsigned long flag;
+       struct intel_iommu *iommu = get_irq_data(irq);
+
+       /* mask it */
+       spin_lock_irqsave(&iommu->register_lock, flag);
+       writel(DMA_FECTL_IM, iommu->reg + DMAR_FECTL_REG);
+       /* Read a reg to force flush the post write */
+       readl(iommu->reg + DMAR_FECTL_REG);
+       spin_unlock_irqrestore(&iommu->register_lock, flag);
+}
+
+void dmar_msi_write(int irq, struct msi_msg *msg)
+{
+       struct intel_iommu *iommu = get_irq_data(irq);
+       unsigned long flag;
+
+       spin_lock_irqsave(&iommu->register_lock, flag);
+       writel(msg->data, iommu->reg + DMAR_FEDATA_REG);
+       writel(msg->address_lo, iommu->reg + DMAR_FEADDR_REG);
+       writel(msg->address_hi, iommu->reg + DMAR_FEUADDR_REG);
+       spin_unlock_irqrestore(&iommu->register_lock, flag);
+}
+
+void dmar_msi_read(int irq, struct msi_msg *msg)
+{
+       struct intel_iommu *iommu = get_irq_data(irq);
+       unsigned long flag;
+
+       spin_lock_irqsave(&iommu->register_lock, flag);
+       msg->data = readl(iommu->reg + DMAR_FEDATA_REG);
+       msg->address_lo = readl(iommu->reg + DMAR_FEADDR_REG);
+       msg->address_hi = readl(iommu->reg + DMAR_FEUADDR_REG);
+       spin_unlock_irqrestore(&iommu->register_lock, flag);
+}
+
+static int iommu_page_fault_do_one(struct intel_iommu *iommu, int type,
+               u8 fault_reason, u16 source_id, u64 addr)
+{
+       char *reason;
+
+       reason = dmar_get_fault_reason(fault_reason);
+
+       printk(KERN_ERR
+               "DMAR:[%s] Request device [%02x:%02x.%d] "
+               "fault addr %llx \n"
+               "DMAR:[fault reason %02d] %s\n",
+               (type ? "DMA Read" : "DMA Write"),
+               (source_id >> 8), PCI_SLOT(source_id & 0xFF),
+               PCI_FUNC(source_id & 0xFF), addr, fault_reason, reason);
+       return 0;
+}
+
+#define PRIMARY_FAULT_REG_LEN (16)
+static irqreturn_t iommu_page_fault(int irq, void *dev_id)
+{
+       struct intel_iommu *iommu = dev_id;
+       int reg, fault_index;
+       u32 fault_status;
+       unsigned long flag;
+
+       spin_lock_irqsave(&iommu->register_lock, flag);
+       fault_status = readl(iommu->reg + DMAR_FSTS_REG);
+
+       /* TBD: ignore advanced fault log currently */
+       if (!(fault_status & DMA_FSTS_PPF))
+               goto clear_overflow;
+
+       fault_index = dma_fsts_fault_record_index(fault_status);
+       reg = cap_fault_reg_offset(iommu->cap);
+       while (1) {
+               u8 fault_reason;
+               u16 source_id;
+               u64 guest_addr;
+               int type;
+               u32 data;
+
+               /* highest 32 bits */
+               data = readl(iommu->reg + reg +
+                               fault_index * PRIMARY_FAULT_REG_LEN + 12);
+               if (!(data & DMA_FRCD_F))
+                       break;
+
+               fault_reason = dma_frcd_fault_reason(data);
+               type = dma_frcd_type(data);
+
+               data = readl(iommu->reg + reg +
+                               fault_index * PRIMARY_FAULT_REG_LEN + 8);
+               source_id = dma_frcd_source_id(data);
+
+               guest_addr = dmar_readq(iommu->reg + reg +
+                               fault_index * PRIMARY_FAULT_REG_LEN);
+               guest_addr = dma_frcd_page_addr(guest_addr);
+               /* clear the fault */
+               writel(DMA_FRCD_F, iommu->reg + reg +
+                       fault_index * PRIMARY_FAULT_REG_LEN + 12);
+
+               spin_unlock_irqrestore(&iommu->register_lock, flag);
+
+               iommu_page_fault_do_one(iommu, type, fault_reason,
+                               source_id, guest_addr);
+
+               fault_index++;
+               if (fault_index > cap_num_fault_regs(iommu->cap))
+                       fault_index = 0;
+               spin_lock_irqsave(&iommu->register_lock, flag);
+       }
+clear_overflow:
+       /* clear primary fault overflow */
+       fault_status = readl(iommu->reg + DMAR_FSTS_REG);
+       if (fault_status & DMA_FSTS_PFO)
+               writel(DMA_FSTS_PFO, iommu->reg + DMAR_FSTS_REG);
+
+       spin_unlock_irqrestore(&iommu->register_lock, flag);
+       return IRQ_HANDLED;
+}
+
+int dmar_set_interrupt(struct intel_iommu *iommu)
+{
+       int irq, ret;
+
+       irq = create_irq();
+       if (!irq) {
+               printk(KERN_ERR "IOMMU: no free vectors\n");
+               return -EINVAL;
+       }
+
+       set_irq_data(irq, iommu);
+       iommu->irq = irq;
+
+       ret = arch_setup_dmar_msi(irq);
+       if (ret) {
+               set_irq_data(irq, NULL);
+               iommu->irq = 0;
+               destroy_irq(irq);
+               return 0;
+       }
+
+       /* Force fault register is cleared */
+       iommu_page_fault(irq, iommu);
+
+       ret = request_irq(irq, iommu_page_fault, 0, iommu->name, iommu);
+       if (ret)
+               printk(KERN_ERR "IOMMU: can't request irq\n");
+       return ret;
+}
+
+static int iommu_init_domains(struct intel_iommu *iommu)
+{
+       unsigned long ndomains;
+       unsigned long nlongs;
+
+       ndomains = cap_ndoms(iommu->cap);
+       pr_debug("Number of Domains supportd <%ld>\n", ndomains);
+       nlongs = BITS_TO_LONGS(ndomains);
+
+       /* TBD: there might be 64K domains,
+        * consider other allocation for future chip
+        */
+       iommu->domain_ids = kcalloc(nlongs, sizeof(unsigned long), GFP_KERNEL);
+       if (!iommu->domain_ids) {
+               printk(KERN_ERR "Allocating domain id array failed\n");
+               return -ENOMEM;
+       }
+       iommu->domains = kcalloc(ndomains, sizeof(struct dmar_domain *),
+                       GFP_KERNEL);
+       if (!iommu->domains) {
+               printk(KERN_ERR "Allocating domain array failed\n");
+               kfree(iommu->domain_ids);
+               return -ENOMEM;
+       }
+
+       /*
+        * if Caching mode is set, then invalid translations are tagged
+        * with domainid 0. Hence we need to pre-allocate it.
+        */
+       if (cap_caching_mode(iommu->cap))
+               set_bit(0, iommu->domain_ids);
+       return 0;
+}
+
+static struct intel_iommu *alloc_iommu(struct dmar_drhd_unit *drhd)
+{
+       struct intel_iommu *iommu;
+       int ret;
+       int map_size;
+       u32 ver;
+
+       iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
+       if (!iommu)
+               return NULL;
+       iommu->reg = ioremap(drhd->reg_base_addr, PAGE_SIZE_4K);
+       if (!iommu->reg) {
+               printk(KERN_ERR "IOMMU: can't map the region\n");
+               goto error;
+       }
+       iommu->cap = dmar_readq(iommu->reg + DMAR_CAP_REG);
+       iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG);
+
+       /* 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) {
+               iounmap(iommu->reg);
+               iommu->reg = ioremap(drhd->reg_base_addr, map_size);
+               if (!iommu->reg) {
+                       printk(KERN_ERR "IOMMU: can't map the region\n");
+                       goto error;
+               }
+       }
+
+       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);
+       ret = iommu_init_domains(iommu);
+       if (ret)
+               goto error_unmap;
+       spin_lock_init(&iommu->lock);
+       spin_lock_init(&iommu->register_lock);
+
+       drhd->iommu = iommu;
+       return iommu;
+error_unmap:
+       iounmap(iommu->reg);
+       iommu->reg = 0;
+error:
+       kfree(iommu);
+       return NULL;
+}
+
+static void domain_exit(struct dmar_domain *domain);
+static void free_iommu(struct intel_iommu *iommu)
+{
+       struct dmar_domain *domain;
+       int i;
+
+       if (!iommu)
+               return;
+
+       i = find_first_bit(iommu->domain_ids, cap_ndoms(iommu->cap));
+       for (; i < cap_ndoms(iommu->cap); ) {
+               domain = iommu->domains[i];
+               clear_bit(i, iommu->domain_ids);
+               domain_exit(domain);
+               i = find_next_bit(iommu->domain_ids,
+                       cap_ndoms(iommu->cap), i+1);
+       }
+
+       if (iommu->gcmd & DMA_GCMD_TE)
+               iommu_disable_translation(iommu);
+
+       if (iommu->irq) {
+               set_irq_data(iommu->irq, NULL);
+               /* This will mask the irq */
+               free_irq(iommu->irq, iommu);
+               destroy_irq(iommu->irq);
+       }
+
+       kfree(iommu->domains);
+       kfree(iommu->domain_ids);
+
+       /* free context mapping */
+       free_context_table(iommu);
+
+       if (iommu->reg)
+               iounmap(iommu->reg);
+       kfree(iommu);
+}
+
+static struct dmar_domain * iommu_alloc_domain(struct intel_iommu *iommu)
+{
+       unsigned long num;
+       unsigned long ndomains;
+       struct dmar_domain *domain;
+       unsigned long flags;
+
+       domain = alloc_domain_mem();
+       if (!domain)
+               return NULL;
+
+       ndomains = cap_ndoms(iommu->cap);
+
+       spin_lock_irqsave(&iommu->lock, flags);
+       num = find_first_zero_bit(iommu->domain_ids, ndomains);
+       if (num >= ndomains) {
+               spin_unlock_irqrestore(&iommu->lock, flags);
+               free_domain_mem(domain);
+               printk(KERN_ERR "IOMMU: no free domain ids\n");
+               return NULL;
+       }
+
+       set_bit(num, iommu->domain_ids);
+       domain->id = num;
+       domain->iommu = iommu;
+       iommu->domains[num] = domain;
+       spin_unlock_irqrestore(&iommu->lock, flags);
+
+       return domain;
+}
+
+static void iommu_free_domain(struct dmar_domain *domain)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&domain->iommu->lock, flags);
+       clear_bit(domain->id, domain->iommu->domain_ids);
+       spin_unlock_irqrestore(&domain->iommu->lock, flags);
+}
+
+static struct iova_domain reserved_iova_list;
+
+static void dmar_init_reserved_ranges(void)
+{
+       struct pci_dev *pdev = NULL;
+       struct iova *iova;
+       int i;
+       u64 addr, size;
+
+       init_iova_domain(&reserved_iova_list);
+
+       /* IOAPIC ranges shouldn't be accessed by DMA */
+       iova = reserve_iova(&reserved_iova_list, IOVA_PFN(IOAPIC_RANGE_START),
+               IOVA_PFN(IOAPIC_RANGE_END));
+       if (!iova)
+               printk(KERN_ERR "Reserve IOAPIC range failed\n");
+
+       /* Reserve all PCI MMIO to avoid peer-to-peer access */
+       for_each_pci_dev(pdev) {
+               struct resource *r;
+
+               for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+                       r = &pdev->resource[i];
+                       if (!r->flags || !(r->flags & IORESOURCE_MEM))
+                               continue;
+                       addr = r->start;
+                       addr &= PAGE_MASK_4K;
+                       size = r->end - addr;
+                       size = PAGE_ALIGN_4K(size);
+                       iova = reserve_iova(&reserved_iova_list, IOVA_PFN(addr),
+                               IOVA_PFN(size + addr) - 1);
+                       if (!iova)
+                               printk(KERN_ERR "Reserve iova failed\n");
+               }
+       }
+
+}
+
+static void domain_reserve_special_ranges(struct dmar_domain *domain)
+{
+       copy_reserved_iova(&reserved_iova_list, &domain->iovad);
+}
+
+static inline int guestwidth_to_adjustwidth(int gaw)
+{
+       int agaw;
+       int r = (gaw - 12) % 9;
+
+       if (r == 0)
+               agaw = gaw;
+       else
+               agaw = gaw + 9 - r;
+       if (agaw > 64)
+               agaw = 64;
+       return agaw;
+}
+
+static int domain_init(struct dmar_domain *domain, int guest_width)
+{
+       struct intel_iommu *iommu;
+       int adjust_width, agaw;
+       unsigned long sagaw;
+
+       init_iova_domain(&domain->iovad);
+       spin_lock_init(&domain->mapping_lock);
+
+       domain_reserve_special_ranges(domain);
+
+       /* calculate AGAW */
+       iommu = domain->iommu;
+       if (guest_width > cap_mgaw(iommu->cap))
+               guest_width = cap_mgaw(iommu->cap);
+       domain->gaw = guest_width;
+       adjust_width = guestwidth_to_adjustwidth(guest_width);
+       agaw = width_to_agaw(adjust_width);
+       sagaw = cap_sagaw(iommu->cap);
+       if (!test_bit(agaw, &sagaw)) {
+               /* hardware doesn't support it, choose a bigger one */
+               pr_debug("IOMMU: hardware doesn't support agaw %d\n", agaw);
+               agaw = find_next_bit(&sagaw, 5, agaw);
+               if (agaw >= 5)
+                       return -ENODEV;
+       }
+       domain->agaw = agaw;
+       INIT_LIST_HEAD(&domain->devices);
+
+       /* always allocate the top pgd */
+       domain->pgd = (struct dma_pte *)alloc_pgtable_page();
+       if (!domain->pgd)
+               return -ENOMEM;
+       __iommu_flush_cache(iommu, domain->pgd, PAGE_SIZE_4K);
+       return 0;
+}
+
+static void domain_exit(struct dmar_domain *domain)
+{
+       u64 end;
+
+       /* Domain 0 is reserved, so dont process it */
+       if (!domain)
+               return;
+
+       domain_remove_dev_info(domain);
+       /* destroy iovas */
+       put_iova_domain(&domain->iovad);
+       end = DOMAIN_MAX_ADDR(domain->gaw);
+       end = end & (~PAGE_MASK_4K);
+
+       /* clear ptes */
+       dma_pte_clear_range(domain, 0, end);
+
+       /* free page tables */
+       dma_pte_free_pagetable(domain, 0, end);
+
+       iommu_free_domain(domain);
+       free_domain_mem(domain);
+}
+
+static int domain_context_mapping_one(struct dmar_domain *domain,
+               u8 bus, u8 devfn)
+{
+       struct context_entry *context;
+       struct intel_iommu *iommu = domain->iommu;
+       unsigned long flags;
+
+       pr_debug("Set context mapping for %02x:%02x.%d\n",
+               bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+       BUG_ON(!domain->pgd);
+       context = device_to_context_entry(iommu, bus, devfn);
+       if (!context)
+               return -ENOMEM;
+       spin_lock_irqsave(&iommu->lock, flags);
+       if (context_present(*context)) {
+               spin_unlock_irqrestore(&iommu->lock, flags);
+               return 0;
+       }
+
+       context_set_domain_id(*context, domain->id);
+       context_set_address_width(*context, domain->agaw);
+       context_set_address_root(*context, virt_to_phys(domain->pgd));
+       context_set_translation_type(*context, CONTEXT_TT_MULTI_LEVEL);
+       context_set_fault_enable(*context);
+       context_set_present(*context);
+       __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))
+               iommu_flush_write_buffer(iommu);
+       else
+               iommu_flush_iotlb_dsi(iommu, 0, 0);
+       spin_unlock_irqrestore(&iommu->lock, flags);
+       return 0;
+}
+
+static int
+domain_context_mapping(struct dmar_domain *domain, struct pci_dev *pdev)
+{
+       int ret;
+       struct pci_dev *tmp, *parent;
+
+       ret = domain_context_mapping_one(domain, pdev->bus->number,
+               pdev->devfn);
+       if (ret)
+               return ret;
+
+       /* dependent device mapping */
+       tmp = pci_find_upstream_pcie_bridge(pdev);
+       if (!tmp)
+               return 0;
+       /* Secondary interface's bus number and devfn 0 */
+       parent = pdev->bus->self;
+       while (parent != tmp) {
+               ret = domain_context_mapping_one(domain, parent->bus->number,
+                       parent->devfn);
+               if (ret)
+                       return ret;
+               parent = parent->bus->self;
+       }
+       if (tmp->is_pcie) /* this is a PCIE-to-PCI bridge */
+               return domain_context_mapping_one(domain,
+                       tmp->subordinate->number, 0);
+       else /* this is a legacy PCI bridge */
+               return domain_context_mapping_one(domain,
+                       tmp->bus->number, tmp->devfn);
+}
+
+static int domain_context_mapped(struct dmar_domain *domain,
+       struct pci_dev *pdev)
+{
+       int ret;
+       struct pci_dev *tmp, *parent;
+
+       ret = device_context_mapped(domain->iommu,
+               pdev->bus->number, pdev->devfn);
+       if (!ret)
+               return ret;
+       /* dependent device mapping */
+       tmp = pci_find_upstream_pcie_bridge(pdev);
+       if (!tmp)
+               return ret;
+       /* Secondary interface's bus number and devfn 0 */
+       parent = pdev->bus->self;
+       while (parent != tmp) {
+               ret = device_context_mapped(domain->iommu, parent->bus->number,
+                       parent->devfn);
+               if (!ret)
+                       return ret;
+               parent = parent->bus->self;
+       }
+       if (tmp->is_pcie)
+               return device_context_mapped(domain->iommu,
+                       tmp->subordinate->number, 0);
+       else
+               return device_context_mapped(domain->iommu,
+                       tmp->bus->number, tmp->devfn);
+}
+
+static int
+domain_page_mapping(struct dmar_domain *domain, dma_addr_t iova,
+                       u64 hpa, size_t size, int prot)
+{
+       u64 start_pfn, end_pfn;
+       struct dma_pte *pte;
+       int index;
+
+       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;
+       index = 0;
+       while (start_pfn < end_pfn) {
+               pte = addr_to_dma_pte(domain, iova + PAGE_SIZE_4K * 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_prot(*pte, prot);
+               __iommu_flush_cache(domain->iommu, pte, sizeof(*pte));
+               start_pfn++;
+               index++;
+       }
+       return 0;
+}
+
+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);
+}
+
+static void domain_remove_dev_info(struct dmar_domain *domain)
+{
+       struct device_domain_info *info;
+       unsigned long flags;
+
+       spin_lock_irqsave(&device_domain_lock, flags);
+       while (!list_empty(&domain->devices)) {
+               info = list_entry(domain->devices.next,
+                       struct device_domain_info, link);
+               list_del(&info->link);
+               list_del(&info->global);
+               if (info->dev)
+                       info->dev->dev.archdata.iommu = NULL;
+               spin_unlock_irqrestore(&device_domain_lock, flags);
+
+               detach_domain_for_dev(info->domain, info->bus, info->devfn);
+               free_devinfo_mem(info);
+
+               spin_lock_irqsave(&device_domain_lock, flags);
+       }
+       spin_unlock_irqrestore(&device_domain_lock, flags);
+}
+
+/*
+ * find_domain
+ * Note: we use struct pci_dev->dev.archdata.iommu stores the info
+ */
+struct dmar_domain *
+find_domain(struct pci_dev *pdev)
+{
+       struct device_domain_info *info;
+
+       /* No lock here, assumes no domain exit in normal case */
+       info = pdev->dev.archdata.iommu;
+       if (info)
+               return info->domain;
+       return NULL;
+}
+
+static int dmar_pci_device_match(struct pci_dev *devices[], int cnt,
+     struct pci_dev *dev)
+{
+       int index;
+
+       while (dev) {
+               for (index = 0; index < cnt; index ++)
+                       if (dev == devices[index])
+                               return 1;
+
+               /* Check our parent */
+               dev = dev->bus->self;
+       }
+
+       return 0;
+}
+
+static struct dmar_drhd_unit *
+dmar_find_matched_drhd_unit(struct pci_dev *dev)
+{
+       struct dmar_drhd_unit *drhd = NULL;
+
+       list_for_each_entry(drhd, &dmar_drhd_units, list) {
+               if (drhd->include_all || dmar_pci_device_match(drhd->devices,
+                                               drhd->devices_cnt, dev))
+                       return drhd;
+       }
+
+       return NULL;
+}
+
+/* domain is initialized */
+static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw)
+{
+       struct dmar_domain *domain, *found = NULL;
+       struct intel_iommu *iommu;
+       struct dmar_drhd_unit *drhd;
+       struct device_domain_info *info, *tmp;
+       struct pci_dev *dev_tmp;
+       unsigned long flags;
+       int bus = 0, devfn = 0;
+
+       domain = find_domain(pdev);
+       if (domain)
+               return domain;
+
+       dev_tmp = pci_find_upstream_pcie_bridge(pdev);
+       if (dev_tmp) {
+               if (dev_tmp->is_pcie) {
+                       bus = dev_tmp->subordinate->number;
+                       devfn = 0;
+               } else {
+                       bus = dev_tmp->bus->number;
+                       devfn = dev_tmp->devfn;
+               }
+               spin_lock_irqsave(&device_domain_lock, flags);
+               list_for_each_entry(info, &device_domain_list, global) {
+                       if (info->bus == bus && info->devfn == devfn) {
+                               found = info->domain;
+                               break;
+                       }
+               }
+               spin_unlock_irqrestore(&device_domain_lock, flags);
+               /* pcie-pci bridge already has a domain, uses it */
+               if (found) {
+                       domain = found;
+                       goto found_domain;
+               }
+       }
+
+       /* Allocate new domain for the device */
+       drhd = dmar_find_matched_drhd_unit(pdev);
+       if (!drhd) {
+               printk(KERN_ERR "IOMMU: can't find DMAR for device %s\n",
+                       pci_name(pdev));
+               return NULL;
+       }
+       iommu = drhd->iommu;
+
+       domain = iommu_alloc_domain(iommu);
+       if (!domain)
+               goto error;
+
+       if (domain_init(domain, gaw)) {
+               domain_exit(domain);
+               goto error;
+       }
+
+       /* register pcie-to-pci device */
+       if (dev_tmp) {
+               info = alloc_devinfo_mem();
+               if (!info) {
+                       domain_exit(domain);
+                       goto error;
+               }
+               info->bus = bus;
+               info->devfn = devfn;
+               info->dev = NULL;
+               info->domain = domain;
+               /* This domain is shared by devices under p2p bridge */
+               domain->flags |= DOMAIN_FLAG_MULTIPLE_DEVICES;
+
+               /* pcie-to-pci bridge already has a domain, uses it */
+               found = NULL;
+               spin_lock_irqsave(&device_domain_lock, flags);
+               list_for_each_entry(tmp, &device_domain_list, global) {
+                       if (tmp->bus == bus && tmp->devfn == devfn) {
+                               found = tmp->domain;
+                               break;
+                       }
+               }
+               if (found) {
+                       free_devinfo_mem(info);
+                       domain_exit(domain);
+                       domain = found;
+               } else {
+                       list_add(&info->link, &domain->devices);
+                       list_add(&info->global, &device_domain_list);
+               }
+               spin_unlock_irqrestore(&device_domain_lock, flags);
+       }
+
+found_domain:
+       info = alloc_devinfo_mem();
+       if (!info)
+               goto error;
+       info->bus = pdev->bus->number;
+       info->devfn = pdev->devfn;
+       info->dev = pdev;
+       info->domain = domain;
+       spin_lock_irqsave(&device_domain_lock, flags);
+       /* somebody is fast */
+       found = find_domain(pdev);
+       if (found != NULL) {
+               spin_unlock_irqrestore(&device_domain_lock, flags);
+               if (found != domain) {
+                       domain_exit(domain);
+                       domain = found;
+               }
+               free_devinfo_mem(info);
+               return domain;
+       }
+       list_add(&info->link, &domain->devices);
+       list_add(&info->global, &device_domain_list);
+       pdev->dev.archdata.iommu = info;
+       spin_unlock_irqrestore(&device_domain_lock, flags);
+       return domain;
+error:
+       /* recheck it here, maybe others set it */
+       return find_domain(pdev);
+}
+
+static int iommu_prepare_identity_map(struct pci_dev *pdev, u64 start, u64 end)
+{
+       struct dmar_domain *domain;
+       unsigned long size;
+       u64 base;
+       int ret;
+
+       printk(KERN_INFO
+               "IOMMU: Setting identity map for device %s [0x%Lx - 0x%Lx]\n",
+               pci_name(pdev), start, end);
+       /* page table init */
+       domain = get_domain_for_dev(pdev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
+       if (!domain)
+               return -ENOMEM;
+
+       /* The address might not be aligned */
+       base = start & PAGE_MASK_4K;
+       size = end - base;
+       size = PAGE_ALIGN_4K(size);
+       if (!reserve_iova(&domain->iovad, IOVA_PFN(base),
+                       IOVA_PFN(base + size) - 1)) {
+               printk(KERN_ERR "IOMMU: reserve iova failed\n");
+               ret = -ENOMEM;
+               goto error;
+       }
+
+       pr_debug("Mapping reserved region %lx@%llx for %s\n",
+               size, base, pci_name(pdev));
+       /*
+        * RMRR range might have overlap with physical memory range,
+        * clear it first
+        */
+       dma_pte_clear_range(domain, base, base + size);
+
+       ret = domain_page_mapping(domain, base, base, size,
+               DMA_PTE_READ|DMA_PTE_WRITE);
+       if (ret)
+               goto error;
+
+       /* context entry init */
+       ret = domain_context_mapping(domain, pdev);
+       if (!ret)
+               return 0;
+error:
+       domain_exit(domain);
+       return ret;
+
+}
+
+static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr,
+       struct pci_dev *pdev)
+{
+       if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
+               return 0;
+       return iommu_prepare_identity_map(pdev, rmrr->base_address,
+               rmrr->end_address + 1);
+}
+
+#ifdef CONFIG_DMAR_GFX_WA
+extern int arch_get_ram_range(int slot, u64 *addr, u64 *size);
+static void __init iommu_prepare_gfx_mapping(void)
+{
+       struct pci_dev *pdev = NULL;
+       u64 base, size;
+       int slot;
+       int ret;
+
+       for_each_pci_dev(pdev) {
+               if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO ||
+                               !IS_GFX_DEVICE(pdev))
+                       continue;
+               printk(KERN_INFO "IOMMU: gfx device %s 1-1 mapping\n",
+                       pci_name(pdev));
+               slot = arch_get_ram_range(0, &base, &size);
+               while (slot >= 0) {
+                       ret = iommu_prepare_identity_map(pdev,
+                                       base, base + size);
+                       if (ret)
+                               goto error;
+                       slot = arch_get_ram_range(slot, &base, &size);
+               }
+               continue;
+error:
+               printk(KERN_ERR "IOMMU: mapping reserved region failed\n");
+       }
+}
+#endif
+
+#ifdef CONFIG_DMAR_FLOPPY_WA
+static inline void iommu_prepare_isa(void)
+{
+       struct pci_dev *pdev;
+       int ret;
+
+       pdev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
+       if (!pdev)
+               return;
+
+       printk(KERN_INFO "IOMMU: Prepare 0-16M unity mapping for LPC\n");
+       ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024);
+
+       if (ret)
+               printk("IOMMU: Failed to create 0-64M identity map, "
+                       "floppy might not work\n");
+
+}
+#else
+static inline void iommu_prepare_isa(void)
+{
+       return;
+}
+#endif /* !CONFIG_DMAR_FLPY_WA */
+
+int __init init_dmars(void)
+{
+       struct dmar_drhd_unit *drhd;
+       struct dmar_rmrr_unit *rmrr;
+       struct pci_dev *pdev;
+       struct intel_iommu *iommu;
+       int ret, unit = 0;
+
+       /*
+        * for each drhd
+        *    allocate root
+        *    initialize and program root entry to not present
+        * endfor
+        */
+       for_each_drhd_unit(drhd) {
+               if (drhd->ignored)
+                       continue;
+               iommu = alloc_iommu(drhd);
+               if (!iommu) {
+                       ret = -ENOMEM;
+                       goto error;
+               }
+
+               /*
+                * TBD:
+                * we could share the same root & context tables
+                * amoung all IOMMU's. Need to Split it later.
+                */
+               ret = iommu_alloc_root_entry(iommu);
+               if (ret) {
+                       printk(KERN_ERR "IOMMU: allocate root entry failed\n");
+                       goto error;
+               }
+       }
+
+       /*
+        * For each rmrr
+        *   for each dev attached to rmrr
+        *   do
+        *     locate drhd for dev, alloc domain for dev
+        *     allocate free domain
+        *     allocate page table entries for rmrr
+        *     if context not allocated for bus
+        *           allocate and init context
+        *           set present in root table for this bus
+        *     init context with domain, translation etc
+        *    endfor
+        * endfor
+        */
+       for_each_rmrr_units(rmrr) {
+               int i;
+               for (i = 0; i < rmrr->devices_cnt; i++) {
+                       pdev = rmrr->devices[i];
+                       /* some BIOS lists non-exist devices in DMAR table */
+                       if (!pdev)
+                               continue;
+                       ret = iommu_prepare_rmrr_dev(rmrr, pdev);
+                       if (ret)
+                               printk(KERN_ERR
+                                "IOMMU: mapping reserved region failed\n");
+               }
+       }
+
+       iommu_prepare_gfx_mapping();
+
+       iommu_prepare_isa();
+
+       /*
+        * for each drhd
+        *   enable fault log
+        *   global invalidate context cache
+        *   global invalidate iotlb
+        *   enable translation
+        */
+       for_each_drhd_unit(drhd) {
+               if (drhd->ignored)
+                       continue;
+               iommu = drhd->iommu;
+               sprintf (iommu->name, "dmar%d", unit++);
+
+               iommu_flush_write_buffer(iommu);
+
+               ret = dmar_set_interrupt(iommu);
+               if (ret)
+                       goto error;
+
+               iommu_set_root_entry(iommu);
+
+               iommu_flush_context_global(iommu, 0);
+               iommu_flush_iotlb_global(iommu, 0);
+
+               ret = iommu_enable_translation(iommu);
+               if (ret)
+                       goto error;
+       }
+
+       return 0;
+error:
+       for_each_drhd_unit(drhd) {
+               if (drhd->ignored)
+                       continue;
+               iommu = drhd->iommu;
+               free_iommu(iommu);
+       }
+       return ret;
+}
+
+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);
+}
+
+struct iova *
+iommu_alloc_iova(struct dmar_domain *domain, size_t size, u64 end)
+{
+       struct iova *piova;
+
+       /* Make sure it's in range */
+       end = min_t(u64, DOMAIN_MAX_ADDR(domain->gaw), end);
+       if (!size || (IOVA_START_ADDR + size > end))
+               return NULL;
+
+       piova = alloc_iova(&domain->iovad,
+                       size >> PAGE_SHIFT_4K, IOVA_PFN(end), 1);
+       return piova;
+}
+
+static struct iova *
+__intel_alloc_iova(struct device *dev, struct dmar_domain *domain,
+               size_t size)
+{
+       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  {
+               /*
+                * First try to allocate an io virtual address in
+                * DMA_32BIT_MASK and if that fails then try allocating
+                * from higer range
+                */
+               iova = iommu_alloc_iova(domain, size, DMA_32BIT_MASK);
+               if (!iova)
+                       iova = iommu_alloc_iova(domain, size, pdev->dma_mask);
+       }
+
+       if (!iova) {
+               printk(KERN_ERR"Allocating iova for %s failed", pci_name(pdev));
+               return NULL;
+       }
+
+       return iova;
+}
+
+static struct dmar_domain *
+get_valid_domain_for_dev(struct pci_dev *pdev)
+{
+       struct dmar_domain *domain;
+       int ret;
+
+       domain = get_domain_for_dev(pdev,
+                       DEFAULT_DOMAIN_ADDRESS_WIDTH);
+       if (!domain) {
+               printk(KERN_ERR
+                       "Allocating domain for %s failed", pci_name(pdev));
+               return 0;
+       }
+
+       /* make sure context mapping is ok */
+       if (unlikely(!domain_context_mapped(domain, pdev))) {
+               ret = domain_context_mapping(domain, pdev);
+               if (ret) {
+                       printk(KERN_ERR
+                               "Domain context map for %s failed",
+                               pci_name(pdev));
+                       return 0;
+               }
+       }
+
+       return domain;
+}
+
+static dma_addr_t intel_map_single(struct device *hwdev, void *addr,
+       size_t size, int dir)
+{
+       struct pci_dev *pdev = to_pci_dev(hwdev);
+       int ret;
+       struct dmar_domain *domain;
+       unsigned long start_addr;
+       struct iova *iova;
+       int prot = 0;
+
+       BUG_ON(dir == DMA_NONE);
+       if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
+               return virt_to_bus(addr);
+
+       domain = get_valid_domain_for_dev(pdev);
+       if (!domain)
+               return 0;
+
+       addr = (void *)virt_to_phys(addr);
+       size = aligned_size((u64)addr, size);
+
+       iova = __intel_alloc_iova(hwdev, domain, size);
+       if (!iova)
+               goto error;
+
+       start_addr = iova->pfn_lo << PAGE_SHIFT_4K;
+
+       /*
+        * Check if DMAR supports zero-length reads on write only
+        * mappings..
+        */
+       if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
+                       !cap_zlr(domain->iommu->cap))
+               prot |= DMA_PTE_READ;
+       if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
+               prot |= DMA_PTE_WRITE;
+       /*
+        * addr - (addr + size) might be partial page, we should map the whole
+        * page.  Note: if two part of one page are separately mapped, we
+        * might have two guest_addr mapping to the same host addr, but this
+        * is not a big problem
+        */
+       ret = domain_page_mapping(domain, start_addr,
+               ((u64)addr) & PAGE_MASK_4K, size, prot);
+       if (ret)
+               goto error;
+
+       pr_debug("Device %s request: %lx@%llx mapping: %lx@%llx, dir %d\n",
+               pci_name(pdev), size, (u64)addr,
+               size, (u64)start_addr, dir);
+
+       /* it's a non-present to present mapping */
+       ret = iommu_flush_iotlb_psi(domain->iommu, domain->id,
+                       start_addr, size >> PAGE_SHIFT_4K, 1);
+       if (ret)
+               iommu_flush_write_buffer(domain->iommu);
+
+       return (start_addr + ((u64)addr & (~PAGE_MASK_4K)));
+
+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)addr, dir);
+       return 0;
+}
+
+static 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;
+       unsigned long start_addr;
+       struct iova *iova;
+
+       if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
+               return;
+       domain = find_domain(pdev);
+       BUG_ON(!domain);
+
+       iova = find_iova(&domain->iovad, IOVA_PFN(dev_addr));
+       if (!iova)
+               return;
+
+       start_addr = iova->pfn_lo << PAGE_SHIFT_4K;
+       size = aligned_size((u64)dev_addr, size);
+
+       pr_debug("Device %s unmapping: %lx@%llx\n",
+               pci_name(pdev), size, (u64)start_addr);
+
+       /*  clear the whole page */
+       dma_pte_clear_range(domain, start_addr, start_addr + size);
+       /* free page tables */
+       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))
+               iommu_flush_write_buffer(domain->iommu);
+
+       /* free iova */
+       __free_iova(&domain->iovad, iova);
+}
+
+static 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);
+       order = get_order(size);
+       flags &= ~(GFP_DMA | GFP_DMA32);
+
+       vaddr = (void *)__get_free_pages(flags, order);
+       if (!vaddr)
+               return NULL;
+       memset(vaddr, 0, size);
+
+       *dma_handle = intel_map_single(hwdev, vaddr, size, DMA_BIDIRECTIONAL);
+       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)
+{
+       int order;
+
+       size = PAGE_ALIGN_4K(size);
+       order = get_order(size);
+
+       intel_unmap_single(hwdev, dma_handle, size, DMA_BIDIRECTIONAL);
+       free_pages((unsigned long)vaddr, order);
+}
+
+#define SG_ENT_VIRT_ADDRESS(sg)        (sg_virt((sg)))
+static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
+       int nelems, int dir)
+{
+       int i;
+       struct pci_dev *pdev = to_pci_dev(hwdev);
+       struct dmar_domain *domain;
+       unsigned long start_addr;
+       struct iova *iova;
+       size_t size = 0;
+       void *addr;
+       struct scatterlist *sg;
+
+       if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
+               return;
+
+       domain = find_domain(pdev);
+
+       iova = find_iova(&domain->iovad, IOVA_PFN(sglist[0].dma_address));
+       if (!iova)
+               return;
+       for_each_sg(sglist, sg, nelems, i) {
+               addr = SG_ENT_VIRT_ADDRESS(sg);
+               size += aligned_size((u64)addr, sg->length);
+       }
+
+       start_addr = iova->pfn_lo << PAGE_SHIFT_4K;
+
+       /*  clear the whole page */
+       dma_pte_clear_range(domain, start_addr, start_addr + size);
+       /* free page tables */
+       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))
+               iommu_flush_write_buffer(domain->iommu);
+
+       /* free iova */
+       __free_iova(&domain->iovad, iova);
+}
+
+static int intel_nontranslate_map_sg(struct device *hddev,
+       struct scatterlist *sglist, int nelems, int dir)
+{
+       int i;
+       struct scatterlist *sg;
+
+       for_each_sg(sglist, sg, nelems, i) {
+               BUG_ON(!sg_page(sg));
+               sg->dma_address = virt_to_bus(SG_ENT_VIRT_ADDRESS(sg));
+               sg->dma_length = sg->length;
+       }
+       return nelems;
+}
+
+static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist,
+                               int nelems, int dir)
+{
+       void *addr;
+       int i;
+       struct pci_dev *pdev = to_pci_dev(hwdev);
+       struct dmar_domain *domain;
+       size_t size = 0;
+       int prot = 0;
+       size_t offset = 0;
+       struct iova *iova = NULL;
+       int ret;
+       struct scatterlist *sg;
+       unsigned long start_addr;
+
+       BUG_ON(dir == DMA_NONE);
+       if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
+               return intel_nontranslate_map_sg(hwdev, sglist, nelems, dir);
+
+       domain = get_valid_domain_for_dev(pdev);
+       if (!domain)
+               return 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);
+       }
+
+       iova = __intel_alloc_iova(hwdev, domain, size);
+       if (!iova) {
+               sglist->dma_length = 0;
+               return 0;
+       }
+
+       /*
+        * Check if DMAR supports zero-length reads on write only
+        * mappings..
+        */
+       if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
+                       !cap_zlr(domain->iommu->cap))
+               prot |= DMA_PTE_READ;
+       if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
+               prot |= DMA_PTE_WRITE;
+
+       start_addr = iova->pfn_lo << PAGE_SHIFT_4K;
+       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,
+                       size, prot);
+               if (ret) {
+                       /*  clear the page */
+                       dma_pte_clear_range(domain, start_addr,
+                                 start_addr + offset);
+                       /* free page tables */
+                       dma_pte_free_pagetable(domain, start_addr,
+                                 start_addr + offset);
+                       /* free iova */
+                       __free_iova(&domain->iovad, iova);
+                       return 0;
+               }
+               sg->dma_address = start_addr + offset +
+                               ((u64)addr & (~PAGE_MASK_4K));
+               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))
+               iommu_flush_write_buffer(domain->iommu);
+       return nelems;
+}
+
+static struct dma_mapping_ops intel_dma_ops = {
+       .alloc_coherent = intel_alloc_coherent,
+       .free_coherent = intel_free_coherent,
+       .map_single = intel_map_single,
+       .unmap_single = intel_unmap_single,
+       .map_sg = intel_map_sg,
+       .unmap_sg = intel_unmap_sg,
+};
+
+static inline int iommu_domain_cache_init(void)
+{
+       int ret = 0;
+
+       iommu_domain_cache = kmem_cache_create("iommu_domain",
+                                        sizeof(struct dmar_domain),
+                                        0,
+                                        SLAB_HWCACHE_ALIGN,
+
+                                        NULL);
+       if (!iommu_domain_cache) {
+               printk(KERN_ERR "Couldn't create iommu_domain cache\n");
+               ret = -ENOMEM;
+       }
+
+       return ret;
+}
+
+static inline int iommu_devinfo_cache_init(void)
+{
+       int ret = 0;
+
+       iommu_devinfo_cache = kmem_cache_create("iommu_devinfo",
+                                        sizeof(struct device_domain_info),
+                                        0,
+                                        SLAB_HWCACHE_ALIGN,
+
+                                        NULL);
+       if (!iommu_devinfo_cache) {
+               printk(KERN_ERR "Couldn't create devinfo cache\n");
+               ret = -ENOMEM;
+       }
+
+       return ret;
+}
+
+static inline int iommu_iova_cache_init(void)
+{
+       int ret = 0;
+
+       iommu_iova_cache = kmem_cache_create("iommu_iova",
+                                        sizeof(struct iova),
+                                        0,
+                                        SLAB_HWCACHE_ALIGN,
+
+                                        NULL);
+       if (!iommu_iova_cache) {
+               printk(KERN_ERR "Couldn't create iova cache\n");
+               ret = -ENOMEM;
+       }
+
+       return ret;
+}
+
+static int __init iommu_init_mempool(void)
+{
+       int ret;
+       ret = iommu_iova_cache_init();
+       if (ret)
+               return ret;
+
+       ret = iommu_domain_cache_init();
+       if (ret)
+               goto domain_error;
+
+       ret = iommu_devinfo_cache_init();
+       if (!ret)
+               return ret;
+
+       kmem_cache_destroy(iommu_domain_cache);
+domain_error:
+       kmem_cache_destroy(iommu_iova_cache);
+
+       return -ENOMEM;
+}
+
+static void __init iommu_exit_mempool(void)
+{
+       kmem_cache_destroy(iommu_devinfo_cache);
+       kmem_cache_destroy(iommu_domain_cache);
+       kmem_cache_destroy(iommu_iova_cache);
+
+}
+
+void __init detect_intel_iommu(void)
+{
+       if (swiotlb || no_iommu || iommu_detected || dmar_disabled)
+               return;
+       if (early_dmar_detect()) {
+               iommu_detected = 1;
+       }
+}
+
+static void __init init_no_remapping_devices(void)
+{
+       struct dmar_drhd_unit *drhd;
+
+       for_each_drhd_unit(drhd) {
+               if (!drhd->include_all) {
+                       int i;
+                       for (i = 0; i < drhd->devices_cnt; i++)
+                               if (drhd->devices[i] != NULL)
+                                       break;
+                       /* ignore DMAR unit if no pci devices exist */
+                       if (i == drhd->devices_cnt)
+                               drhd->ignored = 1;
+               }
+       }
+
+       if (dmar_map_gfx)
+               return;
+
+       for_each_drhd_unit(drhd) {
+               int i;
+               if (drhd->ignored || drhd->include_all)
+                       continue;
+
+               for (i = 0; i < drhd->devices_cnt; i++)
+                       if (drhd->devices[i] &&
+                               !IS_GFX_DEVICE(drhd->devices[i]))
+                               break;
+
+               if (i < drhd->devices_cnt)
+                       continue;
+
+               /* bypass IOMMU if it is just for gfx devices */
+               drhd->ignored = 1;
+               for (i = 0; i < drhd->devices_cnt; i++) {
+                       if (!drhd->devices[i])
+                               continue;
+                       drhd->devices[i]->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
+               }
+       }
+}
+
+int __init intel_iommu_init(void)
+{
+       int ret = 0;
+
+       if (no_iommu || swiotlb || dmar_disabled)
+               return -ENODEV;
+
+       if (dmar_table_init())
+               return  -ENODEV;
+
+       iommu_init_mempool();
+       dmar_init_reserved_ranges();
+
+       init_no_remapping_devices();
+
+       ret = init_dmars();
+       if (ret) {
+               printk(KERN_ERR "IOMMU: dmar init failed\n");
+               put_iova_domain(&reserved_iova_list);
+               iommu_exit_mempool();
+               return ret;
+       }
+       printk(KERN_INFO
+       "PCI-DMA: Intel(R) Virtualization Technology for Directed I/O\n");
+
+       force_iommu = 1;
+       dma_ops = &intel_dma_ops;
+       return 0;
+}
+
diff --git a/drivers/pci/intel-iommu.h b/drivers/pci/intel-iommu.h
new file mode 100644 (file)
index 0000000..ee88dd2
--- /dev/null
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Copyright (C) Ashok Raj <ashok.raj@intel.com>
+ * Copyright (C) Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ */
+
+#ifndef _INTEL_IOMMU_H_
+#define _INTEL_IOMMU_H_
+
+#include <linux/types.h>
+#include <linux/msi.h>
+#include "iova.h"
+#include <linux/io.h>
+
+/*
+ * Intel IOMMU register specification per version 1.0 public spec.
+ */
+
+#define        DMAR_VER_REG    0x0     /* Arch version supported by this IOMMU */
+#define        DMAR_CAP_REG    0x8     /* Hardware supported capabilities */
+#define        DMAR_ECAP_REG   0x10    /* Extended capabilities supported */
+#define        DMAR_GCMD_REG   0x18    /* Global command register */
+#define        DMAR_GSTS_REG   0x1c    /* Global status register */
+#define        DMAR_RTADDR_REG 0x20    /* Root entry table */
+#define        DMAR_CCMD_REG   0x28    /* Context command reg */
+#define        DMAR_FSTS_REG   0x34    /* Fault Status register */
+#define        DMAR_FECTL_REG  0x38    /* Fault control register */
+#define        DMAR_FEDATA_REG 0x3c    /* Fault event interrupt data register */
+#define        DMAR_FEADDR_REG 0x40    /* Fault event interrupt addr register */
+#define        DMAR_FEUADDR_REG 0x44   /* Upper address register */
+#define        DMAR_AFLOG_REG  0x58    /* Advanced Fault control */
+#define        DMAR_PMEN_REG   0x64    /* Enable Protected Memory Region */
+#define        DMAR_PLMBASE_REG 0x68   /* PMRR Low addr */
+#define        DMAR_PLMLIMIT_REG 0x6c  /* PMRR low limit */
+#define        DMAR_PHMBASE_REG 0x70   /* pmrr high base addr */
+#define        DMAR_PHMLIMIT_REG 0x78  /* pmrr high limit */
+
+#define OFFSET_STRIDE          (9)
+/*
+#define dmar_readl(dmar, reg) readl(dmar + reg)
+#define dmar_readq(dmar, reg) ({ \
+               u32 lo, hi; \
+               lo = readl(dmar + reg); \
+               hi = readl(dmar + reg + 4); \
+               (((u64) hi) << 32) + lo; })
+*/
+static inline u64 dmar_readq(void *addr)
+{
+       u32 lo, hi;
+       lo = readl(addr);
+       hi = readl(addr + 4);
+       return (((u64) hi) << 32) + lo;
+}
+
+static inline void dmar_writeq(void __iomem *addr, u64 val)
+{
+       writel((u32)val, addr);
+       writel((u32)(val >> 32), addr + 4);
+}
+
+#define DMAR_VER_MAJOR(v)              (((v) & 0xf0) >> 4)
+#define DMAR_VER_MINOR(v)              ((v) & 0x0f)
+
+/*
+ * Decoding Capability Register
+ */
+#define cap_read_drain(c)      (((c) >> 55) & 1)
+#define cap_write_drain(c)     (((c) >> 54) & 1)
+#define cap_max_amask_val(c)   (((c) >> 48) & 0x3f)
+#define cap_num_fault_regs(c)  ((((c) >> 40) & 0xff) + 1)
+#define cap_pgsel_inv(c)       (((c) >> 39) & 1)
+
+#define cap_super_page_val(c)  (((c) >> 34) & 0xf)
+#define cap_super_offset(c)    (((find_first_bit(&cap_super_page_val(c), 4)) \
+                                       * OFFSET_STRIDE) + 21)
+
+#define cap_fault_reg_offset(c)        ((((c) >> 24) & 0x3ff) * 16)
+#define cap_max_fault_reg_offset(c) \
+       (cap_fault_reg_offset(c) + cap_num_fault_regs(c) * 16)
+
+#define cap_zlr(c)             (((c) >> 22) & 1)
+#define cap_isoch(c)           (((c) >> 23) & 1)
+#define cap_mgaw(c)            ((((c) >> 16) & 0x3f) + 1)
+#define cap_sagaw(c)           (((c) >> 8) & 0x1f)
+#define cap_caching_mode(c)    (((c) >> 7) & 1)
+#define cap_phmr(c)            (((c) >> 6) & 1)
+#define cap_plmr(c)            (((c) >> 5) & 1)
+#define cap_rwbf(c)            (((c) >> 4) & 1)
+#define cap_afl(c)             (((c) >> 3) & 1)
+#define cap_ndoms(c)           (((unsigned long)1) << (4 + 2 * ((c) & 0x7)))
+/*
+ * Extended Capability Register
+ */
+
+#define ecap_niotlb_iunits(e)  ((((e) >> 24) & 0xff) + 1)
+#define ecap_iotlb_offset(e)   ((((e) >> 8) & 0x3ff) * 16)
+#define ecap_max_iotlb_offset(e) \
+       (ecap_iotlb_offset(e) + ecap_niotlb_iunits(e) * 16)
+#define ecap_coherent(e)       ((e) & 0x1)
+
+
+/* IOTLB_REG */
+#define DMA_TLB_GLOBAL_FLUSH (((u64)1) << 60)
+#define DMA_TLB_DSI_FLUSH (((u64)2) << 60)
+#define DMA_TLB_PSI_FLUSH (((u64)3) << 60)
+#define DMA_TLB_IIRG(type) ((type >> 60) & 7)
+#define DMA_TLB_IAIG(val) (((val) >> 57) & 7)
+#define DMA_TLB_READ_DRAIN (((u64)1) << 49)
+#define DMA_TLB_WRITE_DRAIN (((u64)1) << 48)
+#define DMA_TLB_DID(id)        (((u64)((id) & 0xffff)) << 32)
+#define DMA_TLB_IVT (((u64)1) << 63)
+#define DMA_TLB_IH_NONLEAF (((u64)1) << 6)
+#define DMA_TLB_MAX_SIZE (0x3f)
+
+/* GCMD_REG */
+#define DMA_GCMD_TE (((u32)1) << 31)
+#define DMA_GCMD_SRTP (((u32)1) << 30)
+#define DMA_GCMD_SFL (((u32)1) << 29)
+#define DMA_GCMD_EAFL (((u32)1) << 28)
+#define DMA_GCMD_WBF (((u32)1) << 27)
+
+/* GSTS_REG */
+#define DMA_GSTS_TES (((u32)1) << 31)
+#define DMA_GSTS_RTPS (((u32)1) << 30)
+#define DMA_GSTS_FLS (((u32)1) << 29)
+#define DMA_GSTS_AFLS (((u32)1) << 28)
+#define DMA_GSTS_WBFS (((u32)1) << 27)
+
+/* CCMD_REG */
+#define DMA_CCMD_ICC (((u64)1) << 63)
+#define DMA_CCMD_GLOBAL_INVL (((u64)1) << 61)
+#define DMA_CCMD_DOMAIN_INVL (((u64)2) << 61)
+#define DMA_CCMD_DEVICE_INVL (((u64)3) << 61)
+#define DMA_CCMD_FM(m) (((u64)((m) & 0x3)) << 32)
+#define DMA_CCMD_MASK_NOBIT 0
+#define DMA_CCMD_MASK_1BIT 1
+#define DMA_CCMD_MASK_2BIT 2
+#define DMA_CCMD_MASK_3BIT 3
+#define DMA_CCMD_SID(s) (((u64)((s) & 0xffff)) << 16)
+#define DMA_CCMD_DID(d) ((u64)((d) & 0xffff))
+
+/* FECTL_REG */
+#define DMA_FECTL_IM (((u32)1) << 31)
+
+/* FSTS_REG */
+#define DMA_FSTS_PPF ((u32)2)
+#define DMA_FSTS_PFO ((u32)1)
+#define dma_fsts_fault_record_index(s) (((s) >> 8) & 0xff)
+
+/* FRCD_REG, 32 bits access */
+#define DMA_FRCD_F (((u32)1) << 31)
+#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 */
+
+/*
+ * 0: Present
+ * 1-11: Reserved
+ * 12-63: Context Ptr (12 - (haw-1))
+ * 64-127: Reserved
+ */
+struct root_entry {
+       u64     val;
+       u64     rsvd1;
+};
+#define ROOT_ENTRY_NR (PAGE_SIZE_4K/sizeof(struct root_entry))
+static inline bool root_present(struct root_entry *root)
+{
+       return (root->val & 1);
+}
+static inline void set_root_present(struct root_entry *root)
+{
+       root->val |= 1;
+}
+static inline void set_root_value(struct root_entry *root, unsigned long value)
+{
+       root->val |= value & PAGE_MASK_4K;
+}
+
+struct context_entry;
+static inline struct context_entry *
+get_context_addr_from_root(struct root_entry *root)
+{
+       return (struct context_entry *)
+               (root_present(root)?phys_to_virt(
+               root->val & PAGE_MASK_4K):
+               NULL);
+}
+
+/*
+ * low 64 bits:
+ * 0: present
+ * 1: fault processing disable
+ * 2-3: translation type
+ * 12-63: address space root
+ * high 64 bits:
+ * 0-2: address width
+ * 3-6: aval
+ * 8-23: domain id
+ */
+struct context_entry {
+       u64 lo;
+       u64 hi;
+};
+#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_width(c) ((c).hi &  7)
+#define context_domain_id(c) (((c).hi >> 8) & ((1 << 16) - 1))
+
+#define context_set_present(c) do {(c).lo |= 1;} while (0)
+#define context_set_fault_enable(c) \
+       do {(c).lo &= (((u64)-1) << 2) | 1;} while (0)
+#define context_set_translation_type(c, val) \
+       do { \
+               (c).lo &= (((u64)-1) << 4) | 3; \
+               (c).lo |= ((val) & 3) << 2; \
+       } while (0)
+#define CONTEXT_TT_MULTI_LEVEL 0
+#define context_set_address_root(c, val) \
+       do {(c).lo |= (val) & PAGE_MASK_4K;} 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)
+#define context_clear_entry(c) do {(c).lo = 0; (c).hi = 0;} while (0)
+
+/*
+ * 0: readable
+ * 1: writable
+ * 2-6: reserved
+ * 7: super page
+ * 8-11: available
+ * 12-63: Host physcial address
+ */
+struct dma_pte {
+       u64 val;
+};
+#define dma_clear_pte(p)       do {(p).val = 0;} while (0)
+
+#define DMA_PTE_READ (1)
+#define DMA_PTE_WRITE (2)
+
+#define dma_set_pte_readable(p) do {(p).val |= DMA_PTE_READ;} while (0)
+#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_set_pte_addr(p, addr) do {\
+               (p).val |= ((addr) & PAGE_MASK_4K); } while (0)
+#define dma_pte_present(p) (((p).val & 3) != 0)
+
+struct intel_iommu;
+
+struct dmar_domain {
+       int     id;                     /* domain id */
+       struct intel_iommu *iommu;      /* back pointer to owning iommu */
+
+       struct list_head devices;       /* all devices' list */
+       struct iova_domain iovad;       /* iova's that belong to this domain */
+
+       struct dma_pte  *pgd;           /* virtual address */
+       spinlock_t      mapping_lock;   /* page table lock */
+       int             gaw;            /* max guest address width */
+
+       /* adjusted guest address width, 0 is level 2 30-bit */
+       int             agaw;
+
+#define DOMAIN_FLAG_MULTIPLE_DEVICES 1
+       int             flags;
+};
+
+/* PCI domain-device relationship */
+struct device_domain_info {
+       struct list_head link;  /* link to domain siblings */
+       struct list_head global; /* link to global list */
+       u8 bus;                 /* PCI bus numer */
+       u8 devfn;               /* PCI devfn number */
+       struct pci_dev *dev; /* it's NULL for PCIE-to-PCI bridge */
+       struct dmar_domain *domain; /* pointer to domain */
+};
+
+extern int init_dmars(void);
+
+struct intel_iommu {
+       void __iomem    *reg; /* Pointer to hardware regs, virtual addr */
+       u64             cap;
+       u64             ecap;
+       unsigned long   *domain_ids; /* bitmap of domains */
+       struct dmar_domain **domains; /* ptr to domains */
+       int             seg;
+       u32             gcmd; /* Holds TE, EAFL. Don't need SRTP, SFL, WBF */
+       spinlock_t      lock; /* protect context, domain ids */
+       spinlock_t      register_lock; /* protect register handling */
+       struct root_entry *root_entry; /* virtual address */
+
+       unsigned int irq;
+       unsigned char name[7];    /* Device Name */
+       struct msi_msg saved_msg;
+       struct sys_device sysdev;
+};
+
+#ifndef CONFIG_DMAR_GFX_WA
+static inline void iommu_prepare_gfx_mapping(void)
+{
+       return;
+}
+#endif /* !CONFIG_DMAR_GFX_WA */
+
+#endif
diff --git a/drivers/pci/iova.c b/drivers/pci/iova.c
new file mode 100644 (file)
index 0000000..a84571c
--- /dev/null
@@ -0,0 +1,394 @@
+/*
+ * Copyright (c) 2006, Intel Corporation.
+ *
+ * This file is released under the GPLv2.
+ *
+ * Copyright (C) 2006 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ */
+
+#include "iova.h"
+
+void
+init_iova_domain(struct iova_domain *iovad)
+{
+       spin_lock_init(&iovad->iova_alloc_lock);
+       spin_lock_init(&iovad->iova_rbtree_lock);
+       iovad->rbroot = RB_ROOT;
+       iovad->cached32_node = NULL;
+
+}
+
+static struct rb_node *
+__get_cached_rbnode(struct iova_domain *iovad, unsigned long *limit_pfn)
+{
+       if ((*limit_pfn != DMA_32BIT_PFN) ||
+               (iovad->cached32_node == NULL))
+               return rb_last(&iovad->rbroot);
+       else {
+               struct rb_node *prev_node = rb_prev(iovad->cached32_node);
+               struct iova *curr_iova =
+                       container_of(iovad->cached32_node, struct iova, node);
+               *limit_pfn = curr_iova->pfn_lo - 1;
+               return prev_node;
+       }
+}
+
+static void
+__cached_rbnode_insert_update(struct iova_domain *iovad,
+       unsigned long limit_pfn, struct iova *new)
+{
+       if (limit_pfn != DMA_32BIT_PFN)
+               return;
+       iovad->cached32_node = &new->node;
+}
+
+static void
+__cached_rbnode_delete_update(struct iova_domain *iovad, struct iova *free)
+{
+       struct iova *cached_iova;
+       struct rb_node *curr;
+
+       if (!iovad->cached32_node)
+               return;
+       curr = iovad->cached32_node;
+       cached_iova = container_of(curr, struct iova, node);
+
+       if (free->pfn_lo >= cached_iova->pfn_lo)
+               iovad->cached32_node = rb_next(&free->node);
+}
+
+/* Computes the padding size required, to make the
+ * the start address naturally aligned on its size
+ */
+static int
+iova_get_pad_size(int size, unsigned int limit_pfn)
+{
+       unsigned int pad_size = 0;
+       unsigned int order = ilog2(size);
+
+       if (order)
+               pad_size = (limit_pfn + 1) % (1 << order);
+
+       return pad_size;
+}
+
+static int __alloc_iova_range(struct iova_domain *iovad, unsigned long size,
+               unsigned long limit_pfn, struct iova *new, bool size_aligned)
+{
+       struct rb_node *curr = NULL;
+       unsigned long flags;
+       unsigned long saved_pfn;
+       unsigned int pad_size = 0;
+
+       /* Walk the tree backwards */
+       spin_lock_irqsave(&iovad->iova_rbtree_lock, flags);
+       saved_pfn = limit_pfn;
+       curr = __get_cached_rbnode(iovad, &limit_pfn);
+       while (curr) {
+               struct iova *curr_iova = container_of(curr, struct iova, node);
+               if (limit_pfn < curr_iova->pfn_lo)
+                       goto move_left;
+               else if (limit_pfn < curr_iova->pfn_hi)
+                       goto adjust_limit_pfn;
+               else {
+                       if (size_aligned)
+                               pad_size = iova_get_pad_size(size, limit_pfn);
+                       if ((curr_iova->pfn_hi + size + pad_size) <= limit_pfn)
+                               break;  /* found a free slot */
+               }
+adjust_limit_pfn:
+               limit_pfn = curr_iova->pfn_lo - 1;
+move_left:
+               curr = rb_prev(curr);
+       }
+
+       if (!curr) {
+               if (size_aligned)
+                       pad_size = iova_get_pad_size(size, limit_pfn);
+               if ((IOVA_START_PFN + size + pad_size) > limit_pfn) {
+                       spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags);
+                       return -ENOMEM;
+               }
+       }
+
+       /* pfn_lo will point to size aligned address if size_aligned is set */
+       new->pfn_lo = limit_pfn - (size + pad_size) + 1;
+       new->pfn_hi = new->pfn_lo + size - 1;
+
+       spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags);
+       return 0;
+}
+
+static void
+iova_insert_rbtree(struct rb_root *root, struct iova *iova)
+{
+       struct rb_node **new = &(root->rb_node), *parent = NULL;
+       /* Figure out where to put new node */
+       while (*new) {
+               struct iova *this = container_of(*new, struct iova, node);
+               parent = *new;
+
+               if (iova->pfn_lo < this->pfn_lo)
+                       new = &((*new)->rb_left);
+               else if (iova->pfn_lo > this->pfn_lo)
+                       new = &((*new)->rb_right);
+               else
+                       BUG(); /* this should not happen */
+       }
+       /* Add new node and rebalance tree. */
+       rb_link_node(&iova->node, parent, new);
+       rb_insert_color(&iova->node, root);
+}
+
+/**
+ * alloc_iova - allocates an iova
+ * @iovad - iova domain in question
+ * @size - size of page frames to allocate
+ * @limit_pfn - max limit address
+ * @size_aligned - set if size_aligned address range is required
+ * This function allocates an iova in the range limit_pfn to IOVA_START_PFN
+ * looking from limit_pfn instead from IOVA_START_PFN. If the size_aligned
+ * flag is set then the allocated address iova->pfn_lo will be naturally
+ * aligned on roundup_power_of_two(size).
+ */
+struct iova *
+alloc_iova(struct iova_domain *iovad, unsigned long size,
+       unsigned long limit_pfn,
+       bool size_aligned)
+{
+       unsigned long flags;
+       struct iova *new_iova;
+       int ret;
+
+       new_iova = alloc_iova_mem();
+       if (!new_iova)
+               return NULL;
+
+       /* If size aligned is set then round the size to
+        * to next power of two.
+        */
+       if (size_aligned)
+               size = __roundup_pow_of_two(size);
+
+       spin_lock_irqsave(&iovad->iova_alloc_lock, flags);
+       ret = __alloc_iova_range(iovad, size, limit_pfn, new_iova,
+                       size_aligned);
+
+       if (ret) {
+               spin_unlock_irqrestore(&iovad->iova_alloc_lock, flags);
+               free_iova_mem(new_iova);
+               return NULL;
+       }
+
+       /* Insert the new_iova into domain rbtree by holding writer lock */
+       spin_lock(&iovad->iova_rbtree_lock);
+       iova_insert_rbtree(&iovad->rbroot, new_iova);
+       __cached_rbnode_insert_update(iovad, limit_pfn, new_iova);
+       spin_unlock(&iovad->iova_rbtree_lock);
+
+       spin_unlock_irqrestore(&iovad->iova_alloc_lock, flags);
+
+       return new_iova;
+}
+
+/**
+ * find_iova - find's an iova for a given pfn
+ * @iovad - iova domain in question.
+ * pfn - page frame number
+ * This function finds and returns an iova belonging to the
+ * given doamin which matches the given pfn.
+ */
+struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn)
+{
+       unsigned long flags;
+       struct rb_node *node;
+
+       /* Take the lock so that no other thread is manipulating the rbtree */
+       spin_lock_irqsave(&iovad->iova_rbtree_lock, flags);
+       node = iovad->rbroot.rb_node;
+       while (node) {
+               struct iova *iova = container_of(node, struct iova, node);
+
+               /* If pfn falls within iova's range, return iova */
+               if ((pfn >= iova->pfn_lo) && (pfn <= iova->pfn_hi)) {
+                       spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags);
+                       /* We are not holding the lock while this iova
+                        * is referenced by the caller as the same thread
+                        * which called this function also calls __free_iova()
+                        * and it is by desing that only one thread can possibly
+                        * reference a particular iova and hence no conflict.
+                        */
+                       return iova;
+               }
+
+               if (pfn < iova->pfn_lo)
+                       node = node->rb_left;
+               else if (pfn > iova->pfn_lo)
+                       node = node->rb_right;
+       }
+
+       spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags);
+       return NULL;
+}
+
+/**
+ * __free_iova - frees the given iova
+ * @iovad: iova domain in question.
+ * @iova: iova in question.
+ * Frees the given iova belonging to the giving domain
+ */
+void
+__free_iova(struct iova_domain *iovad, struct iova *iova)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&iovad->iova_rbtree_lock, flags);
+       __cached_rbnode_delete_update(iovad, iova);
+       rb_erase(&iova->node, &iovad->rbroot);
+       spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags);
+       free_iova_mem(iova);
+}
+
+/**
+ * free_iova - finds and frees the iova for a given pfn
+ * @iovad: - iova domain in question.
+ * @pfn: - pfn that is allocated previously
+ * This functions finds an iova for a given pfn and then
+ * frees the iova from that domain.
+ */
+void
+free_iova(struct iova_domain *iovad, unsigned long pfn)
+{
+       struct iova *iova = find_iova(iovad, pfn);
+       if (iova)
+               __free_iova(iovad, iova);
+
+}
+
+/**
+ * put_iova_domain - destroys the iova doamin
+ * @iovad: - iova domain in question.
+ * All the iova's in that domain are destroyed.
+ */
+void put_iova_domain(struct iova_domain *iovad)
+{
+       struct rb_node *node;
+       unsigned long flags;
+
+       spin_lock_irqsave(&iovad->iova_rbtree_lock, flags);
+       node = rb_first(&iovad->rbroot);
+       while (node) {
+               struct iova *iova = container_of(node, struct iova, node);
+               rb_erase(node, &iovad->rbroot);
+               free_iova_mem(iova);
+               node = rb_first(&iovad->rbroot);
+       }
+       spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags);
+}
+
+static int
+__is_range_overlap(struct rb_node *node,
+       unsigned long pfn_lo, unsigned long pfn_hi)
+{
+       struct iova *iova = container_of(node, struct iova, node);
+
+       if ((pfn_lo <= iova->pfn_hi) && (pfn_hi >= iova->pfn_lo))
+               return 1;
+       return 0;
+}
+
+static struct iova *
+__insert_new_range(struct iova_domain *iovad,
+       unsigned long pfn_lo, unsigned long pfn_hi)
+{
+       struct iova *iova;
+
+       iova = alloc_iova_mem();
+       if (!iova)
+               return iova;
+
+       iova->pfn_hi = pfn_hi;
+       iova->pfn_lo = pfn_lo;
+       iova_insert_rbtree(&iovad->rbroot, iova);
+       return iova;
+}
+
+static void
+__adjust_overlap_range(struct iova *iova,
+       unsigned long *pfn_lo, unsigned long *pfn_hi)
+{
+       if (*pfn_lo < iova->pfn_lo)
+               iova->pfn_lo = *pfn_lo;
+       if (*pfn_hi > iova->pfn_hi)
+               *pfn_lo = iova->pfn_hi + 1;
+}
+
+/**
+ * reserve_iova - reserves an iova in the given range
+ * @iovad: - iova domain pointer
+ * @pfn_lo: - lower page frame address
+ * @pfn_hi:- higher pfn adderss
+ * This function allocates reserves the address range from pfn_lo to pfn_hi so
+ * that this address is not dished out as part of alloc_iova.
+ */
+struct iova *
+reserve_iova(struct iova_domain *iovad,
+       unsigned long pfn_lo, unsigned long pfn_hi)
+{
+       struct rb_node *node;
+       unsigned long flags;
+       struct iova *iova;
+       unsigned int overlap = 0;
+
+       spin_lock_irqsave(&iovad->iova_alloc_lock, flags);
+       spin_lock(&iovad->iova_rbtree_lock);
+       for (node = rb_first(&iovad->rbroot); node; node = rb_next(node)) {
+               if (__is_range_overlap(node, pfn_lo, pfn_hi)) {
+                       iova = container_of(node, struct iova, node);
+                       __adjust_overlap_range(iova, &pfn_lo, &pfn_hi);
+                       if ((pfn_lo >= iova->pfn_lo) &&
+                               (pfn_hi <= iova->pfn_hi))
+                               goto finish;
+                       overlap = 1;
+
+               } else if (overlap)
+                               break;
+       }
+
+       /* We are here either becasue this is the first reserver node
+        * or need to insert remaining non overlap addr range
+        */
+       iova = __insert_new_range(iovad, pfn_lo, pfn_hi);
+finish:
+
+       spin_unlock(&iovad->iova_rbtree_lock);
+       spin_unlock_irqrestore(&iovad->iova_alloc_lock, flags);
+       return iova;
+}
+
+/**
+ * copy_reserved_iova - copies the reserved between domains
+ * @from: - source doamin from where to copy
+ * @to: - destination domin where to copy
+ * This function copies reserved iova's from one doamin to
+ * other.
+ */
+void
+copy_reserved_iova(struct iova_domain *from, struct iova_domain *to)
+{
+       unsigned long flags;
+       struct rb_node *node;
+
+       spin_lock_irqsave(&from->iova_alloc_lock, flags);
+       spin_lock(&from->iova_rbtree_lock);
+       for (node = rb_first(&from->rbroot); node; node = rb_next(node)) {
+               struct iova *iova = container_of(node, struct iova, node);
+               struct iova *new_iova;
+               new_iova = reserve_iova(to, iova->pfn_lo, iova->pfn_hi);
+               if (!new_iova)
+                       printk(KERN_ERR "Reserve iova range %lx@%lx failed\n",
+                               iova->pfn_lo, iova->pfn_lo);
+       }
+       spin_unlock(&from->iova_rbtree_lock);
+       spin_unlock_irqrestore(&from->iova_alloc_lock, flags);
+}
diff --git a/drivers/pci/iova.h b/drivers/pci/iova.h
new file mode 100644 (file)
index 0000000..ae3028d
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2006, Intel Corporation.
+ *
+ * This file is released under the GPLv2.
+ *
+ * Copyright (C) 2006 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ *
+ */
+
+#ifndef _IOVA_H_
+#define _IOVA_H_
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/rbtree.h>
+#include <linux/dma-mapping.h>
+
+/*
+ * We need a fixed PAGE_SIZE of 4K irrespective of
+ * arch PAGE_SIZE for IOMMU page tables.
+ */
+#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)
+
+/* IO virtual address start page frame number */
+#define IOVA_START_PFN         (1)
+
+#define IOVA_PFN(addr)         ((addr) >> PAGE_SHIFT_4K)
+#define DMA_32BIT_PFN  IOVA_PFN(DMA_32BIT_MASK)
+#define DMA_64BIT_PFN  IOVA_PFN(DMA_64BIT_MASK)
+
+/* iova structure */
+struct iova {
+       struct rb_node  node;
+       unsigned long   pfn_hi; /* IOMMU dish out addr hi */
+       unsigned long   pfn_lo; /* IOMMU dish out addr lo */
+};
+
+/* holds all the iova translations for a domain */
+struct iova_domain {
+       spinlock_t      iova_alloc_lock;/* Lock to protect iova  allocation */
+       spinlock_t      iova_rbtree_lock; /* Lock to protect update of rbtree */
+       struct rb_root  rbroot;         /* iova domain rbtree root */
+       struct rb_node  *cached32_node; /* Save last alloced node */
+};
+
+struct iova *alloc_iova_mem(void);
+void free_iova_mem(struct iova *iova);
+void free_iova(struct iova_domain *iovad, unsigned long pfn);
+void __free_iova(struct iova_domain *iovad, struct iova *iova);
+struct iova *alloc_iova(struct iova_domain *iovad, unsigned long size,
+       unsigned long limit_pfn,
+       bool size_aligned);
+struct iova *reserve_iova(struct iova_domain *iovad, unsigned long pfn_lo,
+       unsigned long pfn_hi);
+void copy_reserved_iova(struct iova_domain *from, struct iova_domain *to);
+void init_iova_domain(struct iova_domain *iovad);
+struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn);
+void put_iova_domain(struct iova_domain *iovad);
+
+#endif
index 6fda33de84e85527f49b048db6889cd90815c75a..fc87e14b50de9a15b491ed800320fd9e01f6e7e5 100644 (file)
@@ -90,3 +90,4 @@ pci_match_one_device(const struct pci_device_id *id, const struct pci_dev *dev)
        return NULL;
 }
 
+struct pci_dev *pci_find_upstream_pcie_bridge(struct pci_dev *pdev);
index 5db6b6690b596bb4ff5079673731e67c2773780d..463a5a9d583d03747323285a18df00d5e46d717c 100644 (file)
@@ -837,6 +837,19 @@ static void pci_release_dev(struct device *dev)
        kfree(pci_dev);
 }
 
+static void set_pcie_port_type(struct pci_dev *pdev)
+{
+       int pos;
+       u16 reg16;
+
+       pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+       if (!pos)
+               return;
+       pdev->is_pcie = 1;
+       pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, &reg16);
+       pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4;
+}
+
 /**
  * pci_cfg_space_size - get the configuration space size of the PCI device.
  * @dev: PCI device
@@ -951,6 +964,7 @@ pci_scan_device(struct pci_bus *bus, int devfn)
        dev->device = (l >> 16) & 0xffff;
        dev->cfg_size = pci_cfg_space_size(dev);
        dev->error_state = pci_channel_io_normal;
+       set_pcie_port_type(dev);
 
        /* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
           set this higher, assuming the system even supports it.  */
index c6e79d01ce3d1a8e4f747a762f8e052712320102..b001b5922e3349088ac2e47b9ee3acb1d934a46e 100644 (file)
 #include "pci.h"
 
 DECLARE_RWSEM(pci_bus_sem);
+/*
+ * find the upstream PCIE-to-PCI bridge of a PCI device
+ * if the device is PCIE, return NULL
+ * if the device isn't connected to a PCIE bridge (that is its parent is a
+ * legacy PCI bridge and the bridge is directly connected to bus 0), return its
+ * parent
+ */
+struct pci_dev *
+pci_find_upstream_pcie_bridge(struct pci_dev *pdev)
+{
+       struct pci_dev *tmp = NULL;
+
+       if (pdev->is_pcie)
+               return NULL;
+       while (1) {
+               if (!pdev->bus->self)
+                       break;
+               pdev = pdev->bus->self;
+               /* a p2p bridge */
+               if (!pdev->is_pcie) {
+                       tmp = pdev;
+                       continue;
+               }
+               /* PCI device should connect to a PCIE bridge */
+               if (pdev->pcie_type != PCI_EXP_TYPE_PCI_BRIDGE) {
+                       /* Busted hardware? */
+                       WARN_ON_ONCE(1);
+                       return NULL;
+               }
+               return pdev;
+       }
+
+       return tmp;
+}
 
 static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr)
 {
index 67d28ee80f220bc4e119b1ac2ebe9639e2459c46..c5e0d89c3ecefecf09cc03e5558b4c0aff4ca315 100644 (file)
@@ -22,9 +22,9 @@
 #include <linux/workqueue.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/bitops.h>
 #include <asm/irq.h>
 #include <asm/io.h>
-#include <asm/bitops.h>
 #include <asm/system.h>
 #include <asm/addrspace.h>
 
index b01985498460f926d0f6e920d900b10fb1b59cb8..d182760f035b1e7f8fed9d516ec4d02bdf9baa0b 100644 (file)
@@ -48,9 +48,9 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/fsl_devices.h>
+#include <linux/bitops.h>
 
 #include <asm/io.h>
-#include <asm/bitops.h>
 #include <asm/system.h>
 #include <asm/time.h>
 #include <asm/mpc8xx.h>
index 39a90a6f0f803110964260d02a167c1256a6394e..bbf3ee10da04ad433027963d9831379827cb715f 100644 (file)
@@ -26,65 +26,124 @@ static struct power_supply *main_battery;
 static void find_main_battery(void)
 {
        struct device *dev;
-       struct power_supply *bat, *batm;
+       struct power_supply *bat = NULL;
+       struct power_supply *max_charge_bat = NULL;
+       struct power_supply *max_energy_bat = NULL;
        union power_supply_propval full;
        int max_charge = 0;
+       int max_energy = 0;
 
        main_battery = NULL;
-       batm = NULL;
+
        list_for_each_entry(dev, &power_supply_class->devices, node) {
                bat = dev_get_drvdata(dev);
-               /* If none of battery devices cantains 'use_for_apm' flag,
-                  choice one with maximum design charge */
-               if (!PSY_PROP(bat, CHARGE_FULL_DESIGN, &full)) {
+
+               if (bat->use_for_apm) {
+                       /* nice, we explicitly asked to report this battery. */
+                       main_battery = bat;
+                       return;
+               }
+
+               if (!PSY_PROP(bat, CHARGE_FULL_DESIGN, &full) ||
+                               !PSY_PROP(bat, CHARGE_FULL, &full)) {
                        if (full.intval > max_charge) {
-                               batm = bat;
+                               max_charge_bat = bat;
                                max_charge = full.intval;
                        }
+               } else if (!PSY_PROP(bat, ENERGY_FULL_DESIGN, &full) ||
+                               !PSY_PROP(bat, ENERGY_FULL, &full)) {
+                       if (full.intval > max_energy) {
+                               max_energy_bat = bat;
+                               max_energy = full.intval;
+                       }
                }
+       }
 
-               if (bat->use_for_apm)
-                       main_battery = bat;
+       if ((max_energy_bat && max_charge_bat) &&
+                       (max_energy_bat != max_charge_bat)) {
+               /* try guess battery with more capacity */
+               if (!PSY_PROP(max_charge_bat, VOLTAGE_MAX_DESIGN, &full)) {
+                       if (max_energy > max_charge * full.intval)
+                               main_battery = max_energy_bat;
+                       else
+                               main_battery = max_charge_bat;
+               } else if (!PSY_PROP(max_energy_bat, VOLTAGE_MAX_DESIGN,
+                                                                 &full)) {
+                       if (max_charge > max_energy / full.intval)
+                               main_battery = max_charge_bat;
+                       else
+                               main_battery = max_energy_bat;
+               } else {
+                       /* give up, choice any */
+                       main_battery = max_energy_bat;
+               }
+       } else if (max_charge_bat) {
+               main_battery = max_charge_bat;
+       } else if (max_energy_bat) {
+               main_battery = max_energy_bat;
+       } else {
+               /* give up, try the last if any */
+               main_battery = bat;
        }
-       if (!main_battery)
-               main_battery = batm;
 }
 
-static int calculate_time(int status)
+static int calculate_time(int status, int using_charge)
 {
-       union power_supply_propval charge_full, charge_empty;
-       union power_supply_propval charge, I;
+       union power_supply_propval full;
+       union power_supply_propval empty;
+       union power_supply_propval cur;
+       union power_supply_propval I;
+       enum power_supply_property full_prop;
+       enum power_supply_property full_design_prop;
+       enum power_supply_property empty_prop;
+       enum power_supply_property empty_design_prop;
+       enum power_supply_property cur_avg_prop;
+       enum power_supply_property cur_now_prop;
 
-       if (MPSY_PROP(CHARGE_FULL, &charge_full)) {
-               /* if battery can't report this property, use design value */
-               if (MPSY_PROP(CHARGE_FULL_DESIGN, &charge_full))
+       if (MPSY_PROP(CURRENT_AVG, &I)) {
+               /* if battery can't report average value, use momentary */
+               if (MPSY_PROP(CURRENT_NOW, &I))
                        return -1;
        }
 
-       if (MPSY_PROP(CHARGE_EMPTY, &charge_empty)) {
-               /* if battery can't report this property, use design value */
-               if (MPSY_PROP(CHARGE_EMPTY_DESIGN, &charge_empty))
-                       charge_empty.intval = 0;
+       if (using_charge) {
+               full_prop = POWER_SUPPLY_PROP_CHARGE_FULL;
+               full_design_prop = POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN;
+               empty_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY;
+               empty_design_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY;
+               cur_avg_prop = POWER_SUPPLY_PROP_CHARGE_AVG;
+               cur_now_prop = POWER_SUPPLY_PROP_CHARGE_NOW;
+       } else {
+               full_prop = POWER_SUPPLY_PROP_ENERGY_FULL;
+               full_design_prop = POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN;
+               empty_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY;
+               empty_design_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY;
+               cur_avg_prop = POWER_SUPPLY_PROP_ENERGY_AVG;
+               cur_now_prop = POWER_SUPPLY_PROP_ENERGY_NOW;
        }
 
-       if (MPSY_PROP(CHARGE_AVG, &charge)) {
-               /* if battery can't report average value, use momentary */
-               if (MPSY_PROP(CHARGE_NOW, &charge))
+       if (_MPSY_PROP(full_prop, &full)) {
+               /* if battery can't report this property, use design value */
+               if (_MPSY_PROP(full_design_prop, &full))
                        return -1;
        }
 
-       if (MPSY_PROP(CURRENT_AVG, &I)) {
+       if (_MPSY_PROP(empty_prop, &empty)) {
+               /* if battery can't report this property, use design value */
+               if (_MPSY_PROP(empty_design_prop, &empty))
+                       empty.intval = 0;
+       }
+
+       if (_MPSY_PROP(cur_avg_prop, &cur)) {
                /* if battery can't report average value, use momentary */
-               if (MPSY_PROP(CURRENT_NOW, &I))
+               if (_MPSY_PROP(cur_now_prop, &cur))
                        return -1;
        }
 
        if (status == POWER_SUPPLY_STATUS_CHARGING)
-               return ((charge.intval - charge_full.intval) * 60L) /
-                      I.intval;
+               return ((cur.intval - full.intval) * 60L) / I.intval;
        else
-               return -((charge.intval - charge_empty.intval) * 60L) /
-                       I.intval;
+               return -((cur.intval - empty.intval) * 60L) / I.intval;
 }
 
 static int calculate_capacity(int using_charge)
@@ -200,18 +259,22 @@ static void apm_battery_apm_get_power_status(struct apm_power_info *info)
        info->units = APM_UNITS_MINS;
 
        if (status.intval == POWER_SUPPLY_STATUS_CHARGING) {
-               if (MPSY_PROP(TIME_TO_FULL_AVG, &time_to_full)) {
-                       if (MPSY_PROP(TIME_TO_FULL_NOW, &time_to_full))
-                               info->time = calculate_time(status.intval);
-                       else
-                               info->time = time_to_full.intval / 60;
+               if (!MPSY_PROP(TIME_TO_FULL_AVG, &time_to_full) ||
+                               !MPSY_PROP(TIME_TO_FULL_NOW, &time_to_full)) {
+                       info->time = time_to_full.intval / 60;
+               } else {
+                       info->time = calculate_time(status.intval, 0);
+                       if (info->time == -1)
+                               info->time = calculate_time(status.intval, 1);
                }
        } else {
-               if (MPSY_PROP(TIME_TO_EMPTY_AVG, &time_to_empty)) {
-                       if (MPSY_PROP(TIME_TO_EMPTY_NOW, &time_to_empty))
-                               info->time = calculate_time(status.intval);
-                       else
-                               info->time = time_to_empty.intval / 60;
+               if (!MPSY_PROP(TIME_TO_EMPTY_AVG, &time_to_empty) ||
+                             !MPSY_PROP(TIME_TO_EMPTY_NOW, &time_to_empty)) {
+                       info->time = time_to_empty.intval / 60;
+               } else {
+                       info->time = calculate_time(status.intval, 0);
+                       if (info->time == -1)
+                               info->time = calculate_time(status.intval, 1);
                }
        }
 
index be7021ee3611d72350514c6a4551f155bd126f98..bdb9b7285b3d7b6b0afc744f3be084d01c1ca11b 100644 (file)
@@ -366,7 +366,7 @@ static int ds2760_battery_probe(struct platform_device *pdev)
 
        retval = power_supply_register(&pdev->dev, &di->bat);
        if (retval) {
-               dev_err(di->dev, "failed to register battery");
+               dev_err(di->dev, "failed to register battery\n");
                goto batt_failed;
        }
 
index 397f4ce849dc6afa7eddcd66379b627c34902c84..87b3493d88e5bea0f93b3fc0ef412bbb1232a722 100644 (file)
@@ -729,7 +729,7 @@ static void ps3av_monitor_info_dump(const struct ps3av_pkt_av_get_monitor_info *
 
 static const struct ps3av_monitor_quirk {
        const char *monitor_name;
-       u32 clear_60, clear_50, clear_vesa;
+       u32 clear_60;
 } ps3av_monitor_quirks[] = {
        {
                .monitor_name   = "DELL 2007WFP",
@@ -757,10 +757,6 @@ static void ps3av_fixup_monitor_info(struct ps3av_info_monitor *info)
                                quirk->monitor_name);
                        info->res_60.res_bits &= ~quirk->clear_60;
                        info->res_60.native &= ~quirk->clear_60;
-                       info->res_50.res_bits &= ~quirk->clear_50;
-                       info->res_50.native &= ~quirk->clear_50;
-                       info->res_vesa.res_bits &= ~quirk->clear_vesa;
-                       info->res_vesa.native &= ~quirk->clear_vesa;
                        break;
                }
        }
index 3a9824e3b251ff3a41fdcacbf8f75b3edc26cd93..55955f16ad919ad7fb6d5aeadbb4334733fa1e71 100644 (file)
@@ -66,7 +66,7 @@ static int ps3stor_probe_access(struct ps3_storage_device *dev)
        if (n > 1)
                dev_info(&dev->sbd.core,
                         "%s:%u: %lu accessible regions found. Only the first "
-                        "one will be used",
+                        "one will be used\n",
                         __func__, __LINE__, n);
        dev->region_idx = __ffs(dev->accessible_regions);
        dev_info(&dev->sbd.core,
index bea25a1391ee3adc0475be28aeb236c716eb1324..9dea585ef8064f656ebeed605dc834179206ee2c 100644 (file)
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/workqueue.h>
+#include <linux/bitops.h>
 #include <asm/ps3.h>
 
 #include <asm/firmware.h>
 #include <asm/lv1call.h>
-#include <asm/bitops.h>
 
 #include "vuart.h"
 
index 6420a90a4a92e87ce4ffa38c04080ef0c40f8d39..cbde770eb121062fcfa67f8dd562f827814cacc1 100644 (file)
@@ -240,7 +240,7 @@ config RTC_DRV_TWL92330
        depends on MENELAUS
        help
          If you say yes here you get support for the RTC on the
-         TWL92330 "Menelaus" power mangement chip, used with OMAP2
+         TWL92330 "Menelaus" power management chip, used with OMAP2
          platforms.  The support is integrated with the rest of
          the Menelaus driver; it's not separate module.
 
index e4bf68ca96f7b2b237888f0a32b7f1b3fc86b449..2fd49edcc712117a0da38adfa60268595d00fd4e 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/string.h>
 #include <linux/pm.h>
+#include <linux/bitops.h>
 
 #include <linux/amba/bus.h>
 
 #include <asm/io.h>
-#include <asm/bitops.h>
 #include <asm/hardware.h>
 #include <asm/irq.h>
 #include <asm/rtc.h>
index 0918b787c4dd033671a0bd1902594b1ae858b653..6f1e9a9804bc9a7b0edbee3e83c256d5c1572e07 100644 (file)
@@ -29,8 +29,8 @@
 #include <linux/interrupt.h>
 #include <linux/string.h>
 #include <linux/pm.h>
+#include <linux/bitops.h>
 
-#include <asm/bitops.h>
 #include <asm/hardware.h>
 #include <asm/irq.h>
 #include <asm/rtc.h>
index 6cad0841f3c4d8719ab56e322a2fb82eb6fb89c7..2ae0e8304d3aa83bd7f75cdd6052b4394ba31a8b 100644 (file)
@@ -200,9 +200,8 @@ void rtc_sysfs_add_device(struct rtc_device *rtc)
 
        err = device_create_file(&rtc->dev, &dev_attr_wakealarm);
        if (err)
-               dev_err(rtc->dev.parent, "failed to create "
-                               "alarm attribute, %d",
-                               err);
+               dev_err(rtc->dev.parent,
+                       "failed to create alarm attribute, %d\n", err);
 }
 
 void rtc_sysfs_del_device(struct rtc_device *rtc)
index 8b9d68f6e016f6f92c3d34a54aba4f6bc4a4e568..5b7385e430ea6b64c6970ec4bf275a89a8bb3285 100644 (file)
@@ -40,7 +40,7 @@ struct DCTL_data {
  *
  *   Each bit configuration leading to an action code 2 (Exit with
  *   programming error or unusual condition indication)
- *   are handled as fatal error´s.
+ *   are handled as fatal errors.
  *
  *   All other configurations are handled as recoverable errors.
  *
@@ -2001,7 +2001,7 @@ dasd_3990_erp_compound_code(struct dasd_ccw_req * erp, char *sense)
                switch (sense[28]) {
                case 0x17:
                        /* issue a Diagnostic Control command with an
-                        * Inhibit Write subcommand and controler modifier */
+                        * Inhibit Write subcommand and controller modifier */
                        erp = dasd_3990_erp_DCTL(erp, 0x20);
                        break;
 
index 2edd5fb6d3dc1e8a4894e0ff5c8557ccdf2de838..8d1c64a24deccd7921c9ecb2e49b68cd9bcce6fb 100644 (file)
@@ -48,8 +48,8 @@ struct raw3270 {
        struct timer_list timer;        /* Device timer. */
 
        unsigned char *ascebc;          /* ascii -> ebcdic table */
-       struct class_device *clttydev;  /* 3270-class tty device ptr */
-       struct class_device *cltubdev;  /* 3270-class tub device ptr */
+       struct device *clttydev;        /* 3270-class tty device ptr */
+       struct device *cltubdev;        /* 3270-class tub device ptr */
 
        struct raw3270_request init_request;
        unsigned char init_data[256];
@@ -1107,11 +1107,9 @@ raw3270_delete_device(struct raw3270 *rp)
        /* Remove from device chain. */
        mutex_lock(&raw3270_mutex);
        if (rp->clttydev && !IS_ERR(rp->clttydev))
-               class_device_destroy(class3270,
-                                    MKDEV(IBM_TTY3270_MAJOR, rp->minor));
+               device_destroy(class3270, MKDEV(IBM_TTY3270_MAJOR, rp->minor));
        if (rp->cltubdev && !IS_ERR(rp->cltubdev))
-               class_device_destroy(class3270,
-                                    MKDEV(IBM_FS3270_MAJOR, rp->minor));
+               device_destroy(class3270, MKDEV(IBM_FS3270_MAJOR, rp->minor));
        list_del_init(&rp->list);
        mutex_unlock(&raw3270_mutex);
 
@@ -1181,24 +1179,22 @@ static int raw3270_create_attributes(struct raw3270 *rp)
        if (rc)
                goto out;
 
-       rp->clttydev = class_device_create(class3270, NULL,
-                                          MKDEV(IBM_TTY3270_MAJOR, rp->minor),
-                                          &rp->cdev->dev, "tty%s",
-                                          rp->cdev->dev.bus_id);
+       rp->clttydev = device_create(class3270, &rp->cdev->dev,
+                                    MKDEV(IBM_TTY3270_MAJOR, rp->minor),
+                                    "tty%s", rp->cdev->dev.bus_id);
        if (IS_ERR(rp->clttydev)) {
                rc = PTR_ERR(rp->clttydev);
                goto out_ttydev;
        }
 
-       rp->cltubdev = class_device_create(class3270, NULL,
-                                          MKDEV(IBM_FS3270_MAJOR, rp->minor),
-                                          &rp->cdev->dev, "tub%s",
-                                          rp->cdev->dev.bus_id);
+       rp->cltubdev = device_create(class3270, &rp->cdev->dev,
+                                    MKDEV(IBM_FS3270_MAJOR, rp->minor),
+                                    "tub%s", rp->cdev->dev.bus_id);
        if (!IS_ERR(rp->cltubdev))
                goto out;
 
        rc = PTR_ERR(rp->cltubdev);
-       class_device_destroy(class3270, MKDEV(IBM_TTY3270_MAJOR, rp->minor));
+       device_destroy(class3270, MKDEV(IBM_TTY3270_MAJOR, rp->minor));
 
 out_ttydev:
        sysfs_remove_group(&rp->cdev->dev.kobj, &raw3270_attr_group);
index 29fe2a5ec2fe4d3255be3848a63bba58d0b81cc7..82a13d9fdfe44d6091b4e63724c72161d7d20aa6 100644 (file)
@@ -157,7 +157,7 @@ cpi_prepare_req(void)
        sclp_ascebc_str(evb->system_name, CPI_LENGTH_SYSTEM_NAME);
        EBC_TOUPPER(evb->system_name, CPI_LENGTH_SYSTEM_NAME);
 
-       /* set sytem level */
+       /* set system level */
        evb->system_level = LINUX_VERSION_CODE;
 
        /* set sysplex name */
index 2e0d29730b67590639f8e0dba84b48ae90ebd5b5..aa7f166f40340dd4c77a99cf9e86428e174ca2d2 100644 (file)
@@ -69,12 +69,9 @@ struct tape_class_device *register_tape_dev(
        if (rc)
                goto fail_with_cdev;
 
-       tcd->class_device = class_device_create(
-                               tape_class,
-                               NULL,
-                               tcd->char_device->dev,
-                               device,
-                               "%s", tcd->device_name
+       tcd->class_device = device_create(tape_class, device,
+                                         tcd->char_device->dev,
+                                         "%s", tcd->device_name
                        );
        rc = IS_ERR(tcd->class_device) ? PTR_ERR(tcd->class_device) : 0;
        if (rc)
@@ -90,7 +87,7 @@ struct tape_class_device *register_tape_dev(
        return tcd;
 
 fail_with_class_device:
-       class_device_destroy(tape_class, tcd->char_device->dev);
+       device_destroy(tape_class, tcd->char_device->dev);
 
 fail_with_cdev:
        cdev_del(tcd->char_device);
@@ -105,11 +102,9 @@ EXPORT_SYMBOL(register_tape_dev);
 void unregister_tape_dev(struct tape_class_device *tcd)
 {
        if (tcd != NULL && !IS_ERR(tcd)) {
-               sysfs_remove_link(
-                       &tcd->class_device->dev->kobj,
-                       tcd->mode_name
-               );
-               class_device_destroy(tape_class, tcd->char_device->dev);
+               sysfs_remove_link(&tcd->class_device->kobj,
+                                 tcd->mode_name);
+               device_destroy(tape_class, tcd->char_device->dev);
                cdev_del(tcd->char_device);
                kfree(tcd);
        }
index a8bd9b47fad62ac022aa9a88517b5b65f917a8ca..e2b5ac918acf6e987cc3d8c06aa271c540f32bbf 100644 (file)
@@ -24,8 +24,8 @@
 #define TAPECLASS_NAME_LEN     32
 
 struct tape_class_device {
-       struct cdev *           char_device;
-       struct class_device *   class_device;
+       struct cdev             *char_device;
+       struct device           *class_device;
        char                    device_name[TAPECLASS_NAME_LEN];
        char                    mode_name[TAPECLASS_NAME_LEN];
 };
index 12f7a4ce82c121b7500b6cb20675e25392a72fe4..e0c4c508e12181b813b51a3926396be5a46e85c9 100644 (file)
@@ -74,7 +74,7 @@ struct vmlogrdr_priv_t {
        int dev_in_use; /* 1: already opened, 0: not opened*/
        spinlock_t priv_lock;
        struct device  *device;
-       struct class_device  *class_device;
+       struct device  *class_device;
        int autorecording;
        int autopurge;
 };
@@ -762,12 +762,10 @@ static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv)
                device_unregister(dev);
                return ret;
        }
-       priv->class_device = class_device_create(
-                               vmlogrdr_class,
-                               NULL,
-                               MKDEV(vmlogrdr_major, priv->minor_num),
-                               dev,
-                               "%s", dev->bus_id );
+       priv->class_device = device_create(vmlogrdr_class, dev,
+                                          MKDEV(vmlogrdr_major,
+                                                priv->minor_num),
+                                          "%s", dev->bus_id);
        if (IS_ERR(priv->class_device)) {
                ret = PTR_ERR(priv->class_device);
                priv->class_device=NULL;
@@ -783,8 +781,7 @@ static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv)
 
 static int vmlogrdr_unregister_device(struct vmlogrdr_priv_t *priv)
 {
-       class_device_destroy(vmlogrdr_class,
-                            MKDEV(vmlogrdr_major, priv->minor_num));
+       device_destroy(vmlogrdr_class, MKDEV(vmlogrdr_major, priv->minor_num));
        if (priv->device != NULL) {
                sysfs_remove_group(&priv->device->kobj, &vmlogrdr_attr_group);
                device_unregister(priv->device);
index 42c1f4659adb41d605557f7cb254937e15781d08..297cdceb0ca4ba7276c57fbb8634bf6cb15f1eb9 100644 (file)
@@ -246,7 +246,7 @@ int chp_add_cmg_attr(struct channel_path *chp)
 static ssize_t chp_status_show(struct device *dev,
                               struct device_attribute *attr, char *buf)
 {
-       struct channel_path *chp = container_of(dev, struct channel_path, dev);
+       struct channel_path *chp = to_channelpath(dev);
 
        if (!chp)
                return 0;
@@ -258,7 +258,7 @@ static ssize_t chp_status_write(struct device *dev,
                                struct device_attribute *attr,
                                const char *buf, size_t count)
 {
-       struct channel_path *cp = container_of(dev, struct channel_path, dev);
+       struct channel_path *cp = to_channelpath(dev);
        char cmd[10];
        int num_args;
        int error;
@@ -286,7 +286,7 @@ static ssize_t chp_configure_show(struct device *dev,
        struct channel_path *cp;
        int status;
 
-       cp = container_of(dev, struct channel_path, dev);
+       cp = to_channelpath(dev);
        status = chp_info_get_status(cp->chpid);
        if (status < 0)
                return status;
@@ -308,7 +308,7 @@ static ssize_t chp_configure_write(struct device *dev,
                return -EINVAL;
        if (val != 0 && val != 1)
                return -EINVAL;
-       cp = container_of(dev, struct channel_path, dev);
+       cp = to_channelpath(dev);
        chp_cfg_schedule(cp->chpid, val);
        cfg_wait_idle();
 
@@ -320,7 +320,7 @@ static DEVICE_ATTR(configure, 0644, chp_configure_show, chp_configure_write);
 static ssize_t chp_type_show(struct device *dev, struct device_attribute *attr,
                             char *buf)
 {
-       struct channel_path *chp = container_of(dev, struct channel_path, dev);
+       struct channel_path *chp = to_channelpath(dev);
 
        if (!chp)
                return 0;
@@ -374,7 +374,7 @@ static void chp_release(struct device *dev)
 {
        struct channel_path *cp;
 
-       cp = container_of(dev, struct channel_path, dev);
+       cp = to_channelpath(dev);
        kfree(cp);
 }
 
index b960f66843e4919e1645806258368763fcaeec84..725b0dd142699f0f613aece0341cb67af9036867 100644 (file)
@@ -158,7 +158,7 @@ static inline u64 time_to_avg_nsec(u32 value, u32 count)
        if (count == 0)
                return 0;
 
-       /* value comes in units of 128 µsec */
+       /* value comes in units of 128 Âµsec */
        ret = time_to_nsec(value);
        do_div(ret, count);
 
index 5d83dd471461a6b13124348709cca88e191eb6e6..838f7ac0dc32420bc258e067c5283a8177406963 100644 (file)
@@ -182,6 +182,15 @@ static int css_register_subchannel(struct subchannel *sch)
        sch->dev.bus = &css_bus_type;
        sch->dev.release = &css_subchannel_release;
        sch->dev.groups = subch_attr_groups;
+       /*
+        * We don't want to generate uevents for I/O subchannels that don't
+        * have a working ccw device behind them since they will be
+        * unregistered before they can be used anyway, so we delay the add
+        * uevent until after device recognition was successful.
+        */
+       if (!cio_is_console(sch->schid))
+               /* Console is special, no need to suppress. */
+               sch->dev.uevent_suppress = 1;
        css_update_ssd_info(sch);
        /* make it known to the system */
        ret = css_sch_device_register(sch);
index 16ea828e99f7a0b39228cda81f78247348e01966..ef7bc0a125efde63b0c06dd7fb64ce52d9ec5a92 100644 (file)
@@ -6,7 +6,7 @@
  */
 
 #include <linux/slab.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 #include "idset.h"
 #include "css.h"
 
index 399695f7b1af147e083d60026bb49a6f11bd2389..3561982749e36d943d927c80227215cf838285d0 100644 (file)
  *    1.15  Changed for 2.6 Kernel  No longer compiles on 2.4 or lower
  *    1.25  Added Packing support
  */
-#include <asm/bitops.h>
 #include <asm/ccwdev.h>
 #include <asm/ccwgroup.h>
 #include <asm/debug.h>
 #include <asm/idals.h>
 #include <asm/io.h>
 
+#include <linux/bitops.h>
 #include <linux/ctype.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
index 449937233732b5b7a054565de71e1c4cd565ead9..6bf3ebbe985a9a000d92fbe449ab5eb073cc03fc 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
  * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)
- * Fixes by : Jochen Röhrig (roehrig@de.ibm.com)
+ * Fixes by : Jochen Röhrig (roehrig@de.ibm.com)
  *            Arnaldo Carvalho de Melo <acme@conectiva.com.br>
              Peter Tiedemann (ptiedem@de.ibm.com)
  * Driver Model stuff by : Cornelia Huck <cornelia.huck@de.ibm.com>
@@ -19,7 +19,7 @@
  *  Dieter Wellerdiek (wel@de.ibm.com)
  *  Martin Schwidefsky (schwidefsky@de.ibm.com)
  *  Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
- *  Jochen Röhrig (roehrig@de.ibm.com)
+ *  Jochen Röhrig (roehrig@de.ibm.com)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -885,7 +885,7 @@ ch_action_firstio(fsm_instance * fi, int event, void *arg)
        }
 
        /**
-        * Don´t setup a timer for receiving the initial RX frame
+        * Don't setup a timer for receiving the initial RX frame
         * if in compatibility mode, since VM TCP delays the initial
         * frame until it has some data to send.
         */
@@ -905,10 +905,10 @@ ch_action_firstio(fsm_instance * fi, int event, void *arg)
                ccw_check_return_code(ch, rc, "init IO");
        }
        /**
-        * If in compatibility mode since we don´t setup a timer, we
+        * If in compatibility mode since we don't setup a timer, we
         * also signal RX channel up immediately. This enables us
         * to send packets early which in turn usually triggers some
-        * reply from VM TCP which brings up the RX channel to it´s
+        * reply from VM TCP which brings up the RX channel to it's
         * final state.
         */
        if ((CHANNEL_DIRECTION(ch->flags) == READ) &&
index a2d08c9ba3c4a9fe49885445c599353d8d2d8085..ff999ff0b6272a9edc2dc1feb5990f549642e416 100644 (file)
@@ -6643,7 +6643,8 @@ qeth_netdev_init(struct net_device *dev)
        dev->vlan_rx_kill_vid = qeth_vlan_rx_kill_vid;
        dev->vlan_rx_add_vid = qeth_vlan_rx_add_vid;
 #endif
-       dev->header_ops = &qeth_null_ops;
+       if (qeth_get_netdev_flags(card) & IFF_NOARP)
+               dev->header_ops = &qeth_null_ops;
 
 #ifdef CONFIG_QETH_IPV6
        /*IPv6 address autoconfiguration stuff*/
index 7507067351bd83b0ff00b20d890ae7a4671a5ed2..fd5d0c1570dfec4e2d56a8cdb543d0b37021a584 100644 (file)
@@ -559,6 +559,7 @@ zfcp_sg_list_alloc(struct zfcp_sg_list *sg_list, size_t size)
                retval = -ENOMEM;
                goto out;
        }
+       sg_init_table(sg_list->sg, sg_list->count);
 
        for (i = 0, sg = sg_list->sg; i < sg_list->count; i++, sg++) {
                sg->length = min(size, PAGE_SIZE);
index 57cac7008e0b4cbf6db25636e6921b7a958a4886..326e7ee232cb7cf4cfafd5bb41cda916b863adfc 100644 (file)
@@ -63,7 +63,7 @@
 static inline void *
 zfcp_sg_to_address(struct scatterlist *list)
 {
-       return (void *) (page_address(list->page) + list->offset);
+       return sg_virt(list);
 }
 
 /**
@@ -74,7 +74,7 @@ zfcp_sg_to_address(struct scatterlist *list)
 static inline void
 zfcp_address_to_sg(void *address, struct scatterlist *list)
 {
-       list->page = virt_to_page(address);
+       sg_set_page(list, virt_to_page(address));
        list->offset = ((unsigned long) address) & (PAGE_SIZE - 1);
 }
 
index a6475a2bb8a7df713343ce615a1c10ec2442fc11..9438d0b28799838442bfa94eb5d5cc0c62bc8692 100644 (file)
@@ -308,13 +308,15 @@ zfcp_erp_adisc(struct zfcp_port *port)
        if (send_els == NULL)
                goto nomem;
 
-       send_els->req = kzalloc(sizeof(struct scatterlist), GFP_ATOMIC);
+       send_els->req = kmalloc(sizeof(struct scatterlist), GFP_ATOMIC);
        if (send_els->req == NULL)
                goto nomem;
+       sg_init_table(send_els->req, 1);
 
-       send_els->resp = kzalloc(sizeof(struct scatterlist), GFP_ATOMIC);
+       send_els->resp = kmalloc(sizeof(struct scatterlist), GFP_ATOMIC);
        if (send_els->resp == NULL)
                goto nomem;
+       sg_init_table(send_els->resp, 1);
 
        address = (void *) get_zeroed_page(GFP_ATOMIC);
        if (address == NULL)
@@ -363,7 +365,7 @@ zfcp_erp_adisc(struct zfcp_port *port)
        retval = -ENOMEM;
  freemem:
        if (address != NULL)
-               __free_pages(send_els->req->page, 0);
+               __free_pages(sg_page(send_els->req), 0);
        if (send_els != NULL) {
                kfree(send_els->req);
                kfree(send_els->resp);
@@ -437,7 +439,7 @@ zfcp_erp_adisc_handler(unsigned long data)
 
  out:
        zfcp_port_put(port);
-       __free_pages(send_els->req->page, 0);
+       __free_pages(sg_page(send_els->req), 0);
        kfree(send_els->req);
        kfree(send_els->resp);
        kfree(send_els);
index 63941a259b927436f2f96e7589d8e8267e48ffa9..f1aa1389ea4ac231866310a92e2cbd625fef6a7c 100644 (file)
@@ -126,7 +126,7 @@ struct vfc_dev {
        volatile struct vfc_regs __iomem *regs;
        struct vfc_regs *phys_regs;
        unsigned int control_reg;
-       struct semaphore device_lock_sem;
+       struct mutex device_lock_mtx;
        int instance;
        int busy;
        unsigned long which_io;
index 9269f7fbd36364957f0cdc97a90357f4e987fd1f..d4f8fcded51d8615e1da7cd5996ac715b0defd9e 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/fs.h>
 #include <linux/delay.h>
 #include <linux/spinlock.h>
+#include <linux/mutex.h>
 #include <linux/mm.h>
 
 #include <asm/openprom.h>
@@ -54,12 +55,12 @@ static unsigned char saa9051_init_array[VFC_SAA9051_NR] = {
 
 void vfc_lock_device(struct vfc_dev *dev)
 {
-       down(&dev->device_lock_sem);
+       mutex_lock(&dev->device_lock_mtx);
 }
 
 void vfc_unlock_device(struct vfc_dev *dev)
 {
-       up(&dev->device_lock_sem);
+       mutex_unlock(&dev->device_lock_mtx);
 }
 
 
@@ -133,7 +134,7 @@ int init_vfc_hw(struct vfc_dev *dev)
 int init_vfc_devstruct(struct vfc_dev *dev, int instance) 
 {
        dev->instance=instance;
-       init_MUTEX(&dev->device_lock_sem);
+       mutex_init(&dev->device_lock_mtx);
        dev->control_reg=0;
        dev->busy=0;
        return 0;
index fb14014ee16e190f6688daba25684a19db216082..afb262b4be15b8d61bfe36bb136ea20bc4f9a6fe 100644 (file)
@@ -1840,7 +1840,7 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
                            (scsi_bufflen(srb) < TW_MIN_SGL_LENGTH)) {
                                if (srb->sc_data_direction == DMA_TO_DEVICE || srb->sc_data_direction == DMA_BIDIRECTIONAL) {
                                        struct scatterlist *sg = scsi_sglist(srb);
-                                       char *buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+                                       char *buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
                                        memcpy(tw_dev->generic_buffer_virt[request_id], buf, sg->length);
                                        kunmap_atomic(buf - sg->offset, KM_IRQ0);
                                }
@@ -1919,7 +1919,7 @@ static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int re
                        char *buf;
                        unsigned long flags = 0;
                        local_irq_save(flags);
-                       buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+                       buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
                        memcpy(buf, tw_dev->generic_buffer_virt[request_id], sg->length);
                        kunmap_atomic(buf - sg->offset, KM_IRQ0);
                        local_irq_restore(flags);
index a64153b960344d84d3b742905fa9132d3bb092c5..59716ebeb10c1a5c100d42d5941f18e2ba1769ff 100644 (file)
@@ -1469,7 +1469,7 @@ static void tw_transfer_internal(TW_Device_Extension *tw_dev, int request_id,
        struct scatterlist *sg = scsi_sglist(cmd);
 
        local_irq_save(flags);
-       buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+       buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
        transfer_len = min(sg->length, len);
 
        memcpy(buf, data, transfer_len);
index a7f916c0c9cdcc618476eecf3dcca083065d8d9c..1c9078191d9ecb4f76819007e4569bda09061bb4 100644 (file)
@@ -25,9 +25,6 @@
 
 #define FAILURE         0xFFFFFFFFL
 
-#define BIT(x)          ((unsigned char)(1<<(x)))      /* single-bit mask in bit position x */
-#define BITW(x)          ((unsigned short)(1<<(x)))    /* single-bit mask in bit position x */
-
 struct sccb;
 typedef void (*CALL_BK_FN) (struct sccb *);
 
@@ -374,9 +371,9 @@ typedef struct SCCBscam_info {
 #define  SCAM_ENABLED   BIT(2)
 #define  SCAM_LEVEL2    BIT(3)
 
-#define        RENEGO_ENA              BITW(10)
-#define        CONNIO_ENA              BITW(11)
-#define  GREEN_PC_ENA   BITW(12)
+#define        RENEGO_ENA              BIT(10)
+#define        CONNIO_ENA              BIT(11)
+#define  GREEN_PC_ENA   BIT(12)
 
 #define  AUTO_RATE_00   00
 #define  AUTO_RATE_05   01
@@ -511,23 +508,23 @@ typedef struct SCCBscam_info {
 
 #define  hp_intena              0x40
 
-#define  RESET          BITW(7)
-#define  PROG_HLT               BITW(6)
-#define  PARITY                 BITW(5)
-#define  FIFO           BITW(4)
-#define  SEL            BITW(3)
-#define  SCAM_SEL               BITW(2)
-#define  RSEL           BITW(1)
-#define  TIMEOUT                BITW(0)
-#define  BUS_FREE               BITW(15)
-#define  XFER_CNT_0     BITW(14)
-#define  PHASE          BITW(13)
-#define  IUNKWN                 BITW(12)
-#define  ICMD_COMP      BITW(11)
-#define  ITICKLE                BITW(10)
-#define  IDO_STRT               BITW(9)
-#define  ITAR_DISC      BITW(8)
-#define  AUTO_INT               (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
+#define  RESET          BIT(7)
+#define  PROG_HLT               BIT(6)
+#define  PARITY                 BIT(5)
+#define  FIFO           BIT(4)
+#define  SEL            BIT(3)
+#define  SCAM_SEL               BIT(2)
+#define  RSEL           BIT(1)
+#define  TIMEOUT                BIT(0)
+#define  BUS_FREE               BIT(15)
+#define  XFER_CNT_0     BIT(14)
+#define  PHASE          BIT(13)
+#define  IUNKWN                 BIT(12)
+#define  ICMD_COMP      BIT(11)
+#define  ITICKLE                BIT(10)
+#define  IDO_STRT               BIT(9)
+#define  ITAR_DISC      BIT(8)
+#define  AUTO_INT               (BIT(12)+BIT(11)+BIT(10)+BIT(9)+BIT(8))
 #define  CLR_ALL_INT    0xFFFF
 #define  CLR_ALL_INT_1  0xFF00
 
@@ -674,37 +671,37 @@ typedef struct SCCBscam_info {
 #define  BIOS_DATA_OFFSET     0x60
 #define  BIOS_RELATIVE_CARD   0x64
 
-#define  AR3      (BITW(9) + BITW(8))
-#define  SDATA    BITW(10)
+#define  AR3      (BIT(9) + BIT(8))
+#define  SDATA    BIT(10)
 
-#define  CRD_OP   BITW(11)     /* Cmp Reg. w/ Data */
+#define  CRD_OP   BIT(11)      /* Cmp Reg. w/ Data */
 
-#define  CRR_OP   BITW(12)     /* Cmp Reg. w. Reg. */
+#define  CRR_OP   BIT(12)      /* Cmp Reg. w. Reg. */
 
-#define  CPE_OP   (BITW(14)+BITW(11))  /* Cmp SCSI phs & Branch EQ */
+#define  CPE_OP   (BIT(14)+BIT(11))    /* Cmp SCSI phs & Branch EQ */
 
-#define  CPN_OP   (BITW(14)+BITW(12))  /* Cmp SCSI phs & Branch NOT EQ */
+#define  CPN_OP   (BIT(14)+BIT(12))    /* Cmp SCSI phs & Branch NOT EQ */
 
 #define  ADATA_OUT   0x00
-#define  ADATA_IN    BITW(8)
-#define  ACOMMAND    BITW(10)
-#define  ASTATUS     (BITW(10)+BITW(8))
-#define  AMSG_OUT    (BITW(10)+BITW(9))
-#define  AMSG_IN     (BITW(10)+BITW(9)+BITW(8))
+#define  ADATA_IN    BIT(8)
+#define  ACOMMAND    BIT(10)
+#define  ASTATUS     (BIT(10)+BIT(8))
+#define  AMSG_OUT    (BIT(10)+BIT(9))
+#define  AMSG_IN     (BIT(10)+BIT(9)+BIT(8))
 
-#define  BRH_OP   BITW(13)     /* Branch */
+#define  BRH_OP   BIT(13)      /* Branch */
 
 #define  ALWAYS   0x00
-#define  EQUAL    BITW(8)
-#define  NOT_EQ   BITW(9)
+#define  EQUAL    BIT(8)
+#define  NOT_EQ   BIT(9)
 
-#define  TCB_OP   (BITW(13)+BITW(11))  /* Test condition & branch */
+#define  TCB_OP   (BIT(13)+BIT(11))    /* Test condition & branch */
 
-#define  FIFO_0      BITW(10)
+#define  FIFO_0      BIT(10)
 
-#define  MPM_OP   BITW(15)     /* Match phase and move data */
+#define  MPM_OP   BIT(15)      /* Match phase and move data */
 
-#define  MRR_OP   BITW(14)     /* Move DReg. to Reg. */
+#define  MRR_OP   BIT(14)      /* Move DReg. to Reg. */
 
 #define  S_IDREG  (BIT(2)+BIT(1)+BIT(0))
 
@@ -712,9 +709,9 @@ typedef struct SCCBscam_info {
 #define  D_AR1    BIT(0)
 #define  D_BUCKET (BIT(2) + BIT(1) + BIT(0))
 
-#define  RAT_OP      (BITW(14)+BITW(13)+BITW(11))
+#define  RAT_OP      (BIT(14)+BIT(13)+BIT(11))
 
-#define  SSI_OP      (BITW(15)+BITW(11))
+#define  SSI_OP      (BIT(15)+BIT(11))
 
 #define  SSI_ITAR_DISC (ITAR_DISC >> 8)
 #define  SSI_IDO_STRT  (IDO_STRT >> 8)
index 30905cebefbb4d876f8c249f9334e291ccce5751..a5763c6e936232e8445be6de3e2bb048d2040c67 100644 (file)
@@ -521,7 +521,7 @@ config SCSI_DPT_I2O
 
 config SCSI_ADVANSYS
        tristate "AdvanSys SCSI support"
-       depends on SCSI
+       depends on SCSI && VIRT_TO_BUS
        depends on ISA || EISA || PCI
        help
          This is a driver for all SCSI host adapters manufactured by
index 988f0bc5eda5e081929864f40f87fbf4e0b49f75..2597209183d0ba7148a6757ee02730b41e01e53c 100644 (file)
@@ -298,8 +298,7 @@ static __inline__ void initialize_SCp(Scsi_Cmnd * cmd)
        if (cmd->use_sg) {
                cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
                cmd->SCp.buffers_residual = cmd->use_sg - 1;
-               cmd->SCp.ptr = page_address(cmd->SCp.buffer->page)+
-                              cmd->SCp.buffer->offset;
+               cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
                cmd->SCp.this_residual = cmd->SCp.buffer->length;
        } else {
                cmd->SCp.buffer = NULL;
@@ -2143,8 +2142,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
                                        ++cmd->SCp.buffer;
                                        --cmd->SCp.buffers_residual;
                                        cmd->SCp.this_residual = cmd->SCp.buffer->length;
-                                       cmd->SCp.ptr = page_address(cmd->SCp.buffer->page)+
-                                                      cmd->SCp.buffer->offset;
+                                       cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
                                        dprintk(NDEBUG_INFORMATION, ("scsi%d : %d bytes and %d buffers left\n", instance->host_no, cmd->SCp.this_residual, cmd->SCp.buffers_residual));
                                }
                                /*
index 96e8e29aa05dd5428c58f64c33bbe046c2424d3a..5b0efc903918360a1d4fcbdb55cbfe7211786cea 100644 (file)
@@ -927,7 +927,7 @@ static void esp_get_dmabufs(struct NCR_ESP *esp, Scsi_Cmnd *sp)
                        esp->dma_mmu_get_scsi_sgl(esp, sp);
                else
                        sp->SCp.ptr =
-                               (char *) virt_to_phys((page_address(sp->SCp.buffer->page) + sp->SCp.buffer->offset));
+                               (char *) virt_to_phys(sg_virt(sp->SCp.buffer));
        }
 }
 
@@ -1748,7 +1748,7 @@ static inline void advance_sg(struct NCR_ESP *esp, Scsi_Cmnd *sp)
        if (esp->dma_advance_sg)
                esp->dma_advance_sg (sp);
        else
-               sp->SCp.ptr = (char *) virt_to_phys((page_address(sp->SCp.buffer->page) + sp->SCp.buffer->offset));
+               sp->SCp.ptr = (char *) virt_to_phys(sg_virt(sp->SCp.buffer));
 
 }
 
index 3168a1794849657c5447df861331e1329a845e91..137d065db3da037f350a53c0afb1afa4ad8a187b 100644 (file)
@@ -875,8 +875,7 @@ static void NCR53c406a_intr(void *dev_id)
                        outb(TRANSFER_INFO | DMA_OP, CMD_REG);
 #if USE_PIO
                         scsi_for_each_sg(current_SC, sg, scsi_sg_count(current_SC), i) {
-                                NCR53c406a_pio_write(page_address(sg->page) + sg->offset,
-                                                     sg->length);
+                                NCR53c406a_pio_write(sg_virt(sg), sg->length);
                         }
                        REG0;
 #endif                         /* USE_PIO */
@@ -897,8 +896,7 @@ static void NCR53c406a_intr(void *dev_id)
                        outb(TRANSFER_INFO | DMA_OP, CMD_REG);
 #if USE_PIO
                         scsi_for_each_sg(current_SC, sg, scsi_sg_count(current_SC), i) {
-                                NCR53c406a_pio_read(page_address(sg->page) + sg->offset,
-                                                    sg->length);
+                                NCR53c406a_pio_read(sg_virt(sg), sg->length);
                         }
                        REG0;
 #endif                         /* USE_PIO */
index 80e448d0f3dbd541bae7406b68617d904472bc13..a77ab8d693d416f48a53c7efd147a3508def7ec4 100644 (file)
@@ -356,7 +356,7 @@ static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigne
        int transfer_len;
        struct scatterlist *sg = scsi_sglist(scsicmd);
 
-       buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+       buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
        transfer_len = min(sg->length, len + offset);
 
        transfer_len -= offset;
index 03b51025a8f441fdb4258d452f218fd5d05c8ee4..9abba8b90f70db5afc23c3dc1d200ba4c3fbc67c 100644 (file)
@@ -1526,7 +1526,7 @@ struct aac_mntent {
        __le32                  capacityhigh;
 };
 
-#define FSCS_NOTCLEAN  0x0001  /* fsck is neccessary before mounting */
+#define FSCS_NOTCLEAN  0x0001  /* fsck is necessary before mounting */
 #define FSCS_READONLY  0x0002  /* possible result of broken mirror */
 #define FSCS_HIDDEN    0x0004  /* should be ignored - set during a clear */
 
index f08e71e0205a5f5a3e538701d44e80bd9a4822ca..ea8c699476446cc8c09587d33dd8b84ced275461 100644 (file)
@@ -1,6 +1,6 @@
 /* aha152x.c -- Adaptec AHA-152x driver
- * Author: Jürgen E. Fischer, fischer@norbit.de
- * Copyright 1993-2004 Jürgen E. Fischer
+ * Author: Jürgen E. Fischer, fischer@norbit.de
+ * Copyright 1993-2004 Jürgen E. Fischer
  *
  * 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
@@ -357,7 +357,7 @@ enum {
        check_condition = 0x0800,       /* requesting sense after CHECK CONDITION */
 };
 
-MODULE_AUTHOR("Jürgen Fischer");
+MODULE_AUTHOR("Jürgen Fischer");
 MODULE_DESCRIPTION(AHA152X_REVID);
 MODULE_LICENSE("GPL");
 
@@ -613,7 +613,7 @@ struct aha152x_scdata {
 #define SCNEXT(SCpnt)          SCDATA(SCpnt)->next
 #define SCSEM(SCpnt)           SCDATA(SCpnt)->done
 
-#define SG_ADDRESS(buffer)     ((char *) (page_address((buffer)->page)+(buffer)->offset))
+#define SG_ADDRESS(buffer)     ((char *) sg_virt((buffer)))
 
 /* state handling */
 static void seldi_run(struct Scsi_Host *shpnt);
index 961a1882cb7eb0741ea26659c67ac8a557fb6516..bbcc2c52d79fed550b90fe623fbfa105ca90a921 100644 (file)
@@ -49,7 +49,7 @@
 #include "aha1542.h"
 
 #define SCSI_BUF_PA(address)   isa_virt_to_bus(address)
-#define SCSI_SG_PA(sgent)      (isa_page_to_bus((sgent)->page) + (sgent)->offset)
+#define SCSI_SG_PA(sgent)      (isa_page_to_bus(sg_page((sgent))) + (sgent)->offset)
 
 static void BAD_DMA(void *address, unsigned int length)
 {
@@ -66,8 +66,7 @@ static void BAD_SG_DMA(Scsi_Cmnd * SCpnt,
                       int badseg)
 {
        printk(KERN_CRIT "sgpnt[%d:%d] page %p/0x%llx length %u\n",
-              badseg, nseg,
-              page_address(sgp->page) + sgp->offset,
+              badseg, nseg, sg_virt(sgp),
               (unsigned long long)SCSI_SG_PA(sgp),
               sgp->length);
 
@@ -712,8 +711,7 @@ static int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
                                printk(KERN_CRIT "Bad segment list supplied to aha1542.c (%d, %d)\n", SCpnt->use_sg, i);
                                scsi_for_each_sg(SCpnt, sg, SCpnt->use_sg, i) {
                                        printk(KERN_CRIT "%d: %p %d\n", i,
-                                              (page_address(sg->page) +
-                                               sg->offset), sg->length);
+                                              sg_virt(sg), sg->length);
                                };
                                printk(KERN_CRIT "cptr %x: ", (unsigned int) cptr);
                                ptr = (unsigned char *) &cptr[i];
index 26f17e3fc45c6113b99e138dde03138502e85b4d..687aef6ef18503f81a2bf4c076c2c4b3f876490f 100644 (file)
@@ -48,7 +48,7 @@ typedef enum {
        CAM_REQ_ABORTED,        /* CCB request aborted by the host */
        CAM_UA_ABORT,           /* Unable to abort CCB request */
        CAM_REQ_CMP_ERR,        /* CCB request completed with an error */
-       CAM_BUSY,               /* CAM subsytem is busy */
+       CAM_BUSY,               /* CAM subsystem is busy */
        CAM_REQ_INVALID,        /* CCB request was invalid */
        CAM_PATH_INVALID,       /* Supplied Path ID is invalid */
        CAM_SEL_TIMEOUT,        /* Target Selection Timeout */
index f81777586b8f8ea77b7a2ee8abeae4b13f1e9523..f7a252885a5c69855e3aa3595dd4d2070a365ef1 100644 (file)
@@ -1343,7 +1343,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \
                                                /* 4 bytes: Areca io control code */
 
        sg = scsi_sglist(cmd);
-       buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+       buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
        if (scsi_sg_count(cmd) > 1) {
                retvalue = ARCMSR_MESSAGE_FAIL;
                goto message_out;
@@ -1593,7 +1593,7 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb,
                strncpy(&inqdata[32], "R001", 4); /* Product Revision */
 
                sg = scsi_sglist(cmd);
-               buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+               buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 
                memcpy(buffer, inqdata, sizeof(inqdata));
                sg = scsi_sglist(cmd);
index 52d0b87e9aa48f06cabb7c86ea6fff4b9b23ede0..d1780980fb206ad633d3ab71acbf7cfbb95a2c09 100644 (file)
@@ -515,8 +515,7 @@ static inline void initialize_SCp(Scsi_Cmnd *cmd)
        if (cmd->use_sg) {
                cmd->SCp.buffer = (struct scatterlist *)cmd->request_buffer;
                cmd->SCp.buffers_residual = cmd->use_sg - 1;
-               cmd->SCp.ptr = (char *)page_address(cmd->SCp.buffer->page) +
-                              cmd->SCp.buffer->offset;
+               cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
                cmd->SCp.this_residual = cmd->SCp.buffer->length;
                /* ++roman: Try to merge some scatter-buffers if they are at
                 * contiguous physical addresses.
@@ -2054,8 +2053,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                                        ++cmd->SCp.buffer;
                                        --cmd->SCp.buffers_residual;
                                        cmd->SCp.this_residual = cmd->SCp.buffer->length;
-                                       cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) +
-                                                  cmd->SCp.buffer->offset;
+                                       cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
                                        /* ++roman: Try to merge some scatter-buffers if
                                         * they are at contiguous physical addresses.
                                         */
index fd42d47892021487aa916588b99d87a55c76a048..a9def6e1d30e6a5bd761a481b1fe522f924bd107 100644 (file)
@@ -1808,12 +1808,12 @@ static irqreturn_t dc395x_interrupt(int irq, void *dev_id)
        irqreturn_t handled = IRQ_NONE;
 
        /*
-        * Check for pending interupt
+        * Check for pending interrupt
         */
        scsi_status = DC395x_read16(acb, TRM_S1040_SCSI_STATUS);
        dma_status = DC395x_read8(acb, TRM_S1040_DMA_STATUS);
        if (scsi_status & SCSIINTERRUPT) {
-               /* interupt pending - let's process it! */
+               /* interrupt pending - let's process it! */
                dc395x_handle_interrupt(acb, scsi_status);
                handled = IRQ_HANDLED;
        }
@@ -4579,7 +4579,7 @@ static void adapter_uninit_chip(struct AdapterCtlBlk *acb)
        if (acb->config & HCC_SCSI_RESET)
                reset_scsi_bus(acb);
 
-       /* clear any pending interupt state */
+       /* clear any pending interrupt state */
        DC395x_read8(acb, TRM_S1040_SCSI_INTSTATUS);
 }
 
index 96180bb47e4189c3fa8304df15fc52d520689915..982c5092be11fa055952f0f0d0f68c3758741a09 100644 (file)
@@ -172,7 +172,7 @@ static void IncStat(struct scsi_pointer *SCp, unsigned int Increment)
                        SCp->Status = 0;
                else {
                        SCp->buffer++;
-                       SCp->ptr = page_address(SCp->buffer->page) + SCp->buffer->offset;
+                       SCp->ptr = sg_virt(SCp->buffer);
                        SCp->this_residual = SCp->buffer->length;
                }
        }
@@ -410,7 +410,7 @@ static int eata_pio_queue(struct scsi_cmnd *cmd,
        } else {
                cmd->SCp.buffer = cmd->request_buffer;
                cmd->SCp.buffers_residual = cmd->use_sg;
-               cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset;
+               cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
                cmd->SCp.this_residual = cmd->SCp.buffer->length;
        }
        cmd->SCp.Status = (cmd->SCp.this_residual != 0);        /* TRUE as long as bytes 
index 668569e8856bdb635ad90d9aaa718abcedf0b754..8335b608e5717b2687b9fae230d200274671b67d 100644 (file)
@@ -973,7 +973,7 @@ static irqreturn_t fd_mcs_intr(int irq, void *dev_id)
                                if (current_SC->SCp.buffers_residual) {
                                        --current_SC->SCp.buffers_residual;
                                        ++current_SC->SCp.buffer;
-                                       current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
+                                       current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
                                        current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
                                } else
                                        break;
@@ -1006,7 +1006,7 @@ static irqreturn_t fd_mcs_intr(int irq, void *dev_id)
                        if (!current_SC->SCp.this_residual && current_SC->SCp.buffers_residual) {
                                --current_SC->SCp.buffers_residual;
                                ++current_SC->SCp.buffer;
-                               current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
+                               current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
                                current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
                        }
                }
@@ -1109,7 +1109,7 @@ static int fd_mcs_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 
        if (current_SC->use_sg) {
                current_SC->SCp.buffer = (struct scatterlist *) current_SC->request_buffer;
-               current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
+               current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
                current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
                current_SC->SCp.buffers_residual = current_SC->use_sg - 1;
        } else {
index 5d282e6a6ae1d14105492faea3934893d213d471..2cd6b4959eb2da2740ae1b1cd86bebb5995c251c 100644 (file)
@@ -1321,7 +1321,7 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id)
            if (current_SC->SCp.buffers_residual) {
               --current_SC->SCp.buffers_residual;
               ++current_SC->SCp.buffer;
-              current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
+              current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
               current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
            } else
                  break;
@@ -1354,7 +1354,7 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id)
             && current_SC->SCp.buffers_residual) {
            --current_SC->SCp.buffers_residual;
            ++current_SC->SCp.buffer;
-           current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
+           current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
            current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
         }
       }
@@ -1439,8 +1439,7 @@ static int fdomain_16x0_queue(struct scsi_cmnd *SCpnt,
 
    if (scsi_sg_count(current_SC)) {
           current_SC->SCp.buffer = scsi_sglist(current_SC);
-          current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page)
-                  + current_SC->SCp.buffer->offset;
+          current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
           current_SC->SCp.this_residual    = current_SC->SCp.buffer->length;
           current_SC->SCp.buffers_residual = scsi_sg_count(current_SC) - 1;
    } else {
index 3ac080ee6e2f2785230259e595d39d806ebeed26..5ab3ce762485e070e61d6aef8f6a0caf630348d5 100644 (file)
@@ -2374,18 +2374,18 @@ static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
             if (cpsum+cpnow > cpcount) 
                 cpnow = cpcount - cpsum;
             cpsum += cpnow;
-            if (!sl->page) {
+            if (!sg_page(sl)) {
                 printk("GDT-HA %d: invalid sc/gt element in gdth_copy_internal_data()\n",
                        ha->hanum);
                 return;
             }
             local_irq_save(flags);
-            address = kmap_atomic(sl->page, KM_BIO_SRC_IRQ) + sl->offset;
+            address = kmap_atomic(sg_page(sl), KM_BIO_SRC_IRQ) + sl->offset;
             if (to_buffer)
                 memcpy(buffer, address, cpnow);
             else
                 memcpy(address, buffer, cpnow);
-            flush_dcache_page(sl->page);
+            flush_dcache_page(sg_page(sl));
             kunmap_atomic(address, KM_BIO_SRC_IRQ);
             local_irq_restore(flags);
             if (cpsum == cpcount)
index 714e6273a70d0444c28e938dbcb864ee677cdb87..db004a45073277edbd946cff38e941893de01a95 100644 (file)
@@ -1828,7 +1828,7 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
                BUG_ON(scsi_sg_count(cmd) > 16);
 
                scsi_for_each_sg(cmd, sg, scsi_sg_count(cmd), i) {
-                       ld(shpnt)[ldn].sge[i].address = (void *) (isa_page_to_bus(sg->page) + sg->offset);
+                       ld(shpnt)[ldn].sge[i].address = (void *) (isa_page_to_bus(sg_page(sg)) + sg->offset);
                        ld(shpnt)[ldn].sge[i].byte_length = sg->length;
                }
                scb->enable |= IM_POINTER_TO_LIST;
index fa7ba64483fb4c3976518f909365f1156bef9262..8d0244c2e7d4fdf759ed85e4a885c3a73a8b5d60 100644 (file)
@@ -47,9 +47,9 @@
 #include <linux/scatterlist.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
+#include <linux/bitops.h>
 
 #include <asm/io.h>
-#include <asm/bitops.h>
 #include <asm/uaccess.h>
 
 #include <scsi/scsi.h>
@@ -175,18 +175,18 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne
 
        while (bcount) {
                count = min(pc->sg->length - pc->b_count, bcount);
-               if (PageHighMem(pc->sg->page)) {
+               if (PageHighMem(sg_page(pc->sg))) {
                        unsigned long flags;
 
                        local_irq_save(flags);
-                       buf = kmap_atomic(pc->sg->page, KM_IRQ0) +
+                       buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) +
                                        pc->sg->offset;
                        drive->hwif->atapi_input_bytes(drive,
                                                buf + pc->b_count, count);
                        kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
                        local_irq_restore(flags);
                } else {
-                       buf = page_address(pc->sg->page) + pc->sg->offset;
+                       buf = sg_virt(pc->sg);
                        drive->hwif->atapi_input_bytes(drive,
                                                buf + pc->b_count, count);
                }
@@ -212,18 +212,18 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign
 
        while (bcount) {
                count = min(pc->sg->length - pc->b_count, bcount);
-               if (PageHighMem(pc->sg->page)) {
+               if (PageHighMem(sg_page(pc->sg))) {
                        unsigned long flags;
 
                        local_irq_save(flags);
-                       buf = kmap_atomic(pc->sg->page, KM_IRQ0) +
+                       buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) +
                                                pc->sg->offset;
                        drive->hwif->atapi_output_bytes(drive,
                                                buf + pc->b_count, count);
                        kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
                        local_irq_restore(flags);
                } else {
-                       buf = page_address(pc->sg->page) + pc->sg->offset;
+                       buf = sg_virt(pc->sg);
                        drive->hwif->atapi_output_bytes(drive,
                                                buf + pc->b_count, count);
                }
index 74cdc1f0a78f976bbf2d64397566430caba7ca32..a3d0c6b149583156fda2f7e2267654c6aab9f47a 100644 (file)
@@ -705,9 +705,7 @@ static int imm_completion(struct scsi_cmnd *cmd)
                                cmd->SCp.buffer++;
                                cmd->SCp.this_residual =
                                    cmd->SCp.buffer->length;
-                               cmd->SCp.ptr =
-                                   page_address(cmd->SCp.buffer->page) +
-                                   cmd->SCp.buffer->offset;
+                               cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
 
                                /*
                                 * Make sure that we transfer even number of bytes
@@ -844,9 +842,7 @@ static int imm_engine(imm_struct *dev, struct scsi_cmnd *cmd)
                        cmd->SCp.buffer =
                            (struct scatterlist *) cmd->request_buffer;
                        cmd->SCp.this_residual = cmd->SCp.buffer->length;
-                       cmd->SCp.ptr =
-                           page_address(cmd->SCp.buffer->page) +
-                           cmd->SCp.buffer->offset;
+                       cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
                } else {
                        /* else fill the only available buffer */
                        cmd->SCp.buffer = NULL;
index ab7cbf3449ce07639880a8b55daadad03a751c4f..c8b452f2878c4a019822775769b1003206b549ed 100644 (file)
@@ -372,7 +372,7 @@ static int in2000_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
        if (cmd->use_sg) {
                cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
                cmd->SCp.buffers_residual = cmd->use_sg - 1;
-               cmd->SCp.ptr = (char *) page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset;
+               cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
                cmd->SCp.this_residual = cmd->SCp.buffer->length;
        } else {
                cmd->SCp.buffer = NULL;
@@ -764,7 +764,7 @@ static void transfer_bytes(Scsi_Cmnd * cmd, int data_in_dir)
                ++cmd->SCp.buffer;
                --cmd->SCp.buffers_residual;
                cmd->SCp.this_residual = cmd->SCp.buffer->length;
-               cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset;
+               cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
        }
 
 /* Set up hardware registers */
index b41dfb5390212ddade69f1ff80bbe1930389b36f..439b97a6a269f6b8377b865d4759c300a0429f8a 100644 (file)
@@ -2872,6 +2872,7 @@ static struct ipr_sglist *ipr_alloc_ucode_buffer(int buf_len)
        }
 
        scatterlist = sglist->scatterlist;
+       sg_init_table(scatterlist, num_elem);
 
        sglist->order = order;
        sglist->num_sg = num_elem;
@@ -2884,12 +2885,12 @@ static struct ipr_sglist *ipr_alloc_ucode_buffer(int buf_len)
 
                        /* Free up what we already allocated */
                        for (j = i - 1; j >= 0; j--)
-                               __free_pages(scatterlist[j].page, order);
+                               __free_pages(sg_page(&scatterlist[j]), order);
                        kfree(sglist);
                        return NULL;
                }
 
-               scatterlist[i].page = page;
+               sg_set_page(&scatterlist[i], page);
        }
 
        return sglist;
@@ -2910,7 +2911,7 @@ static void ipr_free_ucode_buffer(struct ipr_sglist *sglist)
        int i;
 
        for (i = 0; i < sglist->num_sg; i++)
-               __free_pages(sglist->scatterlist[i].page, sglist->order);
+               __free_pages(sg_page(&sglist->scatterlist[i]), sglist->order);
 
        kfree(sglist);
 }
@@ -2940,9 +2941,11 @@ static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist,
        scatterlist = sglist->scatterlist;
 
        for (i = 0; i < (len / bsize_elem); i++, buffer += bsize_elem) {
-               kaddr = kmap(scatterlist[i].page);
+               struct page *page = sg_page(&scatterlist[i]);
+
+               kaddr = kmap(page);
                memcpy(kaddr, buffer, bsize_elem);
-               kunmap(scatterlist[i].page);
+               kunmap(page);
 
                scatterlist[i].length = bsize_elem;
 
@@ -2953,9 +2956,11 @@ static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist,
        }
 
        if (len % bsize_elem) {
-               kaddr = kmap(scatterlist[i].page);
+               struct page *page = sg_page(&scatterlist[i]);
+
+               kaddr = kmap(page);
                memcpy(kaddr, buffer, len % bsize_elem);
-               kunmap(scatterlist[i].page);
+               kunmap(page);
 
                scatterlist[i].length = len % bsize_elem;
        }
@@ -5134,6 +5139,7 @@ static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd,
        u32 ioadl_flags = 0;
        struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
        struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
+       struct ipr_ioadl_desc *last_ioadl = NULL;
        int len = qc->nbytes + qc->pad_len;
        struct scatterlist *sg;
 
@@ -5156,11 +5162,13 @@ static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd,
        ata_for_each_sg(sg, qc) {
                ioadl->flags_and_data_len = cpu_to_be32(ioadl_flags | sg_dma_len(sg));
                ioadl->address = cpu_to_be32(sg_dma_address(sg));
-               if (ata_sg_is_last(sg, qc))
-                       ioadl->flags_and_data_len |= cpu_to_be32(IPR_IOADL_FLAGS_LAST);
-               else
-                       ioadl++;
+
+               last_ioadl = ioadl;
+               ioadl++;
        }
+
+       if (likely(last_ioadl))
+               last_ioadl->flags_and_data_len |= cpu_to_be32(IPR_IOADL_FLAGS_LAST);
 }
 
 /**
index edaac2714c5abc2ecbcfbf711f94ece48a00509a..5c5a9b2628fc446f6ddc7c385122607a8cb6c0ef 100644 (file)
@@ -1515,7 +1515,7 @@ static int ips_is_passthru(struct scsi_cmnd *SC)
                 /* kmap_atomic() ensures addressability of the user buffer.*/
                 /* local_irq_save() protects the KM_IRQ0 address slot.     */
                 local_irq_save(flags);
-                buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+                buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
                 if (buffer && buffer[0] == 'C' && buffer[1] == 'O' &&
                     buffer[2] == 'P' && buffer[3] == 'P') {
                         kunmap_atomic(buffer - sg->offset, KM_IRQ0);
@@ -3523,7 +3523,7 @@ ips_scmd_buf_write(struct scsi_cmnd *scmd, void *data, unsigned int count)
                 /* kmap_atomic() ensures addressability of the data buffer.*/
                 /* local_irq_save() protects the KM_IRQ0 address slot.     */
                 local_irq_save(flags);
-                buffer = kmap_atomic(sg[i].page, KM_IRQ0) + sg[i].offset;
+                buffer = kmap_atomic(sg_page(&sg[i]), KM_IRQ0) + sg[i].offset;
                 memcpy(buffer, &cdata[xfer_cnt], min_cnt);
                 kunmap_atomic(buffer - sg[i].offset, KM_IRQ0);
                 local_irq_restore(flags);
@@ -3556,7 +3556,7 @@ ips_scmd_buf_read(struct scsi_cmnd *scmd, void *data, unsigned int count)
                 /* kmap_atomic() ensures addressability of the data buffer.*/
                 /* local_irq_save() protects the KM_IRQ0 address slot.     */
                 local_irq_save(flags);
-                buffer = kmap_atomic(sg[i].page, KM_IRQ0) + sg[i].offset;
+                buffer = kmap_atomic(sg_page(&sg[i]), KM_IRQ0) + sg[i].offset;
                 memcpy(&cdata[xfer_cnt], buffer, min_cnt);
                 kunmap_atomic(buffer - sg[i].offset, KM_IRQ0);
                 local_irq_restore(flags);
index a21455d0274cb5d634a40baf768726ff4daf1472..6ce4109efdf3365a39ab736597bdd2fa39d696fb 100644 (file)
@@ -70,9 +70,7 @@ module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO);
 static inline void
 iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size)
 {
-       ibuf->sg.page = virt_to_page(vbuf);
-       ibuf->sg.offset = offset_in_page(vbuf);
-       ibuf->sg.length = size;
+       sg_init_one(&ibuf->sg, vbuf, size);
        ibuf->sent = 0;
        ibuf->use_sendmsg = 1;
 }
@@ -80,13 +78,14 @@ iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size)
 static inline void
 iscsi_buf_init_sg(struct iscsi_buf *ibuf, struct scatterlist *sg)
 {
-       ibuf->sg.page = sg->page;
+       sg_init_table(&ibuf->sg, 1);
+       sg_set_page(&ibuf->sg, sg_page(sg));
        ibuf->sg.offset = sg->offset;
        ibuf->sg.length = sg->length;
        /*
         * Fastpath: sg element fits into single page
         */
-       if (sg->length + sg->offset <= PAGE_SIZE && !PageSlab(sg->page))
+       if (sg->length + sg->offset <= PAGE_SIZE && !PageSlab(sg_page(sg)))
                ibuf->use_sendmsg = 0;
        else
                ibuf->use_sendmsg = 1;
@@ -716,7 +715,7 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn)
        for (i = tcp_ctask->sg_count; i < scsi_sg_count(sc); i++) {
                char *dest;
 
-               dest = kmap_atomic(sg[i].page, KM_SOFTIRQ0);
+               dest = kmap_atomic(sg_page(&sg[i]), KM_SOFTIRQ0);
                rc = iscsi_ctask_copy(tcp_conn, ctask, dest + sg[i].offset,
                                      sg[i].length, offset);
                kunmap_atomic(dest, KM_SOFTIRQ0);
@@ -1103,9 +1102,9 @@ iscsi_send(struct iscsi_conn *conn, struct iscsi_buf *buf, int size, int flags)
         * slab case.
         */
        if (buf->use_sendmsg)
-               res = sock_no_sendpage(sk, buf->sg.page, offset, size, flags);
+               res = sock_no_sendpage(sk, sg_page(&buf->sg), offset, size, flags);
        else
-               res = tcp_conn->sendpage(sk, buf->sg.page, offset, size, flags);
+               res = tcp_conn->sendpage(sk, sg_page(&buf->sg), offset, size, flags);
 
        if (res >= 0) {
                conn->txdata_octets += res;
index 7ef0afc3cd68b7f848a7b635af3c30fb8a6690ad..5f3a0d7b18de9db796d4ada15df39d8ef29c1b61 100644 (file)
@@ -285,7 +285,7 @@ static void sas_discover_domain(struct work_struct *work)
        dev = port->port_dev;
 
        SAS_DPRINTK("DOING DISCOVERY on port %d, pid:%d\n", port->id,
-                   current->pid);
+                   task_pid_nr(current));
 
        switch (dev->dev_type) {
        case SAS_END_DEV:
@@ -320,7 +320,7 @@ static void sas_discover_domain(struct work_struct *work)
        }
 
        SAS_DPRINTK("DONE DISCOVERY on port %d, pid:%d, result:%d\n", port->id,
-                   current->pid, error);
+                   task_pid_nr(current), error);
 }
 
 static void sas_revalidate_domain(struct work_struct *work)
@@ -334,12 +334,12 @@ static void sas_revalidate_domain(struct work_struct *work)
                        &port->disc.pending);
 
        SAS_DPRINTK("REVALIDATING DOMAIN on port %d, pid:%d\n", port->id,
-                   current->pid);
+                   task_pid_nr(current));
        if (port->port_dev)
                res = sas_ex_revalidate_domain(port->port_dev);
 
        SAS_DPRINTK("done REVALIDATING DOMAIN on port %d, pid:%d, res 0x%x\n",
-                   port->id, current->pid, res);
+                   port->id, task_pid_nr(current), res);
 }
 
 /* ---------- Events ---------- */
index e5337ad4121efd36f9d6493dc6ea011cd9404b6c..ce348c5c706ce901f05cc72349804c63cc2b9935 100644 (file)
@@ -1243,7 +1243,8 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba *phba)
                                memset(adaptermsg, 0, LPFC_MAX_ADPTMSG);
                                memcpy(&adaptermsg[0], (uint8_t *) irsp,
                                       MAX_MSG_DATA);
-                               dev_warn(&((phba->pcidev)->dev), "lpfc%d: %s",
+                               dev_warn(&((phba->pcidev)->dev),
+                                        "lpfc%d: %s\n",
                                         phba->brd_no, adaptermsg);
                        } else {
                                /* Unknown IOCB command */
@@ -1430,7 +1431,8 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba,
                                memset(adaptermsg, 0, LPFC_MAX_ADPTMSG);
                                memcpy(&adaptermsg[0], (uint8_t *) irsp,
                                       MAX_MSG_DATA);
-                               dev_warn(&((phba->pcidev)->dev), "lpfc%d: %s",
+                               dev_warn(&((phba->pcidev)->dev),
+                                        "lpfc%d: %s\n",
                                         phba->brd_no, adaptermsg);
                        } else {
                                /* Unknown IOCB command */
@@ -1681,7 +1683,7 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba *phba,
                                        memcpy(&adaptermsg[0], (uint8_t *) irsp,
                                               MAX_MSG_DATA);
                                        dev_warn(&((phba->pcidev)->dev),
-                                                "lpfc%d: %s",
+                                                "lpfc%d: %s\n",
                                                 phba->brd_no, adaptermsg);
                                } else {
                                        /* Unknown IOCB command */
index 10d1aff9938a1938b79ec54e92cb1a5bb6bc7ecd..66c652035730387e48d8532579a1986c2ffaa137 100644 (file)
@@ -658,7 +658,7 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy)
                        struct scatterlist *sg;
 
                        sg = scsi_sglist(cmd);
-                       buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+                       buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 
                        memset(buf, 0, cmd->cmnd[4]);
                        kunmap_atomic(buf - sg->offset, KM_IRQ0);
@@ -1542,10 +1542,8 @@ mega_cmd_done(adapter_t *adapter, u8 completed[], int nstatus, int status)
                if( cmd->cmnd[0] == INQUIRY && !islogical ) {
 
                        sgl = scsi_sglist(cmd);
-                       if( sgl->page ) {
-                               c = *(unsigned char *)
-                                       page_address((&sgl[0])->page) +
-                                       (&sgl[0])->offset; 
+                       if( sg_page(sgl) ) {
+                               c = *(unsigned char *) sg_virt(&sgl[0]);
                        } else {
                                printk(KERN_WARNING
                                       "megaraid: invalid sg.\n");
index e4e4c6a39ed6368d090cef0dea29fff4f491e757..c8923108183a5f6a976f33773266d0781170dfae 100644 (file)
@@ -427,7 +427,7 @@ megaraid_exit(void)
  * @id         : pci device id of the class of controllers
  *
  * This routine should be called whenever a new adapter is detected by the
- * PCI hotplug susbsytem.
+ * PCI hotplug susbsystem.
  */
 static int __devinit
 megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -1584,10 +1584,8 @@ megaraid_mbox_build_cmd(adapter_t *adapter, struct scsi_cmnd *scp, int *busy)
                        caddr_t                 vaddr;
 
                        sgl = scsi_sglist(scp);
-                       if (sgl->page) {
-                               vaddr = (caddr_t)
-                                       (page_address((&sgl[0])->page)
-                                        + (&sgl[0])->offset);
+                       if (sg_page(sgl)) {
+                               vaddr = (caddr_t) sg_virt(&sgl[0]);
 
                                memset(vaddr, 0, scp->cmnd[4]);
                        }
@@ -2328,10 +2326,8 @@ megaraid_mbox_dpc(unsigned long devp)
                                && IS_RAID_CH(raid_dev, scb->dev_channel)) {
 
                        sgl = scsi_sglist(scp);
-                       if (sgl->page) {
-                               c = *(unsigned char *)
-                                       (page_address((&sgl[0])->page) +
-                                        (&sgl[0])->offset);
+                       if (sg_page(sgl)) {
+                               c = *(unsigned char *) sg_virt(&sgl[0]);
                        } else {
                                con_log(CL_ANN, (KERN_WARNING
                                                 "megaraid mailbox: invalid sg:%d\n",
index a976e8193d163d1ff983fb405d16d7a981a8e8c1..6715ecb3bfcaf2f1a3bce11c94b826ac72893979 100644 (file)
@@ -68,11 +68,6 @@ static char * nsp32_model[] = {
 typedef u32 u32_le;
 typedef u16 u16_le;
 
-/*
- * MACRO
- */
-#define BIT(x)      (1UL << (x))
-
 /*
  * BASIC Definitions
  */
index 26a6d55faf3ec03a86b480687cceb00872f5365e..8e5eadbd5c5151183da96fceb9cc203ce98cc9cf 100644 (file)
@@ -550,8 +550,7 @@ void dma_mmu_get_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd *sp)
 
 void dma_mmu_get_scsi_sgl(struct NCR_ESP *esp, Scsi_Cmnd *sp)
 {
-        sp->SCp.ptr = page_address(sp->SCp.buffer->page)+
-                     sp->SCp.buffer->offset;
+        sp->SCp.ptr = sg_virt(sp->SCp.buffer);
 }
 
 void dma_mmu_release_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd *sp)
@@ -564,8 +563,7 @@ void dma_mmu_release_scsi_sgl(struct NCR_ESP *esp, Scsi_Cmnd *sp)
 
 void dma_advance_sg(Scsi_Cmnd *sp)
 {
-       sp->SCp.ptr = page_address(sp->SCp.buffer->page)+
-                     sp->SCp.buffer->offset;
+       sp->SCp.ptr = sg_virt(sp->SCp.buffer);
 }
 
 
index 331b789937c4e0a700e4d1406f8e6a708e9a3e03..1c5c4b68f20f1c463b74b05136a1f3e3eeff910a 100644 (file)
@@ -542,7 +542,7 @@ static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int q
        if (STp->raw) {
                if (STp->buffer->syscall_result) {
                        for (i=0; i < STp->buffer->sg_segs; i++)
-                               memset(page_address(STp->buffer->sg[i].page),
+                               memset(page_address(sg_page(&STp->buffer->sg[i])),
                                       0, STp->buffer->sg[i].length);
                        strcpy(STp->buffer->b_data, "READ ERROR ON FRAME");
                 } else
@@ -4437,7 +4437,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp)
                for (i = 0, b_size = 0; 
                     (i < STp->buffer->sg_segs) && ((b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE); 
                     b_size += STp->buffer->sg[i++].length);
-               STp->buffer->aux = (os_aux_t *) (page_address(STp->buffer->sg[i].page) + OS_DATA_SIZE - b_size);
+               STp->buffer->aux = (os_aux_t *) (page_address(sg_page(&STp->buffer->sg[i])) + OS_DATA_SIZE - b_size);
 #if DEBUG
                printk(OSST_DEB_MSG "%s:D: b_data points to %p in segment 0 at %p\n", name,
                        STp->buffer->b_data, page_address(STp->buffer->sg[0].page));
@@ -5252,25 +5252,26 @@ static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
        /* Try to allocate the first segment up to OS_DATA_SIZE and the others
           big enough to reach the goal (code assumes no segments in place) */
        for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) {
-               STbuffer->sg[0].page = alloc_pages(priority, order);
+               struct page *page = alloc_pages(priority, order);
+
                STbuffer->sg[0].offset = 0;
-               if (STbuffer->sg[0].page != NULL) {
+               if (page != NULL) {
+                   sg_set_page(&STbuffer->sg[0], page);
                    STbuffer->sg[0].length = b_size;
-                   STbuffer->b_data = page_address(STbuffer->sg[0].page);
+                   STbuffer->b_data = page_address(page);
                    break;
                }
        }
-       if (STbuffer->sg[0].page == NULL) {
+       if (sg_page(&STbuffer->sg[0]) == NULL) {
                printk(KERN_NOTICE "osst :I: Can't allocate tape buffer main segment.\n");
                return 0;
        }
        /* Got initial segment of 'bsize,order', continue with same size if possible, except for AUX */
        for (segs=STbuffer->sg_segs=1, got=b_size;
             segs < max_segs && got < OS_FRAME_SIZE; ) {
-               STbuffer->sg[segs].page =
-                               alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
+               struct page *page = alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
                STbuffer->sg[segs].offset = 0;
-               if (STbuffer->sg[segs].page == NULL) {
+               if (page == NULL) {
                        if (OS_FRAME_SIZE - got <= (max_segs - segs) * b_size / 2 && order) {
                                b_size /= 2;  /* Large enough for the rest of the buffers */
                                order--;
@@ -5284,6 +5285,7 @@ static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
                        normalize_buffer(STbuffer);
                        return 0;
                }
+               sg_set_page(&STbuffer->sg[segs], page);
                STbuffer->sg[segs].length = (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size;
                got += STbuffer->sg[segs].length;
                STbuffer->buffer_size = got;
@@ -5316,7 +5318,7 @@ static void normalize_buffer(struct osst_buffer *STbuffer)
                     b_size < STbuffer->sg[i].length;
                     b_size *= 2, order++);
 
-               __free_pages(STbuffer->sg[i].page, order);
+               __free_pages(sg_page(&STbuffer->sg[i]), order);
                STbuffer->buffer_size -= STbuffer->sg[i].length;
        }
 #if DEBUG
@@ -5344,7 +5346,7 @@ static int append_to_buffer(const char __user *ubp, struct osst_buffer *st_bp, i
        for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
                cnt = st_bp->sg[i].length - offset < do_count ?
                      st_bp->sg[i].length - offset : do_count;
-               res = copy_from_user(page_address(st_bp->sg[i].page) + offset, ubp, cnt);
+               res = copy_from_user(page_address(sg_page(&st_bp->sg[i])) + offset, ubp, cnt);
                if (res)
                        return (-EFAULT);
                do_count -= cnt;
@@ -5377,7 +5379,7 @@ static int from_buffer(struct osst_buffer *st_bp, char __user *ubp, int do_count
        for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
                cnt = st_bp->sg[i].length - offset < do_count ?
                      st_bp->sg[i].length - offset : do_count;
-               res = copy_to_user(ubp, page_address(st_bp->sg[i].page) + offset, cnt);
+               res = copy_to_user(ubp, page_address(sg_page(&st_bp->sg[i])) + offset, cnt);
                if (res)
                        return (-EFAULT);
                do_count -= cnt;
@@ -5410,7 +5412,7 @@ static int osst_zero_buffer_tail(struct osst_buffer *st_bp)
             i < st_bp->sg_segs && do_count > 0; i++) {
                cnt = st_bp->sg[i].length - offset < do_count ?
                      st_bp->sg[i].length - offset : do_count ;
-               memset(page_address(st_bp->sg[i].page) + offset, 0, cnt);
+               memset(page_address(sg_page(&st_bp->sg[i])) + offset, 0, cnt);
                do_count -= cnt;
                offset = 0;
        }
@@ -5430,7 +5432,7 @@ static int osst_copy_to_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
        for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
                cnt = st_bp->sg[i].length < do_count ?
                      st_bp->sg[i].length : do_count ;
-               memcpy(page_address(st_bp->sg[i].page), ptr, cnt);
+               memcpy(page_address(sg_page(&st_bp->sg[i])), ptr, cnt);
                do_count -= cnt;
                ptr      += cnt;
        }
@@ -5451,7 +5453,7 @@ static int osst_copy_from_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
        for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
                cnt = st_bp->sg[i].length < do_count ?
                      st_bp->sg[i].length : do_count ;
-               memcpy(ptr, page_address(st_bp->sg[i].page), cnt);
+               memcpy(ptr, page_address(sg_page(&st_bp->sg[i])), cnt);
                do_count -= cnt;
                ptr      += cnt;
        }
index b7f0fa24641396ca147a6ba894045adaa13e5327..7db28cd49446b2cfe685fb7a901d784f8b1f2b16 100644 (file)
@@ -24,7 +24,6 @@
 /************************************
  * Some useful macros...
  */
-#define BIT(x)      (1L << (x))
 
 /* SCSI initiator must be ID 7 */
 #define NSP_INITIATOR_ID  7
@@ -394,7 +393,7 @@ enum _burst_mode {
 #define MSG_EXT_SDTR         0x01
 
 /* scatter-gather table */
-#  define BUFFER_ADDR ((char *)((unsigned int)(SCpnt->SCp.buffer->page) + SCpnt->SCp.buffer->offset))
+#  define BUFFER_ADDR ((char *)((sg_virt(SCpnt->SCp.buffer))))
 
 #endif  /*__nsp_cs__*/
 /* end */
index 190e2a7d706748a10275bde1c40842415b459948..969b9387a0c370c8990ff2608d1238441df5fa94 100644 (file)
@@ -443,8 +443,7 @@ SYM53C500_intr(int irq, void *dev_id)
 
                        scsi_for_each_sg(curSC, sg, scsi_sg_count(curSC), i) {
                                SYM53C500_pio_write(fast_pio, port_base,
-                                                   page_address(sg->page) + sg->offset,
-                                                   sg->length);
+                                   sg_virt(sg), sg->length);
                        }
                        REG0(port_base);
                }
@@ -463,8 +462,7 @@ SYM53C500_intr(int irq, void *dev_id)
 
                        scsi_for_each_sg(curSC, sg, scsi_sg_count(curSC), i) {
                                SYM53C500_pio_read(fast_pio, port_base,
-                                                  page_address(sg->page) + sg->offset,
-                                                  sg->length);
+                                       sg_virt(sg), sg->length);
                        }
                        REG0(port_base);
                }
index 67b6d76a6c8d8f3f3d4b97ceb32a3bc6551901dc..67ee51a3d7e14c2d328ac7510284ef3fe2e67bfa 100644 (file)
@@ -608,9 +608,7 @@ static int ppa_completion(struct scsi_cmnd *cmd)
                                cmd->SCp.buffer++;
                                cmd->SCp.this_residual =
                                    cmd->SCp.buffer->length;
-                               cmd->SCp.ptr =
-                                   page_address(cmd->SCp.buffer->page) +
-                                   cmd->SCp.buffer->offset;
+                               cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
                        }
                }
                /* Now check to see if the drive is ready to comunicate */
@@ -756,8 +754,7 @@ static int ppa_engine(ppa_struct *dev, struct scsi_cmnd *cmd)
                        /* if many buffers are available, start filling the first */
                        cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
                        cmd->SCp.this_residual = cmd->SCp.buffer->length;
-                       cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) +
-                           cmd->SCp.buffer->offset;
+                       cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
                } else {
                        /* else fill the only available buffer */
                        cmd->SCp.buffer = NULL;
index 0f43d1d046d950af370e5fc902fdbee37d4edd4a..17b4a7c4618cd0e3a9667d8f2fb60da8c59e17bd 100644 (file)
@@ -111,14 +111,14 @@ static int fill_from_dev_buffer(struct scsi_cmnd *cmd, const void *buf)
        req_len = act_len = 0;
        scsi_for_each_sg(cmd, sgpnt, scsi_sg_count(cmd), k) {
                if (active) {
-                       kaddr = kmap_atomic(sgpnt->page, KM_IRQ0);
+                       kaddr = kmap_atomic(sg_page(sgpnt), KM_IRQ0);
                        len = sgpnt->length;
                        if ((req_len + len) > buflen) {
                                active = 0;
                                len = buflen - req_len;
                        }
                        memcpy(kaddr + sgpnt->offset, buf + req_len, len);
-                       flush_kernel_dcache_page(sgpnt->page);
+                       flush_kernel_dcache_page(sg_page(sgpnt));
                        kunmap_atomic(kaddr, KM_IRQ0);
                        act_len += len;
                }
@@ -147,7 +147,7 @@ static int fetch_to_dev_buffer(struct scsi_cmnd *cmd, void *buf)
 
        req_len = fin = 0;
        scsi_for_each_sg(cmd, sgpnt, scsi_sg_count(cmd), k) {
-               kaddr = kmap_atomic(sgpnt->page, KM_IRQ0);
+               kaddr = kmap_atomic(sg_page(sgpnt), KM_IRQ0);
                len = sgpnt->length;
                if ((req_len + len) > buflen) {
                        len = buflen - req_len;
index 9bb3d1d2a925a0b6a28ecd90e4af02c184c71803..fe415ec8565592924853f0d5c57da5f05453d502 100644 (file)
@@ -671,7 +671,7 @@ struct continuation_t1_entry {
 #define ET_CONTINUE    ET_CONT_T1
 
 /* Marker entry structure*/
-struct marker_entry {
+struct qla4_marker_entry {
        struct qla4_header hdr; /* 00-03 */
 
        uint32_t system_defined; /* 04-07 */
index 1e29f51d596b71d27d14226a153c0853e2eae9b8..d692c713416a54b385e486c3c02b3f90876b5fcf 100644 (file)
@@ -1006,7 +1006,7 @@ int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a)
  * qla4xxx_start_firmware - starts qla4xxx firmware
  * @ha: Pointer to host adapter structure.
  *
- * This routine performs the neccessary steps to start the firmware for
+ * This routine performs the necessary steps to start the firmware for
  * the QLA4010 adapter.
  **/
 static int qla4xxx_start_firmware(struct scsi_qla_host *ha)
index 5006ecb3ef5ea935e55a069eef9d8c9218b70a79..e4461b5d767a2305c0a1c6067e08f53db22235eb 100644 (file)
@@ -69,7 +69,7 @@ static int qla4xxx_get_req_pkt(struct scsi_qla_host *ha,
 static int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha,
                                    struct ddb_entry *ddb_entry, int lun)
 {
-       struct marker_entry *marker_entry;
+       struct qla4_marker_entry *marker_entry;
        unsigned long flags = 0;
        uint8_t status = QLA_SUCCESS;
 
index 03b68d4f3bd0e1821f84aa5d75af404e8170e16c..89460d27c68959225bc27bfb818f989a06426738 100644 (file)
@@ -1286,7 +1286,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
 
         ret = scsi_init_shared_tag_map(host, MAX_SRBS);
         if (ret) {
-                dev_warn(&ha->pdev->dev, "scsi_init_shared_tag_map failed");
+                dev_warn(&ha->pdev->dev, "scsi_init_shared_tag_map failed\n");
                 goto probe_failed;
         }
 
index 2bfbf26c00ed078bc8a3d805b3ea9a40f7aac813..de7b3bc2cbc975ecbbd12658ea95b8d9e00714f5 100644 (file)
@@ -317,7 +317,7 @@ static unsigned int ql_pcmd(struct scsi_cmnd *cmd)
                                return ((priv->qabort == 1 ?
                                         DID_ABORT : DID_RESET) << 16);
                        }
-                       buf = page_address(sg->page) + sg->offset;
+                       buf = sg_virt(sg);
                        if (ql_pdma(priv, phase, buf, sg->length))
                                break;
                }
index 72ee4c9cfb1ac0329fa8d413b5559dac46ee4a26..46cae5a212ded1df5e85b607119335065206dc98 100644 (file)
@@ -625,7 +625,7 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
        scsi_for_each_sg(scp, sg, scp->use_sg, k) {
                if (active) {
                        kaddr = (unsigned char *)
-                               kmap_atomic(sg->page, KM_USER0);
+                               kmap_atomic(sg_page(sg), KM_USER0);
                        if (NULL == kaddr)
                                return (DID_ERROR << 16);
                        kaddr_off = (unsigned char *)kaddr + sg->offset;
@@ -672,7 +672,7 @@ static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
        sg = scsi_sglist(scp);
        req_len = fin = 0;
        for (k = 0; k < scp->use_sg; ++k, sg = sg_next(sg)) {
-               kaddr = (unsigned char *)kmap_atomic(sg->page, KM_USER0);
+               kaddr = (unsigned char *)kmap_atomic(sg_page(sg), KM_USER0);
                if (NULL == kaddr)
                        return -1;
                kaddr_off = (unsigned char *)kaddr + sg->offset;
index aac8a02cbe8040348d8383d8551514a619598b2d..61fdaf02f2511fb09aa6008ab5d78b354d39554b 100644 (file)
@@ -295,7 +295,7 @@ static int scsi_req_map_sg(struct request *rq, struct scatterlist *sgl,
        int i, err, nr_vecs = 0;
 
        for_each_sg(sgl, sg, nsegs, i) {
-               page = sg->page;
+               page = sg_page(sg);
                off = sg->offset;
                len = sg->length;
                data_len += len;
@@ -764,7 +764,7 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
                if (unlikely(!sgl))
                        goto enomem;
 
-               memset(sgl, 0, sizeof(*sgl) * sgp->size);
+               sg_init_table(sgl, sgp->size);
 
                /*
                 * first loop through, set initial index and return value
@@ -780,6 +780,13 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
                if (prev)
                        sg_chain(prev, SCSI_MAX_SG_SEGMENTS, sgl);
 
+               /*
+                * if we have nothing left, mark the last segment as
+                * end-of-list
+                */
+               if (!left)
+                       sg_mark_end(sgl, this);
+
                /*
                 * don't allow subsequent mempool allocs to sleep, it would
                 * violate the mempool principle.
@@ -2353,7 +2360,7 @@ void *scsi_kmap_atomic_sg(struct scatterlist *sgl, int sg_count,
        *offset = *offset - len_complete + sg->offset;
 
        /* Assumption: contiguous pages can be accessed as "page + i" */
-       page = nth_page(sg->page, (*offset >> PAGE_SHIFT));
+       page = nth_page(sg_page(sg), (*offset >> PAGE_SHIFT));
        *offset &= ~PAGE_MASK;
 
        /* Bytes in this sg-entry from *offset to the end of the page */
index 69f542c4923ce5be9c9575cc3ec30f0c82a6b92f..a69b155f39a2b2a1c4134b440e2cd5404d478e10 100644 (file)
@@ -676,7 +676,7 @@ static int sd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
  *     success as well). Returns a negated errno value in case of error.
  *
  *     Note: most ioctls are forward onto the block subsystem or further
- *     down in the scsi subsytem.
+ *     down in the scsi subsystem.
  **/
 static int sd_ioctl(struct inode * inode, struct file * filp, 
                    unsigned int cmd, unsigned long arg)
index ce80fa9ad815906d6a234fad52f9d2ae44443c53..b11324479b5bb400696d6072e61d39803aaf816b 100644 (file)
@@ -999,14 +999,14 @@ connect_loop:
                                for (i = 0; i < nobuffs; ++i)
                                        printk("scsi%d : buffer %d address = %p length = %d\n",
                                             hostno, i,
-                                            page_address(buffer[i].page) + buffer[i].offset,
+                                            sg_virt(&buffer[i]),
                                             buffer[i].length);
                        }
 #endif
 
                        buffer = (struct scatterlist *) SCint->request_buffer;
                        len = buffer->length;
-                       data = page_address(buffer->page) + buffer->offset;
+                       data = sg_virt(buffer);
                } else {
                        DPRINTK (DEBUG_SG, "scsi%d : scatter gather not requested.\n", hostno);
                        buffer = NULL;
@@ -1239,7 +1239,7 @@ connect_loop:
                                        --nobuffs;
                                        ++buffer;
                                        len = buffer->length;
-                                       data = page_address(buffer->page) + buffer->offset;
+                                       data = sg_virt(buffer);
                                        DPRINTK (DEBUG_SG,
                                                 "scsi%d : next scatter-gather buffer len = %d address = %08x\n",
                                                 hostno, len, data);
@@ -1396,7 +1396,7 @@ connect_loop:
                                        --nobuffs;
                                        ++buffer;
                                        len = buffer->length;
-                                       data = page_address(buffer->page) + buffer->offset;
+                                       data = sg_virt(buffer);
                                        DPRINTK (DEBUG_SG, "scsi%d : next scatter-gather buffer len = %d address = %08x\n", hostno, len, data);
                                }
                                break;
index 7238b2dfc4975d9a53a82f07dfd55ff427b27e19..cc19710028468eebe01154f730076fd4abe2362a 100644 (file)
@@ -1169,7 +1169,7 @@ sg_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int *type)
                len = vma->vm_end - sa;
                len = (len < sg->length) ? len : sg->length;
                if (offset < len) {
-                       page = virt_to_page(page_address(sg->page) + offset);
+                       page = virt_to_page(page_address(sg_page(sg)) + offset);
                        get_page(page); /* increment page count */
                        break;
                }
@@ -1717,13 +1717,13 @@ st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages,
                   goto out_unlock; */
         }
 
-       sgl[0].page = pages[0];
+       sg_set_page(sgl, pages[0]);
        sgl[0].offset = uaddr & ~PAGE_MASK;
        if (nr_pages > 1) {
                sgl[0].length = PAGE_SIZE - sgl[0].offset;
                count -= sgl[0].length;
                for (i=1; i < nr_pages ; i++) {
-                       sgl[i].page = pages[i]; 
+                       sg_set_page(&sgl[i], pages[i]);
                        sgl[i].length = count < PAGE_SIZE ? count : PAGE_SIZE;
                        count -= PAGE_SIZE;
                }
@@ -1754,7 +1754,7 @@ st_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_pages,
        int i;
 
        for (i=0; i < nr_pages; i++) {
-               struct page *page = sgl[i].page;
+               struct page *page = sg_page(&sgl[i]);
 
                if (dirtied)
                        SetPageDirty(page);
@@ -1854,7 +1854,7 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
                                scatter_elem_sz_prev = ret_sz;
                        }
                }
-               sg->page = p;
+               sg_set_page(sg, p);
                sg->length = (ret_sz > num) ? num : ret_sz;
 
                SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k=%d, num=%d, "
@@ -1907,14 +1907,14 @@ sg_write_xfer(Sg_request * srp)
                onum = 1;
 
        ksglen = sg->length;
-       p = page_address(sg->page);
+       p = page_address(sg_page(sg));
        for (j = 0, k = 0; j < onum; ++j) {
                res = sg_u_iovec(hp, iovec_count, j, 1, &usglen, &up);
                if (res)
                        return res;
 
                for (; p; sg = sg_next(sg), ksglen = sg->length,
-                    p = page_address(sg->page)) {
+                    p = page_address(sg_page(sg))) {
                        if (usglen <= 0)
                                break;
                        if (ksglen > usglen) {
@@ -1991,12 +1991,12 @@ sg_remove_scat(Sg_scatter_hold * schp)
                } else {
                        int k;
 
-                       for (k = 0; (k < schp->k_use_sg) && sg->page;
+                       for (k = 0; (k < schp->k_use_sg) && sg_page(sg);
                             ++k, sg = sg_next(sg)) {
                                SCSI_LOG_TIMEOUT(5, printk(
                                    "sg_remove_scat: k=%d, pg=0x%p, len=%d\n",
-                                   k, sg->page, sg->length));
-                               sg_page_free(sg->page, sg->length);
+                                   k, sg_page(sg), sg->length));
+                               sg_page_free(sg_page(sg), sg->length);
                        }
                }
                kfree(schp->buffer);
@@ -2038,7 +2038,7 @@ sg_read_xfer(Sg_request * srp)
        } else
                onum = 1;
 
-       p = page_address(sg->page);
+       p = page_address(sg_page(sg));
        ksglen = sg->length;
        for (j = 0, k = 0; j < onum; ++j) {
                res = sg_u_iovec(hp, iovec_count, j, 0, &usglen, &up);
@@ -2046,7 +2046,7 @@ sg_read_xfer(Sg_request * srp)
                        return res;
 
                for (; p; sg = sg_next(sg), ksglen = sg->length,
-                    p = page_address(sg->page)) {
+                    p = page_address(sg_page(sg))) {
                        if (usglen <= 0)
                                break;
                        if (ksglen > usglen) {
@@ -2092,15 +2092,15 @@ sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer)
        if ((!outp) || (num_read_xfer <= 0))
                return 0;
 
-       for (k = 0; (k < schp->k_use_sg) && sg->page; ++k, sg = sg_next(sg)) {
+       for (k = 0; (k < schp->k_use_sg) && sg_page(sg); ++k, sg = sg_next(sg)) {
                num = sg->length;
                if (num > num_read_xfer) {
-                       if (__copy_to_user(outp, page_address(sg->page),
+                       if (__copy_to_user(outp, page_address(sg_page(sg)),
                                           num_read_xfer))
                                return -EFAULT;
                        break;
                } else {
-                       if (__copy_to_user(outp, page_address(sg->page),
+                       if (__copy_to_user(outp, page_address(sg_page(sg)),
                                           num))
                                return -EFAULT;
                        num_read_xfer -= num;
index 73c44cbdea478411d5edad39f308fb97f942f2fb..ce69b9efc10245f01dcdc4e26e7ad58a57adb002 100644 (file)
@@ -3797,7 +3797,7 @@ static void buf_to_sg(struct st_buffer *STbp, unsigned int length)
        sg = &(STbp->sg[0]);
        frp = STbp->frp;
        for (i=count=0; count < length; i++) {
-               sg[i].page = frp[i].page;
+               sg_set_page(&sg[i], frp[i].page);
                if (length - count > frp[i].length)
                        sg[i].length = frp[i].length;
                else
@@ -4446,14 +4446,14 @@ static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pa
         }
 
        /* Populate the scatter/gather list */
-       sgl[0].page = pages[0]; 
+       sg_set_page(&sgl[0], pages[0]);
        sgl[0].offset = uaddr & ~PAGE_MASK;
        if (nr_pages > 1) {
                sgl[0].length = PAGE_SIZE - sgl[0].offset;
                count -= sgl[0].length;
                for (i=1; i < nr_pages ; i++) {
+                       sg_set_page(&sgl[i], pages[i]);;
                        sgl[i].offset = 0;
-                       sgl[i].page = pages[i]; 
                        sgl[i].length = count < PAGE_SIZE ? count : PAGE_SIZE;
                        count -= PAGE_SIZE;
                }
@@ -4483,7 +4483,7 @@ static int sgl_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_p
        int i;
 
        for (i=0; i < nr_pages; i++) {
-               struct page *page = sgl[i].page;
+               struct page *page = sg_page(&sgl[i]);
 
                if (dirtied)
                        SetPageDirty(page);
index dc15a22105f71ac6102cd4b63e5b60c2ab4ca3ef..2dcde373b20e45dda1d555f31c1c5e0429c7e058 100644 (file)
@@ -272,8 +272,7 @@ static struct scsi_host_template *the_template = NULL;
 #define        HOSTNO          instance->host_no
 #define        H_NO(cmd)       (cmd)->device->host->host_no
 
-#define SGADDR(buffer) (void *)(((unsigned long)page_address((buffer)->page)) + \
-                       (buffer)->offset)
+#define SGADDR(buffer) (void *)(((unsigned long)sg_virt(((buffer)))))
 
 #ifdef SUPPORT_TAGS
 
@@ -1596,7 +1595,7 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd,
      * IO while SEL is true. But again, there are some disks out the in the
      * world that do that nevertheless. (Somebody claimed that this announces
      * reselection capability of the target.) So we better skip that test and
-     * only wait for BSY... (Famous german words: Der Klügere gibt nach :-)
+     * only wait for BSY... (Famous german words: Der Klügere gibt nach :-)
      */
 
     while (time_before(jiffies, timeout) && !(NCR5380_read(STATUS_REG) & 
index 8befab7e98397b759c9c3a80989b5f4edb5f42ee..90cee94d9522df03d493a833ed7297c368bc9126 100644 (file)
@@ -196,7 +196,7 @@ static unsigned int sym53c416_base_3[2] = {0,0};
 
 #define MAXHOSTS 4
 
-#define SG_ADDRESS(buffer)     ((char *) (page_address((buffer)->page)+(buffer)->offset))
+#define SG_ADDRESS(buffer)     ((char *) sg_virt((buffer)))
 
 enum phases
 {
index 6e5b952312e364bcd8f9d7c73fdbcb1183486fd5..ae1fb179b88e571ea6e0e0ad544d6449476a0299 100644 (file)
@@ -1781,7 +1781,7 @@ static struct SYM_FWB_SCR SYM_FWB_SCR = {
         *  While testing with bogus QUANTUM drives, the C1010 
         *  sometimes raised a spurious phase mismatch with 
         *  WSR and the CHMOV(1) triggered another PM.
-        *  Waiting explicitely for the PHASE seemed to avoid 
+        *  Waiting explicitly for the PHASE seemed to avoid
         *  the nested phase mismatch. Btw, this didn't happen 
         *  using my IBM drives.
         */
index 5c72ca31a47a9d69a11915f76d7f9e645071b685..44193049c4aed96de169fcea061f52536bf7e92f 100644 (file)
@@ -430,10 +430,7 @@ static __inline__ void dc390_Going_remove (struct dc390_dcb* pDCB, struct dc390_
 
 static struct scatterlist* dc390_sg_build_single(struct scatterlist *sg, void *addr, unsigned int length)
 {
-       memset(sg, 0, sizeof(struct scatterlist));
-       sg->page        = virt_to_page(addr);
-       sg->length      = length;
-       sg->offset      = (unsigned long)addr & ~PAGE_MASK;
+       sg_init_one(sg, addr, length);
        return sg;
 }
 
index ea72bbeb8f9d54ae4a02cf505480e4bca463b29c..6d1f0edd7985632384c83d47793946f88c262875 100644 (file)
@@ -681,7 +681,7 @@ static inline void build_sg_list(struct mscp *mscp, struct scsi_cmnd *SCpnt)
 
        max = scsi_sg_count(SCpnt);
        scsi_for_each_sg(SCpnt, sg, max, i) {
-               mscp->sglist[i].address = isa_page_to_bus(sg->page) + sg->offset;
+               mscp->sglist[i].address = isa_page_to_bus(sg_page(sg)) + sg->offset;
                mscp->sglist[i].num_bytes = sg->length;
                transfer_length += sg->length;
        }
index 0e8e642fd3b031f28dbea5adec68b41e64206474..fdbb92d1f72259aa72f82f90689b072fda504c2a 100644 (file)
@@ -410,8 +410,7 @@ wd33c93_queuecommand(struct scsi_cmnd *cmd,
        if (cmd->use_sg) {
                cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
                cmd->SCp.buffers_residual = cmd->use_sg - 1;
-               cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) +
-                   cmd->SCp.buffer->offset;
+               cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
                cmd->SCp.this_residual = cmd->SCp.buffer->length;
        } else {
                cmd->SCp.buffer = NULL;
@@ -745,8 +744,7 @@ transfer_bytes(const wd33c93_regs regs, struct scsi_cmnd *cmd,
                ++cmd->SCp.buffer;
                --cmd->SCp.buffers_residual;
                cmd->SCp.this_residual = cmd->SCp.buffer->length;
-               cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) +
-                   cmd->SCp.buffer->offset;
+               cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
        }
        if (!cmd->SCp.this_residual) /* avoid bogus setups */
                return;
index 61ffb860dacc78dd5484953145413d1563312129..00123f2383d7c6d6c8557d16ef1329c642c0df1c 100644 (file)
 #define WD33C93_FS_12_15 OWNID_FS_12
 #define WD33C93_FS_16_20 OWNID_FS_16
 
-   /* pass input-clock explicitely. accepted mhz values are 8-10,12-20 */
+   /* pass input-clock explicitly. accepted mhz values are 8-10,12-20 */
 #define WD33C93_FS_MHZ(mhz) (mhz)
 
    /* Control register */
index 255c611e78b8469a8ee2b2951c18f3b357d123c5..03cd44f231dff37f64024f48483afd99d2c49818 100644 (file)
@@ -1123,7 +1123,7 @@ static int wd7000_queuecommand(struct scsi_cmnd *SCpnt,
                any2scsi(scb->maxlen, nseg * sizeof(Sgb));
 
                scsi_for_each_sg(SCpnt, sg, nseg, i) {
-                       any2scsi(sgb[i].ptr, isa_page_to_bus(sg->page) + sg->offset);
+                       any2scsi(sgb[i].ptr, isa_page_to_bus(sg_page(sg)) + sg->offset);
                        any2scsi(sgb[i].len, sg->length);
                }
        } else {
index d6ae38e55d01f72045fd7e8c239420937fa62298..ed438bc7e98da46549a25c8caeb3e839b1c777ad 100644 (file)
@@ -62,11 +62,11 @@ config SERIAL_8250_CONSOLE
          kernel will automatically use the first serial line, /dev/ttyS0, as
          system console.
 
-         you can set that using a kernel command line option such as
+         You can set that using a kernel command line option such as
          "console=uart8250,io,0x3f8,9600n8"
          "console=uart8250,mmio,0xff5e0000,115200n8".
-         and it will switch to normal serial console when correponding port is
-         ready.
+         and it will switch to normal serial console when the corresponding 
+         port is ready.
          "earlycon=uart8250,io,0x3f8,9600n8"
          "earlycon=uart8250,mmio,0xff5e0000,115200n8".
          it will not only setup early console.
@@ -624,7 +624,7 @@ choice
 
 config SERIAL_BFIN_DMA
        bool "DMA mode"
-       depends on DMA_UNCACHED_1M && !KGDB_UART
+       depends on !DMA_UNCACHED_NONE && !KGDB_UART
        help
          This driver works under DMA mode. If this option is selected, the
          blackfin simple dma driver is also enabled.
index 72229df9dc111754a74de5b1e3fb4eb896d8768e..40604a092921dac7352161ffeed1820caa11216f 100644 (file)
@@ -263,15 +263,15 @@ static unsigned int pl01x_get_mctrl(struct uart_port *port)
        unsigned int result = 0;
        unsigned int status = readw(uap->port.membase + UART01x_FR);
 
-#define BIT(uartbit, tiocmbit)         \
+#define TIOCMBIT(uartbit, tiocmbit)    \
        if (status & uartbit)           \
                result |= tiocmbit
 
-       BIT(UART01x_FR_DCD, TIOCM_CAR);
-       BIT(UART01x_FR_DSR, TIOCM_DSR);
-       BIT(UART01x_FR_CTS, TIOCM_CTS);
-       BIT(UART011_FR_RI, TIOCM_RNG);
-#undef BIT
+       TIOCMBIT(UART01x_FR_DCD, TIOCM_CAR);
+       TIOCMBIT(UART01x_FR_DSR, TIOCM_DSR);
+       TIOCMBIT(UART01x_FR_CTS, TIOCM_CTS);
+       TIOCMBIT(UART011_FR_RI, TIOCM_RNG);
+#undef TIOCMBIT
        return result;
 }
 
@@ -282,18 +282,18 @@ static void pl011_set_mctrl(struct uart_port *port, unsigned int mctrl)
 
        cr = readw(uap->port.membase + UART011_CR);
 
-#define        BIT(tiocmbit, uartbit)          \
+#define        TIOCMBIT(tiocmbit, uartbit)             \
        if (mctrl & tiocmbit)           \
                cr |= uartbit;          \
        else                            \
                cr &= ~uartbit
 
-       BIT(TIOCM_RTS, UART011_CR_RTS);
-       BIT(TIOCM_DTR, UART011_CR_DTR);
-       BIT(TIOCM_OUT1, UART011_CR_OUT1);
-       BIT(TIOCM_OUT2, UART011_CR_OUT2);
-       BIT(TIOCM_LOOP, UART011_CR_LBE);
-#undef BIT
+       TIOCMBIT(TIOCM_RTS, UART011_CR_RTS);
+       TIOCMBIT(TIOCM_DTR, UART011_CR_DTR);
+       TIOCMBIT(TIOCM_OUT1, UART011_CR_OUT1);
+       TIOCMBIT(TIOCM_OUT2, UART011_CR_OUT2);
+       TIOCMBIT(TIOCM_LOOP, UART011_CR_LBE);
+#undef TIOCMBIT
 
        writew(cr, uap->port.membase + UART011_CR);
 }
index 7e8724d3571f3f53219075ddabbd667f40517d34..f523cdf4b02b52a3a439a0a80d8cf52af4612842 100644 (file)
@@ -442,11 +442,11 @@ static char *serial_version = "$Revision: 1.25 $";
 #include <asm/uaccess.h>
 #include <linux/kernel.h>
 #include <linux/mutex.h>
+#include <linux/bitops.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/system.h>
-#include <asm/bitops.h>
 #include <linux/delay.h>
 
 #include <asm/arch/svinto.h>
diff --git a/drivers/serial/mcf.c b/drivers/serial/mcf.c
new file mode 100644 (file)
index 0000000..a7d4360
--- /dev/null
@@ -0,0 +1,653 @@
+/****************************************************************************/
+
+/*
+ *     mcf.c -- Freescale ColdFire UART driver
+ *
+ *     (C) Copyright 2003-2007, Greg Ungerer <gerg@snapgear.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+/****************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/console.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfuart.h>
+#include <asm/nettel.h>
+
+/****************************************************************************/
+
+/*
+ *     Some boards implement the DTR/DCD lines using GPIO lines, most
+ *     don't. Dummy out the access macros for those that don't. Those
+ *     that do should define these macros somewhere in there board
+ *     specific inlude files.
+ */
+#if !defined(mcf_getppdcd)
+#define        mcf_getppdcd(p)         (1)
+#endif
+#if !defined(mcf_getppdtr)
+#define        mcf_getppdtr(p)         (1)
+#endif
+#if !defined(mcf_setppdtr)
+#define        mcf_setppdtr(p, v)      do { } while (0)
+#endif
+
+/****************************************************************************/
+
+/*
+ *     Local per-uart structure.
+ */
+struct mcf_uart {
+       struct uart_port        port;
+       unsigned int            sigs;           /* Local copy of line sigs */
+       unsigned char           imr;            /* Local IMR mirror */
+};
+
+/****************************************************************************/
+
+static unsigned int mcf_tx_empty(struct uart_port *port)
+{
+       return (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXEMPTY) ?
+               TIOCSER_TEMT : 0;
+}
+
+/****************************************************************************/
+
+static unsigned int mcf_get_mctrl(struct uart_port *port)
+{
+       struct mcf_uart *pp = (struct mcf_uart *) port;
+       unsigned long flags;
+       unsigned int sigs;
+
+       spin_lock_irqsave(&port->lock, flags);
+       sigs = (readb(port->membase + MCFUART_UIPR) & MCFUART_UIPR_CTS) ?
+               0 : TIOCM_CTS;
+       sigs |= (pp->sigs & TIOCM_RTS);
+       sigs |= (mcf_getppdcd(port->line) ? TIOCM_CD : 0);
+       sigs |= (mcf_getppdtr(port->line) ? TIOCM_DTR : 0);
+       spin_unlock_irqrestore(&port->lock, flags);
+       return sigs;
+}
+
+/****************************************************************************/
+
+static void mcf_set_mctrl(struct uart_port *port, unsigned int sigs)
+{
+       struct mcf_uart *pp = (struct mcf_uart *) port;
+       unsigned long flags;
+
+       spin_lock_irqsave(&port->lock, flags);
+       pp->sigs = sigs;
+       mcf_setppdtr(port->line, (sigs & TIOCM_DTR));
+       if (sigs & TIOCM_RTS)
+               writeb(MCFUART_UOP_RTS, port->membase + MCFUART_UOP1);
+       else
+               writeb(MCFUART_UOP_RTS, port->membase + MCFUART_UOP0);
+       spin_unlock_irqrestore(&port->lock, flags);
+}
+
+/****************************************************************************/
+
+static void mcf_start_tx(struct uart_port *port)
+{
+       struct mcf_uart *pp = (struct mcf_uart *) port;
+       unsigned long flags;
+
+       spin_lock_irqsave(&port->lock, flags);
+       pp->imr |= MCFUART_UIR_TXREADY;
+       writeb(pp->imr, port->membase + MCFUART_UIMR);
+       spin_unlock_irqrestore(&port->lock, flags);
+}
+
+/****************************************************************************/
+
+static void mcf_stop_tx(struct uart_port *port)
+{
+       struct mcf_uart *pp = (struct mcf_uart *) port;
+       unsigned long flags;
+
+       spin_lock_irqsave(&port->lock, flags);
+       pp->imr &= ~MCFUART_UIR_TXREADY;
+       writeb(pp->imr, port->membase + MCFUART_UIMR);
+       spin_unlock_irqrestore(&port->lock, flags);
+}
+
+/****************************************************************************/
+
+static void mcf_stop_rx(struct uart_port *port)
+{
+       struct mcf_uart *pp = (struct mcf_uart *) port;
+       unsigned long flags;
+
+       spin_lock_irqsave(&port->lock, flags);
+       pp->imr &= ~MCFUART_UIR_RXREADY;
+       writeb(pp->imr, port->membase + MCFUART_UIMR);
+       spin_unlock_irqrestore(&port->lock, flags);
+}
+
+/****************************************************************************/
+
+static void mcf_break_ctl(struct uart_port *port, int break_state)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&port->lock, flags);
+       if (break_state == -1)
+               writeb(MCFUART_UCR_CMDBREAKSTART, port->membase + MCFUART_UCR);
+       else
+               writeb(MCFUART_UCR_CMDBREAKSTOP, port->membase + MCFUART_UCR);
+       spin_unlock_irqrestore(&port->lock, flags);
+}
+
+/****************************************************************************/
+
+static void mcf_enable_ms(struct uart_port *port)
+{
+}
+
+/****************************************************************************/
+
+static int mcf_startup(struct uart_port *port)
+{
+       struct mcf_uart *pp = (struct mcf_uart *) port;
+       unsigned long flags;
+
+       spin_lock_irqsave(&port->lock, flags);
+
+       /* Reset UART, get it into known state... */
+       writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR);
+       writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR);
+
+       /* Enable the UART transmitter and receiver */
+       writeb(MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE,
+               port->membase + MCFUART_UCR);
+
+       /* Enable RX interrupts now */
+       pp->imr = MCFUART_UIR_RXREADY;
+       writeb(pp->imr, port->membase + MCFUART_UIMR);
+
+       spin_unlock_irqrestore(&port->lock, flags);
+
+       return 0;
+}
+
+/****************************************************************************/
+
+static void mcf_shutdown(struct uart_port *port)
+{
+       struct mcf_uart *pp = (struct mcf_uart *) port;
+       unsigned long flags;
+
+       spin_lock_irqsave(&port->lock, flags);
+
+       /* Disable all interrupts now */
+       pp->imr = 0;
+       writeb(pp->imr, port->membase + MCFUART_UIMR);
+
+       /* Disable UART transmitter and receiver */
+       writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR);
+       writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR);
+
+       spin_unlock_irqrestore(&port->lock, flags);
+}
+
+/****************************************************************************/
+
+static void mcf_set_termios(struct uart_port *port, struct ktermios *termios,
+       struct ktermios *old)
+{
+       unsigned long flags;
+       unsigned int baud, baudclk;
+       unsigned char mr1, mr2;
+
+       baud = uart_get_baud_rate(port, termios, old, 0, 230400);
+       baudclk = ((MCF_BUSCLK / baud) + 16) / 32;
+
+       mr1 = MCFUART_MR1_RXIRQRDY | MCFUART_MR1_RXERRCHAR;
+       mr2 = 0;
+
+       switch (termios->c_cflag & CSIZE) {
+       case CS5: mr1 |= MCFUART_MR1_CS5; break;
+       case CS6: mr1 |= MCFUART_MR1_CS6; break;
+       case CS7: mr1 |= MCFUART_MR1_CS7; break;
+       case CS8:
+       default:  mr1 |= MCFUART_MR1_CS8; break;
+       }
+
+       if (termios->c_cflag & PARENB) {
+               if (termios->c_cflag & CMSPAR) {
+                       if (termios->c_cflag & PARODD)
+                               mr1 |= MCFUART_MR1_PARITYMARK;
+                       else
+                               mr1 |= MCFUART_MR1_PARITYSPACE;
+               } else {
+                       if (termios->c_cflag & PARODD)
+                               mr1 |= MCFUART_MR1_PARITYODD;
+                       else
+                               mr1 |= MCFUART_MR1_PARITYEVEN;
+               }
+       } else {
+               mr1 |= MCFUART_MR1_PARITYNONE;
+       }
+
+       if (termios->c_cflag & CSTOPB)
+               mr2 |= MCFUART_MR2_STOP2;
+       else
+               mr2 |= MCFUART_MR2_STOP1;
+
+       if (termios->c_cflag & CRTSCTS) {
+               mr1 |= MCFUART_MR1_RXRTS;
+               mr2 |= MCFUART_MR2_TXCTS;
+       }
+
+       spin_lock_irqsave(&port->lock, flags);
+       writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR);
+       writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR);
+       writeb(MCFUART_UCR_CMDRESETMRPTR, port->membase + MCFUART_UCR);
+       writeb(mr1, port->membase + MCFUART_UMR);
+       writeb(mr2, port->membase + MCFUART_UMR);
+       writeb((baudclk & 0xff00) >> 8, port->membase + MCFUART_UBG1);
+       writeb((baudclk & 0xff), port->membase + MCFUART_UBG2);
+       writeb(MCFUART_UCSR_RXCLKTIMER | MCFUART_UCSR_TXCLKTIMER,
+               port->membase + MCFUART_UCSR);
+       writeb(MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE,
+               port->membase + MCFUART_UCR);
+       spin_unlock_irqrestore(&port->lock, flags);
+}
+
+/****************************************************************************/
+
+static void mcf_rx_chars(struct mcf_uart *pp)
+{
+       struct uart_port *port = (struct uart_port *) pp;
+       unsigned char status, ch, flag;
+
+       while ((status = readb(port->membase + MCFUART_USR)) & MCFUART_USR_RXREADY) {
+               ch = readb(port->membase + MCFUART_URB);
+               flag = TTY_NORMAL;
+               port->icount.rx++;
+
+               if (status & MCFUART_USR_RXERR) {
+                       writeb(MCFUART_UCR_CMDRESETERR,
+                               port->membase + MCFUART_UCR);
+
+                       if (status & MCFUART_USR_RXBREAK) {
+                               port->icount.brk++;
+                               if (uart_handle_break(port))
+                                       continue;
+                       } else if (status & MCFUART_USR_RXPARITY) {
+                               port->icount.parity++;
+                       } else if (status & MCFUART_USR_RXOVERRUN) {
+                               port->icount.overrun++;
+                       } else if (status & MCFUART_USR_RXFRAMING) {
+                               port->icount.frame++;
+                       }
+
+                       status &= port->read_status_mask;
+
+                       if (status & MCFUART_USR_RXBREAK)
+                               flag = TTY_BREAK;
+                       else if (status & MCFUART_USR_RXPARITY)
+                               flag = TTY_PARITY;
+                       else if (status & MCFUART_USR_RXFRAMING)
+                               flag = TTY_FRAME;
+               }
+
+               if (uart_handle_sysrq_char(port, ch))
+                       continue;
+               uart_insert_char(port, status, MCFUART_USR_RXOVERRUN, ch, flag);
+       }
+
+       tty_flip_buffer_push(port->info->tty);
+}
+
+/****************************************************************************/
+
+static void mcf_tx_chars(struct mcf_uart *pp)
+{
+       struct uart_port *port = (struct uart_port *) pp;
+       struct circ_buf *xmit = &port->info->xmit;
+
+       if (port->x_char) {
+               /* Send special char - probably flow control */
+               writeb(port->x_char, port->membase + MCFUART_UTB);
+               port->x_char = 0;
+               port->icount.tx++;
+               return;
+       }
+
+       while (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXREADY) {
+               if (xmit->head == xmit->tail)
+                       break;
+               writeb(xmit->buf[xmit->tail], port->membase + MCFUART_UTB);
+               xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE -1);
+               port->icount.tx++;
+       }
+
+       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+               uart_write_wakeup(port);
+
+       if (xmit->head == xmit->tail) {
+               pp->imr &= ~MCFUART_UIR_TXREADY;
+               writeb(pp->imr, port->membase + MCFUART_UIMR);
+       }
+}
+
+/****************************************************************************/
+
+static irqreturn_t mcf_interrupt(int irq, void *data)
+{
+       struct uart_port *port = data;
+       struct mcf_uart *pp = (struct mcf_uart *) port;
+       unsigned int isr;
+
+       isr = readb(port->membase + MCFUART_UISR) & pp->imr;
+       if (isr & MCFUART_UIR_RXREADY)
+               mcf_rx_chars(pp);
+       if (isr & MCFUART_UIR_TXREADY)
+               mcf_tx_chars(pp);
+       return IRQ_HANDLED;
+}
+
+/****************************************************************************/
+
+static void mcf_config_port(struct uart_port *port, int flags)
+{
+       port->type = PORT_MCF;
+
+       /* Clear mask, so no surprise interrupts. */
+       writeb(0, port->membase + MCFUART_UIMR);
+
+       if (request_irq(port->irq, mcf_interrupt, IRQF_DISABLED, "UART", port))
+               printk(KERN_ERR "MCF: unable to attach ColdFire UART %d "
+                       "interrupt vector=%d\n", port->line, port->irq);
+}
+
+/****************************************************************************/
+
+static const char *mcf_type(struct uart_port *port)
+{
+       return (port->type == PORT_MCF) ? "ColdFire UART" : NULL;
+}
+
+/****************************************************************************/
+
+static int mcf_request_port(struct uart_port *port)
+{
+       /* UARTs always present */
+       return 0;
+}
+
+/****************************************************************************/
+
+static void mcf_release_port(struct uart_port *port)
+{
+       /* Nothing to release... */
+}
+
+/****************************************************************************/
+
+static int mcf_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+       if ((ser->type != PORT_UNKNOWN) && (ser->type != PORT_MCF))
+               return -EINVAL;
+       return 0;
+}
+
+/****************************************************************************/
+
+/*
+ *     Define the basic serial functions we support.
+ */
+static struct uart_ops mcf_uart_ops = {
+       .tx_empty       = mcf_tx_empty,
+       .get_mctrl      = mcf_get_mctrl,
+       .set_mctrl      = mcf_set_mctrl,
+       .start_tx       = mcf_start_tx,
+       .stop_tx        = mcf_stop_tx,
+       .stop_rx        = mcf_stop_rx,
+       .enable_ms      = mcf_enable_ms,
+       .break_ctl      = mcf_break_ctl,
+       .startup        = mcf_startup,
+       .shutdown       = mcf_shutdown,
+       .set_termios    = mcf_set_termios,
+       .type           = mcf_type,
+       .request_port   = mcf_request_port,
+       .release_port   = mcf_release_port,
+       .config_port    = mcf_config_port,
+       .verify_port    = mcf_verify_port,
+};
+
+static struct mcf_uart mcf_ports[3];
+
+#define        MCF_MAXPORTS    (sizeof(mcf_ports) / sizeof(struct mcf_uart))
+
+/****************************************************************************/
+#if defined(CONFIG_SERIAL_MCF_CONSOLE)
+/****************************************************************************/
+
+int __init early_mcf_setup(struct mcf_platform_uart *platp)
+{
+       struct uart_port *port;
+       int i;
+
+       for (i = 0; ((i < MCF_MAXPORTS) && (platp[i].mapbase)); i++) {
+               port = &mcf_ports[i].port;
+
+               port->line = i;
+               port->type = PORT_MCF;
+               port->mapbase = platp[i].mapbase;
+               port->membase = (platp[i].membase) ? platp[i].membase :
+                       (unsigned char __iomem *) port->mapbase;
+               port->iotype = SERIAL_IO_MEM;
+               port->irq = platp[i].irq;
+               port->uartclk = MCF_BUSCLK;
+               port->flags = ASYNC_BOOT_AUTOCONF;
+               port->ops = &mcf_uart_ops;
+       }
+
+       return 0;
+}
+
+/****************************************************************************/
+
+static void mcf_console_putc(struct console *co, const char c)
+{
+       struct uart_port *port = &(mcf_ports + co->index)->port;
+       int i;
+
+       for (i = 0; (i < 0x10000); i++) {
+               if (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXREADY)
+                       break;
+       }
+       writeb(c, port->membase + MCFUART_UTB);
+       for (i = 0; (i < 0x10000); i++) {
+               if (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXREADY)
+                       break;
+       }
+}
+
+/****************************************************************************/
+
+static void mcf_console_write(struct console *co, const char *s, unsigned int count)
+{
+       for (; (count); count--, s++) {
+               mcf_console_putc(co, *s);
+               if (*s == '\n')
+                       mcf_console_putc(co, '\r');
+       }
+}
+
+/****************************************************************************/
+
+static int __init mcf_console_setup(struct console *co, char *options)
+{
+       struct uart_port *port;
+       int baud = CONFIG_SERIAL_MCF_BAUDRATE;
+       int bits = 8;
+       int parity = 'n';
+       int flow = 'n';
+
+       if ((co->index >= 0) && (co->index <= MCF_MAXPORTS))
+               co->index = 0;
+       port = &mcf_ports[co->index].port;
+       if (port->membase == 0)
+               return -ENODEV;
+
+       if (options)
+               uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+       return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+/****************************************************************************/
+
+static struct uart_driver mcf_driver;
+
+static struct console mcf_console = {
+       .name           = "ttyS",
+       .write          = mcf_console_write,
+       .device         = uart_console_device,
+       .setup          = mcf_console_setup,
+       .flags          = CON_PRINTBUFFER,
+       .index          = -1,
+       .data           = &mcf_driver,
+};
+
+static int __init mcf_console_init(void)
+{
+       register_console(&mcf_console);
+       return 0;
+}
+
+console_initcall(mcf_console_init);
+
+#define        MCF_CONSOLE     &mcf_console
+
+/****************************************************************************/
+#else
+/****************************************************************************/
+
+#define        MCF_CONSOLE     NULL
+
+/****************************************************************************/
+#endif /* CONFIG_MCF_CONSOLE */
+/****************************************************************************/
+
+/*
+ *     Define the mcf UART driver structure.
+ */
+static struct uart_driver mcf_driver = {
+       .owner          = THIS_MODULE,
+       .driver_name    = "mcf",
+       .dev_name       = "ttyS",
+       .major          = TTY_MAJOR,
+       .minor          = 64,
+       .nr             = MCF_MAXPORTS,
+       .cons           = MCF_CONSOLE,
+};
+
+/****************************************************************************/
+
+static int __devinit mcf_probe(struct platform_device *pdev)
+{
+       struct mcf_platform_uart *platp = pdev->dev.platform_data;
+       struct uart_port *port;
+       int i;
+
+       for (i = 0; ((i < MCF_MAXPORTS) && (platp[i].mapbase)); i++) {
+               port = &mcf_ports[i].port;
+
+               port->line = i;
+               port->type = PORT_MCF;
+               port->mapbase = platp[i].mapbase;
+               port->membase = (platp[i].membase) ? platp[i].membase :
+                       (unsigned char __iomem *) platp[i].mapbase;
+               port->iotype = SERIAL_IO_MEM;
+               port->irq = platp[i].irq;
+               port->uartclk = MCF_BUSCLK;
+               port->ops = &mcf_uart_ops;
+               port->flags = ASYNC_BOOT_AUTOCONF;
+
+               uart_add_one_port(&mcf_driver, port);
+       }
+
+       return 0;
+}
+
+/****************************************************************************/
+
+static int mcf_remove(struct platform_device *pdev)
+{
+       struct uart_port *port;
+       int i;
+
+       for (i = 0; (i < MCF_MAXPORTS); i++) {
+               port = &mcf_ports[i].port;
+               if (port)
+                       uart_remove_one_port(&mcf_driver, port);
+       }
+
+       return 0;
+}
+
+/****************************************************************************/
+
+static struct platform_driver mcf_platform_driver = {
+       .probe          = mcf_probe,
+       .remove         = __devexit_p(mcf_remove),
+       .driver         = {
+               .name   = "mcfuart",
+               .owner  = THIS_MODULE,
+       },
+};
+
+/****************************************************************************/
+
+static int __init mcf_init(void)
+{
+       int rc;
+
+       printk("ColdFire internal UART serial driver\n");
+
+       rc = uart_register_driver(&mcf_driver);
+       if (rc)
+               return rc;
+       rc = platform_driver_register(&mcf_platform_driver);
+       if (rc)
+               return rc;
+       return 0;
+}
+
+/****************************************************************************/
+
+static void __exit mcf_exit(void)
+{
+       platform_driver_unregister(&mcf_platform_driver);
+       uart_unregister_driver(&mcf_driver);
+}
+
+/****************************************************************************/
+
+module_init(mcf_init);
+module_exit(mcf_exit);
+
+MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com>");
+MODULE_DESCRIPTION("Freescale ColdFire UART driver");
+MODULE_LICENSE("GPL");
+
+/****************************************************************************/
index 3f26c4b2f322a0e4140a8987c4b21c42894c84b3..e773c8e1496245bcaca63984bc9ff07ac055c4f9 100644 (file)
@@ -20,8 +20,8 @@
  *                  - S3C2410 and S3C2440 serial support
  *                  - Power Management support
  *                  - Fix console via IrDA devices
- *                  - SysReq (Herbert Pötzl)
- *                  - Break character handling (Herbert Pötzl)
+ *                  - SysReq (Herbert Pötzl)
+ *                  - Break character handling (Herbert Pötzl)
  *                  - spin-lock initialisation (Dimitry Andric)
  *                  - added clock control
  *                  - updated init code to use platform_device info
index 68aa4da0186573fce0ed514f0d1ea0e784e864e5..103189095c80344ecadcdf15db3112abe8f947c1 100644 (file)
@@ -1959,12 +1959,11 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
 
        mutex_lock(&state->mutex);
 
-#ifdef CONFIG_DISABLE_CONSOLE_SUSPEND
-       if (uart_console(port)) {
+       if (!console_suspend_enabled && uart_console(port)) {
+               /* we're going to avoid suspending serial console */
                mutex_unlock(&state->mutex);
                return 0;
        }
-#endif
 
        tty_dev = device_find_child(port->dev, &match, serial_match_port);
        if (device_may_wakeup(tty_dev)) {
@@ -2016,12 +2015,11 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
 
        mutex_lock(&state->mutex);
 
-#ifdef CONFIG_DISABLE_CONSOLE_SUSPEND
-       if (uart_console(port)) {
+       if (!console_suspend_enabled && uart_console(port)) {
+               /* no need to resume serial console, it wasn't suspended */
                mutex_unlock(&state->mutex);
                return 0;
        }
-#endif
 
        if (!port->suspended) {
                disable_irq_wake(port->irq);
index e9aba932f21795184a9aeb0323307b2e6d3866c4..7051e6c5edc345b7bd21c9fc61c8070949712f3a 100644 (file)
@@ -181,7 +181,7 @@ static int mpc52xx_psc_spi_transfer_rxtx(struct spi_device *spi,
                }
 
 
-               /* enable interupts and wait for wake up
+               /* enable interrupts and wait for wake up
                 * if just one byte is expected the Rx FIFO genererates no
                 * FFULL interrupt, so activate the RxRDY interrupt
                 */
index 6cb71d74738f45671ce846be7d76c2c549054bcc..2ef11bb70b2ee9c5b588a432c006efa0cee2320c 100644 (file)
@@ -1070,7 +1070,7 @@ static int setup(struct spi_device *spi)
                return -ENODEV;
        }
 
-       dev_dbg(&spi->dev, "setup spi chip %s, width is %d, dma is %d,",
+       dev_dbg(&spi->dev, "setup spi chip %s, width is %d, dma is %d\n",
                        spi->modalias, chip->width, chip->enable_dma);
        dev_dbg(&spi->dev, "ctl_reg is 0x%x, flag_reg is 0x%x\n",
                        chip->ctl_reg, chip->flag);
index 3b4650ae6f1ab14acd070d9b87f0faa75c1e3ce2..7686ba34430f7011a1d65e0fbf5004c2e40d2384 100644 (file)
@@ -1194,7 +1194,7 @@ static int setup(struct spi_device *spi)
                chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL);
                if (!chip) {
                        dev_err(&spi->dev,
-                               "setup - cannot allocate controller state");
+                               "setup - cannot allocate controller state\n");
                        return -ENOMEM;
                }
                chip->control = SPI_DEFAULT_CONTROL;
@@ -1206,7 +1206,7 @@ static int setup(struct spi_device *spi)
                        if (!chip_info) {
                                dev_err(&spi->dev,
                                        "setup - "
-                                       "cannot allocate controller data");
+                                       "cannot allocate controller data\n");
                                status = -ENOMEM;
                                goto err_first_setup;
                        }
index b4a5e5e9d9fc4bd15ae52a9d78a9700ff3ee2cf8..d976660cb7f07902f70215d530a89008ae9ed4a6 100644 (file)
@@ -22,7 +22,7 @@ config SSB
 
 config SSB_PCIHOST_POSSIBLE
        bool
-       depends on SSB && PCI
+       depends on SSB && (PCI = y || PCI = SSB)
        default y
 
 config SSB_PCIHOST
@@ -37,7 +37,7 @@ config SSB_PCIHOST
 
 config SSB_PCMCIAHOST_POSSIBLE
        bool
-       depends on SSB && PCMCIA && EXPERIMENTAL
+       depends on SSB && (PCMCIA = y || PCMCIA = SSB) && EXPERIMENTAL
        default y
 
 config SSB_PCMCIAHOST
index ab8691a325802e19d374e601e6a3c5f3f60fc55a..3d3dd32bf3ab88475aa16ad6abccdc491682a86b 100644 (file)
@@ -173,7 +173,7 @@ u32 ssb_cpu_clock(struct ssb_mipscore *mcore)
 
 void ssb_mipscore_init(struct ssb_mipscore *mcore)
 {
-       struct ssb_bus *bus = mcore->dev->bus;
+       struct ssb_bus *bus;
        struct ssb_device *dev;
        unsigned long hz, ns;
        unsigned int irq, i;
@@ -183,6 +183,7 @@ void ssb_mipscore_init(struct ssb_mipscore *mcore)
 
        ssb_dprintk(KERN_INFO PFX "Initializing MIPS core...\n");
 
+       bus = mcore->dev->bus;
        hz = ssb_clockspeed(bus);
        if (!hz)
                hz = 100000000;
index f51e22490edfaccae55b641723c939ce0019087b..912d97aaf9bf7b7ad52068dc850a8332aa4a76e5 100644 (file)
@@ -332,7 +332,7 @@ static void acm_read_bulk(struct urb *urb)
                return;
 
        if (status)
-               dev_dbg(&acm->data->dev, "bulk rx status %d", status);
+               dev_dbg(&acm->data->dev, "bulk rx status %d\n", status);
 
        buf = rcv->buffer;
        buf->size = urb->actual_length;
@@ -831,13 +831,13 @@ static int acm_probe (struct usb_interface *intf,
        
        /* normal probing*/
        if (!buffer) {
-               err("Wierd descriptor references\n");
+               err("Weird descriptor references\n");
                return -EINVAL;
        }
 
        if (!buflen) {
                if (intf->cur_altsetting->endpoint->extralen && intf->cur_altsetting->endpoint->extra) {
-                       dev_dbg(&intf->dev,"Seeking extra descriptors on endpoint");
+                       dev_dbg(&intf->dev,"Seeking extra descriptors on endpoint\n");
                        buflen = intf->cur_altsetting->endpoint->extralen;
                        buffer = intf->cur_altsetting->endpoint->extra;
                } else {
@@ -887,24 +887,24 @@ next_desc:
 
        if (!union_header) {
                if (call_interface_num > 0) {
-                       dev_dbg(&intf->dev,"No union descriptor, using call management descriptor");
+                       dev_dbg(&intf->dev,"No union descriptor, using call management descriptor\n");
                        data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = call_interface_num));
                        control_interface = intf;
                } else {
-                       dev_dbg(&intf->dev,"No union descriptor, giving up");
+                       dev_dbg(&intf->dev,"No union descriptor, giving up\n");
                        return -ENODEV;
                }
        } else {
                control_interface = usb_ifnum_to_if(usb_dev, union_header->bMasterInterface0);
                data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = union_header->bSlaveInterface0));
                if (!control_interface || !data_interface) {
-                       dev_dbg(&intf->dev,"no interfaces");
+                       dev_dbg(&intf->dev,"no interfaces\n");
                        return -ENODEV;
                }
        }
        
        if (data_interface_num != call_interface_num)
-               dev_dbg(&intf->dev,"Seperate call control interface. That is not fully supported.");
+               dev_dbg(&intf->dev,"Seperate call control interface. That is not fully supported.\n");
 
 skip_normal_probe:
 
@@ -912,7 +912,7 @@ skip_normal_probe:
        if (data_interface->cur_altsetting->desc.bInterfaceClass != CDC_DATA_INTERFACE_TYPE) {
                if (control_interface->cur_altsetting->desc.bInterfaceClass == CDC_DATA_INTERFACE_TYPE) {
                        struct usb_interface *t;
-                       dev_dbg(&intf->dev,"Your device has switched interfaces.");
+                       dev_dbg(&intf->dev,"Your device has switched interfaces.\n");
 
                        t = control_interface;
                        control_interface = data_interface;
@@ -927,7 +927,7 @@ skip_normal_probe:
                return -ENODEV;
        
        if (usb_interface_claimed(data_interface)) { /* valid in this context */
-               dev_dbg(&intf->dev,"The data interface isn't available");
+               dev_dbg(&intf->dev,"The data interface isn't available\n");
                return -EBUSY;
        }
 
@@ -944,7 +944,7 @@ skip_normal_probe:
        if (!usb_endpoint_dir_in(epread)) {
                /* descriptors are swapped */
                struct usb_endpoint_descriptor *t;
-               dev_dbg(&intf->dev,"The data interface has switched endpoints");
+               dev_dbg(&intf->dev,"The data interface has switched endpoints\n");
                
                t = epread;
                epread = epwrite;
@@ -959,7 +959,7 @@ skip_normal_probe:
        }
 
        if (!(acm = kzalloc(sizeof(struct acm), GFP_KERNEL))) {
-               dev_dbg(&intf->dev, "out of memory (acm kzalloc)");
+               dev_dbg(&intf->dev, "out of memory (acm kzalloc)\n");
                goto alloc_fail;
        }
 
@@ -985,26 +985,26 @@ skip_normal_probe:
 
        buf = usb_buffer_alloc(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma);
        if (!buf) {
-               dev_dbg(&intf->dev, "out of memory (ctrl buffer alloc)");
+               dev_dbg(&intf->dev, "out of memory (ctrl buffer alloc)\n");
                goto alloc_fail2;
        }
        acm->ctrl_buffer = buf;
 
        if (acm_write_buffers_alloc(acm) < 0) {
-               dev_dbg(&intf->dev, "out of memory (write buffer alloc)");
+               dev_dbg(&intf->dev, "out of memory (write buffer alloc)\n");
                goto alloc_fail4;
        }
 
        acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL);
        if (!acm->ctrlurb) {
-               dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)");
+               dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)\n");
                goto alloc_fail5;
        }
        for (i = 0; i < num_rx_buf; i++) {
                struct acm_ru *rcv = &(acm->ru[i]);
 
                if (!(rcv->urb = usb_alloc_urb(0, GFP_KERNEL))) {
-                       dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)");
+                       dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)\n");
                        goto alloc_fail7;
                }
 
@@ -1015,13 +1015,13 @@ skip_normal_probe:
                struct acm_rb *buf = &(acm->rb[i]);
 
                if (!(buf->base = usb_buffer_alloc(acm->dev, readsize, GFP_KERNEL, &buf->dma))) {
-                       dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)");
+                       dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)\n");
                        goto alloc_fail7;
                }
        }
        acm->writeurb = usb_alloc_urb(0, GFP_KERNEL);
        if (!acm->writeurb) {
-               dev_dbg(&intf->dev, "out of memory (writeurb kmalloc)");
+               dev_dbg(&intf->dev, "out of memory (writeurb kmalloc)\n");
                goto alloc_fail7;
        }
 
index f013b4012c9a18a4199f0764d0a8218233fdb577..1f4f6d02fe25598e22a62b785b1b7140913b7c12 100644 (file)
@@ -460,7 +460,7 @@ static int checkintf(struct dev_state *ps, unsigned int ifnum)
                return 0;
        /* if not yet claimed, claim it for the driver */
        dev_warn(&ps->dev->dev, "usbfs: process %d (%s) did not claim interface %u before use\n",
-              current->pid, current->comm, ifnum);
+              task_pid_nr(current), current->comm, ifnum);
        return claimintf(ps, ifnum);
 }
 
index 7dc123d6b2d0e2893f9ddac031da0d3fe71ede35..99e5a68a3f120ead6785fc6b880968e97ab47e83 100644 (file)
@@ -291,7 +291,7 @@ int usb_create_ep_files(struct device *parent,
 
        retval = endpoint_get_minor(ep_dev);
        if (retval) {
-               dev_err(parent, "can not allocate minor number for %s",
+               dev_err(parent, "can not allocate minor number for %s\n",
                        ep_dev->dev.bus_id);
                goto error_register;
        }
index 60a8f55a0cc7d552887dcbb17c34584c3d8cc071..036c3dea855e66d4df3186dd83df3ecbd20542d7 100644 (file)
@@ -2870,10 +2870,9 @@ static int hub_thread(void *__unused)
        set_freezable();
        do {
                hub_events();
-               wait_event_interruptible(khubd_wait,
+               wait_event_freezable(khubd_wait,
                                !list_empty(&hub_event_list) ||
                                kthread_should_stop());
-               try_to_freeze();
        } while (!kthread_should_stop() || !list_empty(&hub_event_list));
 
        pr_debug("%s: khubd exiting\n", usbcore_name);
index c021af3903723b3d27db15f2cc904cd80ed4bd36..8bdaa157ffe7dd7a6fe1276ef2a26544742e7197 100644 (file)
@@ -11,9 +11,9 @@
 #include <linux/timer.h>
 #include <linux/ctype.h>
 #include <linux/device.h>
+#include <linux/scatterlist.h>
 #include <linux/usb/quirks.h>
 #include <asm/byteorder.h>
-#include <asm/scatterlist.h>
 
 #include "hcd.h"       /* for usbcore internals */
 #include "usb.h"
@@ -437,13 +437,11 @@ int usb_sg_init (
 #if defined(CONFIG_HIGHMEM) || defined(CONFIG_IOMMU)
                        io->urbs[i]->transfer_buffer = NULL;
 #else
-                       io->urbs[i]->transfer_buffer =
-                               page_address(sg[i].page) + sg[i].offset;
+                       io->urbs[i]->transfer_buffer = sg_virt(&sg[i]);
 #endif
                } else {
                        /* hc may use _only_ transfer_buffer */
-                       io->urbs [i]->transfer_buffer =
-                               page_address (sg [i].page) + sg [i].offset;
+                       io->urbs [i]->transfer_buffer = sg_virt(&sg[i]);
                        len = sg [i].length;
                }
 
@@ -1526,7 +1524,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
                new_interfaces = kmalloc(nintf * sizeof(*new_interfaces),
                                GFP_KERNEL);
                if (!new_interfaces) {
-                       dev_err(&dev->dev, "Out of memory");
+                       dev_err(&dev->dev, "Out of memory\n");
                        return -ENOMEM;
                }
 
@@ -1535,7 +1533,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
                                        sizeof(struct usb_interface),
                                        GFP_KERNEL);
                        if (!new_interfaces[n]) {
-                               dev_err(&dev->dev, "Out of memory");
+                               dev_err(&dev->dev, "Out of memory\n");
                                ret = -ENOMEM;
 free_interfaces:
                                while (--n >= 0)
index 73726c570a6eeb01cc41d91cb5230a256e57729e..1d174dcb3ac9e6a4ea5ce8133d6e4519d32d9783 100644 (file)
@@ -4006,7 +4006,7 @@ static int __init fsg_bind(struct usb_gadget *gadget)
        DBG(fsg, "removable=%d, stall=%d, buflen=%u\n",
                        mod_data.removable, mod_data.can_stall,
                        mod_data.buflen);
-       DBG(fsg, "I/O thread pid: %d\n", fsg->thread_task->pid);
+       DBG(fsg, "I/O thread pid: %d\n", task_pid_nr(fsg->thread_task));
 
        set_bit(REGISTERED, &fsg->atomic_bitflags);
 
index e78c2ddc1f88a47e6cbd52007d088f43269e8fee..367b75c0b25b3e8f9a4af753fa9c6cea8578d097 100644 (file)
@@ -1272,7 +1272,7 @@ static int lh7a40x_set_halt(struct usb_ep *_ep, int value)
                        /*
                         * Attempts to halt IN endpoints will fail (returning -EAGAIN)
                         * if any transfer requests are still queued, or if the controller
-                        * FIFO still holds bytes that the host hasn\92t collected.
+                        * FIFO still holds bytes that the host hasn't collected.
                         */
                        spin_unlock_irqrestore(&ep->dev->lock, flags);
                        DEBUG
index 0dcb4164dc8368a9187b670c2a303c39cfdfa109..735db4aec831cc2302a761801f51eccc25efdeb7 100644 (file)
@@ -451,7 +451,7 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
 
        /* Some boards (mostly VIA?) report bogus overcurrent indications,
         * causing massive log spam unless we completely ignore them.  It
-        * may be relevant that VIA VT8235 controlers, where PORT_POWER is
+        * may be relevant that VIA VT8235 controllers, where PORT_POWER is
         * always set, seem to clear PORT_OCC and PORT_CSC when writing to
         * PORT_POWER; that's surprising, but maybe within-spec.
         */
index 6829814b7aafbd6faa17288ebd1999a11ff9dec4..44b79e8a6e25526e71264dc77c40f713bd47ad95 100644 (file)
@@ -358,7 +358,7 @@ static int usb_hcd_s3c2410_probe (const struct hc_driver *driver,
        hcd->rsrc_len   = dev->resource[0].end - dev->resource[0].start + 1;
 
        if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
-               dev_err(&dev->dev, "request_mem_region failed");
+               dev_err(&dev->dev, "request_mem_region failed\n");
                retval = -EBUSY;
                goto err_put;
        }
index 94d859aa73f818bc389dc10db5e3c490b760581a..ba370c56172c372d7b435669a9b6792a0ac3f83c 100644 (file)
@@ -1556,7 +1556,7 @@ sl811h_start(struct usb_hcd *hcd)
                hcd->power_budget = sl811->board->power * 2;
        }
 
-       /* enable power and interupts */
+       /* enable power and interrupts */
        port_power(sl811, 1);
 
        return 0;
index 95ce703110d276511030c8629e4b319088a6bc70..7595dfb38e3b18361f82ffbc914e300e34c76245 100644 (file)
@@ -1,5 +1,5 @@
 #
-# USB Imageing devices configuration
+# USB Imaging devices configuration
 #
 comment "USB Imaging devices"
        depends on USB
index e7d982a71548d819e08272a93eb9788defa14f48..91e999c9f680cec92aed6c38fa58698820d3754e 100644 (file)
@@ -519,8 +519,7 @@ static void mts_do_sg (struct urb* transfer)
        context->fragment++;
        mts_int_submit_urb(transfer,
                           context->data_pipe,
-                          page_address(sg[context->fragment].page) +
-                          sg[context->fragment].offset,
+                          sg_virt(&sg[context->fragment]),
                           sg[context->fragment].length,
                           context->fragment + 1 == scsi_sg_count(context->srb) ?
                           mts_data_done : mts_do_sg);
@@ -557,7 +556,7 @@ mts_build_transfer_context(struct scsi_cmnd *srb, struct mts_desc* desc)
                return;
        } else {
                sg = scsi_sglist(srb);
-               desc->context.data = page_address(sg[0].page) + sg[0].offset;
+               desc->context.data = sg_virt(&sg[0]);
                desc->context.data_length = sg[0].length;
        }
 
index 5131cbfb2f5230cec9c0c3cd9d5c95d5f5731538..c567aa7a41ead3643de3c38ab4b286a3c13c283b 100644 (file)
@@ -805,7 +805,7 @@ static int adu_probe(struct usb_interface *interface,
        dev->minor = interface->minor;
 
        /* let the user know what node this device is now attached to */
-       dev_info(&interface->dev, "ADU%d %s now attached to /dev/usb/adutux%d",
+       dev_info(&interface->dev, "ADU%d %s now attached to /dev/usb/adutux%d\n",
                 udev->descriptor.idProduct, dev->serial_number,
                 (dev->minor - ADU_MINOR_BASE));
 exit:
@@ -851,7 +851,7 @@ static void adu_disconnect(struct usb_interface *interface)
                mutex_unlock(&dev->mtx);
        }
 
-       dev_info(&interface->dev, "ADU device adutux%d now disconnected",
+       dev_info(&interface->dev, "ADU device adutux%d now disconnected\n",
                 (minor - ADU_MINOR_BASE));
 
        dbg(2," %s : leave", __FUNCTION__);
index 04e87acd6e46007cec2449ffe34c58257d55c6a8..2677fea147d9ef163053c8a2b458edf170515aec 100644 (file)
@@ -118,7 +118,7 @@ static ssize_t set_brightness(struct device *dev, struct device_attribute *attr,
                                cytherm->brightness, buffer, 8);
        if (retval)
                dev_dbg(&cytherm->udev->dev, "retval = %d\n", retval);
-       /* Inform µC that we have changed the brightness setting */
+       /* Inform ÂµC that we have changed the brightness setting */
        retval = vendor_command(cytherm->udev, WRITE_RAM, BRIGHTNESS_SEM,
                                0x01, buffer, 8);
        if (retval)
index 5c0a26cbd12884e212b319df3608121034ea8e01..cd137577bb2d06b1c6278cb601e30590d6929481 100644 (file)
@@ -1,7 +1,7 @@
 /* 
  * Emagic EMI 2|6 usb audio interface firmware loader.
  * Copyright (C) 2002
- *     Tapio Laxström (tapio.laxstrom@iptime.fi)
+ *     Tapio Laxström (tapio.laxstrom@iptime.fi)
  *
  * 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
@@ -249,7 +249,7 @@ static void __exit emi26_exit (void)
 module_init(emi26_init);
 module_exit(emi26_exit);
 
-MODULE_AUTHOR("tapio laxström");
+MODULE_AUTHOR("Tapio Laxström");
 MODULE_DESCRIPTION("Emagic EMI 2|6 firmware loader.");
 MODULE_LICENSE("GPL");
 
index 23153eac0dfaf0b869991ed39af4698aa3089caa..4758cc5ccebcd37acdc7330718079941f77b332c 100644 (file)
@@ -1,7 +1,7 @@
 /* 
  * Emagic EMI 2|6 usb audio interface firmware loader.
  * Copyright (C) 2002
- *     Tapio Laxström (tapio.laxstrom@iptime.fi)
+ *     Tapio Laxström (tapio.laxstrom@iptime.fi)
  *
  * 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
@@ -292,7 +292,7 @@ static void __exit emi62_exit (void)
 module_init(emi62_init);
 module_exit(emi62_exit);
 
-MODULE_AUTHOR("tapio laxström");
+MODULE_AUTHOR("Tapio Laxström");
 MODULE_DESCRIPTION("Emagic EMI 6|2m firmware loader.");
 MODULE_LICENSE("GPL");
 
index 46d9f27ec17380122d0f3db1ef198b04d3fa2696..d372fbc4effbb0a44c31213142c92f720a13bea3 100644 (file)
@@ -216,7 +216,7 @@ static void iowarrior_callback(struct urb *urb)
 exit:
        retval = usb_submit_urb(urb, GFP_ATOMIC);
        if (retval)
-               dev_err(&dev->interface->dev, "%s - usb_submit_urb failed with result %d",
+               dev_err(&dev->interface->dev, "%s - usb_submit_urb failed with result %d\n",
                        __FUNCTION__, retval);
 
 }
@@ -451,7 +451,7 @@ static ssize_t iowarrior_write(struct file *file,
                break;
        default:
                /* what do we have here ? An unsupported Product-ID ? */
-               dev_err(&dev->interface->dev, "%s - not supported for product=0x%x",
+               dev_err(&dev->interface->dev, "%s - not supported for product=0x%x\n",
                        __FUNCTION__, dev->product_id);
                retval = -EFAULT;
                goto exit;
@@ -526,7 +526,7 @@ static int iowarrior_ioctl(struct inode *inode, struct file *file,
                } else {
                        retval = -EINVAL;
                        dev_err(&dev->interface->dev,
-                               "ioctl 'IOW_WRITE' is not supported for product=0x%x.",
+                               "ioctl 'IOW_WRITE' is not supported for product=0x%x.\n",
                                dev->product_id);
                }
                break;
@@ -752,7 +752,7 @@ static int iowarrior_probe(struct usb_interface *interface,
        /* allocate memory for our device state and intialize it */
        dev = kzalloc(sizeof(struct iowarrior), GFP_KERNEL);
        if (dev == NULL) {
-               dev_err(&interface->dev, "Out of memory");
+               dev_err(&interface->dev, "Out of memory\n");
                return retval;
        }
 
index df0ebcdb9d6a6fbef91cffd476a0f5151945b324..2ad09b1f4848a57d9aac01f2bd46539590ec9377 100644 (file)
@@ -155,7 +155,7 @@ resubmit:
        retval = usb_submit_urb(urb, GFP_ATOMIC);
        if (retval)
                dev_err(&mc->intf->dev,
-                       "can't resubmit intr, %s-%s/motorcontrol0, retval %d",
+                       "can't resubmit intr, %s-%s/motorcontrol0, retval %d\n",
                        mc->udev->bus->bus_name,
                        mc->udev->devpath, retval);
 }
index e901d31e051b3d579e3dcebdf1e66f161e2a31ba..ea3162146481fa4791a4ec750b4c1f5a6b83bc77 100644 (file)
@@ -360,9 +360,9 @@ static void free_sglist (struct scatterlist *sg, int nents)
        if (!sg)
                return;
        for (i = 0; i < nents; i++) {
-               if (!sg [i].page)
+               if (!sg_page(&sg[i]))
                        continue;
-               kfree (page_address (sg [i].page) + sg [i].offset);
+               kfree (sg_virt(&sg[i]));
        }
        kfree (sg);
 }
index 52c4f7bd7a80a3279f8a59fc4ceaed2dd350e71f..c1b279939bbf46f0a3a3ac0f5e5e7187c9304d99 100644 (file)
@@ -400,7 +400,7 @@ visor.c Change Log comments:
 
  (11/11/2001) gkh
        Added support for the m125 devices, and added check to prevent oopses
-       for Clié devices that lie about the number of ports they have.
+       for Clié devices that lie about the number of ports they have.
 
  (08/30/2001) gkh
        Added support for the Clie devices, both the 3.5 and 4.0 os versions.
index 99fefed77919de2dbd28af6de48faa1080181924..4a86696e6c7dd20240aca1776139669c9ac4005c 100644 (file)
@@ -527,7 +527,7 @@ config USB_SERIAL_CYBERJACK
        depends on USB_SERIAL && EXPERIMENTAL
        ---help---
          Say Y here if you want to use a cyberJack pinpad/e-com USB chipcard
-         reader. This is an interface to ISO 7816 compatible contactbased
+         reader. This is an interface to ISO 7816 compatible contact-based
          chipcards, e.g. GSM SIMs.
 
          To compile this driver as a module, choose M here: the
index e4c248c98e8480faa45fbd72600f8fc81cd7c4af..8a8a6b9fb05bf3bc1253bb9c08398fd749aadaf4 100644 (file)
@@ -83,7 +83,7 @@
  *
  * (18/Jun/2003) Ian Abbott
  *      Added Device ID of the USB relais from Rudolf Gugler (backported from
- *      Philipp Gühring's patch for 2.5.x kernel).
+ *      Philipp Gühring's patch for 2.5.x kernel).
  *      Moved read transfer buffer reallocation into startup function.
  *      Free existing write urb and transfer buffer in startup function.
  *      Only use urbs in write urb pool that were successfully allocated.
@@ -1071,7 +1071,7 @@ static ssize_t show_latency_timer(struct device *dev, struct device_attribute *a
                             (char*) &latency, 1, WDR_TIMEOUT);
 
        if (rv < 0) {
-               dev_err(dev, "Unable to read latency timer: %i", rv);
+               dev_err(dev, "Unable to read latency timer: %i\n", rv);
                return -EIO;
        }
        return sprintf(buf, "%i\n", latency);
@@ -1098,7 +1098,7 @@ static ssize_t store_latency_timer(struct device *dev, struct device_attribute *
                             buf, 0, WDR_TIMEOUT);
 
        if (rv < 0) {
-               dev_err(dev, "Unable to write latency timer: %i", rv);
+               dev_err(dev, "Unable to write latency timer: %i\n", rv);
                return -EIO;
        }
 
index b57b90ae9f9d5d8ea4519a264b8b9a0fe49eb797..b51cbb0eaa054491c8bcc2479788f28fa0a0afde 100644 (file)
@@ -17,7 +17,7 @@
  * Bill Ryder - bryder@sgi.com formerly of Silicon Graphics, Inc.- wrote the 
  * FTDI_SIO implementation.
  *
- * Philipp Gühring - pg@futureware.at - added the Device ID of the USB relais
+ * Philipp Gühring - pg@futureware.at - added the Device ID of the USB relais
  * from Rudolf Gugler
  *
  */
@@ -44,7 +44,7 @@
 #define FTDI_ACTZWAVE_PID      0xF2D0
 
 
-/* www.starting-point-systems.com µChameleon device */
+/* www.starting-point-systems.com ÂµChameleon device */
 #define FTDI_MICRO_CHAMELEON_PID       0xCAA0  /* Product Id */
 
 /* www.irtrans.de device */
 
 /*
  * Teratronik product ids.
- * Submitted by O. Wölfelschneider.
+ * Submitted by O. Wölfelschneider.
  */
 #define FTDI_TERATRONIK_VCP_PID         0xEC88 /* Teratronik device (preferring VCP driver on windows) */
 #define FTDI_TERATRONIK_D2XX_PID 0xEC89        /* Teratronik device (preferring D2XX driver on windows) */
index 2ecb1d2a034d0aa03dc08af168ae09a2f918efea..8dd3abc99d639b4ce32d3390006dd681d7bacf2d 100644 (file)
@@ -2882,7 +2882,7 @@ static int edge_startup (struct usb_serial *serial)
            (edge_serial->product_info.NumPorts != serial->num_ports)) {
                dev_warn(&serial->dev->dev, "Device Reported %d serial ports "
                         "vs. core thinking we have %d ports, email "
-                        "greg@kroah.com this information.",
+                        "greg@kroah.com this information.\n",
                         edge_serial->product_info.NumPorts,
                         serial->num_ports);
        }
index e836ad07fdb9e958c1380cf93d11076433adfa60..9b38a08ac83a6803cda3d0123ae26f32b42a851a 100644 (file)
@@ -306,7 +306,7 @@ static struct usb_device_id ipaq_id_table [] = {
        { USB_DEVICE(0x0930, 0x0705) }, /* TOSHIBA Pocket PC e310 */
        { USB_DEVICE(0x0930, 0x0706) }, /* TOSHIBA Pocket PC e740 */
        { USB_DEVICE(0x0930, 0x0707) }, /* TOSHIBA Pocket PC e330 Series */
-       { USB_DEVICE(0x0930, 0x0708) }, /* TOSHIBA Pocket PC e350 Series */
+       { USB_DEVICE(0x0930, 0x0708) }, /* TOSHIBA Pocket PC e350 Series */
        { USB_DEVICE(0x0930, 0x0709) }, /* TOSHIBA Pocket PC e750 Series */
        { USB_DEVICE(0x0930, 0x070A) }, /* TOSHIBA Pocket PC e400 Series */
        { USB_DEVICE(0x0930, 0x070B) }, /* TOSHIBA Pocket PC e800 Series */
@@ -488,7 +488,7 @@ static struct usb_device_id ipaq_id_table [] = {
        { USB_DEVICE(0x0BF8, 0x1001) }, /* Fujitsu Siemens Computers USB Sync */
        { USB_DEVICE(0x0C44, 0x03A2) }, /* Motorola iDEN Smartphone */
        { USB_DEVICE(0x0C8E, 0x6000) }, /* Cesscom Luxian Series */
-       { USB_DEVICE(0x0CAD, 0x9001) }, /* Motorola PowerPad Pocket PC Device */
+       { USB_DEVICE(0x0CAD, 0x9001) }, /* Motorola PowerPad Pocket PC Device */
        { USB_DEVICE(0x0F4E, 0x0200) }, /* Freedom Scientific USB Sync */
        { USB_DEVICE(0x0F98, 0x0201) }, /* Cyberbank USB Sync */
        { USB_DEVICE(0x0FB8, 0x3001) }, /* Wistron USB Sync */
index 1b94daa615845f50f185328b2ecf3326f71bdffa..cbe5530f3db2554bc40b99e2c357dd33e2567e2f 100644 (file)
@@ -227,7 +227,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp)
                                 0,
                                 100000);
        if (result < 0)
-               dev_err(&port->dev, "Init of modem failed (error = %d)", result);
+               dev_err(&port->dev, "Init of modem failed (error = %d)\n", result);
 
        /* reset the bulk pipes */
        usb_clear_halt(dev, usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress));
@@ -255,7 +255,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp)
                                 0,
                                 100000);
        if (result < 0) 
-               dev_err(&port->dev, "Enabling bulk RxRead failed (error = %d)", result);
+               dev_err(&port->dev, "Enabling bulk RxRead failed (error = %d)\n", result);
 
        /*--4: setup the initial flowcontrol */
        dbg("%s:setting init flowcontrol (%s)",__FUNCTION__,buf_flow_init);
@@ -268,7 +268,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp)
                                 0x10,
                                 200000);
        if (result < 0)
-               dev_err(&port->dev, "initial flowcontrol failed (error = %d)", result);
+               dev_err(&port->dev, "initial flowcontrol failed (error = %d)\n", result);
 
 
        /*--5: raise the dtr */
@@ -282,7 +282,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp)
                                 0,
                                 200000);
        if (result < 0)
-               dev_err(&port->dev, "setting dtr failed (error = %d)", result);
+               dev_err(&port->dev, "setting dtr failed (error = %d)\n", result);
 
        /*--6: raise the rts */
        dbg("%s:raising rts",__FUNCTION__);
@@ -295,7 +295,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp)
                                 0,
                                 200000);
        if (result < 0)
-               dev_err(&port->dev, "setting dtr failed (error = %d)", result);
+               dev_err(&port->dev, "setting dtr failed (error = %d)\n", result);
        
        kfree(buf_flow_init);
        return 0;
@@ -322,7 +322,7 @@ static void ipw_close(struct usb_serial_port *port, struct file * filp)
                                 0,
                                 200000);
        if (result < 0)
-               dev_err(&port->dev, "dropping dtr failed (error = %d)", result);
+               dev_err(&port->dev, "dropping dtr failed (error = %d)\n", result);
 
        /*--2: drop the rts */
        dbg("%s:dropping rts",__FUNCTION__);
@@ -334,7 +334,7 @@ static void ipw_close(struct usb_serial_port *port, struct file * filp)
                                 0,
                                 200000);
        if (result < 0)
-               dev_err(&port->dev, "dropping rts failed (error = %d)", result);
+               dev_err(&port->dev, "dropping rts failed (error = %d)\n", result);
 
 
        /*--3: purge */
@@ -347,7 +347,7 @@ static void ipw_close(struct usb_serial_port *port, struct file * filp)
                                 0,
                                 200000);
        if (result < 0)
-               dev_err(&port->dev, "purge failed (error = %d)", result);
+               dev_err(&port->dev, "purge failed (error = %d)\n", result);
 
 
        /* send RXBULK_off (tell modem to stop transmitting bulk data on rx chan) */
@@ -361,7 +361,7 @@ static void ipw_close(struct usb_serial_port *port, struct file * filp)
                                 100000);
 
        if (result < 0)
-               dev_err(&port->dev, "Disabling bulk RxRead failed (error = %d)", result);
+               dev_err(&port->dev, "Disabling bulk RxRead failed (error = %d)\n", result);
 
        /* shutdown any in-flight urbs that we know about */
        usb_kill_urb(port->read_urb);
index 01e811becec4659055bc27f02ec2693ac66011d2..e02c198016b02204ee5ef92c43850356e99d9264 100644 (file)
@@ -478,7 +478,7 @@ static int mos7720_open(struct usb_serial_port *port, struct file * filp)
                response = usb_submit_urb(port0->interrupt_in_urb, GFP_KERNEL);
                if (response)
                        dev_err(&port->dev,
-                               "%s - Error %d submitting control urb",
+                               "%s - Error %d submitting control urb\n",
                                __FUNCTION__, response);
        }
 
@@ -492,7 +492,7 @@ static int mos7720_open(struct usb_serial_port *port, struct file * filp)
        response = usb_submit_urb(port->read_urb, GFP_KERNEL);
        if (response)
                dev_err(&port->dev,
-                       "%s - Error %d submitting read urb", __FUNCTION__, response);
+                       "%s - Error %d submitting read urb\n", __FUNCTION__, response);
 
        /* initialize our icount structure */
        memset(&(mos7720_port->icount), 0x00, sizeof(mos7720_port->icount));
index d19861166b505cbca39a37f692d61fafd41cdf07..eea226ae37bd15bacf66e4057ce54b8152256469 100644 (file)
@@ -256,7 +256,7 @@ static void setup_line(struct work_struct *work)
                                100);
 
        if (result != OTI6858_CTRL_PKT_SIZE) {
-               dev_err(&port->dev, "%s(): error reading status", __FUNCTION__);
+               dev_err(&port->dev, "%s(): error reading status\n", __FUNCTION__);
                kfree(new_setup);
                /* we will try again */
                schedule_delayed_work(&priv->delayed_setup_work, msecs_to_jiffies(2));
index 0bb8de4cc5241a2b4071095b7c6b3b57049fe357..959b3e4e90774faf1a44815b6c6b19df0fedc336 100644 (file)
@@ -48,7 +48,7 @@ enum devicetype {
 static int sierra_set_power_state(struct usb_device *udev, __u16 swiState)
 {
        int result;
-       dev_dbg(&udev->dev, "%s", "SET POWER STATE");
+       dev_dbg(&udev->dev, "%s", "SET POWER STATE\n");
        result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
                        0x00,                   /* __u8 request      */
                        0x40,                   /* __u8 request type */
@@ -63,7 +63,7 @@ static int sierra_set_power_state(struct usb_device *udev, __u16 swiState)
 static int sierra_set_ms_mode(struct usb_device *udev, __u16 eSocMode)
 {
        int result;
-       dev_dbg(&udev->dev, "%s", "DEVICE MODE SWITCH");
+       dev_dbg(&udev->dev, "%s", "DEVICE MODE SWITCH\n");
        result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
                        SWIMS_USB_REQUEST_SetMode,      /* __u8 request      */
                        SWIMS_USB_REQUEST_TYPE_SetMode, /* __u8 request type */
@@ -397,7 +397,7 @@ static void sierra_indat_callback(struct urb *urb)
                        err = usb_submit_urb(urb, GFP_ATOMIC);
                        if (err)
                                dev_err(&port->dev, "resubmit read urb failed."
-                                       "(%d)", err);
+                                       "(%d)\n", err);
                }
        }
        return;
@@ -525,7 +525,7 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp)
 
                result = usb_submit_urb(urb, GFP_KERNEL);
                if (result) {
-                       dev_err(&port->dev, "submit urb %d failed (%d) %d",
+                       dev_err(&port->dev, "submit urb %d failed (%d) %d\n",
                                i, result, urb->transfer_buffer_length);
                }
        }
@@ -538,7 +538,7 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp)
        if (port->interrupt_in_urb) {
                result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
                if (result)
-                       dev_err(&port->dev, "submit irq_in urb failed %d",
+                       dev_err(&port->dev, "submit irq_in urb failed %d\n",
                                result);
        }
        return 0;
index 6831dca93c1bd9643ea6ebc7c7b4c15a21a4f2ac..93a7724e167a8b6c49807905773f3fcb8050578e 100644 (file)
@@ -3,7 +3,7 @@
  * $Id: isd200.c,v 1.16 2002/04/22 03:39:43 mdharm Exp $
  *
  * Current development and maintenance:
- *   (C) 2001-2002 Björn Stenberg (bjorn@haxx.se)
+ *   (C) 2001-2002 Björn Stenberg (bjorn@haxx.se)
  *
  * Developed with the assistance of:
  *   (C) 2002 Alan Stern <stern@rowland.org>
index cc8f7c52c7292400525305c026f2145d536d3ccc..889622baac20ff917f7f3d98c7251f24c10a0e2f 100644 (file)
@@ -195,7 +195,7 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
                 * the *offset and *index values for the next loop. */
                cnt = 0;
                while (cnt < buflen) {
-                       struct page *page = sg->page +
+                       struct page *page = sg_page(sg) +
                                        ((sg->offset + *offset) >> PAGE_SHIFT);
                        unsigned int poff =
                                        (sg->offset + *offset) & (PAGE_SIZE-1);
index 9b656ec427d0613ae388bce16eacbbc03cac62c5..22ab2380367db98baab1c5bd0e7541b4a253f982 100644 (file)
@@ -407,7 +407,7 @@ UNUSUAL_DEV(  0x04cb, 0x0100, 0x0000, 0x2210,
                "FinePix 1400Zoom",
                US_SC_UFI, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY | US_FL_SINGLE_LUN),
 
-/* Reported by Peter Wächtler <pwaechtler@loewe-komp.de>
+/* Reported by Peter Wächtler <pwaechtler@loewe-komp.de>
  * The device needs the flags only.
  */
 UNUSUAL_DEV(  0x04ce, 0x0002, 0x0074, 0x0074,
@@ -1551,7 +1551,7 @@ UNUSUAL_DEV(  0x2735, 0x100b, 0x0000, 0x9999,
                US_FL_GO_SLOW ),
 
 /*
- * David Härdeman <david@2gen.com>
+ * David Härdeman <david@2gen.com>
  * The key makes the SCSI stack print confusing (but harmless) messages
  */
 UNUSUAL_DEV(  0x4146, 0xba01, 0x0100, 0x0100,
index 3451e8d03ab0e4653ff2f7208077f565f7294e19..ac6114eea0c3008f6f328ecd1bcf74368c837929 100644 (file)
@@ -907,12 +907,9 @@ static int usb_stor_scan_thread(void * __us)
        if (delay_use > 0) {
                printk(KERN_DEBUG "usb-storage: waiting for device "
                                "to settle before scanning\n");
-retry:
-               wait_event_interruptible_timeout(us->delay_wait,
+               wait_event_freezable_timeout(us->delay_wait,
                                test_bit(US_FLIDX_DISCONNECTING, &us->flags),
                                delay_use * HZ);
-               if (try_to_freeze())
-                       goto retry;
        }
 
        /* If the device is still connected, perform the scanning */
index b3bf4ecc983a83969559128b47626472cfd980ba..fb9d8d0b2c0452250b85c63b9aa23b0024f8e60f 100644 (file)
@@ -661,7 +661,7 @@ config FB_HECUBA
        help
          This enables support for the Hecuba board. This driver was tested
          with an E-Ink 800x600 display and x86 SBCs through a 16 bit GPIO
-         interface (8 bit data, 4 bit control). If you anticpate using
+         interface (8 bit data, 4 bit control). If you anticipate using
          this driver, say Y or M; otherwise say N. You must specify the
          GPIO IO address to be used for setting control and data.
 
@@ -815,7 +815,7 @@ config FB_XVR500
        help
          This is the framebuffer device for the Sun XVR-500 and similar
          graphics cards based upon the 3DLABS Wildcat chipset.  The driver
-         only works on sparc64 systems where the system firwmare has
+         only works on sparc64 systems where the system firmware has
          mostly initialized the card already.  It is treated as a
          completely dumb framebuffer device.
 
@@ -828,7 +828,7 @@ config FB_XVR2500
        help
          This is the framebuffer device for the Sun XVR-2500 and similar
          graphics cards based upon the 3DLABS Wildcat chipset.  The driver
-         only works on sparc64 systems where the system firwmare has
+         only works on sparc64 systems where the system firmware has
          mostly initialized the card already.  It is treated as a
          completely dumb framebuffer device.
 
index f2e243c353f9914c688b1496e5c30227cb49cfee..4c9ec3f58c52e35c194d98cfebcd830075be6c61 100644 (file)
    +----------+---------------------------------------------+----------+-------+
    |          |                ^                            |          |       |
    |          |                |upper_margin                |          |       |
-   |          |                ¥                            |          |       |
+   |          |                v                            |          |       |
    +----------###############################################----------+-------+
    |          #                ^                            #          |       |
    |          #                |                            #          |       |
    |          #                |                            #          |       |
    |          #                |                            #          |       |
    |          #                |                            #          |       |
-   |          #                ¥                            #          |       |
+   |          #                v                            #          |       |
    +----------###############################################----------+-------+
    |          |                ^                            |          |       |
    |          |                |lower_margin                |          |       |
-   |          |                ¥                            |          |       |
+   |          |                v                            |          |       |
    +----------+---------------------------------------------+----------+-------+
    |          |                ^                            |          |       |
    |          |                |vsync_len                   |          |       |
-   |          |                ¥                            |          |       |
+   |          |                v                            |          |       |
    +----------+---------------------------------------------+----------+-------+
 
 
    CCIR -> PAL
    -----------
 
-      - a scanline is 64 µs long, of which 52.48 µs are visible. This is about
+      - a scanline is 64 Âµs long, of which 52.48 Âµs are visible. This is about
         736 visible 70 ns pixels per line.
       - we have 625 scanlines, of which 575 are visible (interlaced); after
         rounding this becomes 576.
    RETMA -> NTSC
    -------------
 
-      - a scanline is 63.5 µs long, of which 53.5 µs are visible.  This is about
+      - a scanline is 63.5 Âµs long, of which 53.5 Âµs are visible.  This is about
         736 visible 70 ns pixels per line.
       - we have 525 scanlines, of which 485 are visible (interlaced); after
         rounding this becomes 484.
@@ -802,7 +802,7 @@ static u_short ecs_palette[32];
 
 static u_short do_vmode_full = 0;      /* Change the Video Mode */
 static u_short do_vmode_pan = 0;       /* Update the Video Mode */
-static short do_blank = 0;             /* (Un)Blank the Screen (±1) */
+static short do_blank = 0;             /* (Un)Blank the Screen (±1) */
 static u_short do_cursor = 0;          /* Move the Cursor */
 
 
index abe0c435a664ec28e81a2f69b498b58d254c469f..d775eb6590b6540976eb02c414e6825d1d739df6 100644 (file)
@@ -26,7 +26,7 @@
  *                        Anthony Tong <atong@uiuc.edu>
  *
  *  Generic LCD support written by Daniel Mantione, ported from 2.4.20 by Alex Kern
- *  Many Thanks to Ville Syrjälä for patches and fixing nasting 16 bit color bug.
+ *  Many Thanks to Ville Syrjälä for patches and fixing nasting 16 bit color bug.
  *
  *  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
index 832e4613673a3eaf910ff650b5de5ca77385fb31..62bd4441b5e06c81fc9c4366916ecb3a2747f09e 100644 (file)
@@ -457,7 +457,7 @@ static struct fb_ops au1100fb_ops =
 
 /* AU1100 LCD controller device driver */
 
-int au1100fb_drv_probe(struct device *dev)
+static int __init au1100fb_drv_probe(struct device *dev)
 {
        struct au1100fb_device *fbdev = NULL;
        struct resource *regs_res;
index a22ccf9485a416d7201726fa963f34dd7f1a1d34..267422f66255e466a3fc56a82d7993b29fe52314 100644 (file)
@@ -27,7 +27,7 @@ config VGACON_SOFT_SCROLLBACK
          The scrollback buffer of the standard VGA console is located in
         the VGA RAM.  The size of this RAM is fixed and is quite small.
         If you require a larger scrollback buffer, this can be placed in
-        System RAM which is dynamically allocated during intialization.
+        System RAM which is dynamically allocated during initialization.
         Placing the scrollback buffer in System RAM will slightly slow
         down the console.
 
index f57d7b2758b7985686192820ed1fc47d2e857bda..d31b203bf6549bdb94b337e9f28f7265d8b544e4 100644 (file)
@@ -98,7 +98,7 @@ static inline void newport_init_cmap(void)
        }
 }
 
-static struct linux_logo *newport_show_logo(void)
+static const struct linux_logo *newport_show_logo(void)
 {
 #ifdef CONFIG_LOGO_SGI_CLUT224
        const struct linux_logo *logo = fb_find_logo(8);
@@ -108,8 +108,8 @@ static struct linux_logo *newport_show_logo(void)
 
        if (!logo)
                return NULL;
-       *clut = logo->clut;
-       *data = logo->data;
+       clut = logo->clut;
+       data = logo->data;
 
        for (i = 0; i < logo->clutsize; i++) {
                newport_bfwait(npregs);
index 9bb2cbfe4a3db65506dc6ff781ea73b7263c194a..5fb8675e0d6b9278a3c31b9ec732cd3c918578db 100644 (file)
@@ -62,7 +62,7 @@ struct cfb_info {
        struct display_switch   *dispsw;
        struct display          *display;
        struct pci_dev          *dev;
-       unsigned char           __iomem *region;
+       unsigned char           __iomem *region;
        unsigned char           __iomem *regs;
        u_int                   id;
        int                     func_use_count;
@@ -97,11 +97,11 @@ MODULE_PARM_DESC(default_font, "Default font name");
 /*
  * Our access methods.
  */
-#define cyber2000fb_writel(val,reg,cfb)        writel(val, (cfb)->regs + (reg))
-#define cyber2000fb_writew(val,reg,cfb)        writew(val, (cfb)->regs + (reg))
-#define cyber2000fb_writeb(val,reg,cfb)        writeb(val, (cfb)->regs + (reg))
+#define cyber2000fb_writel(val, reg, cfb)      writel(val, (cfb)->regs + (reg))
+#define cyber2000fb_writew(val, reg, cfb)      writew(val, (cfb)->regs + (reg))
+#define cyber2000fb_writeb(val, reg, cfb)      writeb(val, (cfb)->regs + (reg))
 
-#define cyber2000fb_readb(reg,cfb)     readb((cfb)->regs + (reg))
+#define cyber2000fb_readb(reg, cfb)            readb((cfb)->regs + (reg))
 
 static inline void
 cyber2000_crtcw(unsigned int reg, unsigned int val, struct cfb_info *cfb)
@@ -221,12 +221,8 @@ cyber2000fb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
 static void
 cyber2000fb_imageblit(struct fb_info *info, const struct fb_image *image)
 {
-//     struct cfb_info *cfb = (struct cfb_info *)info;
-
-//     if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT)) {
-               cfb_imageblit(info, image);
-               return;
-//     }
+       cfb_imageblit(info, image);
+       return;
 }
 
 static int cyber2000fb_sync(struct fb_info *info)
@@ -277,12 +273,12 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 
        /*
         * Pseudocolour:
-        *         8     8
+        *         8     8
         * pixel --/--+--/-->  red lut  --> red dac
-        *            |  8
-        *            +--/--> green lut --> green dac
-        *            |  8
-        *            +--/-->  blue lut --> blue dac
+        *            |  8
+        *            +--/--> green lut --> green dac
+        *            |  8
+        *            +--/-->  blue lut --> blue dac
         */
        case FB_VISUAL_PSEUDOCOLOR:
                if (regno >= NR_PALETTE)
@@ -292,9 +288,9 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
                green >>= 8;
                blue >>= 8;
 
-               cfb->palette[regno].red   = red;
+               cfb->palette[regno].red = red;
                cfb->palette[regno].green = green;
-               cfb->palette[regno].blue  = blue;
+               cfb->palette[regno].blue = blue;
 
                cyber2000fb_writeb(regno, 0x3c8, cfb);
                cyber2000fb_writeb(red, 0x3c9, cfb);
@@ -304,12 +300,12 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 
        /*
         * Direct colour:
-        *          n     rl
-        *  pixel --/--+--/-->  red lut  --> red dac
-        *             |  gl
-        *             +--/--> green lut --> green dac
-        *             |  bl
-        *             +--/-->  blue lut --> blue dac
+        *         n     rl
+        * pixel --/--+--/-->  red lut  --> red dac
+        *            |  gl
+        *            +--/--> green lut --> green dac
+        *            |  bl
+        *            +--/-->  blue lut --> blue dac
         * n = bpp, rl = red length, gl = green length, bl = blue length
         */
        case FB_VISUAL_DIRECTCOLOR:
@@ -325,9 +321,11 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
                         * to the high 6 bits of the LUT.
                         */
                        cyber2000fb_writeb(regno << 2, 0x3c8, cfb);
-                       cyber2000fb_writeb(cfb->palette[regno >> 1].red, 0x3c9, cfb);
+                       cyber2000fb_writeb(cfb->palette[regno >> 1].red,
+                                          0x3c9, cfb);
                        cyber2000fb_writeb(green, 0x3c9, cfb);
-                       cyber2000fb_writeb(cfb->palette[regno >> 1].blue, 0x3c9, cfb);
+                       cyber2000fb_writeb(cfb->palette[regno >> 1].blue,
+                                          0x3c9, cfb);
 
                        green = cfb->palette[regno << 3].green;
 
@@ -335,9 +333,9 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
                }
 
                if (var->green.length >= 5 && regno < 32) {
-                       cfb->palette[regno << 3].red   = red;
+                       cfb->palette[regno << 3].red = red;
                        cfb->palette[regno << 3].green = green;
-                       cfb->palette[regno << 3].blue  = blue;
+                       cfb->palette[regno << 3].blue = blue;
 
                        /*
                         * The 5 bits of each colour component are
@@ -351,9 +349,9 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
                }
 
                if (var->green.length == 4 && regno < 16) {
-                       cfb->palette[regno << 4].red   = red;
+                       cfb->palette[regno << 4].red = red;
                        cfb->palette[regno << 4].green = green;
-                       cfb->palette[regno << 4].blue  = blue;
+                       cfb->palette[regno << 4].blue = blue;
 
                        /*
                         * The 5 bits of each colour component are
@@ -377,12 +375,12 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 
        /*
         * True colour:
-        *          n     rl
-        *  pixel --/--+--/--> red dac
-        *             |  gl
-        *             +--/--> green dac
-        *             |  bl
-        *             +--/--> blue dac
+        *         n     rl
+        * pixel --/--+--/--> red dac
+        *            |  gl
+        *            +--/--> green dac
+        *            |  bl
+        *            +--/--> blue dac
         * n = bpp, rl = red length, gl = green length, bl = blue length
         */
        case FB_VISUAL_TRUECOLOR:
@@ -494,9 +492,9 @@ static void cyber2000fb_set_timing(struct cfb_info *cfb, struct par_info *hw)
 
        /* PLL registers */
        cyber2000_grphw(EXT_DCLK_MULT, hw->clock_mult, cfb);
-       cyber2000_grphw(EXT_DCLK_DIV,  hw->clock_div, cfb);
+       cyber2000_grphw(EXT_DCLK_DIV, hw->clock_div, cfb);
        cyber2000_grphw(EXT_MCLK_MULT, cfb->mclk_mult, cfb);
-       cyber2000_grphw(EXT_MCLK_DIV,  cfb->mclk_div, cfb);
+       cyber2000_grphw(EXT_MCLK_DIV, cfb->mclk_div, cfb);
        cyber2000_grphw(0x90, 0x01, cfb);
        cyber2000_grphw(0xb9, 0x80, cfb);
        cyber2000_grphw(0xb9, 0x00, cfb);
@@ -515,8 +513,8 @@ static void cyber2000fb_set_timing(struct cfb_info *cfb, struct par_info *hw)
        /*
         * Set up accelerator registers
         */
-       cyber2000fb_writew(hw->width,     CO_REG_SRC_WIDTH,  cfb);
-       cyber2000fb_writew(hw->width,     CO_REG_DEST_WIDTH, cfb);
+       cyber2000fb_writew(hw->width, CO_REG_SRC_WIDTH, cfb);
+       cyber2000fb_writew(hw->width, CO_REG_DEST_WIDTH, cfb);
        cyber2000fb_writeb(hw->co_pixfmt, CO_REG_PIXFMT, cfb);
 }
 
@@ -549,15 +547,15 @@ cyber2000fb_decode_crtc(struct par_info *hw, struct cfb_info *cfb,
 {
        u_int Htotal, Hblankend, Hsyncend;
        u_int Vtotal, Vdispend, Vblankstart, Vblankend, Vsyncstart, Vsyncend;
-#define BIT(v,b1,m,b2) (((v >> b1) & m) << b2)
+#define ENCODE_BIT(v, b1, m, b2) ((((v) >> (b1)) & (m)) << (b2))
 
        hw->crtc[13] = hw->pitch;
        hw->crtc[17] = 0xe3;
        hw->crtc[14] = 0;
        hw->crtc[8]  = 0;
 
-       Htotal      = var->xres + var->right_margin +
-                     var->hsync_len + var->left_margin;
+       Htotal     = var->xres + var->right_margin +
+                    var->hsync_len + var->left_margin;
 
        if (Htotal > 2080)
                return -EINVAL;
@@ -567,15 +565,15 @@ cyber2000fb_decode_crtc(struct par_info *hw, struct cfb_info *cfb,
        hw->crtc[2] = var->xres >> 3;
        hw->crtc[4] = (var->xres + var->right_margin) >> 3;
 
-       Hblankend   = (Htotal - 4*8) >> 3;
+       Hblankend   = (Htotal - 4 * 8) >> 3;
 
-       hw->crtc[3] = BIT(Hblankend,  0, 0x1f,  0) |
-                     BIT(1,          0, 0x01,  7);
+       hw->crtc[3] = ENCODE_BIT(Hblankend,  0, 0x1f,  0) |
+                     ENCODE_BIT(1,          0, 0x01,  7);
 
        Hsyncend    = (var->xres + var->right_margin + var->hsync_len) >> 3;
 
-       hw->crtc[5] = BIT(Hsyncend,   0, 0x1f,  0) |
-                     BIT(Hblankend,  5, 0x01,  7);
+       hw->crtc[5] = ENCODE_BIT(Hsyncend,   0, 0x1f,  0) |
+                     ENCODE_BIT(Hblankend,  5, 0x01,  7);
 
        Vdispend    = var->yres - 1;
        Vsyncstart  = var->yres + var->lower_margin;
@@ -590,20 +588,20 @@ cyber2000fb_decode_crtc(struct par_info *hw, struct cfb_info *cfb,
        Vblankend   = Vtotal - 10;
 
        hw->crtc[6]  = Vtotal;
-       hw->crtc[7]  = BIT(Vtotal,     8, 0x01,  0) |
-                       BIT(Vdispend,   8, 0x01,  1) |
-                       BIT(Vsyncstart, 8, 0x01,  2) |
-                       BIT(Vblankstart,8, 0x01,  3) |
-                       BIT(1,          0, 0x01,  4) |
-                       BIT(Vtotal,     9, 0x01,  5) |
-                       BIT(Vdispend,   9, 0x01,  6) |
-                       BIT(Vsyncstart, 9, 0x01,  7);
-       hw->crtc[9]  = BIT(0,          0, 0x1f,  0) |
-                       BIT(Vblankstart,9, 0x01,  5) |
-                       BIT(1,          0, 0x01,  6);
+       hw->crtc[7]  = ENCODE_BIT(Vtotal,     8, 0x01,  0) |
+                       ENCODE_BIT(Vdispend,   8, 0x01,  1) |
+                       ENCODE_BIT(Vsyncstart, 8, 0x01,  2) |
+                       ENCODE_BIT(Vblankstart, 8, 0x01,  3) |
+                       ENCODE_BIT(1,          0, 0x01,  4) |
+                       ENCODE_BIT(Vtotal,     9, 0x01,  5) |
+                       ENCODE_BIT(Vdispend,   9, 0x01,  6) |
+                       ENCODE_BIT(Vsyncstart, 9, 0x01,  7);
+       hw->crtc[9]  = ENCODE_BIT(0,          0, 0x1f,  0) |
+                       ENCODE_BIT(Vblankstart, 9, 0x01,  5) |
+                       ENCODE_BIT(1,          0, 0x01,  6);
        hw->crtc[10] = Vsyncstart;
-       hw->crtc[11] = BIT(Vsyncend,   0, 0x0f,  0) |
-                      BIT(1,          0, 0x01,  7);
+       hw->crtc[11] = ENCODE_BIT(Vsyncend,   0, 0x0f,  0) |
+                      ENCODE_BIT(1,          0, 0x01,  7);
        hw->crtc[12] = Vdispend;
        hw->crtc[15] = Vblankstart;
        hw->crtc[16] = Vblankend;
@@ -615,10 +613,10 @@ cyber2000fb_decode_crtc(struct par_info *hw, struct cfb_info *cfb,
         * 4=LINECOMP:10 5-IVIDEO 6=FIXCNT
         */
        hw->crtc_ofl =
-               BIT(Vtotal,     10, 0x01,  0) |
-               BIT(Vdispend,   10, 0x01,  1) |
-               BIT(Vsyncstart, 10, 0x01,  2) |
-               BIT(Vblankstart,10, 0x01,  3) |
+               ENCODE_BIT(Vtotal, 10, 0x01, 0) |
+               ENCODE_BIT(Vdispend, 10, 0x01, 1) |
+               ENCODE_BIT(Vsyncstart, 10, 0x01, 2) |
+               ENCODE_BIT(Vblankstart, 10, 0x01, 3) |
                EXT_CRT_VRTOFL_LINECOMP10;
 
        /* woody: set the interlaced bit... */
@@ -750,11 +748,11 @@ cyber2000fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
        var->red.msb_right      = 0;
        var->green.msb_right    = 0;
        var->blue.msb_right     = 0;
+       var->transp.offset      = 0;
+       var->transp.length      = 0;
 
        switch (var->bits_per_pixel) {
        case 8: /* PSEUDOCOLOUR, 256 */
-               var->transp.offset      = 0;
-               var->transp.length      = 0;
                var->red.offset         = 0;
                var->red.length         = 8;
                var->green.offset       = 0;
@@ -766,8 +764,6 @@ cyber2000fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
        case 16:/* DIRECTCOLOUR, 64k or 32k */
                switch (var->green.length) {
                case 6: /* RGB565, 64k */
-                       var->transp.offset      = 0;
-                       var->transp.length      = 0;
                        var->red.offset         = 11;
                        var->red.length         = 5;
                        var->green.offset       = 5;
@@ -778,8 +774,6 @@ cyber2000fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 
                default:
                case 5: /* RGB555, 32k */
-                       var->transp.offset      = 0;
-                       var->transp.length      = 0;
                        var->red.offset         = 10;
                        var->red.length         = 5;
                        var->green.offset       = 5;
@@ -802,8 +796,6 @@ cyber2000fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
                break;
 
        case 24:/* TRUECOLOUR, 16m */
-               var->transp.offset      = 0;
-               var->transp.length      = 0;
                var->red.offset         = 16;
                var->red.length         = 8;
                var->green.offset       = 8;
@@ -830,7 +822,7 @@ cyber2000fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
        mem = var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8);
        if (mem > cfb->fb.fix.smem_len)
                var->yres_virtual = cfb->fb.fix.smem_len * 8 /
-                       (var->bits_per_pixel * var->xres_virtual);
+                                   (var->bits_per_pixel * var->xres_virtual);
 
        if (var->yres > var->yres_virtual)
                var->yres = var->yres_virtual;
@@ -921,7 +913,7 @@ static int cyber2000fb_set_par(struct fb_info *info)
                hw.fetch <<= 1;
        hw.fetch += 1;
 
-       cfb->fb.fix.line_length = var->xres_virtual * var->bits_per_pixel / 8;
+       cfb->fb.fix.line_length = var->xres_virtual * var->bits_per_pixel / 8;
 
        /*
         * Same here - if the size of the video mode exceeds the
@@ -952,7 +944,6 @@ static int cyber2000fb_set_par(struct fb_info *info)
        return 0;
 }
 
-
 /*
  *    Pan or Wrap the Display
  */
@@ -1002,15 +993,15 @@ static int cyber2000fb_blank(int blank, struct fb_info *info)
        switch (blank) {
        case FB_BLANK_POWERDOWN:        /* powerdown - both sync lines down */
                sync = EXT_SYNC_CTL_VS_0 | EXT_SYNC_CTL_HS_0;
-               break;  
+               break;
        case FB_BLANK_HSYNC_SUSPEND:    /* hsync off */
                sync = EXT_SYNC_CTL_VS_NORMAL | EXT_SYNC_CTL_HS_0;
-               break;  
+               break;
        case FB_BLANK_VSYNC_SUSPEND:    /* vsync off */
                sync = EXT_SYNC_CTL_VS_0 | EXT_SYNC_CTL_HS_NORMAL;
                break;
-       case FB_BLANK_NORMAL:           /* soft blank */
-       default: /* unblank */
+       case FB_BLANK_NORMAL:           /* soft blank */
+       default:                        /* unblank */
                break;
        }
 
@@ -1018,7 +1009,8 @@ static int cyber2000fb_blank(int blank, struct fb_info *info)
 
        if (blank <= 1) {
                /* turn on ramdacs */
-               cfb->ramdac_powerdown &= ~(RAMDAC_DACPWRDN | RAMDAC_BYPASS | RAMDAC_RAMPWRDN);
+               cfb->ramdac_powerdown &= ~(RAMDAC_DACPWRDN | RAMDAC_BYPASS |
+                                          RAMDAC_RAMPWRDN);
                cyber2000fb_write_ramdac_ctrl(cfb);
        }
 
@@ -1043,7 +1035,8 @@ static int cyber2000fb_blank(int blank, struct fb_info *info)
 
        if (blank >= 2) {
                /* turn off ramdacs */
-               cfb->ramdac_powerdown |= RAMDAC_DACPWRDN | RAMDAC_BYPASS | RAMDAC_RAMPWRDN;
+               cfb->ramdac_powerdown |= RAMDAC_DACPWRDN | RAMDAC_BYPASS |
+                                        RAMDAC_RAMPWRDN;
                cyber2000fb_write_ramdac_ctrl(cfb);
        }
 
@@ -1068,7 +1061,7 @@ static struct fb_ops cyber2000fb_ops = {
  * of this driver.  It is here solely at the moment to support the other
  * CyberPro modules external to this driver.
  */
-static struct cfb_info         *int_cfb_info;
+static struct cfb_info *int_cfb_info;
 
 /*
  * Enable access to the extended registers
@@ -1085,6 +1078,7 @@ void cyber2000fb_enable_extregs(struct cfb_info *cfb)
                cyber2000_grphw(EXT_FUNC_CTL, old, cfb);
        }
 }
+EXPORT_SYMBOL(cyber2000fb_enable_extregs);
 
 /*
  * Disable access to the extended registers
@@ -1104,11 +1098,13 @@ void cyber2000fb_disable_extregs(struct cfb_info *cfb)
        else
                cfb->func_use_count -= 1;
 }
+EXPORT_SYMBOL(cyber2000fb_disable_extregs);
 
 void cyber2000fb_get_fb_var(struct cfb_info *cfb, struct fb_var_screeninfo *var)
 {
        memcpy(var, &cfb->fb.var, sizeof(struct fb_var_screeninfo));
 }
+EXPORT_SYMBOL(cyber2000fb_get_fb_var);
 
 /*
  * Attach a capture/tv driver to the core CyberX0X0 driver.
@@ -1122,13 +1118,15 @@ int cyber2000fb_attach(struct cyberpro_info *info, int idx)
                info->fb_size         = int_cfb_info->fb.fix.smem_len;
                info->enable_extregs  = cyber2000fb_enable_extregs;
                info->disable_extregs = cyber2000fb_disable_extregs;
-               info->info            = int_cfb_info;
+               info->info            = int_cfb_info;
 
-               strlcpy(info->dev_name, int_cfb_info->fb.fix.id, sizeof(info->dev_name));
+               strlcpy(info->dev_name, int_cfb_info->fb.fix.id,
+                       sizeof(info->dev_name));
        }
 
        return int_cfb_info != NULL;
 }
+EXPORT_SYMBOL(cyber2000fb_attach);
 
 /*
  * Detach a capture/tv driver from the core CyberX0X0 driver.
@@ -1136,12 +1134,7 @@ int cyber2000fb_attach(struct cyberpro_info *info, int idx)
 void cyber2000fb_detach(int idx)
 {
 }
-
-EXPORT_SYMBOL(cyber2000fb_attach);
 EXPORT_SYMBOL(cyber2000fb_detach);
-EXPORT_SYMBOL(cyber2000fb_enable_extregs);
-EXPORT_SYMBOL(cyber2000fb_disable_extregs);
-EXPORT_SYMBOL(cyber2000fb_get_fb_var);
 
 /*
  * These parameters give
@@ -1205,7 +1198,7 @@ static void cyberpro_init_hw(struct cfb_info *cfb)
        int i;
 
        for (i = 0; i < sizeof(igs_regs); i += 2)
-               cyber2000_grphw(igs_regs[i], igs_regs[i+1], cfb);
+               cyber2000_grphw(igs_regs[i], igs_regs[i + 1], cfb);
 
        if (cfb->id == ID_CYBERPRO_5000) {
                unsigned char val;
@@ -1215,8 +1208,8 @@ static void cyberpro_init_hw(struct cfb_info *cfb)
        }
 }
 
-static struct cfb_info * __devinit
-cyberpro_alloc_fb_info(unsigned int id, char *name)
+static struct cfb_info __devinit *cyberpro_alloc_fb_info(unsigned int id,
+                                                        char *name)
 {
        struct cfb_info *cfb;
 
@@ -1228,9 +1221,9 @@ cyberpro_alloc_fb_info(unsigned int id, char *name)
        cfb->id                 = id;
 
        if (id == ID_CYBERPRO_5000)
-               cfb->ref_ps     = 40690; // 24.576 MHz
+               cfb->ref_ps     = 40690; /* 24.576 MHz */
        else
-               cfb->ref_ps     = 69842; // 14.31818 MHz (69841?)
+               cfb->ref_ps     = 69842; /* 14.31818 MHz (69841?) */
 
        cfb->divisors[0]        = 1;
        cfb->divisors[1]        = 2;
@@ -1282,8 +1275,7 @@ cyberpro_alloc_fb_info(unsigned int id, char *name)
        return cfb;
 }
 
-static void
-cyberpro_free_fb_info(struct cfb_info *cfb)
+static void cyberpro_free_fb_info(struct cfb_info *cfb)
 {
        if (cfb) {
                /*
@@ -1300,8 +1292,7 @@ cyberpro_free_fb_info(struct cfb_info *cfb)
  *  video=cyber2000:font:fontname
  */
 #ifndef MODULE
-static int
-cyber2000fb_setup(char *options)
+static int cyber2000fb_setup(char *options)
 {
        char *opt;
 
@@ -1315,7 +1306,8 @@ cyber2000fb_setup(char *options)
                if (strncmp(opt, "font:", 5) == 0) {
                        static char default_font_storage[40];
 
-                       strlcpy(default_font_storage, opt + 5, sizeof(default_font_storage));
+                       strlcpy(default_font_storage, opt + 5,
+                               sizeof(default_font_storage));
                        default_font = default_font_storage;
                        continue;
                }
@@ -1354,10 +1346,18 @@ static int __devinit cyberpro_common_probe(struct cfb_info *cfb)
         * Determine the size of the memory.
         */
        switch (cfb->mem_ctl2 & MEM_CTL2_SIZE_MASK) {
-       case MEM_CTL2_SIZE_4MB: smem_size = 0x00400000; break;
-       case MEM_CTL2_SIZE_2MB: smem_size = 0x00200000; break;
-       case MEM_CTL2_SIZE_1MB: smem_size = 0x00100000; break;
-       default:                smem_size = 0x00100000; break;
+       case MEM_CTL2_SIZE_4MB:
+               smem_size = 0x00400000;
+               break;
+       case MEM_CTL2_SIZE_2MB:
+               smem_size = 0x00200000;
+               break;
+       case MEM_CTL2_SIZE_1MB:
+               smem_size = 0x00100000;
+               break;
+       default:
+               smem_size = 0x00100000;
+               break;
        }
 
        cfb->fb.fix.smem_len   = smem_size;
@@ -1366,8 +1366,8 @@ static int __devinit cyberpro_common_probe(struct cfb_info *cfb)
 
        err = -EINVAL;
        if (!fb_find_mode(&cfb->fb.var, &cfb->fb, NULL, NULL, 0,
-                         &cyber2000fb_default_mode, 8)) {
-               printk("%s: no valid mode found\n", cfb->fb.fix.id);
+                         &cyber2000fb_default_mode, 8)) {
+               printk(KERN_ERR "%s: no valid mode found\n", cfb->fb.fix.id);
                goto failed;
        }
 
@@ -1377,7 +1377,7 @@ static int __devinit cyberpro_common_probe(struct cfb_info *cfb)
        if (cfb->fb.var.yres_virtual < cfb->fb.var.yres)
                cfb->fb.var.yres_virtual = cfb->fb.var.yres;
 
-//     fb_set_var(&cfb->fb.var, -1, &cfb->fb);
+/*     fb_set_var(&cfb->fb.var, -1, &cfb->fb); */
 
        /*
         * Calculate the hsync and vsync frequencies.  Note that
@@ -1425,20 +1425,20 @@ static void cyberpro_common_resume(struct cfb_info *cfb)
 
 #include <asm/arch/hardware.h>
 
-static int __devinit
-cyberpro_vl_probe(void)
+static int __devinit cyberpro_vl_probe(void)
 {
        struct cfb_info *cfb;
        int err = -ENOMEM;
 
-       if (!request_mem_region(FB_START,FB_SIZE,"CyberPro2010")) return err;
+       if (!request_mem_region(FB_START, FB_SIZE, "CyberPro2010"))
+               return err;
 
        cfb = cyberpro_alloc_fb_info(ID_CYBERPRO_2010, "CyberPro2010");
        if (!cfb)
                goto failed_release;
 
        cfb->dev = NULL;
-       cfb->region = ioremap(FB_START,FB_SIZE);
+       cfb->region = ioremap(FB_START, FB_SIZE);
        if (!cfb->region)
                goto failed_ioremap;
 
@@ -1475,7 +1475,7 @@ failed:
 failed_ioremap:
        cyberpro_free_fb_info(cfb);
 failed_release:
-       release_mem_region(FB_START,FB_SIZE);
+       release_mem_region(FB_START, FB_SIZE);
 
        return err;
 }
@@ -1538,7 +1538,8 @@ static int cyberpro_pci_enable_mmio(struct cfb_info *cfb)
         * Allow the CyberPro to accept PCI burst accesses
         */
        if (cfb->id == ID_CYBERPRO_2010) {
-               printk(KERN_INFO "%s: NOT enabling PCI bursts\n", cfb->fb.fix.id);
+               printk(KERN_INFO "%s: NOT enabling PCI bursts\n",
+                      cfb->fb.fix.id);
        } else {
                val = cyber2000_grphr(EXT_BUS_CTL, cfb);
                if (!(val & EXT_BUS_CTL_PCIBURST_WRITE)) {
@@ -1688,9 +1689,10 @@ static int cyberpro_pci_resume(struct pci_dev *dev)
 }
 
 static struct pci_device_id cyberpro_pci_table[] = {
-//     Not yet
-//     { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_1682,
-//             PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_IGA_1682 },
+/*     Not yet
+ *     { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_1682,
+ *             PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_IGA_1682 },
+ */
        { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2000,
                PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_CYBERPRO_2000 },
        { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2010,
@@ -1700,7 +1702,7 @@ static struct pci_device_id cyberpro_pci_table[] = {
        { 0, }
 };
 
-MODULE_DEVICE_TABLE(pci,cyberpro_pci_table);
+MODULE_DEVICE_TABLE(pci, cyberpro_pci_table);
 
 static struct pci_driver cyberpro_driver = {
        .name           = "CyberPro",
index 7f3f18d06718846483d5c67d0dcfb2a3caf52ceb..febf09c63492fa6bdaba484c9bc603d35b1a4140 100644 (file)
@@ -127,7 +127,7 @@ static void gx_set_dclk_frequency(struct fb_info *info)
        int timeout = 1000;
 
        /* Rev. 1 Geode GXs use a 14 MHz reference clock instead of 48 MHz. */
-       if (cpu_data->x86_mask == 1) {
+       if (cpu_data(0).x86_mask == 1) {
                pll_table = gx_pll_table_14MHz;
                pll_table_len = ARRAY_SIZE(gx_pll_table_14MHz);
        } else {
index 23a6bcc3e3ceb74703d1f9aeb76718b0de7e7ede..e92337bef50d00951bc4a7b9689f0d05b31a62ec 100644 (file)
@@ -636,7 +636,7 @@ static int __devinit gxt4500_probe(struct pci_dev *pdev,
 
        info = framebuffer_alloc(sizeof(struct gxt4500_par), &pdev->dev);
        if (!info) {
-               dev_err(&pdev->dev, "gxt4500: cannot alloc FB info record");
+               dev_err(&pdev->dev, "gxt4500: cannot alloc FB info record\n");
                goto err_free_fb;
        }
        par = info->par;
index e8e38edb9b5b6546ef2d251a7490ad9e201a6b09..481d58f7535d0cc4cb5e09ba258a3a486f3cef33 100644 (file)
@@ -4,7 +4,7 @@
  * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G/915GM/
  * 945G/945GM integrated graphics chips.
  *
- * Copyright © 2002, 2003 David Dawes <dawes@xfree86.org>
+ * Copyright Â© 2002, 2003 David Dawes <dawes@xfree86.org>
  *                   2004 Sylvain Meyer
  *                   2006 David Airlie
  *
index 2a0e32074f7d4b1b615b719f5b447b3fae433ea9..5f6fb7d2c40898ab2dfaef590dc855876942b88e 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Linux framebuffer driver for Intel(R) 865G integrated graphics chips.
  *
- * Copyright © 2002, 2003 David Dawes <dawes@xfree86.org>
+ * Copyright Â© 2002, 2003 David Dawes <dawes@xfree86.org>
  *                   2004 Sylvain Meyer
  *
  * This driver consists of two parts.  The first part (intelfbdrv.c) provides
index a9283bae7790a954d98023559b2e0841064e4e90..fc72684aae5aae4328e67db391dcb2b62bdd4e8f 100644 (file)
@@ -78,10 +78,7 @@ const struct linux_logo * __init_refok fb_find_logo(int depth)
 #endif
 #ifdef CONFIG_LOGO_DEC_CLUT224
                /* DEC Linux logo on MIPS/MIPS64 or ALPHA */
-#ifndef CONFIG_ALPHA
-               if (mips_machgroup == MACH_GROUP_DEC)
-#endif
-                       logo = &logo_dec_clut224;
+               logo = &logo_dec_clut224;
 #endif
 #ifdef CONFIG_LOGO_MAC_CLUT224
                /* Macintosh Linux logo on m68k */
@@ -94,10 +91,7 @@ const struct linux_logo * __init_refok fb_find_logo(int depth)
 #endif
 #ifdef CONFIG_LOGO_SGI_CLUT224
                /* SGI Linux logo on MIPS/MIPS64 and VISWS */
-#ifndef CONFIG_X86_VISWS
-               if (mips_machgroup == MACH_GROUP_SGI)
-#endif
-                       logo = &logo_sgi_clut224;
+               logo = &logo_sgi_clut224;
 #endif
 #ifdef CONFIG_LOGO_SUN_CLUT224
                /* Sun Linux logo */
index 42f5d76a87771134d421feafd84895abf4084ccb..8d81ef019c6c6f8de6a5eeb6013b061de650a649 100644 (file)
@@ -510,7 +510,9 @@ int fb_find_mode(struct fb_var_screeninfo *var,
        default_bpp = 8;
 
     /* Did the user specify a video mode? */
-    if (mode_option || (mode_option = fb_mode_option)) {
+    if (!mode_option)
+       mode_option = fb_mode_option;
+    if (mode_option) {
        const char *name = mode_option;
        unsigned int namelen = strlen(name);
        int res_specified = 0, bpp_specified = 0, refresh_specified = 0;
index 7f4d25b8a1849789e6a6f49f094cb2b7d7f2a903..f4fcf11b290d0ddaf3a4f8653a8c95482fb269a8 100644 (file)
@@ -8,7 +8,7 @@ config FB_OMAP
           Frame buffer driver for OMAP based boards.
 
 config FB_OMAP_BOOTLOADER_INIT
-       bool "Check bootloader initializaion"
+       bool "Check bootloader initialization"
        depends on FB_OMAP
        help
          Say Y here if you want to enable checking if the bootloader has
index e682940a97a4183b40cbe0c61c18f27317cff6f0..4d8ad9cd0e19701c0b8c15135ac08610680f107d 100644 (file)
@@ -225,7 +225,7 @@ static void blizzard_restart_sdram(void)
        while (!(blizzard_read_reg(BLIZZARD_MEM_BANK0_STATUS) & 0x01)) {
                if (time_after(jiffies, tmo)) {
                        dev_err(blizzard.fbdev->dev,
-                                       "s1d1374x: SDRAM not ready");
+                                       "s1d1374x: SDRAM not ready\n");
                        break;
                }
                msleep(1);
index f4c23434de6f6a5508cbf1c3bec83e1ed1c5314f..ab32ceb061781fdb1a2c155991ec1b879dc53133 100644 (file)
@@ -880,19 +880,19 @@ static irqreturn_t omap_dispc_irq_handler(int irq, void *dev)
 static int get_dss_clocks(void)
 {
        if (IS_ERR((dispc.dss_ick = clk_get(dispc.fbdev->dev, "dss_ick")))) {
-               dev_err(dispc.fbdev->dev, "can't get dss_ick");
+               dev_err(dispc.fbdev->dev, "can't get dss_ick\n");
                return PTR_ERR(dispc.dss_ick);
        }
 
        if (IS_ERR((dispc.dss1_fck = clk_get(dispc.fbdev->dev, "dss1_fck")))) {
-               dev_err(dispc.fbdev->dev, "can't get dss1_fck");
+               dev_err(dispc.fbdev->dev, "can't get dss1_fck\n");
                clk_put(dispc.dss_ick);
                return PTR_ERR(dispc.dss1_fck);
        }
 
        if (IS_ERR((dispc.dss_54m_fck =
                                clk_get(dispc.fbdev->dev, "dss_54m_fck")))) {
-               dev_err(dispc.fbdev->dev, "can't get dss_54m_fck");
+               dev_err(dispc.fbdev->dev, "can't get dss_54m_fck\n");
                clk_put(dispc.dss_ick);
                clk_put(dispc.dss1_fck);
                return PTR_ERR(dispc.dss_54m_fck);
index dc48e02f215c4b2fad5944589f319aaac6521254..1e642b7a20fed1d7d63958c2a6a410de9040915a 100644 (file)
@@ -508,7 +508,7 @@ int hwa742_update_window_async(struct fb_info *fbi,
        if (unlikely(win->format &
            ~(0x03 | OMAPFB_FORMAT_FLAG_DOUBLE |
            OMAPFB_FORMAT_FLAG_TEARSYNC | OMAPFB_FORMAT_FLAG_FORCE_VSYNC))) {
-               dev_dbg(hwa742.fbdev->dev, "invalid window flag");
+               dev_dbg(hwa742.fbdev->dev, "invalid window flag\n");
                r = -EINVAL;
                goto out;
        }
index 2b4269813b222e66c55d2eec09cb4caaa3d77952..789cfd23c36b1477734b59f9e5accdcead17e6fd 100644 (file)
@@ -84,12 +84,12 @@ static inline u32 rfbi_read_reg(int idx)
 static int rfbi_get_clocks(void)
 {
        if (IS_ERR((rfbi.dss_ick = clk_get(rfbi.fbdev->dev, "dss_ick")))) {
-               dev_err(rfbi.fbdev->dev, "can't get dss_ick");
+               dev_err(rfbi.fbdev->dev, "can't get dss_ick\n");
                return PTR_ERR(rfbi.dss_ick);
        }
 
        if (IS_ERR((rfbi.dss1_fck = clk_get(rfbi.fbdev->dev, "dss1_fck")))) {
-               dev_err(rfbi.fbdev->dev, "can't get dss1_fck");
+               dev_err(rfbi.fbdev->dev, "can't get dss1_fck\n");
                clk_put(rfbi.dss_ick);
                return PTR_ERR(rfbi.dss1_fck);
        }
index e8c5dcdd8813fe2d02343e8a368799222ec5b235..189c3d64138307488010037c06e325255acd344a 100644 (file)
@@ -77,9 +77,6 @@
 #define CONF_DIRTYDETECTION_OFF        (0x600)
 #define CONF_DIRTYDETECTION_ON (0x601)
 
-/* Set the corresponding bit. */
-#define BIT(n) (0x1U << (n))
-
 struct dumchannel_uf {
        int channelnr;
        u32 *dirty;
index ae08d45870917e3fac1dc70dca5201c87ff147d3..5857ccf5f6b15208f64a7221405063f280b2d44a 100644 (file)
@@ -56,7 +56,7 @@
  *     - Add support for different devices
  *     - Backlight support
  *
- * 2004-09-05: Herbert Pötzl <herbert@13thfloor.at>
+ * 2004-09-05: Herbert Pötzl <herbert@13thfloor.at>
  *     - added clock (de-)allocation code
  *     - added fixem fbmem option
  *
@@ -64,7 +64,7 @@
  *     - code cleanup
  *     - added a forgotten return in h1940fb_init
  *
- * 2004-07-19: Herbert Pötzl <herbert@13thfloor.at>
+ * 2004-07-19: Herbert Pötzl <herbert@13thfloor.at>
  *     - code cleanup and extended debugging
  *
  * 2004-07-15: Arnaud Patard <arnaud.patard@rtp-net.org>
index ff9e805c43bccedcbd89689b45136f0c6ea6fa5c..c31f549ebea0b88750118cd7f5a6c72305182895 100644 (file)
@@ -23,8 +23,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  *
  * Authors:
- *   Thomas Hellström <thomas-at-tungstengraphics-dot-com>
- *   Michel Dänzer <michel-at-tungstengraphics-dot-com>
+ *   Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ *   Michel Dänzer <michel-at-tungstengraphics-dot-com>
  *   Alan Hourihane <alanh-at-tungstengraphics-dot-com>
  */
 
index 1fc6695a49d2f1f70642f76b1b830b669ae40eb1..c4aba59d4809a7fce3eec1d0504e926fe67b16bb 100644 (file)
@@ -23,7 +23,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  *
  * Authors:
- *   Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ *   Thomas Hellström <thomas-at-tungstengraphics-dot-com>
  */
 
 #ifndef _VERMILION_H_
diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
new file mode 100644 (file)
index 0000000..9e33fc4
--- /dev/null
@@ -0,0 +1,8 @@
+# Virtio always gets selected by whoever wants it.
+config VIRTIO
+       bool
+
+# Similarly the virtio ring implementation.
+config VIRTIO_RING
+       bool
+       depends on VIRTIO
diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile
new file mode 100644 (file)
index 0000000..f70e409
--- /dev/null
@@ -0,0 +1,2 @@
+obj-$(CONFIG_VIRTIO) += virtio.o
+obj-$(CONFIG_VIRTIO_RING) += virtio_ring.o
diff --git a/drivers/virtio/config.c b/drivers/virtio/config.c
new file mode 100644 (file)
index 0000000..983d482
--- /dev/null
@@ -0,0 +1,13 @@
+/* Configuration space parsing helpers for virtio.
+ *
+ * The configuration is [type][len][... len bytes ...] fields.
+ *
+ * Copyright 2007 Rusty Russell, IBM Corporation.
+ * GPL v2 or later.
+ */
+#include <linux/err.h>
+#include <linux/virtio.h>
+#include <linux/virtio_config.h>
+#include <linux/bug.h>
+#include <asm/system.h>
+
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
new file mode 100644 (file)
index 0000000..15d7787
--- /dev/null
@@ -0,0 +1,189 @@
+#include <linux/virtio.h>
+#include <linux/spinlock.h>
+#include <linux/virtio_config.h>
+
+static ssize_t device_show(struct device *_d,
+                          struct device_attribute *attr, char *buf)
+{
+       struct virtio_device *dev = container_of(_d,struct virtio_device,dev);
+       return sprintf(buf, "%hu", dev->id.device);
+}
+static ssize_t vendor_show(struct device *_d,
+                          struct device_attribute *attr, char *buf)
+{
+       struct virtio_device *dev = container_of(_d,struct virtio_device,dev);
+       return sprintf(buf, "%hu", dev->id.vendor);
+}
+static ssize_t status_show(struct device *_d,
+                          struct device_attribute *attr, char *buf)
+{
+       struct virtio_device *dev = container_of(_d,struct virtio_device,dev);
+       return sprintf(buf, "0x%08x", dev->config->get_status(dev));
+}
+static ssize_t modalias_show(struct device *_d,
+                            struct device_attribute *attr, char *buf)
+{
+       struct virtio_device *dev = container_of(_d,struct virtio_device,dev);
+
+       return sprintf(buf, "virtio:d%08Xv%08X\n",
+                      dev->id.device, dev->id.vendor);
+}
+static struct device_attribute virtio_dev_attrs[] = {
+       __ATTR_RO(device),
+       __ATTR_RO(vendor),
+       __ATTR_RO(status),
+       __ATTR_RO(modalias),
+       __ATTR_NULL
+};
+
+static inline int virtio_id_match(const struct virtio_device *dev,
+                                 const struct virtio_device_id *id)
+{
+       if (id->device != dev->id.device)
+               return 0;
+
+       return id->vendor == VIRTIO_DEV_ANY_ID || id->vendor != dev->id.vendor;
+}
+
+/* This looks through all the IDs a driver claims to support.  If any of them
+ * match, we return 1 and the kernel will call virtio_dev_probe(). */
+static int virtio_dev_match(struct device *_dv, struct device_driver *_dr)
+{
+       unsigned int i;
+       struct virtio_device *dev = container_of(_dv,struct virtio_device,dev);
+       const struct virtio_device_id *ids;
+
+       ids = container_of(_dr, struct virtio_driver, driver)->id_table;
+       for (i = 0; ids[i].device; i++)
+               if (virtio_id_match(dev, &ids[i]))
+                       return 1;
+       return 0;
+}
+
+static int virtio_uevent(struct device *_dv, struct kobj_uevent_env *env)
+{
+       struct virtio_device *dev = container_of(_dv,struct virtio_device,dev);
+
+       return add_uevent_var(env, "MODALIAS=virtio:d%08Xv%08X",
+                             dev->id.device, dev->id.vendor);
+}
+
+static struct bus_type virtio_bus = {
+       .name  = "virtio",
+       .match = virtio_dev_match,
+       .dev_attrs = virtio_dev_attrs,
+       .uevent = virtio_uevent,
+};
+
+static void add_status(struct virtio_device *dev, unsigned status)
+{
+       dev->config->set_status(dev, dev->config->get_status(dev) | status);
+}
+
+static int virtio_dev_probe(struct device *_d)
+{
+       int err;
+       struct virtio_device *dev = container_of(_d,struct virtio_device,dev);
+       struct virtio_driver *drv = container_of(dev->dev.driver,
+                                                struct virtio_driver, driver);
+
+       add_status(dev, VIRTIO_CONFIG_S_DRIVER);
+       err = drv->probe(dev);
+       if (err)
+               add_status(dev, VIRTIO_CONFIG_S_FAILED);
+       else
+               add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
+       return err;
+}
+
+int register_virtio_driver(struct virtio_driver *driver)
+{
+       driver->driver.bus = &virtio_bus;
+       driver->driver.probe = virtio_dev_probe;
+       return driver_register(&driver->driver);
+}
+EXPORT_SYMBOL_GPL(register_virtio_driver);
+
+void unregister_virtio_driver(struct virtio_driver *driver)
+{
+       driver_unregister(&driver->driver);
+}
+EXPORT_SYMBOL_GPL(unregister_virtio_driver);
+
+int register_virtio_device(struct virtio_device *dev)
+{
+       int err;
+
+       dev->dev.bus = &virtio_bus;
+       sprintf(dev->dev.bus_id, "%u", dev->index);
+
+       /* Acknowledge that we've seen the device. */
+       add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE);
+
+       /* device_register() causes the bus infrastructure to look for a
+        * matching driver. */
+       err = device_register(&dev->dev);
+       if (err)
+               add_status(dev, VIRTIO_CONFIG_S_FAILED);
+       return err;
+}
+EXPORT_SYMBOL_GPL(register_virtio_device);
+
+void unregister_virtio_device(struct virtio_device *dev)
+{
+       device_unregister(&dev->dev);
+}
+EXPORT_SYMBOL_GPL(unregister_virtio_device);
+
+int __virtio_config_val(struct virtio_device *vdev,
+                       u8 type, void *val, size_t size)
+{
+       void *token;
+       unsigned int len;
+
+       token = vdev->config->find(vdev, type, &len);
+       if (!token)
+               return -ENOENT;
+
+       if (len != size)
+               return -EIO;
+
+       vdev->config->get(vdev, token, val, size);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(__virtio_config_val);
+
+int virtio_use_bit(struct virtio_device *vdev,
+                  void *token, unsigned int len, unsigned int bitnum)
+{
+       unsigned long bits[16];
+
+       /* This makes it convenient to pass-through find() results. */
+       if (!token)
+               return 0;
+
+       /* bit not in range of this bitfield? */
+       if (bitnum * 8 >= len / 2)
+               return 0;
+
+       /* Giant feature bitfields are silly. */
+       BUG_ON(len > sizeof(bits));
+       vdev->config->get(vdev, token, bits, len);
+
+       if (!test_bit(bitnum, bits))
+               return 0;
+
+       /* Set acknowledge bit, and write it back. */
+       set_bit(bitnum + len * 8 / 2, bits);
+       vdev->config->set(vdev, token, bits, len);
+       return 1;
+}
+EXPORT_SYMBOL_GPL(virtio_use_bit);
+
+static int virtio_init(void)
+{
+       if (bus_register(&virtio_bus) != 0)
+               panic("virtio bus registration failed");
+       return 0;
+}
+core_initcall(virtio_init);
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
new file mode 100644 (file)
index 0000000..0e4baca
--- /dev/null
@@ -0,0 +1,313 @@
+/* Virtio ring implementation.
+ *
+ *  Copyright 2007 Rusty Russell 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/virtio.h>
+#include <linux/virtio_ring.h>
+#include <linux/device.h>
+
+#ifdef DEBUG
+/* For development, we want to crash whenever the ring is screwed. */
+#define BAD_RING(vq, fmt...)                   \
+       do { dev_err(&vq->vq.vdev->dev, fmt); BUG(); } while(0)
+#define START_USE(vq) \
+       do { if ((vq)->in_use) panic("in_use = %i\n", (vq)->in_use); (vq)->in_use = __LINE__; mb(); } while(0)
+#define END_USE(vq) \
+       do { BUG_ON(!(vq)->in_use); (vq)->in_use = 0; mb(); } while(0)
+#else
+#define BAD_RING(vq, fmt...)                   \
+       do { dev_err(&vq->vq.vdev->dev, fmt); (vq)->broken = true; } while(0)
+#define START_USE(vq)
+#define END_USE(vq)
+#endif
+
+struct vring_virtqueue
+{
+       struct virtqueue vq;
+
+       /* Actual memory layout for this queue */
+       struct vring vring;
+
+       /* Other side has made a mess, don't try any more. */
+       bool broken;
+
+       /* Number of free buffers */
+       unsigned int num_free;
+       /* Head of free buffer list. */
+       unsigned int free_head;
+       /* Number we've added since last sync. */
+       unsigned int num_added;
+
+       /* Last used index we've seen. */
+       unsigned int last_used_idx;
+
+       /* How to notify other side. FIXME: commonalize hcalls! */
+       void (*notify)(struct virtqueue *vq);
+
+#ifdef DEBUG
+       /* They're supposed to lock for us. */
+       unsigned int in_use;
+#endif
+
+       /* Tokens for callbacks. */
+       void *data[];
+};
+
+#define to_vvq(_vq) container_of(_vq, struct vring_virtqueue, vq)
+
+static int vring_add_buf(struct virtqueue *_vq,
+                        struct scatterlist sg[],
+                        unsigned int out,
+                        unsigned int in,
+                        void *data)
+{
+       struct vring_virtqueue *vq = to_vvq(_vq);
+       unsigned int i, avail, head, uninitialized_var(prev);
+
+       BUG_ON(data == NULL);
+       BUG_ON(out + in > vq->vring.num);
+       BUG_ON(out + in == 0);
+
+       START_USE(vq);
+
+       if (vq->num_free < out + in) {
+               pr_debug("Can't add buf len %i - avail = %i\n",
+                        out + in, vq->num_free);
+               END_USE(vq);
+               return -ENOSPC;
+       }
+
+       /* We're about to use some buffers from the free list. */
+       vq->num_free -= out + in;
+
+       head = vq->free_head;
+       for (i = vq->free_head; out; i = vq->vring.desc[i].next, out--) {
+               vq->vring.desc[i].flags = VRING_DESC_F_NEXT;
+               vq->vring.desc[i].addr = (page_to_pfn(sg_page(sg))<<PAGE_SHIFT)
+                       + sg->offset;
+               vq->vring.desc[i].len = sg->length;
+               prev = i;
+               sg++;
+       }
+       for (; in; i = vq->vring.desc[i].next, in--) {
+               vq->vring.desc[i].flags = VRING_DESC_F_NEXT|VRING_DESC_F_WRITE;
+               vq->vring.desc[i].addr = (page_to_pfn(sg_page(sg))<<PAGE_SHIFT)
+                       + sg->offset;
+               vq->vring.desc[i].len = sg->length;
+               prev = i;
+               sg++;
+       }
+       /* Last one doesn't continue. */
+       vq->vring.desc[prev].flags &= ~VRING_DESC_F_NEXT;
+
+       /* Update free pointer */
+       vq->free_head = i;
+
+       /* Set token. */
+       vq->data[head] = data;
+
+       /* Put entry in available array (but don't update avail->idx until they
+        * do sync).  FIXME: avoid modulus here? */
+       avail = (vq->vring.avail->idx + vq->num_added++) % vq->vring.num;
+       vq->vring.avail->ring[avail] = head;
+
+       pr_debug("Added buffer head %i to %p\n", head, vq);
+       END_USE(vq);
+       return 0;
+}
+
+static void vring_kick(struct virtqueue *_vq)
+{
+       struct vring_virtqueue *vq = to_vvq(_vq);
+       START_USE(vq);
+       /* Descriptors and available array need to be set before we expose the
+        * new available array entries. */
+       wmb();
+
+       vq->vring.avail->idx += vq->num_added;
+       vq->num_added = 0;
+
+       /* Need to update avail index before checking if we should notify */
+       mb();
+
+       if (!(vq->vring.used->flags & VRING_USED_F_NO_NOTIFY))
+               /* Prod other side to tell it about changes. */
+               vq->notify(&vq->vq);
+
+       END_USE(vq);
+}
+
+static void detach_buf(struct vring_virtqueue *vq, unsigned int head)
+{
+       unsigned int i;
+
+       /* Clear data ptr. */
+       vq->data[head] = NULL;
+
+       /* Put back on free list: find end */
+       i = head;
+       while (vq->vring.desc[i].flags & VRING_DESC_F_NEXT) {
+               i = vq->vring.desc[i].next;
+               vq->num_free++;
+       }
+
+       vq->vring.desc[i].next = vq->free_head;
+       vq->free_head = head;
+       /* Plus final descriptor */
+       vq->num_free++;
+}
+
+/* FIXME: We need to tell other side about removal, to synchronize. */
+static void vring_shutdown(struct virtqueue *_vq)
+{
+       struct vring_virtqueue *vq = to_vvq(_vq);
+       unsigned int i;
+
+       for (i = 0; i < vq->vring.num; i++)
+               detach_buf(vq, i);
+}
+
+static inline bool more_used(const struct vring_virtqueue *vq)
+{
+       return vq->last_used_idx != vq->vring.used->idx;
+}
+
+static void *vring_get_buf(struct virtqueue *_vq, unsigned int *len)
+{
+       struct vring_virtqueue *vq = to_vvq(_vq);
+       void *ret;
+       unsigned int i;
+
+       START_USE(vq);
+
+       if (!more_used(vq)) {
+               pr_debug("No more buffers in queue\n");
+               END_USE(vq);
+               return NULL;
+       }
+
+       i = vq->vring.used->ring[vq->last_used_idx%vq->vring.num].id;
+       *len = vq->vring.used->ring[vq->last_used_idx%vq->vring.num].len;
+
+       if (unlikely(i >= vq->vring.num)) {
+               BAD_RING(vq, "id %u out of range\n", i);
+               return NULL;
+       }
+       if (unlikely(!vq->data[i])) {
+               BAD_RING(vq, "id %u is not a head!\n", i);
+               return NULL;
+       }
+
+       /* detach_buf clears data, so grab it now. */
+       ret = vq->data[i];
+       detach_buf(vq, i);
+       vq->last_used_idx++;
+       END_USE(vq);
+       return ret;
+}
+
+static bool vring_restart(struct virtqueue *_vq)
+{
+       struct vring_virtqueue *vq = to_vvq(_vq);
+
+       START_USE(vq);
+       BUG_ON(!(vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT));
+
+       /* We optimistically turn back on interrupts, then check if there was
+        * more to do. */
+       vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT;
+       mb();
+       if (unlikely(more_used(vq))) {
+               vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
+               END_USE(vq);
+               return false;
+       }
+
+       END_USE(vq);
+       return true;
+}
+
+irqreturn_t vring_interrupt(int irq, void *_vq)
+{
+       struct vring_virtqueue *vq = to_vvq(_vq);
+
+       if (!more_used(vq)) {
+               pr_debug("virtqueue interrupt with no work for %p\n", vq);
+               return IRQ_NONE;
+       }
+
+       if (unlikely(vq->broken))
+               return IRQ_HANDLED;
+
+       pr_debug("virtqueue callback for %p (%p)\n", vq, vq->vq.callback);
+       if (vq->vq.callback && !vq->vq.callback(&vq->vq))
+               vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
+
+       return IRQ_HANDLED;
+}
+
+static struct virtqueue_ops vring_vq_ops = {
+       .add_buf = vring_add_buf,
+       .get_buf = vring_get_buf,
+       .kick = vring_kick,
+       .restart = vring_restart,
+       .shutdown = vring_shutdown,
+};
+
+struct virtqueue *vring_new_virtqueue(unsigned int num,
+                                     struct virtio_device *vdev,
+                                     void *pages,
+                                     void (*notify)(struct virtqueue *),
+                                     bool (*callback)(struct virtqueue *))
+{
+       struct vring_virtqueue *vq;
+       unsigned int i;
+
+       vq = kmalloc(sizeof(*vq) + sizeof(void *)*num, GFP_KERNEL);
+       if (!vq)
+               return NULL;
+
+       vring_init(&vq->vring, num, pages);
+       vq->vq.callback = callback;
+       vq->vq.vdev = vdev;
+       vq->vq.vq_ops = &vring_vq_ops;
+       vq->notify = notify;
+       vq->broken = false;
+       vq->last_used_idx = 0;
+       vq->num_added = 0;
+#ifdef DEBUG
+       vq->in_use = false;
+#endif
+
+       /* No callback?  Tell other side not to bother us. */
+       if (!callback)
+               vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
+
+       /* Put everything in free lists. */
+       vq->num_free = num;
+       vq->free_head = 0;
+       for (i = 0; i < num-1; i++)
+               vq->vring.desc[i].next = i+1;
+
+       return &vq->vq;
+}
+
+void vring_del_virtqueue(struct virtqueue *vq)
+{
+       kfree(to_vvq(vq));
+}
+
index 4b696641ce33a94d7ba3ae36fc86b45114f0e690..5747997f8d7db5c2130c5b8e648330f9daf6084b 100644 (file)
@@ -307,7 +307,7 @@ static void ds1wm_search(void *data, u8 search_type,
                rom_id |= (unsigned long long) r << (i * 4);
 
        }
-       dev_dbg(&ds1wm_data->pdev->dev, "found 0x%08llX", rom_id);
+       dev_dbg(&ds1wm_data->pdev->dev, "found 0x%08llX\n", rom_id);
 
        ds1wm_write_register(ds1wm_data, DS1WM_CMD, ~DS1WM_CMD_SRA);
        ds1wm_reset(ds1wm_data);
similarity index 99%
rename from drivers/char/watchdog/at91rm9200_wdt.c
rename to drivers/watchdog/at91rm9200_wdt.c
index 38bd3737259973fcaebf683a2a5810283e46ffd8..a684b1e873723732836b638b3c52cece15cc0f92 100644 (file)
@@ -9,6 +9,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#include <linux/bitops.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/init.h>
@@ -19,7 +20,6 @@
 #include <linux/platform_device.h>
 #include <linux/types.h>
 #include <linux/watchdog.h>
-#include <asm/bitops.h>
 #include <asm/uaccess.h>
 #include <asm/arch/at91_st.h>
 
similarity index 98%
rename from drivers/char/watchdog/i6300esb.c
rename to drivers/watchdog/i6300esb.c
index c5982502c03d45a8def683ac7c06cf4d83ad3719..f236954d2536c0222efa600c7524527625c7e2dd 100644 (file)
@@ -2,7 +2,7 @@
  *     i6300esb:       Watchdog timer driver for Intel 6300ESB chipset
  *
  *     (c) Copyright 2004 Google Inc.
- *     (c) Copyright 2005 David Härdeman <david@2gen.com>
+ *     (c) Copyright 2005 David Härdeman <david@2gen.com>
  *
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License
@@ -19,7 +19,7 @@
  *     Initial version 0.01
  *  2004YYZZ Ross Biro
  *     Version 0.02
- *  20050210 David Härdeman <david@2gen.com>
+ *  20050210 David Härdeman <david@2gen.com>
  *      Ported driver to kernel 2.6
  */
 
@@ -521,7 +521,7 @@ static void __exit watchdog_cleanup (void)
 module_init(watchdog_init);
 module_exit(watchdog_cleanup);
 
-MODULE_AUTHOR("Ross Biro and David Härdeman");
+MODULE_AUTHOR("Ross Biro and David Härdeman");
 MODULE_DESCRIPTION("Watchdog driver for Intel 6300ESB chipsets");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
similarity index 99%
rename from drivers/char/watchdog/iTCO_vendor_support.c
rename to drivers/watchdog/iTCO_vendor_support.c
index 41508399009710e80a374eb300abe5c9d2ac6e6a..cafc465f2ae3308a9b838dae1e1912061dce9038 100644 (file)
@@ -115,7 +115,7 @@ static void supermicro_old_pre_keepalive(unsigned long acpibase)
  *       For P4DPx:
  *       BIOS setup -> Advanced -> I/O Device Configuration -> Watch Dog
  *      This setting enables or disables Watchdog function. When enabled, the
- *      default watchdog timer is set to be 5 minutes (about 4’35”). It is
+ *      default watchdog timer is set to be 5 minutes (about 4m35s). It is
  *      enough to load and run the OS. The application (service or driver) has
  *      to take over the control once OS is running up and before watchdog
  *      expires.
similarity index 99%
rename from drivers/char/watchdog/ks8695_wdt.c
rename to drivers/watchdog/ks8695_wdt.c
index 7150fb945eaf77c4a2774fdbb884fe3dec8a7d9e..e3a29c3023095ed8ca8e53bf667f16ce865bf095 100644 (file)
@@ -8,6 +8,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/bitops.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/init.h>
@@ -18,7 +19,6 @@
 #include <linux/platform_device.h>
 #include <linux/types.h>
 #include <linux/watchdog.h>
-#include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/arch/regs-timer.h>
similarity index 98%
rename from drivers/char/watchdog/mpc5200_wdt.c
rename to drivers/watchdog/mpc5200_wdt.c
index 9cfb9757662361cb64b770764aa1fa66a4be29f8..11f6a111e75b750dc6716bb19ba2aedb4cdc98aa 100644 (file)
@@ -175,6 +175,8 @@ static int mpc5200_wdt_probe(struct of_device *op, const struct of_device_id *ma
        int size;
 
        has_wdt = of_get_property(op->node, "has-wdt", NULL);
+       if (!has_wdt)
+               has_wdt = of_get_property(op->node, "fsl,has-wdt", NULL);
        if (!has_wdt)
                return -ENODEV;
 
@@ -254,6 +256,7 @@ static int mpc5200_wdt_shutdown(struct of_device *op)
 
 static struct of_device_id mpc5200_wdt_match[] = {
        { .compatible = "mpc5200-gpt", },
+       { .compatible = "fsl,mpc5200-gpt", },
        {},
 };
 static struct of_platform_driver mpc5200_wdt_driver = {
similarity index 99%
rename from drivers/char/watchdog/omap_wdt.c
rename to drivers/watchdog/omap_wdt.c
index 719b066f73c41cd8cbf655d7f2afa0c7ad81e774..635ca454f56bafc6f52f4752a6be5ebdddc17940 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/moduleparam.h>
 #include <linux/clk.h>
+#include <linux/bitops.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/hardware.h>
-#include <asm/bitops.h>
 
 #include <asm/arch/prcm.h>
 
similarity index 99%
rename from drivers/char/watchdog/sa1100_wdt.c
rename to drivers/watchdog/sa1100_wdt.c
index 3475f47aaa45766cc48f3cf7361683ddfede5aee..34a2b3b81800785d8e2967ddd388cfa01905658a 100644 (file)
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
 #include <linux/init.h>
+#include <linux/bitops.h>
 
 #ifdef CONFIG_ARCH_PXA
 #include <asm/arch/pxa-regs.h>
 #endif
 
 #include <asm/hardware.h>
-#include <asm/bitops.h>
 #include <asm/uaccess.h>
 
 #define OSCR_FREQ              CLOCK_TICK_RATE
similarity index 99%
rename from drivers/char/watchdog/w83697hf_wdt.c
rename to drivers/watchdog/w83697hf_wdt.c
index d9e821d08deb3b7ea21b36be0ec4682389e807e5..51826c216d6d0c22451db409841e00864e00fd3d 100644 (file)
@@ -8,7 +8,7 @@
  *     which is based on wdt.c.
  *     Original copyright messages:
  *
- *     (c) Copyright 2003 Pádraig Brady <P@draigBrady.com>
+ *     (c) Copyright 2003 Pádraig Brady <P@draigBrady.com>
  *
  *     (c) Copyright 2000-2001 Marek Michalkiewicz <marekm@linux.org.pl>
  *
index 0b769f7c4a483bda7c77b40289c413511999b196..4750de316ad36fbde50524d81beac8f10cfd424f 100644 (file)
@@ -185,13 +185,14 @@ static void otherend_changed(struct xenbus_watch *watch,
        if (!dev->otherend ||
            strncmp(dev->otherend, vec[XS_WATCH_PATH],
                    strlen(dev->otherend))) {
-               dev_dbg(&dev->dev, "Ignoring watch at %s", vec[XS_WATCH_PATH]);
+               dev_dbg(&dev->dev, "Ignoring watch at %s\n",
+                       vec[XS_WATCH_PATH]);
                return;
        }
 
        state = xenbus_read_driver_state(dev->otherend);
 
-       dev_dbg(&dev->dev, "state is %d, (%s), %s, %s",
+       dev_dbg(&dev->dev, "state is %d, (%s), %s, %s\n",
                state, xenbus_strstate(state), dev->otherend_watch.node,
                vec[XS_WATCH_PATH]);
 
index 5bd4b05d4c451efb112825b147e68ea472ba63b0..560fef2a7b1c39f3d0b5d1ed17fc1e8a9f0bdac4 100644 (file)
        0100  RH 800C [HD Controller]
        0200  RH 800C [RAM Expansion]
 0861  Kato
-# The Rainbow II and III are actually made by Ingenieurbüro Helfrich
+# The Rainbow II and III are actually made by Ingenieurbüro Helfrich
        2000  Rainbow II [Graphics Card]
        2100  Rainbow III [Graphics Card]
        8000  Melody MPEG [Audio Card]
index 873802de21cd9a2539e8ffbc47ee0a8a0a28babb..756f7e9beb2e0a12cc1ad527992ca9fe6537c966 100644 (file)
@@ -162,6 +162,7 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses)
                                if (*e != '\0')
                                        v9ses->uid = ~0;
                        }
+                       kfree(s);
                        break;
 
                default:
index 175b4d9bf3f88af4059caaa368aac3ad761abd37..23581bcb599b2f7d6031644de612742512e218e3 100644 (file)
@@ -687,10 +687,10 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
        retval = p9_client_wstat(oldfid, &wstat);
 
 clunk_newdir:
-       p9_client_clunk(olddirfid);
+       p9_client_clunk(newdirfid);
 
 clunk_olddir:
-       p9_client_clunk(newdirfid);
+       p9_client_clunk(olddirfid);
 
 done:
        return retval;
index d8062745716ae407fee7948a12a88a6370e5e9aa..cc28a69246a7dc8536de2e9c85bb256ad8bbb8e7 100644 (file)
@@ -140,6 +140,7 @@ config EXT4DEV_FS
        tristate "Ext4dev/ext4 extended fs support development (EXPERIMENTAL)"
        depends on EXPERIMENTAL
        select JBD2
+       select CRC16
        help
          Ext4dev is a predecessor filesystem of the next generation
          extended fs ext4, based on ext3 filesystem code. It will be
@@ -219,7 +220,7 @@ config JBD
 
 config JBD_DEBUG
        bool "JBD (ext3) debugging support"
-       depends on JBD
+       depends on JBD && DEBUG_FS
        help
          If you are using the ext3 journaled file system (or potentially any
          other file system/device using JBD), this option allows you to
@@ -228,10 +229,10 @@ config JBD_DEBUG
          debugging output will be turned off.
 
          If you select Y here, then you will be able to turn on debugging
-         with "echo N > /proc/sys/fs/jbd-debug", where N is a number between
-         1 and 5, the higher the number, the more debugging output is
-         generated.  To turn debugging off again, do
-         "echo 0 > /proc/sys/fs/jbd-debug".
+         with "echo N > /sys/kernel/debug/jbd/jbd-debug", where N is a
+         number between 1 and 5, the higher the number, the more debugging
+         output is generated.  To turn debugging off again, do
+         "echo 0 > /sys/kernel/debug/jbd/jbd-debug".
 
 config JBD2
        tristate
index d02f43b50a3d83e9fb6e20c8c64bb83df05eb1a3..f12db415c0f6aa7b2776bdbcec1279a35c17da7f 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -710,18 +710,9 @@ static ssize_t aio_run_iocb(struct kiocb *iocb)
 
        /*
         * Now we are all set to call the retry method in async
-        * context. By setting this thread's io_wait context
-        * to point to the wait queue entry inside the currently
-        * running iocb for the duration of the retry, we ensure
-        * that async notification wakeups are queued by the
-        * operation instead of blocking waits, and when notified,
-        * cause the iocb to be kicked for continuation (through
-        * the aio_wake_function callback).
+        * context.
         */
-       BUG_ON(current->io_wait != NULL);
-       current->io_wait = &iocb->ki_wait;
        ret = retry(iocb);
-       current->io_wait = NULL;
 
        if (ret != -EIOCBRETRY && ret != -EIOCBQUEUED) {
                BUG_ON(!list_empty(&iocb->ki_wait.task_list));
@@ -1508,10 +1499,7 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb)
  *     Simply triggers a retry of the operation via kick_iocb.
  *
  *     This callback is specified in the wait queue entry in
- *     a kiocb (current->io_wait points to this wait queue
- *     entry when an aio operation executes; it is used
- *     instead of a synchronous wait when an i/o blocking
- *     condition is encountered during aio).
+ *     a kiocb.
  *
  * Note:
  * This routine is executed with the wait queue lock held.
index ae58bd3f875f9c92c9599bacebbab85ebdf2c800..966b73e25f82e06f69ad0eca22a3f6fe268c4cd0 100644 (file)
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -103,12 +103,11 @@ EXPORT_SYMBOL(inode_setattr);
 int notify_change(struct dentry * dentry, struct iattr * attr)
 {
        struct inode *inode = dentry->d_inode;
-       mode_t mode;
+       mode_t mode = inode->i_mode;
        int error;
        struct timespec now;
        unsigned int ia_valid = attr->ia_valid;
 
-       mode = inode->i_mode;
        now = current_fs_time(inode->i_sb);
 
        attr->ia_ctime = now;
@@ -125,18 +124,25 @@ int notify_change(struct dentry * dentry, struct iattr * attr)
                if (error)
                        return error;
        }
+
+       /*
+        * We now pass ATTR_KILL_S*ID to the lower level setattr function so
+        * that the function has the ability to reinterpret a mode change
+        * that's due to these bits. This adds an implicit restriction that
+        * no function will ever call notify_change with both ATTR_MODE and
+        * ATTR_KILL_S*ID set.
+        */
+       if ((ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID)) &&
+           (ia_valid & ATTR_MODE))
+               BUG();
+
        if (ia_valid & ATTR_KILL_SUID) {
-               attr->ia_valid &= ~ATTR_KILL_SUID;
                if (mode & S_ISUID) {
-                       if (!(ia_valid & ATTR_MODE)) {
-                               ia_valid = attr->ia_valid |= ATTR_MODE;
-                               attr->ia_mode = inode->i_mode;
-                       }
-                       attr->ia_mode &= ~S_ISUID;
+                       ia_valid = attr->ia_valid |= ATTR_MODE;
+                       attr->ia_mode = (inode->i_mode & ~S_ISUID);
                }
        }
        if (ia_valid & ATTR_KILL_SGID) {
-               attr->ia_valid &= ~ ATTR_KILL_SGID;
                if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
                        if (!(ia_valid & ATTR_MODE)) {
                                ia_valid = attr->ia_valid |= ATTR_MODE;
@@ -145,7 +151,7 @@ int notify_change(struct dentry * dentry, struct iattr * attr)
                        attr->ia_mode &= ~S_ISGID;
                }
        }
-       if (!attr->ia_valid)
+       if (!(attr->ia_valid & ~(ATTR_KILL_SUID | ATTR_KILL_SGID)))
                return 0;
 
        if (ia_valid & ATTR_SIZE)
index e7204d71acc94660f4a50a3d2c10eb2a6a816e63..45f5992a0957173bc0c7e744028ef40e5743aa8e 100644 (file)
@@ -80,7 +80,7 @@ static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid,
 
        *uid = current->uid;
        *gid = current->gid;
-       *pgrp = process_group(current);
+       *pgrp = task_pgrp_nr(current);
 
        *minproto = *maxproto = AUTOFS_PROTO_VERSION;
 
index c1489533277ae87d1f1d5358d7248e35ef5d6eb5..5efff3c0d886985351bbe1588da8245992974525 100644 (file)
@@ -214,8 +214,8 @@ static struct dentry *autofs_root_lookup(struct inode *dir, struct dentry *dentr
 
        oz_mode = autofs_oz_mode(sbi);
        DPRINTK(("autofs_lookup: pid = %u, pgrp = %u, catatonic = %d, "
-                               "oz_mode = %d\n", pid_nr(task_pid(current)),
-                               process_group(current), sbi->catatonic,
+                               "oz_mode = %d\n", task_pid_nr(current),
+                               task_pgrp_nr(current), sbi->catatonic,
                                oz_mode));
 
        /*
@@ -536,7 +536,7 @@ static int autofs_root_ioctl(struct inode *inode, struct file *filp,
        struct autofs_sb_info *sbi = autofs_sbi(inode->i_sb);
        void __user *argp = (void __user *)arg;
 
-       DPRINTK(("autofs_ioctl: cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",cmd,arg,sbi,process_group(current)));
+       DPRINTK(("autofs_ioctl: cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",cmd,arg,sbi,task_pgrp_nr(current)));
 
        if (_IOC_TYPE(cmd) != _IOC_TYPE(AUTOFS_IOC_FIRST) ||
             _IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT)
index 19a9cafb5ddf169ae44183171dfde5db3d243581..be46805972f0b9fc589f6d4dfae59e703f9413cb 100644 (file)
@@ -182,7 +182,7 @@ int autofs_wait_release(struct autofs_sb_info *sbi, autofs_wqt_t wait_queue_toke
 {
        struct autofs_wait_queue *wq, **wql;
 
-       for ( wql = &sbi->queues ; (wq = *wql) != 0 ; wql = &wq->next ) {
+       for (wql = &sbi->queues; (wq = *wql) != NULL; wql = &wq->next) {
                if ( wq->wait_queue_token == wait_queue_token )
                        break;
        }
index d85f42fa92060003b7000f3e686a5070e3da908e..2d4ae40718d9ecdc35119a82a10d264ce5c178ea 100644 (file)
@@ -131,7 +131,7 @@ static inline struct autofs_info *autofs4_dentry_ino(struct dentry *dentry)
    filesystem without "magic".) */
 
 static inline int autofs4_oz_mode(struct autofs_sb_info *sbi) {
-       return sbi->catatonic || process_group(current) == sbi->oz_pgrp;
+       return sbi->catatonic || task_pgrp_nr(current) == sbi->oz_pgrp;
 }
 
 /* Does a dentry have some pending activity? */
index cd81f0836671d436f5a55049812b8d854e78233c..7f05d6ccdb130c8171a80af52c7266ebb14bc2f6 100644 (file)
@@ -226,7 +226,7 @@ static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid,
 
        *uid = current->uid;
        *gid = current->gid;
-       *pgrp = process_group(current);
+       *pgrp = task_pgrp_nr(current);
 
        *minproto = AUTOFS_MIN_PROTO_VERSION;
        *maxproto = AUTOFS_MAX_PROTO_VERSION;
@@ -323,7 +323,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
        sbi->pipe = NULL;
        sbi->catatonic = 1;
        sbi->exp_timeout = 0;
-       sbi->oz_pgrp = process_group(current);
+       sbi->oz_pgrp = task_pgrp_nr(current);
        sbi->sb = s;
        sbi->version = 0;
        sbi->sub_version = 0;
index 45ff3d63b758bd09feea0162cc0a0cbeca0473ad..2bbcc8151dc343eae48914aa95748fef401238f7 100644 (file)
@@ -582,7 +582,7 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s
        oz_mode = autofs4_oz_mode(sbi);
 
        DPRINTK("pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d",
-                current->pid, process_group(current), sbi->catatonic, oz_mode);
+                current->pid, task_pgrp_nr(current), sbi->catatonic, oz_mode);
 
        unhashed = autofs4_lookup_unhashed(sbi, dentry->d_parent, &dentry->d_name);
        if (!unhashed) {
@@ -976,7 +976,7 @@ static int autofs4_root_ioctl(struct inode *inode, struct file *filp,
        void __user *p = (void __user *)arg;
 
        DPRINTK("cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u",
-               cmd,arg,sbi,process_group(current));
+               cmd,arg,sbi,task_pgrp_nr(current));
 
        if (_IOC_TYPE(cmd) != _IOC_TYPE(AUTOFS_IOC_FIRST) ||
             _IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT)
index 0d041a9cb348efe59dd71e1d8079e10ae86fa11b..1fe28e4754c2c7b44fc3516d4f633bc1c8d4351c 100644 (file)
@@ -376,7 +376,7 @@ int autofs4_wait_release(struct autofs_sb_info *sbi, autofs_wqt_t wait_queue_tok
        struct autofs_wait_queue *wq, **wql;
 
        mutex_lock(&sbi->wq_mutex);
-       for (wql = &sbi->queues ; (wq = *wql) != 0 ; wql = &wq->next) {
+       for (wql = &sbi->queues; (wq = *wql) != NULL; wql = &wq->next) {
                if (wq->wait_queue_token == wait_queue_token)
                        break;
        }
index 6e2f3b8dde7f2c9dd636101b86b6049580d8143d..ba8de7ca260bea7e0cf456b4a7bfe56434ad502f 100644 (file)
@@ -1383,10 +1383,10 @@ static void fill_prstatus(struct elf_prstatus *prstatus,
        prstatus->pr_info.si_signo = prstatus->pr_cursig = signr;
        prstatus->pr_sigpend = p->pending.signal.sig[0];
        prstatus->pr_sighold = p->blocked.sig[0];
-       prstatus->pr_pid = p->pid;
-       prstatus->pr_ppid = p->parent->pid;
-       prstatus->pr_pgrp = process_group(p);
-       prstatus->pr_sid = process_session(p);
+       prstatus->pr_pid = task_pid_vnr(p);
+       prstatus->pr_ppid = task_pid_vnr(p->parent);
+       prstatus->pr_pgrp = task_pgrp_vnr(p);
+       prstatus->pr_sid = task_session_vnr(p);
        if (thread_group_leader(p)) {
                /*
                 * This is the record for the group leader.  Add in the
@@ -1429,10 +1429,10 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
                        psinfo->pr_psargs[i] = ' ';
        psinfo->pr_psargs[len] = 0;
 
-       psinfo->pr_pid = p->pid;
-       psinfo->pr_ppid = p->parent->pid;
-       psinfo->pr_pgrp = process_group(p);
-       psinfo->pr_sid = process_session(p);
+       psinfo->pr_pid = task_pid_vnr(p);
+       psinfo->pr_ppid = task_pid_vnr(p->parent);
+       psinfo->pr_pgrp = task_pgrp_vnr(p);
+       psinfo->pr_sid = task_session_vnr(p);
 
        i = p->state ? ffz(~p->state) + 1 : 0;
        psinfo->pr_state = i;
index 033861c6b8f13028905826bcd6424bd3121f8eb2..32649f2a16544502c8affe2d147ac89d1e02ae50 100644 (file)
@@ -1342,10 +1342,10 @@ static void fill_prstatus(struct elf_prstatus *prstatus,
        prstatus->pr_info.si_signo = prstatus->pr_cursig = signr;
        prstatus->pr_sigpend = p->pending.signal.sig[0];
        prstatus->pr_sighold = p->blocked.sig[0];
-       prstatus->pr_pid = p->pid;
-       prstatus->pr_ppid = p->parent->pid;
-       prstatus->pr_pgrp = process_group(p);
-       prstatus->pr_sid = process_session(p);
+       prstatus->pr_pid = task_pid_vnr(p);
+       prstatus->pr_ppid = task_pid_vnr(p->parent);
+       prstatus->pr_pgrp = task_pgrp_vnr(p);
+       prstatus->pr_sid = task_session_vnr(p);
        if (thread_group_leader(p)) {
                /*
                 * This is the record for the group leader.  Add in the
@@ -1391,10 +1391,10 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
                        psinfo->pr_psargs[i] = ' ';
        psinfo->pr_psargs[len] = 0;
 
-       psinfo->pr_pid = p->pid;
-       psinfo->pr_ppid = p->parent->pid;
-       psinfo->pr_pgrp = process_group(p);
-       psinfo->pr_sid = process_session(p);
+       psinfo->pr_pid = task_pid_vnr(p);
+       psinfo->pr_ppid = task_pid_vnr(p->parent);
+       psinfo->pr_pgrp = task_pgrp_vnr(p);
+       psinfo->pr_sid = task_session_vnr(p);
 
        i = p->state ? ffz(~p->state) + 1 : 0;
        psinfo->pr_state = i;
index 576dd7de22784e3007c5854d39ad867dc02d0bca..f95ae9789c913d81d0df5d17250bced9c5479855 100644 (file)
@@ -2,7 +2,7 @@
  *  linux/fs/binfmt_em86.c
  *
  *  Based on linux/fs/binfmt_script.c
- *  Copyright (C) 1996  Martin von Löwis
+ *  Copyright (C) 1996  Martin von Löwis
  *  original #!-checking implemented by tytso.
  *
  *  em86 changes Copyright (C) 1997  Jim Paradis
index 42e94b3ab7bebe362c50e6efed92d4298b959162..b53c7e5f41bbcffd8f936642117ecfce5f258a21 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  binfmt_misc.c
  *
- *  Copyright (C) 1997 Richard Günther
+ *  Copyright (C) 1997 Richard Günther
  *
  *  binfmt_misc detects binaries via a magic or filename extension and invokes
  *  a specified wrapper. This should obsolete binfmt_java, binfmt_em86 and
index 4d0e0f6d3273df654ae2156b0c28cc9f58a8ac57..ab33939b12a7efb8d754fcc80b89bfc88651a33b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  linux/fs/binfmt_script.c
  *
- *  Copyright (C) 1996  Martin von Löwis
+ *  Copyright (C) 1996  Martin von Löwis
  *  original #!-checking implemented by tytso.
  */
 
index 76403b1764c54e53b5b2cb2660ae11d7352f0319..7249e014819e1a0432621d1d2576fd259f27632d 100644 (file)
@@ -2563,7 +2563,7 @@ int nobh_write_end(struct file *file, struct address_space *mapping,
                        struct page *page, void *fsdata)
 {
        struct inode *inode = page->mapping->host;
-       struct buffer_head *head = NULL;
+       struct buffer_head *head = fsdata;
        struct buffer_head *bh;
 
        if (!PageMappedToDisk(page)) {
@@ -2584,7 +2584,6 @@ int nobh_write_end(struct file *file, struct address_space *mapping,
        unlock_page(page);
        page_cache_release(page);
 
-       head = fsdata;
        while (head) {
                bh = head;
                head = head->b_this_page;
index bed6215c0794ef8d9264b113aff767dc85ef4025..3d419163c3d3a345f0a3bd06b230f0186038d60b 100644 (file)
@@ -1,3 +1,19 @@
+Version 1.51
+------------
+Fix memory leak in statfs when mounted to very old servers (e.g.
+Windows 9x).  Add new feature "POSIX open" which allows servers
+which support the current POSIX Extensions to provide better semantics
+(e.g. delete for open files opened with posix open).  Take into
+account umask on posix mkdir not just older style mkdir.  Add
+ability to mount to IPC$ share (which allows CIFS named pipes to be
+opened, read and written as if they were files).  When 1st tree
+connect fails (e.g. due to signing negotiation failure) fix
+leak that causes cifsd not to stop and rmmod to fail to cleanup
+cifs_request_buffers pool. Fix problem with POSIX Open/Mkdir on
+bigendian architectures. Fix possible memory corruption when
+EAGAIN returned on kern_recvmsg. Return better error if server
+requires packet signing but client has disabled it.
+
 Version 1.50
 ------------
 Fix NTLMv2 signing. NFS server mounted over cifs works (if cifs mount is
@@ -6,7 +22,10 @@ done with "serverino" mount option).  Add support for POSIX Unlink
 Samba supports newer POSIX CIFS Protocol Extensions). Add "nounix"
 mount option to allow disabling the CIFS Unix Extensions for just
 that mount. Fix hang on spinlock in find_writable_file (race when
-reopening file after session crash).
+reopening file after session crash).  Byte range unlock request to
+windows server could unlock more bytes (on server copy of file)
+than intended if start of unlock request is well before start of
+a previous byte range lock that we issued.
 
 Version 1.49
 ------------
index 6ecd9d6ba3f3734a572ee757faf1773190069d35..ff6ba8d823f03a91b3ffad88202c75708d1c9eba 100644 (file)
@@ -3,4 +3,4 @@
 #
 obj-$(CONFIG_CIFS) += cifs.o
 
-cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o ioctl.o sess.o export.o
+cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o ioctl.o sess.o export.o cifsacl.o
index f50a88d58f782ee18d06a15650ade6eac3661e6c..2a01f3ef96a0503332da509b81e4c788f07113c2 100644 (file)
@@ -385,10 +385,9 @@ asn1_oid_decode(struct asn1_ctx *ctx,
        unsigned long *optr;
 
        size = eoc - ctx->pointer + 1;
-       *oid = kmalloc(size * sizeof (unsigned long), GFP_ATOMIC);
-       if (*oid == NULL) {
+       *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC);
+       if (*oid == NULL)
                return 0;
-       }
 
        optr = *oid;
 
@@ -581,9 +580,8 @@ decode_negTokenInit(unsigned char *security_blob, int length,
                        return 0;
                } else if ((cls != ASN1_UNI) || (con != ASN1_CON)
                           || (tag != ASN1_SEQ)) {
-                       cFYI(1,
-                            ("Exit 6 cls = %d con = %d tag = %d end = %p (%d)",
-                             cls, con, tag, end, *end));
+                       cFYI(1, ("cls = %d con = %d tag = %d end = %p (%d)",
+                               cls, con, tag, end, *end));
                }
 
                if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
index 1bf8cf522ad668a2832f095f1b75aaf40a7fde0a..73c4c419663c1dc1a3558d2df405fcb58bc07e66 100644 (file)
@@ -209,13 +209,16 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
                i++;
                tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
                dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType);
-               length =
-                   sprintf(buf,
-                           "\n%d) %s Uses: %d Type: %s DevInfo: 0x%x "
-                           "Attributes: 0x%x\nPathComponentMax: %d Status: %d",
-                           i, tcon->treeName,
-                           atomic_read(&tcon->useCount),
-                           tcon->nativeFileSystem,
+               length = sprintf(buf, "\n%d) %s Uses: %d ", i,
+                                tcon->treeName, atomic_read(&tcon->useCount));
+               buf += length;
+               if (tcon->nativeFileSystem) {
+                       length = sprintf(buf, "Type: %s ",
+                                        tcon->nativeFileSystem);
+                       buf += length;
+               }
+               length = sprintf(buf, "DevInfo: 0x%x Attributes: 0x%x"
+                                "\nPathComponentMax: %d Status: %d",
                            le32_to_cpu(tcon->fsDevInfo.DeviceCharacteristics),
                            le32_to_cpu(tcon->fsAttrInfo.Attributes),
                            le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength),
@@ -876,11 +879,16 @@ security_flags_write(struct file *file, const char __user *buffer,
        if (count < 3) {
                /* single char or single char followed by null */
                c = flags_string[0];
-               if (c == '0' || c == 'n' || c == 'N')
+               if (c == '0' || c == 'n' || c == 'N') {
                        extended_security = CIFSSEC_DEF; /* default */
-               else if (c == '1' || c == 'y' || c == 'Y')
+                       return count;
+               } else if (c == '1' || c == 'y' || c == 'Y') {
                        extended_security = CIFSSEC_MAX;
-               return count;
+                       return count;
+               } else if (!isdigit(c)) {
+                       cERROR(1, ("invalid flag %c", c));
+                       return -EINVAL;
+               }
        }
        /* else we have a number */
 
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
new file mode 100644 (file)
index 0000000..e8e5635
--- /dev/null
@@ -0,0 +1,333 @@
+/*
+ *   fs/cifs/cifsacl.c
+ *
+ *   Copyright (C) International Business Machines  Corp., 2007
+ *   Author(s): Steve French (sfrench@us.ibm.com)
+ *
+ *   Contains the routines for mapping CIFS/NTFS ACLs
+ *
+ *   This library is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Lesser General Public License as published
+ *   by the Free Software Foundation; either version 2.1 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This library 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 Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public License
+ *   along with this library; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/fs.h>
+#include "cifspdu.h"
+#include "cifsglob.h"
+#include "cifsacl.h"
+#include "cifsproto.h"
+#include "cifs_debug.h"
+
+
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+
+static struct cifs_wksid wksidarr[NUM_WK_SIDS] = {
+       {{1, 0, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} }, "null user"},
+       {{1, 1, {0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0} }, "nobody"},
+       {{1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11), 0, 0, 0, 0} }, "net-users"},
+       {{1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(18), 0, 0, 0, 0} }, "sys"},
+       {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(544), 0, 0, 0} }, "root"},
+       {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(545), 0, 0, 0} }, "users"},
+       {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(546), 0, 0, 0} }, "guest"}
+};
+
+
+/* security id for everyone */
+static const struct cifs_sid sid_everyone =
+               {1, 1, {0, 0, 0, 0, 0, 0}, {} };
+/* group users */
+static const struct cifs_sid sid_user =
+               {1, 2 , {0, 0, 0, 0, 0, 5}, {} };
+
+
+int match_sid(struct cifs_sid *ctsid)
+{
+       int i, j;
+       int num_subauth, num_sat, num_saw;
+       struct cifs_sid *cwsid;
+
+       if (!ctsid)
+               return (-1);
+
+       for (i = 0; i < NUM_WK_SIDS; ++i) {
+               cwsid = &(wksidarr[i].cifssid);
+
+               /* compare the revision */
+               if (ctsid->revision != cwsid->revision)
+                       continue;
+
+               /* compare all of the six auth values */
+               for (j = 0; j < 6; ++j) {
+                       if (ctsid->authority[j] != cwsid->authority[j])
+                               break;
+               }
+               if (j < 6)
+                       continue; /* all of the auth values did not match */
+
+               /* compare all of the subauth values if any */
+               num_sat = ctsid->num_subauth;
+               num_saw = cwsid->num_subauth;
+               num_subauth = num_sat < num_saw ? num_sat : num_saw;
+               if (num_subauth) {
+                       for (j = 0; j < num_subauth; ++j) {
+                               if (ctsid->sub_auth[j] != cwsid->sub_auth[j])
+                                       break;
+                       }
+                       if (j < num_subauth)
+                               continue; /* all sub_auth values do not match */
+               }
+
+               cFYI(1, ("matching sid: %s\n", wksidarr[i].sidname));
+               return (0); /* sids compare/match */
+       }
+
+       cFYI(1, ("No matching sid"));
+       return (-1);
+}
+
+/* if the two SIDs (roughly equivalent to a UUID for a user or group) are
+   the same returns 1, if they do not match returns 0 */
+int compare_sids(struct cifs_sid *ctsid, struct cifs_sid *cwsid)
+{
+       int i;
+       int num_subauth, num_sat, num_saw;
+
+       if ((!ctsid) || (!cwsid))
+               return (0);
+
+       /* compare the revision */
+       if (ctsid->revision != cwsid->revision)
+               return (0);
+
+       /* compare all of the six auth values */
+       for (i = 0; i < 6; ++i) {
+               if (ctsid->authority[i] != cwsid->authority[i])
+                       return (0);
+       }
+
+       /* compare all of the subauth values if any */
+       num_sat = ctsid->num_subauth;
+       num_saw = cwsid->num_subauth;
+       num_subauth = num_sat < num_saw ? num_sat : num_saw;
+       if (num_subauth) {
+               for (i = 0; i < num_subauth; ++i) {
+                       if (ctsid->sub_auth[i] != cwsid->sub_auth[i])
+                               return (0);
+               }
+       }
+
+       return (1); /* sids compare/match */
+}
+
+
+static void parse_ace(struct cifs_ace *pace, char *end_of_acl)
+{
+       int num_subauth;
+
+       /* validate that we do not go past end of acl */
+
+       /* XXX this if statement can be removed
+       if (end_of_acl < (char *)pace + sizeof(struct cifs_ace)) {
+               cERROR(1, ("ACL too small to parse ACE"));
+               return;
+       } */
+
+       num_subauth = pace->num_subauth;
+       if (num_subauth) {
+#ifdef CONFIG_CIFS_DEBUG2
+               int i;
+               cFYI(1, ("ACE revision %d num_subauth %d",
+                       pace->revision, pace->num_subauth));
+               for (i = 0; i < num_subauth; ++i) {
+                       cFYI(1, ("ACE sub_auth[%d]: 0x%x", i,
+                               le32_to_cpu(pace->sub_auth[i])));
+               }
+
+               /* BB add length check to make sure that we do not have huge
+                       num auths and therefore go off the end */
+
+               cFYI(1, ("RID %d", le32_to_cpu(pace->sub_auth[num_subauth-1])));
+#endif
+       }
+
+       return;
+}
+
+static void parse_ntace(struct cifs_ntace *pntace, char *end_of_acl)
+{
+       /* validate that we do not go past end of acl */
+       if (end_of_acl < (char *)pntace + sizeof(struct cifs_ntace)) {
+               cERROR(1, ("ACL too small to parse NT ACE"));
+               return;
+       }
+
+#ifdef CONFIG_CIFS_DEBUG2
+       cFYI(1, ("NTACE type %d flags 0x%x size %d, access Req 0x%x",
+               pntace->type, pntace->flags, pntace->size,
+               pntace->access_req));
+#endif
+       return;
+}
+
+
+
+static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
+                      struct cifs_sid *pownersid, struct cifs_sid *pgrpsid)
+{
+       int i;
+       int num_aces = 0;
+       int acl_size;
+       char *acl_base;
+       struct cifs_ntace **ppntace;
+       struct cifs_ace **ppace;
+
+       /* BB need to add parm so we can store the SID BB */
+
+       /* validate that we do not go past end of acl */
+       if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
+               cERROR(1, ("ACL too small to parse DACL"));
+               return;
+       }
+
+#ifdef CONFIG_CIFS_DEBUG2
+       cFYI(1, ("DACL revision %d size %d num aces %d",
+               le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
+               le32_to_cpu(pdacl->num_aces)));
+#endif
+
+       acl_base = (char *)pdacl;
+       acl_size = sizeof(struct cifs_acl);
+
+       num_aces = le32_to_cpu(pdacl->num_aces);
+       if (num_aces  > 0) {
+               ppntace = kmalloc(num_aces * sizeof(struct cifs_ntace *),
+                               GFP_KERNEL);
+               ppace = kmalloc(num_aces * sizeof(struct cifs_ace *),
+                               GFP_KERNEL);
+
+/*             cifscred->cecount = pdacl->num_aces;
+               cifscred->ntaces = kmalloc(num_aces *
+                       sizeof(struct cifs_ntace *), GFP_KERNEL);
+               cifscred->aces = kmalloc(num_aces *
+                       sizeof(struct cifs_ace *), GFP_KERNEL);*/
+
+               for (i = 0; i < num_aces; ++i) {
+                       ppntace[i] = (struct cifs_ntace *)
+                                       (acl_base + acl_size);
+                       ppace[i] = (struct cifs_ace *) ((char *)ppntace[i] +
+                                       sizeof(struct cifs_ntace));
+
+                       parse_ntace(ppntace[i], end_of_acl);
+                       if (end_of_acl < ((char *)ppace[i] +
+                                       (le16_to_cpu(ppntace[i]->size) -
+                                       sizeof(struct cifs_ntace)))) {
+                               cERROR(1, ("ACL too small to parse ACE"));
+                               break;
+                       } else
+                               parse_ace(ppace[i], end_of_acl);
+
+/*                     memcpy((void *)(&(cifscred->ntaces[i])),
+                               (void *)ppntace[i],
+                               sizeof(struct cifs_ntace));
+                       memcpy((void *)(&(cifscred->aces[i])),
+                               (void *)ppace[i],
+                               sizeof(struct cifs_ace)); */
+
+                       acl_base = (char *)ppntace[i];
+                       acl_size = le16_to_cpu(ppntace[i]->size);
+               }
+
+               kfree(ppace);
+               kfree(ppntace);
+       }
+
+       return;
+}
+
+
+static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
+{
+
+       /* BB need to add parm so we can store the SID BB */
+
+       /* validate that we do not go past end of acl */
+       if (end_of_acl < (char *)psid + sizeof(struct cifs_sid)) {
+               cERROR(1, ("ACL too small to parse SID"));
+               return -EINVAL;
+       }
+
+       if (psid->num_subauth) {
+#ifdef CONFIG_CIFS_DEBUG2
+               int i;
+               cFYI(1, ("SID revision %d num_auth %d First subauth 0x%x",
+                       psid->revision, psid->num_subauth, psid->sub_auth[0]));
+
+               for (i = 0; i < psid->num_subauth; i++) {
+                       cFYI(1, ("SID sub_auth[%d]: 0x%x ", i,
+                               le32_to_cpu(psid->sub_auth[i])));
+               }
+
+               /* BB add length check to make sure that we do not have huge
+                       num auths and therefore go off the end */
+               cFYI(1, ("RID 0x%x",
+                       le32_to_cpu(psid->sub_auth[psid->num_subauth-1])));
+#endif
+       }
+
+       return 0;
+}
+
+
+/* Convert CIFS ACL to POSIX form */
+int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len)
+{
+       int rc;
+       struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
+       struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
+       char *end_of_acl = ((char *)pntsd) + acl_len;
+
+       owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
+                               le32_to_cpu(pntsd->osidoffset));
+       group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
+                               le32_to_cpu(pntsd->gsidoffset));
+       dacl_ptr = (struct cifs_acl *)((char *)pntsd +
+                               le32_to_cpu(pntsd->dacloffset));
+#ifdef CONFIG_CIFS_DEBUG2
+       cFYI(1, ("revision %d type 0x%x ooffset 0x%x goffset 0x%x "
+                "sacloffset 0x%x dacloffset 0x%x",
+                pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
+                le32_to_cpu(pntsd->gsidoffset),
+                le32_to_cpu(pntsd->sacloffset),
+                le32_to_cpu(pntsd->dacloffset)));
+#endif
+       rc = parse_sid(owner_sid_ptr, end_of_acl);
+       if (rc)
+               return rc;
+
+       rc = parse_sid(group_sid_ptr, end_of_acl);
+       if (rc)
+               return rc;
+
+       parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr, group_sid_ptr);
+
+/*     cifscred->uid = owner_sid_ptr->rid;
+       cifscred->gid = group_sid_ptr->rid;
+       memcpy((void *)(&(cifscred->osid)), (void *)owner_sid_ptr,
+                       sizeof (struct cifs_sid));
+       memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr,
+                       sizeof (struct cifs_sid)); */
+
+
+       return (0);
+}
+#endif /* CONFIG_CIFS_EXPERIMENTAL */
index 5eff35d6e564ac95550697f7b884a9612ac667ca..420f87813647b9b9307ce484b3813f59180247a4 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *   fs/cifs/cifsacl.h
  *
- *   Copyright (c) International Business Machines  Corp., 2005
+ *   Copyright (c) International Business Machines  Corp., 2007
  *   Author(s): Steve French (sfrench@us.ibm.com)
  *
  *   This library is free software; you can redistribute it and/or modify
 #ifndef _CIFSACL_H
 #define _CIFSACL_H
 
+
+#define NUM_AUTHS 6 /* number of authority fields */
+#define NUM_SUBAUTHS 5 /* number of sub authority fields */
+#define NUM_WK_SIDS 7 /* number of well known sids */
+#define SIDNAMELENGTH 20 /* long enough for the ones we care about */
+
+#define READ_BIT        0x4
+#define WRITE_BIT       0x2
+#define EXEC_BIT        0x1
+
+#define UBITSHIFT      6
+#define GBITSHIFT      3
+
+struct cifs_ntsd {
+       __le16 revision; /* revision level */
+       __le16 type;
+       __le32 osidoffset;
+       __le32 gsidoffset;
+       __le32 sacloffset;
+       __le32 dacloffset;
+} __attribute__((packed));
+
 struct cifs_sid {
        __u8 revision; /* revision level */
-       __u8 num_subauths;
+       __u8 num_subauth;
+       __u8 authority[6];
+       __le32 sub_auth[5]; /* sub_auth[num_subauth] */ /* BB FIXME endianness BB */
+} __attribute__((packed));
+
+struct cifs_acl {
+       __le16 revision; /* revision level */
+       __le16 size;
+       __le32 num_aces;
+} __attribute__((packed));
+
+struct cifs_ntace { /* first part of ACE which contains perms */
+       __u8 type;
+       __u8 flags;
+       __le16 size;
+       __le32 access_req;
+} __attribute__((packed));
+
+struct cifs_ace { /* last part of ACE which includes user info */
+       __u8 revision; /* revision level */
+       __u8 num_subauth;
        __u8 authority[6];
-       __u32 sub_auth[4];
-       /* next sub_auth if any ... */
+       __le32 sub_auth[5];
 } __attribute__((packed));
 
-/* everyone */
-/* extern const struct cifs_sid sid_everyone;*/
-/* group users */
-/* extern const struct cifs_sid sid_user;*/
+struct cifs_wksid {
+       struct cifs_sid cifssid;
+       char sidname[SIDNAMELENGTH];
+} __attribute__((packed));
+
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+
+extern int match_sid(struct cifs_sid *);
+extern int compare_sids(struct cifs_sid *, struct cifs_sid *);
+
+#endif /*  CONFIG_CIFS_EXPERIMENTAL */
 
 #endif /* _CIFSACL_H */
index 36272293027d41902231b0725aba64ba680e49dc..632070b4275d91ba46baa1d735b578aeca555462 100644 (file)
@@ -345,7 +345,7 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses,
        user = kmalloc(2 + (len * 2), GFP_KERNEL);
        if (user == NULL)
                goto calc_exit_2;
-       len = cifs_strtoUCS(user, ses->userName, len, nls_cp);
+       len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp);
        UniStrupr(user);
        hmac_md5_update((char *)user, 2*len, pctxt);
 
@@ -356,7 +356,8 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses,
                domain = kmalloc(2 + (len * 2), GFP_KERNEL);
                if (domain == NULL)
                        goto calc_exit_1;
-               len = cifs_strtoUCS(domain, ses->domainName, len, nls_cp);
+               len = cifs_strtoUCS((__le16 *)domain, ses->domainName, len,
+                                       nls_cp);
                /* the following line was removed since it didn't work well
                   with lower cased domain name that passed as an option.
                   Maybe converting the domain name earlier makes sense */
index ba8f7868cb23c84a5e713910f7b7d5a72bfc6f8a..a6fbea57c4b1e6d895375ed10e8ef636995d763e 100644 (file)
 static struct quotactl_ops cifs_quotactl_ops;
 #endif /* QUOTA */
 
-#ifdef CONFIG_CIFS_EXPERIMENTAL
-extern struct export_operations cifs_export_ops;
-#endif /* EXPERIMENTAL */
-
 int cifsFYI = 0;
 int cifsERROR = 1;
 int traceSMB = 0;
@@ -240,9 +236,9 @@ static int cifs_permission(struct inode *inode, int mask, struct nameidata *nd)
 
        cifs_sb = CIFS_SB(inode->i_sb);
 
-       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) {
+       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
                return 0;
-       else /* file mode might have been restricted at mount time
+       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 */
@@ -312,15 +308,15 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
                                        seq_printf(s, ",domain=%s",
                                           cifs_sb->tcon->ses->domainName);
                        }
+                       if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) ||
+                          !(cifs_sb->tcon->unix_ext))
+                               seq_printf(s, ",uid=%d", cifs_sb->mnt_uid);
+                       if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) ||
+                          !(cifs_sb->tcon->unix_ext))
+                               seq_printf(s, ",gid=%d", cifs_sb->mnt_gid);
                }
                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
                        seq_printf(s, ",posixpaths");
-               if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) ||
-                  !(cifs_sb->tcon->unix_ext))
-                       seq_printf(s, ",uid=%d", cifs_sb->mnt_uid);
-               if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) ||
-                  !(cifs_sb->tcon->unix_ext))
-                       seq_printf(s, ",gid=%d", cifs_sb->mnt_gid);
                seq_printf(s, ",rsize=%d", cifs_sb->rsize);
                seq_printf(s, ",wsize=%d", cifs_sb->wsize);
        }
@@ -346,7 +342,7 @@ int cifs_xquota_set(struct super_block *sb, int quota_type, qid_t qid,
        if (pTcon) {
                cFYI(1, ("set type: 0x%x id: %d", quota_type, qid));
        } else {
-               return -EIO;
+               rc = -EIO;
        }
 
        FreeXid(xid);
@@ -716,7 +712,7 @@ static int
 cifs_init_inodecache(void)
 {
        cifs_inode_cachep = kmem_cache_create("cifs_inode_cache",
-                                             sizeof (struct cifsInodeInfo),
+                                             sizeof(struct cifsInodeInfo),
                                              0, (SLAB_RECLAIM_ACCOUNT|
                                                SLAB_MEM_SPREAD),
                                              cifs_init_once);
@@ -816,8 +812,8 @@ static int
 cifs_init_mids(void)
 {
        cifs_mid_cachep = kmem_cache_create("cifs_mpx_ids",
-                               sizeof (struct mid_q_entry), 0,
-                               SLAB_HWCACHE_ALIGN, NULL);
+                                           sizeof(struct mid_q_entry), 0,
+                                           SLAB_HWCACHE_ALIGN, NULL);
        if (cifs_mid_cachep == NULL)
                return -ENOMEM;
 
@@ -829,8 +825,8 @@ cifs_init_mids(void)
        }
 
        cifs_oplock_cachep = kmem_cache_create("cifs_oplock_structs",
-                               sizeof (struct oplock_q_entry), 0,
-                               SLAB_HWCACHE_ALIGN, NULL);
+                                       sizeof(struct oplock_q_entry), 0,
+                                       SLAB_HWCACHE_ALIGN, NULL);
        if (cifs_oplock_cachep == NULL) {
                mempool_destroy(cifs_mid_poolp);
                kmem_cache_destroy(cifs_mid_cachep);
@@ -882,7 +878,8 @@ static int cifs_oplock_thread(void *dummyarg)
                                the call */
                                /* mutex_lock(&inode->i_mutex);*/
                                if (S_ISREG(inode->i_mode)) {
-                                       rc = filemap_fdatawrite(inode->i_mapping);
+                                       rc =
+                                          filemap_fdatawrite(inode->i_mapping);
                                        if (CIFS_I(inode)->clientCanCacheRead
                                                                         == 0) {
                                                filemap_fdatawait(inode->i_mapping);
@@ -907,8 +904,7 @@ static int cifs_oplock_thread(void *dummyarg)
                                            0 /* len */ , 0 /* offset */, 0,
                                            0, LOCKING_ANDX_OPLOCK_RELEASE,
                                            0 /* wait flag */);
-                                       cFYI(1, 
-                                             ("Oplock release rc = %d ", rc));
+                                       cFYI(1, ("Oplock release rc = %d", rc));
                                }
                        } else
                                spin_unlock(&GlobalMid_Lock);
index a20de77a3856d91d49ff590e17f6b27d214a7c14..5574ba3ab1f9c3c669b5f3e606bff729bcc2ebd6 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *   fs/cifs/cifsfs.h
  *
- *   Copyright (c) International Business Machines  Corp., 2002, 2005
+ *   Copyright (c) International Business Machines  Corp., 2002, 2007
  *   Author(s): Steve French (sfrench@us.ibm.com)
  *
  *   This library is free software; you can redistribute it and/or modify
@@ -99,7 +99,12 @@ extern int   cifs_setxattr(struct dentry *, const char *, const void *,
                        size_t, int);
 extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
 extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
-extern int cifs_ioctl (struct inode *inode, struct file *filep,
+extern int cifs_ioctl(struct inode *inode, struct file *filep,
                       unsigned int command, unsigned long arg);
-#define CIFS_VERSION   "1.50"
+
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+extern const struct export_operations cifs_export_ops;
+#endif /* EXPERIMENTAL */
+
+#define CIFS_VERSION   "1.51"
 #endif                         /* _CIFSFS_H */
index b98742fc3b5aea0d325a395edd750eff093e115c..87f51f23276f42f23d054679042fb92b1ace313f 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/in.h>
 #include <linux/in6.h>
 #include "cifs_fs_sb.h"
+#include "cifsacl.h"
 /*
  * The sizes of various internal tables and strings
  */
@@ -89,7 +90,8 @@ enum statusEnum {
 };
 
 enum securityEnum {
-       LANMAN = 0,             /* Legacy LANMAN auth */
+       PLAINTXT = 0,           /* Legacy with Plaintext passwords */
+       LANMAN,                 /* Legacy LANMAN auth */
        NTLM,                   /* Legacy NTLM012 auth with NTLM hash */
        NTLMv2,                 /* Legacy NTLM auth with NTLMv2 hash */
        RawNTLMSSP,             /* NTLMSSP without SPNEGO */
@@ -115,6 +117,17 @@ struct mac_key {
        } data;
 };
 
+struct cifs_cred {
+       int uid;
+       int gid;
+       int mode;
+       int cecount;
+       struct cifs_sid osid;
+       struct cifs_sid gsid;
+       struct cifs_ntace *ntaces;
+       struct cifs_ace *aces;
+};
+
 /*
  *****************************************************************
  * Except the CIFS PDUs themselves all the
@@ -279,6 +292,7 @@ struct cifsTconInfo {
        FILE_SYSTEM_DEVICE_INFO fsDevInfo;
        FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if fs name truncated */
        FILE_SYSTEM_UNIX_INFO fsUnixInfo;
+       unsigned ipc:1;         /* set if connection to IPC$ eg for RPC/PIPES */
        unsigned retry:1;
        unsigned nocase:1;
        unsigned unix_ext:1; /* if off disable Linux extensions to CIFS protocol
@@ -329,6 +343,7 @@ struct cifsFileInfo {
        struct list_head llist; /* list of byte range locks we have. */
        unsigned closePend:1;   /* file is marked to close */
        unsigned invalidHandle:1;  /* file closed via session abend */
+       unsigned messageMode:1;    /* for pipes: message vs byte mode */
        atomic_t wrtPending;   /* handle in use - defer close */
        struct semaphore fh_sem; /* prevents reopen race after dead ses*/
        char *search_resume_name; /* BB removeme BB */
@@ -464,6 +479,9 @@ struct dir_notify_req {
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
 #define   CIFSSEC_MAY_LANMAN   0x00010
 #define   CIFSSEC_MAY_PLNTXT   0x00020
+#else
+#define   CIFSSEC_MAY_LANMAN    0
+#define   CIFSSEC_MAY_PLNTXT    0
 #endif /* weak passwords */
 #define   CIFSSEC_MAY_SEAL     0x00040 /* not supported yet */
 
@@ -477,14 +495,23 @@ require use of the stronger protocol */
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
 #define   CIFSSEC_MUST_LANMAN  0x10010
 #define   CIFSSEC_MUST_PLNTXT  0x20020
+#ifdef CONFIG_CIFS_UPCALL
+#define   CIFSSEC_MASK          0x3F03F /* allows weak security but also krb5 */
+#else
 #define   CIFSSEC_MASK          0x37037 /* current flags supported if weak */
+#endif /* UPCALL */
+#else /* do not allow weak pw hash */
+#ifdef CONFIG_CIFS_UPCALL
+#define   CIFSSEC_MASK          0x0F00F /* flags supported if no weak allowed */
 #else
-#define          CIFSSEC_MASK          0x07007 /* flags supported if no weak config */
+#define          CIFSSEC_MASK          0x07007 /* flags supported if no weak allowed */
+#endif /* UPCALL */
 #endif /* WEAK_PW_HASH */
 #define   CIFSSEC_MUST_SEAL    0x40040 /* not supported yet */
 
 #define   CIFSSEC_DEF  CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2
 #define   CIFSSEC_MAX  CIFSSEC_MUST_SIGN | CIFSSEC_MUST_NTLMV2
+#define   CIFSSEC_AUTH_MASK (CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_LANMAN | CIFSSEC_MAY_PLNTXT | CIFSSEC_MAY_KRB5)
 /*
  *****************************************************************
  * All constants go here
index 6a2056e58ceb63af6857ee69af4759227f8ffbf1..c41ff74e9128b91af914930334b241fd3c0d313f 100644 (file)
                                         /* file_execute, file_read_attributes*/
                                         /* write_dac, and delete.           */
 
+#define FILE_READ_RIGHTS (FILE_READ_DATA | FILE_READ_EA | FILE_READ_ATTRIBUTES)
+#define FILE_WRITE_RIGHTS (FILE_WRITE_DATA | FILE_APPEND_DATA \
+                               | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES)
+#define FILE_EXEC_RIGHTS (FILE_EXECUTE)
+
+
 /*
  * Invalid readdir handle
  */
@@ -360,10 +366,10 @@ struct smb_hdr {
        __u8 WordCount;
 } __attribute__((packed));
 /* given a pointer to an smb_hdr retrieve the value of byte count */
-#define BCC(smb_var) ( *(__u16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) ) )
-#define BCC_LE(smb_var) ( *(__le16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) ) )
+#define BCC(smb_var) ( *(__u16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2 * smb_var->WordCount)))
+#define BCC_LE(smb_var) ( *(__le16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2 * smb_var->WordCount)))
 /* given a pointer to an smb_hdr retrieve the pointer to the byte area */
-#define pByteArea(smb_var) ((unsigned char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) + 2 )
+#define pByteArea(smb_var) ((unsigned char *)smb_var + sizeof(struct smb_hdr) + (2 * smb_var->WordCount) + 2)
 
 /*
  * Computer Name Length (since Netbios name was length 16 with last byte 0x20)
@@ -716,6 +722,14 @@ typedef struct smb_com_findclose_req {
 #define REQ_OPENDIRONLY    0x00000008
 #define REQ_EXTENDED_INFO  0x00000010
 
+/* File type */
+#define DISK_TYPE              0x0000
+#define BYTE_PIPE_TYPE         0x0001
+#define MESSAGE_PIPE_TYPE      0x0002
+#define PRINTER_TYPE           0x0003
+#define COMM_DEV_TYPE          0x0004
+#define UNKNOWN_TYPE           0xFFFF
+
 typedef struct smb_com_open_req {      /* also handles create */
        struct smb_hdr hdr;     /* wct = 24 */
        __u8 AndXCommand;
index 04a69dafedba006c281f98ec9d92c1bd99c9a0bc..1a883663b22dfcc51eac71da6fc8930bf5b7d3e6 100644 (file)
@@ -50,7 +50,8 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *,
                        int * /* bytes returned */ , const int long_op);
 extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *,
                        struct kvec *, int /* nvec to send */,
-                       int * /* type of buf returned */ , const int long_op);
+                       int * /* type of buf returned */ , const int long_op,
+                       const int logError /* whether to log status code*/ );
 extern int SendReceiveBlockingLock(const unsigned int /* xid */ ,
                                        struct cifsTconInfo *,
                                struct smb_hdr * /* input */ ,
@@ -65,7 +66,7 @@ extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr);
 extern int decode_negTokenInit(unsigned char *security_blob, int length,
                        enum securityEnum *secType);
 extern int cifs_inet_pton(int, char *source, void *dst);
-extern int map_smb_to_linux_error(struct smb_hdr *smb);
+extern int map_smb_to_linux_error(struct smb_hdr *smb, int logErr);
 extern void header_assemble(struct smb_hdr *, char /* command */ ,
                            const struct cifsTconInfo *, int /* length of
                            fixed section (word count) in two byte units */);
@@ -304,12 +305,13 @@ extern int cifs_calculate_mac_key(struct mac_key *key, const char *rn,
                                 const char *pass);
 extern int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *,
                        const struct nls_table *);
-extern void CalcNTLMv2_response(const struct cifsSesInfo *, char * );
+extern void CalcNTLMv2_response(const struct cifsSesInfo *, char *);
 extern void setup_ntlmv2_rsp(struct cifsSesInfo *, char *,
                             const struct nls_table *);
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
 extern void calc_lanman_hash(struct cifsSesInfo *ses, char *lnm_session_key);
 #endif /* CIFS_WEAK_PW_HASH */
+extern int parse_sec_desc(struct cifs_ntsd *, int);
 extern int CIFSSMBCopy(int xid,
                        struct cifsTconInfo *source_tcon,
                        const char *fromName,
index 8eb102f940d433537ac2219521d692f567301439..f0d9a485d0951f29c3f140ebda33391d7471a53d 100644 (file)
 #include <asm/uaccess.h>
 #include "cifspdu.h"
 #include "cifsglob.h"
+#include "cifsacl.h"
 #include "cifsproto.h"
 #include "cifs_unicode.h"
 #include "cifs_debug.h"
-#include "cifsacl.h"
 
 #ifdef CONFIG_CIFS_POSIX
 static struct {
@@ -94,9 +94,8 @@ static void mark_open_files_invalid(struct cifsTconInfo *pTcon)
        write_lock(&GlobalSMBSeslock);
        list_for_each_safe(tmp, tmp1, &pTcon->openFileList) {
                open_file = list_entry(tmp, struct cifsFileInfo, tlist);
-               if (open_file) {
+               if (open_file)
                        open_file->invalidHandle = TRUE;
-               }
        }
        write_unlock(&GlobalSMBSeslock);
        /* BB Add call to invalidate_inodes(sb) for all superblocks mounted
@@ -439,8 +438,13 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
 
        pSMB->hdr.Mid = GetNextMid(server);
        pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
+
        if ((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5)
                pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
+       else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_KRB5) {
+               cFYI(1, ("Kerberos only mechanism, enable extended security"));
+               pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
+       }
 
        count = 0;
        for (i = 0; i < CIFS_NUM_PROT; i++) {
@@ -513,7 +517,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
                                (int)ts.tv_sec, (int)utc.tv_sec,
                                (int)(utc.tv_sec - ts.tv_sec)));
                        val = (int)(utc.tv_sec - ts.tv_sec);
-                       seconds = val < 0 ? -val : val;
+                       seconds = abs(val);
                        result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
                        remain = seconds % MIN_TZ_ADJ;
                        if (remain >= (MIN_TZ_ADJ / 2))
@@ -574,7 +578,20 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
                server->secType = NTLM;
        else if (secFlags & CIFSSEC_MAY_NTLMV2)
                server->secType = NTLMv2;
-       /* else krb5 ... any others ... */
+       else if (secFlags & CIFSSEC_MAY_KRB5)
+               server->secType = Kerberos;
+       else if (secFlags & CIFSSEC_MAY_LANMAN)
+               server->secType = LANMAN;
+/* #ifdef CONFIG_CIFS_EXPERIMENTAL
+       else if (secFlags & CIFSSEC_MAY_PLNTXT)
+               server->secType = ??
+#endif */
+       else {
+               rc = -EOPNOTSUPP;
+               cERROR(1, ("Invalid security type"));
+               goto neg_err_exit;
+       }
+       /* else ... any others ...? */
 
        /* one byte, so no need to convert this or EncryptionKeyLen from
           little endian */
@@ -604,22 +621,26 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
        if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) &&
                (server->capabilities & CAP_EXTENDED_SECURITY)) {
                count = pSMBr->ByteCount;
-               if (count < 16)
+               if (count < 16) {
                        rc = -EIO;
-               else if (count == 16) {
-                       server->secType = RawNTLMSSP;
-                       if (server->socketUseCount.counter > 1) {
-                               if (memcmp(server->server_GUID,
-                                          pSMBr->u.extended_response.
-                                          GUID, 16) != 0) {
-                                       cFYI(1, ("server UID changed"));
-                                       memcpy(server->server_GUID,
-                                               pSMBr->u.extended_response.GUID,
-                                               16);
-                               }
-                       } else
+                       goto neg_err_exit;
+               }
+
+               if (server->socketUseCount.counter > 1) {
+                       if (memcmp(server->server_GUID,
+                                  pSMBr->u.extended_response.
+                                  GUID, 16) != 0) {
+                               cFYI(1, ("server UID changed"));
                                memcpy(server->server_GUID,
-                                      pSMBr->u.extended_response.GUID, 16);
+                                       pSMBr->u.extended_response.GUID,
+                                       16);
+                       }
+               } else
+                       memcpy(server->server_GUID,
+                              pSMBr->u.extended_response.GUID, 16);
+
+               if (count == 16) {
+                       server->secType = RawNTLMSSP;
                } else {
                        rc = decode_negTokenInit(pSMBr->u.extended_response.
                                                 SecurityBlob,
@@ -642,10 +663,12 @@ signing_check:
                /* MUST_SIGN already includes the MAY_SIGN FLAG
                   so if this is zero it means that signing is disabled */
                cFYI(1, ("Signing disabled"));
-               if (server->secMode & SECMODE_SIGN_REQUIRED)
+               if (server->secMode & SECMODE_SIGN_REQUIRED) {
                        cERROR(1, ("Server requires "
-                                  "/proc/fs/cifs/PacketSigningEnabled "
-                                  "to be on"));
+                                  "packet signing to be enabled in "
+                                  "/proc/fs/cifs/SecurityFlags."));
+                       rc = -EOPNOTSUPP;
+               }
                server->secMode &=
                        ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
        } else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) {
@@ -1052,7 +1075,7 @@ PsxCreat:
                                InformationLevel) - 4;
        offset = param_offset + params;
        pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset);
-       pdata->Level = SMB_QUERY_FILE_UNIX_BASIC;
+       pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
        pdata->Permissions = cpu_to_le64(mode);
        pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
        pdata->OpenFlags =  cpu_to_le32(*pOplock);
@@ -1098,8 +1121,8 @@ PsxCreat:
        if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
                *pOplock |= CIFS_CREATE_ACTION;
        /* check to make sure response data is there */
-       if (psx_rsp->ReturnedLevel != SMB_QUERY_FILE_UNIX_BASIC) {
-               pRetData->Type = -1; /* unknown */
+       if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
+               pRetData->Type = cpu_to_le32(-1); /* unknown */
 #ifdef CONFIG_CIFS_DEBUG2
                cFYI(1, ("unknown type"));
 #endif
@@ -1107,12 +1130,12 @@ PsxCreat:
                if (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP)
                                        + sizeof(FILE_UNIX_BASIC_INFO)) {
                        cERROR(1, ("Open response data too small"));
-                       pRetData->Type = -1;
+                       pRetData->Type = cpu_to_le32(-1);
                        goto psx_create_err;
                }
                memcpy((char *) pRetData,
                        (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
-                       sizeof (FILE_UNIX_BASIC_INFO));
+                       sizeof(FILE_UNIX_BASIC_INFO));
        }
 
 psx_create_err:
@@ -1193,9 +1216,9 @@ OldOpenRetry:
        }
        if (*pOplock & REQ_OPLOCK)
                pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
-       else if (*pOplock & REQ_BATCHOPLOCK) {
+       else if (*pOplock & REQ_BATCHOPLOCK)
                pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
-       }
+
        pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
        /* BB fixme add conversion for access_flags to bits 0 - 2 of mode */
        /* 0 = read
@@ -1310,9 +1333,8 @@ openRetry:
        }
        if (*pOplock & REQ_OPLOCK)
                pSMB->OpenFlags = cpu_to_le32(REQ_OPLOCK);
-       else if (*pOplock & REQ_BATCHOPLOCK) {
+       else if (*pOplock & REQ_BATCHOPLOCK)
                pSMB->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
-       }
        pSMB->DesiredAccess = cpu_to_le32(access_flags);
        pSMB->AllocationSize = 0;
        /* set file as system file if special file such
@@ -1424,9 +1446,8 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
 
        iov[0].iov_base = (char *)pSMB;
        iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
-       rc = SendReceive2(xid, tcon->ses, iov,
-                         1 /* num iovecs */,
-                         &resp_buf_type, 0);
+       rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
+                        &resp_buf_type, 0 /* not long op */, 1 /* log err */ );
        cifs_stats_inc(&tcon->num_reads);
        pSMBr = (READ_RSP *)iov[0].iov_base;
        if (rc) {
@@ -1446,11 +1467,11 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
                        *nbytes = 0;
                } else {
                        pReadData = (char *) (&pSMBr->hdr.Protocol) +
-                           le16_to_cpu(pSMBr->DataOffset);
-/*                      if (rc = copy_to_user(buf, pReadData, data_length)) {
+                                       le16_to_cpu(pSMBr->DataOffset);
+/*                     if (rc = copy_to_user(buf, pReadData, data_length)) {
                                cERROR(1,("Faulting on read rc = %d",rc));
                                rc = -EFAULT;
-                        }*/ /* can not use copy_to_user when using page cache*/
+                       }*/ /* can not use copy_to_user when using page cache*/
                        if (*buf)
                                memcpy(*buf, pReadData, data_length);
                }
@@ -1645,7 +1666,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
 
 
        rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type,
-                         long_op);
+                         long_op, 0 /* do not log STATUS code */ );
        cifs_stats_inc(&tcon->num_writes);
        if (rc) {
                cFYI(1, ("Send error Write2 = %d", rc));
@@ -2538,7 +2559,7 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata,
                cFYI(1, ("data starts after end of smb"));
                return -EINVAL;
        } else if (data_count + *ppdata > end_of_smb) {
-               cFYI(1,("data %p + count %d (%p) ends after end of smb %p start %p",
+               cFYI(1, ("data %p + count %d (%p) ends after end of smb %p start %p",
                        *ppdata, data_count, (data_count + *ppdata),
                        end_of_smb, pSMBr));
                return -EINVAL;
@@ -2615,7 +2636,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
                                        reparse_buf->TargetNameOffset +
                                        reparse_buf->TargetNameLen) >
                                                end_of_smb) {
-                                       cFYI(1,("reparse buf goes beyond SMB"));
+                                       cFYI(1, ("reparse buf beyond SMB"));
                                        rc = -EIO;
                                        goto qreparse_out;
                                }
@@ -3042,25 +3063,12 @@ GetExtAttrOut:
 
 #endif /* CONFIG_POSIX */
 
-
-/* security id for everyone */
-static const struct cifs_sid sid_everyone =
-               {1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}};
-/* group users */
-static const struct cifs_sid sid_user =
-               {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}};
-
-/* Convert CIFS ACL to POSIX form */
-static int parse_sec_desc(struct cifs_sid *psec_desc, int acl_len)
-{
-       return 0;
-}
-
+#ifdef CONFIG_CIFS_EXPERIMENTAL
 /* Get Security Descriptor (by handle) from remote server for a file or dir */
 int
 CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
                /* BB fix up return info */ char *acl_inf, const int buflen,
-                 const int acl_type /* ACCESS/DEFAULT not sure implication */)
+                 const int acl_type)
 {
        int rc = 0;
        int buf_type = 0;
@@ -3085,12 +3093,13 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
        iov[0].iov_base = (char *)pSMB;
        iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
 
-       rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type, 0);
+       rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
+                        0 /* not long op */, 0 /* do not log STATUS codes */ );
        cifs_stats_inc(&tcon->num_acl_get);
        if (rc) {
                cFYI(1, ("Send error in QuerySecDesc = %d", rc));
        } else {                /* decode response */
-               struct cifs_sid *psec_desc;
+               struct cifs_ntsd *psec_desc;
                __le32 * parm;
                int parm_len;
                int data_len;
@@ -3105,8 +3114,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
                        goto qsec_out;
                pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base;
 
-               cERROR(1, ("smb %p parm %p data %p",
-                         pSMBr, parm, psec_desc));  /* BB removeme BB */
+               cFYI(1, ("smb %p parm %p data %p", pSMBr, parm, psec_desc));
 
                if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
                        rc = -EIO;      /* bad smb */
@@ -3115,7 +3123,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
 
 /* BB check that data area is minimum length and as big as acl_len */
 
-               acl_len = le32_to_cpu(*(__le32 *)parm);
+               acl_len = le32_to_cpu(*parm);
                /* BB check if (acl_len > bufsize) */
 
                parse_sec_desc(psec_desc, acl_len);
@@ -3128,6 +3136,7 @@ qsec_out:
 /*     cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
        return rc;
 }
+#endif /* CONFIG_CIFS_EXPERIMENTAL */
 
 /* Legacy Query Path Information call for lookup to old servers such
    as Win9x/WinME */
@@ -3363,6 +3372,9 @@ UnixQPathInfoRetry:
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
                if (rc || (pSMBr->ByteCount < sizeof(FILE_UNIX_BASIC_INFO))) {
+                       cERROR(1, ("Malformed FILE_UNIX_BASIC_INFO response.\n"
+                                  "Unix Extensions can be disabled on mount "
+                                  "by specifying the nosfu mount option."));
                        rc = -EIO;      /* bad smb */
                } else {
                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
@@ -3883,12 +3895,10 @@ getDFSRetry:
        pSMB->hdr.Mid = GetNextMid(ses->server);
        pSMB->hdr.Tid = ses->ipc_tid;
        pSMB->hdr.Uid = ses->Suid;
-       if (ses->capabilities & CAP_STATUS32) {
+       if (ses->capabilities & CAP_STATUS32)
                pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
-       }
-       if (ses->capabilities & CAP_DFS) {
+       if (ses->capabilities & CAP_DFS)
                pSMB->hdr.Flags2 |= SMBFLG2_DFS;
-       }
 
        if (ses->capabilities & CAP_UNICODE) {
                pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
@@ -4060,10 +4070,6 @@ oldQFSInfoRetry:
                (void **) &pSMBr);
        if (rc)
                return rc;
-       rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
-                     (void **) &pSMBr);
-       if (rc)
-               return rc;
 
        params = 2;     /* level */
        pSMB->TotalDataCount = 0;
@@ -4265,7 +4271,7 @@ QFSAttributeRetry:
                             *) (((char *) &pSMBr->hdr.Protocol) +
                                 data_offset);
                        memcpy(&tcon->fsAttrInfo, response_data,
-                              sizeof (FILE_SYSTEM_ATTRIBUTE_INFO));
+                              sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
                }
        }
        cifs_buf_release(pSMB);
@@ -4334,7 +4340,7 @@ QFSDeviceRetry:
                                (((char *) &pSMBr->hdr.Protocol) +
                                 data_offset);
                        memcpy(&tcon->fsDevInfo, response_data,
-                              sizeof (FILE_SYSTEM_DEVICE_INFO));
+                              sizeof(FILE_SYSTEM_DEVICE_INFO));
                }
        }
        cifs_buf_release(pSMB);
@@ -4402,7 +4408,7 @@ QFSUnixRetry:
                             *) (((char *) &pSMBr->hdr.Protocol) +
                                 data_offset);
                        memcpy(&tcon->fsUnixInfo, response_data,
-                              sizeof (FILE_SYSTEM_UNIX_INFO));
+                              sizeof(FILE_SYSTEM_UNIX_INFO));
                }
        }
        cifs_buf_release(pSMB);
@@ -4612,7 +4618,7 @@ SetEOFRetry:
                strncpy(pSMB->FileName, fileName, name_len);
        }
        params = 6 + name_len;
-       data_count = sizeof (struct file_end_of_file_info);
+       data_count = sizeof(struct file_end_of_file_info);
        pSMB->MaxParameterCount = cpu_to_le16(2);
        pSMB->MaxDataCount = cpu_to_le16(4100);
        pSMB->MaxSetupCount = 0;
@@ -4800,7 +4806,7 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon,
 
        data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
 
-       count = sizeof (FILE_BASIC_INFO);
+       count = sizeof(FILE_BASIC_INFO);
        pSMB->MaxParameterCount = cpu_to_le16(2);
        pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */
        pSMB->SetupCount = 1;
@@ -4871,7 +4877,7 @@ SetTimesRetry:
        }
 
        params = 6 + name_len;
-       count = sizeof (FILE_BASIC_INFO);
+       count = sizeof(FILE_BASIC_INFO);
        pSMB->MaxParameterCount = cpu_to_le16(2);
        pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */
        pSMB->MaxSetupCount = 0;
@@ -4900,7 +4906,7 @@ SetTimesRetry:
                pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
        pSMB->Reserved4 = 0;
        pSMB->hdr.smb_buf_length += byte_count;
-       memcpy(data_offset, data, sizeof (FILE_BASIC_INFO));
+       memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
        pSMB->ByteCount = cpu_to_le16(byte_count);
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -5003,7 +5009,7 @@ setPermsRetry:
        }
 
        params = 6 + name_len;
-       count = sizeof (FILE_UNIX_BASIC_INFO);
+       count = sizeof(FILE_UNIX_BASIC_INFO);
        pSMB->MaxParameterCount = cpu_to_le16(2);
        pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */
        pSMB->MaxSetupCount = 0;
index 4af3588c1a9615b39976bac9fadc3487a64025eb..19ee11f7f35ad6188207d25edccb0af3b8cdad11 100644 (file)
@@ -124,7 +124,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
        struct mid_q_entry *mid_entry;
 
        spin_lock(&GlobalMid_Lock);
-       if ( kthread_should_stop() ) {
+       if (kthread_should_stop()) {
                /* the demux thread will exit normally
                next time through the loop */
                spin_unlock(&GlobalMid_Lock);
@@ -151,9 +151,8 @@ cifs_reconnect(struct TCP_Server_Info *server)
        }
        list_for_each(tmp, &GlobalTreeConnectionList) {
                tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
-               if ((tcon) && (tcon->ses) && (tcon->ses->server == server)) {
+               if ((tcon) && (tcon->ses) && (tcon->ses->server == server))
                        tcon->tidStatus = CifsNeedReconnect;
-               }
        }
        read_unlock(&GlobalSMBSeslock);
        /* do not want to be sending data on a socket we are freeing */
@@ -187,7 +186,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
        spin_unlock(&GlobalMid_Lock);
        up(&server->tcpSem);
 
-       while ( (!kthread_should_stop()) && (server->tcpStatus != CifsGood)) {
+       while ((!kthread_should_stop()) && (server->tcpStatus != CifsGood)) {
                try_to_freeze();
                if (server->protocolType == IPV6) {
                        rc = ipv6_connect(&server->addr.sockAddr6,
@@ -204,7 +203,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
                } else {
                        atomic_inc(&tcpSesReconnectCount);
                        spin_lock(&GlobalMid_Lock);
-                       if ( !kthread_should_stop() )
+                       if (!kthread_should_stop())
                                server->tcpStatus = CifsGood;
                        server->sequence_number = 0;
                        spin_unlock(&GlobalMid_Lock);
@@ -352,17 +351,15 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
 
        current->flags |= PF_MEMALLOC;
        server->tsk = current;  /* save process info to wake at shutdown */
-       cFYI(1, ("Demultiplex PID: %d", current->pid));
+       cFYI(1, ("Demultiplex PID: %d", task_pid_nr(current)));
        write_lock(&GlobalSMBSeslock);
        atomic_inc(&tcpSesAllocCount);
        length = tcpSesAllocCount.counter;
        write_unlock(&GlobalSMBSeslock);
        complete(&cifsd_complete);
-       if (length  > 1) {
-               mempool_resize(cifs_req_poolp,
-                       length + cifs_min_rcv,
-                       GFP_KERNEL);
-       }
+       if (length  > 1)
+               mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
+                               GFP_KERNEL);
 
        set_freezable();
        while (!kthread_should_stop()) {
@@ -378,7 +375,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
                        }
                } else if (isLargeBuf) {
                        /* we are reusing a dirty large buf, clear its start */
-                       memset(bigbuf, 0, sizeof (struct smb_hdr));
+                       memset(bigbuf, 0, sizeof(struct smb_hdr));
                }
 
                if (smallbuf == NULL) {
@@ -391,7 +388,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
                        }
                        /* beginning of smb buffer is cleared in our buf_get */
                } else /* if existing small buf clear beginning */
-                       memset(smallbuf, 0, sizeof (struct smb_hdr));
+                       memset(smallbuf, 0, sizeof(struct smb_hdr));
 
                isLargeBuf = FALSE;
                isMultiRsp = FALSE;
@@ -400,11 +397,13 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
                iov.iov_len = 4;
                smb_msg.msg_control = NULL;
                smb_msg.msg_controllen = 0;
+               pdu_length = 4; /* enough to get RFC1001 header */
+incomplete_rcv:
                length =
                    kernel_recvmsg(csocket, &smb_msg,
-                                &iov, 1, 4, 0 /* BB see socket.h flags */);
+                               &iov, 1, pdu_length, 0 /* BB other flags? */);
 
-               if ( kthread_should_stop() ) {
+               if (kthread_should_stop()) {
                        break;
                } else if (server->tcpStatus == CifsNeedReconnect) {
                        cFYI(1, ("Reconnect after server stopped responding"));
@@ -416,7 +415,10 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
                        msleep(1); /* minimum sleep to prevent looping
                                allowing socket to clear and app threads to set
                                tcpStatus CifsNeedReconnect if server hung */
-                       continue;
+                       if (pdu_length < 4)
+                               goto incomplete_rcv;
+                       else
+                               continue;
                } else if (length <= 0) {
                        if (server->tcpStatus == CifsNew) {
                                cFYI(1, ("tcp session abend after SMBnegprot"));
@@ -437,13 +439,11 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
                        wake_up(&server->response_q);
                        continue;
                } else if (length < 4) {
-                       cFYI(1,
-                           ("Frame under four bytes received (%d bytes long)",
+                       cFYI(1, ("less than four bytes received (%d bytes)",
                              length));
-                       cifs_reconnect(server);
-                       csocket = server->ssocket;
-                       wake_up(&server->response_q);
-                       continue;
+                       pdu_length -= length;
+                       msleep(1);
+                       goto incomplete_rcv;
                }
 
                /* The right amount was read from socket - 4 bytes */
@@ -504,7 +504,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
 
                /* else we have an SMB response */
                if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
-                           (pdu_length < sizeof (struct smb_hdr) - 1 - 4)) {
+                           (pdu_length < sizeof(struct smb_hdr) - 1 - 4)) {
                        cERROR(1, ("Invalid size SMB length %d pdu_length %d",
                                        length, pdu_length+4));
                        cifs_reconnect(server);
@@ -528,7 +528,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
                     total_read += length) {
                        length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
                                                pdu_length - total_read, 0);
-                       if ( kthread_should_stop() ||
+                       if (kthread_should_stop() ||
                            (length == -EINTR)) {
                                /* then will exit */
                                reconnect = 2;
@@ -546,6 +546,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
                                              allowing socket to clear and app
                                              threads to set tcpStatus
                                              CifsNeedReconnect if server hung*/
+                               length = 0;
                                continue;
                        } else if (length <= 0) {
                                cERROR(1, ("Received no data, expecting %d",
@@ -631,9 +632,9 @@ multi_t2_fnd:
                        /* Was previous buf put in mpx struct for multi-rsp? */
                        if (!isMultiRsp) {
                                /* smb buffer will be freed by user thread */
-                               if (isLargeBuf) {
+                               if (isLargeBuf)
                                        bigbuf = NULL;
-                               else
+                               else
                                        smallbuf = NULL;
                        }
                        wake_up_process(task_to_wake);
@@ -676,9 +677,8 @@ multi_t2_fnd:
                server->ssocket = NULL;
        }
        /* buffer usuallly freed in free_mid - need to free it here on exit */
-       if (bigbuf != NULL)
-               cifs_buf_release(bigbuf);
-       if (smallbuf != NULL)
+       cifs_buf_release(bigbuf);
+       if (smallbuf) /* no sense logging a debug message if NULL */
                cifs_small_buf_release(smallbuf);
 
        read_lock(&GlobalSMBSeslock);
@@ -702,9 +702,8 @@ multi_t2_fnd:
                list_for_each(tmp, &GlobalSMBSessionList) {
                        ses = list_entry(tmp, struct cifsSesInfo,
                                         cifsSessionList);
-                       if (ses->server == server) {
+                       if (ses->server == server)
                                ses->status = CifsExiting;
-                       }
                }
 
                spin_lock(&GlobalMid_Lock);
@@ -714,9 +713,8 @@ multi_t2_fnd:
                                cFYI(1, ("Clearing Mid 0x%x - waking up ",
                                         mid_entry->mid));
                                task_to_wake = mid_entry->tsk;
-                               if (task_to_wake) {
+                               if (task_to_wake)
                                        wake_up_process(task_to_wake);
-                               }
                        }
                }
                spin_unlock(&GlobalMid_Lock);
@@ -749,18 +747,15 @@ multi_t2_fnd:
        list_for_each(tmp, &GlobalSMBSessionList) {
                ses = list_entry(tmp, struct cifsSesInfo,
                                cifsSessionList);
-               if (ses->server == server) {
+               if (ses->server == server)
                        ses->server = NULL;
-               }
        }
        write_unlock(&GlobalSMBSeslock);
 
        kfree(server);
-       if (length  > 0) {
-               mempool_resize(cifs_req_poolp,
-                       length + cifs_min_rcv,
-                       GFP_KERNEL);
-       }
+       if (length  > 0)
+               mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
+                               GFP_KERNEL);
 
        return 0;
 }
@@ -1477,7 +1472,7 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
        if (psin_server->sin_port) { /* user overrode default port */
                rc = (*csocket)->ops->connect(*csocket,
                                (struct sockaddr *) psin_server,
-                               sizeof (struct sockaddr_in), 0);
+                               sizeof(struct sockaddr_in), 0);
                if (rc >= 0)
                        connected = 1;
        }
@@ -1493,7 +1488,7 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
 
                        rc = (*csocket)->ops->connect(*csocket,
                                        (struct sockaddr *) psin_server,
-                                       sizeof (struct sockaddr_in), 0);
+                                       sizeof(struct sockaddr_in), 0);
                        if (rc >= 0)
                                connected = 1;
                }
@@ -1502,7 +1497,7 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
                psin_server->sin_port = htons(RFC1001_PORT);
                rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
                                              psin_server,
-                                             sizeof (struct sockaddr_in), 0);
+                                             sizeof(struct sockaddr_in), 0);
                if (rc >= 0)
                        connected = 1;
        }
@@ -1610,7 +1605,7 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
        if (psin_server->sin6_port) { /* user overrode default port */
                rc = (*csocket)->ops->connect(*csocket,
                                (struct sockaddr *) psin_server,
-                               sizeof (struct sockaddr_in6), 0);
+                               sizeof(struct sockaddr_in6), 0);
                if (rc >= 0)
                        connected = 1;
        }
@@ -1626,7 +1621,7 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
 
                        rc = (*csocket)->ops->connect(*csocket,
                                        (struct sockaddr *) psin_server,
-                                       sizeof (struct sockaddr_in6), 0);
+                                       sizeof(struct sockaddr_in6), 0);
                        if (rc >= 0)
                                connected = 1;
                }
@@ -1634,7 +1629,7 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
        if (!connected) {
                psin_server->sin6_port = htons(RFC1001_PORT);
                rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
-                                psin_server, sizeof (struct sockaddr_in6), 0);
+                                psin_server, sizeof(struct sockaddr_in6), 0);
                if (rc >= 0)
                        connected = 1;
        }
@@ -1750,7 +1745,16 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
                        cFYI(1, ("very large write cap"));
 #endif /* CIFS_DEBUG2 */
                if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
-                       cFYI(1, ("setting capabilities failed"));
+                       if (vol_info == NULL) {
+                               cFYI(1, ("resetting capabilities failed"));
+                       } else
+                               cERROR(1, ("Negotiating Unix capabilities "
+                                          "with the server failed.  Consider "
+                                          "mounting with the Unix Extensions\n"
+                                          "disabled, if problems are found, "
+                                          "by specifying the nounix mount "
+                                          "option."));
+
                }
        }
 }
@@ -1909,8 +1913,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                        return rc;
                }
 
-               srvTcp = kmalloc(sizeof (struct TCP_Server_Info), GFP_KERNEL);
-               if (srvTcp == NULL) {
+               srvTcp = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
+               if (!srvTcp) {
                        rc = -ENOMEM;
                        sock_release(csocket);
                        kfree(volume_info.UNC);
@@ -1919,9 +1923,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                        FreeXid(xid);
                        return rc;
                } else {
-                       memset(srvTcp, 0, sizeof (struct TCP_Server_Info));
                        memcpy(&srvTcp->addr.sockAddr, &sin_server,
-                               sizeof (struct sockaddr_in));
+                               sizeof(struct sockaddr_in));
                        atomic_set(&srvTcp->inFlight, 0);
                        /* BB Add code for ipv6 case too */
                        srvTcp->ssocket = csocket;
@@ -2173,8 +2176,18 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                                                if (tsk)
                                                        kthread_stop(tsk);
                                        }
-                               } else
+                               } else {
                                        cFYI(1, ("No session or bad tcon"));
+                                       if ((pSesInfo->server) &&
+                                           (pSesInfo->server->tsk)) {
+                                               struct task_struct *tsk;
+                                               force_sig(SIGKILL,
+                                                       pSesInfo->server->tsk);
+                                               tsk = pSesInfo->server->tsk;
+                                               if (tsk)
+                                                       kthread_stop(tsk);
+                                       }
+                               }
                                sesInfoFree(pSesInfo);
                                /* pSesInfo = NULL; */
                        }
@@ -2185,8 +2198,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                tcon->ses = pSesInfo;
 
                /* do not care if following two calls succeed - informational */
-               CIFSSMBQFSDeviceInfo(xid, tcon);
-               CIFSSMBQFSAttributeInfo(xid, tcon);
+               if (!tcon->ipc) {
+                       CIFSSMBQFSDeviceInfo(xid, tcon);
+                       CIFSSMBQFSAttributeInfo(xid, tcon);
+               }
 
                /* tell server which Unix caps we support */
                if (tcon->ses->capabilities & CAP_UNIX)
@@ -2526,8 +2541,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
 sesssetup_nomem:       /* do not return an error on nomem for the info strings,
                           since that could make reconnection harder, and
                           reconnection might be needed to free memory */
-       if (smb_buffer)
-               cifs_buf_release(smb_buffer);
+       cifs_buf_release(smb_buffer);
 
        return rc;
 }
@@ -2547,7 +2561,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
        int remaining_words = 0;
        int bytes_returned = 0;
        int len;
-       int SecurityBlobLength = sizeof (NEGOTIATE_MESSAGE);
+       int SecurityBlobLength = sizeof(NEGOTIATE_MESSAGE);
        PNEGOTIATE_MESSAGE SecurityBlob;
        PCHALLENGE_MESSAGE SecurityBlob2;
        __u32 negotiate_flags, capabilities;
@@ -2865,15 +2879,14 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
                rc = -EIO;
        }
 
-       if (smb_buffer)
-               cifs_buf_release(smb_buffer);
+       cifs_buf_release(smb_buffer);
 
        return rc;
 }
 static int
 CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
-               char *ntlm_session_key, int ntlmv2_flag,
-               const struct nls_table *nls_codepage)
+                       char *ntlm_session_key, int ntlmv2_flag,
+                       const struct nls_table *nls_codepage)
 {
        struct smb_hdr *smb_buffer;
        struct smb_hdr *smb_buffer_response;
@@ -2886,7 +2899,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
        int remaining_words = 0;
        int bytes_returned = 0;
        int len;
-       int SecurityBlobLength = sizeof (AUTHENTICATE_MESSAGE);
+       int SecurityBlobLength = sizeof(AUTHENTICATE_MESSAGE);
        PAUTHENTICATE_MESSAGE SecurityBlob;
        __u32 negotiate_flags, capabilities;
        __u16 count;
@@ -2901,8 +2914,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                return -ENOMEM;
        }
        smb_buffer_response = smb_buffer;
-       pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
-       pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
+       pSMB = (SESSION_SETUP_ANDX *)smb_buffer;
+       pSMBr = (SESSION_SETUP_ANDX *)smb_buffer_response;
 
        /* send SMBsessionSetup here */
        header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
@@ -2921,7 +2934,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
 
        capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
-           CAP_EXTENDED_SECURITY;
+                       CAP_EXTENDED_SECURITY;
        if (ses->capabilities & CAP_UNICODE) {
                smb_buffer->Flags2 |= SMBFLG2_UNICODE;
                capabilities |= CAP_UNICODE;
@@ -2936,15 +2949,14 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
        }
        pSMB->req.Capabilities = cpu_to_le32(capabilities);
 
-       bcc_ptr = (char *) &pSMB->req.SecurityBlob;
-       SecurityBlob = (PAUTHENTICATE_MESSAGE) bcc_ptr;
+       bcc_ptr = (char *)&pSMB->req.SecurityBlob;
+       SecurityBlob = (PAUTHENTICATE_MESSAGE)bcc_ptr;
        strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
        SecurityBlob->MessageType = NtLmAuthenticate;
        bcc_ptr += SecurityBlobLength;
-       negotiate_flags =
-           NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
-           NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
-           0x80000000 | NTLMSSP_NEGOTIATE_128;
+       negotiate_flags = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
+                       NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
+                       0x80000000 | NTLMSSP_NEGOTIATE_128;
        if (sign_CIFS_PDUs)
                negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
        if (ntlmv2_flag)
@@ -2979,36 +2991,32 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                        SecurityBlob->DomainName.Length = 0;
                        SecurityBlob->DomainName.MaximumLength = 0;
                } else {
-                       __u16 len =
-                           cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
+                       __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
                                          nls_codepage);
-                       len *= 2;
+                       ln *= 2;
                        SecurityBlob->DomainName.MaximumLength =
-                           cpu_to_le16(len);
+                           cpu_to_le16(ln);
                        SecurityBlob->DomainName.Buffer =
                            cpu_to_le32(SecurityBlobLength);
-                       bcc_ptr += len;
-                       SecurityBlobLength += len;
-                       SecurityBlob->DomainName.Length =
-                           cpu_to_le16(len);
+                       bcc_ptr += ln;
+                       SecurityBlobLength += ln;
+                       SecurityBlob->DomainName.Length = cpu_to_le16(ln);
                }
                if (user == NULL) {
                        SecurityBlob->UserName.Buffer = 0;
                        SecurityBlob->UserName.Length = 0;
                        SecurityBlob->UserName.MaximumLength = 0;
                } else {
-                       __u16 len =
-                           cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
+                       __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
                                          nls_codepage);
-                       len *= 2;
+                       ln *= 2;
                        SecurityBlob->UserName.MaximumLength =
-                           cpu_to_le16(len);
+                           cpu_to_le16(ln);
                        SecurityBlob->UserName.Buffer =
                            cpu_to_le32(SecurityBlobLength);
-                       bcc_ptr += len;
-                       SecurityBlobLength += len;
-                       SecurityBlob->UserName.Length =
-                           cpu_to_le16(len);
+                       bcc_ptr += ln;
+                       SecurityBlobLength += ln;
+                       SecurityBlob->UserName.Length = cpu_to_le16(ln);
                }
 
                /* SecurityBlob->WorkstationName.Length =
@@ -3052,33 +3060,32 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                        SecurityBlob->DomainName.Length = 0;
                        SecurityBlob->DomainName.MaximumLength = 0;
                } else {
-                       __u16 len;
+                       __u16 ln;
                        negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
                        strncpy(bcc_ptr, domain, 63);
-                       len = strnlen(domain, 64);
+                       ln = strnlen(domain, 64);
                        SecurityBlob->DomainName.MaximumLength =
-                           cpu_to_le16(len);
+                           cpu_to_le16(ln);
                        SecurityBlob->DomainName.Buffer =
                            cpu_to_le32(SecurityBlobLength);
-                       bcc_ptr += len;
-                       SecurityBlobLength += len;
-                       SecurityBlob->DomainName.Length = cpu_to_le16(len);
+                       bcc_ptr += ln;
+                       SecurityBlobLength += ln;
+                       SecurityBlob->DomainName.Length = cpu_to_le16(ln);
                }
                if (user == NULL) {
                        SecurityBlob->UserName.Buffer = 0;
                        SecurityBlob->UserName.Length = 0;
                        SecurityBlob->UserName.MaximumLength = 0;
                } else {
-                       __u16 len;
+                       __u16 ln;
                        strncpy(bcc_ptr, user, 63);
-                       len = strnlen(user, 64);
-                       SecurityBlob->UserName.MaximumLength =
-                           cpu_to_le16(len);
+                       ln = strnlen(user, 64);
+                       SecurityBlob->UserName.MaximumLength = cpu_to_le16(ln);
                        SecurityBlob->UserName.Buffer =
-                           cpu_to_le32(SecurityBlobLength);
-                       bcc_ptr += len;
-                       SecurityBlobLength += len;
-                       SecurityBlob->UserName.Length = cpu_to_le16(len);
+                                               cpu_to_le32(SecurityBlobLength);
+                       bcc_ptr += ln;
+                       SecurityBlobLength += ln;
+                       SecurityBlob->UserName.Length = cpu_to_le16(ln);
                }
                /* BB fill in our workstation name if known BB */
 
@@ -3100,12 +3107,11 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
        rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
                         &bytes_returned, 1);
        if (rc) {
-/*    rc = map_smb_to_linux_error(smb_buffer_response);  *//* done in SendReceive now */
-       } else if ((smb_buffer_response->WordCount == 3)
-                  || (smb_buffer_response->WordCount == 4)) {
+/*   rc = map_smb_to_linux_error(smb_buffer_response) done in SendReceive now */
+       } else if ((smb_buffer_response->WordCount == 3) ||
+                  (smb_buffer_response->WordCount == 4)) {
                __u16 action = le16_to_cpu(pSMBr->resp.Action);
-               __u16 blob_len =
-                   le16_to_cpu(pSMBr->resp.SecurityBlobLength);
+               __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
                if (action & GUEST_LOGIN)
                        cFYI(1, (" Guest login")); /* BB Should we set anything
                                                         in SesInfo struct ? */
@@ -3145,8 +3151,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                        } else {
                                                remaining_words = BCC(smb_buffer_response) / 2;
                                        }
-                                       len =
-                                           UniStrnlen((wchar_t *) bcc_ptr,remaining_words - 1);
+                                       len = UniStrnlen((wchar_t *) bcc_ptr,
+                                                       remaining_words - 1);
 /* We look for obvious messed up bcc or strings in response so we do not go off
   the end since (at least) WIN2K and Windows XP have a major bug in not null
   terminating last Unicode string in response  */
@@ -3230,7 +3236,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                                <= BCC(smb_buffer_response)) {
                                                if (ses->serverOS)
                                                        kfree(ses->serverOS);
-                                               ses->serverOS = kzalloc(len + 1,GFP_KERNEL);
+                                               ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
                                                strncpy(ses->serverOS,bcc_ptr, len);
 
                                                bcc_ptr += len;
@@ -3259,28 +3265,24 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                                bcc_ptr[0] = 0;
                                                bcc_ptr++;
                                        } else
-                                               cFYI(1,
-                                                    ("field of length %d "
+                                               cFYI(1, ("field of length %d "
                                                   "extends beyond end of smb ",
                                                      len));
                                }
                        } else {
-                               cERROR(1,
-                                      (" Security Blob extends beyond end "
+                               cERROR(1, ("Security Blob extends beyond end "
                                        "of SMB"));
                        }
                } else {
                        cERROR(1, ("No session structure passed in."));
                }
        } else {
-               cERROR(1,
-                      (" Invalid Word count %d: ",
+               cERROR(1, ("Invalid Word count %d: ",
                        smb_buffer_response->WordCount));
                rc = -EIO;
        }
 
-       if (smb_buffer)
-               cifs_buf_release(smb_buffer);
+       cifs_buf_release(smb_buffer);
 
        return rc;
 }
@@ -3389,6 +3391,18 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
                bcc_ptr = pByteArea(smb_buffer_response);
                length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
                /* skip service field (NB: this field is always ASCII) */
+               if (length == 3) {
+                       if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
+                           (bcc_ptr[2] == 'C')) {
+                               cFYI(1, ("IPC connection"));
+                               tcon->ipc = 1;
+                       }
+               } else if (length == 2) {
+                       if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
+                               /* the most common case */
+                               cFYI(1, ("disk share connection"));
+                       }
+               }
                bcc_ptr += length + 1;
                strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
                if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
@@ -3399,9 +3413,11 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
                                kfree(tcon->nativeFileSystem);
                                tcon->nativeFileSystem =
                                    kzalloc(length + 2, GFP_KERNEL);
-                               cifs_strfromUCS_le(tcon->nativeFileSystem,
-                                                  (__le16 *) bcc_ptr,
-                                                  length, nls_codepage);
+                               if (tcon->nativeFileSystem)
+                                       cifs_strfromUCS_le(
+                                               tcon->nativeFileSystem,
+                                               (__le16 *) bcc_ptr,
+                                               length, nls_codepage);
                                bcc_ptr += 2 * length;
                                bcc_ptr[0] = 0; /* null terminate the string */
                                bcc_ptr[1] = 0;
@@ -3416,8 +3432,9 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
                                kfree(tcon->nativeFileSystem);
                                tcon->nativeFileSystem =
                                    kzalloc(length + 1, GFP_KERNEL);
-                               strncpy(tcon->nativeFileSystem, bcc_ptr,
-                                       length);
+                               if (tcon->nativeFileSystem)
+                                       strncpy(tcon->nativeFileSystem, bcc_ptr,
+                                               length);
                        }
                        /* else do not bother copying these information fields*/
                }
@@ -3433,8 +3450,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
                ses->ipc_tid = smb_buffer_response->Tid;
        }
 
-       if (smb_buffer)
-               cifs_buf_release(smb_buffer);
+       cifs_buf_release(smb_buffer);
        return rc;
 }
 
index 4830acc86d747740c9e2cd96c3d8465beb1287d9..793404b109252b7f589a1d5f11da8667e76379c2 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   vfs operations that deal with dentries
  *
- *   Copyright (C) International Business Machines  Corp., 2002,2005
+ *   Copyright (C) International Business Machines  Corp., 2002,2007
  *   Author(s): Steve French (sfrench@us.ibm.com)
  *
  *   This library is free software; you can redistribute it and/or modify
@@ -269,7 +269,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
                        CIFSSMBClose(xid, pTcon, fileHandle);
                } else if (newinode) {
                        pCifsFile =
-                          kzalloc(sizeof (struct cifsFileInfo), GFP_KERNEL);
+                          kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
 
                        if (pCifsFile == NULL)
                                goto cifs_create_out;
@@ -397,7 +397,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
                                /* BB Do not bother to decode buf since no
                                   local inode yet to put timestamps in,
                                   but we can reuse it safely */
-                               int bytes_written;
+                               unsigned int bytes_written;
                                struct win_dev *pdev;
                                pdev = (struct win_dev *)buf;
                                if (S_ISCHR(mode)) {
@@ -450,8 +450,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
 
        xid = GetXid();
 
-       cFYI(1,
-            (" parent inode = 0x%p name is: %s and dentry = 0x%p",
+       cFYI(1, (" parent inode = 0x%p name is: %s and dentry = 0x%p",
              parent_dir_inode, direntry->d_name.name, direntry));
 
        /* check whether path exists */
index 893fd0aebff82160ec04ecd6b4de5825c7bfa956..75949d6a5f1b33484635f6019d08a6f66402cefd 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/exportfs.h>
 #include "cifsglob.h"
 #include "cifs_debug.h"
+#include "cifsfs.h"
 
 #ifdef CONFIG_CIFS_EXPERIMENTAL
 static struct dentry *cifs_get_parent(struct dentry *dentry)
@@ -52,7 +53,7 @@ static struct dentry *cifs_get_parent(struct dentry *dentry)
        return ERR_PTR(-EACCES);
 }
 
-struct export_operations cifs_export_ops = {
+const struct export_operations cifs_export_ops = {
        .get_parent = cifs_get_parent,
 /*     Following five export operations are unneeded so far and can default:
        .get_dentry =
index 894b1f7b299d5d5dc679b391bb54ca6e1abc092e..1e7e4c06d9e3f8771f813064fcdc2bcce29596cc 100644 (file)
@@ -467,7 +467,7 @@ reopen_error_exit:
 int cifs_close(struct inode *inode, struct file *file)
 {
        int rc = 0;
-       int xid;
+       int xid, timeout;
        struct cifs_sb_info *cifs_sb;
        struct cifsTconInfo *pTcon;
        struct cifsFileInfo *pSMBFile =
@@ -485,9 +485,9 @@ int cifs_close(struct inode *inode, struct file *file)
                        /* no sense reconnecting to close a file that is
                           already closed */
                        if (pTcon->tidStatus != CifsNeedReconnect) {
-                               int timeout = 2;
+                               timeout = 2;
                                while ((atomic_read(&pSMBFile->wrtPending) != 0)
-                                        && (timeout < 1000) ) {
+                                       && (timeout <= 2048)) {
                                        /* Give write a better chance to get to
                                        server ahead of the close.  We do not
                                        want to add a wait_q here as it would
@@ -522,12 +522,30 @@ int cifs_close(struct inode *inode, struct file *file)
                list_del(&pSMBFile->flist);
                list_del(&pSMBFile->tlist);
                write_unlock(&GlobalSMBSeslock);
+               timeout = 10;
+               /* We waited above to give the SMBWrite a chance to issue
+                  on the wire (so we do not get SMBWrite returning EBADF
+                  if writepages is racing with close.  Note that writepages
+                  does not specify a file handle, so it is possible for a file
+                  to be opened twice, and the application close the "wrong"
+                  file handle - in these cases we delay long enough to allow
+                  the SMBWrite to get on the wire before the SMB Close.
+                  We allow total wait here over 45 seconds, more than
+                  oplock break time, and more than enough to allow any write
+                  to complete on the server, or to time out on the client */
+               while ((atomic_read(&pSMBFile->wrtPending) != 0)
+                               && (timeout <= 50000)) {
+                       cERROR(1, ("writes pending, delay free of handle"));
+                       msleep(timeout);
+                       timeout *= 8;
+               }
                kfree(pSMBFile->search_resume_name);
                kfree(file->private_data);
                file->private_data = NULL;
        } else
                rc = -EBADF;
 
+       read_lock(&GlobalSMBSeslock);
        if (list_empty(&(CIFS_I(inode)->openFileList))) {
                cFYI(1, ("closing last open instance for inode %p", inode));
                /* if the file is not open we do not know if we can cache info
@@ -535,6 +553,7 @@ int cifs_close(struct inode *inode, struct file *file)
                CIFS_I(inode)->clientCanCacheRead = FALSE;
                CIFS_I(inode)->clientCanCacheAll  = FALSE;
        }
+       read_unlock(&GlobalSMBSeslock);
        if ((rc == 0) && CIFS_I(inode)->write_behind_rc)
                rc = CIFS_I(inode)->write_behind_rc;
        FreeXid(xid);
@@ -767,7 +786,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
                        mutex_lock(&fid->lock_mutex);
                        list_for_each_entry_safe(li, tmp, &fid->llist, llist) {
                                if (pfLock->fl_start <= li->offset &&
-                                               length >= li->length) {
+                                               (pfLock->fl_start + length) >=
+                                               (li->offset + li->length)) {
                                        stored_rc = CIFSSMBLock(xid, pTcon,
                                                        netfid,
                                                        li->length, li->offset,
@@ -1022,6 +1042,7 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)
        }
 
        read_lock(&GlobalSMBSeslock);
+refind_writable:
        list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
                if (open_file->closePend)
                        continue;
@@ -1029,24 +1050,49 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)
                    ((open_file->pfile->f_flags & O_RDWR) ||
                     (open_file->pfile->f_flags & O_WRONLY))) {
                        atomic_inc(&open_file->wrtPending);
+
+                       if (!open_file->invalidHandle) {
+                               /* found a good writable file */
+                               read_unlock(&GlobalSMBSeslock);
+                               return open_file;
+                       }
+       
                        read_unlock(&GlobalSMBSeslock);
-                       if ((open_file->invalidHandle) &&
-                          (!open_file->closePend) /* BB fixme -since the second clause can not be true remove it BB */) {
-                               rc = cifs_reopen_file(open_file->pfile, FALSE);
-                               /* if it fails, try another handle - might be */
-                               /* dangerous to hold up writepages with retry */
-                               if (rc) {
-                                       cFYI(1,
-                                             ("failed on reopen file in wp"));
+                       /* Had to unlock since following call can block */
+                       rc = cifs_reopen_file(open_file->pfile, FALSE);
+                       if (!rc) { 
+                               if (!open_file->closePend)
+                                       return open_file;
+                               else { /* start over in case this was deleted */
+                                      /* since the list could be modified */
                                        read_lock(&GlobalSMBSeslock);
-                                       /* can not use this handle, no write
-                                       pending on this one after all */
-                                       atomic_dec
-                                            (&open_file->wrtPending);
-                                       continue;
+                                       atomic_dec(&open_file->wrtPending);
+                                       goto refind_writable;
                                }
                        }
-                       return open_file;
+
+                       /* if it fails, try another handle if possible -
+                       (we can not do this if closePending since
+                       loop could be modified - in which case we
+                       have to start at the beginning of the list
+                       again. Note that it would be bad
+                       to hold up writepages here (rather than
+                       in caller) with continuous retries */
+                       cFYI(1, ("wp failed on reopen file"));
+                       read_lock(&GlobalSMBSeslock);
+                       /* can not use this handle, no write
+                          pending on this one after all */
+                       atomic_dec(&open_file->wrtPending);
+                       
+                       if (open_file->closePend) /* list could have changed */
+                               goto refind_writable;
+                       /* else we simply continue to the next entry. Thus
+                          we do not loop on reopen errors.  If we
+                          can not reopen the file, for example if we
+                          reconnected to a server with another client
+                          racing to delete or lock the file we would not
+                          make progress if we restarted before the beginning
+                          of the loop here. */
                }
        }
        read_unlock(&GlobalSMBSeslock);
@@ -1709,7 +1755,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
        struct page *page;
        struct cifs_sb_info *cifs_sb;
        struct cifsTconInfo *pTcon;
-       int bytes_read = 0;
+       unsigned int bytes_read = 0;
        unsigned int read_size, i;
        char *smb_read_data = NULL;
        struct smb_com_read_rsp *pSMBr;
@@ -1803,7 +1849,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
 
                        i +=  bytes_read >> PAGE_CACHE_SHIFT;
                        cifs_stats_bytes_read(pTcon, bytes_read);
-                       if ((int)(bytes_read & PAGE_CACHE_MASK) != bytes_read) {
+                       if ((bytes_read & PAGE_CACHE_MASK) != bytes_read) {
                                i++; /* account for partial page */
 
                                /* server copy of file can have smaller size
index dd4167762a8edaf847913027a9265e3c293144ac..5e8b388be3b672a7130e9e26f8bb954ed8321534 100644 (file)
@@ -115,7 +115,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
                inode->i_mode = le64_to_cpu(findData.Permissions);
                /* since we set the inode type below we need to mask off
                   to avoid strange results if bits set above */
-                       inode->i_mode &= ~S_IFMT;
+               inode->i_mode &= ~S_IFMT;
                if (type == UNIX_FILE) {
                        inode->i_mode |= S_IFREG;
                } else if (type == UNIX_SYMLINK) {
@@ -575,19 +575,33 @@ int cifs_get_inode_info(struct inode **pinode,
        return rc;
 }
 
+static const struct inode_operations cifs_ipc_inode_ops = {
+       .lookup = cifs_lookup,
+};
+
 /* gets root inode */
 void cifs_read_inode(struct inode *inode)
 {
-       int xid;
+       int xid, rc;
        struct cifs_sb_info *cifs_sb;
 
        cifs_sb = CIFS_SB(inode->i_sb);
        xid = GetXid();
 
        if (cifs_sb->tcon->unix_ext)
-               cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid);
+               rc = cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid);
        else
-               cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid);
+               rc = cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid);
+       if (rc && cifs_sb->tcon->ipc) {
+               cFYI(1, ("ipc connection - fake read inode"));
+               inode->i_mode |= S_IFDIR;
+               inode->i_nlink = 2;
+               inode->i_op = &cifs_ipc_inode_ops;
+               inode->i_fop = &simple_dir_operations;
+               inode->i_uid = cifs_sb->mnt_uid;
+               inode->i_gid = cifs_sb->mnt_gid;
+       }
+
        /* can not call macro FreeXid here since in a void func */
        _FreeXid(xid);
 }
@@ -919,18 +933,25 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
                        goto mkdir_out;
                }
 
+               mode &= ~current->fs->umask;
                rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT,
                                mode, NULL /* netfid */, pInfo, &oplock,
                                full_path, cifs_sb->local_nls,
                                cifs_sb->mnt_cifs_flags &
                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
-               if (rc) {
+               if (rc == -EOPNOTSUPP) {
+                       kfree(pInfo);
+                       goto mkdir_retry_old;
+               } else if (rc) {
                        cFYI(1, ("posix mkdir returned 0x%x", rc));
                        d_drop(direntry);
                } else {
                        int obj_type;
-                       if (pInfo->Type == -1) /* no return info - go query */
+                       if (pInfo->Type == cpu_to_le32(-1)) {
+                               /* no return info, go query for it */
+                               kfree(pInfo);
                                goto mkdir_get_info;
+                       }
 /*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need
        to set uid/gid */
                        inc_nlink(inode);
@@ -940,8 +961,10 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
                                direntry->d_op = &cifs_dentry_ops;
 
                        newinode = new_inode(inode->i_sb);
-                       if (newinode == NULL)
+                       if (newinode == NULL) {
+                               kfree(pInfo);
                                goto mkdir_get_info;
+                       }
                        /* Is an i_ino of zero legal? */
                        /* Are there sanity checks we can use to ensure that
                           the server is really filling in that field? */
@@ -972,7 +995,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
                kfree(pInfo);
                goto mkdir_out;
        }
-
+mkdir_retry_old:
        /* BB add setting the equivalent of mode via CreateX w/ACLs */
        rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls,
                          cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -1377,8 +1400,17 @@ static int cifs_vmtruncate(struct inode *inode, loff_t offset)
        }
        i_size_write(inode, offset);
        spin_unlock(&inode->i_lock);
+       /*
+        * unmap_mapping_range is called twice, first simply for efficiency
+        * so that truncate_inode_pages does fewer single-page unmaps. However
+        * after this first call, and before truncate_inode_pages finishes,
+        * it is possible for private pages to be COWed, which remain after
+        * truncate_inode_pages finishes, hence the second unmap_mapping_range
+        * call must be made for correctness.
+        */
        unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
        truncate_inode_pages(mapping, offset);
+       unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
        goto out_truncate;
 
 do_expand:
@@ -1469,7 +1501,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
                        atomic_dec(&open_file->wrtPending);
                        cFYI(1, ("SetFSize for attrs rc = %d", rc));
                        if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
-                               int bytes_written;
+                               unsigned int bytes_written;
                                rc = CIFSSMBWrite(xid, pTcon,
                                                  nfid, 0, attrs->ia_size,
                                                  &bytes_written, NULL, NULL,
@@ -1502,7 +1534,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
                                        cifs_sb->mnt_cifs_flags &
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
                                if (rc == 0) {
-                                       int bytes_written;
+                                       unsigned int bytes_written;
                                        rc = CIFSSMBWrite(xid, pTcon,
                                                        netfid, 0,
                                                        attrs->ia_size,
@@ -1538,6 +1570,11 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
        }
 
        time_buf.Attributes = 0;
+
+       /* skip mode change if it's just for clearing setuid/setgid */
+       if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
+               attrs->ia_valid &= ~ATTR_MODE;
+
        if (attrs->ia_valid & ATTR_MODE) {
                cFYI(1, ("Mode changed to 0x%x", attrs->ia_mode));
                mode = attrs->ia_mode;
index 6a85ef7b879752ec04e093784e3eef61b676dd29..11f265726db780e968e8084359696bc8a4c6446b 100644 (file)
@@ -237,7 +237,7 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
        char *tmp_path = NULL;
        char *tmpbuffer;
        unsigned char *referrals = NULL;
-       int num_referrals = 0;
+       unsigned int num_referrals = 0;
        int len;
        __u16 fid;
 
index 0bcec0844bee8830099f9ae264e8cd65860bf012..51ec681fe74a2e32c19d90e2f45de591bb3ab048 100644 (file)
@@ -169,7 +169,6 @@ cifs_buf_get(void)
 void
 cifs_buf_release(void *buf_to_free)
 {
-
        if (buf_to_free == NULL) {
                /* cFYI(1, ("Null buffer passed to cifs_buf_release"));*/
                return;
index 2bfed3f45d0f97c4d9765bd6842c07e1e39f515f..f06359cb22ee96645e7dfd7b0aa62cc0de216b2b 100644 (file)
@@ -114,10 +114,16 @@ static const struct smb_to_posix_error mapping_table_ERRSRV[] = {
        {ERRusempx, -EIO},
        {ERRusestd, -EIO},
        {ERR_NOTIFY_ENUM_DIR, -ENOBUFS},
-       {ERRaccountexpired, -EACCES},
+       {ERRnoSuchUser, -EACCES},
+/*     {ERRaccountexpired, -EACCES},
        {ERRbadclient, -EACCES},
        {ERRbadLogonTime, -EACCES},
-       {ERRpasswordExpired, -EACCES},
+       {ERRpasswordExpired, -EACCES},*/
+       {ERRaccountexpired, -EKEYEXPIRED},
+       {ERRbadclient, -EACCES},
+       {ERRbadLogonTime, -EACCES},
+       {ERRpasswordExpired, -EKEYEXPIRED},
+
        {ERRnosupport, -EINVAL},
        {0, 0}
 };
@@ -270,7 +276,7 @@ static const struct {
         from NT_STATUS_NO_SUCH_USER to NT_STATUS_LOGON_FAILURE
         during the session setup } */
        {
-       ERRDOS, ERRnoaccess, NT_STATUS_NO_SUCH_USER}, {
+       ERRDOS, ERRnoaccess, NT_STATUS_NO_SUCH_USER}, { /* could map to 2238 */
        ERRHRD, ERRgeneral, NT_STATUS_GROUP_EXISTS}, {
        ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_GROUP}, {
        ERRHRD, ERRgeneral, NT_STATUS_MEMBER_IN_GROUP}, {
@@ -285,10 +291,10 @@ static const struct {
        ERRHRD, ERRgeneral, NT_STATUS_PASSWORD_RESTRICTION}, {
        ERRDOS, ERRnoaccess, NT_STATUS_LOGON_FAILURE}, {
        ERRHRD, ERRgeneral, NT_STATUS_ACCOUNT_RESTRICTION}, {
-       ERRSRV, 2241, NT_STATUS_INVALID_LOGON_HOURS}, {
-       ERRSRV, 2240, NT_STATUS_INVALID_WORKSTATION}, {
+       ERRSRV, ERRbadLogonTime, NT_STATUS_INVALID_LOGON_HOURS}, {
+       ERRSRV, ERRbadclient, NT_STATUS_INVALID_WORKSTATION}, {
        ERRSRV, ERRpasswordExpired, NT_STATUS_PASSWORD_EXPIRED}, {
-       ERRSRV, 2239, NT_STATUS_ACCOUNT_DISABLED}, {
+       ERRSRV, ERRaccountexpired, NT_STATUS_ACCOUNT_DISABLED}, {
        ERRHRD, ERRgeneral, NT_STATUS_NONE_MAPPED}, {
        ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_LUIDS_REQUESTED}, {
        ERRHRD, ERRgeneral, NT_STATUS_LUIDS_EXHAUSTED}, {
@@ -585,7 +591,7 @@ static const struct {
        ERRDOS, ERRnoaccess, NT_STATUS_TRUST_FAILURE}, {
        ERRHRD, ERRgeneral, NT_STATUS_MUTANT_LIMIT_EXCEEDED}, {
        ERRDOS, ERRnetlogonNotStarted, NT_STATUS_NETLOGON_NOT_STARTED}, {
-       ERRSRV, 2239, NT_STATUS_ACCOUNT_EXPIRED}, {
+       ERRSRV, ERRaccountexpired, NT_STATUS_ACCOUNT_EXPIRED}, {
        ERRHRD, ERRgeneral, NT_STATUS_POSSIBLE_DEADLOCK}, {
        ERRHRD, ERRgeneral, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT}, {
        ERRHRD, ERRgeneral, NT_STATUS_REMOTE_SESSION_LIMIT}, {
@@ -754,7 +760,7 @@ ntstatus_to_dos(__u32 ntstatus, __u8 * eclass, __u16 * ecode)
 }
 
 int
-map_smb_to_linux_error(struct smb_hdr *smb)
+map_smb_to_linux_error(struct smb_hdr *smb, int logErr)
 {
        unsigned int i;
        int rc = -EIO;  /* if transport error smb error may not be set */
@@ -771,7 +777,9 @@ map_smb_to_linux_error(struct smb_hdr *smb)
                /* translate the newer STATUS codes to old style SMB errors
                 * and then to POSIX errors */
                __u32 err = le32_to_cpu(smb->Status.CifsError);
-               if (cifsFYI & CIFS_RC)
+               if (logErr && (err != (NT_STATUS_MORE_PROCESSING_REQUIRED)))
+                       cifs_print_status(err);
+               else if (cifsFYI & CIFS_RC)
                        cifs_print_status(err);
                ntstatus_to_dos(err, &smberrclass, &smberrcode);
        } else {
@@ -813,7 +821,7 @@ map_smb_to_linux_error(struct smb_hdr *smb)
        }
        /* else ERRHRD class errors or junk  - return EIO */
 
-       cFYI(1, (" !!Mapping smb error code %d to POSIX err %d !!",
+       cFYI(1, ("Mapping smb error code %d to POSIX err %d",
                 smberrcode, rc));
 
        /* generic corrective action e.g. reconnect SMB session on
@@ -899,8 +907,11 @@ struct timespec cnvrtDosUnixTm(__u16 date, __u16 time)
                cERROR(1, ("illegal hours %d", st->Hours));
        days = sd->Day;
        month = sd->Month;
-       if ((days > 31) || (month > 12))
+       if ((days > 31) || (month > 12)) {
                cERROR(1, ("illegal date, month %d day: %d", month, days));
+               if (month > 12)
+                       month = 12;
+       }
        month -= 1;
        days += total_days_of_prev_months[month];
        days += 3652; /* account for difference in days between 1980 and 1970 */
index 916df9431336734b8cab6495659ef4d345133498..3746580e97016f390a491684ecfae3a14cbd5796 100644 (file)
@@ -121,7 +121,7 @@ static void AdjustForTZ(struct cifsTconInfo *tcon, struct inode *inode)
 
 
 static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
-                         char *buf, int *pobject_type, int isNewInode)
+                         char *buf, unsigned int *pobject_type, int isNewInode)
 {
        loff_t local_size;
        struct timespec local_mtime;
@@ -294,7 +294,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
 }
 
 static void unix_fill_in_inode(struct inode *tmp_inode,
-       FILE_UNIX_INFO *pfindData, int *pobject_type, int isNewInode)
+       FILE_UNIX_INFO *pfindData, unsigned int *pobject_type, int isNewInode)
 {
        loff_t local_size;
        struct timespec local_mtime;
@@ -826,7 +826,7 @@ static int cifs_filldir(char *pfindEntry, struct file *file,
        int rc = 0;
        struct qstr qstring;
        struct cifsFileInfo *pCifsF;
-       unsigned obj_type;
+       unsigned int obj_type;
        ino_t  inum;
        struct cifs_sb_info *cifs_sb;
        struct inode *tmp_inode;
@@ -1067,7 +1067,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
                for (i = 0; (i < num_to_fill) && (rc == 0); i++) {
                        if (current_entry == NULL) {
                                /* evaluate whether this case is an error */
-                               cERROR(1,("past end of SMB num to fill %d i %d",
+                               cERROR(1, ("past SMB end,  num to fill %d i %d",
                                          num_to_fill, i));
                                break;
                        }
index 892be9b4d1f362351de1c0075b2f9b3086aff514..899dc6078d9ab7848b3ffda2547161c212c2e9e5 100644 (file)
@@ -67,14 +67,59 @@ static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
                pSMB->req.hdr.Flags2 |= SMBFLG2_DFS;
                capabilities |= CAP_DFS;
        }
-       if (ses->capabilities & CAP_UNIX) {
+       if (ses->capabilities & CAP_UNIX)
                capabilities |= CAP_UNIX;
-       }
 
        /* BB check whether to init vcnum BB */
        return capabilities;
 }
 
+static void
+unicode_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp)
+{
+       char *bcc_ptr = *pbcc_area;
+       int bytes_ret = 0;
+
+       /* Copy OS version */
+       bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32,
+                                 nls_cp);
+       bcc_ptr += 2 * bytes_ret;
+       bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, init_utsname()->release,
+                                 32, nls_cp);
+       bcc_ptr += 2 * bytes_ret;
+       bcc_ptr += 2; /* trailing null */
+
+       bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
+                                 32, nls_cp);
+       bcc_ptr += 2 * bytes_ret;
+       bcc_ptr += 2; /* trailing null */
+
+       *pbcc_area = bcc_ptr;
+}
+
+static void unicode_domain_string(char **pbcc_area, struct cifsSesInfo *ses,
+                                  const struct nls_table *nls_cp)
+{
+       char *bcc_ptr = *pbcc_area;
+       int bytes_ret = 0;
+
+       /* copy domain */
+       if (ses->domainName == NULL) {
+               /* Sending null domain better than using a bogus domain name (as
+               we did briefly in 2.6.18) since server will use its default */
+               *bcc_ptr = 0;
+               *(bcc_ptr+1) = 0;
+               bytes_ret = 0;
+       } else
+               bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName,
+                                         256, nls_cp);
+       bcc_ptr += 2 * bytes_ret;
+       bcc_ptr += 2;  /* account for null terminator */
+
+       *pbcc_area = bcc_ptr;
+}
+
+
 static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
                                   const struct nls_table *nls_cp)
 {
@@ -100,32 +145,9 @@ static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
        }
        bcc_ptr += 2 * bytes_ret;
        bcc_ptr += 2; /* account for null termination */
-       /* copy domain */
-       if (ses->domainName == NULL) {
-               /* Sending null domain better than using a bogus domain name (as
-               we did briefly in 2.6.18) since server will use its default */
-               *bcc_ptr = 0;
-               *(bcc_ptr+1) = 0;
-               bytes_ret = 0;
-       } else
-               bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName,
-                                         256, nls_cp);
-       bcc_ptr += 2 * bytes_ret;
-       bcc_ptr += 2;  /* account for null terminator */
-
-       /* Copy OS version */
-       bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32,
-                                 nls_cp);
-       bcc_ptr += 2 * bytes_ret;
-       bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, init_utsname()->release,
-                                 32, nls_cp);
-       bcc_ptr += 2 * bytes_ret;
-       bcc_ptr += 2; /* trailing null */
 
-       bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
-                                 32, nls_cp);
-       bcc_ptr += 2 * bytes_ret;
-       bcc_ptr += 2; /* trailing null */
+       unicode_domain_string(&bcc_ptr, ses, nls_cp);
+       unicode_oslm_strings(&bcc_ptr, nls_cp);
 
        *pbcc_area = bcc_ptr;
 }
@@ -203,14 +225,11 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft,
        if (len >= words_left)
                return rc;
 
-       if (ses->serverOS)
-               kfree(ses->serverOS);
+       kfree(ses->serverOS);
        /* UTF-8 string will not grow more than four times as big as UCS-16 */
        ses->serverOS = kzalloc(4 * len, GFP_KERNEL);
-       if (ses->serverOS != NULL) {
-               cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len,
-                                  nls_cp);
-       }
+       if (ses->serverOS != NULL)
+               cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, nls_cp);
        data += 2 * (len + 1);
        words_left -= len + 1;
 
@@ -220,8 +239,7 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft,
        if (len >= words_left)
                return rc;
 
-       if (ses->serverNOS)
-               kfree(ses->serverNOS);
+       kfree(ses->serverNOS);
        ses->serverNOS = kzalloc(4 * len, GFP_KERNEL); /* BB this is wrong length FIXME BB */
        if (ses->serverNOS != NULL) {
                cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len,
@@ -240,8 +258,7 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft,
        if (len > words_left)
                return rc;
 
-       if (ses->serverDomain)
-               kfree(ses->serverDomain);
+       kfree(ses->serverDomain);
        ses->serverDomain = kzalloc(2 * (len + 1), GFP_KERNEL); /* BB FIXME wrong length */
        if (ses->serverDomain != NULL) {
                cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len,
@@ -271,8 +288,7 @@ static int decode_ascii_ssetup(char **pbcc_area, int bleft,
        if (len >= bleft)
                return rc;
 
-       if (ses->serverOS)
-               kfree(ses->serverOS);
+       kfree(ses->serverOS);
 
        ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
        if (ses->serverOS)
@@ -289,8 +305,7 @@ static int decode_ascii_ssetup(char **pbcc_area, int bleft,
        if (len >= bleft)
                return rc;
 
-       if (ses->serverNOS)
-               kfree(ses->serverNOS);
+       kfree(ses->serverNOS);
 
        ses->serverNOS = kzalloc(len + 1, GFP_KERNEL);
        if (ses->serverNOS)
@@ -479,7 +494,8 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
                if (ses->capabilities & CAP_UNICODE) {
                        if (iov[0].iov_len % 2) {
                                *bcc_ptr = 0;
-                       }       bcc_ptr++;
+                               bcc_ptr++;
+                       }
                        unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
                } else
                        ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
@@ -497,7 +513,8 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
 
        iov[1].iov_base = str_area;
        iov[1].iov_len = count;
-       rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type, 0);
+       rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type,
+                         0 /* not long op */, 1 /* log NT STATUS if any */ );
        /* SMB request buf freed in SendReceive2 */
 
        cFYI(1, ("ssetup rc from sendrecv2 is %d", rc));
index 2ef0be28882033e560925957a19307d99c52685c..7f50e8577c1c144c8e28e443b54ac6996db87fd6 100644 (file)
 #define ERRusestd              251     /* temporarily unable to use either raw
                                           or mpx */
 #define ERR_NOTIFY_ENUM_DIR    1024
+#define ERRnoSuchUser          2238    /* user account does not exist */
 #define ERRaccountexpired      2239
-#define ERRbadclient           2240
-#define ERRbadLogonTime                2241
+#define ERRbadclient           2240    /* can not logon from this client */
+#define ERRbadLogonTime                2241    /* logon hours do not allow this */
 #define ERRpasswordExpired     2242
 #define ERRnetlogonNotStarted  2455
 #define ERRnosupport           0xFFFF
index 746bc9405db15ef8e8d7a3a01f50ca21b5337db7..7ed32b3cb781a0011a0560b7fe3898825f5c9e4f 100644 (file)
@@ -55,7 +55,7 @@ AllocMidQEntry(const struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
        if (temp == NULL)
                return temp;
        else {
-               memset(temp, 0, sizeof (struct mid_q_entry));
+               memset(temp, 0, sizeof(struct mid_q_entry));
                temp->mid = smb_buffer->Mid;    /* always LE */
                temp->pid = current->pid;
                temp->command = smb_buffer->Command;
@@ -158,7 +158,7 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
        iov.iov_len = len;
 
        smb_msg.msg_name = sin;
-       smb_msg.msg_namelen = sizeof (struct sockaddr);
+       smb_msg.msg_namelen = sizeof(struct sockaddr);
        smb_msg.msg_control = NULL;
        smb_msg.msg_controllen = 0;
        smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; /* BB add more flags?*/
@@ -228,7 +228,7 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
                return -ENOTSOCK; /* BB eventually add reconnect code here */
 
        smb_msg.msg_name = sin;
-       smb_msg.msg_namelen = sizeof (struct sockaddr);
+       smb_msg.msg_namelen = sizeof(struct sockaddr);
        smb_msg.msg_control = NULL;
        smb_msg.msg_controllen = 0;
        smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; /* BB add more flags?*/
@@ -363,9 +363,8 @@ static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf,
                } /* else ok - we are setting up session */
        }
        *ppmidQ = AllocMidQEntry(in_buf, ses);
-       if (*ppmidQ == NULL) {
+       if (*ppmidQ == NULL)
                return -ENOMEM;
-       }
        return 0;
 }
 
@@ -419,7 +418,7 @@ static int wait_for_response(struct cifsSesInfo *ses,
 int
 SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
             struct kvec *iov, int n_vec, int *pRespBufType /* ret */,
-            const int long_op)
+            const int long_op, const int logError)
 {
        int rc = 0;
        unsigned int receive_len;
@@ -465,7 +464,6 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
                wake_up(&ses->server->request_q);
                return rc;
        }
-
        rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number);
 
        midQ->midState = MID_REQUEST_SUBMITTED;
@@ -568,13 +566,11 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
                        }
 
                        /* BB special case reconnect tid and uid here? */
-                       /* BB special case Errbadpassword and pwdexpired here */
-                       rc = map_smb_to_linux_error(midQ->resp_buf);
+                       rc = map_smb_to_linux_error(midQ->resp_buf, logError);
 
                        /* convert ByteCount if necessary */
-                       if (receive_len >=
-                           sizeof (struct smb_hdr) -
-                           4 /* do not count RFC1001 header */  +
+                       if (receive_len >= sizeof(struct smb_hdr) - 4
+                           /* do not count RFC1001 header */  +
                            (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ )
                                BCC(midQ->resp_buf) =
                                        le16_to_cpu(BCC_LE(midQ->resp_buf));
@@ -749,12 +745,11 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
                        *pbytes_returned = out_buf->smb_buf_length;
 
                        /* BB special case reconnect tid and uid here? */
-                       rc = map_smb_to_linux_error(out_buf);
+                       rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
 
                        /* convert ByteCount if necessary */
-                       if (receive_len >=
-                           sizeof (struct smb_hdr) -
-                           4 /* do not count RFC1001 header */  +
+                       if (receive_len >= sizeof(struct smb_hdr) - 4
+                           /* do not count RFC1001 header */  +
                            (2 * out_buf->WordCount) + 2 /* bcc */ )
                                BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
                } else {
@@ -993,12 +988,11 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
                        *pbytes_returned = out_buf->smb_buf_length;
 
                        /* BB special case reconnect tid and uid here? */
-                       rc = map_smb_to_linux_error(out_buf);
+                       rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
 
                        /* convert ByteCount if necessary */
-                       if (receive_len >=
-                           sizeof (struct smb_hdr) -
-                           4 /* do not count RFC1001 header */  +
+                       if (receive_len >= sizeof(struct smb_hdr) - 4
+                           /* do not count RFC1001 header */  +
                            (2 * out_buf->WordCount) + 2 /* bcc */ )
                                BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
                } else {
index f61e433d281c908c6b106a8f3c95ed8bf267ec9b..369e838bebd3142554b72d58e7333547079b3e41 100644 (file)
@@ -261,21 +261,26 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
                                cifs_sb->local_nls,
                                cifs_sb->mnt_cifs_flags &
                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
-/*             else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+               else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
                        __u16 fid;
                        int oplock = FALSE;
-                       rc = CIFSSMBOpen(xid, pTcon, full_path,
-                                        FILE_OPEN, GENERIC_READ, 0, &fid,
-                                        &oplock, NULL, cifs_sb->local_nls,
-                                        cifs_sb->mnt_cifs_flags &
-                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
+                       if (experimEnabled) 
+                               rc = CIFSSMBOpen(xid, pTcon, full_path,
+                                       FILE_OPEN, GENERIC_READ, 0, &fid,
+                                       &oplock, NULL, cifs_sb->local_nls,
+                                       cifs_sb->mnt_cifs_flags &
+                                       CIFS_MOUNT_MAP_SPECIAL_CHR);
+                       /* else rc is EOPNOTSUPP from above */
+
                        if(rc == 0) {
                                rc = CIFSSMBGetCIFSACL(xid, pTcon, fid,
                                        ea_value, buf_size,
                                        ACL_TYPE_ACCESS);
                                CIFSSMBClose(xid, pTcon, fid);
                        }
-               } */  /* BB enable after fixing up return data */
+               }
+#endif /* EXPERIMENTAL */
 #else
                cFYI(1, ("query POSIX ACL not supported yet"));
 #endif /* CONFIG_CIFS_POSIX */
index cdb4c07a78700a93e34739a4aadddda96bfce8cc..359e531094ddddb74a88de2dbb74e11dde27d528 100644 (file)
@@ -51,7 +51,7 @@ static void *alloc_upcall(int opcode, int size)
 
         inp->ih.opcode = opcode;
        inp->ih.pid = current->pid;
-       inp->ih.pgid = process_group(current);
+       inp->ih.pgid = task_pgrp_nr(current);
 #ifdef CONFIG_CODA_FS_OLD_API
        memset(&inp->ih.cred, 0, sizeof(struct coda_cred));
        inp->ih.cred.cr_fsuid = current->fsuid;
index 6dacd39bf04842c89a53f42de5117fa2ac67bcc3..a4284ccac1f98a41becf824a638819222e1b5ae0 100644 (file)
@@ -3001,7 +3001,7 @@ static int __init init_sys32_ioctl(void)
        int i;
 
        for (i = 0; i < ARRAY_SIZE(ioctl_start); i++) {
-               if (ioctl_start[i].next != 0) {
+               if (ioctl_start[i].next) {
                        printk("ioctl translation %d bad\n",i);
                        return -1;
                }
index 5c817bd0838980c1089ca38d13505c864fb878dc..350680fd7da7db367f7f8699a2dc78a50dce6696 100644 (file)
@@ -148,7 +148,7 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i
 {
        struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping;
        struct page *pages[BLKS_PER_BUF];
-       unsigned i, blocknr, buffer, unread;
+       unsigned i, blocknr, buffer;
        unsigned long devsize;
        char *data;
 
@@ -175,7 +175,6 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i
        devsize = mapping->host->i_size >> PAGE_CACHE_SHIFT;
 
        /* Ok, read in BLKS_PER_BUF pages completely first. */
-       unread = 0;
        for (i = 0; i < BLKS_PER_BUF; i++) {
                struct page *page = NULL;
 
@@ -362,7 +361,7 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
        if (offset & 3)
                return -EINVAL;
 
-       buf = kmalloc(256, GFP_KERNEL);
+       buf = kmalloc(CRAMFS_MAXPATHLEN, GFP_KERNEL);
        if (!buf)
                return -ENOMEM;
 
@@ -376,7 +375,7 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
                int namelen, error;
 
                mutex_lock(&read_mutex);
-               de = cramfs_read(sb, OFFSET(inode) + offset, sizeof(*de)+256);
+               de = cramfs_read(sb, OFFSET(inode) + offset, sizeof(*de)+CRAMFS_MAXPATHLEN);
                name = (char *)(de+1);
 
                /*
@@ -426,7 +425,7 @@ static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry, s
                char *name;
                int namelen, retval;
 
-               de = cramfs_read(dir->i_sb, OFFSET(dir) + offset, sizeof(*de)+256);
+               de = cramfs_read(dir->i_sb, OFFSET(dir) + offset, sizeof(*de)+CRAMFS_MAXPATHLEN);
                name = (char *)(de+1);
 
                /* Try to take advantage of sorted directories */
index 5489b2d98a002901d28fdc2417135aab1744b9d0..d9ca1e5ceb92f02302fdeedb7bc1e2b6e5768f2e 100644 (file)
@@ -38,7 +38,7 @@ int sysctl_vfs_cache_pressure __read_mostly = 100;
 EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure);
 
  __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lock);
-static __cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock);
+__cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock);
 
 EXPORT_SYMBOL(dcache_lock);
 
@@ -1479,6 +1479,8 @@ static void switch_names(struct dentry *dentry, struct dentry *target)
                         * dentry:internal, target:external.  Steal target's
                         * storage and make target internal.
                         */
+                       memcpy(target->d_iname, dentry->d_name.name,
+                                       dentry->d_name.len + 1);
                        dentry->d_name.name = target->d_name.name;
                        target->d_name.name = target->d_iname;
                }
index 11be8a325e26d1b00070861bb74ddf14a0dc4284..6a713b33992f4caedaecb6ba604c47d25e6e6a07 100644 (file)
@@ -413,7 +413,7 @@ struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
        d_move(old_dentry, dentry);
        fsnotify_move(old_dir->d_inode, new_dir->d_inode, old_name,
                old_dentry->d_name.name, S_ISDIR(old_dentry->d_inode->i_mode),
-               NULL, old_dentry->d_inode);
+               NULL, old_dentry);
        fsnotify_oldname_free(old_name);
        unlock_rename(new_dir, old_dir);
        dput(dentry);
index 6438941ab1f8baf21e4ca88ce5d05b120b525f8b..4f741546f4bbce873079bee9060eac437934d8b6 100644 (file)
@@ -456,7 +456,7 @@ static int check_version(struct dlm_write_request *req)
                printk(KERN_DEBUG "dlm: process %s (%d) version mismatch "
                       "user (%d.%d.%d) kernel (%d.%d.%d)\n",
                       current->comm,
-                      current->pid,
+                      task_pid_nr(current),
                       req->version[0],
                       req->version[1],
                       req->version[2],
index 1ae90ef2c74d7b267e4250e2235c095e74469c30..0a9882edf56222721abbcf7f0b185b5c6a009456 100644 (file)
@@ -283,7 +283,7 @@ int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg,
                pg = virt_to_page(addr);
                offset = offset_in_page(addr);
                if (sg) {
-                       sg[i].page = pg;
+                       sg_set_page(&sg[i], pg);
                        sg[i].offset = offset;
                }
                remainder_of_page = PAGE_CACHE_SIZE - offset;
@@ -713,10 +713,13 @@ ecryptfs_encrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
 {
        struct scatterlist src_sg, dst_sg;
 
-       src_sg.page = src_page;
+       sg_init_table(&src_sg, 1);
+       sg_init_table(&dst_sg, 1);
+
+       sg_set_page(&src_sg, src_page);
        src_sg.offset = src_offset;
        src_sg.length = size;
-       dst_sg.page = dst_page;
+       sg_set_page(&dst_sg, dst_page);
        dst_sg.offset = dst_offset;
        dst_sg.length = size;
        return encrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
@@ -742,10 +745,13 @@ ecryptfs_decrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
 {
        struct scatterlist src_sg, dst_sg;
 
-       src_sg.page = src_page;
+       sg_init_table(&src_sg, 1);
+       sg_init_table(&dst_sg, 1);
+
+       sg_set_page(&src_sg, src_page);
        src_sg.offset = src_offset;
        src_sg.length = size;
-       dst_sg.page = dst_page;
+       sg_set_page(&dst_sg, dst_page);
        dst_sg.offset = dst_offset;
        dst_sg.length = size;
        return decrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
index 5701f816faf47e30975b4d2a46baeb6d21c05a38..0b1ab016fa2e513589c004373323c376af1de9ba 100644 (file)
@@ -914,6 +914,14 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
                if (rc < 0)
                        goto out;
        }
+
+       /*
+        * mode change is for clearing setuid/setgid bits. Allow lower fs
+        * to interpret this in its own way.
+        */
+       if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
+               ia->ia_valid &= ~ATTR_MODE;
+
        rc = notify_change(lower_dentry, ia);
 out:
        fsstack_copy_attr_all(inode, lower_inode, NULL);
index 89d9710dd63dd2a091a1bacd8e78c536914c7a54..263fed88c0cabac8e37e8b6801d50bdac0500326 100644 (file)
@@ -1040,6 +1040,9 @@ decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
        };
        int rc = 0;
 
+       sg_init_table(&dst_sg, 1);
+       sg_init_table(&src_sg, 1);
+
        if (unlikely(ecryptfs_verbosity > 0)) {
                ecryptfs_printk(
                        KERN_DEBUG, "Session key encryption key (size [%d]):\n",
index 5276b19423c1abeda0ccd20cc0b0f0f99fc0d1eb..f7f407075be107e6dc0625676268300bdd1df501 100644 (file)
@@ -10,6 +10,8 @@
 #include <linux/string.h>
 #include <linux/efs_fs.h>
 #include <linux/smp_lock.h>
+#include <linux/exportfs.h>
+
 
 static efs_ino_t efs_find_entry(struct inode *inode, const char *name, int len) {
        struct buffer_head *bh;
@@ -75,13 +77,10 @@ struct dentry *efs_lookup(struct inode *dir, struct dentry *dentry, struct namei
        return NULL;
 }
 
-struct dentry *efs_get_dentry(struct super_block *sb, void *vobjp)
+static struct inode *efs_nfs_get_inode(struct super_block *sb, u64 ino,
+               u32 generation)
 {
-       __u32 *objp = vobjp;
-       unsigned long ino = objp[0];
-       __u32 generation = objp[1];
        struct inode *inode;
-       struct dentry *result;
 
        if (ino == 0)
                return ERR_PTR(-ESTALE);
@@ -91,20 +90,25 @@ struct dentry *efs_get_dentry(struct super_block *sb, void *vobjp)
 
        if (is_bad_inode(inode) ||
            (generation && inode->i_generation != generation)) {
-               result = ERR_PTR(-ESTALE);
-               goto out_iput;
+               iput(inode);
+               return ERR_PTR(-ESTALE);
        }
 
-       result = d_alloc_anon(inode);
-       if (!result) {
-               result = ERR_PTR(-ENOMEM);
-               goto out_iput;
-       }
-       return result;
+       return inode;
+}
 
- out_iput:
-       iput(inode);
-       return result;
+struct dentry *efs_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,
+                                   efs_nfs_get_inode);
+}
+
+struct dentry *efs_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,
+                                   efs_nfs_get_inode);
 }
 
 struct dentry *efs_get_parent(struct dentry *child)
index 25d0326c5f1c9a6c44b220c89e5bd94a9f32c6be..c79bc627f1079adf72ac3779befdda1540272dec 100644 (file)
@@ -113,8 +113,9 @@ static const struct super_operations efs_superblock_operations = {
        .remount_fs     = efs_remount,
 };
 
-static struct export_operations efs_export_ops = {
-       .get_dentry     = efs_get_dentry,
+static const struct export_operations efs_export_ops = {
+       .fh_to_dentry   = efs_fh_to_dentry,
+       .fh_to_parent   = efs_fh_to_parent,
        .get_parent     = efs_get_parent,
 };
 
index 77b9953624f480e37d80fb13010fb3e1bc8b3c51..34f68f3a069a1b7d4924dc8be718927f9e6c791d 100644 (file)
@@ -325,15 +325,14 @@ static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq)
        int wake_nests = 0;
        unsigned long flags;
        struct task_struct *this_task = current;
-       struct list_head *lsthead = &psw->wake_task_list, *lnk;
+       struct list_head *lsthead = &psw->wake_task_list;
        struct wake_task_node *tncur;
        struct wake_task_node tnode;
 
        spin_lock_irqsave(&psw->lock, flags);
 
        /* Try to see if the current task is already inside this wakeup call */
-       list_for_each(lnk, lsthead) {
-               tncur = list_entry(lnk, struct wake_task_node, llink);
+       list_for_each_entry(tncur, lsthead, llink) {
 
                if (tncur->wq == wq ||
                    (tncur->task == this_task && ++wake_nests > EP_MAX_POLLWAKE_NESTS)) {
@@ -463,7 +462,7 @@ static void ep_free(struct eventpoll *ep)
         * holding "epmutex" we can be sure that no file cleanup code will hit
         * us during this operation. So we can avoid the lock on "ep->lock".
         */
-       while ((rbp = rb_first(&ep->rbr)) != 0) {
+       while ((rbp = rb_first(&ep->rbr)) != NULL) {
                epi = rb_entry(rbp, struct epitem, rbn);
                ep_remove(ep, epi);
        }
index 070ddf13cb719d62ead6233961c2bb9716beed02..2c942e2d14ea2b3ebf2fb51bcf692e3a37565ae5 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -234,7 +234,7 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
        vma->vm_start = vma->vm_end - PAGE_SIZE;
 
        vma->vm_flags = VM_STACK_FLAGS;
-       vma->vm_page_prot = protection_map[vma->vm_flags & 0x7];
+       vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
        err = insert_vm_struct(mm, vma);
        if (err) {
                up_write(&mm->mmap_sem);
@@ -775,8 +775,8 @@ static int de_thread(struct task_struct *tsk)
         * Reparenting needs write_lock on tasklist_lock,
         * so it is safe to do it under read_lock.
         */
-       if (unlikely(tsk->group_leader == child_reaper(tsk)))
-               tsk->nsproxy->pid_ns->child_reaper = tsk;
+       if (unlikely(tsk->group_leader == task_child_reaper(tsk)))
+               task_active_pid_ns(tsk)->child_reaper = tsk;
 
        zap_other_threads(tsk);
        read_unlock(&tasklist_lock);
@@ -841,8 +841,8 @@ static int de_thread(struct task_struct *tsk)
                 */
                tsk->start_time = leader->start_time;
 
-               BUG_ON(leader->tgid != tsk->tgid);
-               BUG_ON(tsk->pid == tsk->tgid);
+               BUG_ON(!same_thread_group(leader, tsk));
+               BUG_ON(has_group_leader_pid(tsk));
                /*
                 * An exec() starts a new thread group with the
                 * TGID of the previous thread group. Rehash the
@@ -857,7 +857,7 @@ static int de_thread(struct task_struct *tsk)
                 */
                detach_pid(tsk, PIDTYPE_PID);
                tsk->pid = leader->pid;
-               attach_pid(tsk, PIDTYPE_PID,  find_pid(tsk->pid));
+               attach_pid(tsk, PIDTYPE_PID,  task_pid(leader));
                transfer_pid(leader, tsk, PIDTYPE_PGID);
                transfer_pid(leader, tsk, PIDTYPE_SID);
                list_replace_rcu(&leader->tasks, &tsk->tasks);
@@ -1433,7 +1433,7 @@ static int format_corename(char *corename, const char *pattern, long signr)
                        case 'p':
                                pid_in_pattern = 1;
                                rc = snprintf(out_ptr, out_end - out_ptr,
-                                             "%d", current->tgid);
+                                             "%d", task_tgid_vnr(current));
                                if (rc > out_end - out_ptr)
                                        goto out;
                                out_ptr += rc;
@@ -1513,7 +1513,7 @@ static int format_corename(char *corename, const char *pattern, long signr)
        if (!ispipe && !pid_in_pattern
             && (core_uses_pid || atomic_read(&current->mm->mm_users) != 1)) {
                rc = snprintf(out_ptr, out_end - out_ptr,
-                             ".%d", current->tgid);
+                             ".%d", task_tgid_vnr(current));
                if (rc > out_end - out_ptr)
                        goto out;
                out_ptr += rc;
index 8adb32a9387a3e6cb76ba0cf80b9873d51dad3bd..109ab5e44eca3f6d5961f721b582d137779c6265 100644 (file)
@@ -1,4 +1,13 @@
-
+/*
+ * Copyright (C) Neil Brown 2002
+ * Copyright (C) Christoph Hellwig 2007
+ *
+ * This file contains the code mapping from inodes to NFS file handles,
+ * and for mapping back from file handles to dentries.
+ *
+ * For details on why we do all the strange and hairy things in here
+ * take a look at Documentation/filesystems/Exporting.
+ */
 #include <linux/exportfs.h>
 #include <linux/fs.h>
 #include <linux/file.h>
 #define dprintk(fmt, args...) do{}while(0)
 
 
-static int get_name(struct dentry *dentry, char *name,
+static int get_name(struct vfsmount *mnt, struct dentry *dentry, char *name,
                struct dentry *child);
 
 
-static struct dentry *exportfs_get_dentry(struct super_block *sb, void *obj)
+static int exportfs_get_name(struct vfsmount *mnt, struct dentry *dir,
+               char *name, struct dentry *child)
 {
-       struct dentry *result = ERR_PTR(-ESTALE);
-
-       if (sb->s_export_op->get_dentry) {
-               result = sb->s_export_op->get_dentry(sb, obj);
-               if (!result)
-                       result = ERR_PTR(-ESTALE);
-       }
-
-       return result;
-}
-
-static int exportfs_get_name(struct dentry *dir, char *name,
-               struct dentry *child)
-{
-       struct export_operations *nop = dir->d_sb->s_export_op;
+       const struct export_operations *nop = dir->d_sb->s_export_op;
 
        if (nop->get_name)
                return nop->get_name(dir, name, child);
        else
-               return get_name(dir, name, child);
+               return get_name(mnt, dir, name, child);
 }
 
 /*
@@ -98,7 +94,7 @@ 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 super_block *sb, struct dentry *target_dir)
+reconnect_path(struct vfsmount *mnt, struct dentry *target_dir)
 {
        char nbuf[NAME_MAX+1];
        int noprogress = 0;
@@ -121,7 +117,7 @@ reconnect_path(struct super_block *sb, struct dentry *target_dir)
                        pd->d_flags &= ~DCACHE_DISCONNECTED;
                        spin_unlock(&pd->d_lock);
                        noprogress = 0;
-               } else if (pd == sb->s_root) {
+               } else if (pd == mnt->mnt_sb->s_root) {
                        printk(KERN_ERR "export: Eeek filesystem root is not connected, impossible\n");
                        spin_lock(&pd->d_lock);
                        pd->d_flags &= ~DCACHE_DISCONNECTED;
@@ -147,8 +143,8 @@ reconnect_path(struct super_block *sb, struct dentry *target_dir)
                        struct dentry *npd;
 
                        mutex_lock(&pd->d_inode->i_mutex);
-                       if (sb->s_export_op->get_parent)
-                               ppd = sb->s_export_op->get_parent(pd);
+                       if (mnt->mnt_sb->s_export_op->get_parent)
+                               ppd = mnt->mnt_sb->s_export_op->get_parent(pd);
                        mutex_unlock(&pd->d_inode->i_mutex);
 
                        if (IS_ERR(ppd)) {
@@ -161,7 +157,7 @@ reconnect_path(struct super_block *sb, struct dentry *target_dir)
 
                        dprintk("%s: find name of %lu in %lu\n", __FUNCTION__,
                                pd->d_inode->i_ino, ppd->d_inode->i_ino);
-                       err = exportfs_get_name(ppd, nbuf, pd);
+                       err = exportfs_get_name(mnt, ppd, nbuf, pd);
                        if (err) {
                                dput(ppd);
                                dput(pd);
@@ -214,125 +210,6 @@ reconnect_path(struct super_block *sb, struct dentry *target_dir)
        return 0;
 }
 
-/**
- * find_exported_dentry - helper routine to implement export_operations->decode_fh
- * @sb:                The &super_block identifying the filesystem
- * @obj:       An opaque identifier of the object to be found - passed to
- *             get_inode
- * @parent:    An optional opqaue identifier of the parent of the object.
- * @acceptable:        A function used to test possible &dentries to see if they are
- *             acceptable
- * @context:   A parameter to @acceptable so that it knows on what basis to
- *             judge.
- *
- * find_exported_dentry is the central helper routine to enable file systems
- * to provide the decode_fh() export_operation.  It's main task is to take
- * an &inode, find or create an appropriate &dentry structure, and possibly
- * splice this into the dcache in the correct place.
- *
- * The decode_fh() operation provided by the filesystem should call
- * find_exported_dentry() with the same parameters that it received except
- * that instead of the file handle fragment, pointers to opaque identifiers
- * for the object and optionally its parent are passed.  The default decode_fh
- * routine passes one pointer to the start of the filehandle fragment, and
- * one 8 bytes into the fragment.  It is expected that most filesystems will
- * take this approach, though the offset to the parent identifier may well be
- * different.
- *
- * find_exported_dentry() will call get_dentry to get an dentry pointer from
- * the file system.  If any &dentry in the d_alias list is acceptable, it will
- * be returned.  Otherwise find_exported_dentry() will attempt to splice a new
- * &dentry into the dcache using get_name() and get_parent() to find the
- * appropriate place.
- */
-
-struct dentry *
-find_exported_dentry(struct super_block *sb, void *obj, void *parent,
-                    int (*acceptable)(void *context, struct dentry *de),
-                    void *context)
-{
-       struct dentry *result, *alias;
-       int err = -ESTALE;
-
-       /*
-        * Attempt to find the inode.
-        */
-       result = exportfs_get_dentry(sb, obj);
-       if (IS_ERR(result))
-               return result;
-
-       if (S_ISDIR(result->d_inode->i_mode)) {
-               if (!(result->d_flags & DCACHE_DISCONNECTED)) {
-                       if (acceptable(context, result))
-                               return result;
-                       err = -EACCES;
-                       goto err_result;
-               }
-
-               err = reconnect_path(sb, result);
-               if (err)
-                       goto err_result;
-       } else {
-               struct dentry *target_dir, *nresult;
-               char nbuf[NAME_MAX+1];
-
-               alias = find_acceptable_alias(result, acceptable, context);
-               if (alias)
-                       return alias;
-
-               if (parent == NULL)
-                       goto err_result;
-
-               target_dir = exportfs_get_dentry(sb,parent);
-               if (IS_ERR(target_dir)) {
-                       err = PTR_ERR(target_dir);
-                       goto err_result;
-               }
-
-               err = reconnect_path(sb, target_dir);
-               if (err) {
-                       dput(target_dir);
-                       goto err_result;
-               }
-
-               /*
-                * As we weren't after a directory, have one more step to go.
-                */
-               err = exportfs_get_name(target_dir, nbuf, result);
-               if (!err) {
-                       mutex_lock(&target_dir->d_inode->i_mutex);
-                       nresult = lookup_one_len(nbuf, target_dir,
-                                                strlen(nbuf));
-                       mutex_unlock(&target_dir->d_inode->i_mutex);
-                       if (!IS_ERR(nresult)) {
-                               if (nresult->d_inode) {
-                                       dput(result);
-                                       result = nresult;
-                               } else
-                                       dput(nresult);
-                       }
-               }
-               dput(target_dir);
-       }
-
-       alias = find_acceptable_alias(result, acceptable, context);
-       if (alias)
-               return alias;
-
-       /* drat - I just cannot find anything acceptable */
-       dput(result);
-       /* It might be justifiable to return ESTALE here,
-        * but the filehandle at-least looks reasonable good
-        * and it may just be a permission problem, so returning
-        * -EACCESS is safer
-        */
-       return ERR_PTR(-EACCES);
-
- err_result:
-       dput(result);
-       return ERR_PTR(err);
-}
-
 struct getdents_callback {
        char *name;             /* name that was found. It already points to a
                                   buffer NAME_MAX+1 is size */
@@ -370,8 +247,8 @@ static int filldir_one(void * __buf, const char * name, int len,
  * calls readdir on the parent until it finds an entry with
  * the same inode number as the child, and returns that.
  */
-static int get_name(struct dentry *dentry, char *name,
-                       struct dentry *child)
+static int get_name(struct vfsmount *mnt, struct dentry *dentry,
+               char *name, struct dentry *child)
 {
        struct inode *dir = dentry->d_inode;
        int error;
@@ -387,7 +264,7 @@ static int get_name(struct dentry *dentry, char *name,
        /*
         * Open the directory ...
         */
-       file = dentry_open(dget(dentry), NULL, O_RDONLY);
+       file = dentry_open(dget(dentry), mntget(mnt), O_RDONLY);
        error = PTR_ERR(file);
        if (IS_ERR(file))
                goto out;
@@ -434,100 +311,177 @@ out:
  * can be used to check that it is still valid.  It places them in the
  * filehandle fragment where export_decode_fh expects to find them.
  */
-static int export_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len,
-                  int connectable)
+static int export_encode_fh(struct dentry *dentry, struct fid *fid,
+               int *max_len, int connectable)
 {
        struct inode * inode = dentry->d_inode;
        int len = *max_len;
-       int type = 1;
+       int type = FILEID_INO32_GEN;
        
        if (len < 2 || (connectable && len < 4))
                return 255;
 
        len = 2;
-       fh[0] = inode->i_ino;
-       fh[1] = inode->i_generation;
+       fid->i32.ino = inode->i_ino;
+       fid->i32.gen = inode->i_generation;
        if (connectable && !S_ISDIR(inode->i_mode)) {
                struct inode *parent;
 
                spin_lock(&dentry->d_lock);
                parent = dentry->d_parent->d_inode;
-               fh[2] = parent->i_ino;
-               fh[3] = parent->i_generation;
+               fid->i32.parent_ino = parent->i_ino;
+               fid->i32.parent_gen = parent->i_generation;
                spin_unlock(&dentry->d_lock);
                len = 4;
-               type = 2;
+               type = FILEID_INO32_GEN_PARENT;
        }
        *max_len = len;
        return type;
 }
 
-
-/**
- * export_decode_fh - default export_operations->decode_fh function
- * @sb:  The superblock
- * @fh:  pointer to the file handle fragment
- * @fh_len: length of file handle fragment
- * @acceptable: function for testing acceptability of dentrys
- * @context:   context for @acceptable
- *
- * This is the default decode_fh() function.
- * a fileid_type of 1 indicates that the filehandlefragment
- * just contains an object identifier understood by  get_dentry.
- * a fileid_type of 2 says that there is also a directory
- * identifier 8 bytes in to the filehandlefragement.
- */
-static struct dentry *export_decode_fh(struct super_block *sb, __u32 *fh, int fh_len,
-                             int fileid_type,
-                        int (*acceptable)(void *context, struct dentry *de),
-                        void *context)
-{
-       __u32 parent[2];
-       parent[0] = parent[1] = 0;
-       if (fh_len < 2 || fileid_type > 2)
-               return NULL;
-       if (fileid_type == 2) {
-               if (fh_len > 2) parent[0] = fh[2];
-               if (fh_len > 3) parent[1] = fh[3];
-       }
-       return find_exported_dentry(sb, fh, parent,
-                                  acceptable, context);
-}
-
-int exportfs_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len,
+int exportfs_encode_fh(struct dentry *dentry, struct fid *fid, int *max_len,
                int connectable)
 {
-       struct export_operations *nop = dentry->d_sb->s_export_op;
+       const struct export_operations *nop = dentry->d_sb->s_export_op;
        int error;
 
        if (nop->encode_fh)
-               error = nop->encode_fh(dentry, fh, max_len, connectable);
+               error = nop->encode_fh(dentry, fid->raw, max_len, connectable);
        else
-               error = export_encode_fh(dentry, fh, max_len, connectable);
+               error = export_encode_fh(dentry, fid, max_len, connectable);
 
        return error;
 }
 EXPORT_SYMBOL_GPL(exportfs_encode_fh);
 
-struct dentry *exportfs_decode_fh(struct vfsmount *mnt, __u32 *fh, int fh_len,
-               int fileid_type, int (*acceptable)(void *, struct dentry *),
-               void *context)
+struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
+               int fh_len, int fileid_type,
+               int (*acceptable)(void *, struct dentry *), void *context)
 {
-       struct export_operations *nop = mnt->mnt_sb->s_export_op;
-       struct dentry *result;
+       const struct export_operations *nop = mnt->mnt_sb->s_export_op;
+       struct dentry *result, *alias;
+       int err;
 
-       if (nop->decode_fh) {
-               result = nop->decode_fh(mnt->mnt_sb, fh, fh_len, fileid_type,
-                       acceptable, context);
+       /*
+        * 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;
+
+       if (S_ISDIR(result->d_inode->i_mode)) {
+               /*
+                * This request is for a directory.
+                *
+                * On the positive side there is only one dentry for each
+                * directory inode.  On the negative side this implies that we
+                * to ensure our dentry is connected all the way up to the
+                * filesystem root.
+                */
+               if (result->d_flags & DCACHE_DISCONNECTED) {
+                       err = reconnect_path(mnt, result);
+                       if (err)
+                               goto err_result;
+               }
+
+               if (!acceptable(context, result)) {
+                       err = -EACCES;
+                       goto err_result;
+               }
+
+               return result;
        } else {
-               result = export_decode_fh(mnt->mnt_sb, fh, fh_len, fileid_type,
-                       acceptable, context);
+               /*
+                * 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
+                * or any alias for it is acceptable.  This is always true
+                * if this filesystem is exported without the subtreecheck
+                * option.  If the filesystem is exported with the subtree
+                * check option there's a fair chance we need to look at
+                * the parent directory in the file handle and make sure
+                * it's connected to the filesystem root.
+                */
+               alias = find_acceptable_alias(result, acceptable, context);
+               if (alias)
+                       return alias;
+
+               /*
+                * Try to extract a dentry for the parent directory from the
+                * file handle.  If this fails we'll have to give up.
+                */
+               err = -ESTALE;
+               if (!nop->fh_to_parent)
+                       goto err_result;
+
+               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;
+
+               /*
+                * And as usual we need to make sure the parent directory is
+                * connected to the filesystem root.  The VFS really doesn't
+                * like disconnected directories..
+                */
+               err = reconnect_path(mnt, target_dir);
+               if (err) {
+                       dput(target_dir);
+                       goto err_result;
+               }
+
+               /*
+                * Now that we've got both a well-connected parent and a
+                * dentry for the inode we're after, make sure that our
+                * inode is actually connected to the parent.
+                */
+               err = exportfs_get_name(mnt, target_dir, nbuf, result);
+               if (!err) {
+                       mutex_lock(&target_dir->d_inode->i_mutex);
+                       nresult = lookup_one_len(nbuf, target_dir,
+                                                strlen(nbuf));
+                       mutex_unlock(&target_dir->d_inode->i_mutex);
+                       if (!IS_ERR(nresult)) {
+                               if (nresult->d_inode) {
+                                       dput(result);
+                                       result = nresult;
+                               } else
+                                       dput(nresult);
+                       }
+               }
+
+               /*
+                * At this point we are done with the parent, but it's pinned
+                * by the child dentry anyway.
+                */
+               dput(target_dir);
+
+               /*
+                * And finally make sure the dentry is actually acceptable
+                * to NFSD.
+                */
+               alias = find_acceptable_alias(result, acceptable, context);
+               if (!alias) {
+                       err = -EACCES;
+                       goto err_result;
+               }
+
+               return alias;
        }
 
-       return result;
+ err_result:
+       dput(result);
+       return ERR_PTR(err);
 }
 EXPORT_SYMBOL_GPL(exportfs_decode_fh);
 
-EXPORT_SYMBOL(find_exported_dentry);
-
 MODULE_LICENSE("GPL");
index 05d9342bb64ee271586f0a9f136e36f599b8cf83..d868e26c15eba90e48c5c1324c9f207ef109d1e6 100644 (file)
 
 typedef struct ext2_dir_entry_2 ext2_dirent;
 
+static inline unsigned ext2_rec_len_from_disk(__le16 dlen)
+{
+       unsigned len = le16_to_cpu(dlen);
+
+       if (len == EXT2_MAX_REC_LEN)
+               return 1 << 16;
+       return len;
+}
+
+static inline __le16 ext2_rec_len_to_disk(unsigned len)
+{
+       if (len == (1 << 16))
+               return cpu_to_le16(EXT2_MAX_REC_LEN);
+       else if (len > (1 << 16))
+               BUG();
+       return cpu_to_le16(len);
+}
+
 /*
  * ext2 uses block-sized chunks. Arguably, sector-sized ones would be
  * more robust, but we have what we have
@@ -106,7 +124,7 @@ static void ext2_check_page(struct page *page)
        }
        for (offs = 0; offs <= limit - EXT2_DIR_REC_LEN(1); offs += rec_len) {
                p = (ext2_dirent *)(kaddr + offs);
-               rec_len = le16_to_cpu(p->rec_len);
+               rec_len = ext2_rec_len_from_disk(p->rec_len);
 
                if (rec_len < EXT2_DIR_REC_LEN(1))
                        goto Eshort;
@@ -204,7 +222,8 @@ static inline int ext2_match (int len, const char * const name,
  */
 static inline ext2_dirent *ext2_next_entry(ext2_dirent *p)
 {
-       return (ext2_dirent *)((char*)p + le16_to_cpu(p->rec_len));
+       return (ext2_dirent *)((char *)p +
+                       ext2_rec_len_from_disk(p->rec_len));
 }
 
 static inline unsigned 
@@ -316,7 +335,7 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
                                        return 0;
                                }
                        }
-                       filp->f_pos += le16_to_cpu(de->rec_len);
+                       filp->f_pos += ext2_rec_len_from_disk(de->rec_len);
                }
                ext2_put_page(page);
        }
@@ -425,7 +444,7 @@ void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de,
 {
        loff_t pos = page_offset(page) +
                        (char *) de - (char *) page_address(page);
-       unsigned len = le16_to_cpu(de->rec_len);
+       unsigned len = ext2_rec_len_from_disk(de->rec_len);
        int err;
 
        lock_page(page);
@@ -482,7 +501,7 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode)
                                /* We hit i_size */
                                name_len = 0;
                                rec_len = chunk_size;
-                               de->rec_len = cpu_to_le16(chunk_size);
+                               de->rec_len = ext2_rec_len_to_disk(chunk_size);
                                de->inode = 0;
                                goto got_it;
                        }
@@ -496,7 +515,7 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode)
                        if (ext2_match (namelen, name, de))
                                goto out_unlock;
                        name_len = EXT2_DIR_REC_LEN(de->name_len);
-                       rec_len = le16_to_cpu(de->rec_len);
+                       rec_len = ext2_rec_len_from_disk(de->rec_len);
                        if (!de->inode && rec_len >= reclen)
                                goto got_it;
                        if (rec_len >= name_len + reclen)
@@ -518,8 +537,8 @@ got_it:
                goto out_unlock;
        if (de->inode) {
                ext2_dirent *de1 = (ext2_dirent *) ((char *) de + name_len);
-               de1->rec_len = cpu_to_le16(rec_len - name_len);
-               de->rec_len = cpu_to_le16(name_len);
+               de1->rec_len = ext2_rec_len_to_disk(rec_len - name_len);
+               de->rec_len = ext2_rec_len_to_disk(name_len);
                de = de1;
        }
        de->name_len = namelen;
@@ -550,7 +569,8 @@ int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page )
        struct inode *inode = mapping->host;
        char *kaddr = page_address(page);
        unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1);
-       unsigned to = ((char*)dir - kaddr) + le16_to_cpu(dir->rec_len);
+       unsigned to = ((char *)dir - kaddr) +
+                               ext2_rec_len_from_disk(dir->rec_len);
        loff_t pos;
        ext2_dirent * pde = NULL;
        ext2_dirent * de = (ext2_dirent *) (kaddr + from);
@@ -574,7 +594,7 @@ int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page )
                                                        &page, NULL);
        BUG_ON(err);
        if (pde)
-               pde->rec_len = cpu_to_le16(to - from);
+               pde->rec_len = ext2_rec_len_to_disk(to - from);
        dir->inode = 0;
        err = ext2_commit_chunk(page, pos, to - from);
        inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
@@ -610,14 +630,14 @@ int ext2_make_empty(struct inode *inode, struct inode *parent)
        memset(kaddr, 0, chunk_size);
        de = (struct ext2_dir_entry_2 *)kaddr;
        de->name_len = 1;
-       de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(1));
+       de->rec_len = ext2_rec_len_to_disk(EXT2_DIR_REC_LEN(1));
        memcpy (de->name, ".\0\0", 4);
        de->inode = cpu_to_le32(inode->i_ino);
        ext2_set_de_type (de, inode);
 
        de = (struct ext2_dir_entry_2 *)(kaddr + EXT2_DIR_REC_LEN(1));
        de->name_len = 2;
-       de->rec_len = cpu_to_le16(chunk_size - EXT2_DIR_REC_LEN(1));
+       de->rec_len = ext2_rec_len_to_disk(chunk_size - EXT2_DIR_REC_LEN(1));
        de->inode = cpu_to_le32(parent->i_ino);
        memcpy (de->name, "..\0", 4);
        ext2_set_de_type (de, inode);
index 77bd5f9262f94c4e2da4a012c5f89b50af357dd1..154e25f13d772235e7c7d242a0b5e6fdbf977cd7 100644 (file)
@@ -311,13 +311,10 @@ static const struct super_operations ext2_sops = {
 #endif
 };
 
-static struct dentry *ext2_get_dentry(struct super_block *sb, void *vobjp)
+static struct inode *ext2_nfs_get_inode(struct super_block *sb,
+               u64 ino, u32 generation)
 {
-       __u32 *objp = vobjp;
-       unsigned long ino = objp[0];
-       __u32 generation = objp[1];
        struct inode *inode;
-       struct dentry *result;
 
        if (ino < EXT2_FIRST_INO(sb) && ino != EXT2_ROOT_INO)
                return ERR_PTR(-ESTALE);
@@ -338,15 +335,21 @@ static struct dentry *ext2_get_dentry(struct super_block *sb, void *vobjp)
                iput(inode);
                return ERR_PTR(-ESTALE);
        }
-       /* now to find a dentry.
-        * If possible, get a well-connected one
-        */
-       result = d_alloc_anon(inode);
-       if (!result) {
-               iput(inode);
-               return ERR_PTR(-ENOMEM);
-       }
-       return result;
+       return inode;
+}
+
+static struct dentry *ext2_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,
+                                   ext2_nfs_get_inode);
+}
+
+static struct dentry *ext2_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,
+                                   ext2_nfs_get_inode);
 }
 
 /* Yes, most of these are left as NULL!!
@@ -354,9 +357,10 @@ static struct dentry *ext2_get_dentry(struct super_block *sb, void *vobjp)
  * systems, but can be improved upon.
  * Currently only get_parent is required.
  */
-static struct export_operations ext2_export_ops = {
+static const struct export_operations ext2_export_ops = {
+       .fh_to_dentry = ext2_fh_to_dentry,
+       .fh_to_parent = ext2_fh_to_parent,
        .get_parent = ext2_get_parent,
-       .get_dentry = ext2_get_dentry,
 };
 
 static unsigned long get_sb_block(void **data)
index dd1fd3c0fc05c1bf4593decf9cd692df28558079..a588e23841d4e68323d2604e70ad92ec227923c6 100644 (file)
@@ -47,7 +47,7 @@ int ext3_sync_file(struct file * file, struct dentry *dentry, int datasync)
        struct inode *inode = dentry->d_inode;
        int ret = 0;
 
-       J_ASSERT(ext3_journal_current_handle() == 0);
+       J_ASSERT(ext3_journal_current_handle() == NULL);
 
        /*
         * data=writeback:
index 2f2b6864db10608c412e8eac665f9c30344324d1..9b162cd6c16c170ce7c35c3fc2f993ccc648cbc3 100644 (file)
@@ -1028,7 +1028,7 @@ struct buffer_head *ext3_getblk(handle_t *handle, struct inode *inode,
                }
                if (buffer_new(&dummy)) {
                        J_ASSERT(create != 0);
-                       J_ASSERT(handle != 0);
+                       J_ASSERT(handle != NULL);
 
                        /*
                         * Now that we do not always journal data, we should
@@ -2954,7 +2954,7 @@ int ext3_write_inode(struct inode *inode, int wait)
                return 0;
 
        if (ext3_journal_current_handle()) {
-               jbd_debug(0, "called recursively, non-PF_MEMALLOC!\n");
+               jbd_debug(1, "called recursively, non-PF_MEMALLOC!\n");
                dump_stack();
                return -EIO;
        }
index 771f7ada15d9a9b516fd0782f8ab3ee793cba48d..44de1453c30158e5bc742d2cfc54cf56d5ec0724 100644 (file)
@@ -245,10 +245,10 @@ static int setup_new_group_blocks(struct super_block *sb,
                        brelse(gdb);
                        goto exit_bh;
                }
-               lock_buffer(bh);
-               memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, bh->b_size);
+               lock_buffer(gdb);
+               memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, gdb->b_size);
                set_buffer_uptodate(gdb);
-               unlock_buffer(bh);
+               unlock_buffer(gdb);
                ext3_journal_dirty_metadata(handle, gdb);
                ext3_set_bit(bit, bh->b_data);
                brelse(gdb);
index 141573de7a9a4ca69416c24c0a84aa00e8e1674d..de55da9e28ba618b85b7d7831793dec0e44a7d72 100644 (file)
@@ -631,13 +631,10 @@ static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs)
 }
 
 
-static struct dentry *ext3_get_dentry(struct super_block *sb, void *vobjp)
+static struct inode *ext3_nfs_get_inode(struct super_block *sb,
+               u64 ino, u32 generation)
 {
-       __u32 *objp = vobjp;
-       unsigned long ino = objp[0];
-       __u32 generation = objp[1];
        struct inode *inode;
-       struct dentry *result;
 
        if (ino < EXT3_FIRST_INO(sb) && ino != EXT3_ROOT_INO)
                return ERR_PTR(-ESTALE);
@@ -660,15 +657,22 @@ static struct dentry *ext3_get_dentry(struct super_block *sb, void *vobjp)
                iput(inode);
                return ERR_PTR(-ESTALE);
        }
-       /* now to find a dentry.
-        * If possible, get a well-connected one
-        */
-       result = d_alloc_anon(inode);
-       if (!result) {
-               iput(inode);
-               return ERR_PTR(-ENOMEM);
-       }
-       return result;
+
+       return inode;
+}
+
+static struct dentry *ext3_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,
+                                   ext3_nfs_get_inode);
+}
+
+static struct dentry *ext3_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,
+                                   ext3_nfs_get_inode);
 }
 
 #ifdef CONFIG_QUOTA
@@ -737,9 +741,10 @@ static const struct super_operations ext3_sops = {
 #endif
 };
 
-static struct export_operations ext3_export_ops = {
+static const struct export_operations ext3_export_ops = {
+       .fh_to_dentry = ext3_fh_to_dentry,
+       .fh_to_parent = ext3_fh_to_parent,
        .get_parent = ext3_get_parent,
-       .get_dentry = ext3_get_dentry,
 };
 
 enum {
@@ -1620,7 +1625,11 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
                }
 
                brelse (bh);
-               sb_set_blocksize(sb, blocksize);
+               if (!sb_set_blocksize(sb, blocksize)) {
+                       printk(KERN_ERR "EXT3-fs: bad blocksize %d.\n",
+                               blocksize);
+                       goto out_fail;
+               }
                logic_sb_block = (sb_block * EXT3_MIN_BLOCK_SIZE) / blocksize;
                offset = (sb_block * EXT3_MIN_BLOCK_SIZE) % blocksize;
                bh = sb_bread(sb, logic_sb_block);
index f58cbb26323e1ea666d78eba4cb4d3bd4c16490a..408373819e34eddb7dec372b9d518189d54b4242 100644 (file)
@@ -741,12 +741,11 @@ ext3_xattr_block_set(handle_t *handle, struct inode *inode,
                }
        } else {
                /* Allocate a buffer where we construct the new block. */
-               s->base = kmalloc(sb->s_blocksize, GFP_KERNEL);
+               s->base = kzalloc(sb->s_blocksize, GFP_KERNEL);
                /* assert(header == s->base) */
                error = -ENOMEM;
                if (s->base == NULL)
                        goto cleanup;
-               memset(s->base, 0, sb->s_blocksize);
                header(s->base)->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC);
                header(s->base)->h_blocks = cpu_to_le32(1);
                header(s->base)->h_refcount = cpu_to_le32(1);
index b74bf436844187c32cce9cc31ecdce1031a1cc1e..e906b65448e2ed9da721f68056333eacf4386e98 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/quotaops.h>
 #include <linux/buffer_head.h>
 
+#include "group.h"
 /*
  * balloc.c contains the blocks allocation and deallocation routines
  */
@@ -42,6 +43,94 @@ void ext4_get_group_no_and_offset(struct super_block *sb, ext4_fsblk_t blocknr,
 
 }
 
+/* Initializes an uninitialized block bitmap if given, and returns the
+ * number of blocks free in the group. */
+unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
+                               int block_group, struct ext4_group_desc *gdp)
+{
+       unsigned long start;
+       int bit, bit_max;
+       unsigned free_blocks, group_blocks;
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+
+       if (bh) {
+               J_ASSERT_BH(bh, buffer_locked(bh));
+
+               /* If checksum is bad mark all blocks used to prevent allocation
+                * essentially implementing a per-group read-only flag. */
+               if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
+                       ext4_error(sb, __FUNCTION__,
+                                  "Checksum bad for group %u\n", block_group);
+                       gdp->bg_free_blocks_count = 0;
+                       gdp->bg_free_inodes_count = 0;
+                       gdp->bg_itable_unused = 0;
+                       memset(bh->b_data, 0xff, sb->s_blocksize);
+                       return 0;
+               }
+               memset(bh->b_data, 0, sb->s_blocksize);
+       }
+
+       /* Check for superblock and gdt backups in this group */
+       bit_max = ext4_bg_has_super(sb, block_group);
+
+       if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG) ||
+           block_group < le32_to_cpu(sbi->s_es->s_first_meta_bg) *
+                         sbi->s_desc_per_block) {
+               if (bit_max) {
+                       bit_max += ext4_bg_num_gdb(sb, block_group);
+                       bit_max +=
+                               le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks);
+               }
+       } else { /* For META_BG_BLOCK_GROUPS */
+               int group_rel = (block_group -
+                                le32_to_cpu(sbi->s_es->s_first_meta_bg)) %
+                               EXT4_DESC_PER_BLOCK(sb);
+               if (group_rel == 0 || group_rel == 1 ||
+                   (group_rel == EXT4_DESC_PER_BLOCK(sb) - 1))
+                       bit_max += 1;
+       }
+
+       if (block_group == sbi->s_groups_count - 1) {
+               /*
+                * Even though mke2fs always initialize first and last group
+                * if some other tool enabled the EXT4_BG_BLOCK_UNINIT we need
+                * to make sure we calculate the right free blocks
+                */
+               group_blocks = ext4_blocks_count(sbi->s_es) -
+                       le32_to_cpu(sbi->s_es->s_first_data_block) -
+                       (EXT4_BLOCKS_PER_GROUP(sb) * (sbi->s_groups_count -1));
+       } else {
+               group_blocks = EXT4_BLOCKS_PER_GROUP(sb);
+       }
+
+       free_blocks = group_blocks - bit_max;
+
+       if (bh) {
+               for (bit = 0; bit < bit_max; bit++)
+                       ext4_set_bit(bit, bh->b_data);
+
+               start = block_group * EXT4_BLOCKS_PER_GROUP(sb) +
+                       le32_to_cpu(sbi->s_es->s_first_data_block);
+
+               /* Set bits for block and inode bitmaps, and inode table */
+               ext4_set_bit(ext4_block_bitmap(sb, gdp) - start, bh->b_data);
+               ext4_set_bit(ext4_inode_bitmap(sb, gdp) - start, bh->b_data);
+               for (bit = (ext4_inode_table(sb, gdp) - start),
+                    bit_max = bit + sbi->s_itb_per_group; bit < bit_max; bit++)
+                       ext4_set_bit(bit, bh->b_data);
+
+               /*
+                * Also if the number of blocks within the group is
+                * less than the blocksize * 8 ( which is the size
+                * of bitmap ), set rest of the block bitmap to 1
+                */
+               mark_bitmap_end(group_blocks, sb->s_blocksize * 8, bh->b_data);
+       }
+
+       return free_blocks - sbi->s_itb_per_group - 2;
+}
+
+
 /*
  * The free blocks are managed by bitmaps.  A file system contains several
  * blocks groups.  Each group contains 1 bitmap block for blocks, 1 bitmap
@@ -119,7 +208,7 @@ block_in_use(ext4_fsblk_t block, struct super_block *sb, unsigned char *map)
  *
  * Return buffer_head on success or NULL in case of failure.
  */
-static struct buffer_head *
+struct buffer_head *
 read_block_bitmap(struct super_block *sb, unsigned int block_group)
 {
        int i;
@@ -127,11 +216,24 @@ read_block_bitmap(struct super_block *sb, unsigned int block_group)
        struct buffer_head * bh = NULL;
        ext4_fsblk_t bitmap_blk;
 
-       desc = ext4_get_group_desc (sb, block_group, NULL);
+       desc = ext4_get_group_desc(sb, block_group, NULL);
        if (!desc)
                return NULL;
        bitmap_blk = ext4_block_bitmap(sb, desc);
-       bh = sb_bread(sb, bitmap_blk);
+       if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
+               bh = sb_getblk(sb, bitmap_blk);
+               if (!buffer_uptodate(bh)) {
+                       lock_buffer(bh);
+                       if (!buffer_uptodate(bh)) {
+                               ext4_init_block_bitmap(sb, bh, block_group,
+                                                      desc);
+                               set_buffer_uptodate(bh);
+                       }
+                       unlock_buffer(bh);
+               }
+       } else {
+               bh = sb_bread(sb, bitmap_blk);
+       }
        if (!bh)
                ext4_error (sb, __FUNCTION__,
                            "Cannot read block bitmap - "
@@ -627,6 +729,7 @@ do_more:
        desc->bg_free_blocks_count =
                cpu_to_le16(le16_to_cpu(desc->bg_free_blocks_count) +
                        group_freed);
+       desc->bg_checksum = ext4_group_desc_csum(sbi, block_group, desc);
        spin_unlock(sb_bgl_lock(sbi, block_group));
        percpu_counter_add(&sbi->s_freeblocks_counter, count);
 
@@ -1685,8 +1788,11 @@ allocated:
                        ret_block, goal_hits, goal_attempts);
 
        spin_lock(sb_bgl_lock(sbi, group_no));
+       if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))
+               gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
        gdp->bg_free_blocks_count =
                        cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count)-num);
+       gdp->bg_checksum = ext4_group_desc_csum(sbi, group_no, gdp);
        spin_unlock(sb_bgl_lock(sbi, group_no));
        percpu_counter_sub(&sbi->s_freeblocks_counter, num);
 
index 0fb1e62b20d09e25d89c9cfbf00495212f051afe..f612bef983158f4a82c3d2a4b1211a94e713019a 100644 (file)
@@ -47,9 +47,7 @@ const struct file_operations ext4_dir_operations = {
        .compat_ioctl   = ext4_compat_ioctl,
 #endif
        .fsync          = ext4_sync_file,       /* BKL held */
-#ifdef CONFIG_EXT4_INDEX
        .release        = ext4_release_dir,
-#endif
 };
 
 
@@ -107,7 +105,6 @@ static int ext4_readdir(struct file * filp,
 
        sb = inode->i_sb;
 
-#ifdef CONFIG_EXT4_INDEX
        if (EXT4_HAS_COMPAT_FEATURE(inode->i_sb,
                                    EXT4_FEATURE_COMPAT_DIR_INDEX) &&
            ((EXT4_I(inode)->i_flags & EXT4_INDEX_FL) ||
@@ -123,7 +120,6 @@ static int ext4_readdir(struct file * filp,
                 */
                EXT4_I(filp->f_path.dentry->d_inode)->i_flags &= ~EXT4_INDEX_FL;
        }
-#endif
        stored = 0;
        offset = filp->f_pos & (sb->s_blocksize - 1);
 
@@ -232,7 +228,6 @@ out:
        return ret;
 }
 
-#ifdef CONFIG_EXT4_INDEX
 /*
  * These functions convert from the major/minor hash to an f_pos
  * value.
@@ -518,5 +513,3 @@ static int ext4_release_dir (struct inode * inode, struct file * filp)
 
        return 0;
 }
-
-#endif
index 78beb096f57dd616d39d294b681930c4959bfc89..85287742f2ae487562be3a8ac39e40774a5de9d3 100644 (file)
@@ -33,7 +33,7 @@
 #include <linux/fs.h>
 #include <linux/time.h>
 #include <linux/ext4_jbd2.h>
-#include <linux/jbd.h>
+#include <linux/jbd2.h>
 #include <linux/highuid.h>
 #include <linux/pagemap.h>
 #include <linux/quotaops.h>
@@ -52,7 +52,7 @@ static ext4_fsblk_t ext_pblock(struct ext4_extent *ex)
 {
        ext4_fsblk_t block;
 
-       block = le32_to_cpu(ex->ee_start);
+       block = le32_to_cpu(ex->ee_start_lo);
        block |= ((ext4_fsblk_t) le16_to_cpu(ex->ee_start_hi) << 31) << 1;
        return block;
 }
@@ -65,7 +65,7 @@ static ext4_fsblk_t idx_pblock(struct ext4_extent_idx *ix)
 {
        ext4_fsblk_t block;
 
-       block = le32_to_cpu(ix->ei_leaf);
+       block = le32_to_cpu(ix->ei_leaf_lo);
        block |= ((ext4_fsblk_t) le16_to_cpu(ix->ei_leaf_hi) << 31) << 1;
        return block;
 }
@@ -77,7 +77,7 @@ static ext4_fsblk_t idx_pblock(struct ext4_extent_idx *ix)
  */
 static void ext4_ext_store_pblock(struct ext4_extent *ex, ext4_fsblk_t pb)
 {
-       ex->ee_start = cpu_to_le32((unsigned long) (pb & 0xffffffff));
+       ex->ee_start_lo = cpu_to_le32((unsigned long) (pb & 0xffffffff));
        ex->ee_start_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff);
 }
 
@@ -88,7 +88,7 @@ static void ext4_ext_store_pblock(struct ext4_extent *ex, ext4_fsblk_t pb)
  */
 static void ext4_idx_store_pblock(struct ext4_extent_idx *ix, ext4_fsblk_t pb)
 {
-       ix->ei_leaf = cpu_to_le32((unsigned long) (pb & 0xffffffff));
+       ix->ei_leaf_lo = cpu_to_le32((unsigned long) (pb & 0xffffffff));
        ix->ei_leaf_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff);
 }
 
@@ -1409,8 +1409,7 @@ has_space:
        eh->eh_entries = cpu_to_le16(le16_to_cpu(eh->eh_entries)+1);
        nearex = path[depth].p_ext;
        nearex->ee_block = newext->ee_block;
-       nearex->ee_start = newext->ee_start;
-       nearex->ee_start_hi = newext->ee_start_hi;
+       ext4_ext_store_pblock(nearex, ext_pblock(newext));
        nearex->ee_len = newext->ee_len;
 
 merge:
@@ -2177,7 +2176,6 @@ int ext4_ext_convert_to_initialized(handle_t *handle, struct inode *inode,
        }
        /* ex2: iblock to iblock + maxblocks-1 : initialised */
        ex2->ee_block = cpu_to_le32(iblock);
-       ex2->ee_start = cpu_to_le32(newblock);
        ext4_ext_store_pblock(ex2, newblock);
        ex2->ee_len = cpu_to_le16(allocated);
        if (ex2 != ex)
index 2a167d7131fa38feec17d647bbbdefbb98b6b601..8d50879d1c2c68f23284314ff4fc7c5afe3c0a8e 100644 (file)
@@ -47,7 +47,7 @@ int ext4_sync_file(struct file * file, struct dentry *dentry, int datasync)
        struct inode *inode = dentry->d_inode;
        int ret = 0;
 
-       J_ASSERT(ext4_journal_current_handle() == 0);
+       J_ASSERT(ext4_journal_current_handle() == NULL);
 
        /*
         * data=writeback:
diff --git a/fs/ext4/group.h b/fs/ext4/group.h
new file mode 100644 (file)
index 0000000..1577910
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ *  linux/fs/ext4/group.h
+ *
+ * Copyright (C) 2007 Cluster File Systems, Inc
+ *
+ * Author: Andreas Dilger <adilger@clusterfs.com>
+ */
+
+#ifndef _LINUX_EXT4_GROUP_H
+#define _LINUX_EXT4_GROUP_H
+
+extern __le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 group,
+                                  struct ext4_group_desc *gdp);
+extern int ext4_group_desc_csum_verify(struct ext4_sb_info *sbi, __u32 group,
+                                      struct ext4_group_desc *gdp);
+struct buffer_head *read_block_bitmap(struct super_block *sb,
+                                     unsigned int block_group);
+extern unsigned ext4_init_block_bitmap(struct super_block *sb,
+                                      struct buffer_head *bh, int group,
+                                      struct ext4_group_desc *desc);
+#define ext4_free_blocks_after_init(sb, group, desc)                   \
+               ext4_init_block_bitmap(sb, NULL, group, desc)
+extern unsigned ext4_init_inode_bitmap(struct super_block *sb,
+                                      struct buffer_head *bh, int group,
+                                      struct ext4_group_desc *desc);
+extern void mark_bitmap_end(int start_bit, int end_bit, char *bitmap);
+#endif /* _LINUX_EXT4_GROUP_H */
index d0c7793d939395c2500def60e7aa01a680cf2704..c61f37fd3f05e4d72061791d79600024c858df97 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "xattr.h"
 #include "acl.h"
+#include "group.h"
 
 /*
  * ialloc.c contains the inodes allocation and deallocation routines
  * the free blocks count in the block.
  */
 
+/*
+ * To avoid calling the atomic setbit hundreds or thousands of times, we only
+ * need to use it within a single byte (to ensure we get endianness right).
+ * We can use memset for the rest of the bitmap as there are no other users.
+ */
+void mark_bitmap_end(int start_bit, int end_bit, char *bitmap)
+{
+       int i;
+
+       if (start_bit >= end_bit)
+               return;
+
+       ext4_debug("mark end bits +%d through +%d used\n", start_bit, end_bit);
+       for (i = start_bit; i < ((start_bit + 7) & ~7UL); i++)
+               ext4_set_bit(i, bitmap);
+       if (i < end_bit)
+               memset(bitmap + (i >> 3), 0xff, (end_bit - i) >> 3);
+}
+
+/* Initializes an uninitialized inode bitmap */
+unsigned ext4_init_inode_bitmap(struct super_block *sb,
+                               struct buffer_head *bh, int block_group,
+                               struct ext4_group_desc *gdp)
+{
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+
+       J_ASSERT_BH(bh, buffer_locked(bh));
+
+       /* If checksum is bad mark all blocks and inodes use to prevent
+        * allocation, essentially implementing a per-group read-only flag. */
+       if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
+               ext4_error(sb, __FUNCTION__, "Checksum bad for group %u\n",
+                          block_group);
+               gdp->bg_free_blocks_count = 0;
+               gdp->bg_free_inodes_count = 0;
+               gdp->bg_itable_unused = 0;
+               memset(bh->b_data, 0xff, sb->s_blocksize);
+               return 0;
+       }
+
+       memset(bh->b_data, 0, (EXT4_INODES_PER_GROUP(sb) + 7) / 8);
+       mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), EXT4_BLOCKS_PER_GROUP(sb),
+                       bh->b_data);
+
+       return EXT4_INODES_PER_GROUP(sb);
+}
 
 /*
  * Read the inode allocation bitmap for a given block_group, reading
@@ -59,8 +106,20 @@ read_inode_bitmap(struct super_block * sb, unsigned long block_group)
        desc = ext4_get_group_desc(sb, block_group, NULL);
        if (!desc)
                goto error_out;
-
-       bh = sb_bread(sb, ext4_inode_bitmap(sb, desc));
+       if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
+               bh = sb_getblk(sb, ext4_inode_bitmap(sb, desc));
+               if (!buffer_uptodate(bh)) {
+                       lock_buffer(bh);
+                       if (!buffer_uptodate(bh)) {
+                               ext4_init_inode_bitmap(sb, bh, block_group,
+                                                      desc);
+                               set_buffer_uptodate(bh);
+                       }
+                       unlock_buffer(bh);
+               }
+       } else {
+               bh = sb_bread(sb, ext4_inode_bitmap(sb, desc));
+       }
        if (!bh)
                ext4_error(sb, "read_inode_bitmap",
                            "Cannot read inode bitmap - "
@@ -169,6 +228,8 @@ void ext4_free_inode (handle_t *handle, struct inode * inode)
                        if (is_directory)
                                gdp->bg_used_dirs_count = cpu_to_le16(
                                  le16_to_cpu(gdp->bg_used_dirs_count) - 1);
+                       gdp->bg_checksum = ext4_group_desc_csum(sbi,
+                                                       block_group, gdp);
                        spin_unlock(sb_bgl_lock(sbi, block_group));
                        percpu_counter_inc(&sbi->s_freeinodes_counter);
                        if (is_directory)
@@ -435,7 +496,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode * dir, int mode)
        struct ext4_sb_info *sbi;
        int err = 0;
        struct inode *ret;
-       int i;
+       int i, free = 0;
 
        /* Cannot create files in a deleted directory */
        if (!dir || !dir->i_nlink)
@@ -517,11 +578,13 @@ repeat_in_this_group:
        goto out;
 
 got:
-       ino += group * EXT4_INODES_PER_GROUP(sb) + 1;
-       if (ino < EXT4_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) {
-               ext4_error (sb, "ext4_new_inode",
-                           "reserved inode or inode > inodes count - "
-                           "block_group = %d, inode=%lu", group, ino);
+       ino++;
+       if ((group == 0 && ino < EXT4_FIRST_INO(sb)) ||
+           ino > EXT4_INODES_PER_GROUP(sb)) {
+               ext4_error(sb, __FUNCTION__,
+                          "reserved inode or inode > inodes count - "
+                          "block_group = %d, inode=%lu", group,
+                          ino + group * EXT4_INODES_PER_GROUP(sb));
                err = -EIO;
                goto fail;
        }
@@ -529,13 +592,78 @@ got:
        BUFFER_TRACE(bh2, "get_write_access");
        err = ext4_journal_get_write_access(handle, bh2);
        if (err) goto fail;
+
+       /* We may have to initialize the block bitmap if it isn't already */
+       if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM) &&
+           gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
+               struct buffer_head *block_bh = read_block_bitmap(sb, group);
+
+               BUFFER_TRACE(block_bh, "get block bitmap access");
+               err = ext4_journal_get_write_access(handle, block_bh);
+               if (err) {
+                       brelse(block_bh);
+                       goto fail;
+               }
+
+               free = 0;
+               spin_lock(sb_bgl_lock(sbi, group));
+               /* recheck and clear flag under lock if we still need to */
+               if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
+                       gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
+                       free = ext4_free_blocks_after_init(sb, group, gdp);
+                       gdp->bg_free_blocks_count = cpu_to_le16(free);
+               }
+               spin_unlock(sb_bgl_lock(sbi, group));
+
+               /* Don't need to dirty bitmap block if we didn't change it */
+               if (free) {
+                       BUFFER_TRACE(block_bh, "dirty block bitmap");
+                       err = ext4_journal_dirty_metadata(handle, block_bh);
+               }
+
+               brelse(block_bh);
+               if (err)
+                       goto fail;
+       }
+
        spin_lock(sb_bgl_lock(sbi, group));
+       /* If we didn't allocate from within the initialized part of the inode
+        * table then we need to initialize up to this inode. */
+       if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
+               if (gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
+                       gdp->bg_flags &= cpu_to_le16(~EXT4_BG_INODE_UNINIT);
+
+                       /* When marking the block group with
+                        * ~EXT4_BG_INODE_UNINIT we don't want to depend
+                        * on the value of bg_itable_unsed even though
+                        * mke2fs could have initialized the same for us.
+                        * Instead we calculated the value below
+                        */
+
+                       free = 0;
+               } else {
+                       free = EXT4_INODES_PER_GROUP(sb) -
+                               le16_to_cpu(gdp->bg_itable_unused);
+               }
+
+               /*
+                * Check the relative inode number against the last used
+                * relative inode number in this group. if it is greater
+                * we need to  update the bg_itable_unused count
+                *
+                */
+               if (ino > free)
+                       gdp->bg_itable_unused =
+                               cpu_to_le16(EXT4_INODES_PER_GROUP(sb) - ino);
+       }
+
        gdp->bg_free_inodes_count =
                cpu_to_le16(le16_to_cpu(gdp->bg_free_inodes_count) - 1);
        if (S_ISDIR(mode)) {
                gdp->bg_used_dirs_count =
                        cpu_to_le16(le16_to_cpu(gdp->bg_used_dirs_count) + 1);
        }
+       gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp);
        spin_unlock(sb_bgl_lock(sbi, group));
        BUFFER_TRACE(bh2, "call ext4_journal_dirty_metadata");
        err = ext4_journal_dirty_metadata(handle, bh2);
@@ -557,7 +685,7 @@ got:
                inode->i_gid = current->fsgid;
        inode->i_mode = mode;
 
-       inode->i_ino = ino;
+       inode->i_ino = ino + group * EXT4_INODES_PER_GROUP(sb);
        /* This is the optimal IO size (for stat), not the fs block size */
        inode->i_blocks = 0;
        inode->i_mtime = inode->i_atime = inode->i_ctime = ei->i_crtime =
@@ -573,11 +701,6 @@ got:
        /* dirsync only applies to directories */
        if (!S_ISDIR(mode))
                ei->i_flags &= ~EXT4_DIRSYNC_FL;
-#ifdef EXT4_FRAGMENTS
-       ei->i_faddr = 0;
-       ei->i_frag_no = 0;
-       ei->i_frag_size = 0;
-#endif
        ei->i_file_acl = 0;
        ei->i_dir_acl = 0;
        ei->i_dtime = 0;
index 0df2b1e06d0b75be46a211b24085ea6485c7b7a6..5489703d95738ffb075ed7cb275aab94eb4d74e6 100644 (file)
@@ -1027,7 +1027,7 @@ struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode,
                }
                if (buffer_new(&dummy)) {
                        J_ASSERT(create != 0);
-                       J_ASSERT(handle != 0);
+                       J_ASSERT(handle != NULL);
 
                        /*
                         * Now that we do not always journal data, we should
@@ -2711,11 +2711,6 @@ void ext4_read_inode(struct inode * inode)
        }
        inode->i_blocks = le32_to_cpu(raw_inode->i_blocks);
        ei->i_flags = le32_to_cpu(raw_inode->i_flags);
-#ifdef EXT4_FRAGMENTS
-       ei->i_faddr = le32_to_cpu(raw_inode->i_faddr);
-       ei->i_frag_no = raw_inode->i_frag;
-       ei->i_frag_size = raw_inode->i_fsize;
-#endif
        ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl);
        if (EXT4_SB(inode->i_sb)->s_es->s_creator_os !=
            cpu_to_le32(EXT4_OS_HURD))
@@ -2860,11 +2855,6 @@ static int ext4_do_update_inode(handle_t *handle,
        raw_inode->i_blocks = cpu_to_le32(inode->i_blocks);
        raw_inode->i_dtime = cpu_to_le32(ei->i_dtime);
        raw_inode->i_flags = cpu_to_le32(ei->i_flags);
-#ifdef EXT4_FRAGMENTS
-       raw_inode->i_faddr = cpu_to_le32(ei->i_faddr);
-       raw_inode->i_frag = ei->i_frag_no;
-       raw_inode->i_fsize = ei->i_frag_size;
-#endif
        if (EXT4_SB(inode->i_sb)->s_es->s_creator_os !=
            cpu_to_le32(EXT4_OS_HURD))
                raw_inode->i_file_acl_high =
@@ -3243,12 +3233,14 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
                                                      iloc, handle);
                        if (ret) {
                                EXT4_I(inode)->i_state |= EXT4_STATE_NO_EXPAND;
-                               if (mnt_count != sbi->s_es->s_mnt_count) {
+                               if (mnt_count !=
+                                       le16_to_cpu(sbi->s_es->s_mnt_count)) {
                                        ext4_warning(inode->i_sb, __FUNCTION__,
                                        "Unable to expand inode %lu. Delete"
                                        " some EAs or run e2fsck.",
                                        inode->i_ino);
-                                       mnt_count = sbi->s_es->s_mnt_count;
+                                       mnt_count =
+                                         le16_to_cpu(sbi->s_es->s_mnt_count);
                                }
                        }
                }
index 5fdb862e71c47fb8df885e87e93090141227154a..94ee6f315dc17580c6de82f65d3f58735a29b870 100644 (file)
@@ -144,7 +144,6 @@ struct dx_map_entry
        u16 size;
 };
 
-#ifdef CONFIG_EXT4_INDEX
 static inline unsigned dx_get_block (struct dx_entry *entry);
 static void dx_set_block (struct dx_entry *entry, unsigned value);
 static inline unsigned dx_get_hash (struct dx_entry *entry);
@@ -766,8 +765,6 @@ static void dx_insert_block(struct dx_frame *frame, u32 hash, u32 block)
        dx_set_block(new, block);
        dx_set_count(entries, count + 1);
 }
-#endif
-
 
 static void ext4_update_dx_flag(struct inode *inode)
 {
@@ -869,7 +866,6 @@ static struct buffer_head * ext4_find_entry (struct dentry *dentry,
        name = dentry->d_name.name;
        if (namelen > EXT4_NAME_LEN)
                return NULL;
-#ifdef CONFIG_EXT4_INDEX
        if (is_dx(dir)) {
                bh = ext4_dx_find_entry(dentry, res_dir, &err);
                /*
@@ -881,7 +877,6 @@ static struct buffer_head * ext4_find_entry (struct dentry *dentry,
                        return bh;
                dxtrace(printk("ext4_find_entry: dx failed, falling back\n"));
        }
-#endif
        nblocks = dir->i_size >> EXT4_BLOCK_SIZE_BITS(sb);
        start = EXT4_I(dir)->i_dir_start_lookup;
        if (start >= nblocks)
@@ -957,7 +952,6 @@ cleanup_and_exit:
        return ret;
 }
 
-#ifdef CONFIG_EXT4_INDEX
 static struct buffer_head * ext4_dx_find_entry(struct dentry *dentry,
                       struct ext4_dir_entry_2 **res_dir, int *err)
 {
@@ -1025,7 +1019,6 @@ errout:
        dx_release (frames);
        return NULL;
 }
-#endif
 
 static struct dentry *ext4_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd)
 {
@@ -1121,7 +1114,6 @@ static inline void ext4_set_de_type(struct super_block *sb,
                de->file_type = ext4_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
 }
 
-#ifdef CONFIG_EXT4_INDEX
 /*
  * Move count entries from end of map between two memory locations.
  * Returns pointer to last entry moved.
@@ -1266,8 +1258,6 @@ errout:
        *error = err;
        return NULL;
 }
-#endif
-
 
 /*
  * Add a new entry into a directory (leaf) block.  If de is non-NULL,
@@ -1364,7 +1354,6 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
        return 0;
 }
 
-#ifdef CONFIG_EXT4_INDEX
 /*
  * This converts a one block unindexed directory to a 3 block indexed
  * directory, and adds the dentry to the indexed directory.
@@ -1443,7 +1432,6 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
 
        return add_dirent_to_buf(handle, dentry, inode, de, bh);
 }
-#endif
 
 /*
  *     ext4_add_entry()
@@ -1464,9 +1452,7 @@ static int ext4_add_entry (handle_t *handle, struct dentry *dentry,
        struct ext4_dir_entry_2 *de;
        struct super_block * sb;
        int     retval;
-#ifdef CONFIG_EXT4_INDEX
        int     dx_fallback=0;
-#endif
        unsigned blocksize;
        u32 block, blocks;
 
@@ -1474,7 +1460,6 @@ static int ext4_add_entry (handle_t *handle, struct dentry *dentry,
        blocksize = sb->s_blocksize;
        if (!dentry->d_name.len)
                return -EINVAL;
-#ifdef CONFIG_EXT4_INDEX
        if (is_dx(dir)) {
                retval = ext4_dx_add_entry(handle, dentry, inode);
                if (!retval || (retval != ERR_BAD_DX_DIR))
@@ -1483,7 +1468,6 @@ static int ext4_add_entry (handle_t *handle, struct dentry *dentry,
                dx_fallback++;
                ext4_mark_inode_dirty(handle, dir);
        }
-#endif
        blocks = dir->i_size >> sb->s_blocksize_bits;
        for (block = 0, offset = 0; block < blocks; block++) {
                bh = ext4_bread(handle, dir, block, 0, &retval);
@@ -1493,11 +1477,9 @@ static int ext4_add_entry (handle_t *handle, struct dentry *dentry,
                if (retval != -ENOSPC)
                        return retval;
 
-#ifdef CONFIG_EXT4_INDEX
                if (blocks == 1 && !dx_fallback &&
                    EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX))
                        return make_indexed_dir(handle, dentry, inode, bh);
-#endif
                brelse(bh);
        }
        bh = ext4_append(handle, dir, &block, &retval);
@@ -1509,7 +1491,6 @@ static int ext4_add_entry (handle_t *handle, struct dentry *dentry,
        return add_dirent_to_buf(handle, dentry, inode, de, bh);
 }
 
-#ifdef CONFIG_EXT4_INDEX
 /*
  * Returns 0 for success, or a negative error value
  */
@@ -1644,7 +1625,6 @@ cleanup:
        dx_release(frames);
        return err;
 }
-#endif
 
 /*
  * ext4_delete_entry deletes a directory entry by merging it with the
index 472fc0d3e1c0776de5e4594321e66b69795bd1ed..bd8a52bb39997576ab2d93e7f3c795262640503e 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/errno.h>
 #include <linux/slab.h>
 
+#include "group.h"
 
 #define outside(b, first, last)        ((b) < (first) || (b) >= (last))
 #define inside(b, first, last) ((b) >= (first) && (b) < (last))
@@ -140,22 +141,29 @@ static struct buffer_head *bclean(handle_t *handle, struct super_block *sb,
 }
 
 /*
- * To avoid calling the atomic setbit hundreds or thousands of times, we only
- * need to use it within a single byte (to ensure we get endianness right).
- * We can use memset for the rest of the bitmap as there are no other users.
+ * If we have fewer than thresh credits, extend by EXT4_MAX_TRANS_DATA.
+ * If that fails, restart the transaction & regain write access for the
+ * buffer head which is used for block_bitmap modifications.
  */
-static void mark_bitmap_end(int start_bit, int end_bit, char *bitmap)
+static int extend_or_restart_transaction(handle_t *handle, int thresh,
+                                        struct buffer_head *bh)
 {
-       int i;
+       int err;
+
+       if (handle->h_buffer_credits >= thresh)
+               return 0;
 
-       if (start_bit >= end_bit)
-               return;
+       err = ext4_journal_extend(handle, EXT4_MAX_TRANS_DATA);
+       if (err < 0)
+               return err;
+       if (err) {
+               if ((err = ext4_journal_restart(handle, EXT4_MAX_TRANS_DATA)))
+                       return err;
+               if ((err = ext4_journal_get_write_access(handle, bh)))
+                       return err;
+        }
 
-       ext4_debug("mark end bits +%d through +%d used\n", start_bit, end_bit);
-       for (i = start_bit; i < ((start_bit + 7) & ~7UL); i++)
-               ext4_set_bit(i, bitmap);
-       if (i < end_bit)
-               memset(bitmap + (i >> 3), 0xff, (end_bit - i) >> 3);
+       return 0;
 }
 
 /*
@@ -180,8 +188,9 @@ static int setup_new_group_blocks(struct super_block *sb,
        int i;
        int err = 0, err2;
 
-       handle = ext4_journal_start_sb(sb, reserved_gdb + gdblocks +
-                                      2 + sbi->s_itb_per_group);
+       /* This transaction may be extended/restarted along the way */
+       handle = ext4_journal_start_sb(sb, EXT4_MAX_TRANS_DATA);
+
        if (IS_ERR(handle))
                return PTR_ERR(handle);
 
@@ -208,6 +217,9 @@ static int setup_new_group_blocks(struct super_block *sb,
 
                ext4_debug("update backup group %#04lx (+%d)\n", block, bit);
 
+               if ((err = extend_or_restart_transaction(handle, 1, bh)))
+                       goto exit_bh;
+
                gdb = sb_getblk(sb, block);
                if (!gdb) {
                        err = -EIO;
@@ -217,10 +229,10 @@ static int setup_new_group_blocks(struct super_block *sb,
                        brelse(gdb);
                        goto exit_bh;
                }
-               lock_buffer(bh);
-               memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, bh->b_size);
+               lock_buffer(gdb);
+               memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, gdb->b_size);
                set_buffer_uptodate(gdb);
-               unlock_buffer(bh);
+               unlock_buffer(gdb);
                ext4_journal_dirty_metadata(handle, gdb);
                ext4_set_bit(bit, bh->b_data);
                brelse(gdb);
@@ -233,6 +245,9 @@ static int setup_new_group_blocks(struct super_block *sb,
 
                ext4_debug("clear reserved block %#04lx (+%d)\n", block, bit);
 
+               if ((err = extend_or_restart_transaction(handle, 1, bh)))
+                       goto exit_bh;
+
                if (IS_ERR(gdb = bclean(handle, sb, block))) {
                        err = PTR_ERR(bh);
                        goto exit_bh;
@@ -254,6 +269,10 @@ static int setup_new_group_blocks(struct super_block *sb,
                struct buffer_head *it;
 
                ext4_debug("clear inode block %#04lx (+%d)\n", block, bit);
+
+               if ((err = extend_or_restart_transaction(handle, 1, bh)))
+                       goto exit_bh;
+
                if (IS_ERR(it = bclean(handle, sb, block))) {
                        err = PTR_ERR(it);
                        goto exit_bh;
@@ -262,6 +281,10 @@ static int setup_new_group_blocks(struct super_block *sb,
                brelse(it);
                ext4_set_bit(bit, bh->b_data);
        }
+
+       if ((err = extend_or_restart_transaction(handle, 2, bh)))
+               goto exit_bh;
+
        mark_bitmap_end(input->blocks_count, EXT4_BLOCKS_PER_GROUP(sb),
                        bh->b_data);
        ext4_journal_dirty_metadata(handle, bh);
@@ -289,7 +312,6 @@ exit_journal:
        return err;
 }
 
-
 /*
  * Iterate through the groups which hold BACKUP superblock/GDT copies in an
  * ext4 filesystem.  The counters should be initialized to 1, 5, and 7 before
@@ -842,6 +864,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
        ext4_inode_table_set(sb, gdp, input->inode_table); /* LV FIXME */
        gdp->bg_free_blocks_count = cpu_to_le16(input->free_blocks_count);
        gdp->bg_free_inodes_count = cpu_to_le16(EXT4_INODES_PER_GROUP(sb));
+       gdp->bg_checksum = ext4_group_desc_csum(sbi, input->group, gdp);
 
        /*
         * Make the new blocks and inodes valid next.  We do this before
index 4c8d31c6145442e3236aa9785b2b6889100bdcad..8031dc0e24e5d7eccc2f984a9ac92d24e97c40d2 100644 (file)
 #include <linux/quotaops.h>
 #include <linux/seq_file.h>
 #include <linux/log2.h>
+#include <linux/crc16.h>
 
 #include <asm/uaccess.h>
 
 #include "xattr.h"
 #include "acl.h"
 #include "namei.h"
+#include "group.h"
 
 static int ext4_load_journal(struct super_block *, struct ext4_super_block *,
                             unsigned long journal_devnum);
@@ -68,31 +70,31 @@ static void ext4_write_super_lockfs(struct super_block *sb);
 ext4_fsblk_t ext4_block_bitmap(struct super_block *sb,
                               struct ext4_group_desc *bg)
 {
-       return le32_to_cpu(bg->bg_block_bitmap) |
+       return le32_to_cpu(bg->bg_block_bitmap_lo) |
                (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
-                (ext4_fsblk_t)le32_to_cpu(bg->bg_block_bitmap_hi) << 32 : 0);
+               (ext4_fsblk_t)le32_to_cpu(bg->bg_block_bitmap_hi) << 32 : 0);
 }
 
 ext4_fsblk_t ext4_inode_bitmap(struct super_block *sb,
                               struct ext4_group_desc *bg)
 {
-       return le32_to_cpu(bg->bg_inode_bitmap) |
+       return le32_to_cpu(bg->bg_inode_bitmap_lo) |
                (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
-                (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_bitmap_hi) << 32 : 0);
+               (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_bitmap_hi) << 32 : 0);
 }
 
 ext4_fsblk_t ext4_inode_table(struct super_block *sb,
                              struct ext4_group_desc *bg)
 {
-       return le32_to_cpu(bg->bg_inode_table) |
+       return le32_to_cpu(bg->bg_inode_table_lo) |
                (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
-                (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_table_hi) << 32 : 0);
+               (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_table_hi) << 32 : 0);
 }
 
 void ext4_block_bitmap_set(struct super_block *sb,
                           struct ext4_group_desc *bg, ext4_fsblk_t blk)
 {
-       bg->bg_block_bitmap = cpu_to_le32((u32)blk);
+       bg->bg_block_bitmap_lo = cpu_to_le32((u32)blk);
        if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
                bg->bg_block_bitmap_hi = cpu_to_le32(blk >> 32);
 }
@@ -100,7 +102,7 @@ void ext4_block_bitmap_set(struct super_block *sb,
 void ext4_inode_bitmap_set(struct super_block *sb,
                           struct ext4_group_desc *bg, ext4_fsblk_t blk)
 {
-       bg->bg_inode_bitmap  = cpu_to_le32((u32)blk);
+       bg->bg_inode_bitmap_lo  = cpu_to_le32((u32)blk);
        if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
                bg->bg_inode_bitmap_hi = cpu_to_le32(blk >> 32);
 }
@@ -108,7 +110,7 @@ void ext4_inode_bitmap_set(struct super_block *sb,
 void ext4_inode_table_set(struct super_block *sb,
                          struct ext4_group_desc *bg, ext4_fsblk_t blk)
 {
-       bg->bg_inode_table = cpu_to_le32((u32)blk);
+       bg->bg_inode_table_lo = cpu_to_le32((u32)blk);
        if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
                bg->bg_inode_table_hi = cpu_to_le32(blk >> 32);
 }
@@ -684,13 +686,10 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs)
 }
 
 
-static struct dentry *ext4_get_dentry(struct super_block *sb, void *vobjp)
+static struct inode *ext4_nfs_get_inode(struct super_block *sb,
+               u64 ino, u32 generation)
 {
-       __u32 *objp = vobjp;
-       unsigned long ino = objp[0];
-       __u32 generation = objp[1];
        struct inode *inode;
-       struct dentry *result;
 
        if (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO)
                return ERR_PTR(-ESTALE);
@@ -713,15 +712,22 @@ static struct dentry *ext4_get_dentry(struct super_block *sb, void *vobjp)
                iput(inode);
                return ERR_PTR(-ESTALE);
        }
-       /* now to find a dentry.
-        * If possible, get a well-connected one
-        */
-       result = d_alloc_anon(inode);
-       if (!result) {
-               iput(inode);
-               return ERR_PTR(-ENOMEM);
-       }
-       return result;
+
+       return inode;
+}
+
+static struct dentry *ext4_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,
+                                   ext4_nfs_get_inode);
+}
+
+static struct dentry *ext4_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,
+                                   ext4_nfs_get_inode);
 }
 
 #ifdef CONFIG_QUOTA
@@ -790,9 +796,10 @@ static const struct super_operations ext4_sops = {
 #endif
 };
 
-static struct export_operations ext4_export_ops = {
+static const struct export_operations ext4_export_ops = {
+       .fh_to_dentry = ext4_fh_to_dentry,
+       .fh_to_parent = ext4_fh_to_parent,
        .get_parent = ext4_get_parent,
-       .get_dentry = ext4_get_dentry,
 };
 
 enum {
@@ -1037,7 +1044,7 @@ static int parse_options (char *options, struct super_block *sb,
                        if (option < 0)
                                return 0;
                        if (option == 0)
-                               option = JBD_DEFAULT_MAX_COMMIT_AGE;
+                               option = JBD2_DEFAULT_MAX_COMMIT_AGE;
                        sbi->s_commit_interval = HZ * option;
                        break;
                case Opt_data_journal:
@@ -1308,6 +1315,43 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es,
        return res;
 }
 
+__le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 block_group,
+                           struct ext4_group_desc *gdp)
+{
+       __u16 crc = 0;
+
+       if (sbi->s_es->s_feature_ro_compat &
+           cpu_to_le32(EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
+               int offset = offsetof(struct ext4_group_desc, bg_checksum);
+               __le32 le_group = cpu_to_le32(block_group);
+
+               crc = crc16(~0, sbi->s_es->s_uuid, sizeof(sbi->s_es->s_uuid));
+               crc = crc16(crc, (__u8 *)&le_group, sizeof(le_group));
+               crc = crc16(crc, (__u8 *)gdp, offset);
+               offset += sizeof(gdp->bg_checksum); /* skip checksum */
+               /* for checksum of struct ext4_group_desc do the rest...*/
+               if ((sbi->s_es->s_feature_incompat &
+                    cpu_to_le32(EXT4_FEATURE_INCOMPAT_64BIT)) &&
+                   offset < le16_to_cpu(sbi->s_es->s_desc_size))
+                       crc = crc16(crc, (__u8 *)gdp + offset,
+                                   le16_to_cpu(sbi->s_es->s_desc_size) -
+                                       offset);
+       }
+
+       return cpu_to_le16(crc);
+}
+
+int ext4_group_desc_csum_verify(struct ext4_sb_info *sbi, __u32 block_group,
+                               struct ext4_group_desc *gdp)
+{
+       if ((sbi->s_es->s_feature_ro_compat &
+            cpu_to_le32(EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) &&
+           (gdp->bg_checksum != ext4_group_desc_csum(sbi, block_group, gdp)))
+               return 0;
+
+       return 1;
+}
+
 /* Called at mount-time, super-block is locked */
 static int ext4_check_descriptors (struct super_block * sb)
 {
@@ -1319,13 +1363,17 @@ static int ext4_check_descriptors (struct super_block * sb)
        ext4_fsblk_t inode_table;
        struct ext4_group_desc * gdp = NULL;
        int desc_block = 0;
+       int flexbg_flag = 0;
        int i;
 
+       if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG))
+               flexbg_flag = 1;
+
        ext4_debug ("Checking group descriptors");
 
        for (i = 0; i < sbi->s_groups_count; i++)
        {
-               if (i == sbi->s_groups_count - 1)
+               if (i == sbi->s_groups_count - 1 || flexbg_flag)
                        last_block = ext4_blocks_count(sbi->s_es) - 1;
                else
                        last_block = first_block +
@@ -1362,7 +1410,16 @@ static int ext4_check_descriptors (struct super_block * sb)
                                    i, inode_table);
                        return 0;
                }
-               first_block += EXT4_BLOCKS_PER_GROUP(sb);
+               if (!ext4_group_desc_csum_verify(sbi, i, gdp)) {
+                       ext4_error(sb, __FUNCTION__,
+                                  "Checksum for group %d failed (%u!=%u)\n", i,
+                                  le16_to_cpu(ext4_group_desc_csum(sbi, i,
+                                                                   gdp)),
+                                  le16_to_cpu(gdp->bg_checksum));
+                       return 0;
+               }
+               if (!flexbg_flag)
+                       first_block += EXT4_BLOCKS_PER_GROUP(sb);
                gdp = (struct ext4_group_desc *)
                        ((__u8 *)gdp + EXT4_DESC_SIZE(sb));
        }
@@ -1726,14 +1783,6 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
                if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE)
                        sb->s_time_gran = 1 << (EXT4_EPOCH_BITS - 2);
        }
-       sbi->s_frag_size = EXT4_MIN_FRAG_SIZE <<
-                                  le32_to_cpu(es->s_log_frag_size);
-       if (blocksize != sbi->s_frag_size) {
-               printk(KERN_ERR
-                      "EXT4-fs: fragsize %lu != blocksize %u (unsupported)\n",
-                      sbi->s_frag_size, blocksize);
-               goto failed_mount;
-       }
        sbi->s_desc_size = le16_to_cpu(es->s_desc_size);
        if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_64BIT)) {
                if (sbi->s_desc_size < EXT4_MIN_DESC_SIZE_64BIT ||
@@ -1747,7 +1796,6 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
        } else
                sbi->s_desc_size = EXT4_MIN_DESC_SIZE;
        sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group);
-       sbi->s_frags_per_group = le32_to_cpu(es->s_frags_per_group);
        sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group);
        if (EXT4_INODE_SIZE(sb) == 0)
                goto cantfind_ext4;
@@ -1771,12 +1819,6 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
                        sbi->s_blocks_per_group);
                goto failed_mount;
        }
-       if (sbi->s_frags_per_group > blocksize * 8) {
-               printk (KERN_ERR
-                       "EXT4-fs: #fragments per group too big: %lu\n",
-                       sbi->s_frags_per_group);
-               goto failed_mount;
-       }
        if (sbi->s_inodes_per_group > blocksize * 8) {
                printk (KERN_ERR
                        "EXT4-fs: #inodes per group too big: %lu\n",
@@ -2630,7 +2672,7 @@ static int ext4_statfs (struct dentry * dentry, struct kstatfs * buf)
 
        if (test_opt(sb, MINIX_DF)) {
                sbi->s_overhead_last = 0;
-       } else if (sbi->s_blocks_last != le32_to_cpu(es->s_blocks_count)) {
+       } else if (sbi->s_blocks_last != ext4_blocks_count(es)) {
                unsigned long ngroups = sbi->s_groups_count, i;
                ext4_fsblk_t overhead = 0;
                smp_rmb();
@@ -2665,14 +2707,14 @@ static int ext4_statfs (struct dentry * dentry, struct kstatfs * buf)
                overhead += ngroups * (2 + sbi->s_itb_per_group);
                sbi->s_overhead_last = overhead;
                smp_wmb();
-               sbi->s_blocks_last = le32_to_cpu(es->s_blocks_count);
+               sbi->s_blocks_last = ext4_blocks_count(es);
        }
 
        buf->f_type = EXT4_SUPER_MAGIC;
        buf->f_bsize = sb->s_blocksize;
        buf->f_blocks = ext4_blocks_count(es) - sbi->s_overhead_last;
        buf->f_bfree = percpu_counter_sum_positive(&sbi->s_freeblocks_counter);
-       es->s_free_blocks_count = cpu_to_le32(buf->f_bfree);
+       ext4_free_blocks_count_set(es, buf->f_bfree);
        buf->f_bavail = buf->f_bfree - ext4_r_blocks_count(es);
        if (buf->f_bfree < ext4_r_blocks_count(es))
                buf->f_bavail = 0;
index b10d68fffb551d7b70b8797bfcd41b6de3bfaed4..86387302c2a9b45591e71c8e6900fdde92c09eaf 100644 (file)
@@ -750,12 +750,11 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
                }
        } else {
                /* Allocate a buffer where we construct the new block. */
-               s->base = kmalloc(sb->s_blocksize, GFP_KERNEL);
+               s->base = kzalloc(sb->s_blocksize, GFP_KERNEL);
                /* assert(header == s->base) */
                error = -ENOMEM;
                if (s->base == NULL)
                        goto cleanup;
-               memset(s->base, 0, sb->s_blocksize);
                header(s->base)->h_magic = cpu_to_le32(EXT4_XATTR_MAGIC);
                header(s->base)->h_blocks = cpu_to_le32(1);
                header(s->base)->h_refcount = cpu_to_le32(1);
@@ -1121,7 +1120,7 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
        int total_ino, total_blk;
        void *base, *start, *end;
        int extra_isize = 0, error = 0, tried_min_extra_isize = 0;
-       int s_min_extra_isize = EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize;
+       int s_min_extra_isize = le16_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize);
 
        down_write(&EXT4_I(inode)->xattr_sem);
 retry:
@@ -1293,7 +1292,7 @@ retry:
 
                i.name = b_entry_name;
                i.value = buffer;
-               i.value_len = cpu_to_le32(size);
+               i.value_len = size;
                error = ext4_xattr_block_find(inode, &i, bs);
                if (error)
                        goto cleanup;
index c0c5e9c55b588c37264deb5be91bb42c64d1f2a0..920a576e1c25e26240c8ed583cbdfce7e4452e4e 100644 (file)
@@ -653,24 +653,15 @@ static const struct super_operations fat_sops = {
  * of i_logstart is used to store the directory entry offset.
  */
 
-static struct dentry *
-fat_decode_fh(struct super_block *sb, __u32 *fh, int len, int fhtype,
-             int (*acceptable)(void *context, struct dentry *de),
-             void *context)
-{
-       if (fhtype != 3)
-               return ERR_PTR(-ESTALE);
-       if (len < 5)
-               return ERR_PTR(-ESTALE);
-
-       return sb->s_export_op->find_exported_dentry(sb, fh, NULL, acceptable, context);
-}
-
-static struct dentry *fat_get_dentry(struct super_block *sb, void *inump)
+static struct dentry *fat_fh_to_dentry(struct super_block *sb,
+               struct fid *fid, int fh_len, int fh_type)
 {
        struct inode *inode = NULL;
        struct dentry *result;
-       __u32 *fh = inump;
+       u32 *fh = fid->raw;
+
+       if (fh_len < 5 || fh_type != 3)
+               return NULL;
 
        inode = iget(sb, fh[0]);
        if (!inode || is_bad_inode(inode) || inode->i_generation != fh[1]) {
@@ -783,10 +774,9 @@ out:
        return parent;
 }
 
-static struct export_operations fat_export_ops = {
-       .decode_fh      = fat_decode_fh,
+static const struct export_operations fat_export_ops = {
        .encode_fh      = fat_encode_fh,
-       .get_dentry     = fat_get_dentry,
+       .fh_to_dentry   = fat_fh_to_dentry,
        .get_parent     = fat_get_parent,
 };
 
index c9db73fc5e3d2d2e137bab66724d4c91f3d7544c..8685263ccc4a7aa51d6666136c285687393bfabb 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/ptrace.h>
 #include <linux/signal.h>
 #include <linux/rcupdate.h>
+#include <linux/pid_namespace.h>
 
 #include <asm/poll.h>
 #include <asm/siginfo.h>
@@ -292,7 +293,7 @@ int f_setown(struct file *filp, unsigned long arg, int force)
                who = -who;
        }
        rcu_read_lock();
-       pid = find_pid(who);
+       pid = find_vpid(who);
        result = __f_setown(filp, pid, type, force);
        rcu_read_unlock();
        return result;
@@ -308,7 +309,7 @@ pid_t f_getown(struct file *filp)
 {
        pid_t pid;
        read_lock(&filp->f_owner.lock);
-       pid = pid_nr(filp->f_owner.pid);
+       pid = pid_nr_ns(filp->f_owner.pid, current->nsproxy->pid_ns);
        if (filp->f_owner.pid_type == PIDTYPE_PGID)
                pid = -pid;
        read_unlock(&filp->f_owner.lock);
index 3176fefc92e139771a9c9065524c26e8e437e7fa..664e3f2309b89811b028603da0f17a6e266ee9fd 100644 (file)
@@ -323,12 +323,11 @@ void file_kill(struct file *file)
 
 int fs_may_remount_ro(struct super_block *sb)
 {
-       struct list_head *p;
+       struct file *file;
 
        /* Check that no files are currently opened for writing. */
        file_list_lock();
-       list_for_each(p, &sb->s_files) {
-               struct file *file = list_entry(p, struct file, f_u.fu_list);
+       list_for_each_entry(file, &sb->s_files, f_u.fu_list) {
                struct inode *inode = file->f_path.dentry->d_inode;
 
                /* File with pending delete? */
index 686734ff973d947f6f393d2e5fe14427040e978c..0fca82021d7652df2d2fc8e1b1f33204e8712651 100644 (file)
@@ -89,7 +89,7 @@ void __mark_inode_dirty(struct inode *inode, int flags)
                if (inode->i_ino || strcmp(inode->i_sb->s_id, "bdev"))
                        printk(KERN_DEBUG
                               "%s(%d): dirtied inode %lu (%s) on %s\n",
-                              current->comm, current->pid, inode->i_ino,
+                              current->comm, task_pid_nr(current), inode->i_ino,
                               name, inode->i_sb->s_id);
        }
 
index d1acab931330ba8744058482c1ff5a50e753c62d..3763757f9fe704f088aa83810289929a33b17ad7 100644 (file)
@@ -63,13 +63,21 @@ static u64 time_to_jiffies(unsigned long sec, unsigned long nsec)
  * Set dentry and possibly attribute timeouts from the lookup/mk*
  * replies
  */
-static void fuse_change_timeout(struct dentry *entry, struct fuse_entry_out *o)
+static void fuse_change_entry_timeout(struct dentry *entry,
+                                     struct fuse_entry_out *o)
 {
        fuse_dentry_settime(entry,
                time_to_jiffies(o->entry_valid, o->entry_valid_nsec));
-       if (entry->d_inode)
-               get_fuse_inode(entry->d_inode)->i_time =
-                       time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
+}
+
+static u64 attr_timeout(struct fuse_attr_out *o)
+{
+       return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
+}
+
+static u64 entry_attr_timeout(struct fuse_entry_out *o)
+{
+       return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
 }
 
 /*
@@ -108,13 +116,19 @@ static void fuse_lookup_init(struct fuse_req *req, struct inode *dir,
                             struct dentry *entry,
                             struct fuse_entry_out *outarg)
 {
+       struct fuse_conn *fc = get_fuse_conn(dir);
+
+       memset(outarg, 0, sizeof(struct fuse_entry_out));
        req->in.h.opcode = FUSE_LOOKUP;
        req->in.h.nodeid = get_node_id(dir);
        req->in.numargs = 1;
        req->in.args[0].size = entry->d_name.len + 1;
        req->in.args[0].value = entry->d_name.name;
        req->out.numargs = 1;
-       req->out.args[0].size = sizeof(struct fuse_entry_out);
+       if (fc->minor < 9)
+               req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
+       else
+               req->out.args[0].size = sizeof(struct fuse_entry_out);
        req->out.args[0].value = outarg;
 }
 
@@ -140,6 +154,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
                struct fuse_req *req;
                struct fuse_req *forget_req;
                struct dentry *parent;
+               u64 attr_version;
 
                /* For negative dentries, always do a fresh lookup */
                if (!inode)
@@ -156,6 +171,10 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
                        return 0;
                }
 
+               spin_lock(&fc->lock);
+               attr_version = fc->attr_version;
+               spin_unlock(&fc->lock);
+
                parent = dget_parent(entry);
                fuse_lookup_init(req, parent->d_inode, entry, &outarg);
                request_send(fc, req);
@@ -180,8 +199,10 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
                if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
                        return 0;
 
-               fuse_change_attributes(inode, &outarg.attr);
-               fuse_change_timeout(entry, &outarg);
+               fuse_change_attributes(inode, &outarg.attr,
+                                      entry_attr_timeout(&outarg),
+                                      attr_version);
+               fuse_change_entry_timeout(entry, &outarg);
        }
        return 1;
 }
@@ -228,6 +249,7 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
        struct fuse_conn *fc = get_fuse_conn(dir);
        struct fuse_req *req;
        struct fuse_req *forget_req;
+       u64 attr_version;
 
        if (entry->d_name.len > FUSE_NAME_MAX)
                return ERR_PTR(-ENAMETOOLONG);
@@ -242,6 +264,10 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
                return ERR_PTR(PTR_ERR(forget_req));
        }
 
+       spin_lock(&fc->lock);
+       attr_version = fc->attr_version;
+       spin_unlock(&fc->lock);
+
        fuse_lookup_init(req, dir, entry, &outarg);
        request_send(fc, req);
        err = req->out.h.error;
@@ -253,7 +279,8 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
                err = -EIO;
        if (!err && outarg.nodeid) {
                inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
-                                 &outarg.attr);
+                                 &outarg.attr, entry_attr_timeout(&outarg),
+                                 attr_version);
                if (!inode) {
                        fuse_send_forget(fc, forget_req, outarg.nodeid, 1);
                        return ERR_PTR(-ENOMEM);
@@ -276,7 +303,7 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
 
        entry->d_op = &fuse_dentry_operations;
        if (!err)
-               fuse_change_timeout(entry, &outarg);
+               fuse_change_entry_timeout(entry, &outarg);
        else
                fuse_invalidate_entry_cache(entry);
        return NULL;
@@ -335,6 +362,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
 
        flags &= ~O_NOCTTY;
        memset(&inarg, 0, sizeof(inarg));
+       memset(&outentry, 0, sizeof(outentry));
        inarg.flags = flags;
        inarg.mode = mode;
        req->in.h.opcode = FUSE_CREATE;
@@ -345,7 +373,10 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
        req->in.args[1].size = entry->d_name.len + 1;
        req->in.args[1].value = entry->d_name.name;
        req->out.numargs = 2;
-       req->out.args[0].size = sizeof(outentry);
+       if (fc->minor < 9)
+               req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
+       else
+               req->out.args[0].size = sizeof(outentry);
        req->out.args[0].value = &outentry;
        req->out.args[1].size = sizeof(outopen);
        req->out.args[1].value = &outopen;
@@ -363,7 +394,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
 
        fuse_put_request(fc, req);
        inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
-                         &outentry.attr);
+                         &outentry.attr, entry_attr_timeout(&outentry), 0);
        if (!inode) {
                flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
                ff->fh = outopen.fh;
@@ -373,7 +404,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
        }
        fuse_put_request(fc, forget_req);
        d_instantiate(entry, inode);
-       fuse_change_timeout(entry, &outentry);
+       fuse_change_entry_timeout(entry, &outentry);
        file = lookup_instantiate_filp(nd, entry, generic_file_open);
        if (IS_ERR(file)) {
                ff->fh = outopen.fh;
@@ -410,9 +441,13 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
                return PTR_ERR(forget_req);
        }
 
+       memset(&outarg, 0, sizeof(outarg));
        req->in.h.nodeid = get_node_id(dir);
        req->out.numargs = 1;
-       req->out.args[0].size = sizeof(outarg);
+       if (fc->minor < 9)
+               req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
+       else
+               req->out.args[0].size = sizeof(outarg);
        req->out.args[0].value = &outarg;
        request_send(fc, req);
        err = req->out.h.error;
@@ -428,7 +463,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
                goto out_put_forget_req;
 
        inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
-                         &outarg.attr);
+                         &outarg.attr, entry_attr_timeout(&outarg), 0);
        if (!inode) {
                fuse_send_forget(fc, forget_req, outarg.nodeid, 1);
                return -ENOMEM;
@@ -451,7 +486,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
        } else
                d_instantiate(entry, inode);
 
-       fuse_change_timeout(entry, &outarg);
+       fuse_change_entry_timeout(entry, &outarg);
        fuse_invalidate_attr(dir);
        return 0;
 
@@ -663,51 +698,83 @@ static int fuse_link(struct dentry *entry, struct inode *newdir,
        return err;
 }
 
-static int fuse_do_getattr(struct inode *inode)
+static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
+                         struct kstat *stat)
+{
+       stat->dev = inode->i_sb->s_dev;
+       stat->ino = attr->ino;
+       stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
+       stat->nlink = attr->nlink;
+       stat->uid = attr->uid;
+       stat->gid = attr->gid;
+       stat->rdev = inode->i_rdev;
+       stat->atime.tv_sec = attr->atime;
+       stat->atime.tv_nsec = attr->atimensec;
+       stat->mtime.tv_sec = attr->mtime;
+       stat->mtime.tv_nsec = attr->mtimensec;
+       stat->ctime.tv_sec = attr->ctime;
+       stat->ctime.tv_nsec = attr->ctimensec;
+       stat->size = attr->size;
+       stat->blocks = attr->blocks;
+       stat->blksize = (1 << inode->i_blkbits);
+}
+
+static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
+                          struct file *file)
 {
        int err;
-       struct fuse_attr_out arg;
+       struct fuse_getattr_in inarg;
+       struct fuse_attr_out outarg;
        struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_req *req = fuse_get_req(fc);
+       struct fuse_req *req;
+       u64 attr_version;
+
+       req = fuse_get_req(fc);
        if (IS_ERR(req))
                return PTR_ERR(req);
 
+       spin_lock(&fc->lock);
+       attr_version = fc->attr_version;
+       spin_unlock(&fc->lock);
+
+       memset(&inarg, 0, sizeof(inarg));
+       memset(&outarg, 0, sizeof(outarg));
+       /* Directories have separate file-handle space */
+       if (file && S_ISREG(inode->i_mode)) {
+               struct fuse_file *ff = file->private_data;
+
+               inarg.getattr_flags |= FUSE_GETATTR_FH;
+               inarg.fh = ff->fh;
+       }
        req->in.h.opcode = FUSE_GETATTR;
        req->in.h.nodeid = get_node_id(inode);
+       req->in.numargs = 1;
+       req->in.args[0].size = sizeof(inarg);
+       req->in.args[0].value = &inarg;
        req->out.numargs = 1;
-       req->out.args[0].size = sizeof(arg);
-       req->out.args[0].value = &arg;
+       if (fc->minor < 9)
+               req->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
+       else
+               req->out.args[0].size = sizeof(outarg);
+       req->out.args[0].value = &outarg;
        request_send(fc, req);
        err = req->out.h.error;
        fuse_put_request(fc, req);
        if (!err) {
-               if ((inode->i_mode ^ arg.attr.mode) & S_IFMT) {
+               if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
                        make_bad_inode(inode);
                        err = -EIO;
                } else {
-                       struct fuse_inode *fi = get_fuse_inode(inode);
-                       fuse_change_attributes(inode, &arg.attr);
-                       fi->i_time = time_to_jiffies(arg.attr_valid,
-                                                    arg.attr_valid_nsec);
+                       fuse_change_attributes(inode, &outarg.attr,
+                                              attr_timeout(&outarg),
+                                              attr_version);
+                       if (stat)
+                               fuse_fillattr(inode, &outarg.attr, stat);
                }
        }
        return err;
 }
 
-/*
- * Check if attributes are still valid, and if not send a GETATTR
- * request to refresh them.
- */
-static int fuse_refresh_attributes(struct inode *inode)
-{
-       struct fuse_inode *fi = get_fuse_inode(inode);
-
-       if (fi->i_time < get_jiffies_64())
-               return fuse_do_getattr(inode);
-       else
-               return 0;
-}
-
 /*
  * Calling into a user-controlled filesystem gives the filesystem
  * daemon ptrace-like capabilities over the requester process.  This
@@ -721,7 +788,7 @@ static int fuse_refresh_attributes(struct inode *inode)
  * for which the owner of the mount has ptrace privilege.  This
  * excludes processes started by other users, suid or sgid processes.
  */
-static int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task)
+int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task)
 {
        if (fc->flags & FUSE_ALLOW_OTHER)
                return 1;
@@ -795,11 +862,14 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
         */
        if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) ||
            ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
-               err = fuse_refresh_attributes(inode);
-               if (err)
-                       return err;
+               struct fuse_inode *fi = get_fuse_inode(inode);
+               if (fi->i_time < get_jiffies_64()) {
+                       err = fuse_do_getattr(inode, NULL, NULL);
+                       if (err)
+                               return err;
 
-               refreshed = true;
+                       refreshed = true;
+               }
        }
 
        if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
@@ -809,7 +879,7 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
                   attributes.  This is also needed, because the root
                   node will at first have no permissions */
                if (err == -EACCES && !refreshed) {
-                       err = fuse_do_getattr(inode);
+                       err = fuse_do_getattr(inode, NULL, NULL);
                        if (!err)
                                err = generic_permission(inode, mask, NULL);
                }
@@ -825,7 +895,7 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
                        if (refreshed)
                                return -EACCES;
 
-                       err = fuse_do_getattr(inode);
+                       err = fuse_do_getattr(inode, NULL, NULL);
                        if (!err && !(inode->i_mode & S_IXUGO))
                                return -EACCES;
                }
@@ -962,6 +1032,20 @@ static int fuse_dir_fsync(struct file *file, struct dentry *de, int datasync)
        return file ? fuse_fsync_common(file, de, datasync, 1) : 0;
 }
 
+static bool update_mtime(unsigned ivalid)
+{
+       /* Always update if mtime is explicitly set  */
+       if (ivalid & ATTR_MTIME_SET)
+               return true;
+
+       /* If it's an open(O_TRUNC) or an ftruncate(), don't update */
+       if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE)))
+               return false;
+
+       /* In all other cases update */
+       return true;
+}
+
 static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
 {
        unsigned ivalid = iattr->ia_valid;
@@ -974,16 +1058,19 @@ static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
                arg->valid |= FATTR_GID,    arg->gid = iattr->ia_gid;
        if (ivalid & ATTR_SIZE)
                arg->valid |= FATTR_SIZE,   arg->size = iattr->ia_size;
-       /* You can only _set_ these together (they may change by themselves) */
-       if ((ivalid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME)) {
-               arg->valid |= FATTR_ATIME | FATTR_MTIME;
+       if (ivalid & ATTR_ATIME) {
+               arg->valid |= FATTR_ATIME;
                arg->atime = iattr->ia_atime.tv_sec;
-               arg->mtime = iattr->ia_mtime.tv_sec;
+               arg->atimensec = iattr->ia_atime.tv_nsec;
+               if (!(ivalid & ATTR_ATIME_SET))
+                       arg->valid |= FATTR_ATIME_NOW;
        }
-       if (ivalid & ATTR_FILE) {
-               struct fuse_file *ff = iattr->ia_file->private_data;
-               arg->valid |= FATTR_FH;
-               arg->fh = ff->fh;
+       if ((ivalid & ATTR_MTIME) && update_mtime(ivalid)) {
+               arg->valid |= FATTR_MTIME;
+               arg->mtime = iattr->ia_mtime.tv_sec;
+               arg->mtimensec = iattr->ia_mtime.tv_nsec;
+               if (!(ivalid & ATTR_MTIME_SET))
+                       arg->valid |= FATTR_MTIME_NOW;
        }
 }
 
@@ -995,22 +1082,28 @@ static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
  * vmtruncate() doesn't allow for this case, so do the rlimit checking
  * and the actual truncation by hand.
  */
-static int fuse_setattr(struct dentry *entry, struct iattr *attr)
+static int fuse_do_setattr(struct dentry *entry, struct iattr *attr,
+                          struct file *file)
 {
        struct inode *inode = entry->d_inode;
        struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_inode *fi = get_fuse_inode(inode);
        struct fuse_req *req;
        struct fuse_setattr_in inarg;
        struct fuse_attr_out outarg;
        int err;
 
+       if (!fuse_allow_task(fc, current))
+               return -EACCES;
+
        if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
                err = inode_change_ok(inode, attr);
                if (err)
                        return err;
        }
 
+       if ((attr->ia_valid & ATTR_OPEN) && fc->atomic_o_trunc)
+               return 0;
+
        if (attr->ia_valid & ATTR_SIZE) {
                unsigned long limit;
                if (IS_SWAPFILE(inode))
@@ -1027,14 +1120,28 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
                return PTR_ERR(req);
 
        memset(&inarg, 0, sizeof(inarg));
+       memset(&outarg, 0, sizeof(outarg));
        iattr_to_fattr(attr, &inarg);
+       if (file) {
+               struct fuse_file *ff = file->private_data;
+               inarg.valid |= FATTR_FH;
+               inarg.fh = ff->fh;
+       }
+       if (attr->ia_valid & ATTR_SIZE) {
+               /* For mandatory locking in truncate */
+               inarg.valid |= FATTR_LOCKOWNER;
+               inarg.lock_owner = fuse_lock_owner_id(fc, current->files);
+       }
        req->in.h.opcode = FUSE_SETATTR;
        req->in.h.nodeid = get_node_id(inode);
        req->in.numargs = 1;
        req->in.args[0].size = sizeof(inarg);
        req->in.args[0].value = &inarg;
        req->out.numargs = 1;
-       req->out.args[0].size = sizeof(outarg);
+       if (fc->minor < 9)
+               req->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
+       else
+               req->out.args[0].size = sizeof(outarg);
        req->out.args[0].value = &outarg;
        request_send(fc, req);
        err = req->out.h.error;
@@ -1050,11 +1157,18 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
                return -EIO;
        }
 
-       fuse_change_attributes(inode, &outarg.attr);
-       fi->i_time = time_to_jiffies(outarg.attr_valid, outarg.attr_valid_nsec);
+       fuse_change_attributes(inode, &outarg.attr, attr_timeout(&outarg), 0);
        return 0;
 }
 
+static int fuse_setattr(struct dentry *entry, struct iattr *attr)
+{
+       if (attr->ia_valid & ATTR_FILE)
+               return fuse_do_setattr(entry, attr, attr->ia_file);
+       else
+               return fuse_do_setattr(entry, attr, NULL);
+}
+
 static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
                        struct kstat *stat)
 {
@@ -1066,8 +1180,10 @@ static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
        if (!fuse_allow_task(fc, current))
                return -EACCES;
 
-       err = fuse_refresh_attributes(inode);
-       if (!err) {
+       if (fi->i_time < get_jiffies_64())
+               err = fuse_do_getattr(inode, stat, NULL);
+       else {
+               err = 0;
                generic_fillattr(inode, stat);
                stat->mode = fi->orig_i_mode;
        }
@@ -1172,6 +1288,9 @@ static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
        struct fuse_getxattr_out outarg;
        ssize_t ret;
 
+       if (!fuse_allow_task(fc, current))
+               return -EACCES;
+
        if (fc->no_listxattr)
                return -EOPNOTSUPP;
 
index c4b98c03a46ef7c24761e70a723486067e3a9806..0fcdba9d47c090ba5b6dae59abfdc41897d5b7f1 100644 (file)
@@ -28,7 +28,9 @@ static int fuse_send_open(struct inode *inode, struct file *file, int isdir,
                return PTR_ERR(req);
 
        memset(&inarg, 0, sizeof(inarg));
-       inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
+       inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY);
+       if (!fc->atomic_o_trunc)
+               inarg.flags &= ~O_TRUNC;
        req->in.h.opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN;
        req->in.h.nodeid = get_node_id(inode);
        req->in.numargs = 1;
@@ -54,6 +56,7 @@ struct fuse_file *fuse_file_alloc(void)
                        kfree(ff);
                        ff = NULL;
                }
+               INIT_LIST_HEAD(&ff->write_entry);
                atomic_set(&ff->count, 0);
        }
        return ff;
@@ -148,12 +151,18 @@ int fuse_release_common(struct inode *inode, struct file *file, int isdir)
 {
        struct fuse_file *ff = file->private_data;
        if (ff) {
+               struct fuse_conn *fc = get_fuse_conn(inode);
+
                fuse_release_fill(ff, get_node_id(inode), file->f_flags,
                                  isdir ? FUSE_RELEASEDIR : FUSE_RELEASE);
 
                /* Hold vfsmount and dentry until release is finished */
                ff->reserved_req->vfsmount = mntget(file->f_path.mnt);
                ff->reserved_req->dentry = dget(file->f_path.dentry);
+
+               spin_lock(&fc->lock);
+               list_del(&ff->write_entry);
+               spin_unlock(&fc->lock);
                /*
                 * Normally this will send the RELEASE request,
                 * however if some asynchronous READ or WRITE requests
@@ -180,7 +189,7 @@ static int fuse_release(struct inode *inode, struct file *file)
  * Scramble the ID space with XTEA, so that the value of the files_struct
  * pointer is not exposed to userspace.
  */
-static u64 fuse_lock_owner_id(struct fuse_conn *fc, fl_owner_t id)
+u64 fuse_lock_owner_id(struct fuse_conn *fc, fl_owner_t id)
 {
        u32 *k = fc->scramble_key;
        u64 v = (unsigned long) id;
@@ -299,11 +308,19 @@ void fuse_read_fill(struct fuse_req *req, struct fuse_file *ff,
 }
 
 static size_t fuse_send_read(struct fuse_req *req, struct file *file,
-                            struct inode *inode, loff_t pos, size_t count)
+                            struct inode *inode, loff_t pos, size_t count,
+                            fl_owner_t owner)
 {
        struct fuse_conn *fc = get_fuse_conn(inode);
        struct fuse_file *ff = file->private_data;
+
        fuse_read_fill(req, ff, inode, pos, count, FUSE_READ);
+       if (owner != NULL) {
+               struct fuse_read_in *inarg = &req->misc.read_in;
+
+               inarg->read_flags |= FUSE_READ_LOCKOWNER;
+               inarg->lock_owner = fuse_lock_owner_id(fc, owner);
+       }
        request_send(fc, req);
        return req->out.args[0].size;
 }
@@ -327,7 +344,8 @@ static int fuse_readpage(struct file *file, struct page *page)
        req->out.page_zeroing = 1;
        req->num_pages = 1;
        req->pages[0] = page;
-       fuse_send_read(req, file, inode, page_offset(page), PAGE_CACHE_SIZE);
+       fuse_send_read(req, file, inode, page_offset(page), PAGE_CACHE_SIZE,
+                      NULL);
        err = req->out.h.error;
        fuse_put_request(fc, req);
        if (!err)
@@ -434,30 +452,47 @@ out:
        return err;
 }
 
-static size_t fuse_send_write(struct fuse_req *req, struct file *file,
-                             struct inode *inode, loff_t pos, size_t count)
+static void fuse_write_fill(struct fuse_req *req, struct fuse_file *ff,
+                           struct inode *inode, loff_t pos, size_t count,
+                           int writepage)
 {
        struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_file *ff = file->private_data;
-       struct fuse_write_in inarg;
-       struct fuse_write_out outarg;
+       struct fuse_write_in *inarg = &req->misc.write.in;
+       struct fuse_write_out *outarg = &req->misc.write.out;
 
-       memset(&inarg, 0, sizeof(struct fuse_write_in));
-       inarg.fh = ff->fh;
-       inarg.offset = pos;
-       inarg.size = count;
+       memset(inarg, 0, sizeof(struct fuse_write_in));
+       inarg->fh = ff->fh;
+       inarg->offset = pos;
+       inarg->size = count;
+       inarg->write_flags = writepage ? FUSE_WRITE_CACHE : 0;
        req->in.h.opcode = FUSE_WRITE;
        req->in.h.nodeid = get_node_id(inode);
        req->in.argpages = 1;
        req->in.numargs = 2;
-       req->in.args[0].size = sizeof(struct fuse_write_in);
-       req->in.args[0].value = &inarg;
+       if (fc->minor < 9)
+               req->in.args[0].size = FUSE_COMPAT_WRITE_IN_SIZE;
+       else
+               req->in.args[0].size = sizeof(struct fuse_write_in);
+       req->in.args[0].value = inarg;
        req->in.args[1].size = count;
        req->out.numargs = 1;
        req->out.args[0].size = sizeof(struct fuse_write_out);
-       req->out.args[0].value = &outarg;
+       req->out.args[0].value = outarg;
+}
+
+static size_t fuse_send_write(struct fuse_req *req, struct file *file,
+                             struct inode *inode, loff_t pos, size_t count,
+                             fl_owner_t owner)
+{
+       struct fuse_conn *fc = get_fuse_conn(inode);
+       fuse_write_fill(req, file->private_data, inode, pos, count, 0);
+       if (owner != NULL) {
+               struct fuse_write_in *inarg = &req->misc.write.in;
+               inarg->write_flags |= FUSE_WRITE_LOCKOWNER;
+               inarg->lock_owner = fuse_lock_owner_id(fc, owner);
+       }
        request_send(fc, req);
-       return outarg.size;
+       return req->misc.write.out.size;
 }
 
 static int fuse_write_begin(struct file *file, struct address_space *mapping,
@@ -478,6 +513,7 @@ static int fuse_buffered_write(struct file *file, struct inode *inode,
        int err;
        size_t nres;
        struct fuse_conn *fc = get_fuse_conn(inode);
+       struct fuse_inode *fi = get_fuse_inode(inode);
        unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
        struct fuse_req *req;
 
@@ -491,7 +527,7 @@ static int fuse_buffered_write(struct file *file, struct inode *inode,
        req->num_pages = 1;
        req->pages[0] = page;
        req->page_offset = offset;
-       nres = fuse_send_write(req, file, inode, pos, count);
+       nres = fuse_send_write(req, file, inode, pos, count, NULL);
        err = req->out.h.error;
        fuse_put_request(fc, req);
        if (!err && !nres)
@@ -499,6 +535,7 @@ static int fuse_buffered_write(struct file *file, struct inode *inode,
        if (!err) {
                pos += nres;
                spin_lock(&fc->lock);
+               fi->attr_version = ++fc->attr_version;
                if (pos > inode->i_size)
                        i_size_write(inode, pos);
                spin_unlock(&fc->lock);
@@ -591,9 +628,11 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf,
                nbytes = (req->num_pages << PAGE_SHIFT) - req->page_offset;
                nbytes = min(count, nbytes);
                if (write)
-                       nres = fuse_send_write(req, file, inode, pos, nbytes);
+                       nres = fuse_send_write(req, file, inode, pos, nbytes,
+                                              current->files);
                else
-                       nres = fuse_send_read(req, file, inode, pos, nbytes);
+                       nres = fuse_send_read(req, file, inode, pos, nbytes,
+                                             current->files);
                fuse_release_user_pages(req, !write);
                if (req->out.h.error) {
                        if (!res)
@@ -695,7 +734,8 @@ static int convert_fuse_file_lock(const struct fuse_file_lock *ffl,
 }
 
 static void fuse_lk_fill(struct fuse_req *req, struct file *file,
-                        const struct file_lock *fl, int opcode, pid_t pid)
+                        const struct file_lock *fl, int opcode, pid_t pid,
+                        int flock)
 {
        struct inode *inode = file->f_path.dentry->d_inode;
        struct fuse_conn *fc = get_fuse_conn(inode);
@@ -708,6 +748,8 @@ static void fuse_lk_fill(struct fuse_req *req, struct file *file,
        arg->lk.end = fl->fl_end;
        arg->lk.type = fl->fl_type;
        arg->lk.pid = pid;
+       if (flock)
+               arg->lk_flags |= FUSE_LK_FLOCK;
        req->in.h.opcode = opcode;
        req->in.h.nodeid = get_node_id(inode);
        req->in.numargs = 1;
@@ -727,7 +769,7 @@ static int fuse_getlk(struct file *file, struct file_lock *fl)
        if (IS_ERR(req))
                return PTR_ERR(req);
 
-       fuse_lk_fill(req, file, fl, FUSE_GETLK, 0);
+       fuse_lk_fill(req, file, fl, FUSE_GETLK, 0, 0);
        req->out.numargs = 1;
        req->out.args[0].size = sizeof(outarg);
        req->out.args[0].value = &outarg;
@@ -740,7 +782,7 @@ static int fuse_getlk(struct file *file, struct file_lock *fl)
        return err;
 }
 
-static int fuse_setlk(struct file *file, struct file_lock *fl)
+static int fuse_setlk(struct file *file, struct file_lock *fl, int flock)
 {
        struct inode *inode = file->f_path.dentry->d_inode;
        struct fuse_conn *fc = get_fuse_conn(inode);
@@ -757,7 +799,7 @@ static int fuse_setlk(struct file *file, struct file_lock *fl)
        if (IS_ERR(req))
                return PTR_ERR(req);
 
-       fuse_lk_fill(req, file, fl, opcode, pid);
+       fuse_lk_fill(req, file, fl, opcode, pid, flock);
        request_send(fc, req);
        err = req->out.h.error;
        /* locking is restartable */
@@ -783,8 +825,25 @@ static int fuse_file_lock(struct file *file, int cmd, struct file_lock *fl)
                if (fc->no_lock)
                        err = posix_lock_file_wait(file, fl);
                else
-                       err = fuse_setlk(file, fl);
+                       err = fuse_setlk(file, fl, 0);
+       }
+       return err;
+}
+
+static int fuse_file_flock(struct file *file, int cmd, struct file_lock *fl)
+{
+       struct inode *inode = file->f_path.dentry->d_inode;
+       struct fuse_conn *fc = get_fuse_conn(inode);
+       int err;
+
+       if (fc->no_lock) {
+               err = flock_lock_file_wait(file, fl);
+       } else {
+               /* emulate flock with POSIX locks */
+               fl->fl_owner = (fl_owner_t) file;
+               err = fuse_setlk(file, fl, 1);
        }
+
        return err;
 }
 
@@ -836,6 +895,7 @@ static const struct file_operations fuse_file_operations = {
        .release        = fuse_release,
        .fsync          = fuse_fsync,
        .lock           = fuse_file_lock,
+       .flock          = fuse_file_flock,
        .splice_read    = generic_file_splice_read,
 };
 
@@ -848,6 +908,7 @@ static const struct file_operations fuse_direct_io_file_operations = {
        .release        = fuse_release,
        .fsync          = fuse_fsync,
        .lock           = fuse_file_lock,
+       .flock          = fuse_file_flock,
        /* no mmap and splice_read */
 };
 
index 1764506fdd11bc4da0e89a658c9a0bbdaa2a51b0..6c5461de1a5fd5c4cbbf806fddb6d12a948841fa 100644 (file)
@@ -67,6 +67,12 @@ struct fuse_inode {
        /** The sticky bit in inode->i_mode may have been removed, so
            preserve the original mode */
        mode_t orig_i_mode;
+
+       /** Version of last attribute change */
+       u64 attr_version;
+
+       /** Files usable in writepage.  Protected by fc->lock */
+       struct list_head write_files;
 };
 
 /** FUSE specific file data */
@@ -79,6 +85,9 @@ struct fuse_file {
 
        /** Refcount */
        atomic_t count;
+
+       /** Entry on inode's write_files list */
+       struct list_head write_entry;
 };
 
 /** One input argument of a request */
@@ -210,6 +219,10 @@ struct fuse_req {
                struct fuse_init_in init_in;
                struct fuse_init_out init_out;
                struct fuse_read_in read_in;
+               struct {
+                       struct fuse_write_in in;
+                       struct fuse_write_out out;
+               } write;
                struct fuse_lk_in lk_in;
        } misc;
 
@@ -317,6 +330,9 @@ struct fuse_conn {
        /** Do readpages asynchronously?  Only set in INIT */
        unsigned async_read : 1;
 
+       /** Do not send separate SETATTR request before open(O_TRUNC)  */
+       unsigned atomic_o_trunc : 1;
+
        /*
         * The following bitfields are only for optimization purposes
         * and hence races in setting them will not cause malfunction
@@ -387,6 +403,9 @@ struct fuse_conn {
 
        /** Reserved request for the DESTROY message */
        struct fuse_req *destroy_req;
+
+       /** Version counter for attribute changes */
+       u64 attr_version;
 };
 
 static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb)
@@ -416,7 +435,8 @@ extern const struct file_operations fuse_dev_operations;
  * Get a filled in inode
  */
 struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
-                       int generation, struct fuse_attr *attr);
+                       int generation, struct fuse_attr *attr,
+                       u64 attr_valid, u64 attr_version);
 
 /**
  * Send FORGET command
@@ -477,7 +497,8 @@ void fuse_init_symlink(struct inode *inode);
 /**
  * Change attributes of an inode
  */
-void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr);
+void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
+                           u64 attr_valid, u64 attr_version);
 
 /**
  * Initialize the client device
@@ -565,3 +586,10 @@ void fuse_ctl_remove_conn(struct fuse_conn *fc);
  * Is file type valid?
  */
 int fuse_valid_type(int m);
+
+/**
+ * Is task allowed to perform filesystem operation?
+ */
+int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task);
+
+u64 fuse_lock_owner_id(struct fuse_conn *fc, fl_owner_t id);
index fd0735715c14e7f1943c905cb104f101fac73139..9a68d69708457c5ecd387895e77cba73e51e7efb 100644 (file)
@@ -56,6 +56,7 @@ static struct inode *fuse_alloc_inode(struct super_block *sb)
        fi->i_time = 0;
        fi->nodeid = 0;
        fi->nlookup = 0;
+       INIT_LIST_HEAD(&fi->write_files);
        fi->forget_req = fuse_request_alloc();
        if (!fi->forget_req) {
                kmem_cache_free(fuse_inode_cachep, inode);
@@ -68,6 +69,7 @@ static struct inode *fuse_alloc_inode(struct super_block *sb)
 static void fuse_destroy_inode(struct inode *inode)
 {
        struct fuse_inode *fi = get_fuse_inode(inode);
+       BUG_ON(!list_empty(&fi->write_files));
        if (fi->forget_req)
                fuse_request_free(fi->forget_req);
        kmem_cache_free(fuse_inode_cachep, inode);
@@ -117,12 +119,22 @@ static void fuse_truncate(struct address_space *mapping, loff_t offset)
        unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
 }
 
-void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr)
+
+void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
+                           u64 attr_valid, u64 attr_version)
 {
        struct fuse_conn *fc = get_fuse_conn(inode);
        struct fuse_inode *fi = get_fuse_inode(inode);
        loff_t oldsize;
 
+       spin_lock(&fc->lock);
+       if (attr_version != 0 && fi->attr_version > attr_version) {
+               spin_unlock(&fc->lock);
+               return;
+       }
+       fi->attr_version = ++fc->attr_version;
+       fi->i_time = attr_valid;
+
        inode->i_ino     = attr->ino;
        inode->i_mode    = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
        inode->i_nlink   = attr->nlink;
@@ -136,6 +148,11 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr)
        inode->i_ctime.tv_sec   = attr->ctime;
        inode->i_ctime.tv_nsec  = attr->ctimensec;
 
+       if (attr->blksize != 0)
+               inode->i_blkbits = ilog2(attr->blksize);
+       else
+               inode->i_blkbits = inode->i_sb->s_blocksize_bits;
+
        /*
         * Don't set the sticky bit in i_mode, unless we want the VFS
         * to check permissions.  This prevents failures due to the
@@ -145,7 +162,6 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr)
        if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS))
                inode->i_mode &= ~S_ISVTX;
 
-       spin_lock(&fc->lock);
        oldsize = inode->i_size;
        i_size_write(inode, attr->size);
        spin_unlock(&fc->lock);
@@ -194,7 +210,8 @@ static int fuse_inode_set(struct inode *inode, void *_nodeidp)
 }
 
 struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
-                       int generation, struct fuse_attr *attr)
+                       int generation, struct fuse_attr *attr,
+                       u64 attr_valid, u64 attr_version)
 {
        struct inode *inode;
        struct fuse_inode *fi;
@@ -222,7 +239,8 @@ struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
        spin_lock(&fc->lock);
        fi->nlookup ++;
        spin_unlock(&fc->lock);
-       fuse_change_attributes(inode, attr);
+       fuse_change_attributes(inode, attr, attr_valid, attr_version);
+
        return inode;
 }
 
@@ -287,6 +305,11 @@ static int fuse_statfs(struct dentry *dentry, struct kstatfs *buf)
        struct fuse_statfs_out outarg;
        int err;
 
+       if (!fuse_allow_task(fc, current)) {
+               buf->f_type = FUSE_SUPER_MAGIC;
+               return 0;
+       }
+
        req = fuse_get_req(fc);
        if (IS_ERR(req))
                return PTR_ERR(req);
@@ -452,6 +475,7 @@ static struct fuse_conn *new_conn(void)
                }
                fc->reqctr = 0;
                fc->blocked = 1;
+               fc->attr_version = 1;
                get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key));
        }
 out:
@@ -483,7 +507,7 @@ static struct inode *get_root_inode(struct super_block *sb, unsigned mode)
        attr.mode = mode;
        attr.ino = FUSE_ROOT_ID;
        attr.nlink = 1;
-       return fuse_iget(sb, 1, 0, &attr);
+       return fuse_iget(sb, 1, 0, &attr, 0, 0);
 }
 
 static const struct super_operations fuse_super_operations = {
@@ -514,6 +538,8 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
                                fc->async_read = 1;
                        if (!(arg->flags & FUSE_POSIX_LOCKS))
                                fc->no_lock = 1;
+                       if (arg->flags & FUSE_ATOMIC_O_TRUNC)
+                               fc->atomic_o_trunc = 1;
                } else {
                        ra_pages = fc->max_read / PAGE_CACHE_SIZE;
                        fc->no_lock = 1;
@@ -536,7 +562,8 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req)
        arg->major = FUSE_KERNEL_VERSION;
        arg->minor = FUSE_KERNEL_MINOR_VERSION;
        arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE;
-       arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS;
+       arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_FILE_OPS |
+               FUSE_ATOMIC_O_TRUNC;
        req->in.h.opcode = FUSE_INIT;
        req->in.numargs = 1;
        req->in.args[0].size = sizeof(*arg);
index e2d1347796a9b391eff23d7ee592a4093c684f4f..b9da62348a877303a777884c35f08c2083e640d5 100644 (file)
 #define GFS2_LARGE_FH_SIZE 8
 #define GFS2_OLD_FH_SIZE 10
 
-static struct dentry *gfs2_decode_fh(struct super_block *sb,
-                                    __u32 *p,
-                                    int fh_len,
-                                    int fh_type,
-                                    int (*acceptable)(void *context,
-                                                      struct dentry *dentry),
-                                    void *context)
-{
-       __be32 *fh = (__force __be32 *)p;
-       struct gfs2_inum_host inum, parent;
-
-       memset(&parent, 0, sizeof(struct gfs2_inum));
-
-       switch (fh_len) {
-       case GFS2_LARGE_FH_SIZE:
-       case GFS2_OLD_FH_SIZE:
-               parent.no_formal_ino = ((u64)be32_to_cpu(fh[4])) << 32;
-               parent.no_formal_ino |= be32_to_cpu(fh[5]);
-               parent.no_addr = ((u64)be32_to_cpu(fh[6])) << 32;
-               parent.no_addr |= be32_to_cpu(fh[7]);
-       case GFS2_SMALL_FH_SIZE:
-               inum.no_formal_ino = ((u64)be32_to_cpu(fh[0])) << 32;
-               inum.no_formal_ino |= be32_to_cpu(fh[1]);
-               inum.no_addr = ((u64)be32_to_cpu(fh[2])) << 32;
-               inum.no_addr |= be32_to_cpu(fh[3]);
-               break;
-       default:
-               return NULL;
-       }
-
-       return gfs2_export_ops.find_exported_dentry(sb, &inum, &parent,
-                                                   acceptable, context);
-}
-
 static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len,
                          int connectable)
 {
@@ -189,10 +155,10 @@ static struct dentry *gfs2_get_parent(struct dentry *child)
        return dentry;
 }
 
-static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj)
+static struct dentry *gfs2_get_dentry(struct super_block *sb,
+               struct gfs2_inum_host *inum)
 {
        struct gfs2_sbd *sdp = sb->s_fs_info;
-       struct gfs2_inum_host *inum = inum_obj;
        struct gfs2_holder i_gh, ri_gh, rgd_gh;
        struct gfs2_rgrpd *rgd;
        struct inode *inode;
@@ -289,11 +255,50 @@ fail:
        return ERR_PTR(error);
 }
 
-struct export_operations gfs2_export_ops = {
-       .decode_fh = gfs2_decode_fh,
+static struct dentry *gfs2_fh_to_dentry(struct super_block *sb, struct fid *fid,
+               int fh_len, int fh_type)
+{
+       struct gfs2_inum_host this;
+       __be32 *fh = (__force __be32 *)fid->raw;
+
+       switch (fh_type) {
+       case GFS2_SMALL_FH_SIZE:
+       case GFS2_LARGE_FH_SIZE:
+       case GFS2_OLD_FH_SIZE:
+               this.no_formal_ino = ((u64)be32_to_cpu(fh[0])) << 32;
+               this.no_formal_ino |= be32_to_cpu(fh[1]);
+               this.no_addr = ((u64)be32_to_cpu(fh[2])) << 32;
+               this.no_addr |= be32_to_cpu(fh[3]);
+               return gfs2_get_dentry(sb, &this);
+       default:
+               return NULL;
+       }
+}
+
+static struct dentry *gfs2_fh_to_parent(struct super_block *sb, struct fid *fid,
+               int fh_len, int fh_type)
+{
+       struct gfs2_inum_host parent;
+       __be32 *fh = (__force __be32 *)fid->raw;
+
+       switch (fh_type) {
+       case GFS2_LARGE_FH_SIZE:
+       case GFS2_OLD_FH_SIZE:
+               parent.no_formal_ino = ((u64)be32_to_cpu(fh[4])) << 32;
+               parent.no_formal_ino |= be32_to_cpu(fh[5]);
+               parent.no_addr = ((u64)be32_to_cpu(fh[6])) << 32;
+               parent.no_addr |= be32_to_cpu(fh[7]);
+               return gfs2_get_dentry(sb, &parent);
+       default:
+               return NULL;
+       }
+}
+
+const struct export_operations gfs2_export_ops = {
        .encode_fh = gfs2_encode_fh,
+       .fh_to_dentry = gfs2_fh_to_dentry,
+       .fh_to_parent = gfs2_fh_to_parent,
        .get_name = gfs2_get_name,
        .get_parent = gfs2_get_parent,
-       .get_dentry = gfs2_get_dentry,
 };
 
index 407029b3b2b3857b6564126fe191d1bc96094c67..da849051183654131be35f18df854f30ad400437 100644 (file)
@@ -14,6 +14,6 @@
 
 extern struct file_system_type gfs2_fs_type;
 extern struct file_system_type gfs2meta_fs_type;
-extern struct export_operations gfs2_export_ops;
+extern const struct export_operations gfs2_export_ops;
 
 #endif /* __OPS_FSTYPE_DOT_H__ */
index 7457501b95656087cfe27339b94d3bace7585782..2c5b921528760b9da6d8abcc3f90668a8e9381d7 100644 (file)
@@ -666,6 +666,49 @@ out:
 }
 EXPORT_SYMBOL_GPL(inotify_add_watch);
 
+/**
+ * inotify_clone_watch - put the watch next to existing one
+ * @old: already installed watch
+ * @new: new watch
+ *
+ * Caller must hold the inotify_mutex of inode we are dealing with;
+ * it is expected to remove the old watch before unlocking the inode.
+ */
+s32 inotify_clone_watch(struct inotify_watch *old, struct inotify_watch *new)
+{
+       struct inotify_handle *ih = old->ih;
+       int ret = 0;
+
+       new->mask = old->mask;
+       new->ih = ih;
+
+       mutex_lock(&ih->mutex);
+
+       /* Initialize a new watch */
+       ret = inotify_handle_get_wd(ih, new);
+       if (unlikely(ret))
+               goto out;
+       ret = new->wd;
+
+       get_inotify_handle(ih);
+
+       new->inode = igrab(old->inode);
+
+       list_add(&new->h_list, &ih->watches);
+       list_add(&new->i_list, &old->inode->inotify_watches);
+out:
+       mutex_unlock(&ih->mutex);
+       return ret;
+}
+
+void inotify_evict_watch(struct inotify_watch *watch)
+{
+       get_inotify_watch(watch);
+       mutex_lock(&watch->ih->mutex);
+       inotify_remove_watch_locked(watch->ih, watch);
+       mutex_unlock(&watch->ih->mutex);
+}
+
 /**
  * inotify_rm_wd - remove a watch from an inotify instance
  * @ih: inotify handle
index 10d2c211d18b28414aa8b0f26dcfe489fa0ddfe9..d6ff77e8e7ec563b273bd94d2458ba89b1355cee 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/capability.h>
 #include <linux/syscalls.h>
 #include <linux/security.h>
+#include <linux/pid_namespace.h>
 
 static int set_task_ioprio(struct task_struct *task, int ioprio)
 {
@@ -93,7 +94,7 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
                        if (!who)
                                p = current;
                        else
-                               p = find_task_by_pid(who);
+                               p = find_task_by_vpid(who);
                        if (p)
                                ret = set_task_ioprio(p, ioprio);
                        break;
@@ -101,7 +102,7 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
                        if (!who)
                                pgrp = task_pgrp(current);
                        else
-                               pgrp = find_pid(who);
+                               pgrp = find_vpid(who);
                        do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
                                ret = set_task_ioprio(p, ioprio);
                                if (ret)
@@ -180,7 +181,7 @@ asmlinkage long sys_ioprio_get(int which, int who)
                        if (!who)
                                p = current;
                        else
-                               p = find_task_by_pid(who);
+                               p = find_task_by_vpid(who);
                        if (p)
                                ret = get_task_ioprio(p);
                        break;
@@ -188,7 +189,7 @@ asmlinkage long sys_ioprio_get(int which, int who)
                        if (!who)
                                pgrp = task_pgrp(current);
                        else
-                               pgrp = find_pid(who);
+                               pgrp = find_vpid(who);
                        do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
                                tmpio = get_task_ioprio(p);
                                if (tmpio < 0)
index 4af856a7fda7fd3f0fc97b86cccefa595c3d58db..29f9753ae5e5ba45c25eec7eaf26261ab6441b42 100644 (file)
@@ -42,16 +42,6 @@ isofs_export_iget(struct super_block *sb,
        return result;
 }
 
-static struct dentry *
-isofs_export_get_dentry(struct super_block *sb, void *vobjp)
-{
-       __u32 *objp = vobjp;
-       unsigned long block = objp[0];
-       unsigned long offset = objp[1];
-       __u32 generation = objp[2];
-       return isofs_export_iget(sb, block, offset, generation);
-}
-
 /* This function is surprisingly simple.  The trick is understanding
  * that "child" is always a directory. So, to find its parent, you
  * simply need to find its ".." entry, normalize its block and offset,
@@ -182,43 +172,44 @@ isofs_export_encode_fh(struct dentry *dentry,
        return type;
 }
 
+struct isofs_fid {
+       u32 block;
+       u16 offset;
+       u16 parent_offset;
+       u32 generation;
+       u32 parent_block;
+       u32 parent_generation;
+};
 
-static struct dentry *
-isofs_export_decode_fh(struct super_block *sb,
-                      __u32 *fh32,
-                      int fh_len,
-                      int fileid_type,
-                      int (*acceptable)(void *context, struct dentry *de),
-                      void *context)
+static struct dentry *isofs_fh_to_dentry(struct super_block *sb,
+       struct fid *fid, int fh_len, int fh_type)
 {
-       __u16 *fh16 = (__u16*)fh32;
-       __u32 child[3];   /* The child is what triggered all this. */
-       __u32 parent[3];  /* The parent is just along for the ride. */
+       struct isofs_fid *ifid = (struct isofs_fid *)fid;
 
-       if (fh_len < 3 || fileid_type > 2)
+       if (fh_len < 3 || fh_type > 2)
                return NULL;
 
-       child[0] = fh32[0];
-       child[1] = fh16[2];  /* fh16 [sic] */
-       child[2] = fh32[2];
-
-       parent[0] = 0;
-       parent[1] = 0;
-       parent[2] = 0;
-       if (fileid_type == 2) {
-               if (fh_len > 2) parent[0] = fh32[3];
-               parent[1] = fh16[3];  /* fh16 [sic] */
-               if (fh_len > 4) parent[2] = fh32[4];
-       }
-
-       return sb->s_export_op->find_exported_dentry(sb, child, parent,
-                                                    acceptable, context);
+       return isofs_export_iget(sb, ifid->block, ifid->offset,
+                       ifid->generation);
 }
 
+static struct dentry *isofs_fh_to_parent(struct super_block *sb,
+               struct fid *fid, int fh_len, int fh_type)
+{
+       struct isofs_fid *ifid = (struct isofs_fid *)fid;
+
+       if (fh_type != 2)
+               return NULL;
+
+       return isofs_export_iget(sb,
+                       fh_len > 2 ? ifid->parent_block : 0,
+                       ifid->parent_offset,
+                       fh_len > 4 ? ifid->parent_generation : 0);
+}
 
-struct export_operations isofs_export_ops = {
-       .decode_fh      = isofs_export_decode_fh,
+const struct export_operations isofs_export_ops = {
        .encode_fh      = isofs_export_encode_fh,
-       .get_dentry     = isofs_export_get_dentry,
+       .fh_to_dentry   = isofs_fh_to_dentry,
+       .fh_to_parent   = isofs_fh_to_parent,
        .get_parent     = isofs_export_get_parent,
 };
index aa359a2e4ce613cb49710e94f248846789fbde4f..09e3d306e96fb298518f50bac38d4ee697b4bf8c 100644 (file)
@@ -3,7 +3,7 @@
  *
  *  (C) 1991  Linus Torvalds - minix filesystem
  *      1992, 1993, 1994  Eric Youngdale Modified for ISO 9660 filesystem.
- *      1994  Eberhard Moenkeberg - multi session handling.
+ *      1994  Eberhard Mönkeberg - multi session handling.
  *      1995  Mark Dobie - allow mounting of some weird VideoCDs and PhotoCDs.
  *     1997  Gordon Chaffee - Joliet CDs
  *     1998  Eric Lammerts - ISO 9660 Level 3
index a07e67b1ea7fb4b6e49f375d6a71c1b5ec879c16..f3213f9f89afcfaa79f98fc9bb2a61f2165fca0f 100644 (file)
@@ -178,4 +178,4 @@ isofs_normalize_block_and_offset(struct iso_directory_record* de,
 extern const struct inode_operations isofs_dir_inode_operations;
 extern const struct file_operations isofs_dir_operations;
 extern const struct address_space_operations isofs_symlink_aops;
-extern struct export_operations isofs_export_ops;
+extern const struct export_operations isofs_export_ops;
index a003d50edcdbdc1fe45a7627e83191cd55df378c..8f1f2aa5fb39b2df5b744c2f7e495145cf1b2df8 100644 (file)
@@ -375,7 +375,7 @@ void journal_commit_transaction(journal_t *journal)
                        struct buffer_head *bh = jh2bh(jh);
 
                        jbd_lock_bh_state(bh);
-                       jbd_slab_free(jh->b_committed_data, bh->b_size);
+                       jbd_free(jh->b_committed_data, bh->b_size);
                        jh->b_committed_data = NULL;
                        jbd_unlock_bh_state(bh);
                }
@@ -466,7 +466,7 @@ void journal_commit_transaction(journal_t *journal)
        spin_unlock(&journal->j_list_lock);
 
        if (err)
-               __journal_abort_hard(journal);
+               journal_abort(journal, err);
 
        journal_write_revoke_records(journal, commit_transaction);
 
@@ -524,7 +524,7 @@ void journal_commit_transaction(journal_t *journal)
 
                        descriptor = journal_get_descriptor_buffer(journal);
                        if (!descriptor) {
-                               __journal_abort_hard(journal);
+                               journal_abort(journal, -EIO);
                                continue;
                        }
 
@@ -557,7 +557,7 @@ void journal_commit_transaction(journal_t *journal)
                   and repeat this loop: we'll fall into the
                   refile-on-abort condition above. */
                if (err) {
-                       __journal_abort_hard(journal);
+                       journal_abort(journal, err);
                        continue;
                }
 
@@ -748,7 +748,7 @@ wait_for_iobuf:
                err = -EIO;
 
        if (err)
-               __journal_abort_hard(journal);
+               journal_abort(journal, err);
 
        /* End of a transaction!  Finally, we can do checkpoint
            processing: any buffers committed as a result of this
@@ -792,14 +792,14 @@ restart_loop:
                 * Otherwise, we can just throw away the frozen data now.
                 */
                if (jh->b_committed_data) {
-                       jbd_slab_free(jh->b_committed_data, bh->b_size);
+                       jbd_free(jh->b_committed_data, bh->b_size);
                        jh->b_committed_data = NULL;
                        if (jh->b_frozen_data) {
                                jh->b_committed_data = jh->b_frozen_data;
                                jh->b_frozen_data = NULL;
                        }
                } else if (jh->b_frozen_data) {
-                       jbd_slab_free(jh->b_frozen_data, bh->b_size);
+                       jbd_free(jh->b_frozen_data, bh->b_size);
                        jh->b_frozen_data = NULL;
                }
 
index a6be78c05dce50420fdf1c08fad3cd80ac5120cd..5d14243499d47d117fa662620f34da9d3bd76ed8 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/kthread.h>
 #include <linux/poison.h>
 #include <linux/proc_fs.h>
+#include <linux/debugfs.h>
 
 #include <asm/uaccess.h>
 #include <asm/page.h>
@@ -83,7 +84,6 @@ EXPORT_SYMBOL(journal_force_commit);
 
 static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *);
 static void __journal_abort_soft (journal_t *journal, int errno);
-static int journal_create_jbd_slab(size_t slab_size);
 
 /*
  * Helper function used to manage commit timeouts
@@ -218,7 +218,7 @@ static int journal_start_thread(journal_t *journal)
        if (IS_ERR(t))
                return PTR_ERR(t);
 
-       wait_event(journal->j_wait_done_commit, journal->j_task != 0);
+       wait_event(journal->j_wait_done_commit, journal->j_task != NULL);
        return 0;
 }
 
@@ -230,7 +230,8 @@ static void journal_kill_thread(journal_t *journal)
        while (journal->j_task) {
                wake_up(&journal->j_wait_commit);
                spin_unlock(&journal->j_state_lock);
-               wait_event(journal->j_wait_done_commit, journal->j_task == 0);
+               wait_event(journal->j_wait_done_commit,
+                               journal->j_task == NULL);
                spin_lock(&journal->j_state_lock);
        }
        spin_unlock(&journal->j_state_lock);
@@ -334,10 +335,10 @@ repeat:
                char *tmp;
 
                jbd_unlock_bh_state(bh_in);
-               tmp = jbd_slab_alloc(bh_in->b_size, GFP_NOFS);
+               tmp = jbd_alloc(bh_in->b_size, GFP_NOFS);
                jbd_lock_bh_state(bh_in);
                if (jh_in->b_frozen_data) {
-                       jbd_slab_free(tmp, bh_in->b_size);
+                       jbd_free(tmp, bh_in->b_size);
                        goto repeat;
                }
 
@@ -654,10 +655,9 @@ static journal_t * journal_init_common (void)
        journal_t *journal;
        int err;
 
-       journal = jbd_kmalloc(sizeof(*journal), GFP_KERNEL);
+       journal = kzalloc(sizeof(*journal), GFP_KERNEL);
        if (!journal)
                goto fail;
-       memset(journal, 0, sizeof(*journal));
 
        init_waitqueue_head(&journal->j_wait_transaction_locked);
        init_waitqueue_head(&journal->j_wait_logspace);
@@ -1095,13 +1095,6 @@ int journal_load(journal_t *journal)
                }
        }
 
-       /*
-        * Create a slab for this blocksize
-        */
-       err = journal_create_jbd_slab(be32_to_cpu(sb->s_blocksize));
-       if (err)
-               return err;
-
        /* Let the recovery code check whether it needs to recover any
         * data from the journal. */
        if (journal_recover(journal))
@@ -1614,86 +1607,6 @@ int journal_blocks_per_page(struct inode *inode)
        return 1 << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits);
 }
 
-/*
- * Simple support for retrying memory allocations.  Introduced to help to
- * debug different VM deadlock avoidance strategies.
- */
-void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry)
-{
-       return kmalloc(size, flags | (retry ? __GFP_NOFAIL : 0));
-}
-
-/*
- * jbd slab management: create 1k, 2k, 4k, 8k slabs as needed
- * and allocate frozen and commit buffers from these slabs.
- *
- * Reason for doing this is to avoid, SLAB_DEBUG - since it could
- * cause bh to cross page boundary.
- */
-
-#define JBD_MAX_SLABS 5
-#define JBD_SLAB_INDEX(size)  (size >> 11)
-
-static struct kmem_cache *jbd_slab[JBD_MAX_SLABS];
-static const char *jbd_slab_names[JBD_MAX_SLABS] = {
-       "jbd_1k", "jbd_2k", "jbd_4k", NULL, "jbd_8k"
-};
-
-static void journal_destroy_jbd_slabs(void)
-{
-       int i;
-
-       for (i = 0; i < JBD_MAX_SLABS; i++) {
-               if (jbd_slab[i])
-                       kmem_cache_destroy(jbd_slab[i]);
-               jbd_slab[i] = NULL;
-       }
-}
-
-static int journal_create_jbd_slab(size_t slab_size)
-{
-       int i = JBD_SLAB_INDEX(slab_size);
-
-       BUG_ON(i >= JBD_MAX_SLABS);
-
-       /*
-        * Check if we already have a slab created for this size
-        */
-       if (jbd_slab[i])
-               return 0;
-
-       /*
-        * Create a slab and force alignment to be same as slabsize -
-        * this will make sure that allocations won't cross the page
-        * boundary.
-        */
-       jbd_slab[i] = kmem_cache_create(jbd_slab_names[i],
-                               slab_size, slab_size, 0, NULL);
-       if (!jbd_slab[i]) {
-               printk(KERN_EMERG "JBD: no memory for jbd_slab cache\n");
-               return -ENOMEM;
-       }
-       return 0;
-}
-
-void * jbd_slab_alloc(size_t size, gfp_t flags)
-{
-       int idx;
-
-       idx = JBD_SLAB_INDEX(size);
-       BUG_ON(jbd_slab[idx] == NULL);
-       return kmem_cache_alloc(jbd_slab[idx], flags | __GFP_NOFAIL);
-}
-
-void jbd_slab_free(void *ptr,  size_t size)
-{
-       int idx;
-
-       idx = JBD_SLAB_INDEX(size);
-       BUG_ON(jbd_slab[idx] == NULL);
-       kmem_cache_free(jbd_slab[idx], ptr);
-}
-
 /*
  * Journal_head storage management
  */
@@ -1739,14 +1652,14 @@ static struct journal_head *journal_alloc_journal_head(void)
        atomic_inc(&nr_journal_heads);
 #endif
        ret = kmem_cache_alloc(journal_head_cache, GFP_NOFS);
-       if (ret == 0) {
+       if (ret == NULL) {
                jbd_debug(1, "out of memory for journal_head\n");
                if (time_after(jiffies, last_warning + 5*HZ)) {
                        printk(KERN_NOTICE "ENOMEM in %s, retrying.\n",
                               __FUNCTION__);
                        last_warning = jiffies;
                }
-               while (ret == 0) {
+               while (ret == NULL) {
                        yield();
                        ret = kmem_cache_alloc(journal_head_cache, GFP_NOFS);
                }
@@ -1881,13 +1794,13 @@ static void __journal_remove_journal_head(struct buffer_head *bh)
                                printk(KERN_WARNING "%s: freeing "
                                                "b_frozen_data\n",
                                                __FUNCTION__);
-                               jbd_slab_free(jh->b_frozen_data, bh->b_size);
+                               jbd_free(jh->b_frozen_data, bh->b_size);
                        }
                        if (jh->b_committed_data) {
                                printk(KERN_WARNING "%s: freeing "
                                                "b_committed_data\n",
                                                __FUNCTION__);
-                               jbd_slab_free(jh->b_committed_data, bh->b_size);
+                               jbd_free(jh->b_committed_data, bh->b_size);
                        }
                        bh->b_private = NULL;
                        jh->b_bh = NULL;        /* debug, really */
@@ -1939,64 +1852,41 @@ void journal_put_journal_head(struct journal_head *jh)
 }
 
 /*
- * /proc tunables
+ * debugfs tunables
  */
-#if defined(CONFIG_JBD_DEBUG)
-int journal_enable_debug;
-EXPORT_SYMBOL(journal_enable_debug);
-#endif
+#ifdef CONFIG_JBD_DEBUG
 
-#if defined(CONFIG_JBD_DEBUG) && defined(CONFIG_PROC_FS)
+u8 journal_enable_debug __read_mostly;
+EXPORT_SYMBOL(journal_enable_debug);
 
-static struct proc_dir_entry *proc_jbd_debug;
+static struct dentry *jbd_debugfs_dir;
+static struct dentry *jbd_debug;
 
-static int read_jbd_debug(char *page, char **start, off_t off,
-                         int count, int *eof, void *data)
+static void __init jbd_create_debugfs_entry(void)
 {
-       int ret;
-
-       ret = sprintf(page + off, "%d\n", journal_enable_debug);
-       *eof = 1;
-       return ret;
+       jbd_debugfs_dir = debugfs_create_dir("jbd", NULL);
+       if (jbd_debugfs_dir)
+               jbd_debug = debugfs_create_u8("jbd-debug", S_IRUGO,
+                                              jbd_debugfs_dir,
+                                              &journal_enable_debug);
 }
 
-static int write_jbd_debug(struct file *file, const char __user *buffer,
-                          unsigned long count, void *data)
+static void __exit jbd_remove_debugfs_entry(void)
 {
-       char buf[32];
-
-       if (count > ARRAY_SIZE(buf) - 1)
-               count = ARRAY_SIZE(buf) - 1;
-       if (copy_from_user(buf, buffer, count))
-               return -EFAULT;
-       buf[ARRAY_SIZE(buf) - 1] = '\0';
-       journal_enable_debug = simple_strtoul(buf, NULL, 10);
-       return count;
+       debugfs_remove(jbd_debug);
+       debugfs_remove(jbd_debugfs_dir);
 }
 
-#define JBD_PROC_NAME "sys/fs/jbd-debug"
+#else
 
-static void __init create_jbd_proc_entry(void)
+static inline void jbd_create_debugfs_entry(void)
 {
-       proc_jbd_debug = create_proc_entry(JBD_PROC_NAME, 0644, NULL);
-       if (proc_jbd_debug) {
-               /* Why is this so hard? */
-               proc_jbd_debug->read_proc = read_jbd_debug;
-               proc_jbd_debug->write_proc = write_jbd_debug;
-       }
 }
 
-static void __exit remove_jbd_proc_entry(void)
+static inline void jbd_remove_debugfs_entry(void)
 {
-       if (proc_jbd_debug)
-               remove_proc_entry(JBD_PROC_NAME, NULL);
 }
 
-#else
-
-#define create_jbd_proc_entry() do {} while (0)
-#define remove_jbd_proc_entry() do {} while (0)
-
 #endif
 
 struct kmem_cache *jbd_handle_cache;
@@ -2042,7 +1932,6 @@ static void journal_destroy_caches(void)
        journal_destroy_revoke_caches();
        journal_destroy_journal_head_cache();
        journal_destroy_handle_cache();
-       journal_destroy_jbd_slabs();
 }
 
 static int __init journal_init(void)
@@ -2054,7 +1943,7 @@ static int __init journal_init(void)
        ret = journal_init_caches();
        if (ret != 0)
                journal_destroy_caches();
-       create_jbd_proc_entry();
+       jbd_create_debugfs_entry();
        return ret;
 }
 
@@ -2065,7 +1954,7 @@ static void __exit journal_exit(void)
        if (n)
                printk(KERN_EMERG "JBD: leaked %d journal_heads!\n", n);
 #endif
-       remove_jbd_proc_entry();
+       jbd_remove_debugfs_entry();
        journal_destroy_caches();
 }
 
index 2a5f4b833e353626d6b3d6199e6ea13f2989e3de..c5d9694b6a2ff2df7f9311942674321c05147c88 100644 (file)
@@ -250,10 +250,10 @@ int journal_recover(journal_t *journal)
        if (!err)
                err = do_one_pass(journal, &info, PASS_REPLAY);
 
-       jbd_debug(0, "JBD: recovery, exit status %d, "
+       jbd_debug(1, "JBD: recovery, exit status %d, "
                  "recovered transactions %u to %u\n",
                  err, info.start_transaction, info.end_transaction);
-       jbd_debug(0, "JBD: Replayed %d and revoked %d/%d blocks\n",
+       jbd_debug(1, "JBD: Replayed %d and revoked %d/%d blocks\n",
                  info.nr_replays, info.nr_revoke_hits, info.nr_revokes);
 
        /* Restart the log at the next transaction ID, thus invalidating
@@ -297,7 +297,7 @@ int journal_skip_recovery(journal_t *journal)
 #ifdef CONFIG_JBD_DEBUG
                int dropped = info.end_transaction - be32_to_cpu(sb->s_sequence);
 #endif
-               jbd_debug(0,
+               jbd_debug(1,
                          "JBD: ignoring %d transaction%s from the journal.\n",
                          dropped, (dropped == 1) ? "" : "s");
                journal->j_transaction_sequence = ++info.end_transaction;
index 8df5bac0b7a52a5402116745ce3eb341e89e8a3f..08ff6c7028cc585b13cab54d01abb8ca1c6ea15d 100644 (file)
@@ -96,13 +96,12 @@ static int start_this_handle(journal_t *journal, handle_t *handle)
 
 alloc_transaction:
        if (!journal->j_running_transaction) {
-               new_transaction = jbd_kmalloc(sizeof(*new_transaction),
-                                               GFP_NOFS);
+               new_transaction = kzalloc(sizeof(*new_transaction),
+                                               GFP_NOFS|__GFP_NOFAIL);
                if (!new_transaction) {
                        ret = -ENOMEM;
                        goto out;
                }
-               memset(new_transaction, 0, sizeof(*new_transaction));
        }
 
        jbd_debug(3, "New handle %p going live.\n", handle);
@@ -675,7 +674,7 @@ repeat:
                                JBUFFER_TRACE(jh, "allocate memory for buffer");
                                jbd_unlock_bh_state(bh);
                                frozen_buffer =
-                                       jbd_slab_alloc(jh2bh(jh)->b_size,
+                                       jbd_alloc(jh2bh(jh)->b_size,
                                                         GFP_NOFS);
                                if (!frozen_buffer) {
                                        printk(KERN_EMERG
@@ -735,7 +734,7 @@ done:
 
 out:
        if (unlikely(frozen_buffer))    /* It's usually NULL */
-               jbd_slab_free(frozen_buffer, bh->b_size);
+               jbd_free(frozen_buffer, bh->b_size);
 
        JBUFFER_TRACE(jh, "exit");
        return error;
@@ -888,7 +887,7 @@ int journal_get_undo_access(handle_t *handle, struct buffer_head *bh)
 
 repeat:
        if (!jh->b_committed_data) {
-               committed_data = jbd_slab_alloc(jh2bh(jh)->b_size, GFP_NOFS);
+               committed_data = jbd_alloc(jh2bh(jh)->b_size, GFP_NOFS);
                if (!committed_data) {
                        printk(KERN_EMERG "%s: No memory for committed data\n",
                                __FUNCTION__);
@@ -915,7 +914,7 @@ repeat:
 out:
        journal_put_journal_head(jh);
        if (unlikely(committed_data))
-               jbd_slab_free(committed_data, bh->b_size);
+               jbd_free(committed_data, bh->b_size);
        return err;
 }
 
@@ -1172,7 +1171,7 @@ int journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
        }
 
        /* That test should have eliminated the following case: */
-       J_ASSERT_JH(jh, jh->b_frozen_data == 0);
+       J_ASSERT_JH(jh, jh->b_frozen_data == NULL);
 
        JBUFFER_TRACE(jh, "file as BJ_Metadata");
        spin_lock(&journal->j_list_lock);
@@ -1522,7 +1521,7 @@ static void __journal_temp_unlink_buffer(struct journal_head *jh)
 
        J_ASSERT_JH(jh, jh->b_jlist < BJ_Types);
        if (jh->b_jlist != BJ_None)
-               J_ASSERT_JH(jh, transaction != 0);
+               J_ASSERT_JH(jh, transaction != NULL);
 
        switch (jh->b_jlist) {
        case BJ_None:
@@ -1591,11 +1590,11 @@ __journal_try_to_free_buffer(journal_t *journal, struct buffer_head *bh)
        if (buffer_locked(bh) || buffer_dirty(bh))
                goto out;
 
-       if (jh->b_next_transaction != 0)
+       if (jh->b_next_transaction != NULL)
                goto out;
 
        spin_lock(&journal->j_list_lock);
-       if (jh->b_transaction != 0 && jh->b_cp_transaction == 0) {
+       if (jh->b_transaction != NULL && jh->b_cp_transaction == NULL) {
                if (jh->b_jlist == BJ_SyncData || jh->b_jlist == BJ_Locked) {
                        /* A written-back ordered data buffer */
                        JBUFFER_TRACE(jh, "release data");
@@ -1603,7 +1602,7 @@ __journal_try_to_free_buffer(journal_t *journal, struct buffer_head *bh)
                        journal_remove_journal_head(bh);
                        __brelse(bh);
                }
-       } else if (jh->b_cp_transaction != 0 && jh->b_transaction == 0) {
+       } else if (jh->b_cp_transaction != NULL && jh->b_transaction == NULL) {
                /* written-back checkpointed metadata buffer */
                if (jh->b_jlist == BJ_None) {
                        JBUFFER_TRACE(jh, "remove from checkpoint list");
@@ -1963,7 +1962,7 @@ void __journal_file_buffer(struct journal_head *jh,
 
        J_ASSERT_JH(jh, jh->b_jlist < BJ_Types);
        J_ASSERT_JH(jh, jh->b_transaction == transaction ||
-                               jh->b_transaction == 0);
+                               jh->b_transaction == NULL);
 
        if (jh->b_transaction && jh->b_jlist == jlist)
                return;
index c0f59d1b13dc336f82e490810f928f5e7b6b1a70..6986f334c643291181cd56c01c42a8820ad110f0 100644 (file)
@@ -278,7 +278,7 @@ static inline void write_tag_block(int tag_bytes, journal_block_tag_t *tag,
                                   unsigned long long block)
 {
        tag->t_blocknr = cpu_to_be32(block & (u32)~0);
-       if (tag_bytes > JBD_TAG_SIZE32)
+       if (tag_bytes > JBD2_TAG_SIZE32)
                tag->t_blocknr_high = cpu_to_be32((block >> 31) >> 1);
 }
 
@@ -384,7 +384,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
                        struct buffer_head *bh = jh2bh(jh);
 
                        jbd_lock_bh_state(bh);
-                       jbd2_slab_free(jh->b_committed_data, bh->b_size);
+                       jbd2_free(jh->b_committed_data, bh->b_size);
                        jh->b_committed_data = NULL;
                        jbd_unlock_bh_state(bh);
                }
@@ -475,7 +475,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
        spin_unlock(&journal->j_list_lock);
 
        if (err)
-               __jbd2_journal_abort_hard(journal);
+               jbd2_journal_abort(journal, err);
 
        jbd2_journal_write_revoke_records(journal, commit_transaction);
 
@@ -533,7 +533,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
 
                        descriptor = jbd2_journal_get_descriptor_buffer(journal);
                        if (!descriptor) {
-                               __jbd2_journal_abort_hard(journal);
+                               jbd2_journal_abort(journal, -EIO);
                                continue;
                        }
 
@@ -566,7 +566,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
                   and repeat this loop: we'll fall into the
                   refile-on-abort condition above. */
                if (err) {
-                       __jbd2_journal_abort_hard(journal);
+                       jbd2_journal_abort(journal, err);
                        continue;
                }
 
@@ -757,7 +757,7 @@ wait_for_iobuf:
                err = -EIO;
 
        if (err)
-               __jbd2_journal_abort_hard(journal);
+               jbd2_journal_abort(journal, err);
 
        /* End of a transaction!  Finally, we can do checkpoint
            processing: any buffers committed as a result of this
@@ -801,14 +801,14 @@ restart_loop:
                 * Otherwise, we can just throw away the frozen data now.
                 */
                if (jh->b_committed_data) {
-                       jbd2_slab_free(jh->b_committed_data, bh->b_size);
+                       jbd2_free(jh->b_committed_data, bh->b_size);
                        jh->b_committed_data = NULL;
                        if (jh->b_frozen_data) {
                                jh->b_committed_data = jh->b_frozen_data;
                                jh->b_frozen_data = NULL;
                        }
                } else if (jh->b_frozen_data) {
-                       jbd2_slab_free(jh->b_frozen_data, bh->b_size);
+                       jbd2_free(jh->b_frozen_data, bh->b_size);
                        jh->b_frozen_data = NULL;
                }
 
index f37324aee817c9181fee667ba334c9df293f8666..6ddc5531587c7c6598180f105e46645f13d74337 100644 (file)
@@ -84,7 +84,6 @@ EXPORT_SYMBOL(jbd2_journal_force_commit);
 
 static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *);
 static void __journal_abort_soft (journal_t *journal, int errno);
-static int jbd2_journal_create_jbd_slab(size_t slab_size);
 
 /*
  * Helper function used to manage commit timeouts
@@ -335,10 +334,10 @@ repeat:
                char *tmp;
 
                jbd_unlock_bh_state(bh_in);
-               tmp = jbd2_slab_alloc(bh_in->b_size, GFP_NOFS);
+               tmp = jbd2_alloc(bh_in->b_size, GFP_NOFS);
                jbd_lock_bh_state(bh_in);
                if (jh_in->b_frozen_data) {
-                       jbd2_slab_free(tmp, bh_in->b_size);
+                       jbd2_free(tmp, bh_in->b_size);
                        goto repeat;
                }
 
@@ -655,10 +654,9 @@ static journal_t * journal_init_common (void)
        journal_t *journal;
        int err;
 
-       journal = jbd_kmalloc(sizeof(*journal), GFP_KERNEL);
+       journal = kzalloc(sizeof(*journal), GFP_KERNEL|__GFP_NOFAIL);
        if (!journal)
                goto fail;
-       memset(journal, 0, sizeof(*journal));
 
        init_waitqueue_head(&journal->j_wait_transaction_locked);
        init_waitqueue_head(&journal->j_wait_logspace);
@@ -672,7 +670,7 @@ static journal_t * journal_init_common (void)
        spin_lock_init(&journal->j_list_lock);
        spin_lock_init(&journal->j_state_lock);
 
-       journal->j_commit_interval = (HZ * JBD_DEFAULT_MAX_COMMIT_AGE);
+       journal->j_commit_interval = (HZ * JBD2_DEFAULT_MAX_COMMIT_AGE);
 
        /* The journal is marked for error until we succeed with recovery! */
        journal->j_flags = JBD2_ABORT;
@@ -1096,13 +1094,6 @@ int jbd2_journal_load(journal_t *journal)
                }
        }
 
-       /*
-        * Create a slab for this blocksize
-        */
-       err = jbd2_journal_create_jbd_slab(be32_to_cpu(sb->s_blocksize));
-       if (err)
-               return err;
-
        /* Let the recovery code check whether it needs to recover any
         * data from the journal. */
        if (jbd2_journal_recover(journal))
@@ -1621,89 +1612,9 @@ int jbd2_journal_blocks_per_page(struct inode *inode)
 size_t journal_tag_bytes(journal_t *journal)
 {
        if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT))
-               return JBD_TAG_SIZE64;
+               return JBD2_TAG_SIZE64;
        else
-               return JBD_TAG_SIZE32;
-}
-
-/*
- * Simple support for retrying memory allocations.  Introduced to help to
- * debug different VM deadlock avoidance strategies.
- */
-void * __jbd2_kmalloc (const char *where, size_t size, gfp_t flags, int retry)
-{
-       return kmalloc(size, flags | (retry ? __GFP_NOFAIL : 0));
-}
-
-/*
- * jbd slab management: create 1k, 2k, 4k, 8k slabs as needed
- * and allocate frozen and commit buffers from these slabs.
- *
- * Reason for doing this is to avoid, SLAB_DEBUG - since it could
- * cause bh to cross page boundary.
- */
-
-#define JBD_MAX_SLABS 5
-#define JBD_SLAB_INDEX(size)  (size >> 11)
-
-static struct kmem_cache *jbd_slab[JBD_MAX_SLABS];
-static const char *jbd_slab_names[JBD_MAX_SLABS] = {
-       "jbd2_1k", "jbd2_2k", "jbd2_4k", NULL, "jbd2_8k"
-};
-
-static void jbd2_journal_destroy_jbd_slabs(void)
-{
-       int i;
-
-       for (i = 0; i < JBD_MAX_SLABS; i++) {
-               if (jbd_slab[i])
-                       kmem_cache_destroy(jbd_slab[i]);
-               jbd_slab[i] = NULL;
-       }
-}
-
-static int jbd2_journal_create_jbd_slab(size_t slab_size)
-{
-       int i = JBD_SLAB_INDEX(slab_size);
-
-       BUG_ON(i >= JBD_MAX_SLABS);
-
-       /*
-        * Check if we already have a slab created for this size
-        */
-       if (jbd_slab[i])
-               return 0;
-
-       /*
-        * Create a slab and force alignment to be same as slabsize -
-        * this will make sure that allocations won't cross the page
-        * boundary.
-        */
-       jbd_slab[i] = kmem_cache_create(jbd_slab_names[i],
-                               slab_size, slab_size, 0, NULL);
-       if (!jbd_slab[i]) {
-               printk(KERN_EMERG "JBD: no memory for jbd_slab cache\n");
-               return -ENOMEM;
-       }
-       return 0;
-}
-
-void * jbd2_slab_alloc(size_t size, gfp_t flags)
-{
-       int idx;
-
-       idx = JBD_SLAB_INDEX(size);
-       BUG_ON(jbd_slab[idx] == NULL);
-       return kmem_cache_alloc(jbd_slab[idx], flags | __GFP_NOFAIL);
-}
-
-void jbd2_slab_free(void *ptr,  size_t size)
-{
-       int idx;
-
-       idx = JBD_SLAB_INDEX(size);
-       BUG_ON(jbd_slab[idx] == NULL);
-       kmem_cache_free(jbd_slab[idx], ptr);
+               return JBD2_TAG_SIZE32;
 }
 
 /*
@@ -1770,7 +1681,7 @@ static void journal_free_journal_head(struct journal_head *jh)
 {
 #ifdef CONFIG_JBD2_DEBUG
        atomic_dec(&nr_journal_heads);
-       memset(jh, JBD_POISON_FREE, sizeof(*jh));
+       memset(jh, JBD2_POISON_FREE, sizeof(*jh));
 #endif
        kmem_cache_free(jbd2_journal_head_cache, jh);
 }
@@ -1893,13 +1804,13 @@ static void __journal_remove_journal_head(struct buffer_head *bh)
                                printk(KERN_WARNING "%s: freeing "
                                                "b_frozen_data\n",
                                                __FUNCTION__);
-                               jbd2_slab_free(jh->b_frozen_data, bh->b_size);
+                               jbd2_free(jh->b_frozen_data, bh->b_size);
                        }
                        if (jh->b_committed_data) {
                                printk(KERN_WARNING "%s: freeing "
                                                "b_committed_data\n",
                                                __FUNCTION__);
-                               jbd2_slab_free(jh->b_committed_data, bh->b_size);
+                               jbd2_free(jh->b_committed_data, bh->b_size);
                        }
                        bh->b_private = NULL;
                        jh->b_bh = NULL;        /* debug, really */
@@ -1953,16 +1864,14 @@ void jbd2_journal_put_journal_head(struct journal_head *jh)
 /*
  * debugfs tunables
  */
-#if defined(CONFIG_JBD2_DEBUG)
-u8 jbd2_journal_enable_debug;
+#ifdef CONFIG_JBD2_DEBUG
+u8 jbd2_journal_enable_debug __read_mostly;
 EXPORT_SYMBOL(jbd2_journal_enable_debug);
-#endif
-
-#if defined(CONFIG_JBD2_DEBUG) && defined(CONFIG_DEBUG_FS)
 
 #define JBD2_DEBUG_NAME "jbd2-debug"
 
-struct dentry *jbd2_debugfs_dir, *jbd2_debug;
+static struct dentry *jbd2_debugfs_dir;
+static struct dentry *jbd2_debug;
 
 static void __init jbd2_create_debugfs_entry(void)
 {
@@ -1975,24 +1884,18 @@ static void __init jbd2_create_debugfs_entry(void)
 
 static void __exit jbd2_remove_debugfs_entry(void)
 {
-       if (jbd2_debug)
-               debugfs_remove(jbd2_debug);
-       if (jbd2_debugfs_dir)
-               debugfs_remove(jbd2_debugfs_dir);
+       debugfs_remove(jbd2_debug);
+       debugfs_remove(jbd2_debugfs_dir);
 }
 
 #else
 
 static void __init jbd2_create_debugfs_entry(void)
 {
-       do {
-       } while (0);
 }
 
 static void __exit jbd2_remove_debugfs_entry(void)
 {
-       do {
-       } while (0);
 }
 
 #endif
@@ -2040,7 +1943,6 @@ static void jbd2_journal_destroy_caches(void)
        jbd2_journal_destroy_revoke_caches();
        jbd2_journal_destroy_jbd2_journal_head_cache();
        jbd2_journal_destroy_handle_cache();
-       jbd2_journal_destroy_jbd_slabs();
 }
 
 static int __init journal_init(void)
index b50be8a044eb8d8bb8849bedc662d516bfa971bb..d0ce627539ef11710993c0c4236dc4821e0eacdf 100644 (file)
@@ -311,7 +311,7 @@ int jbd2_journal_skip_recovery(journal_t *journal)
 static inline unsigned long long read_tag_block(int tag_bytes, journal_block_tag_t *tag)
 {
        unsigned long long block = be32_to_cpu(tag->t_blocknr);
-       if (tag_bytes > JBD_TAG_SIZE32)
+       if (tag_bytes > JBD2_TAG_SIZE32)
                block |= (u64)be32_to_cpu(tag->t_blocknr_high) << 32;
        return block;
 }
index 01d88975e0c5641101921ef8e0901fd631446c78..3595fd432d5b55b25806e0bf48d03a2756de040a 100644 (file)
@@ -352,7 +352,7 @@ int jbd2_journal_revoke(handle_t *handle, unsigned long long blocknr,
                if (bh)
                        BUFFER_TRACE(bh, "found on hash");
        }
-#ifdef JBD_EXPENSIVE_CHECKING
+#ifdef JBD2_EXPENSIVE_CHECKING
        else {
                struct buffer_head *bh2;
 
@@ -453,7 +453,7 @@ int jbd2_journal_cancel_revoke(handle_t *handle, struct journal_head *jh)
                }
        }
 
-#ifdef JBD_EXPENSIVE_CHECKING
+#ifdef JBD2_EXPENSIVE_CHECKING
        /* There better not be one left behind by now! */
        record = find_revoke_record(journal, bh->b_blocknr);
        J_ASSERT_JH(jh, record == NULL);
index 7946ff43fc40b5d91290efe2d5401e3aa3bf0d07..b1fcf2b3dca3e9154c2f1aa4ded8c796e1cbaac3 100644 (file)
@@ -96,13 +96,12 @@ static int start_this_handle(journal_t *journal, handle_t *handle)
 
 alloc_transaction:
        if (!journal->j_running_transaction) {
-               new_transaction = jbd_kmalloc(sizeof(*new_transaction),
-                                               GFP_NOFS);
+               new_transaction = kzalloc(sizeof(*new_transaction),
+                                               GFP_NOFS|__GFP_NOFAIL);
                if (!new_transaction) {
                        ret = -ENOMEM;
                        goto out;
                }
-               memset(new_transaction, 0, sizeof(*new_transaction));
        }
 
        jbd_debug(3, "New handle %p going live.\n", handle);
@@ -236,7 +235,7 @@ out:
 /* Allocate a new handle.  This should probably be in a slab... */
 static handle_t *new_handle(int nblocks)
 {
-       handle_t *handle = jbd_alloc_handle(GFP_NOFS);
+       handle_t *handle = jbd2_alloc_handle(GFP_NOFS);
        if (!handle)
                return NULL;
        memset(handle, 0, sizeof(*handle));
@@ -282,7 +281,7 @@ handle_t *jbd2_journal_start(journal_t *journal, int nblocks)
 
        err = start_this_handle(journal, handle);
        if (err < 0) {
-               jbd_free_handle(handle);
+               jbd2_free_handle(handle);
                current->journal_info = NULL;
                handle = ERR_PTR(err);
        }
@@ -668,7 +667,7 @@ repeat:
                                JBUFFER_TRACE(jh, "allocate memory for buffer");
                                jbd_unlock_bh_state(bh);
                                frozen_buffer =
-                                       jbd2_slab_alloc(jh2bh(jh)->b_size,
+                                       jbd2_alloc(jh2bh(jh)->b_size,
                                                         GFP_NOFS);
                                if (!frozen_buffer) {
                                        printk(KERN_EMERG
@@ -728,7 +727,7 @@ done:
 
 out:
        if (unlikely(frozen_buffer))    /* It's usually NULL */
-               jbd2_slab_free(frozen_buffer, bh->b_size);
+               jbd2_free(frozen_buffer, bh->b_size);
 
        JBUFFER_TRACE(jh, "exit");
        return error;
@@ -881,7 +880,7 @@ int jbd2_journal_get_undo_access(handle_t *handle, struct buffer_head *bh)
 
 repeat:
        if (!jh->b_committed_data) {
-               committed_data = jbd2_slab_alloc(jh2bh(jh)->b_size, GFP_NOFS);
+               committed_data = jbd2_alloc(jh2bh(jh)->b_size, GFP_NOFS);
                if (!committed_data) {
                        printk(KERN_EMERG "%s: No memory for committed data\n",
                                __FUNCTION__);
@@ -908,7 +907,7 @@ repeat:
 out:
        jbd2_journal_put_journal_head(jh);
        if (unlikely(committed_data))
-               jbd2_slab_free(committed_data, bh->b_size);
+               jbd2_free(committed_data, bh->b_size);
        return err;
 }
 
@@ -1411,7 +1410,7 @@ int jbd2_journal_stop(handle_t *handle)
                spin_unlock(&journal->j_state_lock);
        }
 
-       jbd_free_handle(handle);
+       jbd2_free_handle(handle);
        return err;
 }
 
index 8ec9323e830a810eef5a0833f5e365d02ca7c9ee..9728614b89588252431f83ffa454cd1bd89c020d 100644 (file)
@@ -228,11 +228,28 @@ struct posix_acl *jffs2_get_acl(struct inode *inode, int type)
        return acl;
 }
 
+static int __jffs2_set_acl(struct inode *inode, int xprefix, struct posix_acl *acl)
+{
+       char *value = NULL;
+       size_t size = 0;
+       int rc;
+
+       if (acl) {
+               value = jffs2_acl_to_medium(acl, &size);
+               if (IS_ERR(value))
+                       return PTR_ERR(value);
+       }
+       rc = do_jffs2_setxattr(inode, xprefix, "", value, size, 0);
+       if (!value && rc == -ENODATA)
+               rc = 0;
+       kfree(value);
+
+       return rc;
+}
+
 static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
 {
        struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
-       size_t size = 0;
-       char *value = NULL;
        int rc, xprefix;
 
        if (S_ISLNK(inode->i_mode))
@@ -267,17 +284,7 @@ static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
        default:
                return -EINVAL;
        }
-       if (acl) {
-               value = jffs2_acl_to_medium(acl, &size);
-               if (IS_ERR(value))
-                       return PTR_ERR(value);
-       }
-
-       rc = do_jffs2_setxattr(inode, xprefix, "", value, size, 0);
-       if (!value && rc == -ENODATA)
-               rc = 0;
-       if (value)
-               kfree(value);
+       rc = __jffs2_set_acl(inode, xprefix, acl);
        if (!rc) {
                switch(type) {
                case ACL_TYPE_ACCESS:
@@ -312,37 +319,59 @@ int jffs2_permission(struct inode *inode, int mask, struct nameidata *nd)
        return generic_permission(inode, mask, jffs2_check_acl);
 }
 
-int jffs2_init_acl(struct inode *inode, struct posix_acl *acl)
+int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, int *i_mode)
 {
        struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
-       struct posix_acl *clone;
-       mode_t mode;
-       int rc = 0;
+       struct posix_acl *acl, *clone;
+       int rc;
 
-       f->i_acl_access = JFFS2_ACL_NOT_CACHED;
-       f->i_acl_default = JFFS2_ACL_NOT_CACHED;
+       f->i_acl_default = NULL;
+       f->i_acl_access = NULL;
+
+       if (S_ISLNK(*i_mode))
+               return 0;       /* Symlink always has no-ACL */
+
+       acl = jffs2_get_acl(dir_i, ACL_TYPE_DEFAULT);
+       if (IS_ERR(acl))
+               return PTR_ERR(acl);
+
+       if (!acl) {
+               *i_mode &= ~current->fs->umask;
+       } else {
+               if (S_ISDIR(*i_mode))
+                       jffs2_iset_acl(inode, &f->i_acl_default, acl);
 
-       if (acl) {
-               if (S_ISDIR(inode->i_mode)) {
-                       rc = jffs2_set_acl(inode, ACL_TYPE_DEFAULT, acl);
-                       if (rc)
-                               goto cleanup;
-               }
                clone = posix_acl_clone(acl, GFP_KERNEL);
-               rc = -ENOMEM;
                if (!clone)
-                       goto cleanup;
-               mode = inode->i_mode;
-               rc = posix_acl_create_masq(clone, &mode);
-               if (rc >= 0) {
-                       inode->i_mode = mode;
-                       if (rc > 0)
-                               rc = jffs2_set_acl(inode, ACL_TYPE_ACCESS, clone);
-               }
+                       return -ENOMEM;
+               rc = posix_acl_create_masq(clone, (mode_t *)i_mode);
+               if (rc < 0)
+                       return rc;
+               if (rc > 0)
+                       jffs2_iset_acl(inode, &f->i_acl_access, clone);
+
                posix_acl_release(clone);
        }
- cleanup:
-       posix_acl_release(acl);
+       return 0;
+}
+
+int jffs2_init_acl_post(struct inode *inode)
+{
+       struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
+       int rc;
+
+       if (f->i_acl_default) {
+               rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_DEFAULT, f->i_acl_default);
+               if (rc)
+                       return rc;
+       }
+
+       if (f->i_acl_access) {
+               rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_ACCESS, f->i_acl_access);
+               if (rc)
+                       return rc;
+       }
+
        return rc;
 }
 
index 90a2dbf590519028ee893ed6b8587e2f6682463f..76c6ebd1acd975840d303ddc65b0ecde54091579 100644 (file)
@@ -31,7 +31,8 @@ struct jffs2_acl_header {
 extern struct posix_acl *jffs2_get_acl(struct inode *inode, int type);
 extern int jffs2_permission(struct inode *, int, struct nameidata *);
 extern int jffs2_acl_chmod(struct inode *);
-extern int jffs2_init_acl(struct inode *, struct posix_acl *);
+extern int jffs2_init_acl_pre(struct inode *, struct inode *, int *);
+extern int jffs2_init_acl_post(struct inode *);
 extern void jffs2_clear_acl(struct jffs2_inode_info *);
 
 extern struct xattr_handler jffs2_acl_access_xattr_handler;
@@ -39,10 +40,11 @@ extern struct xattr_handler jffs2_acl_default_xattr_handler;
 
 #else
 
-#define jffs2_get_acl(inode, type)     (NULL)
-#define jffs2_permission NULL
-#define jffs2_acl_chmod(inode)         (0)
-#define jffs2_init_acl(inode,dir)      (0)
+#define jffs2_get_acl(inode, type)             (NULL)
+#define jffs2_permission                       (NULL)
+#define jffs2_acl_chmod(inode)                 (0)
+#define jffs2_init_acl_pre(dir_i,inode,mode)   (0)
+#define jffs2_init_acl_post(inode)             (0)
 #define jffs2_clear_acl(f)
 
 #endif /* CONFIG_JFFS2_FS_POSIX_ACL */
index 2a49f2c51a9f8a11e42d7664a7dffc7ceb60060b..4130adabd76e6d9a9d496d1e6d176a43cb905783 100644 (file)
 #define JFFS2_ERROR(fmt, ...)                                          \
        do {                                                            \
                printk(JFFS2_ERR_MSG_PREFIX                             \
-                       " (%d) %s: " fmt, current->pid,                 \
+                       " (%d) %s: " fmt, task_pid_nr(current),         \
                        __FUNCTION__ , ##__VA_ARGS__);                  \
        } while(0)
 
 #define JFFS2_WARNING(fmt, ...)                                                \
        do {                                                            \
                printk(JFFS2_WARN_MSG_PREFIX                            \
-                       " (%d) %s: " fmt, current->pid,                 \
+                       " (%d) %s: " fmt, task_pid_nr(current),         \
                        __FUNCTION__ , ##__VA_ARGS__);                  \
        } while(0)
 
 #define JFFS2_NOTICE(fmt, ...)                                         \
        do {                                                            \
                printk(JFFS2_NOTICE_MSG_PREFIX                          \
-                       " (%d) %s: " fmt, current->pid,                 \
+                       " (%d) %s: " fmt, task_pid_nr(current),         \
                        __FUNCTION__ , ##__VA_ARGS__);                  \
        } while(0)
 
 #define JFFS2_DEBUG(fmt, ...)                                          \
        do {                                                            \
                printk(JFFS2_DBG_MSG_PREFIX                             \
-                       " (%d) %s: " fmt, current->pid,                 \
+                       " (%d) %s: " fmt, task_pid_nr(current),         \
                        __FUNCTION__ , ##__VA_ARGS__);                  \
        } while(0)
 
index 8353eb9c179955a8a9b54ec0d461560f2ae217b3..787e392ffd41bac38f0d3db617b0070faed368f6 100644 (file)
@@ -182,7 +182,6 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode,
        struct jffs2_inode_info *f, *dir_f;
        struct jffs2_sb_info *c;
        struct inode *inode;
-       struct posix_acl *acl;
        int ret;
 
        ri = jffs2_alloc_raw_inode();
@@ -193,7 +192,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode,
 
        D1(printk(KERN_DEBUG "jffs2_create()\n"));
 
-       inode = jffs2_new_inode(dir_i, mode, ri, &acl);
+       inode = jffs2_new_inode(dir_i, mode, ri);
 
        if (IS_ERR(inode)) {
                D1(printk(KERN_DEBUG "jffs2_new_inode() failed\n"));
@@ -211,14 +210,6 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode,
 
        ret = jffs2_do_create(c, dir_f, f, ri,
                              dentry->d_name.name, dentry->d_name.len);
-
-       if (ret)
-               goto fail_acl;
-
-       ret = jffs2_init_security(inode, dir_i);
-       if (ret)
-               goto fail_acl;
-       ret = jffs2_init_acl(inode, acl);
        if (ret)
                goto fail;
 
@@ -231,8 +222,6 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode,
                  inode->i_ino, inode->i_mode, inode->i_nlink, f->inocache->nlink, inode->i_mapping->nrpages));
        return 0;
 
- fail_acl:
-       posix_acl_release(acl);
  fail:
        make_bad_inode(inode);
        iput(inode);
@@ -309,7 +298,6 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
        struct jffs2_full_dirent *fd;
        int namelen;
        uint32_t alloclen;
-       struct posix_acl *acl;
        int ret, targetlen = strlen(target);
 
        /* FIXME: If you care. We'd need to use frags for the target
@@ -336,7 +324,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
                return ret;
        }
 
-       inode = jffs2_new_inode(dir_i, S_IFLNK | S_IRWXUGO, ri, &acl);
+       inode = jffs2_new_inode(dir_i, S_IFLNK | S_IRWXUGO, ri);
 
        if (IS_ERR(inode)) {
                jffs2_free_raw_inode(ri);
@@ -366,7 +354,6 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
                up(&f->sem);
                jffs2_complete_reservation(c);
                jffs2_clear_inode(inode);
-               posix_acl_release(acl);
                return PTR_ERR(fn);
        }
 
@@ -377,7 +364,6 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
                up(&f->sem);
                jffs2_complete_reservation(c);
                jffs2_clear_inode(inode);
-               posix_acl_release(acl);
                return -ENOMEM;
        }
 
@@ -395,10 +381,9 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
        ret = jffs2_init_security(inode, dir_i);
        if (ret) {
                jffs2_clear_inode(inode);
-               posix_acl_release(acl);
                return ret;
        }
-       ret = jffs2_init_acl(inode, acl);
+       ret = jffs2_init_acl_post(inode);
        if (ret) {
                jffs2_clear_inode(inode);
                return ret;
@@ -476,7 +461,6 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
        struct jffs2_full_dirent *fd;
        int namelen;
        uint32_t alloclen;
-       struct posix_acl *acl;
        int ret;
 
        mode |= S_IFDIR;
@@ -499,7 +483,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
                return ret;
        }
 
-       inode = jffs2_new_inode(dir_i, mode, ri, &acl);
+       inode = jffs2_new_inode(dir_i, mode, ri);
 
        if (IS_ERR(inode)) {
                jffs2_free_raw_inode(ri);
@@ -526,7 +510,6 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
                up(&f->sem);
                jffs2_complete_reservation(c);
                jffs2_clear_inode(inode);
-               posix_acl_release(acl);
                return PTR_ERR(fn);
        }
        /* No data here. Only a metadata node, which will be
@@ -540,10 +523,9 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
        ret = jffs2_init_security(inode, dir_i);
        if (ret) {
                jffs2_clear_inode(inode);
-               posix_acl_release(acl);
                return ret;
        }
-       ret = jffs2_init_acl(inode, acl);
+       ret = jffs2_init_acl_post(inode);
        if (ret) {
                jffs2_clear_inode(inode);
                return ret;
@@ -639,7 +621,6 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
        union jffs2_device_node dev;
        int devlen = 0;
        uint32_t alloclen;
-       struct posix_acl *acl;
        int ret;
 
        if (!new_valid_dev(rdev))
@@ -666,7 +647,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
                return ret;
        }
 
-       inode = jffs2_new_inode(dir_i, mode, ri, &acl);
+       inode = jffs2_new_inode(dir_i, mode, ri);
 
        if (IS_ERR(inode)) {
                jffs2_free_raw_inode(ri);
@@ -695,7 +676,6 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
                up(&f->sem);
                jffs2_complete_reservation(c);
                jffs2_clear_inode(inode);
-               posix_acl_release(acl);
                return PTR_ERR(fn);
        }
        /* No data here. Only a metadata node, which will be
@@ -709,10 +689,9 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
        ret = jffs2_init_security(inode, dir_i);
        if (ret) {
                jffs2_clear_inode(inode);
-               posix_acl_release(acl);
                return ret;
        }
-       ret = jffs2_init_acl(inode, acl);
+       ret = jffs2_init_acl_post(inode);
        if (ret) {
                jffs2_clear_inode(inode);
                return ret;
index 023a17539dd4f7c296aed08e957a1867bf4bde3e..f9c5dd6f4b64fb77b12b83d7041e6416f2072f41 100644 (file)
@@ -255,7 +255,7 @@ static int jffs2_write_end(struct file *filp, struct address_space *mapping,
                   _whole_ page. This helps to reduce the number of
                   nodes in files which have many short writes, like
                   syslog files. */
-               start = aligned_start = 0;
+               aligned_start = 0;
        }
 
        ri = jffs2_alloc_raw_inode();
@@ -291,14 +291,11 @@ static int jffs2_write_end(struct file *filp, struct address_space *mapping,
        }
 
        /* Adjust writtenlen for the padding we did, so we don't confuse our caller */
-       if (writtenlen < (start&3))
-               writtenlen = 0;
-       else
-               writtenlen -= (start&3);
+       writtenlen -= min(writtenlen, (start - aligned_start));
 
        if (writtenlen) {
-               if (inode->i_size < (pg->index << PAGE_CACHE_SHIFT) + start + writtenlen) {
-                       inode->i_size = (pg->index << PAGE_CACHE_SHIFT) + start + writtenlen;
+               if (inode->i_size < pos + writtenlen) {
+                       inode->i_size = pos + writtenlen;
                        inode->i_blocks = (inode->i_size + 511) >> 9;
 
                        inode->i_ctime = inode->i_mtime = ITIME(je32_to_cpu(ri->ctime));
index ed85f9afdbc8ae4dfb5c65541c89a526d9a6f400..d2e06f7ea96fdff2eac4a3c683c026e5c5d9fac6 100644 (file)
@@ -402,8 +402,7 @@ void jffs2_write_super (struct super_block *sb)
 
 /* jffs2_new_inode: allocate a new inode and inocache, add it to the hash,
    fill in the raw_inode while you're at it. */
-struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri,
-                              struct posix_acl **acl)
+struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri)
 {
        struct inode *inode;
        struct super_block *sb = dir_i->i_sb;
@@ -438,19 +437,11 @@ struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_i
 
        /* POSIX ACLs have to be processed now, at least partly.
           The umask is only applied if there's no default ACL */
-       if (!S_ISLNK(mode)) {
-               *acl = jffs2_get_acl(dir_i, ACL_TYPE_DEFAULT);
-               if (IS_ERR(*acl)) {
-                       make_bad_inode(inode);
-                       iput(inode);
-                       inode = (void *)*acl;
-                       *acl = NULL;
-                       return inode;
-               }
-               if (!(*acl))
-                       mode &= ~current->fs->umask;
-       } else {
-               *acl = NULL;
+       ret = jffs2_init_acl_pre(dir_i, inode, &mode);
+       if (ret) {
+           make_bad_inode(inode);
+           iput(inode);
+           return ERR_PTR(ret);
        }
        ret = jffs2_do_new_inode (c, f, mode, ri);
        if (ret) {
index f6743a915cf389abb8df8dfad0873e1c4a3bc431..bf64686cf09848b5d9a0730114ed17fe367c8e5e 100644 (file)
@@ -173,15 +173,13 @@ int jffs2_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
 extern const struct inode_operations jffs2_symlink_inode_operations;
 
 /* fs.c */
-struct posix_acl;
-
 int jffs2_setattr (struct dentry *, struct iattr *);
 int jffs2_do_setattr (struct inode *, struct iattr *);
 void jffs2_read_inode (struct inode *);
 void jffs2_clear_inode (struct inode *);
 void jffs2_dirty_inode(struct inode *inode);
 struct inode *jffs2_new_inode (struct inode *dir_i, int mode,
-                              struct jffs2_raw_inode *ri, struct posix_acl **acl);
+                              struct jffs2_raw_inode *ri);
 int jffs2_statfs (struct dentry *, struct kstatfs *);
 void jffs2_write_super (struct super_block *);
 int jffs2_remount_fs (struct super_block *, int *, char *);
index 2f5695446d0f56eb92d0e2b8f26e90a7ed2938c3..147e2cbee9e465168f37f0837c2ea04854eadb1f 100644 (file)
@@ -465,6 +465,14 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str
 
        up(&f->sem);
        jffs2_complete_reservation(c);
+
+       ret = jffs2_init_security(&f->vfs_inode, &dir_f->vfs_inode);
+       if (ret)
+               return ret;
+       ret = jffs2_init_acl_post(&f->vfs_inode);
+       if (ret)
+               return ret;
+
        ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen,
                                ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
 
index df0b8535de849f5d26d732c7da5eb66e35bfd762..df25ecc418af0c7a3e06932255853312eb7b2e84 100644 (file)
@@ -773,7 +773,7 @@ int dtSearch(struct inode *ip, struct component_name * key, ino_t * data,
              getChild:
                /* update max. number of pages to split */
                if (BT_STACK_FULL(btstack)) {
-                       /* Something's corrupted, mark filesytem dirty so
+                       /* Something's corrupted, mark filesystem dirty so
                         * chkdsk will fix it.
                         */
                        jfs_error(sb, "stack overrun in dtSearch!");
index f0ec72b263f1f4f8e852aeb91d6a201de316b5ed..8e2cf2cde185d67571489bacf321f45feeef5131 100644 (file)
@@ -18,6 +18,8 @@
 #ifndef        _H_JFS_INODE
 #define _H_JFS_INODE
 
+struct fid;
+
 extern struct inode *ialloc(struct inode *, umode_t);
 extern int jfs_fsync(struct file *, struct dentry *, int);
 extern int jfs_ioctl(struct inode *, struct file *,
@@ -32,7 +34,10 @@ extern void jfs_truncate_nolock(struct inode *, loff_t);
 extern void jfs_free_zero_link(struct inode *);
 extern struct dentry *jfs_get_parent(struct dentry *dentry);
 extern void jfs_get_inode_flags(struct jfs_inode_info *);
-extern struct dentry *jfs_get_dentry(struct super_block *sb, void *vobjp);
+extern struct dentry *jfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
+       int fh_len, int fh_type);
+extern struct dentry *jfs_fh_to_parent(struct super_block *sb, struct fid *fid,
+       int fh_len, int fh_type);
 extern void jfs_set_inode_flags(struct inode *);
 extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
 
index 932797ba433b0b5d2ac1a4c06f122564990049d0..4e0a8493cef69c394bcab1478f0872e7268b0425 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/fs.h>
 #include <linux/ctype.h>
 #include <linux/quotaops.h>
+#include <linux/exportfs.h>
 #include "jfs_incore.h"
 #include "jfs_superblock.h"
 #include "jfs_inode.h"
@@ -1477,13 +1478,10 @@ static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry, struc
        return dentry;
 }
 
-struct dentry *jfs_get_dentry(struct super_block *sb, void *vobjp)
+static struct inode *jfs_nfs_get_inode(struct super_block *sb,
+               u64 ino, u32 generation)
 {
-       __u32 *objp = vobjp;
-       unsigned long ino = objp[0];
-       __u32 generation = objp[1];
        struct inode *inode;
-       struct dentry *result;
 
        if (ino == 0)
                return ERR_PTR(-ESTALE);
@@ -1493,20 +1491,25 @@ struct dentry *jfs_get_dentry(struct super_block *sb, void *vobjp)
 
        if (is_bad_inode(inode) ||
            (generation && inode->i_generation != generation)) {
-               result = ERR_PTR(-ESTALE);
-               goto out_iput;
+               iput(inode);
+               return ERR_PTR(-ESTALE);
        }
 
-       result = d_alloc_anon(inode);
-       if (!result) {
-               result = ERR_PTR(-ENOMEM);
-               goto out_iput;
-       }
-       return result;
+       return inode;
+}
 
- out_iput:
-       iput(inode);
-       return result;
+struct dentry *jfs_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,
+                                   jfs_nfs_get_inode);
+}
+
+struct dentry *jfs_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,
+                                   jfs_nfs_get_inode);
 }
 
 struct dentry *jfs_get_parent(struct dentry *dentry)
index cff60c171943b9b23334428bd650ac829fc19b7b..314bb4ff1ba8a185715c8979feee658613eb6f13 100644 (file)
@@ -48,7 +48,7 @@ MODULE_LICENSE("GPL");
 static struct kmem_cache * jfs_inode_cachep;
 
 static const struct super_operations jfs_super_operations;
-static struct export_operations jfs_export_operations;
+static const struct export_operations jfs_export_operations;
 static struct file_system_type jfs_fs_type;
 
 #define MAX_COMMIT_THREADS 64
@@ -737,8 +737,9 @@ static const struct super_operations jfs_super_operations = {
 #endif
 };
 
-static struct export_operations jfs_export_operations = {
-       .get_dentry     = jfs_get_dentry,
+static const struct export_operations jfs_export_operations = {
+       .fh_to_dentry   = jfs_fh_to_dentry,
+       .fh_to_parent   = jfs_fh_to_parent,
        .get_parent     = jfs_get_parent,
 };
 
index ae51481e45e5f679e240d64e5f8e1f39e7c0e2c7..6e68b700958d331e7e0c2446d54b7d9d06b8f3c2 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/mount.h>
 #include <linux/vfs.h>
 #include <linux/mutex.h>
+#include <linux/exportfs.h>
 
 #include <asm/uaccess.h>
 
@@ -678,6 +679,93 @@ 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
+ * @fid:       file handle to convert
+ * @fh_len:    length of the file handle in bytes
+ * @fh_type:   type of file handle
+ * @get_inode: filesystem callback to retrieve inode
+ *
+ * This function decodes @fid as long as it has one of the well-known
+ * Linux filehandle types and calls @get_inode on it to retrieve the
+ * inode for the object specified in the file handle.
+ */
+struct dentry *generic_fh_to_dentry(struct super_block *sb, struct fid *fid,
+               int fh_len, int fh_type, struct inode *(*get_inode)
+                       (struct super_block *sb, u64 ino, u32 gen))
+{
+       struct inode *inode = NULL;
+
+       if (fh_len < 2)
+               return NULL;
+
+       switch (fh_type) {
+       case FILEID_INO32_GEN:
+       case FILEID_INO32_GEN_PARENT:
+               inode = get_inode(sb, fid->i32.ino, fid->i32.gen);
+               break;
+       }
+
+       return exportfs_d_alloc(inode);
+}
+EXPORT_SYMBOL_GPL(generic_fh_to_dentry);
+
+/**
+ * generic_fh_to_dentry - generic helper for the fh_to_parent export operation
+ * @sb:                filesystem to do the file handle conversion on
+ * @fid:       file handle to convert
+ * @fh_len:    length of the file handle in bytes
+ * @fh_type:   type of file handle
+ * @get_inode: filesystem callback to retrieve inode
+ *
+ * This function decodes @fid as long as it has one of the well-known
+ * Linux filehandle types and calls @get_inode on it to retrieve the
+ * inode for the _parent_ object specified in the file handle if it
+ * is specified in the file handle, or NULL otherwise.
+ */
+struct dentry *generic_fh_to_parent(struct super_block *sb, struct fid *fid,
+               int fh_len, int fh_type, struct inode *(*get_inode)
+                       (struct super_block *sb, u64 ino, u32 gen))
+{
+       struct inode *inode = NULL;
+
+       if (fh_len <= 2)
+               return NULL;
+
+       switch (fh_type) {
+       case FILEID_INO32_GEN_PARENT:
+               inode = get_inode(sb, fid->i32.parent_ino,
+                                 (fh_len > 3 ? fid->i32.parent_gen : 0));
+               break;
+       }
+
+       return exportfs_d_alloc(inode);
+}
+EXPORT_SYMBOL_GPL(generic_fh_to_parent);
+
 EXPORT_SYMBOL(dcache_dir_close);
 EXPORT_SYMBOL(dcache_dir_lseek);
 EXPORT_SYMBOL(dcache_dir_open);
index 464eeccb675be82378a7d9d7a69b7498cf5b106a..3b993db26cee2c2df753f883239e6e917039bd38 100644 (file)
@@ -1174,7 +1174,7 @@ static int fastcall do_path_lookup(int dfd, const char *name,
 out:
        if (unlikely(!retval && !audit_dummy_context() && nd->dentry &&
                                nd->dentry->d_inode))
-               audit_inode(name, nd->dentry->d_inode);
+               audit_inode(name, nd->dentry);
 out_fail:
        return retval;
 
@@ -1214,7 +1214,7 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
        retval = path_walk(name, nd);
        if (unlikely(!retval && !audit_dummy_context() && nd->dentry &&
                                nd->dentry->d_inode))
-               audit_inode(name, nd->dentry->d_inode);
+               audit_inode(name, nd->dentry);
 
        return retval;
 
@@ -1469,7 +1469,7 @@ static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
                return -ENOENT;
 
        BUG_ON(victim->d_parent->d_inode != dir);
-       audit_inode_child(victim->d_name.name, victim->d_inode, dir);
+       audit_inode_child(victim->d_name.name, victim, dir);
 
        error = permission(dir,MAY_WRITE | MAY_EXEC, NULL);
        if (error)
@@ -1659,8 +1659,10 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
                error = locks_verify_locked(inode);
                if (!error) {
                        DQUOT_INIT(inode);
-                       
-                       error = do_truncate(dentry, 0, ATTR_MTIME|ATTR_CTIME, NULL);
+
+                       error = do_truncate(dentry, 0,
+                                           ATTR_MTIME|ATTR_CTIME|ATTR_OPEN,
+                                           NULL);
                }
                put_write_access(inode);
                if (error)
@@ -1781,7 +1783,7 @@ do_last:
         * It already exists.
         */
        mutex_unlock(&dir->d_inode->i_mutex);
-       audit_inode(pathname, path.dentry->d_inode);
+       audit_inode(pathname, path.dentry);
 
        error = -EEXIST;
        if (flag & O_EXCL)
@@ -2560,7 +2562,7 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
        if (!error) {
                const char *new_name = old_dentry->d_name.name;
                fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir,
-                             new_dentry->d_inode, old_dentry->d_inode);
+                             new_dentry->d_inode, old_dentry);
        }
        fsnotify_oldname_free(old_name);
 
index 07daa797259184f1c4cd181cf09f04156bd4dabe..06083885b21e85314e3a196d13c7822dcc7c6e9d 100644 (file)
@@ -246,7 +246,7 @@ static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root,
                        list_add(&mnt->mnt_slave, &old->mnt_slave_list);
                        mnt->mnt_master = old;
                        CLEAR_MNT_SHARED(mnt);
-               } else {
+               } else if (!(flag & CL_PRIVATE)) {
                        if ((flag & CL_PROPAGATION) || IS_MNT_SHARED(old))
                                list_add(&mnt->mnt_share, &old->mnt_share);
                        if (IS_MNT_SLAVE(old))
@@ -746,6 +746,26 @@ Enomem:
        return NULL;
 }
 
+struct vfsmount *collect_mounts(struct vfsmount *mnt, struct dentry *dentry)
+{
+       struct vfsmount *tree;
+       down_read(&namespace_sem);
+       tree = copy_tree(mnt, dentry, CL_COPY_ALL | CL_PRIVATE);
+       up_read(&namespace_sem);
+       return tree;
+}
+
+void drop_collected_mounts(struct vfsmount *mnt)
+{
+       LIST_HEAD(umount_list);
+       down_read(&namespace_sem);
+       spin_lock(&vfsmount_lock);
+       umount_tree(mnt, 0, &umount_list);
+       spin_unlock(&vfsmount_lock);
+       up_read(&namespace_sem);
+       release_mounts(&umount_list);
+}
+
 /*
  *  @source_mnt : mount tree to be attached
  *  @nd         : place the mount tree @source_mnt is attached
@@ -1411,7 +1431,7 @@ long do_mount(char *dev_name, char *dir_name, char *type_page,
                mnt_flags |= MNT_RELATIME;
 
        flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE |
-                  MS_NOATIME | MS_NODIRATIME | MS_RELATIME);
+                  MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT);
 
        /* ... and get the mountpoint */
        retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd);
index af8b235d405dba2ea74c260fd13aba31a5ac46f1..11833f4caeaa9a2ea5549675636330a689c0e80b 100644 (file)
@@ -168,7 +168,8 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
        spin_unlock(&inode->i_lock);
 
        spin_unlock(&clp->cl_lock);
-       kfree(delegation);
+       if (delegation != NULL)
+               nfs_free_delegation(delegation);
        return status;
 }
 
index 8ec7fbd8240c2ed37c24e0f342b72c90a1a3a212..35334539d9475dc0188bdb80f4a1d15ef70b56a9 100644 (file)
@@ -562,6 +562,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
        nfs_fattr_init(&fattr);
        desc->entry = &my_entry;
 
+       nfs_block_sillyrename(dentry);
        while(!desc->entry->eof) {
                res = readdir_search_pagecache(desc);
 
@@ -592,6 +593,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
                        break;
                }
        }
+       nfs_unblock_sillyrename(dentry);
        unlock_kernel();
        if (res > 0)
                res = 0;
@@ -866,6 +868,7 @@ struct dentry_operations nfs_dentry_operations = {
 static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
 {
        struct dentry *res;
+       struct dentry *parent;
        struct inode *inode = NULL;
        int error;
        struct nfs_fh fhandle;
@@ -894,26 +897,31 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
                goto out_unlock;
        }
 
+       parent = dentry->d_parent;
+       /* Protect against concurrent sillydeletes */
+       nfs_block_sillyrename(parent);
        error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr);
        if (error == -ENOENT)
                goto no_entry;
        if (error < 0) {
                res = ERR_PTR(error);
-               goto out_unlock;
+               goto out_unblock_sillyrename;
        }
        inode = nfs_fhget(dentry->d_sb, &fhandle, &fattr);
        res = (struct dentry *)inode;
        if (IS_ERR(res))
-               goto out_unlock;
+               goto out_unblock_sillyrename;
 
 no_entry:
        res = d_materialise_unique(dentry, inode);
        if (res != NULL) {
                if (IS_ERR(res))
-                       goto out_unlock;
+                       goto out_unblock_sillyrename;
                dentry = res;
        }
        nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
+out_unblock_sillyrename:
+       nfs_unblock_sillyrename(parent);
 out_unlock:
        unlock_kernel();
 out:
index d29f90d00aa24298882785747996bd5427193afe..b3bb89f7d5d2856719a705e37ddb320b7a285127 100644 (file)
@@ -131,7 +131,7 @@ nfs_file_release(struct inode *inode, struct file *filp)
 {
        /* Ensure that dirty pages are flushed out with the right creds */
        if (filp->f_mode & FMODE_WRITE)
-               filemap_fdatawrite(filp->f_mapping);
+               nfs_wb_all(filp->f_path.dentry->d_inode);
        nfs_inc_stats(inode, NFSIOS_VFSRELEASE);
        return NFS_PROTO(inode)->file_release(inode, filp);
 }
index 6c22453d77aea6071622f6d2d104d1b6c258d223..db5d96dc6107d5cb8b21235963fd4a950728401f 100644 (file)
@@ -357,6 +357,10 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
 
        nfs_inc_stats(inode, NFSIOS_VFSSETATTR);
 
+       /* skip mode change if it's just for clearing setuid/setgid */
+       if (attr->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
+               attr->ia_valid &= ~ATTR_MODE;
+
        if (attr->ia_valid & ATTR_SIZE) {
                if (!S_ISREG(inode->i_mode) || attr->ia_size == i_size_read(inode))
                        attr->ia_valid &= ~ATTR_SIZE;
@@ -510,7 +514,7 @@ struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx)
        return ctx;
 }
 
-void put_nfs_open_context(struct nfs_open_context *ctx)
+static void __put_nfs_open_context(struct nfs_open_context *ctx, int wait)
 {
        struct inode *inode = ctx->path.dentry->d_inode;
 
@@ -518,8 +522,12 @@ void put_nfs_open_context(struct nfs_open_context *ctx)
                return;
        list_del(&ctx->list);
        spin_unlock(&inode->i_lock);
-       if (ctx->state != NULL)
-               nfs4_close_state(&ctx->path, ctx->state, ctx->mode);
+       if (ctx->state != NULL) {
+               if (wait)
+                       nfs4_close_sync(&ctx->path, ctx->state, ctx->mode);
+               else
+                       nfs4_close_state(&ctx->path, ctx->state, ctx->mode);
+       }
        if (ctx->cred != NULL)
                put_rpccred(ctx->cred);
        dput(ctx->path.dentry);
@@ -527,6 +535,16 @@ void put_nfs_open_context(struct nfs_open_context *ctx)
        kfree(ctx);
 }
 
+void put_nfs_open_context(struct nfs_open_context *ctx)
+{
+       __put_nfs_open_context(ctx, 0);
+}
+
+static void put_nfs_open_context_sync(struct nfs_open_context *ctx)
+{
+       __put_nfs_open_context(ctx, 1);
+}
+
 /*
  * Ensure that mmap has a recent RPC credential for use when writing out
  * shared pages
@@ -573,7 +591,7 @@ static void nfs_file_clear_open_context(struct file *filp)
                spin_lock(&inode->i_lock);
                list_move_tail(&ctx->list, &NFS_I(inode)->open_files);
                spin_unlock(&inode->i_lock);
-               put_nfs_open_context(ctx);
+               put_nfs_open_context_sync(ctx);
        }
 }
 
@@ -1165,6 +1183,9 @@ static void init_once(struct kmem_cache * cachep, void *foo)
        INIT_RADIX_TREE(&nfsi->nfs_page_tree, GFP_ATOMIC);
        nfsi->ncommit = 0;
        nfsi->npages = 0;
+       atomic_set(&nfsi->silly_count, 1);
+       INIT_HLIST_HEAD(&nfsi->silly_list);
+       init_waitqueue_head(&nfsi->waitqueue);
        nfs4_init_once(nfsi);
 }
 
index d2802b1ca3b9b84d57efbadd789c019094e2bc2e..b35069a2aa9e575bd81fa09f59b67048718cca48 100644 (file)
@@ -178,7 +178,7 @@ extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struc
 extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *);
 extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *);
 extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *);
-extern int nfs4_do_close(struct path *path, struct nfs4_state *state);
+extern int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait);
 extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
 extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *);
 extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle);
@@ -209,6 +209,7 @@ extern void nfs4_drop_state_owner(struct nfs4_state_owner *);
 extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *);
 extern void nfs4_put_open_state(struct nfs4_state *);
 extern void nfs4_close_state(struct path *, struct nfs4_state *, mode_t);
+extern void nfs4_close_sync(struct path *, struct nfs4_state *, mode_t);
 extern void nfs4_state_set_mode_locked(struct nfs4_state *, mode_t);
 extern void nfs4_schedule_state_recovery(struct nfs_client *);
 extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp);
@@ -235,6 +236,7 @@ extern struct svc_version nfs4_callback_version1;
 #else
 
 #define nfs4_close_state(a, b, c) do { } while (0)
+#define nfs4_close_sync(a, b, c) do { } while (0)
 
 #endif /* CONFIG_NFS_V4 */
 #endif /* __LINUX_FS_NFS_NFS4_FS.H */
index cb99fd90a9acc5147135bb70846517ad8e79165e..f03d9d5f5ba40d9d3db91a1dbb4ef43d74ab64bc 100644 (file)
@@ -1305,7 +1305,7 @@ static const struct rpc_call_ops nfs4_close_ops = {
  *
  * NOTE: Caller must be holding the sp->so_owner semaphore!
  */
-int nfs4_do_close(struct path *path, struct nfs4_state *state)
+int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
 {
        struct nfs_server *server = NFS_SERVER(state->inode);
        struct nfs4_closedata *calldata;
@@ -1333,8 +1333,11 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state)
        task = rpc_run_task(server->client, RPC_TASK_ASYNC, &nfs4_close_ops, calldata);
        if (IS_ERR(task))
                return PTR_ERR(task);
+       status = 0;
+       if (wait)
+               status = rpc_wait_for_completion_task(task);
        rpc_put_task(task);
-       return 0;
+       return status;
 out_free_calldata:
        kfree(calldata);
 out:
@@ -1365,13 +1368,14 @@ static int nfs4_intent_set_file(struct nameidata *nd, struct path *path, struct
        }
        ret = PTR_ERR(filp);
 out_close:
-       nfs4_close_state(path, state, nd->intent.open.flags);
+       nfs4_close_sync(path, state, nd->intent.open.flags);
        return ret;
 }
 
 struct dentry *
 nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
 {
+       struct dentry *parent;
        struct path path = {
                .mnt = nd->mnt,
                .dentry = dentry,
@@ -1394,6 +1398,9 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
        cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0);
        if (IS_ERR(cred))
                return (struct dentry *)cred;
+       parent = dentry->d_parent;
+       /* Protect against concurrent sillydeletes */
+       nfs_block_sillyrename(parent);
        state = nfs4_do_open(dir, &path, nd->intent.open.flags, &attr, cred);
        put_rpccred(cred);
        if (IS_ERR(state)) {
@@ -1401,12 +1408,14 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
                        d_add(dentry, NULL);
                        nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
                }
+               nfs_unblock_sillyrename(parent);
                return (struct dentry *)state;
        }
        res = d_add_unique(dentry, igrab(state->inode));
        if (res != NULL)
                path.dentry = res;
        nfs_set_verifier(path.dentry, nfs_save_change_attribute(dir));
+       nfs_unblock_sillyrename(parent);
        nfs4_intent_set_file(nd, &path, state);
        return res;
 }
@@ -1444,7 +1453,7 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st
                nfs4_intent_set_file(nd, &path, state);
                return 1;
        }
-       nfs4_close_state(&path, state, openflags);
+       nfs4_close_sync(&path, state, openflags);
 out_drop:
        d_drop(dentry);
        return 0;
@@ -1898,7 +1907,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
        if (status == 0 && (nd->flags & LOOKUP_OPEN) != 0)
                status = nfs4_intent_set_file(nd, &path, state);
        else
-               nfs4_close_state(&path, state, flags);
+               nfs4_close_sync(&path, state, flags);
 out:
        return status;
 }
index bfb36261cecb2ba6a542690b20ab3a573789d5e1..23a9a36556bf5f5ca4dba357157cbb35dc9ac331 100644 (file)
@@ -425,7 +425,7 @@ void nfs4_put_open_state(struct nfs4_state *state)
 /*
  * Close the current file.
  */
-void nfs4_close_state(struct path *path, struct nfs4_state *state, mode_t mode)
+static void __nfs4_close(struct path *path, struct nfs4_state *state, mode_t mode, int wait)
 {
        struct nfs4_state_owner *owner = state->owner;
        int call_close = 0;
@@ -466,7 +466,17 @@ void nfs4_close_state(struct path *path, struct nfs4_state *state, mode_t mode)
                nfs4_put_open_state(state);
                nfs4_put_state_owner(owner);
        } else
-               nfs4_do_close(path, state);
+               nfs4_do_close(path, state, wait);
+}
+
+void nfs4_close_state(struct path *path, struct nfs4_state *state, mode_t mode)
+{
+       __nfs4_close(path, state, mode, 0);
+}
+
+void nfs4_close_sync(struct path *path, struct nfs4_state *state, mode_t mode)
+{
+       __nfs4_close(path, state, mode, 1);
 }
 
 /*
index e87b44ee9ac9b0490e00de2dd420e4cb1bcebb46..4b0334590ee5ebdd959fc29e629312296a767aed 100644 (file)
@@ -43,7 +43,7 @@
  *                             from being used (thanks to Leo Spiekman)
  *     Andy Walker     :       Allow to specify the NFS server in nfs_root
  *                             without giving a path name
- *     Swen Thümmler   :       Allow to specify the NFS options in nfs_root
+ *     Swen Thümmler  :       Allow to specify the NFS options in nfs_root
  *                             without giving a path name. Fix BOOTP request
  *                             for domainname (domainname is NIS domain, not
  *                             DNS domain!). Skip dummy devices for BOOTP.
index 97669ed05500c6277387f1b0323d53b6face4950..4f80d88e9fee005d69bd2d279ddeb5dc8bb4fd2f 100644 (file)
@@ -211,6 +211,7 @@ nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
        nfs_fattr_init(&fattr);
        dprintk("NFS call  create %s\n", dentry->d_name.name);
        status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+       nfs_mark_for_revalidate(dir);
        if (status == 0)
                status = nfs_instantiate(dentry, &fhandle, &fattr);
        dprintk("NFS reply create: %d\n", status);
index 1aed850d18f2ebab29f2b6b7077f4effb85413ff..233ad38161f924095e12e26ed4955337b16cdec6 100644 (file)
 #include <linux/sunrpc/sched.h>
 #include <linux/sunrpc/clnt.h>
 #include <linux/nfs_fs.h>
-
+#include <linux/sched.h>
+#include <linux/wait.h>
 
 struct nfs_unlinkdata {
+       struct hlist_node list;
        struct nfs_removeargs args;
        struct nfs_removeres res;
        struct inode *dir;
@@ -52,6 +54,20 @@ static int nfs_copy_dname(struct dentry *dentry, struct nfs_unlinkdata *data)
        return 0;
 }
 
+static void nfs_free_dname(struct nfs_unlinkdata *data)
+{
+       kfree(data->args.name.name);
+       data->args.name.name = NULL;
+       data->args.name.len = 0;
+}
+
+static void nfs_dec_sillycount(struct inode *dir)
+{
+       struct nfs_inode *nfsi = NFS_I(dir);
+       if (atomic_dec_return(&nfsi->silly_count) == 1)
+               wake_up(&nfsi->waitqueue);
+}
+
 /**
  * nfs_async_unlink_init - Initialize the RPC info
  * task: rpc_task of the sillydelete
@@ -95,6 +111,8 @@ static void nfs_async_unlink_done(struct rpc_task *task, void *calldata)
 static void nfs_async_unlink_release(void *calldata)
 {
        struct nfs_unlinkdata   *data = calldata;
+
+       nfs_dec_sillycount(data->dir);
        nfs_free_unlinkdata(data);
 }
 
@@ -104,33 +122,100 @@ static const struct rpc_call_ops nfs_unlink_ops = {
        .rpc_release = nfs_async_unlink_release,
 };
 
-static int nfs_call_unlink(struct dentry *dentry, struct nfs_unlinkdata *data)
+static int nfs_do_call_unlink(struct dentry *parent, struct inode *dir, struct nfs_unlinkdata *data)
 {
        struct rpc_task *task;
+       struct dentry *alias;
+
+       alias = d_lookup(parent, &data->args.name);
+       if (alias != NULL) {
+               int ret = 0;
+               /*
+                * Hey, we raced with lookup... See if we need to transfer
+                * the sillyrename information to the aliased dentry.
+                */
+               nfs_free_dname(data);
+               spin_lock(&alias->d_lock);
+               if (!(alias->d_flags & DCACHE_NFSFS_RENAMED)) {
+                       alias->d_fsdata = data;
+                       alias->d_flags ^= DCACHE_NFSFS_RENAMED;
+                       ret = 1;
+               }
+               spin_unlock(&alias->d_lock);
+               nfs_dec_sillycount(dir);
+               dput(alias);
+               return ret;
+       }
+       data->dir = igrab(dir);
+       if (!data->dir) {
+               nfs_dec_sillycount(dir);
+               return 0;
+       }
+       data->args.fh = NFS_FH(dir);
+       nfs_fattr_init(&data->res.dir_attr);
+
+       task = rpc_run_task(NFS_CLIENT(dir), RPC_TASK_ASYNC, &nfs_unlink_ops, data);
+       if (!IS_ERR(task))
+               rpc_put_task(task);
+       return 1;
+}
+
+static int nfs_call_unlink(struct dentry *dentry, struct nfs_unlinkdata *data)
+{
        struct dentry *parent;
        struct inode *dir;
+       int ret = 0;
 
-       if (nfs_copy_dname(dentry, data) < 0)
-               goto out_free;
 
        parent = dget_parent(dentry);
        if (parent == NULL)
                goto out_free;
-       dir = igrab(parent->d_inode);
+       dir = parent->d_inode;
+       if (nfs_copy_dname(dentry, data) != 0)
+               goto out_dput;
+       /* Non-exclusive lock protects against concurrent lookup() calls */
+       spin_lock(&dir->i_lock);
+       if (atomic_inc_not_zero(&NFS_I(dir)->silly_count) == 0) {
+               /* Deferred delete */
+               hlist_add_head(&data->list, &NFS_I(dir)->silly_list);
+               spin_unlock(&dir->i_lock);
+               ret = 1;
+               goto out_dput;
+       }
+       spin_unlock(&dir->i_lock);
+       ret = nfs_do_call_unlink(parent, dir, data);
+out_dput:
        dput(parent);
-       if (dir == NULL)
-               goto out_free;
+out_free:
+       return ret;
+}
 
-       data->dir = dir;
-       data->args.fh = NFS_FH(dir);
-       nfs_fattr_init(&data->res.dir_attr);
+void nfs_block_sillyrename(struct dentry *dentry)
+{
+       struct nfs_inode *nfsi = NFS_I(dentry->d_inode);
 
-       task = rpc_run_task(NFS_CLIENT(dir), RPC_TASK_ASYNC, &nfs_unlink_ops, data);
-       if (!IS_ERR(task))
-               rpc_put_task(task);
-       return 1;
-out_free:
-       return 0;
+       wait_event(nfsi->waitqueue, atomic_cmpxchg(&nfsi->silly_count, 1, 0) == 1);
+}
+
+void nfs_unblock_sillyrename(struct dentry *dentry)
+{
+       struct inode *dir = dentry->d_inode;
+       struct nfs_inode *nfsi = NFS_I(dir);
+       struct nfs_unlinkdata *data;
+
+       atomic_inc(&nfsi->silly_count);
+       spin_lock(&dir->i_lock);
+       while (!hlist_empty(&nfsi->silly_list)) {
+               if (!atomic_inc_not_zero(&nfsi->silly_count))
+                       break;
+               data = hlist_entry(nfsi->silly_list.first, struct nfs_unlinkdata, list);
+               hlist_del(&data->list);
+               spin_unlock(&dir->i_lock);
+               if (nfs_do_call_unlink(dentry, dir, data) == 0)
+                       nfs_free_unlinkdata(data);
+               spin_lock(&dir->i_lock);
+       }
+       spin_unlock(&dir->i_lock);
 }
 
 /**
index 0cf9d1cd9bd256c1f1ff4928f523fb48788b3b41..89527a487ed7d5365464bd6fe537c9014cfce117 100644 (file)
@@ -174,8 +174,6 @@ static void nfs_mark_uptodate(struct page *page, unsigned int base, unsigned int
                return;
        if (count != nfs_page_length(page))
                return;
-       if (count != PAGE_CACHE_SIZE)
-               zero_user_page(page, count, PAGE_CACHE_SIZE - count, KM_USER0);
        SetPageUptodate(page);
 }
 
@@ -627,7 +625,8 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx,
                                return ERR_PTR(error);
                        }
                        spin_unlock(&inode->i_lock);
-                       return new;
+                       req = new;
+                       goto zero_page;
                }
                spin_unlock(&inode->i_lock);
 
@@ -655,13 +654,23 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx,
        if (offset < req->wb_offset) {
                req->wb_offset = offset;
                req->wb_pgbase = offset;
-               req->wb_bytes = rqend - req->wb_offset;
+               req->wb_bytes = max(end, rqend) - req->wb_offset;
+               goto zero_page;
        }
 
        if (end > rqend)
                req->wb_bytes = end - req->wb_offset;
 
        return req;
+zero_page:
+       /* If this page might potentially be marked as up to date,
+        * then we need to zero any uninitalised data. */
+       if (req->wb_pgbase == 0 && req->wb_bytes != PAGE_CACHE_SIZE
+                       && !PageUptodate(req->wb_page))
+               zero_user_page(req->wb_page, req->wb_bytes,
+                               PAGE_CACHE_SIZE - req->wb_bytes,
+                               KM_USER0);
+       return req;
 }
 
 int nfs_flush_incompatible(struct file *file, struct page *page)
index 04b266729802f698c1203577c4ad52a78ed71ae6..66d0aeb32a47e5f4385e68c1947a8d8c1ab3a7e5 100644 (file)
@@ -386,15 +386,13 @@ static int check_export(struct inode *inode, int flags, unsigned char *uuid)
                dprintk("exp_export: export of non-dev fs without fsid\n");
                return -EINVAL;
        }
-       if (!inode->i_sb->s_export_op) {
+
+       if (!inode->i_sb->s_export_op ||
+           !inode->i_sb->s_export_op->fh_to_dentry) {
                dprintk("exp_export: export of invalid fs type.\n");
                return -EINVAL;
        }
 
-       /* Ok, we can export it */;
-       if (!inode->i_sb->s_export_op->find_exported_dentry)
-               inode->i_sb->s_export_op->find_exported_dentry =
-                       find_exported_dentry;
        return 0;
 
 }
index ebd03cc07479e78ccdd0e4b62f9c1c0ee7619da2..6f03918018a3106b0ffdedb0da170c5613a05c69 100644 (file)
@@ -88,7 +88,7 @@ nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname)
 {
        struct xdr_netobj cksum;
        struct hash_desc desc;
-       struct scatterlist sg[1];
+       struct scatterlist sg;
        __be32 status = nfserr_resource;
 
        dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n",
@@ -102,11 +102,9 @@ nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname)
        if (cksum.data == NULL)
                goto out;
 
-       sg[0].page = virt_to_page(clname->data);
-       sg[0].offset = offset_in_page(clname->data);
-       sg[0].length = clname->len;
+       sg_init_one(&sg, clname->data, clname->len);
 
-       if (crypto_hash_digest(&desc, sg, sg->length, cksum.data))
+       if (crypto_hash_digest(&desc, &sg, sg.length, cksum.data))
                goto out;
 
        md5_to_hex(dname, cksum.data);
index 7011d62acfc8dd3516b52961ad598a8371fcc08d..4f712e970584939847ed8287ffa0e379cea177e4 100644 (file)
@@ -115,8 +115,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
        dprintk("nfsd: fh_verify(%s)\n", SVCFH_fmt(fhp));
 
        if (!fhp->fh_dentry) {
-               __u32 *datap=NULL;
-               __u32 tfh[3];           /* filehandle fragment for oldstyle filehandles */
+               struct fid *fid = NULL, sfid;
                int fileid_type;
                int data_left = fh->fh_size/4;
 
@@ -128,7 +127,6 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
 
                if (fh->fh_version == 1) {
                        int len;
-                       datap = fh->fh_auth;
                        if (--data_left<0) goto out;
                        switch (fh->fh_auth_type) {
                        case 0: break;
@@ -144,9 +142,11 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
                                fh->fh_fsid[1] = fh->fh_fsid[2];
                        }
                        if ((data_left -= len)<0) goto out;
-                       exp = rqst_exp_find(rqstp, fh->fh_fsid_type, datap);
-                       datap += len;
+                       exp = rqst_exp_find(rqstp, fh->fh_fsid_type,
+                                           fh->fh_auth);
+                       fid = (struct fid *)(fh->fh_auth + len);
                } else {
+                       __u32 tfh[2];
                        dev_t xdev;
                        ino_t xino;
                        if (fh->fh_size != NFS_FHSIZE)
@@ -190,22 +190,22 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
                        error = nfserr_badhandle;
 
                if (fh->fh_version != 1) {
-                       tfh[0] = fh->ofh_ino;
-                       tfh[1] = fh->ofh_generation;
-                       tfh[2] = fh->ofh_dirino;
-                       datap = tfh;
+                       sfid.i32.ino = fh->ofh_ino;
+                       sfid.i32.gen = fh->ofh_generation;
+                       sfid.i32.parent_ino = fh->ofh_dirino;
+                       fid = &sfid;
                        data_left = 3;
                        if (fh->ofh_dirino == 0)
-                               fileid_type = 1;
+                               fileid_type = FILEID_INO32_GEN;
                        else
-                               fileid_type = 2;
+                               fileid_type = FILEID_INO32_GEN_PARENT;
                } else
                        fileid_type = fh->fh_fileid_type;
 
-               if (fileid_type == 0)
+               if (fileid_type == FILEID_ROOT)
                        dentry = dget(exp->ex_dentry);
                else {
-                       dentry = exportfs_decode_fh(exp->ex_mnt, datap,
+                       dentry = exportfs_decode_fh(exp->ex_mnt, fid,
                                        data_left, fileid_type,
                                        nfsd_acceptable, exp);
                }
@@ -286,16 +286,21 @@ out:
  * an inode.  In this case a call to fh_update should be made
  * before the fh goes out on the wire ...
  */
-static inline int _fh_update(struct dentry *dentry, struct svc_export *exp,
-                            __u32 *datap, int *maxsize)
+static void _fh_update(struct svc_fh *fhp, struct svc_export *exp,
+               struct dentry *dentry)
 {
-       if (dentry == exp->ex_dentry) {
-               *maxsize = 0;
-               return 0;
-       }
+       if (dentry != exp->ex_dentry) {
+               struct fid *fid = (struct fid *)
+                       (fhp->fh_handle.fh_auth + fhp->fh_handle.fh_size/4 - 1);
+               int maxsize = (fhp->fh_maxsize - fhp->fh_handle.fh_size)/4;
+               int subtreecheck = !(exp->ex_flags & NFSEXP_NOSUBTREECHECK);
 
-       return exportfs_encode_fh(dentry, datap, maxsize,
-                         !(exp->ex_flags & NFSEXP_NOSUBTREECHECK));
+               fhp->fh_handle.fh_fileid_type =
+                       exportfs_encode_fh(dentry, fid, &maxsize, subtreecheck);
+               fhp->fh_handle.fh_size += maxsize * 4;
+       } else {
+               fhp->fh_handle.fh_fileid_type = FILEID_ROOT;
+       }
 }
 
 /*
@@ -457,12 +462,8 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry,
                datap += len/4;
                fhp->fh_handle.fh_size = 4 + len;
 
-               if (inode) {
-                       int size = (fhp->fh_maxsize-len-4)/4;
-                       fhp->fh_handle.fh_fileid_type =
-                               _fh_update(dentry, exp, datap, &size);
-                       fhp->fh_handle.fh_size += size*4;
-               }
+               if (inode)
+                       _fh_update(fhp, exp, dentry);
                if (fhp->fh_handle.fh_fileid_type == 255)
                        return nfserr_opnotsupp;
        }
@@ -479,7 +480,6 @@ __be32
 fh_update(struct svc_fh *fhp)
 {
        struct dentry *dentry;
-       __u32 *datap;
 
        if (!fhp->fh_dentry)
                goto out_bad;
@@ -490,15 +490,10 @@ fh_update(struct svc_fh *fhp)
        if (fhp->fh_handle.fh_version != 1) {
                _fh_update_old(dentry, fhp->fh_export, &fhp->fh_handle);
        } else {
-               int size;
-               if (fhp->fh_handle.fh_fileid_type != 0)
+               if (fhp->fh_handle.fh_fileid_type != FILEID_ROOT)
                        goto out;
-               datap = fhp->fh_handle.fh_auth+
-                       fhp->fh_handle.fh_size/4 -1;
-               size = (fhp->fh_maxsize - fhp->fh_handle.fh_size)/4;
-               fhp->fh_handle.fh_fileid_type =
-                       _fh_update(dentry, fhp->fh_export, datap, &size);
-               fhp->fh_handle.fh_size += size*4;
+
+               _fh_update(fhp, fhp->fh_export, dentry);
                if (fhp->fh_handle.fh_fileid_type == 255)
                        return nfserr_opnotsupp;
        }
index 819545d216706be7447392a482328b37d4d3cb5c..d0199189924cee7d5ea49aafd52dcc81fab21df2 100644 (file)
@@ -364,14 +364,23 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
        if (iap->ia_valid & ATTR_MODE) {
                iap->ia_mode &= S_IALLUGO;
                imode = iap->ia_mode |= (imode & ~S_IALLUGO);
+               /* if changing uid/gid revoke setuid/setgid in mode */
+               if ((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid) {
+                       iap->ia_valid |= ATTR_KILL_PRIV;
+                       iap->ia_mode &= ~S_ISUID;
+               }
+               if ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid)
+                       iap->ia_mode &= ~S_ISGID;
+       } else {
+               /*
+                * Revoke setuid/setgid bit on chown/chgrp
+                */
+               if ((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid)
+                       iap->ia_valid |= ATTR_KILL_SUID | ATTR_KILL_PRIV;
+               if ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid)
+                       iap->ia_valid |= ATTR_KILL_SGID;
        }
 
-       /* Revoke setuid/setgid bit on chown/chgrp */
-       if ((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid)
-               iap->ia_valid |= ATTR_KILL_SUID | ATTR_KILL_PRIV;
-       if ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid)
-               iap->ia_valid |= ATTR_KILL_SGID;
-
        /* Change the attributes. */
 
        iap->ia_valid |= ATTR_CTIME;
@@ -1020,13 +1029,13 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
                if (EX_WGATHER(exp)) {
                        if (atomic_read(&inode->i_writecount) > 1
                            || (last_ino == inode->i_ino && last_dev == inode->i_sb->s_dev)) {
-                               dprintk("nfsd: write defer %d\n", current->pid);
+                               dprintk("nfsd: write defer %d\n", task_pid_nr(current));
                                msleep(10);
-                               dprintk("nfsd: write resume %d\n", current->pid);
+                               dprintk("nfsd: write resume %d\n", task_pid_nr(current));
                        }
 
                        if (inode->i_state & I_DIRTY) {
-                               dprintk("nfsd: write sync %d\n", current->pid);
+                               dprintk("nfsd: write sync %d\n", task_pid_nr(current));
                                host_err=nfsd_sync(file);
                        }
 #if 0
index e7905816c4caa1dce9b471bced589051e53da3e7..64965e1c21c46ca2dcb9aae20611a0725e9d4f4b 100644 (file)
@@ -111,7 +111,7 @@ utf8_wctomb(__u8 *s, wchar_t wc, int maxlen)
        int c, nc;
        const struct utf8_table *t;
   
-       if (s == 0)
+       if (!s)
                return 0;
   
        l = wc;
index 345798ebd366b85019bd163d42e11a9be39cd098..37c11e1943722aeb351683c768b058dfeffae8fa 100644 (file)
@@ -382,7 +382,7 @@ ToDo/Notes:
          own locking so it does not matter if the vfs inode is locked.
        - Fix bug in mft record writing where we forgot to set the device in
          the buffers when mapping them after the VM had discarded them.
-         Thanks to Martin MOKREJŠ for the bug report.
+         Thanks to Martin MOKREJÅ for the bug report.
 
 2.1.22 - Many bug and race fixes and error handling improvements.
 
@@ -1585,7 +1585,7 @@ tng-0.0.4 - Big changes, getting in line with Al Viro's comments.
          for reading $MFT (ntfs_mft_readpage). In the process create dedicated
          address space operations (ntfs_mft_aops) for $MFT inode mapping. Also
          removed the now superfluous exports from the kernel core patch.
-       - Fix a bug where kfree() was used insted of ntfs_free().
+       - Fix a bug where kfree() was used instead of ntfs_free().
        - Change map_mft_record() to take ntfs_inode as argument instead of
          vfs inode. Dito for unmap_mft_record(). Adapt all callers.
        - Add pointer to ntfs_volume to ntfs_inode.
index e93c6142b23c9554932342129ef5a6e35eb8b90a..e1781c8b16504cf9c59333c3ac5b7475b9978578 100644 (file)
@@ -450,58 +450,40 @@ try_next:
        return parent_dent;
 }
 
-/**
- * ntfs_get_dentry - find a dentry for the inode from a file handle sub-fragment
- * @sb:                super block identifying the mounted ntfs volume
- * @fh:                the file handle sub-fragment
- *
- * Find a dentry for the inode given a file handle sub-fragment.  This function
- * is called from fs/exportfs/expfs.c::find_exported_dentry() which in turn is
- * called from the default ->decode_fh() which is export_decode_fh() in the
- * same file.  The code is closely based on the default ->get_dentry() helper
- * fs/exportfs/expfs.c::get_object().
- *
- * The @fh contains two 32-bit unsigned values, the first one is the inode
- * number and the second one is the inode generation.
- *
- * Return the dentry on success or the error code on error (IS_ERR() is true).
- */
-static struct dentry *ntfs_get_dentry(struct super_block *sb, void *fh)
+static struct inode *ntfs_nfs_get_inode(struct super_block *sb,
+               u64 ino, u32 generation)
 {
-       struct inode *vi;
-       struct dentry *dent;
-       unsigned long ino = ((u32 *)fh)[0];
-       u32 gen = ((u32 *)fh)[1];
+       struct inode *inode;
 
-       ntfs_debug("Entering for inode 0x%lx, generation 0x%x.", ino, gen);
-       vi = ntfs_iget(sb, ino);
-       if (IS_ERR(vi)) {
-               ntfs_error(sb, "Failed to get inode 0x%lx.", ino);
-               return (struct dentry *)vi;
-       }
-       if (unlikely(is_bad_inode(vi) || vi->i_generation != gen)) {
-               /* We didn't find the right inode. */
-               ntfs_error(sb, "Inode 0x%lx, bad count: %d %d or version 0x%x "
-                               "0x%x.", vi->i_ino, vi->i_nlink,
-                               atomic_read(&vi->i_count), vi->i_generation,
-                               gen);
-               iput(vi);
-               return ERR_PTR(-ESTALE);
-       }
-       /* Now find a dentry.  If possible, get a well-connected one. */
-       dent = d_alloc_anon(vi);
-       if (unlikely(!dent)) {
-               iput(vi);
-               return ERR_PTR(-ENOMEM);
+       inode = ntfs_iget(sb, ino);
+       if (!IS_ERR(inode)) {
+               if (is_bad_inode(inode) || inode->i_generation != generation) {
+                       iput(inode);
+                       inode = ERR_PTR(-ESTALE);
+               }
        }
-       ntfs_debug("Done for inode 0x%lx, generation 0x%x.", ino, gen);
-       return dent;
+
+       return inode;
+}
+
+static struct dentry *ntfs_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,
+                                   ntfs_nfs_get_inode);
+}
+
+static struct dentry *ntfs_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,
+                                   ntfs_nfs_get_inode);
 }
 
 /**
  * Export operations allowing NFS exporting of mounted NTFS partitions.
  *
- * We use the default ->decode_fh() and ->encode_fh() for now.  Note that they
+ * We use the default ->encode_fh() for now.  Note that they
  * use 32 bits to store the inode number which is an unsigned long so on 64-bit
  * architectures is usually 64 bits so it would all fail horribly on huge
  * volumes.  I guess we need to define our own encode and decode fh functions
@@ -517,10 +499,9 @@ static struct dentry *ntfs_get_dentry(struct super_block *sb, void *fh)
  * allowing the inode number 0 which is used in NTFS for the system file $MFT
  * and due to using iget() whereas NTFS needs ntfs_iget().
  */
-struct export_operations ntfs_export_ops = {
+const struct export_operations ntfs_export_ops = {
        .get_parent     = ntfs_get_parent,      /* Find the parent of a given
                                                   directory. */
-       .get_dentry     = ntfs_get_dentry,      /* Find a dentry for the inode
-                                                  given a file handle
-                                                  sub-fragment. */
+       .fh_to_dentry   = ntfs_fh_to_dentry,
+       .fh_to_parent   = ntfs_fh_to_parent,
 };
index d73f5a9ac341b62d658ecf81dd8d3eebf142c685..d6a340bf80fce0e18909e037901e293c728dc27b 100644 (file)
@@ -69,7 +69,7 @@ extern const struct inode_operations ntfs_dir_inode_ops;
 extern const struct  file_operations ntfs_empty_file_ops;
 extern const struct inode_operations ntfs_empty_inode_ops;
 
-extern struct export_operations ntfs_export_ops;
+extern const struct export_operations ntfs_export_ops;
 
 /**
  * NTFS_SB - return the ntfs volume given a vfs super block
index 4847fbfb0107af9a687dccdd4a77f9c3690bdf02..9ef85e628fe1cf8c181b8cbbeecba86dca31854d 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * sysctl.c - Code for sysctl handling in NTFS Linux kernel driver. Part of
  *           the Linux-NTFS project. Adapted from the old NTFS driver,
- *           Copyright (C) 1997 Martin von Löwis, Régis Duchesne
+ *           Copyright (C) 1997 Martin von Löwis, Régis Duchesne
  *
  * Copyright (c) 2002-2005 Anton Altaparmakov
  *
index beda5bf96405df5f8c630ffe1197395969adf86a..d4f8ce920d95b744616618e8d828ceb047d74253 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * sysctl.h - Defines for sysctl handling in NTFS Linux kernel driver. Part of
  *           the Linux-NTFS project. Adapted from the old NTFS driver,
- *           Copyright (C) 1997 Martin von Löwis, Régis Duchesne
+ *           Copyright (C) 1997 Martin von Löwis, Régis Duchesne
  *
  * Copyright (c) 2002-2004 Anton Altaparmakov
  *
index f14b541fab951d01aae5155a4cbd224c6c807b2e..9cc7c0418b70eb53b04d1904a197feb82b196b24 100644 (file)
@@ -1372,7 +1372,7 @@ static ssize_t o2hb_region_pid_read(struct o2hb_region *reg,
 
        spin_lock(&o2hb_live_lock);
        if (reg->hr_task)
-               pid = reg->hr_task->pid;
+               pid = task_pid_nr(reg->hr_task);
        spin_unlock(&o2hb_live_lock);
 
        if (!pid)
index 75cd877f6d42e17d3687674158a37764826e0633..cd046060114ef4790a0039919bb68e3ff3ab86fd 100644 (file)
@@ -192,7 +192,7 @@ extern struct mlog_bits mlog_and_bits, mlog_not_bits;
  * previous token if args expands to nothing.
  */
 #define __mlog_printk(level, fmt, args...)                             \
-       printk(level "(%u,%lu):%s:%d " fmt, current->pid,               \
+       printk(level "(%u,%lu):%s:%d " fmt, task_pid_nr(current),       \
               __mlog_cpu_guess, __PRETTY_FUNCTION__, __LINE__ ,        \
               ##args)
 
index 014e73978dac074aa406f4494f9e6288515a88a3..3094ddb7a25491b1d2db567707ce7f6a01592c27 100644 (file)
@@ -376,7 +376,7 @@ out:
  * directory locks. The dentries have already been deleted on other
  * nodes via ocfs2_remote_dentry_delete().
  *
- * Normally, the VFS handles the d_move() for the file sytem, after
+ * Normally, the VFS handles the d_move() for the file system, after
  * the ->rename() callback. OCFS2 wants to handle this internally, so
  * the new lock can be created atomically with respect to the cluster.
  */
index a2c33160bfd6838dd17487b49492f6a85e5b3539..2fde7bf91434b0e95faddaf188d193877d803b39 100644 (file)
@@ -259,7 +259,7 @@ static void dlm_print_reco_node_status(struct dlm_ctxt *dlm)
        struct dlm_lock_resource *res;
 
        mlog(ML_NOTICE, "%s(%d): recovery info, state=%s, dead=%u, master=%u\n",
-            dlm->name, dlm->dlm_reco_thread_task->pid,
+            dlm->name, task_pid_nr(dlm->dlm_reco_thread_task),
             dlm->reco.state & DLM_RECO_STATE_ACTIVE ? "ACTIVE" : "inactive",
             dlm->reco.dead_node, dlm->reco.new_master);
 
@@ -420,7 +420,7 @@ void dlm_wait_for_recovery(struct dlm_ctxt *dlm)
        if (dlm_in_recovery(dlm)) {
                mlog(0, "%s: reco thread %d in recovery: "
                     "state=%d, master=%u, dead=%u\n",
-                    dlm->name, dlm->dlm_reco_thread_task->pid,
+                    dlm->name, task_pid_nr(dlm->dlm_reco_thread_task),
                     dlm->reco.state, dlm->reco.new_master,
                     dlm->reco.dead_node);
        }
@@ -483,7 +483,7 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm)
                return 0;
        }
        mlog(0, "%s(%d):recovery thread found node %u in the recovery map!\n",
-            dlm->name, dlm->dlm_reco_thread_task->pid,
+            dlm->name, task_pid_nr(dlm->dlm_reco_thread_task),
             dlm->reco.dead_node);
        spin_unlock(&dlm->spinlock);
 
@@ -507,7 +507,7 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm)
                mlog(0, "another node will master this recovery session.\n");
        }
        mlog(0, "dlm=%s (%d), new_master=%u, this node=%u, dead_node=%u\n",
-            dlm->name, dlm->dlm_reco_thread_task->pid, dlm->reco.new_master,
+            dlm->name, task_pid_nr(dlm->dlm_reco_thread_task), dlm->reco.new_master,
             dlm->node_num, dlm->reco.dead_node);
 
        /* it is safe to start everything back up here
@@ -520,7 +520,7 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm)
 
 master_here:
        mlog(0, "(%d) mastering recovery of %s:%u here(this=%u)!\n",
-            dlm->dlm_reco_thread_task->pid,
+            task_pid_nr(dlm->dlm_reco_thread_task),
             dlm->name, dlm->reco.dead_node, dlm->node_num);
 
        status = dlm_remaster_locks(dlm, dlm->reco.dead_node);
index c3bbc198f9ce66d6a0c4bf2b02bb581932e12ee1..535bfa9568a4af534a9cfbe91a025dd854e2c9f3 100644 (file)
@@ -45,9 +45,9 @@ struct ocfs2_inode_handle
        u32 ih_generation;
 };
 
-static struct dentry *ocfs2_get_dentry(struct super_block *sb, void *vobjp)
+static struct dentry *ocfs2_get_dentry(struct super_block *sb,
+               struct ocfs2_inode_handle *handle)
 {
-       struct ocfs2_inode_handle *handle = vobjp;
        struct inode *inode;
        struct dentry *result;
 
@@ -194,54 +194,37 @@ bail:
        return type;
 }
 
-static struct dentry *ocfs2_decode_fh(struct super_block *sb, u32 *fh_in,
-                                     int fh_len, int fileid_type,
-                                     int (*acceptable)(void *context,
-                                                       struct dentry *de),
-                                     void *context)
+static struct dentry *ocfs2_fh_to_dentry(struct super_block *sb,
+               struct fid *fid, int fh_len, int fh_type)
 {
-       struct ocfs2_inode_handle handle, parent;
-       struct dentry *ret = NULL;
-       __le32 *fh = (__force __le32 *) fh_in;
-
-       mlog_entry("(0x%p, 0x%p, %d, %d, 0x%p, 0x%p)\n",
-                  sb, fh, fh_len, fileid_type, acceptable, context);
-
-       if (fh_len < 3 || fileid_type > 2)
-               goto bail;
-
-       if (fileid_type == 2) {
-               if (fh_len < 6)
-                       goto bail;
-
-               parent.ih_blkno = (u64)le32_to_cpu(fh[3]) << 32;
-               parent.ih_blkno |= (u64)le32_to_cpu(fh[4]);
-               parent.ih_generation = le32_to_cpu(fh[5]);
+       struct ocfs2_inode_handle handle;
 
-               mlog(0, "Decoding parent: blkno: %llu, generation: %u\n",
-                    (unsigned long long)parent.ih_blkno,
-                    parent.ih_generation);
-       }
+       if (fh_len < 3 || fh_type > 2)
+               return NULL;
 
-       handle.ih_blkno = (u64)le32_to_cpu(fh[0]) << 32;
-       handle.ih_blkno |= (u64)le32_to_cpu(fh[1]);
-       handle.ih_generation = le32_to_cpu(fh[2]);
+       handle.ih_blkno = (u64)le32_to_cpu(fid->raw[0]) << 32;
+       handle.ih_blkno |= (u64)le32_to_cpu(fid->raw[1]);
+       handle.ih_generation = le32_to_cpu(fid->raw[2]);
+       return ocfs2_get_dentry(sb, &handle);
+}
 
-       mlog(0, "Encoding fh: blkno: %llu, generation: %u\n",
-            (unsigned long long)handle.ih_blkno, handle.ih_generation);
+static struct dentry *ocfs2_fh_to_parent(struct super_block *sb,
+               struct fid *fid, int fh_len, int fh_type)
+{
+       struct ocfs2_inode_handle parent;
 
-       ret = ocfs2_export_ops.find_exported_dentry(sb, &handle, &parent,
-                                                   acceptable, context);
+       if (fh_type != 2 || fh_len < 6)
+               return NULL;
 
-bail:
-       mlog_exit_ptr(ret);
-       return ret;
+       parent.ih_blkno = (u64)le32_to_cpu(fid->raw[3]) << 32;
+       parent.ih_blkno |= (u64)le32_to_cpu(fid->raw[4]);
+       parent.ih_generation = le32_to_cpu(fid->raw[5]);
+       return ocfs2_get_dentry(sb, &parent);
 }
 
-struct export_operations ocfs2_export_ops = {
-       .decode_fh      = ocfs2_decode_fh,
+const struct export_operations ocfs2_export_ops = {
        .encode_fh      = ocfs2_encode_fh,
-
+       .fh_to_dentry   = ocfs2_fh_to_dentry,
+       .fh_to_parent   = ocfs2_fh_to_parent,
        .get_parent     = ocfs2_get_parent,
-       .get_dentry     = ocfs2_get_dentry,
 };
index e08bed9e45a09a2c5dfe9aba7d834d9f85c541e3..41a738678c374c581b0a11963b7f6ef6b62712e6 100644 (file)
@@ -28,6 +28,6 @@
 
 #include <linux/exportfs.h>
 
-extern struct export_operations ocfs2_export_ops;
+extern const struct export_operations ocfs2_export_ops;
 
 #endif /* OCFS2_EXPORT_H */
index 75385144df7da2fe10e8158a27322ec473a96d37..3b69c53e18379801e9bad4111e689be2cdaf1952 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -569,7 +569,7 @@ asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
        dentry = file->f_path.dentry;
        inode = dentry->d_inode;
 
-       audit_inode(NULL, inode);
+       audit_inode(NULL, dentry);
 
        err = -EROFS;
        if (IS_RDONLY(inode))
@@ -727,7 +727,7 @@ asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group)
                goto out;
 
        dentry = file->f_path.dentry;
-       audit_inode(NULL, dentry->d_inode);
+       audit_inode(NULL, dentry);
        error = chown_common(dentry, user, group);
        fput(file);
 out:
index d45bd8ec36bf1443bd76c906be04cb67b15236a3..f249be2fee7a22d0d6056c526f385b5550751b17 100644 (file)
@@ -22,6 +22,7 @@
 #define CL_COPY_ALL            0x04
 #define CL_MAKE_SHARED                 0x08
 #define CL_PROPAGATION                 0x10
+#define CL_PRIVATE             0x20
 
 static inline void set_mnt_shared(struct vfsmount *mnt)
 {
index 27b59f5f3bd1f382ab16401671b5316dd867841d..63c95afb561f8e8742118197b0731317ea871463 100644 (file)
@@ -77,6 +77,7 @@
 #include <linux/cpuset.h>
 #include <linux/rcupdate.h>
 #include <linux/delayacct.h>
+#include <linux/pid_namespace.h>
 
 #include <asm/pgtable.h>
 #include <asm/processor.h>
@@ -145,8 +146,7 @@ static inline const char *get_task_state(struct task_struct *tsk)
                                            TASK_UNINTERRUPTIBLE |
                                            TASK_STOPPED |
                                            TASK_TRACED)) |
-                       (tsk->exit_state & (EXIT_ZOMBIE |
-                                           EXIT_DEAD));
+                                          tsk->exit_state;
        const char **p = &task_state_array[0];
 
        while (state) {
@@ -161,8 +161,15 @@ static inline char *task_state(struct task_struct *p, char *buffer)
        struct group_info *group_info;
        int g;
        struct fdtable *fdt = NULL;
+       struct pid_namespace *ns;
+       pid_t ppid, tpid;
 
+       ns = current->nsproxy->pid_ns;
        rcu_read_lock();
+       ppid = pid_alive(p) ?
+               task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
+       tpid = pid_alive(p) && p->ptrace ?
+               task_ppid_nr_ns(rcu_dereference(p->parent), ns) : 0;
        buffer += sprintf(buffer,
                "State:\t%s\n"
                "Tgid:\t%d\n"
@@ -172,9 +179,9 @@ static inline char *task_state(struct task_struct *p, char *buffer)
                "Uid:\t%d\t%d\t%d\t%d\n"
                "Gid:\t%d\t%d\t%d\t%d\n",
                get_task_state(p),
-               p->tgid, p->pid,
-               pid_alive(p) ? rcu_dereference(p->real_parent)->tgid : 0,
-               pid_alive(p) && p->ptrace ? rcu_dereference(p->parent)->pid : 0,
+               task_tgid_nr_ns(p, ns),
+               task_pid_nr_ns(p, ns),
+               ppid, tpid,
                p->uid, p->euid, p->suid, p->fsuid,
                p->gid, p->egid, p->sgid, p->fsgid);
 
@@ -394,6 +401,9 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole)
        unsigned long rsslim = 0;
        char tcomm[sizeof(task->comm)];
        unsigned long flags;
+       struct pid_namespace *ns;
+
+       ns = current->nsproxy->pid_ns;
 
        state = *get_task_state(task);
        vsize = eip = esp = 0;
@@ -416,7 +426,7 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole)
                struct signal_struct *sig = task->signal;
 
                if (sig->tty) {
-                       tty_pgrp = pid_nr(sig->tty->pgrp);
+                       tty_pgrp = pid_nr_ns(sig->tty->pgrp, ns);
                        tty_nr = new_encode_dev(tty_devnum(sig->tty));
                }
 
@@ -446,12 +456,12 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole)
                        maj_flt += sig->maj_flt;
                        utime = cputime_add(utime, sig->utime);
                        stime = cputime_add(stime, sig->stime);
-                       gtime += cputime_add(gtime, sig->gtime);
+                       gtime = cputime_add(gtime, sig->gtime);
                }
 
-               sid = signal_session(sig);
-               pgid = process_group(task);
-               ppid = rcu_dereference(task->real_parent)->tgid;
+               sid = task_session_nr_ns(task, ns);
+               pgid = task_pgrp_nr_ns(task, ns);
+               ppid = task_ppid_nr_ns(task, ns);
 
                unlock_task_sighand(task, &flags);
        }
@@ -483,7 +493,7 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole)
        res = sprintf(buffer, "%d (%s) %c %d %d %d %d %d %u %lu \
 %lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \
 %lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu %lu %ld\n",
-               task->pid,
+               task_pid_nr_ns(task, ns),
                tcomm,
                state,
                ppid,
index 4fe74d156416f0936b686d57dc6ee7bd2518dba5..aeaf0d0f2f51813bdc2f63115d855e66efe9e93c 100644 (file)
 #include <linux/mm.h>
 #include <linux/rcupdate.h>
 #include <linux/kallsyms.h>
+#include <linux/resource.h>
 #include <linux/module.h>
 #include <linux/mount.h>
 #include <linux/security.h>
 #include <linux/ptrace.h>
+#include <linux/cgroup.h>
 #include <linux/cpuset.h>
 #include <linux/audit.h>
 #include <linux/poll.h>
 #include <linux/nsproxy.h>
 #include <linux/oom.h>
 #include <linux/elf.h>
+#include <linux/pid_namespace.h>
 #include "internal.h"
 
 /* NOTE:
@@ -301,6 +304,78 @@ static int proc_oom_score(struct task_struct *task, char *buffer)
        return sprintf(buffer, "%lu\n", points);
 }
 
+struct limit_names {
+       char *name;
+       char *unit;
+};
+
+static const struct limit_names lnames[RLIM_NLIMITS] = {
+       [RLIMIT_CPU] = {"Max cpu time", "ms"},
+       [RLIMIT_FSIZE] = {"Max file size", "bytes"},
+       [RLIMIT_DATA] = {"Max data size", "bytes"},
+       [RLIMIT_STACK] = {"Max stack size", "bytes"},
+       [RLIMIT_CORE] = {"Max core file size", "bytes"},
+       [RLIMIT_RSS] = {"Max resident set", "bytes"},
+       [RLIMIT_NPROC] = {"Max processes", "processes"},
+       [RLIMIT_NOFILE] = {"Max open files", "files"},
+       [RLIMIT_MEMLOCK] = {"Max locked memory", "bytes"},
+       [RLIMIT_AS] = {"Max address space", "bytes"},
+       [RLIMIT_LOCKS] = {"Max file locks", "locks"},
+       [RLIMIT_SIGPENDING] = {"Max pending signals", "signals"},
+       [RLIMIT_MSGQUEUE] = {"Max msgqueue size", "bytes"},
+       [RLIMIT_NICE] = {"Max nice priority", NULL},
+       [RLIMIT_RTPRIO] = {"Max realtime priority", NULL},
+};
+
+/* Display limits for a process */
+static int proc_pid_limits(struct task_struct *task, char *buffer)
+{
+       unsigned int i;
+       int count = 0;
+       unsigned long flags;
+       char *bufptr = buffer;
+
+       struct rlimit rlim[RLIM_NLIMITS];
+
+       rcu_read_lock();
+       if (!lock_task_sighand(task,&flags)) {
+               rcu_read_unlock();
+               return 0;
+       }
+       memcpy(rlim, task->signal->rlim, sizeof(struct rlimit) * RLIM_NLIMITS);
+       unlock_task_sighand(task, &flags);
+       rcu_read_unlock();
+
+       /*
+        * print the file header
+        */
+       count += sprintf(&bufptr[count], "%-25s %-20s %-20s %-10s\n",
+                       "Limit", "Soft Limit", "Hard Limit", "Units");
+
+       for (i = 0; i < RLIM_NLIMITS; i++) {
+               if (rlim[i].rlim_cur == RLIM_INFINITY)
+                       count += sprintf(&bufptr[count], "%-25s %-20s ",
+                                        lnames[i].name, "unlimited");
+               else
+                       count += sprintf(&bufptr[count], "%-25s %-20lu ",
+                                        lnames[i].name, rlim[i].rlim_cur);
+
+               if (rlim[i].rlim_max == RLIM_INFINITY)
+                       count += sprintf(&bufptr[count], "%-20s ", "unlimited");
+               else
+                       count += sprintf(&bufptr[count], "%-20lu ",
+                                        rlim[i].rlim_max);
+
+               if (lnames[i].unit)
+                       count += sprintf(&bufptr[count], "%-10s\n",
+                                        lnames[i].unit);
+               else
+                       count += sprintf(&bufptr[count], "\n");
+       }
+
+       return count;
+}
+
 /************************************************************************/
 /*                       Here the fs part begins                        */
 /************************************************************************/
@@ -349,18 +424,21 @@ struct proc_mounts {
 static int mounts_open(struct inode *inode, struct file *file)
 {
        struct task_struct *task = get_proc_task(inode);
+       struct nsproxy *nsp;
        struct mnt_namespace *ns = NULL;
        struct proc_mounts *p;
        int ret = -EINVAL;
 
        if (task) {
-               task_lock(task);
-               if (task->nsproxy) {
-                       ns = task->nsproxy->mnt_ns;
+               rcu_read_lock();
+               nsp = task_nsproxy(task);
+               if (nsp) {
+                       ns = nsp->mnt_ns;
                        if (ns)
                                get_mnt_ns(ns);
                }
-               task_unlock(task);
+               rcu_read_unlock();
+
                put_task_struct(task);
        }
 
@@ -423,16 +501,20 @@ static int mountstats_open(struct inode *inode, struct file *file)
 
        if (!ret) {
                struct seq_file *m = file->private_data;
+               struct nsproxy *nsp;
                struct mnt_namespace *mnt_ns = NULL;
                struct task_struct *task = get_proc_task(inode);
 
                if (task) {
-                       task_lock(task);
-                       if (task->nsproxy)
-                               mnt_ns = task->nsproxy->mnt_ns;
-                       if (mnt_ns)
-                               get_mnt_ns(mnt_ns);
-                       task_unlock(task);
+                       rcu_read_lock();
+                       nsp = task_nsproxy(task);
+                       if (nsp) {
+                               mnt_ns = nsp->mnt_ns;
+                               if (mnt_ns)
+                                       get_mnt_ns(mnt_ns);
+                       }
+                       rcu_read_unlock();
+
                        put_task_struct(task);
                }
 
@@ -1437,7 +1519,7 @@ static int proc_readfd_common(struct file * filp, void * dirent,
        struct dentry *dentry = filp->f_path.dentry;
        struct inode *inode = dentry->d_inode;
        struct task_struct *p = get_proc_task(inode);
-       unsigned int fd, tid, ino;
+       unsigned int fd, ino;
        int retval;
        struct files_struct * files;
        struct fdtable *fdt;
@@ -1446,7 +1528,6 @@ static int proc_readfd_common(struct file * filp, void * dirent,
        if (!p)
                goto out_no_task;
        retval = 0;
-       tid = p->pid;
 
        fd = filp->f_pos;
        switch (fd) {
@@ -1681,7 +1762,6 @@ static int proc_pident_readdir(struct file *filp,
                const struct pid_entry *ents, unsigned int nents)
 {
        int i;
-       int pid;
        struct dentry *dentry = filp->f_path.dentry;
        struct inode *inode = dentry->d_inode;
        struct task_struct *task = get_proc_task(inode);
@@ -1694,7 +1774,6 @@ static int proc_pident_readdir(struct file *filp,
                goto out_no_task;
 
        ret = 0;
-       pid = task->pid;
        i = filp->f_pos;
        switch (i) {
        case 0:
@@ -1928,14 +2007,14 @@ static int proc_self_readlink(struct dentry *dentry, char __user *buffer,
                              int buflen)
 {
        char tmp[PROC_NUMBUF];
-       sprintf(tmp, "%d", current->tgid);
+       sprintf(tmp, "%d", task_tgid_vnr(current));
        return vfs_readlink(dentry,buffer,buflen,tmp);
 }
 
 static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
        char tmp[PROC_NUMBUF];
-       sprintf(tmp, "%d", current->tgid);
+       sprintf(tmp, "%d", task_tgid_vnr(current));
        return ERR_PTR(vfs_follow_link(nd,tmp));
 }
 
@@ -2101,6 +2180,7 @@ static const struct pid_entry tgid_base_stuff[] = {
        REG("environ",    S_IRUSR, environ),
        INF("auxv",       S_IRUSR, pid_auxv),
        INF("status",     S_IRUGO, pid_status),
+       INF("limits",     S_IRUSR, pid_limits),
 #ifdef CONFIG_SCHED_DEBUG
        REG("sched",      S_IRUGO|S_IWUSR, pid_sched),
 #endif
@@ -2130,8 +2210,11 @@ static const struct pid_entry tgid_base_stuff[] = {
 #ifdef CONFIG_SCHEDSTATS
        INF("schedstat",  S_IRUGO, pid_schedstat),
 #endif
-#ifdef CONFIG_CPUSETS
+#ifdef CONFIG_PROC_PID_CPUSET
        REG("cpuset",     S_IRUGO, cpuset),
+#endif
+#ifdef CONFIG_CGROUPS
+       REG("cgroup",  S_IRUGO, cgroup),
 #endif
        INF("oom_score",  S_IRUGO, oom_score),
        REG("oom_adj",    S_IRUGO|S_IWUSR, oom_adjust),
@@ -2172,48 +2255,27 @@ static const struct inode_operations proc_tgid_base_inode_operations = {
        .setattr        = proc_setattr,
 };
 
-/**
- * proc_flush_task -  Remove dcache entries for @task from the /proc dcache.
- *
- * @task: task that should be flushed.
- *
- * Looks in the dcache for
- * /proc/@pid
- * /proc/@tgid/task/@pid
- * if either directory is present flushes it and all of it'ts children
- * from the dcache.
- *
- * It is safe and reasonable to cache /proc entries for a task until
- * that task exits.  After that they just clog up the dcache with
- * useless entries, possibly causing useful dcache entries to be
- * flushed instead.  This routine is proved to flush those useless
- * dcache entries at process exit time.
- *
- * NOTE: This routine is just an optimization so it does not guarantee
- *       that no dcache entries will exist at process exit time it
- *       just makes it very unlikely that any will persist.
- */
-void proc_flush_task(struct task_struct *task)
+static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid)
 {
        struct dentry *dentry, *leader, *dir;
        char buf[PROC_NUMBUF];
        struct qstr name;
 
        name.name = buf;
-       name.len = snprintf(buf, sizeof(buf), "%d", task->pid);
-       dentry = d_hash_and_lookup(proc_mnt->mnt_root, &name);
+       name.len = snprintf(buf, sizeof(buf), "%d", pid);
+       dentry = d_hash_and_lookup(mnt->mnt_root, &name);
        if (dentry) {
                shrink_dcache_parent(dentry);
                d_drop(dentry);
                dput(dentry);
        }
 
-       if (thread_group_leader(task))
+       if (tgid == 0)
                goto out;
 
        name.name = buf;
-       name.len = snprintf(buf, sizeof(buf), "%d", task->tgid);
-       leader = d_hash_and_lookup(proc_mnt->mnt_root, &name);
+       name.len = snprintf(buf, sizeof(buf), "%d", tgid);
+       leader = d_hash_and_lookup(mnt->mnt_root, &name);
        if (!leader)
                goto out;
 
@@ -2224,7 +2286,7 @@ void proc_flush_task(struct task_struct *task)
                goto out_put_leader;
 
        name.name = buf;
-       name.len = snprintf(buf, sizeof(buf), "%d", task->pid);
+       name.len = snprintf(buf, sizeof(buf), "%d", pid);
        dentry = d_hash_and_lookup(dir, &name);
        if (dentry) {
                shrink_dcache_parent(dentry);
@@ -2239,6 +2301,55 @@ out:
        return;
 }
 
+/**
+ * proc_flush_task -  Remove dcache entries for @task from the /proc dcache.
+ * @task: task that should be flushed.
+ *
+ * When flushing dentries from proc, one needs to flush them from global
+ * proc (proc_mnt) and from all the namespaces' procs this task was seen
+ * in. This call is supposed to do all of this job.
+ *
+ * Looks in the dcache for
+ * /proc/@pid
+ * /proc/@tgid/task/@pid
+ * if either directory is present flushes it and all of it'ts children
+ * from the dcache.
+ *
+ * It is safe and reasonable to cache /proc entries for a task until
+ * that task exits.  After that they just clog up the dcache with
+ * useless entries, possibly causing useful dcache entries to be
+ * flushed instead.  This routine is proved to flush those useless
+ * dcache entries at process exit time.
+ *
+ * NOTE: This routine is just an optimization so it does not guarantee
+ *       that no dcache entries will exist at process exit time it
+ *       just makes it very unlikely that any will persist.
+ */
+
+void proc_flush_task(struct task_struct *task)
+{
+       int i, leader;
+       struct pid *pid, *tgid;
+       struct upid *upid;
+
+       leader = thread_group_leader(task);
+       proc_flush_task_mnt(proc_mnt, task->pid, leader ? task->tgid : 0);
+       pid = task_pid(task);
+       if (pid->level == 0)
+               return;
+
+       tgid = task_tgid(task);
+       for (i = 1; i <= pid->level; i++) {
+               upid = &pid->numbers[i];
+               proc_flush_task_mnt(upid->ns->proc_mnt, upid->nr,
+                               leader ? 0 : tgid->numbers[i].nr);
+       }
+
+       upid = &pid->numbers[pid->level];
+       if (upid->nr == 1)
+               pid_ns_release_proc(upid->ns);
+}
+
 static struct dentry *proc_pid_instantiate(struct inode *dir,
                                           struct dentry * dentry,
                                           struct task_struct *task, const void *ptr)
@@ -2274,6 +2385,7 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct
        struct dentry *result = ERR_PTR(-ENOENT);
        struct task_struct *task;
        unsigned tgid;
+       struct pid_namespace *ns;
 
        result = proc_base_lookup(dir, dentry);
        if (!IS_ERR(result) || PTR_ERR(result) != -ENOENT)
@@ -2283,8 +2395,9 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct
        if (tgid == ~0U)
                goto out;
 
+       ns = dentry->d_sb->s_fs_info;
        rcu_read_lock();
-       task = find_task_by_pid(tgid);
+       task = find_task_by_pid_ns(tgid, ns);
        if (task)
                get_task_struct(task);
        rcu_read_unlock();
@@ -2301,7 +2414,8 @@ out:
  * Find the first task with tgid >= tgid
  *
  */
-static struct task_struct *next_tgid(unsigned int tgid)
+static struct task_struct *next_tgid(unsigned int tgid,
+               struct pid_namespace *ns)
 {
        struct task_struct *task;
        struct pid *pid;
@@ -2309,9 +2423,9 @@ static struct task_struct *next_tgid(unsigned int tgid)
        rcu_read_lock();
 retry:
        task = NULL;
-       pid = find_ge_pid(tgid);
+       pid = find_ge_pid(tgid, ns);
        if (pid) {
-               tgid = pid->nr + 1;
+               tgid = pid_nr_ns(pid, ns) + 1;
                task = pid_task(pid, PIDTYPE_PID);
                /* What we to know is if the pid we have find is the
                 * pid of a thread_group_leader.  Testing for task
@@ -2351,6 +2465,7 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
        struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode);
        struct task_struct *task;
        int tgid;
+       struct pid_namespace *ns;
 
        if (!reaper)
                goto out_no_task;
@@ -2361,11 +2476,12 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
                        goto out;
        }
 
+       ns = filp->f_dentry->d_sb->s_fs_info;
        tgid = filp->f_pos - TGID_OFFSET;
-       for (task = next_tgid(tgid);
+       for (task = next_tgid(tgid, ns);
             task;
-            put_task_struct(task), task = next_tgid(tgid + 1)) {
-               tgid = task->pid;
+            put_task_struct(task), task = next_tgid(tgid + 1, ns)) {
+               tgid = task_pid_nr_ns(task, ns);
                filp->f_pos = tgid + TGID_OFFSET;
                if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) {
                        put_task_struct(task);
@@ -2388,6 +2504,7 @@ static const struct pid_entry tid_base_stuff[] = {
        REG("environ",   S_IRUSR, environ),
        INF("auxv",      S_IRUSR, pid_auxv),
        INF("status",    S_IRUGO, pid_status),
+       INF("limits",    S_IRUSR, pid_limits),
 #ifdef CONFIG_SCHED_DEBUG
        REG("sched",     S_IRUGO|S_IWUSR, pid_sched),
 #endif
@@ -2416,8 +2533,11 @@ static const struct pid_entry tid_base_stuff[] = {
 #ifdef CONFIG_SCHEDSTATS
        INF("schedstat", S_IRUGO, pid_schedstat),
 #endif
-#ifdef CONFIG_CPUSETS
+#ifdef CONFIG_PROC_PID_CPUSET
        REG("cpuset",    S_IRUGO, cpuset),
+#endif
+#ifdef CONFIG_CGROUPS
+       REG("cgroup",  S_IRUGO, cgroup),
 #endif
        INF("oom_score", S_IRUGO, oom_score),
        REG("oom_adj",   S_IRUGO|S_IWUSR, oom_adjust),
@@ -2486,6 +2606,7 @@ static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry
        struct task_struct *task;
        struct task_struct *leader = get_proc_task(dir);
        unsigned tid;
+       struct pid_namespace *ns;
 
        if (!leader)
                goto out_no_task;
@@ -2494,14 +2615,15 @@ static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry
        if (tid == ~0U)
                goto out;
 
+       ns = dentry->d_sb->s_fs_info;
        rcu_read_lock();
-       task = find_task_by_pid(tid);
+       task = find_task_by_pid_ns(tid, ns);
        if (task)
                get_task_struct(task);
        rcu_read_unlock();
        if (!task)
                goto out;
-       if (leader->tgid != task->tgid)
+       if (!same_thread_group(leader, task))
                goto out_drop_task;
 
        result = proc_task_instantiate(dir, dentry, task, NULL);
@@ -2526,14 +2648,14 @@ out_no_task:
  * threads past it.
  */
 static struct task_struct *first_tid(struct task_struct *leader,
-                                       int tid, int nr)
+               int tid, int nr, struct pid_namespace *ns)
 {
        struct task_struct *pos;
 
        rcu_read_lock();
        /* Attempt to start with the pid of a thread */
        if (tid && (nr > 0)) {
-               pos = find_task_by_pid(tid);
+               pos = find_task_by_pid_ns(tid, ns);
                if (pos && (pos->group_leader == leader))
                        goto found;
        }
@@ -2602,6 +2724,7 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi
        ino_t ino;
        int tid;
        unsigned long pos = filp->f_pos;  /* avoiding "long long" filp->f_pos */
+       struct pid_namespace *ns;
 
        task = get_proc_task(inode);
        if (!task)
@@ -2635,12 +2758,13 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi
        /* f_version caches the tgid value that the last readdir call couldn't
         * return. lseek aka telldir automagically resets f_version to 0.
         */
+       ns = filp->f_dentry->d_sb->s_fs_info;
        tid = (int)filp->f_version;
        filp->f_version = 0;
-       for (task = first_tid(leader, tid, pos - 2);
+       for (task = first_tid(leader, tid, pos - 2, ns);
             task;
             task = next_tid(task), pos++) {
-               tid = task->pid;
+               tid = task_pid_nr_ns(task, ns);
                if (proc_task_fill_cache(filp, dirent, filldir, task, tid) < 0) {
                        /* returning this tgid failed, save it as the first
                         * pid for the next readir call */
index 99ca00485fc307ff52014dc303b60fd918f87de4..abe6a3f04368490aa9776dbb919cd1cc5c0dd075 100644 (file)
@@ -448,7 +448,7 @@ out_mod:
        return NULL;
 }                      
 
-int proc_fill_super(struct super_block *s, void *data, int silent)
+int proc_fill_super(struct super_block *s)
 {
        struct inode * root_inode;
 
index d6dc72c78bc1bd9a1d36fb29e6728450fcbb34e5..e0d064e9764ef55422cf79119b7624b3e6b87373 100644 (file)
@@ -91,7 +91,8 @@ static int loadavg_read_proc(char *page, char **start, off_t off,
                LOAD_INT(a), LOAD_FRAC(a),
                LOAD_INT(b), LOAD_FRAC(b),
                LOAD_INT(c), LOAD_FRAC(c),
-               nr_running(), nr_threads, current->nsproxy->pid_ns->last_pid);
+               nr_running(), nr_threads,
+               task_active_pid_ns(current)->last_pid);
        return proc_calc_metrics(page, start, off, count, eof, len);
 }
 
index cf3046638b09406947198ba81ac4c93aa01ec7f8..ec9cb3b6c93bf777e8c6cb8ed4a6f8405898fa87 100644 (file)
 #include <linux/bitops.h>
 #include <linux/smp_lock.h>
 #include <linux/mount.h>
+#include <linux/pid_namespace.h>
 
 #include "internal.h"
 
 struct proc_dir_entry *proc_bus, *proc_root_fs, *proc_root_driver;
 
+static int proc_test_super(struct super_block *sb, void *data)
+{
+       return sb->s_fs_info == data;
+}
+
+static int proc_set_super(struct super_block *sb, void *data)
+{
+       struct pid_namespace *ns;
+
+       ns = (struct pid_namespace *)data;
+       sb->s_fs_info = get_pid_ns(ns);
+       return set_anon_super(sb, NULL);
+}
+
 static int proc_get_sb(struct file_system_type *fs_type,
        int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
+       int err;
+       struct super_block *sb;
+       struct pid_namespace *ns;
+       struct proc_inode *ei;
+
        if (proc_mnt) {
                /* Seed the root directory with a pid so it doesn't need
                 * to be special in base.c.  I would do this earlier but
                 * the only task alive when /proc is mounted the first time
                 * is the init_task and it doesn't have any pids.
                 */
-               struct proc_inode *ei;
                ei = PROC_I(proc_mnt->mnt_sb->s_root->d_inode);
                if (!ei->pid)
                        ei->pid = find_get_pid(1);
        }
-       return get_sb_single(fs_type, flags, data, proc_fill_super, mnt);
+
+       if (flags & MS_KERNMOUNT)
+               ns = (struct pid_namespace *)data;
+       else
+               ns = current->nsproxy->pid_ns;
+
+       sb = sget(fs_type, proc_test_super, proc_set_super, ns);
+       if (IS_ERR(sb))
+               return PTR_ERR(sb);
+
+       if (!sb->s_root) {
+               sb->s_flags = flags;
+               err = proc_fill_super(sb);
+               if (err) {
+                       up_write(&sb->s_umount);
+                       deactivate_super(sb);
+                       return err;
+               }
+
+               ei = PROC_I(sb->s_root->d_inode);
+               if (!ei->pid) {
+                       rcu_read_lock();
+                       ei->pid = get_pid(find_pid_ns(1, ns));
+                       rcu_read_unlock();
+               }
+
+               sb->s_flags |= MS_ACTIVE;
+               ns->proc_mnt = mnt;
+       }
+
+       return simple_set_mnt(mnt, sb);
+}
+
+static void proc_kill_sb(struct super_block *sb)
+{
+       struct pid_namespace *ns;
+
+       ns = (struct pid_namespace *)sb->s_fs_info;
+       kill_anon_super(sb);
+       put_pid_ns(ns);
 }
 
 static struct file_system_type proc_fs_type = {
        .name           = "proc",
        .get_sb         = proc_get_sb,
-       .kill_sb        = kill_anon_super,
+       .kill_sb        = proc_kill_sb,
 };
 
 void __init proc_root_init(void)
@@ -54,12 +112,13 @@ void __init proc_root_init(void)
        err = register_filesystem(&proc_fs_type);
        if (err)
                return;
-       proc_mnt = kern_mount(&proc_fs_type);
+       proc_mnt = kern_mount_data(&proc_fs_type, &init_pid_ns);
        err = PTR_ERR(proc_mnt);
        if (IS_ERR(proc_mnt)) {
                unregister_filesystem(&proc_fs_type);
                return;
        }
+
        proc_misc_init();
 
        proc_net_init();
@@ -153,6 +212,22 @@ struct proc_dir_entry proc_root = {
        .parent         = &proc_root,
 };
 
+int pid_ns_prepare_proc(struct pid_namespace *ns)
+{
+       struct vfsmount *mnt;
+
+       mnt = kern_mount_data(&proc_fs_type, ns);
+       if (IS_ERR(mnt))
+               return PTR_ERR(mnt);
+
+       return 0;
+}
+
+void pid_ns_release_proc(struct pid_namespace *ns)
+{
+       mntput(ns->proc_mnt);
+}
+
 EXPORT_SYMBOL(proc_symlink);
 EXPORT_SYMBOL(proc_mkdir);
 EXPORT_SYMBOL(create_proc_entry);
index 2a5dd34649b34eb2c81275c57ef7afdf9a6ec781..16b331dd9913a93f6575d8ec38dd9b63dcf05251 100644 (file)
@@ -47,7 +47,9 @@
     test_bit(_ALLOC_ ## optname , &SB_ALLOC_OPTS(s))
 
 static inline void get_bit_address(struct super_block *s,
-                                  b_blocknr_t block, int *bmap_nr, int *offset)
+                                  b_blocknr_t block,
+                                  unsigned int *bmap_nr,
+                                  unsigned int *offset)
 {
        /* It is in the bitmap block number equal to the block
         * number divided by the number of bits in a block. */
@@ -56,10 +58,10 @@ static inline void get_bit_address(struct super_block *s,
        *offset = block & ((s->s_blocksize << 3) - 1);
 }
 
-#ifdef CONFIG_REISERFS_CHECK
 int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value)
 {
-       int bmap, offset;
+       unsigned int bmap, offset;
+       unsigned int bmap_count = reiserfs_bmap_count(s);
 
        if (block == 0 || block >= SB_BLOCK_COUNT(s)) {
                reiserfs_warning(s,
@@ -75,25 +77,26 @@ int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value)
        if (unlikely(test_bit(REISERFS_OLD_FORMAT,
                              &(REISERFS_SB(s)->s_properties)))) {
                b_blocknr_t bmap1 = REISERFS_SB(s)->s_sbh->b_blocknr + 1;
-               if (block >= bmap1 && block <= bmap1 + SB_BMAP_NR(s)) {
+               if (block >= bmap1 &&
+                   block <= bmap1 + bmap_count) {
                        reiserfs_warning(s, "vs: 4019: is_reusable: "
                                         "bitmap block %lu(%u) can't be freed or reused",
-                                        block, SB_BMAP_NR(s));
+                                        block, bmap_count);
                        return 0;
                }
        } else {
                if (offset == 0) {
                        reiserfs_warning(s, "vs: 4020: is_reusable: "
                                         "bitmap block %lu(%u) can't be freed or reused",
-                                        block, SB_BMAP_NR(s));
+                                        block, bmap_count);
                        return 0;
                }
        }
 
-       if (bmap >= SB_BMAP_NR(s)) {
+       if (bmap >= bmap_count) {
                reiserfs_warning(s,
                                 "vs-4030: is_reusable: there is no so many bitmap blocks: "
-                                "block=%lu, bitmap_nr=%d", block, bmap);
+                                "block=%lu, bitmap_nr=%u", block, bmap);
                return 0;
        }
 
@@ -106,12 +109,11 @@ int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value)
 
        return 1;
 }
-#endif                         /* CONFIG_REISERFS_CHECK */
 
 /* searches in journal structures for a given block number (bmap, off). If block
    is found in reiserfs journal it suggests next free block candidate to test. */
-static inline int is_block_in_journal(struct super_block *s, int bmap, int
-                                     off, int *next)
+static inline int is_block_in_journal(struct super_block *s, unsigned int bmap,
+                                     int off, int *next)
 {
        b_blocknr_t tmp;
 
@@ -132,8 +134,8 @@ static inline int is_block_in_journal(struct super_block *s, int bmap, int
 /* it searches for a window of zero bits with given minimum and maximum lengths in one bitmap
  * block; */
 static int scan_bitmap_block(struct reiserfs_transaction_handle *th,
-                            int bmap_n, int *beg, int boundary, int min,
-                            int max, int unfm)
+                            unsigned int bmap_n, int *beg, int boundary,
+                            int min, int max, int unfm)
 {
        struct super_block *s = th->t_super;
        struct reiserfs_bitmap_info *bi = &SB_AP_BITMAP(s)[bmap_n];
@@ -143,8 +145,8 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th,
 
        BUG_ON(!th->t_trans_id);
 
-       RFALSE(bmap_n >= SB_BMAP_NR(s), "Bitmap %d is out of range (0..%d)",
-              bmap_n, SB_BMAP_NR(s) - 1);
+       RFALSE(bmap_n >= reiserfs_bmap_count(s), "Bitmap %u is out of "
+              "range (0..%u)", bmap_n, reiserfs_bmap_count(s) - 1);
        PROC_INFO_INC(s, scan_bitmap.bmap);
 /* this is unclear and lacks comments, explain how journal bitmaps
    work here for the reader.  Convey a sense of the design here. What
@@ -249,12 +251,12 @@ static int bmap_hash_id(struct super_block *s, u32 id)
        } else {
                hash_in = (char *)(&id);
                hash = keyed_hash(hash_in, 4);
-               bm = hash % SB_BMAP_NR(s);
+               bm = hash % reiserfs_bmap_count(s);
                if (!bm)
                        bm = 1;
        }
        /* this can only be true when SB_BMAP_NR = 1 */
-       if (bm >= SB_BMAP_NR(s))
+       if (bm >= reiserfs_bmap_count(s))
                bm = 0;
        return bm;
 }
@@ -273,7 +275,7 @@ static inline int block_group_used(struct super_block *s, u32 id)
         * to make a better decision. This favors long-term performace gain
         * with a better on-disk layout vs. a short term gain of skipping the
         * read and potentially having a bad placement. */
-       if (info->first_zero_hint == 0) {
+       if (info->free_count == UINT_MAX) {
                struct buffer_head *bh = reiserfs_read_bitmap_block(s, bm);
                brelse(bh);
        }
@@ -309,16 +311,16 @@ __le32 reiserfs_choose_packing(struct inode * dir)
  * bitmap and place new blocks there. Returns number of allocated blocks. */
 static int scan_bitmap(struct reiserfs_transaction_handle *th,
                       b_blocknr_t * start, b_blocknr_t finish,
-                      int min, int max, int unfm, unsigned long file_block)
+                      int min, int max, int unfm, sector_t file_block)
 {
        int nr_allocated = 0;
        struct super_block *s = th->t_super;
        /* find every bm and bmap and bmap_nr in this file, and change them all to bitmap_blocknr
         * - Hans, it is not a block number - Zam. */
 
-       int bm, off;
-       int end_bm, end_off;
-       int off_max = s->s_blocksize << 3;
+       unsigned int bm, off;
+       unsigned int end_bm, end_off;
+       unsigned int off_max = s->s_blocksize << 3;
 
        BUG_ON(!th->t_trans_id);
 
@@ -328,10 +330,10 @@ static int scan_bitmap(struct reiserfs_transaction_handle *th,
 
        get_bit_address(s, *start, &bm, &off);
        get_bit_address(s, finish, &end_bm, &end_off);
-       if (bm > SB_BMAP_NR(s))
+       if (bm > reiserfs_bmap_count(s))
                return 0;
-       if (end_bm > SB_BMAP_NR(s))
-               end_bm = SB_BMAP_NR(s);
+       if (end_bm > reiserfs_bmap_count(s))
+               end_bm = reiserfs_bmap_count(s);
 
        /* When the bitmap is more than 10% free, anyone can allocate.
         * When it's less than 10% free, only files that already use the
@@ -385,7 +387,7 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th,
        struct reiserfs_super_block *rs;
        struct buffer_head *sbh, *bmbh;
        struct reiserfs_bitmap_info *apbi;
-       int nr, offset;
+       unsigned int nr, offset;
 
        BUG_ON(!th->t_trans_id);
 
@@ -397,10 +399,12 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th,
 
        get_bit_address(s, block, &nr, &offset);
 
-       if (nr >= sb_bmap_nr(rs)) {
+       if (nr >= reiserfs_bmap_count(s)) {
                reiserfs_warning(s, "vs-4075: reiserfs_free_block: "
-                                "block %lu is out of range on %s",
-                                block, reiserfs_bdevname(s));
+                                "block %lu is out of range on %s "
+                                "(nr=%u,max=%u)", block,
+                                reiserfs_bdevname(s), nr,
+                                reiserfs_bmap_count(s));
                return;
        }
 
@@ -434,12 +438,19 @@ void reiserfs_free_block(struct reiserfs_transaction_handle *th,
                         int for_unformatted)
 {
        struct super_block *s = th->t_super;
-
        BUG_ON(!th->t_trans_id);
 
        RFALSE(!s, "vs-4061: trying to free block on nonexistent device");
-       RFALSE(is_reusable(s, block, 1) == 0,
-              "vs-4071: can not free such block");
+       if (!is_reusable(s, block, 1))
+               return;
+
+       if (block > sb_block_count(REISERFS_SB(s)->s_rs)) {
+               reiserfs_panic(th->t_super, "bitmap-4072",
+                              "Trying to free block outside file system "
+                              "boundaries (%lu > %lu)",
+                              block, sb_block_count(REISERFS_SB(s)->s_rs));
+               return;
+       }
        /* mark it before we clear it, just in case */
        journal_mark_freed(th, s, block);
        _reiserfs_free_block(th, inode, block, for_unformatted);
@@ -449,11 +460,11 @@ void reiserfs_free_block(struct reiserfs_transaction_handle *th,
 static void reiserfs_free_prealloc_block(struct reiserfs_transaction_handle *th,
                                         struct inode *inode, b_blocknr_t block)
 {
+       BUG_ON(!th->t_trans_id);
        RFALSE(!th->t_super,
               "vs-4060: trying to free block on nonexistent device");
-       RFALSE(is_reusable(th->t_super, block, 1) == 0,
-              "vs-4070: can not free such block");
-       BUG_ON(!th->t_trans_id);
+       if (!is_reusable(th->t_super, block, 1))
+               return;
        _reiserfs_free_block(th, inode, block, 1);
 }
 
@@ -1207,27 +1218,22 @@ void reiserfs_cache_bitmap_metadata(struct super_block *sb,
 {
        unsigned long *cur = (unsigned long *)(bh->b_data + bh->b_size);
 
-       info->first_zero_hint = 1 << (sb->s_blocksize_bits + 3);
+       /* The first bit must ALWAYS be 1 */
+       BUG_ON(!reiserfs_test_le_bit(0, (unsigned long *)bh->b_data));
+
+       info->free_count = 0;
 
        while (--cur >= (unsigned long *)bh->b_data) {
-               int base = ((char *)cur - bh->b_data) << 3;
+               int i;
 
                /* 0 and ~0 are special, we can optimize for them */
-               if (*cur == 0) {
-                       info->first_zero_hint = base;
+               if (*cur == 0)
                        info->free_count += BITS_PER_LONG;
-               } else if (*cur != ~0L) {       /* A mix, investigate */
-                       int b;
-                       for (b = BITS_PER_LONG - 1; b >= 0; b--) {
-                               if (!reiserfs_test_le_bit(b, cur)) {
-                                       info->first_zero_hint = base + b;
+               else if (*cur != ~0L)   /* A mix, investigate */
+                       for (i = BITS_PER_LONG - 1; i >= 0; i--)
+                               if (!reiserfs_test_le_bit(i, cur))
                                        info->free_count++;
-                               }
-                       }
-               }
        }
-       /* The first bit must ALWAYS be 1 */
-       BUG_ON(info->first_zero_hint == 0);
 }
 
 struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb,
@@ -1257,7 +1263,7 @@ struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb,
                BUG_ON(!buffer_uptodate(bh));
                BUG_ON(atomic_read(&bh->b_count) == 0);
 
-               if (info->first_zero_hint == 0)
+               if (info->free_count == UINT_MAX)
                        reiserfs_cache_bitmap_metadata(sb, bh, info);
        }
 
@@ -1267,12 +1273,13 @@ struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb,
 int reiserfs_init_bitmap_cache(struct super_block *sb)
 {
        struct reiserfs_bitmap_info *bitmap;
+       unsigned int bmap_nr = reiserfs_bmap_count(sb);
 
-       bitmap = vmalloc(sizeof (*bitmap) * SB_BMAP_NR(sb));
+       bitmap = vmalloc(sizeof(*bitmap) * bmap_nr);
        if (bitmap == NULL)
                return -ENOMEM;
 
-       memset(bitmap, 0, sizeof (*bitmap) * SB_BMAP_NR(sb));
+       memset(bitmap, 0xff, sizeof(*bitmap) * bmap_nr);
 
        SB_AP_BITMAP(sb) = bitmap;
 
index 9ea12004fa57e6ecbe44abb357ee2599cbed9daf..231fd5ccadc52040775842b7a8867c18656314b8 100644 (file)
@@ -199,7 +199,7 @@ static inline void set_block_dev_mapped(struct buffer_head *bh,
 // files which were created in the earlier version can not be longer,
 // than 2 gb
 //
-static int file_capable(struct inode *inode, long block)
+static int file_capable(struct inode *inode, sector_t block)
 {
        if (get_inode_item_key_version(inode) != KEY_FORMAT_3_5 ||      // it is new file.
            block < (1 << (31 - inode->i_sb->s_blocksize_bits)))        // old file, but 'block' is inside of 2gb
@@ -242,7 +242,7 @@ static int restart_transaction(struct reiserfs_transaction_handle *th,
 // Please improve the english/clarity in the comment above, as it is
 // hard to understand.
 
-static int _get_block_create_0(struct inode *inode, long block,
+static int _get_block_create_0(struct inode *inode, sector_t block,
                               struct buffer_head *bh_result, int args)
 {
        INITIALIZE_PATH(path);
@@ -250,7 +250,7 @@ static int _get_block_create_0(struct inode *inode, long block,
        struct buffer_head *bh;
        struct item_head *ih, tmp_ih;
        int fs_gen;
-       int blocknr;
+       b_blocknr_t blocknr;
        char *p = NULL;
        int chars;
        int ret;
@@ -569,7 +569,7 @@ static int convert_tail_for_hole(struct inode *inode,
 }
 
 static inline int _allocate_block(struct reiserfs_transaction_handle *th,
-                                 long block,
+                                 sector_t block,
                                  struct inode *inode,
                                  b_blocknr_t * allocated_block_nr,
                                  struct treepath *path, int flags)
@@ -1515,19 +1515,20 @@ struct inode *reiserfs_iget(struct super_block *s, const struct cpu_key *key)
        return inode;
 }
 
-struct dentry *reiserfs_get_dentry(struct super_block *sb, void *vobjp)
+static struct dentry *reiserfs_get_dentry(struct super_block *sb,
+       u32 objectid, u32 dir_id, u32 generation)
+
 {
-       __u32 *data = vobjp;
        struct cpu_key key;
        struct dentry *result;
        struct inode *inode;
 
-       key.on_disk_key.k_objectid = data[0];
-       key.on_disk_key.k_dir_id = data[1];
+       key.on_disk_key.k_objectid = objectid;
+       key.on_disk_key.k_dir_id = dir_id;
        reiserfs_write_lock(sb);
        inode = reiserfs_iget(sb, &key);
-       if (inode && !IS_ERR(inode) && data[2] != 0 &&
-           data[2] != inode->i_generation) {
+       if (inode && !IS_ERR(inode) && generation != 0 &&
+           generation != inode->i_generation) {
                iput(inode);
                inode = NULL;
        }
@@ -1544,14 +1545,9 @@ struct dentry *reiserfs_get_dentry(struct super_block *sb, void *vobjp)
        return result;
 }
 
-struct dentry *reiserfs_decode_fh(struct super_block *sb, __u32 * data,
-                                 int len, int fhtype,
-                                 int (*acceptable) (void *contect,
-                                                    struct dentry * de),
-                                 void *context)
+struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
+               int fh_len, int fh_type)
 {
-       __u32 obj[3], parent[3];
-
        /* fhtype happens to reflect the number of u32s encoded.
         * due to a bug in earlier code, fhtype might indicate there
         * are more u32s then actually fitted.
@@ -1564,32 +1560,28 @@ struct dentry *reiserfs_decode_fh(struct super_block *sb, __u32 * data,
         *   6 - as above plus generation of directory
         * 6 does not fit in NFSv2 handles
         */
-       if (fhtype > len) {
-               if (fhtype != 6 || len != 5)
+       if (fh_type > fh_len) {
+               if (fh_type != 6 || fh_len != 5)
                        reiserfs_warning(sb,
-                                        "nfsd/reiserfs, fhtype=%d, len=%d - odd",
-                                        fhtype, len);
-               fhtype = 5;
+                               "nfsd/reiserfs, fhtype=%d, len=%d - odd",
+                               fh_type, fh_len);
+               fh_type = 5;
        }
 
-       obj[0] = data[0];
-       obj[1] = data[1];
-       if (fhtype == 3 || fhtype >= 5)
-               obj[2] = data[2];
-       else
-               obj[2] = 0;     /* generation number */
+       return reiserfs_get_dentry(sb, fid->raw[0], fid->raw[1],
+               (fh_type == 3 || fh_type >= 5) ? fid->raw[2] : 0);
+}
 
-       if (fhtype >= 4) {
-               parent[0] = data[fhtype >= 5 ? 3 : 2];
-               parent[1] = data[fhtype >= 5 ? 4 : 3];
-               if (fhtype == 6)
-                       parent[2] = data[5];
-               else
-                       parent[2] = 0;
-       }
-       return sb->s_export_op->find_exported_dentry(sb, obj,
-                                                    fhtype < 4 ? NULL : parent,
-                                                    acceptable, context);
+struct dentry *reiserfs_fh_to_parent(struct super_block *sb, struct fid *fid,
+               int fh_len, int fh_type)
+{
+       if (fh_type < 4)
+               return NULL;
+
+       return reiserfs_get_dentry(sb,
+               (fh_type >= 5) ? fid->raw[3] : fid->raw[2],
+               (fh_type >= 5) ? fid->raw[4] : fid->raw[3],
+               (fh_type == 6) ? fid->raw[5] : 0);
 }
 
 int reiserfs_encode_fh(struct dentry *dentry, __u32 * data, int *lenp,
@@ -3061,7 +3053,11 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
 {
        struct inode *inode = dentry->d_inode;
        int error;
-       unsigned int ia_valid = attr->ia_valid;
+       unsigned int ia_valid;
+
+       /* must be turned off for recursive notify_change calls */
+       ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID);
+
        reiserfs_write_lock(inode->i_sb);
        if (attr->ia_valid & ATTR_SIZE) {
                /* version 2 items will be caught by the s_maxbytes check
index 4cad9e75ef560f6238087bf2cc49ccd5cc571412..bb05a3e51b93ba709a01135d940e8c3c0fa8f320 100644 (file)
@@ -219,11 +219,12 @@ static void allocate_bitmap_nodes(struct super_block *p_s_sb)
        }
 }
 
-static int set_bit_in_list_bitmap(struct super_block *p_s_sb, int block,
+static int set_bit_in_list_bitmap(struct super_block *p_s_sb,
+                                 b_blocknr_t block,
                                  struct reiserfs_list_bitmap *jb)
 {
-       int bmap_nr = block / (p_s_sb->s_blocksize << 3);
-       int bit_nr = block % (p_s_sb->s_blocksize << 3);
+       unsigned int bmap_nr = block / (p_s_sb->s_blocksize << 3);
+       unsigned int bit_nr = block % (p_s_sb->s_blocksize << 3);
 
        if (!jb->bitmaps[bmap_nr]) {
                jb->bitmaps[bmap_nr] = get_bitmap_node(p_s_sb);
@@ -239,7 +240,7 @@ static void cleanup_bitmap_list(struct super_block *p_s_sb,
        if (jb->bitmaps == NULL)
                return;
 
-       for (i = 0; i < SB_BMAP_NR(p_s_sb); i++) {
+       for (i = 0; i < reiserfs_bmap_count(p_s_sb); i++) {
                if (jb->bitmaps[i]) {
                        free_bitmap_node(p_s_sb, jb->bitmaps[i]);
                        jb->bitmaps[i] = NULL;
@@ -289,7 +290,7 @@ static int free_bitmap_nodes(struct super_block *p_s_sb)
 */
 int reiserfs_allocate_list_bitmaps(struct super_block *p_s_sb,
                                   struct reiserfs_list_bitmap *jb_array,
-                                  int bmap_nr)
+                                  unsigned int bmap_nr)
 {
        int i;
        int failed = 0;
@@ -483,7 +484,7 @@ static inline struct reiserfs_journal_cnode *get_journal_hash_dev(struct
 **
 */
 int reiserfs_in_journal(struct super_block *p_s_sb,
-                       int bmap_nr, int bit_nr, int search_all,
+                       unsigned int bmap_nr, int bit_nr, int search_all,
                        b_blocknr_t * next_zero_bit)
 {
        struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
@@ -1013,7 +1014,7 @@ static int flush_commit_list(struct super_block *s,
                             struct reiserfs_journal_list *jl, int flushall)
 {
        int i;
-       int bn;
+       b_blocknr_t bn;
        struct buffer_head *tbh = NULL;
        unsigned long trans_id = jl->j_trans_id;
        struct reiserfs_journal *journal = SB_JOURNAL(s);
@@ -2307,8 +2308,9 @@ static int journal_read_transaction(struct super_block *p_s_sb,
    Right now it is only used from journal code. But later we might use it
    from other places.
    Note: Do not use journal_getblk/sb_getblk functions here! */
-static struct buffer_head *reiserfs_breada(struct block_device *dev, int block,
-                                          int bufsize, unsigned int max_block)
+static struct buffer_head *reiserfs_breada(struct block_device *dev,
+                                          b_blocknr_t block, int bufsize,
+                                          b_blocknr_t max_block)
 {
        struct buffer_head *bhlist[BUFNR];
        unsigned int blocks = BUFNR;
@@ -2732,7 +2734,7 @@ int journal_init(struct super_block *p_s_sb, const char *j_dev_name,
        journal->j_persistent_trans = 0;
        if (reiserfs_allocate_list_bitmaps(p_s_sb,
                                           journal->j_list_bitmap,
-                                          SB_BMAP_NR(p_s_sb)))
+                                          reiserfs_bmap_count(p_s_sb)))
                goto free_and_return;
        allocate_bitmap_nodes(p_s_sb);
 
@@ -2740,7 +2742,7 @@ int journal_init(struct super_block *p_s_sb, const char *j_dev_name,
        SB_JOURNAL_1st_RESERVED_BLOCK(p_s_sb) = (old_format ?
                                                 REISERFS_OLD_DISK_OFFSET_IN_BYTES
                                                 / p_s_sb->s_blocksize +
-                                                SB_BMAP_NR(p_s_sb) +
+                                                reiserfs_bmap_count(p_s_sb) +
                                                 1 :
                                                 REISERFS_DISK_OFFSET_IN_BYTES /
                                                 p_s_sb->s_blocksize + 2);
index bc808a91eeaa75fba63c211667b3869a295ce1ed..5e7388b32d020f17b6b22fb515bbe04a8a3ee67c 100644 (file)
@@ -356,13 +356,11 @@ extern struct tree_balance *cur_tb;
 void reiserfs_panic(struct super_block *sb, const char *fmt, ...)
 {
        do_reiserfs_warning(fmt);
-       printk(KERN_EMERG "REISERFS: panic (device %s): %s\n",
-              reiserfs_bdevname(sb), error_buf);
-       BUG();
 
-       /* this is not actually called, but makes reiserfs_panic() "noreturn" */
-       panic("REISERFS: panic (device %s): %s\n",
-             reiserfs_bdevname(sb), error_buf);
+       dump_stack();
+
+       panic(KERN_EMERG "REISERFS: panic (device %s): %s\n",
+              reiserfs_bdevname(sb), error_buf);
 }
 
 void reiserfs_abort(struct super_block *sb, int errno, const char *fmt, ...)
index 976cc7887a0dfe60c4f5933e7d7757acfb6cf8bf..f71c3948edef8324ac68a71042fbc35209cb5ea3 100644 (file)
@@ -61,7 +61,8 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
        }
 
        /* count used bits in last bitmap block */
-       block_r = SB_BLOCK_COUNT(s) - (SB_BMAP_NR(s) - 1) * s->s_blocksize * 8;
+       block_r = SB_BLOCK_COUNT(s) -
+                       (reiserfs_bmap_count(s) - 1) * s->s_blocksize * 8;
 
        /* count bitmap blocks in new fs */
        bmap_nr_new = block_count_new / (s->s_blocksize * 8);
@@ -73,7 +74,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
 
        /* save old values */
        block_count = SB_BLOCK_COUNT(s);
-       bmap_nr = SB_BMAP_NR(s);
+       bmap_nr = reiserfs_bmap_count(s);
 
        /* resizing of reiserfs bitmaps (journal and real), if needed */
        if (bmap_nr_new > bmap_nr) {
@@ -119,7 +120,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
                        return -ENOMEM;
                }
                memset(bitmap, 0,
-                      sizeof(struct reiserfs_bitmap_info) * SB_BMAP_NR(s));
+                      sizeof(struct reiserfs_bitmap_info) * bmap_nr_new);
                for (i = 0; i < bmap_nr; i++)
                        bitmap[i] = old_bitmap[i];
 
@@ -143,7 +144,6 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
                        mark_buffer_dirty(bh);
                        sync_dirty_buffer(bh);
                        // update bitmap_info stuff
-                       bitmap[i].first_zero_hint = 1;
                        bitmap[i].free_count = sb_blocksize(sb) * 8 - 1;
                        brelse(bh);
                }
@@ -173,8 +173,6 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
        for (i = block_r; i < s->s_blocksize * 8; i++)
                reiserfs_test_and_clear_le_bit(i, bh->b_data);
        info->free_count += s->s_blocksize * 8 - block_r;
-       if (!info->first_zero_hint)
-               info->first_zero_hint = block_r;
 
        journal_mark_dirty(&th, s, bh);
        brelse(bh);
@@ -196,9 +194,6 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
        brelse(bh);
 
        info->free_count -= s->s_blocksize * 8 - block_r_new;
-       /* Extreme case where last bitmap is the only valid block in itself. */
-       if (!info->free_count)
-               info->first_zero_hint = 0;
        /* update super */
        reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
        free_blocks = SB_FREE_BLOCKS(s);
@@ -206,7 +201,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
                           free_blocks + (block_count_new - block_count -
                                          (bmap_nr_new - bmap_nr)));
        PUT_SB_BLOCK_COUNT(s, block_count_new);
-       PUT_SB_BMAP_NR(s, bmap_nr_new);
+       PUT_SB_BMAP_NR(s, bmap_would_wrap(bmap_nr_new) ? : bmap_nr_new);
        s->s_dirt = 1;
 
        journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s));
index 981027d1187bb49f33b0798cd9cfb790a2d8e549..ca41567d7890b8fecbec571d59f357e66eeb171e 100644 (file)
@@ -559,7 +559,7 @@ static int is_tree_node(struct buffer_head *bh, int level)
 /* The function is NOT SCHEDULE-SAFE! */
 static void search_by_key_reada(struct super_block *s,
                                struct buffer_head **bh,
-                               unsigned long *b, int num)
+                               b_blocknr_t *b, int num)
 {
        int i, j;
 
@@ -611,7 +611,7 @@ int search_by_key(struct super_block *p_s_sb, const struct cpu_key *p_s_key,        /*
                                           DISK_LEAF_NODE_LEVEL */
     )
 {
-       int n_block_number;
+       b_blocknr_t n_block_number;
        int expected_level;
        struct buffer_head *p_s_bh;
        struct path_element *p_s_last_element;
@@ -619,7 +619,7 @@ int search_by_key(struct super_block *p_s_sb, const struct cpu_key *p_s_key,        /*
        int right_neighbor_of_leaf_node;
        int fs_gen;
        struct buffer_head *reada_bh[SEARCH_BY_KEY_READA];
-       unsigned long reada_blocks[SEARCH_BY_KEY_READA];
+       b_blocknr_t reada_blocks[SEARCH_BY_KEY_READA];
        int reada_count = 0;
 
 #ifdef CONFIG_REISERFS_CHECK
index b82897ae090bdba89331029216c3ce33893415fd..5cd85fe5df5d9671516a03d3c9927b96ea0e7c63 100644 (file)
@@ -319,7 +319,7 @@ static int finish_unfinished(struct super_block *s)
 
 /* to protect file being unlinked from getting lost we "safe" link files
    being unlinked. This link will be deleted in the same transaction with last
-   item of file. mounting the filesytem we scan all these links and remove
+   item of file. mounting the filesystem we scan all these links and remove
    files which almost got lost */
 void add_save_link(struct reiserfs_transaction_handle *th,
                   struct inode *inode, int truncate)
@@ -661,11 +661,11 @@ static struct quotactl_ops reiserfs_qctl_operations = {
 };
 #endif
 
-static struct export_operations reiserfs_export_ops = {
+static const struct export_operations reiserfs_export_ops = {
        .encode_fh = reiserfs_encode_fh,
-       .decode_fh = reiserfs_decode_fh,
+       .fh_to_dentry = reiserfs_fh_to_dentry,
+       .fh_to_parent = reiserfs_fh_to_parent,
        .get_parent = reiserfs_get_parent,
-       .get_dentry = reiserfs_get_dentry,
 };
 
 /* this struct is used in reiserfs_getopt () for containing the value for those
@@ -1725,6 +1725,21 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
                set_sb_umount_state(rs, REISERFS_ERROR_FS);
                set_sb_fs_state(rs, 0);
 
+               /* Clear out s_bmap_nr if it would wrap. We can handle this
+                * case, but older revisions can't. This will cause the
+                * file system to fail mount on those older implementations,
+                * avoiding corruption. -jeffm */
+               if (bmap_would_wrap(reiserfs_bmap_count(s)) &&
+                   sb_bmap_nr(rs) != 0) {
+                       reiserfs_warning(s, "super-2030: This file system "
+                                       "claims to use %u bitmap blocks in "
+                                       "its super block, but requires %u. "
+                                       "Clearing to zero.", sb_bmap_nr(rs),
+                                       reiserfs_bmap_count(s));
+
+                       set_sb_bmap_nr(rs, 0);
+               }
+
                if (old_format_only(s)) {
                        /* filesystem of format 3.5 either with standard or non-standard
                           journal */
index fab4b9b2664fff2d460e93ef87f5d606be32a082..1597f6b649e040a5aad306e5cde5330f2e953f73 100644 (file)
@@ -484,7 +484,7 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer,
        /* Resize it so we're ok to write there */
        newattrs.ia_size = buffer_size;
        newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
-       mutex_lock(&xinode->i_mutex);
+       mutex_lock_nested(&xinode->i_mutex, I_MUTEX_XATTR);
        err = notify_change(fp->f_path.dentry, &newattrs);
        if (err)
                goto out_filp;
@@ -1223,7 +1223,8 @@ int reiserfs_xattr_init(struct super_block *s, int mount_flags)
                if (!IS_ERR(dentry)) {
                        if (!(mount_flags & MS_RDONLY) && !dentry->d_inode) {
                                struct inode *inode = dentry->d_parent->d_inode;
-                               mutex_lock(&inode->i_mutex);
+                               mutex_lock_nested(&inode->i_mutex,
+                                                 I_MUTEX_XATTR);
                                err = inode->i_op->mkdir(inode, dentry, 0700);
                                mutex_unlock(&inode->i_mutex);
                                if (err) {
index 7dede89658f535964e8808682d6d7fe784281d4e..47f47925aea2bead2a4491d672476a7a63e9be1b 100644 (file)
@@ -177,11 +177,6 @@ get_max:
        return max;
 }
 
-#define BIT(i)         (1UL << ((i)&(__NFDBITS-1)))
-#define MEM(i,m)       ((m)+(unsigned)(i)/__NFDBITS)
-#define ISSET(i,m)     (((i)&*(m)) != 0)
-#define SET(i,m)       (*(m) |= (i))
-
 #define POLLIN_SET (POLLRDNORM | POLLRDBAND | POLLIN | POLLHUP | POLLERR)
 #define POLLOUT_SET (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR)
 #define POLLEX_SET (POLLPRI)
index 1bfcca2104be91ac9a8233cd94bf0e0e3ef6a182..ceaf2e3d594cdd89afabab0253cf1ab59badceba 100644 (file)
@@ -15,7 +15,7 @@
  *  Added kerneld support: Jacques Gelinas and Bjorn Ekwall
  *  Added change_root: Werner Almesberger & Hans Lermen, Feb '96
  *  Added options to /proc/mounts:
- *    Torbjörn Lindh (torbjorn.lindh@gopta.se), April 14, 1996.
+ *    Torbjörn Lindh (torbjorn.lindh@gopta.se), April 14, 1996.
  *  Added devfs support: Richard Gooch <rgooch@atnf.csiro.au>, 13-JAN-1998
  *  Heavily rewritten for 'one fs - one tree' dcache architecture. AV, Mar 2000
  */
 #include <asm/uaccess.h>
 
 
-void get_filesystem(struct file_system_type *fs);
-void put_filesystem(struct file_system_type *fs);
-struct file_system_type *get_fs_type(const char *name);
-
 LIST_HEAD(super_blocks);
 DEFINE_SPINLOCK(sb_lock);
 
@@ -336,21 +332,21 @@ struct super_block *sget(struct file_system_type *type,
                        void *data)
 {
        struct super_block *s = NULL;
-       struct list_head *p;
+       struct super_block *old;
        int err;
 
 retry:
        spin_lock(&sb_lock);
-       if (test) list_for_each(p, &type->fs_supers) {
-               struct super_block *old;
-               old = list_entry(p, struct super_block, s_instances);
-               if (!test(old, data))
-                       continue;
-               if (!grab_super(old))
-                       goto retry;
-               if (s)
-                       destroy_super(s);
-               return old;
+       if (test) {
+               list_for_each_entry(old, &type->fs_supers, s_instances) {
+                       if (!test(old, data))
+                               continue;
+                       if (!grab_super(old))
+                               goto retry;
+                       if (s)
+                               destroy_super(s);
+                       return old;
+               }
        }
        if (!s) {
                spin_unlock(&sb_lock);
@@ -421,7 +417,7 @@ restart:
 }
 
 /*
- * Call the ->sync_fs super_op against all filesytems which are r/w and
+ * Call the ->sync_fs super_op against all filesystems which are r/w and
  * which implement it.
  *
  * This operation is careful to avoid the livelock which could easily happen
@@ -429,7 +425,7 @@ restart:
  * is used only here.  We set it against all filesystems and then clear it as
  * we sync them.  So redirtied filesystems are skipped.
  *
- * But if process A is currently running sync_filesytems and then process B
+ * But if process A is currently running sync_filesystems and then process B
  * calls sync_filesystems as well, process B will set all the s_need_sync_fs
  * flags again, which will cause process A to resync everything.  Fix that with
  * a local mutex.
@@ -948,9 +944,9 @@ do_kern_mount(const char *fstype, int flags, const char *name, void *data)
        return mnt;
 }
 
-struct vfsmount *kern_mount(struct file_system_type *type)
+struct vfsmount *kern_mount_data(struct file_system_type *type, void *data)
 {
-       return vfs_kern_mount(type, 0, type->name, NULL);
+       return vfs_kern_mount(type, MS_KERNMOUNT, type->name, data);
 }
 
-EXPORT_SYMBOL(kern_mount);
+EXPORT_SYMBOL_GPL(kern_mount_data);
index d3be1e7fb48b6d3ad4ccb7ceccf1b1fbf637767e..27d1785b764463c4bc654e9713f41c369d9ea0cb 100644 (file)
@@ -540,7 +540,7 @@ int sysfs_add_file(struct sysfs_dirent *dir_sd, const struct attribute *attr,
 /**
  *     sysfs_create_file - create an attribute file for an object.
  *     @kobj:  object we're creating for. 
- *     @attr:  atrribute descriptor.
+ *     @attr:  attribute descriptor.
  */
 
 int sysfs_create_file(struct kobject * kobj, const struct attribute * attr)
index a44fd92caca31c72aba82e61ec6b321d7ebf5a7d..6645b7313b3372a0a490bdc9b382f81fc8ace71c 100644 (file)
@@ -267,7 +267,7 @@ sys_fsetxattr(int fd, char __user *name, void __user *value,
        if (!f)
                return error;
        dentry = f->f_path.dentry;
-       audit_inode(NULL, dentry->d_inode);
+       audit_inode(NULL, dentry);
        error = setxattr(dentry, name, value, size, flags);
        fput(f);
        return error;
@@ -349,7 +349,7 @@ sys_fgetxattr(int fd, char __user *name, void __user *value, size_t size)
        f = fget(fd);
        if (!f)
                return error;
-       audit_inode(NULL, f->f_path.dentry->d_inode);
+       audit_inode(NULL, f->f_path.dentry);
        error = getxattr(f->f_path.dentry, name, value, size);
        fput(f);
        return error;
@@ -422,7 +422,7 @@ sys_flistxattr(int fd, char __user *list, size_t size)
        f = fget(fd);
        if (!f)
                return error;
-       audit_inode(NULL, f->f_path.dentry->d_inode);
+       audit_inode(NULL, f->f_path.dentry);
        error = listxattr(f->f_path.dentry, list, size);
        fput(f);
        return error;
@@ -485,7 +485,7 @@ sys_fremovexattr(int fd, char __user *name)
        if (!f)
                return error;
        dentry = f->f_path.dentry;
-       audit_inode(NULL, dentry->d_inode);
+       audit_inode(NULL, dentry);
        error = removexattr(dentry, name);
        fput(f);
        return error;
index 726449d4fd223fc80817968e50c77d1e92f3977f..15bd4948832ce7b1f789074b4ec77f53d0a9e25a 100644 (file)
 static struct dentry dotdot = { .d_name.name = "..", .d_name.len = 2, };
 
 /*
- * XFS encodes and decodes the fileid portion of NFS filehandles
- * itself instead of letting the generic NFS code do it.  This
- * allows filesystems with 64 bit inode numbers to be exported.
- *
- * Note that a side effect is that xfs_vget() won't be passed a
- * zero inode/generation pair under normal circumstances.  As
- * however a malicious client could send us such data, the check
- * remains in that code.
+ * Note that we only accept fileids which are long enough rather than allow
+ * the parent generation number to default to zero.  XFS considers zero a
+ * valid generation number not an invalid/wildcard value.
  */
-
-STATIC struct dentry *
-xfs_fs_decode_fh(
-       struct super_block      *sb,
-       __u32                   *fh,
-       int                     fh_len,
-       int                     fileid_type,
-       int (*acceptable)(
-               void            *context,
-               struct dentry   *de),
-       void                    *context)
+static int xfs_fileid_length(int fileid_type)
 {
-       xfs_fid2_t              ifid;
-       xfs_fid2_t              pfid;
-       void                    *parent = NULL;
-       int                     is64 = 0;
-       __u32                   *p = fh;
-
-#if XFS_BIG_INUMS
-       is64 = (fileid_type & XFS_FILEID_TYPE_64FLAG);
-       fileid_type &= ~XFS_FILEID_TYPE_64FLAG;
-#endif
-
-       /*
-        * Note that we only accept fileids which are long enough
-        * rather than allow the parent generation number to default
-        * to zero.  XFS considers zero a valid generation number not
-        * an invalid/wildcard value.  There's little point printk'ing
-        * a warning here as we don't have the client information
-        * which would make such a warning useful.
-        */
-       if (fileid_type > 2 ||
-           fh_len < xfs_fileid_length((fileid_type == 2), is64))
-               return NULL;
-
-       p = xfs_fileid_decode_fid2(p, &ifid, is64);
-
-       if (fileid_type == 2) {
-               p = xfs_fileid_decode_fid2(p, &pfid, is64);
-               parent = &pfid;
+       switch (fileid_type) {
+       case FILEID_INO32_GEN:
+               return 2;
+       case FILEID_INO32_GEN_PARENT:
+               return 4;
+       case FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG:
+               return 3;
+       case FILEID_INO32_GEN_PARENT | XFS_FILEID_TYPE_64FLAG:
+               return 6;
        }
-
-       fh = (__u32 *)&ifid;
-       return sb->s_export_op->find_exported_dentry(sb, fh, parent, acceptable, context);
+       return 255; /* invalid */
 }
 
-
 STATIC int
 xfs_fs_encode_fh(
        struct dentry           *dentry,
@@ -96,21 +59,21 @@ xfs_fs_encode_fh(
        int                     *max_len,
        int                     connectable)
 {
+       struct fid              *fid = (struct fid *)fh;
+       struct xfs_fid64        *fid64 = (struct xfs_fid64 *)fh;
        struct inode            *inode = dentry->d_inode;
-       int                     type = 1;
-       __u32                   *p = fh;
+       int                     fileid_type;
        int                     len;
-       int                     is64 = 0;
-#if XFS_BIG_INUMS
-       if (!(XFS_M(inode->i_sb)->m_flags & XFS_MOUNT_SMALL_INUMS)) {
-               /* filesystem may contain 64bit inode numbers */
-               is64 = XFS_FILEID_TYPE_64FLAG;
-       }
-#endif
 
        /* Directories don't need their parent encoded, they have ".." */
        if (S_ISDIR(inode->i_mode))
-           connectable = 0;
+               fileid_type = FILEID_INO32_GEN;
+       else
+               fileid_type = FILEID_INO32_GEN_PARENT;
+
+       /* filesystem may contain 64bit inode numbers */
+       if (!(XFS_M(inode->i_sb)->m_flags & XFS_MOUNT_SMALL_INUMS))
+               fileid_type |= XFS_FILEID_TYPE_64FLAG;
 
        /*
         * Only encode if there is enough space given.  In practice
@@ -118,39 +81,118 @@ xfs_fs_encode_fh(
         * over NFSv2 with the subtree_check export option; the other
         * seven combinations work.  The real answer is "don't use v2".
         */
-       len = xfs_fileid_length(connectable, is64);
+       len = xfs_fileid_length(fileid_type);
        if (*max_len < len)
                return 255;
        *max_len = len;
 
-       p = xfs_fileid_encode_inode(p, inode, is64);
-       if (connectable) {
+       switch (fileid_type) {
+       case FILEID_INO32_GEN_PARENT:
                spin_lock(&dentry->d_lock);
-               p = xfs_fileid_encode_inode(p, dentry->d_parent->d_inode, is64);
+               fid->i32.parent_ino = dentry->d_parent->d_inode->i_ino;
+               fid->i32.parent_gen = dentry->d_parent->d_inode->i_generation;
                spin_unlock(&dentry->d_lock);
-               type = 2;
+               /*FALLTHRU*/
+       case FILEID_INO32_GEN:
+               fid->i32.ino = inode->i_ino;
+               fid->i32.gen = inode->i_generation;
+               break;
+       case FILEID_INO32_GEN_PARENT | XFS_FILEID_TYPE_64FLAG:
+               spin_lock(&dentry->d_lock);
+               fid64->parent_ino = dentry->d_parent->d_inode->i_ino;
+               fid64->parent_gen = dentry->d_parent->d_inode->i_generation;
+               spin_unlock(&dentry->d_lock);
+               /*FALLTHRU*/
+       case FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG:
+               fid64->ino = inode->i_ino;
+               fid64->gen = inode->i_generation;
+               break;
        }
-       BUG_ON((p - fh) != len);
-       return type | is64;
+
+       return fileid_type;
 }
 
-STATIC struct dentry *
-xfs_fs_get_dentry(
+STATIC struct inode *
+xfs_nfs_get_inode(
        struct super_block      *sb,
-       void                    *data)
-{
+       u64                     ino,
+       u32                     generation)
+ {
+       xfs_fid_t               xfid;
        bhv_vnode_t             *vp;
-       struct inode            *inode;
-       struct dentry           *result;
        int                     error;
 
-       error = xfs_vget(XFS_M(sb), &vp, (fid_t *)data);
-       if (error || vp == NULL)
-               return ERR_PTR(-ESTALE) ;
+       xfid.fid_len = sizeof(xfs_fid_t) - sizeof(xfid.fid_len);
+       xfid.fid_pad = 0;
+       xfid.fid_ino = ino;
+       xfid.fid_gen = generation;
 
-       inode = vn_to_inode(vp);
+       error = xfs_vget(XFS_M(sb), &vp, &xfid);
+       if (error)
+               return ERR_PTR(-error);
+
+       return vp ? vn_to_inode(vp) : NULL;
+}
+
+STATIC struct dentry *
+xfs_fs_fh_to_dentry(struct super_block *sb, struct fid *fid,
+                int fh_len, int fileid_type)
+{
+       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;
+
+       switch (fileid_type) {
+       case FILEID_INO32_GEN_PARENT:
+       case FILEID_INO32_GEN:
+               inode = xfs_nfs_get_inode(sb, fid->i32.ino, fid->i32.gen);
+               break;
+       case FILEID_INO32_GEN_PARENT | XFS_FILEID_TYPE_64FLAG:
+       case FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG:
+               inode = xfs_nfs_get_inode(sb, fid64->ino, fid64->gen);
+               break;
+       }
+
+       if (!inode)
+               return NULL;
+       if (IS_ERR(inode))
+               return ERR_PTR(PTR_ERR(inode));
+       result = d_alloc_anon(inode);
+       if (!result) {
+               iput(inode);
+               return ERR_PTR(-ENOMEM);
+       }
+       return result;
+}
+
+STATIC struct dentry *
+xfs_fs_fh_to_parent(struct super_block *sb, struct fid *fid,
+                int fh_len, int fileid_type)
+{
+       struct xfs_fid64        *fid64 = (struct xfs_fid64 *)fid;
+       struct inode            *inode = NULL;
+       struct dentry           *result;
+
+       switch (fileid_type) {
+       case FILEID_INO32_GEN_PARENT:
+               inode = xfs_nfs_get_inode(sb, fid->i32.parent_ino,
+                                             fid->i32.parent_gen);
+               break;
+       case FILEID_INO32_GEN_PARENT | XFS_FILEID_TYPE_64FLAG:
+               inode = xfs_nfs_get_inode(sb, fid64->parent_ino,
+                                             fid64->parent_gen);
+               break;
+       }
+
+       if (!inode)
+               return NULL;
+       if (IS_ERR(inode))
+               return ERR_PTR(PTR_ERR(inode));
        result = d_alloc_anon(inode);
-        if (!result) {
+       if (!result) {
                iput(inode);
                return ERR_PTR(-ENOMEM);
        }
@@ -178,9 +220,9 @@ xfs_fs_get_parent(
        return parent;
 }
 
-struct export_operations xfs_export_operations = {
-       .decode_fh              = xfs_fs_decode_fh,
+const struct export_operations xfs_export_operations = {
        .encode_fh              = xfs_fs_encode_fh,
+       .fh_to_dentry           = xfs_fs_fh_to_dentry,
+       .fh_to_parent           = xfs_fs_fh_to_parent,
        .get_parent             = xfs_fs_get_parent,
-       .get_dentry             = xfs_fs_get_dentry,
 };
index e794ca4efc761b28edd3813f6c9dea16ca03d957..3272b6ae7a356d229b99611aabb5ea3976279fb2 100644 (file)
  * a subdirectory) or use the "fsid" export option.
  */
 
+struct xfs_fid64 {
+       u64 ino;
+       u32 gen;
+       u64 parent_ino;
+       u32 parent_gen;
+} __attribute__((packed));
+
 /* This flag goes on the wire.  Don't play with it. */
 #define XFS_FILEID_TYPE_64FLAG 0x80    /* NFS fileid has 64bit inodes */
 
-/* Calculate the length in u32 units of the fileid data */
-static inline int
-xfs_fileid_length(int hasparent, int is64)
-{
-       return hasparent ? (is64 ? 6 : 4) : (is64 ? 3 : 2);
-}
-
-/*
- * Decode encoded inode information (either for the inode itself
- * or the parent) into an xfs_fid2_t structure.  Advances and
- * returns the new data pointer
- */
-static inline __u32 *
-xfs_fileid_decode_fid2(__u32 *p, xfs_fid2_t *fid, int is64)
-{
-       fid->fid_len = sizeof(xfs_fid2_t) - sizeof(fid->fid_len);
-       fid->fid_pad = 0;
-       fid->fid_ino = *p++;
-#if XFS_BIG_INUMS
-       if (is64)
-               fid->fid_ino |= (((__u64)(*p++)) << 32);
-#endif
-       fid->fid_gen = *p++;
-       return p;
-}
-
-/*
- * Encode inode information (either for the inode itself or the
- * parent) into a fileid buffer.  Advances and returns the new
- * data pointer.
- */
-static inline __u32 *
-xfs_fileid_encode_inode(__u32 *p, struct inode *inode, int is64)
-{
-       *p++ = (__u32)inode->i_ino;
-#if XFS_BIG_INUMS
-       if (is64)
-               *p++ = (__u32)(inode->i_ino >> 32);
-#endif
-       *p++ = inode->i_generation;
-       return p;
-}
-
 #endif /* __XFS_EXPORT_H__ */
index ffec630e7db71743ecc2b63089992be081b8e830..2b34bad48b079c73da80bc47c696d92a51198bd4 100644 (file)
@@ -152,11 +152,11 @@ xfs_find_handle(
                lock_mode = xfs_ilock_map_shared(ip);
 
                /* fill in fid section of handle from inode */
-               handle.ha_fid.xfs_fid_len = sizeof(xfs_fid_t) -
-                                           sizeof(handle.ha_fid.xfs_fid_len);
-               handle.ha_fid.xfs_fid_pad = 0;
-               handle.ha_fid.xfs_fid_gen = ip->i_d.di_gen;
-               handle.ha_fid.xfs_fid_ino = ip->i_ino;
+               handle.ha_fid.fid_len = sizeof(xfs_fid_t) -
+                                       sizeof(handle.ha_fid.fid_len);
+               handle.ha_fid.fid_pad = 0;
+               handle.ha_fid.fid_gen = ip->i_d.di_gen;
+               handle.ha_fid.fid_ino = ip->i_ino;
 
                xfs_iunlock_map_shared(ip, lock_mode);
 
@@ -222,10 +222,10 @@ xfs_vget_fsop_handlereq(
        if (hlen < sizeof(*handlep))
                memset(((char *)handlep) + hlen, 0, sizeof(*handlep) - hlen);
        if (hlen > sizeof(handlep->ha_fsid)) {
-               if (handlep->ha_fid.xfs_fid_len !=
-                               (hlen - sizeof(handlep->ha_fsid)
-                                       - sizeof(handlep->ha_fid.xfs_fid_len))
-                   || handlep->ha_fid.xfs_fid_pad)
+               if (handlep->ha_fid.fid_len !=
+                   (hlen - sizeof(handlep->ha_fsid) -
+                           sizeof(handlep->ha_fid.fid_len)) ||
+                   handlep->ha_fid.fid_pad)
                        return XFS_ERROR(EINVAL);
        }
 
@@ -233,9 +233,9 @@ xfs_vget_fsop_handlereq(
         * Crack the handle, obtain the inode # & generation #
         */
        xfid = (struct xfs_fid *)&handlep->ha_fid;
-       if (xfid->xfs_fid_len == sizeof(*xfid) - sizeof(xfid->xfs_fid_len)) {
-               ino  = xfid->xfs_fid_ino;
-               igen = xfid->xfs_fid_gen;
+       if (xfid->fid_len == sizeof(*xfid) - sizeof(xfid->fid_len)) {
+               ino  = xfid->fid_ino;
+               igen = xfid->fid_gen;
        } else {
                return XFS_ERROR(EINVAL);
        }
index c78c23310fe85296f00affc28796fe58d419c544..3efcf45b14abed330cd482a8370b76c398572fde 100644 (file)
@@ -118,7 +118,7 @@ extern int  xfs_blkdev_get(struct xfs_mount *, const char *,
 extern void xfs_blkdev_put(struct block_device *);
 extern void xfs_blkdev_issue_flush(struct xfs_buftarg *);
 
-extern struct export_operations xfs_export_operations;
+extern const struct export_operations xfs_export_operations;
 
 #define XFS_M(sb)              ((struct xfs_mount *)((sb)->s_fs_info))
 
index 6cd5704258a29f1584ec63faa9a7a000e71eb05e..a1e55fb9d5dde43c95565c1aece67d4345232391 100644 (file)
@@ -41,29 +41,16 @@ int
 xfs_dmops_get(struct xfs_mount *mp, struct xfs_mount_args *args)
 {
        if (args->flags & XFSMNT_DMAPI) {
-               struct xfs_dmops *ops;
-
-               ops = symbol_get(xfs_dmcore_xfs);
-               if (!ops) {
-                       request_module("xfs_dmapi");
-                       ops = symbol_get(xfs_dmcore_xfs);
-               }
-
-               if (!ops) {
-                       cmn_err(CE_WARN, "XFS: no dmapi support available.");
-                       return EINVAL;
-               }
-               mp->m_dm_ops = ops;
-       } else {
-               mp->m_dm_ops = &xfs_dmcore_stub;
+               cmn_err(CE_WARN,
+                       "XFS: dmapi support not available in this kernel.");
+               return EINVAL;
        }
 
+       mp->m_dm_ops = &xfs_dmcore_stub;
        return 0;
 }
 
 void
 xfs_dmops_put(struct xfs_mount *mp)
 {
-       if (mp->m_dm_ops != &xfs_dmcore_stub)
-               symbol_put(xfs_dmcore_xfs);
 }
index ec3c9c27e0de699fe66e6fc1aaf48428549b072b..aab9662765170b556bdf82cd623c2642dce8aa45 100644 (file)
@@ -389,30 +389,13 @@ typedef struct xfs_fsop_attrmulti_handlereq {
  */
 typedef struct { __u32 val[2]; } xfs_fsid_t; /* file system id type */
 
-
-#ifndef HAVE_FID
-#define MAXFIDSZ       46
-
-typedef struct fid {
-       __u16           fid_len;                /* length of data in bytes */
-       unsigned char   fid_data[MAXFIDSZ];     /* data (fid_len worth)  */
-} fid_t;
-#endif
-
 typedef struct xfs_fid {
-       __u16   xfs_fid_len;            /* length of remainder  */
-       __u16   xfs_fid_pad;
-       __u32   xfs_fid_gen;            /* generation number    */
-       __u64   xfs_fid_ino;            /* 64 bits inode number */
+       __u16   fid_len;                /* length of remainder  */
+       __u16   fid_pad;
+       __u32   fid_gen;                /* generation number    */
+       __u64   fid_ino;                /* 64 bits inode number */
 } xfs_fid_t;
 
-typedef struct xfs_fid2 {
-       __u16   fid_len;        /* length of remainder */
-       __u16   fid_pad;        /* padding, must be zero */
-       __u32   fid_gen;        /* generation number */
-       __u64   fid_ino;        /* inode number */
-} xfs_fid2_t;
-
 typedef struct xfs_handle {
        union {
                __s64       align;      /* force alignment of ha_fid     */
@@ -422,9 +405,9 @@ typedef struct xfs_handle {
 } xfs_handle_t;
 #define ha_fsid ha_u._ha_fsid
 
-#define XFS_HSIZE(handle)      (((char *) &(handle).ha_fid.xfs_fid_pad  \
+#define XFS_HSIZE(handle)      (((char *) &(handle).ha_fid.fid_pad      \
                                 - (char *) &(handle))                    \
-                                + (handle).ha_fid.xfs_fid_len)
+                                + (handle).ha_fid.fid_len)
 
 /*
  * Flags for going down operation
index c266a0184b42e2e38eac37059a1b8ee0997dd1ab..2ec1d8a27352e6a8595af8cbaecbfc9390e16cdd 100644 (file)
@@ -135,19 +135,13 @@ int
 xfs_qmops_get(struct xfs_mount *mp, struct xfs_mount_args *args)
 {
        if (args->flags & (XFSMNT_UQUOTA | XFSMNT_PQUOTA | XFSMNT_GQUOTA)) {
-               struct xfs_qmops *ops;
-
-               ops = symbol_get(xfs_qmcore_xfs);
-               if (!ops) {
-                       request_module("xfs_quota");
-                       ops = symbol_get(xfs_qmcore_xfs);
-               }
-
-               if (!ops) {
-                       cmn_err(CE_WARN, "XFS: no quota support available.");
-                       return EINVAL;
-               }
-               mp->m_qm_ops = ops;
+#ifdef CONFIG_XFS_QUOTA
+               mp->m_qm_ops = &xfs_qmcore_xfs;
+#else
+               cmn_err(CE_WARN,
+                       "XFS: qouta support not available in this kernel.");
+               return EINVAL;
+#endif
        } else {
                mp->m_qm_ops = &xfs_qmcore_stub;
        }
@@ -158,6 +152,4 @@ xfs_qmops_get(struct xfs_mount *mp, struct xfs_mount_args *args)
 void
 xfs_qmops_put(struct xfs_mount *mp)
 {
-       if (mp->m_qm_ops != &xfs_qmcore_stub)
-               symbol_put(xfs_qmcore_xfs);
 }
index a5a8454f2a631684de389d911a54055c5e64701a..a1544597bcd318c7f35a80551321c1f103b55f13 100644 (file)
@@ -1635,9 +1635,8 @@ int
 xfs_vget(
        xfs_mount_t     *mp,
        bhv_vnode_t     **vpp,
-       fid_t           *fidp)
+       xfs_fid_t       *xfid)
 {
-       xfs_fid_t       *xfid = (struct xfs_fid *)fidp;
        xfs_inode_t     *ip;
        int             error;
        xfs_ino_t       ino;
@@ -1647,11 +1646,11 @@ xfs_vget(
         * Invalid.  Since handles can be created in user space and passed in
         * via gethandle(), this is not cause for a panic.
         */
-       if (xfid->xfs_fid_len != sizeof(*xfid) - sizeof(xfid->xfs_fid_len))
+       if (xfid->fid_len != sizeof(*xfid) - sizeof(xfid->fid_len))
                return XFS_ERROR(EINVAL);
 
-       ino  = xfid->xfs_fid_ino;
-       igen = xfid->xfs_fid_gen;
+       ino  = xfid->fid_ino;
+       igen = xfid->fid_gen;
 
        /*
         * NFS can sometimes send requests for ino 0.  Fail them gracefully.
index bc99e3eb7dbba0291d139c4e0a6340e18f64b87b..a592fe02a3393367150447d4dae6af4ce36870dc 100644 (file)
@@ -2,7 +2,7 @@
 #define _XFS_VFSOPS_H 1
 
 struct cred;
-struct fid;
+struct xfs_fid;
 struct inode;
 struct kstatfs;
 struct xfs_mount;
@@ -17,7 +17,7 @@ int xfs_root(struct xfs_mount *mp, bhv_vnode_t **vpp);
 int xfs_statvfs(struct xfs_mount *mp, struct kstatfs *statp,
                bhv_vnode_t *vp);
 int xfs_sync(struct xfs_mount *mp, int flags);
-int xfs_vget(struct xfs_mount *mp, bhv_vnode_t **vpp, struct fid *fidp);
+int xfs_vget(struct xfs_mount *mp, bhv_vnode_t **vpp, struct xfs_fid *xfid);
 int xfs_parseargs(struct xfs_mount *mp, char *options,
                struct xfs_mount_args *args, int update);
 int xfs_showargs(struct xfs_mount *mp, struct seq_file *m);
index 5e3c57ca9981e6573b4a968e91f3a18e8ee68b42..efd5aff9eaf6aa1d149fa6431ca6355e944c5b1a 100644 (file)
@@ -3466,23 +3466,14 @@ std_return:
 }
 
 
-/*
- * xfs_fid2
- *
- * A fid routine that takes a pointer to a previously allocated
- * fid structure (like xfs_fast_fid) but uses a 64 bit inode number.
- */
 int
 xfs_fid2(
        xfs_inode_t     *ip,
-       fid_t           *fidp)
+       xfs_fid_t       *xfid)
 {
-       xfs_fid2_t      *xfid = (xfs_fid2_t *)fidp;
-
        vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
-       ASSERT(sizeof(fid_t) >= sizeof(xfs_fid2_t));
 
-       xfid->fid_len = sizeof(xfs_fid2_t) - sizeof(xfid->fid_len);
+       xfid->fid_len = sizeof(xfs_fid_t) - sizeof(xfid->fid_len);
        xfid->fid_pad = 0;
        /*
         * use memcpy because the inode is a long long and there's no
index f36e74f2f0c2a18719fcaca6b585fefe97ce940a..b7e461c40cfbace8e0289ab1d131a67f8b813a86 100644 (file)
@@ -39,7 +39,7 @@ int xfs_readdir(struct xfs_inode      *dp, void *dirent, size_t bufsize,
 int xfs_symlink(struct xfs_inode *dp, bhv_vname_t *dentry,
                char *target_path, mode_t mode, bhv_vnode_t **vpp,
                struct cred *credp);
-int xfs_fid2(struct xfs_inode *ip, fid_t       *fidp);
+int xfs_fid2(struct xfs_inode *ip, struct xfs_fid *xfid);
 int xfs_rwlock(struct xfs_inode *ip, bhv_vrwlock_t locktype);
 void xfs_rwunlock(struct xfs_inode *ip, bhv_vrwlock_t locktype);
 int xfs_inode_flush(struct xfs_inode *ip, int flags);
index 9df275cf7bc1a795e9b8aeff4555f07de249c35c..4053df94345306968f68216bfb05744ecc1cf223 100644 (file)
@@ -71,9 +71,9 @@ u32 acpi_hw_get_mode(void);
 struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id);
 
 acpi_status
-acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value);
+acpi_hw_register_read(u32 register_id, u32 * return_value);
 
-acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value);
+acpi_status acpi_hw_register_write(u32 register_id, u32 value);
 
 acpi_status
 acpi_hw_low_level_read(u32 width,
index 86aea44ce6d447a83ed0146288f514c225171314..7b74b60a68a47b26d3addf541b3440f23bd947ad 100644 (file)
@@ -264,7 +264,6 @@ struct acpi_device_wakeup_flags {
 
 struct acpi_device_wakeup_state {
        u8 enabled:1;
-       u8 active:1;
 };
 
 struct acpi_device_wakeup {
@@ -333,6 +332,7 @@ int acpi_bus_get_power(acpi_handle handle, int *state);
 int acpi_bus_set_power(acpi_handle handle, int state);
 #ifdef CONFIG_ACPI_PROC_EVENT
 int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data);
+int acpi_bus_generate_proc_event4(const char *class, const char *bid, u8 type, int data);
 int acpi_bus_receive_event(struct acpi_bus_event *event);
 #else
 static inline int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
index 3d7ab9e0c9fe2e93dacda51f409b65cbe5a0bb3f..9512f0456ad1f241df8ba36e64f1d0cb060fef6a 100644 (file)
@@ -314,6 +314,8 @@ acpi_resource_to_address64(struct acpi_resource *resource,
  */
 acpi_status acpi_get_register(u32 register_id, u32 * return_value);
 
+acpi_status acpi_get_register_unlocked(u32 register_id, u32 *return_value);
+
 acpi_status acpi_set_register(u32 register_id, u32 value);
 
 acpi_status
index 4e5d3ca53a8eb15d6ae209d187f15404a7edf0bc..a1b1b2ee3e512d0c1d3a338c2cd1aca50dee2372 100644 (file)
@@ -257,7 +257,8 @@ struct acpi_table_dbgp {
 struct acpi_table_dmar {
        struct acpi_table_header header;        /* Common ACPI table header */
        u8 width;               /* Host Address Width */
-       u8 reserved[11];
+       u8 flags;
+       u8 reserved[10];
 };
 
 /* DMAR subtable header */
@@ -265,8 +266,6 @@ struct acpi_table_dmar {
 struct acpi_dmar_header {
        u16 type;
        u16 length;
-       u8 flags;
-       u8 reserved[3];
 };
 
 /* Values for subtable type in struct acpi_dmar_header */
@@ -274,13 +273,15 @@ struct acpi_dmar_header {
 enum acpi_dmar_type {
        ACPI_DMAR_TYPE_HARDWARE_UNIT = 0,
        ACPI_DMAR_TYPE_RESERVED_MEMORY = 1,
-       ACPI_DMAR_TYPE_RESERVED = 2     /* 2 and greater are reserved */
+       ACPI_DMAR_TYPE_ATSR = 2,
+       ACPI_DMAR_TYPE_RESERVED = 3     /* 3 and greater are reserved */
 };
 
 struct acpi_dmar_device_scope {
        u8 entry_type;
        u8 length;
-       u8 segment;
+       u16 reserved;
+       u8 enumeration_id;
        u8 bus;
 };
 
@@ -290,7 +291,14 @@ enum acpi_dmar_scope_type {
        ACPI_DMAR_SCOPE_TYPE_NOT_USED = 0,
        ACPI_DMAR_SCOPE_TYPE_ENDPOINT = 1,
        ACPI_DMAR_SCOPE_TYPE_BRIDGE = 2,
-       ACPI_DMAR_SCOPE_TYPE_RESERVED = 3       /* 3 and greater are reserved */
+       ACPI_DMAR_SCOPE_TYPE_IOAPIC = 3,
+       ACPI_DMAR_SCOPE_TYPE_HPET = 4,
+       ACPI_DMAR_SCOPE_TYPE_RESERVED = 5       /* 5 and greater are reserved */
+};
+
+struct acpi_dmar_pci_path {
+       u8 dev;
+       u8 fn;
 };
 
 /*
@@ -301,6 +309,9 @@ enum acpi_dmar_scope_type {
 
 struct acpi_dmar_hardware_unit {
        struct acpi_dmar_header header;
+       u8 flags;
+       u8 reserved;
+       u16 segment;
        u64 address;            /* Register Base Address */
 };
 
@@ -312,7 +323,9 @@ struct acpi_dmar_hardware_unit {
 
 struct acpi_dmar_reserved_memory {
        struct acpi_dmar_header header;
-       u64 address;            /* 4_k aligned base address */
+       u16 reserved;
+       u16 segment;
+       u64 base_address;               /* 4_k aligned base address */
        u64 end_address;        /* 4_k aligned limit address */
 };
 
index 99934a999e6651e904bc23310d7c36a17153f05f..26d79f6db8a044490c95c8752a40a9fa4c68eff5 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <linux/kernel.h>
 #include <linux/cpu.h>
+#include <linux/cpuidle.h>
 
 #include <asm/acpi.h>
 
@@ -75,7 +76,9 @@ struct acpi_processor_cx {
 };
 
 struct acpi_processor_power {
+       struct cpuidle_device dev;
        struct acpi_processor_cx *state;
+       struct acpi_processor_cx *bm_state;
        unsigned long bm_check_timestamp;
        u32 default_state;
        u32 bm_activity;
@@ -199,6 +202,7 @@ struct acpi_processor_flags {
        u8 bm_check:1;
        u8 has_cst:1;
        u8 power_setup_done:1;
+       u8 bm_rld_set:1;
 };
 
 struct acpi_processor {
@@ -322,6 +326,7 @@ int acpi_processor_power_exit(struct acpi_processor *pr,
                              struct acpi_device *device);
 int acpi_processor_suspend(struct acpi_device * device, pm_message_t state);
 int acpi_processor_resume(struct acpi_device * device);
+extern struct cpuidle_driver acpi_idle_driver;
 
 /* in processor_thermal.c */
 int acpi_processor_get_limit_info(struct acpi_processor *pr);
index 9e71201000d58eb8943650bc14c938aca1850513..9e19a704d4840693a31bd88413060024e3623266 100644 (file)
@@ -1,7 +1,12 @@
 #ifndef _ALPHA_BITOPS_H
 #define _ALPHA_BITOPS_H
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <asm/compiler.h>
+#include <asm/barrier.h>
 
 /*
  * Copyright 1994, Linus Torvalds.
@@ -69,6 +74,13 @@ clear_bit(unsigned long nr, volatile void * addr)
        :"Ir" (1UL << (nr & 31)), "m" (*m));
 }
 
+static inline void
+clear_bit_unlock(unsigned long nr, volatile void * addr)
+{
+       smp_mb();
+       clear_bit(nr, addr);
+}
+
 /*
  * WARNING: non atomic version.
  */
@@ -80,6 +92,13 @@ __clear_bit(unsigned long nr, volatile void * addr)
        *m &= ~(1 << (nr & 31));
 }
 
+static inline void
+__clear_bit_unlock(unsigned long nr, volatile void * addr)
+{
+       smp_mb();
+       __clear_bit(nr, addr);
+}
+
 static inline void
 change_bit(unsigned long nr, volatile void * addr)
 {
@@ -116,6 +135,36 @@ test_and_set_bit(unsigned long nr, volatile void *addr)
        unsigned long temp;
        int *m = ((int *) addr) + (nr >> 5);
 
+       __asm__ __volatile__(
+#ifdef CONFIG_SMP
+       "       mb\n"
+#endif
+       "1:     ldl_l %0,%4\n"
+       "       and %0,%3,%2\n"
+       "       bne %2,2f\n"
+       "       xor %0,%3,%0\n"
+       "       stl_c %0,%1\n"
+       "       beq %0,3f\n"
+       "2:\n"
+#ifdef CONFIG_SMP
+       "       mb\n"
+#endif
+       ".subsection 2\n"
+       "3:     br 1b\n"
+       ".previous"
+       :"=&r" (temp), "=m" (*m), "=&r" (oldbit)
+       :"Ir" (1UL << (nr & 31)), "m" (*m) : "memory");
+
+       return oldbit != 0;
+}
+
+static inline int
+test_and_set_bit_lock(unsigned long nr, volatile void *addr)
+{
+       unsigned long oldbit;
+       unsigned long temp;
+       int *m = ((int *) addr) + (nr >> 5);
+
        __asm__ __volatile__(
        "1:     ldl_l %0,%4\n"
        "       and %0,%3,%2\n"
@@ -158,6 +207,9 @@ test_and_clear_bit(unsigned long nr, volatile void * addr)
        int *m = ((int *) addr) + (nr >> 5);
 
        __asm__ __volatile__(
+#ifdef CONFIG_SMP
+       "       mb\n"
+#endif
        "1:     ldl_l %0,%4\n"
        "       and %0,%3,%2\n"
        "       beq %2,2f\n"
@@ -199,6 +251,9 @@ test_and_change_bit(unsigned long nr, volatile void * addr)
        int *m = ((int *) addr) + (nr >> 5);
 
        __asm__ __volatile__(
+#ifdef CONFIG_SMP
+       "       mb\n"
+#endif
        "1:     ldl_l %0,%4\n"
        "       and %0,%3,%2\n"
        "       xor %0,%3,%0\n"
index 2a5cc0b367ab4c36dfa79839248c662fa75f7aec..b7bf68d0407bed6367f5f7f848768681fd7d6357 100644 (file)
@@ -40,7 +40,6 @@ static inline unsigned long ide_default_io_base(int index)
        }
 }
 
-#define IDE_ARCH_OBSOLETE_INIT
 #define ide_default_io_ctl(base)       ((base) + 0x206) /* obsolete */
 
 #ifdef CONFIG_PCI
index 917365405e8388fbe2b10e37621bcb30c82aa8d1..440747ca6349058d31f04b6191ed2de0870ce557 100644 (file)
@@ -5,7 +5,10 @@
 #include <asm/types.h>
   
 struct scatterlist {
-       struct page *page;
+#ifdef CONFIG_DEBUG_SG
+       unsigned long sg_magic;
+#endif
+       unsigned long page_link;
        unsigned int offset;
 
        unsigned int length;
index 1ca3ed3bd6d38f1c2461e5d83980758affeac76e..eefab3fb51ae87f76050c34118fabe6d31c87078 100644 (file)
@@ -92,17 +92,6 @@ flush_tlb_other(struct mm_struct *mm)
        if (*mmc) *mmc = 0;
 }
 
-/* Flush a specified range of user mapping page tables from TLB.
-   Although Alpha uses VPTE caches, this can be a nop, as Alpha does
-   not have finegrained tlb flushing, so it will flush VPTE stuff
-   during next flush_tlb_range.  */
-
-static inline void
-flush_tlb_pgtables(struct mm_struct *mm, unsigned long start,
-                  unsigned long end)
-{
-}
-
 #ifndef CONFIG_SMP
 /* Flush everything (kernel mapping may also have changed
    due to vmalloc/vfree).  */
index 002227924b9fa09c48a80b909ecb7329d219cce2..a6d1ee0980f21d3372a552952f79c4aaef96c0da 100644 (file)
 #define TIMER3_CLEAR   __REG(0x80000e0c)       /* Timer 3 Clear Register */
 
 /* Timer Control register bits */
-#define TIMER_CTRL_ENABLE      (1 << 7) /* Enable (Start° Timer */
+#define TIMER_CTRL_ENABLE      (1 << 7) /* Enable (Start Timer) */
 #define TIMER_CTRL_PERIODIC    (1 << 6) /* Periodic Running Mode */
 #define TIMER_CTRL_FREE_RUNNING (0 << 6) /* Normal Running Mode */
 #define TIMER_CTRL_CLKSEL_508K (1 << 3) /* 508KHz Clock select (Timer 1, 2) */
-#define TIMER_CTRL_CLKSEL_2K   (0 << 3) /* 2KHz Clock Select (Timer 1, 2)*/
+#define TIMER_CTRL_CLKSEL_2K   (0 << 3) /* 2KHz Clock Select (Timer 1, 2) */
 
 /* Power and State Control */
 #define POWER_BASE     __REG(0x80000400)
index c72f9d79417cbc3208bdc0574bb6784685605523..eeeea90cd5a96f1b08a12acc6b1d00d68a588c4f 100644 (file)
@@ -17,9 +17,6 @@
 
 #define IO_SPACE_LIMIT 0xffff0000
 
-#define        BIT(x)  ((1)<<(x))
-
-
 extern int (*ixp4xx_pci_read)(u32 addr, u32 cmd, u32* data);
 extern int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data);
 
index 6903db7fae154b15b5490e4ba2d8154a7690d869..9d9f4b54b2ce6f20013c6e5f39f69980b308288f 100644 (file)
@@ -7,6 +7,8 @@
  *
  */
 
+#include <linux/suspend.h>
+
 struct pxa_cpu_pm_fns {
        int     save_size;
        void    (*save)(unsigned long *);
index b41831b6432fb44f7967720b31e892e58005ed82..47a6b086eee27fd3ef5dc9a9a04a09db8c5488ee 100644 (file)
 
 #ifdef __KERNEL__
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <linux/compiler.h>
 #include <asm/system.h>
 
@@ -286,6 +290,7 @@ static inline int constant_fls(int x)
 
 #include <asm-generic/bitops/sched.h>
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 
 /*
  * Ext2 is defined to use little-endian byte ordering.
index 678134bf24753cd09203ff01820686ad4f0cd564..e99406a7bece7264569542b85a72ea8c7d3aaa1e 100644 (file)
@@ -5,7 +5,7 @@
 
 #include <linux/mm.h> /* need struct page */
 
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 
 /*
  * DMA-consistent mapping functions.  These allocate/free a region of
@@ -274,8 +274,8 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
        for (i = 0; i < nents; i++, sg++) {
                char *virt;
 
-               sg->dma_address = page_to_dma(dev, sg->page) + sg->offset;
-               virt = page_address(sg->page) + sg->offset;
+               sg->dma_address = page_to_dma(dev, sg_page(sg)) + sg->offset;
+               virt = sg_virt(sg);
 
                if (!arch_is_coherent())
                        dma_cache_maint(virt, sg->length, dir);
@@ -371,7 +371,7 @@ dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents,
        int i;
 
        for (i = 0; i < nents; i++, sg++) {
-               char *virt = page_address(sg->page) + sg->offset;
+               char *virt = sg_virt(sg);
                if (!arch_is_coherent())
                        dma_cache_maint(virt, sg->length, dir);
        }
@@ -384,7 +384,7 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
        int i;
 
        for (i = 0; i < nents; i++, sg++) {
-               char *virt = page_address(sg->page) + sg->offset;
+               char *virt = sg_virt(sg);
                if (!arch_is_coherent())
                        dma_cache_maint(virt, sg->length, dir);
        }
@@ -401,7 +401,7 @@ extern void dma_sync_sg_for_device(struct device*, struct scatterlist*, int, enu
  *
  * On the SA-1111, a bug limits DMA to only certain regions of RAM.
  * On the IXP425, the PCI inbound window is 64MB (256MB total RAM)
- * On some ADI engineering sytems, PCI inbound window is 32MB (12MB total RAM)
+ * On some ADI engineering systems, PCI inbound window is 32MB (12MB total RAM)
  *
  * The following are helper functions used by the dmabounce subystem
  *
index 4f68c8a5a1998cd9f222c32831875e0f8a1ea97a..f348fcf3150b982bd82192d68a820419f675b78e 100644 (file)
@@ -18,7 +18,6 @@
 #endif
 
 #if !defined(CONFIG_ARCH_L7200)
-# define IDE_ARCH_OBSOLETE_INIT
 # ifdef CONFIG_ARCH_CLPS7500
 #  define ide_default_io_ctl(base)     ((base) + 0x206) /* obsolete */
 # else
index de2f65eb42ed7cad529e8369c3dce85e505f2127..ca0a37d0340093b06b1a7d28f09b1c9e89015f48 100644 (file)
@@ -5,7 +5,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-       struct page     *page;          /* buffer page                   */
+#ifdef CONFIG_DEBUG_SG
+       unsigned long   sg_magic;
+#endif
+       unsigned long   page_link;
        unsigned int    offset;         /* buffer offset                 */
        dma_addr_t      dma_address;    /* dma address                   */
        unsigned int    length;         /* length                        */
index 71be4fded7e20f1b069f2dbe7ad3c6a5d63456ca..8c6bc1bb9d1a5cb83c0abe7359841c1c48011bf0 100644 (file)
@@ -463,11 +463,6 @@ extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
  */
 extern void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte);
 
-/*
- * ARM processors do not cache TLB tables in RAM.
- */
-#define flush_tlb_pgtables(mm,start,end)       do { } while (0)
-
 #endif
 
 #endif /* CONFIG_MMU */
index 7dbd603c38cc3cf6e5a2244e547c90b45df46e7e..d6993a6b6473b8071c42ef9c5485f7f5dbb6d95d 100644 (file)
@@ -44,6 +44,13 @@ struct usba_platform_data {
 struct platform_device *
 at32_add_device_usba(unsigned int id, struct usba_platform_data *data);
 
+struct ide_platform_data {
+       u8      cs;
+};
+struct platform_device *
+at32_add_device_ide(unsigned int id, unsigned int extint,
+                   struct ide_platform_data *data);
+
 /* depending on what's hooked up, not all SSC pins will be used */
 #define        ATMEL_SSC_TK            0x01
 #define        ATMEL_SSC_TF            0x02
@@ -58,4 +65,20 @@ at32_add_device_usba(unsigned int id, struct usba_platform_data *data);
 struct platform_device *
 at32_add_device_ssc(unsigned int id, unsigned int flags);
 
+struct platform_device *at32_add_device_twi(unsigned int id);
+struct platform_device *at32_add_device_mci(unsigned int id);
+struct platform_device *at32_add_device_ac97c(unsigned int id);
+struct platform_device *at32_add_device_abdac(unsigned int id);
+
+struct cf_platform_data {
+       int     detect_pin;
+       int     reset_pin;
+       int     vcc_pin;
+       int     ready_pin;
+       u8      cs;
+};
+struct platform_device *
+at32_add_device_cf(unsigned int id, unsigned int extint,
+               struct cf_platform_data *data);
+
 #endif /* __ASM_ARCH_BOARD_H */
index 5299f8c8e11dc71d99c068d66a2848fb1c73b7f3..1a50b69b1a192de23bd6bdf88881a5181082faeb 100644 (file)
@@ -8,6 +8,10 @@
 #ifndef __ASM_AVR32_BITOPS_H
 #define __ASM_AVR32_BITOPS_H
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <asm/byteorder.h>
 #include <asm/system.h>
 
@@ -288,6 +292,7 @@ static inline int ffs(unsigned long word)
 #include <asm-generic/bitops/fls64.h>
 #include <asm-generic/bitops/sched.h>
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 
 #include <asm-generic/bitops/ext2-non-atomic.h>
 #include <asm-generic/bitops/ext2-atomic.h>
index 81e342636ac4cb3d93fc612b9018f5895f57e2c7..a7131630c057ae3c3b1b00c92ec712a26fa1eaf4 100644 (file)
@@ -217,8 +217,8 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
        for (i = 0; i < nents; i++) {
                char *virt;
 
-               sg[i].dma_address = page_to_bus(sg[i].page) + sg[i].offset;
-               virt = page_address(sg[i].page) + sg[i].offset;
+               sg[i].dma_address = page_to_bus(sg_page(&sg[i])) + sg[i].offset;
+               virt = sg_virt(&sg[i]);
                dma_cache_sync(dev, virt, sg[i].length, direction);
        }
 
@@ -327,8 +327,7 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
        int i;
 
        for (i = 0; i < nents; i++) {
-               dma_cache_sync(dev, page_address(sg[i].page) + sg[i].offset,
-                              sg[i].length, direction);
+               dma_cache_sync(dev, sg_virt(&sg[i]), sg[i].length, direction);
        }
 }
 
index c6d5ce3b3a25f558ecda0bc7a7b89661e49e10d2..377320e3bd1741b19d7c5acdc2ad2de78502ae6a 100644 (file)
@@ -4,7 +4,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page                *page;
+#ifdef CONFIG_DEBUG_SG
+   unsigned long       sg_magic;
+#endif
+    unsigned long      page_link;
     unsigned int       offset;
     dma_addr_t         dma_address;
     unsigned int       length;
index 730e268f81f383083573c424a3eaeddb966f1dd8..5bc7c88a5770a9c211d8aa6d32c2b04ed4186166 100644 (file)
@@ -19,7 +19,6 @@
  *  - flush_tlb_page(vma, vmaddr) flushes one page
  *  - flush_tlb_range(vma, start, end) flushes a range of pages
  *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
- *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
  */
 extern void flush_tlb(void);
 extern void flush_tlb_all(void);
@@ -29,12 +28,6 @@ extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
 extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page);
 extern void __flush_tlb_page(unsigned long asid, unsigned long page);
 
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-                                     unsigned long start, unsigned long end)
-{
-       /* Nothing to do */
-}
-
 extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
 
 #endif /* __ASM_AVR32_TLBFLUSH_H */
diff --git a/include/asm-blackfin/bf5xx_timers.h b/include/asm-blackfin/bf5xx_timers.h
deleted file mode 100644 (file)
index 86c7703..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * include/asm/bf5xx_timers.h
- *
- * This file contains the major Data structures and constants
- * used for General Purpose Timer Implementation in BF5xx
- *
- * Copyright (C) 2005 John DeHority
- * Copyright (C) 2006 Hella Aglaia GmbH (awe@aglaia-gmbh.de)
- *
- */
-
-#ifndef _BLACKFIN_TIMERS_H_
-#define _BLACKFIN_TIMERS_H_
-
-#undef MAX_BLACKFIN_GPTIMERS
-/*
- * BF537: 8 timers:
- */
-#if defined(CONFIG_BF537)
-#  define MAX_BLACKFIN_GPTIMERS 8
-#  define TIMER0_GROUP_REG     TIMER_ENABLE
-#endif
-/*
- * BF561: 12 timers:
- */
-#if defined(CONFIG_BF561)
-#  define MAX_BLACKFIN_GPTIMERS 12
-#  define TIMER0_GROUP_REG     TMRS8_ENABLE
-#  define TIMER8_GROUP_REG     TMRS4_ENABLE
-#endif
-/*
- * All others: 3 timers:
- */
-#if !defined(MAX_BLACKFIN_GPTIMERS)
-#  define MAX_BLACKFIN_GPTIMERS 3
-#  define TIMER0_GROUP_REG     TIMER_ENABLE
-#endif
-
-#define BLACKFIN_GPTIMER_IDMASK ((1UL << MAX_BLACKFIN_GPTIMERS) - 1)
-#define BFIN_TIMER_OCTET(x) ((x) >> 3)
-
-/* used in masks for timer_enable() and timer_disable() */
-#define TIMER0bit  0x0001  /*  0001b */
-#define TIMER1bit  0x0002  /*  0010b */
-#define TIMER2bit  0x0004  /*  0100b */
-
-#if (MAX_BLACKFIN_GPTIMERS > 3)
-#  define TIMER3bit  0x0008
-#  define TIMER4bit  0x0010
-#  define TIMER5bit  0x0020
-#  define TIMER6bit  0x0040
-#  define TIMER7bit  0x0080
-#endif
-
-#if (MAX_BLACKFIN_GPTIMERS > 8)
-#  define TIMER8bit  0x0100
-#  define TIMER9bit  0x0200
-#  define TIMER10bit 0x0400
-#  define TIMER11bit 0x0800
-#endif
-
-#define TIMER0_id   0
-#define TIMER1_id   1
-#define TIMER2_id   2
-
-#if (MAX_BLACKFIN_GPTIMERS > 3)
-#  define TIMER3_id   3
-#  define TIMER4_id   4
-#  define TIMER5_id   5
-#  define TIMER6_id   6
-#  define TIMER7_id   7
-#endif
-
-#if (MAX_BLACKFIN_GPTIMERS > 8)
-#  define TIMER8_id   8
-#  define TIMER9_id   9
-#  define TIMER10_id 10
-#  define TIMER11_id 11
-#endif
-
-/* associated timers for ppi framesync: */
-
-#if defined(CONFIG_BF561)
-#  define FS0_1_TIMER_ID   TIMER8_id
-#  define FS0_2_TIMER_ID   TIMER9_id
-#  define FS1_1_TIMER_ID   TIMER10_id
-#  define FS1_2_TIMER_ID   TIMER11_id
-#  define FS0_1_TIMER_BIT  TIMER8bit
-#  define FS0_2_TIMER_BIT  TIMER9bit
-#  define FS1_1_TIMER_BIT  TIMER10bit
-#  define FS1_2_TIMER_BIT  TIMER11bit
-#  undef FS1_TIMER_ID
-#  undef FS2_TIMER_ID
-#  undef FS1_TIMER_BIT
-#  undef FS2_TIMER_BIT
-#else
-#  define FS1_TIMER_ID  TIMER0_id
-#  define FS2_TIMER_ID  TIMER1_id
-#  define FS1_TIMER_BIT TIMER0bit
-#  define FS2_TIMER_BIT TIMER1bit
-#endif
-
-/*
-** Timer Configuration Register Bits
-*/
-#define TIMER_ERR           0xC000
-#define TIMER_ERR_OVFL      0x4000
-#define TIMER_ERR_PROG_PER  0x8000
-#define TIMER_ERR_PROG_PW   0xC000
-#define TIMER_EMU_RUN       0x0200
-#define        TIMER_TOGGLE_HI     0x0100
-#define        TIMER_CLK_SEL       0x0080
-#define TIMER_OUT_DIS       0x0040
-#define TIMER_TIN_SEL       0x0020
-#define TIMER_IRQ_ENA       0x0010
-#define TIMER_PERIOD_CNT    0x0008
-#define TIMER_PULSE_HI      0x0004
-#define TIMER_MODE          0x0003
-#define TIMER_MODE_PWM      0x0001
-#define TIMER_MODE_WDTH     0x0002
-#define TIMER_MODE_EXT_CLK  0x0003
-
-/*
-** Timer Status Register Bits
-*/
-#define TIMER_STATUS_TIMIL0 0x0001
-#define TIMER_STATUS_TIMIL1 0x0002
-#define TIMER_STATUS_TIMIL2 0x0004
-#if (MAX_BLACKFIN_GPTIMERS > 3)
-#  define TIMER_STATUS_TIMIL3 0x00000008
-#  define TIMER_STATUS_TIMIL4 0x00010000
-#  define TIMER_STATUS_TIMIL5 0x00020000
-#  define TIMER_STATUS_TIMIL6 0x00040000
-#  define TIMER_STATUS_TIMIL7 0x00080000
-#  if (MAX_BLACKFIN_GPTIMERS > 8)
-#    define TIMER_STATUS_TIMIL8  0x0001
-#    define TIMER_STATUS_TIMIL9  0x0002
-#    define TIMER_STATUS_TIMIL10 0x0004
-#    define TIMER_STATUS_TIMIL11 0x0008
-#  endif
-#  define TIMER_STATUS_INTR   0x000F000F
-#else
-#  define TIMER_STATUS_INTR   0x0007   /* any timer interrupt */
-#endif
-
-#define TIMER_STATUS_TOVF0  0x0010     /* timer 0 overflow error */
-#define TIMER_STATUS_TOVF1  0x0020
-#define TIMER_STATUS_TOVF2  0x0040
-#if (MAX_BLACKFIN_GPTIMERS > 3)
-#  define TIMER_STATUS_TOVF3  0x00000080
-#  define TIMER_STATUS_TOVF4  0x00100000
-#  define TIMER_STATUS_TOVF5  0x00200000
-#  define TIMER_STATUS_TOVF6  0x00400000
-#  define TIMER_STATUS_TOVF7  0x00800000
-#  if (MAX_BLACKFIN_GPTIMERS > 8)
-#    define TIMER_STATUS_TOVF8   0x0010
-#    define TIMER_STATUS_TOVF9   0x0020
-#    define TIMER_STATUS_TOVF10  0x0040
-#    define TIMER_STATUS_TOVF11  0x0080
-#  endif
-#  define TIMER_STATUS_OFLOW  0x00F000F0
-#else
-#  define TIMER_STATUS_OFLOW  0x0070   /* any timer overflow */
-#endif
-
-/*
-** Timer Slave Enable Status : write 1 to clear
-*/
-#define TIMER_STATUS_TRUN0  0x1000
-#define TIMER_STATUS_TRUN1  0x2000
-#define TIMER_STATUS_TRUN2  0x4000
-#if (MAX_BLACKFIN_GPTIMERS > 3)
-#  define TIMER_STATUS_TRUN3  0x00008000
-#  define TIMER_STATUS_TRUN4  0x10000000
-#  define TIMER_STATUS_TRUN5  0x20000000
-#  define TIMER_STATUS_TRUN6  0x40000000
-#  define TIMER_STATUS_TRUN7  0x80000000
-#  define TIMER_STATUS_TRUN   0xF000F000
-#  if (MAX_BLACKFIN_GPTIMERS > 8)
-#    define TIMER_STATUS_TRUN8  0x1000
-#    define TIMER_STATUS_TRUN9  0x2000
-#    define TIMER_STATUS_TRUN10 0x4000
-#    define TIMER_STATUS_TRUN11 0x8000
-#  endif
-#else
-#  define TIMER_STATUS_TRUN   0x7000
-#endif
-
-/*******************************************************************************
-*      GP_TIMER API's
-*******************************************************************************/
-
-void  set_gptimer_pwidth    (int timer_id, int width);
-int   get_gptimer_pwidth    (int timer_id);
-void  set_gptimer_period    (int timer_id, int period);
-int   get_gptimer_period    (int timer_id);
-int   get_gptimer_count     (int timer_id);
-short get_gptimer_intr      (int timer_id);
-void  set_gptimer_config    (int timer_id, short config);
-short get_gptimer_config    (int timer_id);
-void  set_gptimer_pulse_hi  (int timer_id);
-void  clear_gptimer_pulse_hi(int timer_id);
-void  enable_gptimers       (short mask);
-void  disable_gptimers      (short mask);
-short get_enabled_timers    (void);
-int   get_gptimer_status    (int octet);
-void  set_gptimer_status    (int octet, int value);
-
-#endif
index a970781a0f98a25cad63f9202164f0674d572022..14cb8d35924e7c3505126057d3f9648d927435fe 100644 (file)
@@ -47,6 +47,8 @@
 
 extern unsigned long get_cclk(void);
 extern unsigned long get_sclk(void);
+extern unsigned long sclk_to_usecs(unsigned long sclk);
+extern unsigned long usecs_to_sclk(unsigned long usecs);
 
 extern void dump_thread(struct pt_regs *regs, struct user *dump);
 extern void dump_bfin_regs(struct pt_regs *fp, void *retaddr);
@@ -105,7 +107,7 @@ extern void led_disp_num(int);
 extern void led_toggle_num(int);
 extern void init_leds(void);
 
-extern char *bfin_board_name __attribute__ ((weak));
+extern const char bfin_board_name[];
 extern unsigned long wall_jiffies;
 extern unsigned long ipdt_table[];
 extern unsigned long dpdt_table[];
index 27c2d0e48e1b6b314e88f18b274dd15c41541017..b39a175c79c1bcaba34f4decfefc337166992698 100644 (file)
 
 #ifdef __KERNEL__
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <asm-generic/bitops/ffs.h>
 #include <asm-generic/bitops/__ffs.h>
 #include <asm-generic/bitops/sched.h>
@@ -199,6 +203,7 @@ static __inline__ int __test_bit(int nr, const void *addr)
 
 #include <asm-generic/bitops/find.h>
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 
 #include <asm-generic/bitops/ext2-atomic.h>
 #include <asm-generic/bitops/ext2-non-atomic.h>
index b42a531e7a1b9d90497652897e6ca7d4cd104f3f..b469505af3642ef24c55a48bad402dd127a81c6c 100644 (file)
@@ -109,9 +109,7 @@ struct dma_register {
 
        unsigned long curr_desc_ptr;    /* DMA Current Descriptor Pointer
                                           register */
-       unsigned short curr_addr_ptr_lo;        /* DMA Current Address Pointer
-                                                  register */
-       unsigned short curr_addr_ptr_hi;        /* DMA Current Address Pointer
+       unsigned long curr_addr_ptr;    /* DMA Current Address Pointer
                                                   register */
        unsigned short irq_status;      /* DMA irq status register */
        unsigned short dummy6;
@@ -166,6 +164,9 @@ void set_dma_curr_addr(unsigned int channel, unsigned long addr);
 unsigned short get_dma_curr_irqstat(unsigned int channel);
 unsigned short get_dma_curr_xcount(unsigned int channel);
 unsigned short get_dma_curr_ycount(unsigned int channel);
+unsigned long get_dma_next_desc_ptr(unsigned int channel);
+unsigned long get_dma_curr_desc_ptr(unsigned int channel);
+unsigned long get_dma_curr_addr(unsigned int channel);
 
 /* set large DMA mode descriptor */
 void set_dma_sg(unsigned int channel, struct dmasg *sg, int nr_sg);
index dd203cd93796fa1f88c5e5eceb63ed18330e3e92..33ce98ef7e0f6cc8c7cea119e3b59baa8581603c 100644 (file)
@@ -29,6 +29,7 @@
 
 /*
 *  Number     BF537/6/4    BF561    BF533/2/1
+*             BF527/5/2
 *
 *  GPIO_0       PF0         PF0        PF0
 *  GPIO_1       PF1         PF1        PF1
 
 #endif
 
-#ifdef BF537_FAMILY
+#if defined(BF527_FAMILY) || defined(BF537_FAMILY)
 #define MAX_BLACKFIN_GPIOS 48
 
 #define        GPIO_PF0        0
diff --git a/include/asm-blackfin/gptimers.h b/include/asm-blackfin/gptimers.h
new file mode 100644 (file)
index 0000000..c97ab03
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * include/asm/bf5xx_timers.h
+ *
+ * This file contains the major Data structures and constants
+ * used for General Purpose Timer Implementation in BF5xx
+ *
+ * Copyright (C) 2005 John DeHority
+ * Copyright (C) 2006 Hella Aglaia GmbH (awe@aglaia-gmbh.de)
+ *
+ */
+
+#ifndef _BLACKFIN_TIMERS_H_
+#define _BLACKFIN_TIMERS_H_
+
+#include <linux/types.h>
+#include <asm/blackfin.h>
+
+/*
+ * BF537/BF527: 8 timers:
+ */
+#if defined(BF527_FAMILY) || defined(BF537_FAMILY)
+# define MAX_BLACKFIN_GPTIMERS 8
+# define TIMER0_GROUP_REG      TIMER_ENABLE
+#endif
+/*
+ * BF561: 12 timers:
+ */
+#if defined(CONFIG_BF561)
+# define MAX_BLACKFIN_GPTIMERS 12
+# define TIMER0_GROUP_REG      TMRS8_ENABLE
+# define TIMER8_GROUP_REG      TMRS4_ENABLE
+#endif
+/*
+ * All others: 3 timers:
+ */
+#if !defined(MAX_BLACKFIN_GPTIMERS)
+# define MAX_BLACKFIN_GPTIMERS 3
+# define TIMER0_GROUP_REG      TIMER_ENABLE
+#endif
+
+#define BLACKFIN_GPTIMER_IDMASK ((1UL << MAX_BLACKFIN_GPTIMERS) - 1)
+#define BFIN_TIMER_OCTET(x) ((x) >> 3)
+
+/* used in masks for timer_enable() and timer_disable() */
+#define TIMER0bit  0x0001  /*  0001b */
+#define TIMER1bit  0x0002  /*  0010b */
+#define TIMER2bit  0x0004  /*  0100b */
+
+#if (MAX_BLACKFIN_GPTIMERS > 3)
+# define TIMER3bit  0x0008
+# define TIMER4bit  0x0010
+# define TIMER5bit  0x0020
+# define TIMER6bit  0x0040
+# define TIMER7bit  0x0080
+#endif
+
+#if (MAX_BLACKFIN_GPTIMERS > 8)
+# define TIMER8bit  0x0100
+# define TIMER9bit  0x0200
+# define TIMER10bit 0x0400
+# define TIMER11bit 0x0800
+#endif
+
+#define TIMER0_id   0
+#define TIMER1_id   1
+#define TIMER2_id   2
+
+#if (MAX_BLACKFIN_GPTIMERS > 3)
+# define TIMER3_id   3
+# define TIMER4_id   4
+# define TIMER5_id   5
+# define TIMER6_id   6
+# define TIMER7_id   7
+#endif
+
+#if (MAX_BLACKFIN_GPTIMERS > 8)
+# define TIMER8_id   8
+# define TIMER9_id   9
+# define TIMER10_id 10
+# define TIMER11_id 11
+#endif
+
+/* associated timers for ppi framesync: */
+
+#if defined(CONFIG_BF561)
+# define FS0_1_TIMER_ID   TIMER8_id
+# define FS0_2_TIMER_ID   TIMER9_id
+# define FS1_1_TIMER_ID   TIMER10_id
+# define FS1_2_TIMER_ID   TIMER11_id
+# define FS0_1_TIMER_BIT  TIMER8bit
+# define FS0_2_TIMER_BIT  TIMER9bit
+# define FS1_1_TIMER_BIT  TIMER10bit
+# define FS1_2_TIMER_BIT  TIMER11bit
+# undef FS1_TIMER_ID
+# undef FS2_TIMER_ID
+# undef FS1_TIMER_BIT
+# undef FS2_TIMER_BIT
+#else
+# define FS1_TIMER_ID  TIMER0_id
+# define FS2_TIMER_ID  TIMER1_id
+# define FS1_TIMER_BIT TIMER0bit
+# define FS2_TIMER_BIT TIMER1bit
+#endif
+
+/*
+ * Timer Configuration Register Bits
+ */
+#define TIMER_ERR           0xC000
+#define TIMER_ERR_OVFL      0x4000
+#define TIMER_ERR_PROG_PER  0x8000
+#define TIMER_ERR_PROG_PW   0xC000
+#define TIMER_EMU_RUN       0x0200
+#define        TIMER_TOGGLE_HI     0x0100
+#define        TIMER_CLK_SEL       0x0080
+#define TIMER_OUT_DIS       0x0040
+#define TIMER_TIN_SEL       0x0020
+#define TIMER_IRQ_ENA       0x0010
+#define TIMER_PERIOD_CNT    0x0008
+#define TIMER_PULSE_HI      0x0004
+#define TIMER_MODE          0x0003
+#define TIMER_MODE_PWM      0x0001
+#define TIMER_MODE_WDTH     0x0002
+#define TIMER_MODE_EXT_CLK  0x0003
+
+/*
+ * Timer Status Register Bits
+ */
+#define TIMER_STATUS_TIMIL0 0x0001
+#define TIMER_STATUS_TIMIL1 0x0002
+#define TIMER_STATUS_TIMIL2 0x0004
+#if (MAX_BLACKFIN_GPTIMERS > 3)
+# define TIMER_STATUS_TIMIL3 0x00000008
+# define TIMER_STATUS_TIMIL4 0x00010000
+# define TIMER_STATUS_TIMIL5 0x00020000
+# define TIMER_STATUS_TIMIL6 0x00040000
+# define TIMER_STATUS_TIMIL7 0x00080000
+# if (MAX_BLACKFIN_GPTIMERS > 8)
+#  define TIMER_STATUS_TIMIL8  0x0001
+#  define TIMER_STATUS_TIMIL9  0x0002
+#  define TIMER_STATUS_TIMIL10 0x0004
+#  define TIMER_STATUS_TIMIL11 0x0008
+# endif
+# define TIMER_STATUS_INTR   0x000F000F
+#else
+# define TIMER_STATUS_INTR   0x0007    /* any timer interrupt */
+#endif
+
+#define TIMER_STATUS_TOVF0  0x0010     /* timer 0 overflow error */
+#define TIMER_STATUS_TOVF1  0x0020
+#define TIMER_STATUS_TOVF2  0x0040
+#if (MAX_BLACKFIN_GPTIMERS > 3)
+# define TIMER_STATUS_TOVF3  0x00000080
+# define TIMER_STATUS_TOVF4  0x00100000
+# define TIMER_STATUS_TOVF5  0x00200000
+# define TIMER_STATUS_TOVF6  0x00400000
+# define TIMER_STATUS_TOVF7  0x00800000
+# if (MAX_BLACKFIN_GPTIMERS > 8)
+#  define TIMER_STATUS_TOVF8   0x0010
+#  define TIMER_STATUS_TOVF9   0x0020
+#  define TIMER_STATUS_TOVF10  0x0040
+#  define TIMER_STATUS_TOVF11  0x0080
+# endif
+# define TIMER_STATUS_OFLOW  0x00F000F0
+#else
+# define TIMER_STATUS_OFLOW  0x0070    /* any timer overflow */
+#endif
+
+/*
+ * Timer Slave Enable Status : write 1 to clear
+ */
+#define TIMER_STATUS_TRUN0  0x1000
+#define TIMER_STATUS_TRUN1  0x2000
+#define TIMER_STATUS_TRUN2  0x4000
+#if (MAX_BLACKFIN_GPTIMERS > 3)
+# define TIMER_STATUS_TRUN3  0x00008000
+# define TIMER_STATUS_TRUN4  0x10000000
+# define TIMER_STATUS_TRUN5  0x20000000
+# define TIMER_STATUS_TRUN6  0x40000000
+# define TIMER_STATUS_TRUN7  0x80000000
+# define TIMER_STATUS_TRUN   0xF000F000
+# if (MAX_BLACKFIN_GPTIMERS > 8)
+#  define TIMER_STATUS_TRUN8  0x1000
+#  define TIMER_STATUS_TRUN9  0x2000
+#  define TIMER_STATUS_TRUN10 0x4000
+#  define TIMER_STATUS_TRUN11 0x8000
+# endif
+#else
+# define TIMER_STATUS_TRUN   0x7000
+#endif
+
+/* The actual gptimer API */
+
+void     set_gptimer_pwidth    (int timer_id, uint32_t width);
+uint32_t get_gptimer_pwidth    (int timer_id);
+void     set_gptimer_period    (int timer_id, uint32_t period);
+uint32_t get_gptimer_period    (int timer_id);
+uint32_t get_gptimer_count     (int timer_id);
+uint16_t get_gptimer_intr      (int timer_id);
+void     clear_gptimer_intr    (int timer_id);
+void     set_gptimer_config    (int timer_id, uint16_t config);
+uint16_t get_gptimer_config    (int timer_id);
+void     set_gptimer_pulse_hi  (int timer_id);
+void     clear_gptimer_pulse_hi(int timer_id);
+void     enable_gptimers       (uint16_t mask);
+void     disable_gptimers      (uint16_t mask);
+uint16_t get_enabled_gptimers  (void);
+uint32_t get_gptimer_status    (int group);
+void     set_gptimer_status    (int group, uint32_t value);
+
+#endif
index 41b2db46a1681d69b3a619e4b1259ab835f71886..121e272581d68a53225b0941b63bca62cee57036 100644 (file)
@@ -20,7 +20,6 @@
 #define MAX_HWIFS      1
 
 /* Legacy ... BLK_DEV_IDECS */
-#define IDE_ARCH_OBSOLETE_INIT
 #define ide_default_io_ctl(base)       ((base) + 0x206) /* obsolete */
 
 
index 991db986cd4bec896737bd17561d4e34ec4e96ec..a89120445be66e790403153add1e569ed456daa2 100644 (file)
 
 /* Anomalies that don't exist on this proc */
 #define ANOMALY_05000323 (0)
+#define ANOMALY_05000244 (0)
+#define ANOMALY_05000198 (0)
+#define ANOMALY_05000125 (0)
+#define ANOMALY_05000158 (0)
+#define ANOMALY_05000273 (0)
+#define ANOMALY_05000263 (0)
+#define ANOMALY_05000311 (0)
+#define ANOMALY_05000230 (0)
 #endif
diff --git a/include/asm-blackfin/mach-bf527/bf527.h b/include/asm-blackfin/mach-bf527/bf527.h
new file mode 100644 (file)
index 0000000..056eb4b
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * File:         include/asm-blackfin/mach-bf527/bf527.h
+ * Based on:   include/asm-blackfin/mach-bf537/bf537.h
+ * Author:     Michael Hennerich (michael.hennerich@analog.com)
+ *
+ * Created:
+ * Description:  SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF527
+ *
+ * Modified:
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __MACH_BF527_H__
+#define __MACH_BF527_H__
+
+#define SUPPORTED_REVID 2
+
+#define OFFSET_(x) ((x) & 0x0000FFFF)
+
+/*some misc defines*/
+#define IMASK_IVG15            0x8000
+#define IMASK_IVG14            0x4000
+#define IMASK_IVG13            0x2000
+#define IMASK_IVG12            0x1000
+
+#define IMASK_IVG11            0x0800
+#define IMASK_IVG10            0x0400
+#define IMASK_IVG9             0x0200
+#define IMASK_IVG8             0x0100
+
+#define IMASK_IVG7             0x0080
+#define IMASK_IVGTMR   0x0040
+#define IMASK_IVGHW            0x0020
+
+/***************************/
+
+#define BFIN_DSUBBANKS 4
+#define BFIN_DWAYS             2
+#define BFIN_DLINES            64
+#define BFIN_ISUBBANKS 4
+#define BFIN_IWAYS             4
+#define BFIN_ILINES            32
+
+#define WAY0_L                 0x1
+#define WAY1_L                 0x2
+#define WAY01_L                        0x3
+#define WAY2_L                 0x4
+#define WAY02_L                        0x5
+#define        WAY12_L                 0x6
+#define        WAY012_L                0x7
+
+#define        WAY3_L                  0x8
+#define        WAY03_L                 0x9
+#define        WAY13_L                 0xA
+#define        WAY013_L                0xB
+
+#define        WAY32_L                 0xC
+#define        WAY320_L                0xD
+#define        WAY321_L                0xE
+#define        WAYALL_L                0xF
+
+#define DMC_ENABLE (2<<2)      /*yes, 2, not 1 */
+
+/********************************* EBIU Settings ************************************/
+#define AMBCTL0VAL     ((CONFIG_BANK_1 << 16) | CONFIG_BANK_0)
+#define AMBCTL1VAL     ((CONFIG_BANK_3 << 16) | CONFIG_BANK_2)
+
+#ifdef CONFIG_C_AMBEN_ALL
+#define V_AMBEN AMBEN_ALL
+#endif
+#ifdef CONFIG_C_AMBEN
+#define V_AMBEN 0x0
+#endif
+#ifdef CONFIG_C_AMBEN_B0
+#define V_AMBEN AMBEN_B0
+#endif
+#ifdef CONFIG_C_AMBEN_B0_B1
+#define V_AMBEN AMBEN_B0_B1
+#endif
+#ifdef CONFIG_C_AMBEN_B0_B1_B2
+#define V_AMBEN AMBEN_B0_B1_B2
+#endif
+#ifdef CONFIG_C_AMCKEN
+#define V_AMCKEN AMCKEN
+#else
+#define V_AMCKEN 0x0
+#endif
+#ifdef CONFIG_C_CDPRIO
+#define V_CDPRIO 0x100
+#else
+#define V_CDPRIO 0x0
+#endif
+
+#define AMGCTLVAL      (V_AMBEN | V_AMCKEN | V_CDPRIO)
+
+#ifdef CONFIG_BF527
+#define CPU "BF527"
+#endif
+#ifdef CONFIG_BF525
+#define CPU "BF525"
+#endif
+#ifdef CONFIG_BF522
+#define CPU "BF522"
+#endif
+#ifndef CPU
+#define        CPU "UNKNOWN"
+#define CPUID 0x0
+#endif
+
+#endif                         /* __MACH_BF527_H__  */
diff --git a/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h
new file mode 100644 (file)
index 0000000..0b867e6
--- /dev/null
@@ -0,0 +1,152 @@
+#include <linux/serial.h>
+#include <asm/dma.h>
+#include <asm/portmux.h>
+
+#define NR_PORTS               2
+
+#define OFFSET_THR              0x00   /* Transmit Holding register            */
+#define OFFSET_RBR              0x00   /* Receive Buffer register              */
+#define OFFSET_DLL              0x00   /* Divisor Latch (Low-Byte)             */
+#define OFFSET_IER              0x04   /* Interrupt Enable Register            */
+#define OFFSET_DLH              0x04   /* Divisor Latch (High-Byte)            */
+#define OFFSET_IIR              0x08   /* Interrupt Identification Register    */
+#define OFFSET_LCR              0x0C   /* Line Control Register                */
+#define OFFSET_MCR              0x10   /* Modem Control Register               */
+#define OFFSET_LSR              0x14   /* Line Status Register                 */
+#define OFFSET_MSR              0x18   /* Modem Status Register                */
+#define OFFSET_SCR              0x1C   /* SCR Scratch Register                 */
+#define OFFSET_GCTL             0x24   /* Global Control Register              */
+
+#define UART_GET_CHAR(uart)     bfin_read16(((uart)->port.membase + OFFSET_RBR))
+#define UART_GET_DLL(uart)     bfin_read16(((uart)->port.membase + OFFSET_DLL))
+#define UART_GET_IER(uart)      bfin_read16(((uart)->port.membase + OFFSET_IER))
+#define UART_GET_DLH(uart)     bfin_read16(((uart)->port.membase + OFFSET_DLH))
+#define UART_GET_IIR(uart)      bfin_read16(((uart)->port.membase + OFFSET_IIR))
+#define UART_GET_LCR(uart)      bfin_read16(((uart)->port.membase + OFFSET_LCR))
+#define UART_GET_LSR(uart)      bfin_read16(((uart)->port.membase + OFFSET_LSR))
+#define UART_GET_GCTL(uart)     bfin_read16(((uart)->port.membase + OFFSET_GCTL))
+
+#define UART_PUT_CHAR(uart, v)   bfin_write16(((uart)->port.membase + OFFSET_THR), v)
+#define UART_PUT_DLL(uart, v)    bfin_write16(((uart)->port.membase + OFFSET_DLL), v)
+#define UART_PUT_IER(uart, v)    bfin_write16(((uart)->port.membase + OFFSET_IER), v)
+#define UART_PUT_DLH(uart, v)    bfin_write16(((uart)->port.membase + OFFSET_DLH), v)
+#define UART_PUT_LCR(uart, v)    bfin_write16(((uart)->port.membase + OFFSET_LCR), v)
+#define UART_PUT_GCTL(uart, v)   bfin_write16(((uart)->port.membase + OFFSET_GCTL), v)
+
+#if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS)
+# define CONFIG_SERIAL_BFIN_CTSRTS
+
+# ifndef CONFIG_UART0_CTS_PIN
+#  define CONFIG_UART0_CTS_PIN -1
+# endif
+
+# ifndef CONFIG_UART0_RTS_PIN
+#  define CONFIG_UART0_RTS_PIN -1
+# endif
+
+# ifndef CONFIG_UART1_CTS_PIN
+#  define CONFIG_UART1_CTS_PIN -1
+# endif
+
+# ifndef CONFIG_UART1_RTS_PIN
+#  define CONFIG_UART1_RTS_PIN -1
+# endif
+#endif
+/*
+ * The pin configuration is different from schematic
+ */
+struct bfin_serial_port {
+       struct uart_port port;
+       unsigned int old_status;
+#ifdef CONFIG_SERIAL_BFIN_DMA
+       int tx_done;
+       int tx_count;
+       struct circ_buf rx_dma_buf;
+       struct timer_list rx_dma_timer;
+       int rx_dma_nrows;
+       unsigned int tx_dma_channel;
+       unsigned int rx_dma_channel;
+       struct work_struct tx_dma_workqueue;
+#else
+       struct work_struct cts_workqueue;
+#endif
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+       int cts_pin;
+       int rts_pin;
+#endif
+};
+
+struct bfin_serial_port bfin_serial_ports[NR_PORTS];
+struct bfin_serial_res {
+       unsigned long uart_base_addr;
+       int uart_irq;
+#ifdef CONFIG_SERIAL_BFIN_DMA
+       unsigned int uart_tx_dma_channel;
+       unsigned int uart_rx_dma_channel;
+#endif
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+       int uart_cts_pin;
+       int uart_rts_pin;
+#endif
+};
+
+struct bfin_serial_res bfin_serial_resource[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       {
+        0xFFC00400,
+        IRQ_UART0_RX,
+#ifdef CONFIG_SERIAL_BFIN_DMA
+        CH_UART0_TX,
+        CH_UART0_RX,
+#endif
+#ifdef CONFIG_BFIN_UART0_CTSRTS
+        CONFIG_UART0_CTS_PIN,
+        CONFIG_UART0_RTS_PIN,
+#endif
+        },
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       {
+        0xFFC02000,
+        IRQ_UART1_RX,
+#ifdef CONFIG_SERIAL_BFIN_DMA
+        CH_UART1_TX,
+        CH_UART1_RX,
+#endif
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+        CONFIG_UART1_CTS_PIN,
+        CONFIG_UART1_RTS_PIN,
+#endif
+        },
+#endif
+};
+
+int nr_ports = ARRAY_SIZE(bfin_serial_resource);
+
+#define DRIVER_NAME "bfin-uart"
+
+static void bfin_serial_hw_init(struct bfin_serial_port *uart)
+{
+
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       peripheral_request(P_UART0_TX, DRIVER_NAME);
+       peripheral_request(P_UART0_RX, DRIVER_NAME);
+#endif
+
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       peripheral_request(P_UART1_TX, DRIVER_NAME);
+       peripheral_request(P_UART1_RX, DRIVER_NAME);
+#endif
+
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+       if (uart->cts_pin >= 0) {
+               gpio_request(uart->cts_pin, DRIVER_NAME);
+               gpio_direction_input(uart->cts_pin);
+       }
+
+       if (uart->rts_pin >= 0) {
+               gpio_request(uart->rts_pin, DRIVER_NAME);
+               gpio_direction_output(uart->rts_pin);
+       }
+#endif
+}
diff --git a/include/asm-blackfin/mach-bf527/blackfin.h b/include/asm-blackfin/mach-bf527/blackfin.h
new file mode 100644 (file)
index 0000000..1bd07e3
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * File:         include/asm-blackfin/mach-bf527/blackfin.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:
+ *
+ * Modified:
+ *
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _MACH_BLACKFIN_H_
+#define _MACH_BLACKFIN_H_
+
+#define BF527_FAMILY
+
+#include "bf527.h"
+#include "mem_map.h"
+#include "defBF522.h"
+#include "anomaly.h"
+
+#if defined(CONFIG_BF527)
+#include "defBF527.h"
+#endif
+
+#if defined(CONFIG_BF525)
+#include "defBF525.h"
+#endif
+
+#if !defined(__ASSEMBLY__)
+#include "cdefBF522.h"
+
+#if defined(CONFIG_BF527)
+#include "cdefBF527.h"
+#endif
+
+#if defined(CONFIG_BF525)
+#include "cdefBF525.h"
+#endif
+#endif
+
+/* UART_IIR Register */
+#define STATUS(x)      ((x << 1) & 0x06)
+#define STATUS_P1      0x02
+#define STATUS_P0      0x01
+
+/* DPMC*/
+#define bfin_read_STOPCK_OFF() bfin_read_STOPCK()
+#define bfin_write_STOPCK_OFF(val) bfin_write_STOPCK(val)
+#define STOPCK_OFF STOPCK
+
+/* PLL_DIV Masks                                                                                                       */
+#define CCLK_DIV1 CSEL_DIV1    /*          CCLK = VCO / 1                                  */
+#define CCLK_DIV2 CSEL_DIV2    /*          CCLK = VCO / 2                                  */
+#define CCLK_DIV4 CSEL_DIV4    /*          CCLK = VCO / 4                                  */
+#define CCLK_DIV8 CSEL_DIV8    /*          CCLK = VCO / 8                                  */
+
+#endif
index 5f801a0ef7979d7e786d3a0e39ae6f8a0edcfbe1..3f4de5d9d4cb06d705462edf06b7acc35d962cfe 100644 (file)
@@ -45,8 +45,8 @@
 #define bfin_write_PLL_STAT(val)               bfin_write16(PLL_STAT, val)
 #define bfin_read_PLL_LOCKCNT()                        bfin_read16(PLL_LOCKCNT)
 #define bfin_write_PLL_LOCKCNT(val)            bfin_write16(PLL_LOCKCNT, val)
-#define bfin_read_CHIPID()                     bfin_read16(CHIPID)
-#define bfin_write_CHIPID(val)                 bfin_write16(CHIPID, val)
+#define bfin_read_CHIPID()                     bfin_read32(CHIPID)
+#define bfin_write_CHIPID(val)                 bfin_write32(CHIPID, val)
 
 
 /* System Interrupt Controller (0xFFC00100 - 0xFFC001FF)                                                       */
@@ -59,9 +59,8 @@
 #define bfin_write_SIC_RVECT(val)              bfin_write32(SIC_RVECT, val)
 #define bfin_read_SIC_IMASK0()                 bfin_read32(SIC_IMASK0)
 #define bfin_write_SIC_IMASK0(val)             bfin_write32(SIC_IMASK0, val)
-/* legacy register name (below) provided for backwards code compatibility */
-#define bfin_read_SIC_IMASK()                  bfin_read32(SIC_IMASK)
-#define bfin_write_SIC_IMASK(val)              bfin_write32(SIC_IMASK, val)
+#define bfin_read_SIC_IMASK(x)                 bfin_read32(SIC_IMASK0 + (x << 6))
+#define bfin_write_SIC_IMASK(x, val)           bfin_write32((SIC_IMASK0 + (x << 6)), val)
 
 #define bfin_read_SIC_IAR0()                   bfin_read32(SIC_IAR0)
 #define bfin_write_SIC_IAR0(val)               bfin_write32(SIC_IAR0, val)
 
 #define bfin_read_SIC_ISR0()                   bfin_read32(SIC_ISR0)
 #define bfin_write_SIC_ISR0(val)               bfin_write32(SIC_ISR0, val)
-/* legacy register name (below) provided for backwards code compatibility */
-#define bfin_read_SIC_ISR()                    bfin_read32(SIC_ISR)
-#define bfin_write_SIC_ISR(val)                        bfin_write32(SIC_ISR, val)
+#define bfin_read_SIC_ISR(x)                   bfin_read32(SIC_ISR0 + (x << 6))
+#define bfin_write_SIC_ISR(x, val)             bfin_write32((SIC_ISR0 + (x << 6)), val)
 
 #define bfin_read_SIC_IWR0()                   bfin_read32(SIC_IWR0)
 #define bfin_write_SIC_IWR0(val)               bfin_write32(SIC_IWR0, val)
-/* legacy register name (below) provided for backwards code compatibility */
-#define bfin_read_SIC_IWR()                    bfin_read32(SIC_IWR)
-#define bfin_write_SIC_IWR(val)                        bfin_write32(SIC_IWR, val)
+#define bfin_read_SIC_IWR(x)                   bfin_read32(SIC_IWR0 + (x << 6))
+#define bfin_write_SIC_IWR(x, val)             bfin_write32((SIC_IWR0 + (x << 6)), val)
 
 /* SIC Additions to ADSP-BF52x (0xFFC0014C - 0xFFC00162) */
 
index 2be3293f9e26eea2d3d97b453cfa724f81f984c8..82134f578f326a0be244f4659782dda429e7a68f 100644 (file)
 #define _DEF_BF527_H
 
 /* Include all Core registers and bit definitions */
-#include <def_LPBlackfin.h>
+#include <asm/mach-common/def_LPBlackfin.h>
 
 /* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF527 */
 
 /* Include defBF52x_base.h for the set of #defines that are common to all ADSP-BF52x processors */
-#include <defBF52x_base.h>
+#include "defBF52x_base.h"
 
 /* The following are the #defines needed by ADSP-BF527 that are not in the common header */
 /* 10/100 Ethernet Controller  (0xFFC03000 - 0xFFC031FF) */
index b1ff67db01f8e78f23283613fb2457000908e6fd..d6c24c54699d40a158ce6f35392f92964a7ee23e 100644 (file)
 #define SYSCR                          0xFFC00104      /* System Configuration Register                        */
 #define SIC_RVECT                      0xFFC00108      /* Interrupt Reset Vector Address Register      */
 
-#define SIC_IMASK                      0xFFC0010C      /* Interrupt Mask Register                                      */
+#define SIC_IMASK0                     0xFFC0010C      /* Interrupt Mask Register                                      */
 #define SIC_IAR0                       0xFFC00110      /* Interrupt Assignment Register 0                      */
 #define SIC_IAR1                       0xFFC00114      /* Interrupt Assignment Register 1                      */
 #define SIC_IAR2                       0xFFC00118      /* Interrupt Assignment Register 2                      */
 #define SIC_IAR3                       0xFFC0011C      /* Interrupt Assignment Register 3                      */
-#define SIC_ISR                                0xFFC00120      /* Interrupt Status Register                            */
-#define SIC_IWR                                0xFFC00124      /* Interrupt Wakeup Register                            */
+#define SIC_ISR0                               0xFFC00120      /* Interrupt Status Register                            */
+#define SIC_IWR0                               0xFFC00124      /* Interrupt Wakeup Register                            */
 
 /* SIC Additions to ADSP-BF52x (0xFFC0014C - 0xFFC00162) */
 #define SIC_IMASK1                      0xFFC0014C     /* Interrupt Mask register of SIC2 */
 
 /* *************  SYSTEM INTERRUPT CONTROLLER MASKS *************************************/
 /* Peripheral Masks For SIC_ISR, SIC_IWR, SIC_IMASK                                                                            */
+
+#if 0
 #define IRQ_PLL_WAKEUP 0x00000001      /* PLL Wakeup Interrupt                                                         */
 
 #define IRQ_ERROR1      0x00000002  /* Error Interrupt (DMA, DMARx Block, DMARx Overflow) */
 #define IRQ_DMA15              0x40000000      /* DMA Channels 15 (MDMA0 Destination) TX Interrupt */
 #define IRQ_WDOG               0x80000000      /* Software Watchdog Timer Interrupt                            */
 #define IRQ_PFB_PORTG  0x10000000      /* PF Port G (PF31:16) Interrupt B                                      */
+#endif
 
 /* SIC_IAR0 Macros                                                                                                                     */
 #define P0_IVG(x)              (((x)&0xF)-7)                   /* Peripheral #0 assigned IVG #x        */
diff --git a/include/asm-blackfin/mach-bf527/dma.h b/include/asm-blackfin/mach-bf527/dma.h
new file mode 100644 (file)
index 0000000..a41627a
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * file:        include/asm-blackfin/mach-bf527/dma.h
+ * based on:   include/asm-blackfin/mach-bf537/dma.h
+ * author:     Michael Hennerich (michael.hennerich@analog.com)
+ *
+ * created:
+ * description:
+ *     system DMA map
+ * rev:
+ *
+ * modified:
+ *
+ *
+ * bugs:         enter bugs at http://blackfin.uclinux.org/
+ *
+ * this program is free software; you can redistribute it and/or modify
+ * it under the terms of the gnu general public license as published by
+ * the free software foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * this program is distributed in the hope that it will be useful,
+ * but without any warranty; without even the implied warranty of
+ * merchantability or fitness for a particular purpose.  see the
+ * gnu general public license for more details.
+ *
+ * you should have received a copy of the gnu general public license
+ * along with this program; see the file copying.
+ * if not, write to the free software foundation,
+ * 59 temple place - suite 330, boston, ma 02111-1307, usa.
+ */
+
+#ifndef _MACH_DMA_H_
+#define _MACH_DMA_H_
+
+#define MAX_BLACKFIN_DMA_CHANNEL 16
+
+#define CH_PPI                         0       /* PPI receive/transmit or NFC */
+#define CH_NFC                 0       /* PPI receive/transmit or NFC */
+#define CH_EMAC_RX             1       /* Ethernet MAC receive or HOSTDP */
+#define CH_EMAC_HOSTDP                 1       /* Ethernet MAC receive or HOSTDP */
+#define CH_EMAC_TX             2       /* Ethernet MAC transmit or NFC */
+#define CH_SPORT0_RX           3       /* SPORT0 receive */
+#define CH_SPORT0_TX           4       /* SPORT0 transmit */
+#define CH_SPORT1_RX           5       /* SPORT1 receive */
+#define CH_SPORT1_TX           6       /* SPORT1 transmit */
+#define CH_SPI                         7       /* SPI transmit/receive */
+#define CH_UART0_RX            8       /* UART0 receive */
+#define CH_UART0_TX            9       /* UART0 transmit */
+#define CH_UART1_RX            10      /* UART1 receive */
+#define CH_UART1_TX            11      /* UART1 transmit */
+
+#define CH_MEM_STREAM0_DEST    12      /* TX */
+#define CH_MEM_STREAM0_SRC     13      /* RX */
+#define CH_MEM_STREAM1_DEST    14      /* TX */
+#define CH_MEM_STREAM1_SRC     15      /* RX */
+
+extern int channel2irq(unsigned int channel);
+extern struct dma_register *base_addr[];
+
+#endif
diff --git a/include/asm-blackfin/mach-bf527/irq.h b/include/asm-blackfin/mach-bf527/irq.h
new file mode 100644 (file)
index 0000000..304f5bc
--- /dev/null
@@ -0,0 +1,263 @@
+/*
+ * file:       include/asm-blackfin/mach-bf527/irq.h
+ * based on:   include/asm-blackfin/mach-bf537/irq.h
+ * author:     Michael Hennerich (michael.hennerich@analog.com)
+ *
+ * created:
+ * description:
+ *     system mmr register map
+ * rev:
+ *
+ * modified:
+ *
+ *
+ * bugs:         enter bugs at http://blackfin.uclinux.org/
+ *
+ * this program is free software; you can redistribute it and/or modify
+ * it under the terms of the gnu general public license as published by
+ * the free software foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * this program is distributed in the hope that it will be useful,
+ * but without any warranty; without even the implied warranty of
+ * merchantability or fitness for a particular purpose.  see the
+ * gnu general public license for more details.
+ *
+ * you should have received a copy of the gnu general public license
+ * along with this program; see the file copying.
+ * if not, write to the free software foundation,
+ * 59 temple place - suite 330, boston, ma 02111-1307, usa.
+ */
+
+#ifndef _BF527_IRQ_H_
+#define _BF527_IRQ_H_
+
+/*
+ * Interrupt source definitions
+       Event Source    Core Event Name
+       Core        Emulation               **
+       Events         (highest priority)  EMU         0
+       Reset                   RST         1
+       NMI                     NMI         2
+       Exception               EVX         3
+       Reserved                --          4
+       Hardware Error          IVHW        5
+       Core Timer              IVTMR       6 *
+
+       .....
+
+        Software Interrupt 1    IVG14       31
+        Software Interrupt 2    --
+        (lowest priority)  IVG15       32 *
+*/
+
+#define NR_PERI_INTS    (2 * 32)
+
+/* The ABSTRACT IRQ definitions */
+/** the first seven of the following are fixed, the rest you change if you need to **/
+#define IRQ_EMU                        0       /* Emulation */
+#define IRQ_RST                        1       /* reset */
+#define IRQ_NMI                        2       /* Non Maskable */
+#define IRQ_EVX                        3       /* Exception */
+#define IRQ_UNUSED             4       /* - unused interrupt */
+#define IRQ_HWERR              5       /* Hardware Error */
+#define IRQ_CORETMR            6       /* Core timer */
+
+#define BFIN_IRQ(x)            ((x) + 7)
+
+#define IRQ_PLL_WAKEUP         BFIN_IRQ(0)     /* PLL Wakeup Interrupt */
+#define IRQ_DMA0_ERROR         BFIN_IRQ(1)     /* DMA Error 0 (generic) */
+#define IRQ_DMAR0_BLK          BFIN_IRQ(2)     /* DMAR0 Block Interrupt */
+#define IRQ_DMAR1_BLK          BFIN_IRQ(3)     /* DMAR1 Block Interrupt */
+#define IRQ_DMAR0_OVR          BFIN_IRQ(4)     /* DMAR0 Overflow Error */
+#define IRQ_DMAR1_OVR          BFIN_IRQ(5)     /* DMAR1 Overflow Error */
+#define IRQ_PPI_ERROR          BFIN_IRQ(6)     /* PPI Error */
+#define IRQ_MAC_ERROR          BFIN_IRQ(7)     /* MAC Status */
+#define IRQ_SPORT0_ERROR       BFIN_IRQ(8)     /* SPORT0 Status */
+#define IRQ_SPORT1_ERROR       BFIN_IRQ(9)     /* SPORT1 Status */
+#define IRQ_UART0_ERROR                BFIN_IRQ(12)    /* UART0 Status */
+#define IRQ_UART1_ERROR                BFIN_IRQ(13)    /* UART1 Status */
+#define IRQ_RTC                        BFIN_IRQ(14)    /* RTC */
+#define IRQ_PPI                BFIN_IRQ(15)    /* DMA Channel 0 (PPI/NAND) */
+#define IRQ_SPORT0_RX          BFIN_IRQ(16)    /* DMA 3 Channel (SPORT0 RX) */
+#define IRQ_SPORT0_TX          BFIN_IRQ(17)    /* DMA 4 Channel (SPORT0 TX) */
+#define IRQ_SPORT1_RX          BFIN_IRQ(18)    /* DMA 5 Channel (SPORT1 RX) */
+#define IRQ_SPORT1_TX          BFIN_IRQ(19)    /* DMA 6 Channel (SPORT1 TX) */
+#define IRQ_TWI                BFIN_IRQ(20)    /* TWI */
+#define IRQ_SPI                BFIN_IRQ(21)    /* DMA 7 Channel (SPI) */
+#define IRQ_UART0_RX           BFIN_IRQ(22)    /* DMA8 Channel (UART0 RX) */
+#define IRQ_UART0_TX           BFIN_IRQ(23)    /* DMA9 Channel (UART0 TX) */
+#define IRQ_UART1_RX           BFIN_IRQ(24)    /* DMA10 Channel (UART1 RX) */
+#define IRQ_UART1_TX           BFIN_IRQ(25)    /* DMA11 Channel (UART1 TX) */
+#define IRQ_OPTSEC             BFIN_IRQ(26)    /* OTPSEC Interrupt */
+#define IRQ_CNT                BFIN_IRQ(27)    /* GP Counter */
+#define IRQ_MAC_RX             BFIN_IRQ(28)    /* DMA1 Channel (MAC RX/HDMA) */
+#define IRQ_PORTH_INTA         BFIN_IRQ(29)    /* Port H Interrupt A */
+#define IRQ_MAC_TX             BFIN_IRQ(30)    /* DMA2 Channel (MAC TX/NAND) */
+#define IRQ_NFC                        BFIN_IRQ(30)    /* DMA2 Channel (MAC TX/NAND) */
+#define IRQ_PORTH_INTB         BFIN_IRQ(31)    /* Port H Interrupt B */
+#define IRQ_TMR0               BFIN_IRQ(32)    /* Timer 0 */
+#define IRQ_TMR1               BFIN_IRQ(33)    /* Timer 1 */
+#define IRQ_TMR2               BFIN_IRQ(34)    /* Timer 2 */
+#define IRQ_TMR3               BFIN_IRQ(35)    /* Timer 3 */
+#define IRQ_TMR4               BFIN_IRQ(36)    /* Timer 4 */
+#define IRQ_TMR5               BFIN_IRQ(37)    /* Timer 5 */
+#define IRQ_TMR6               BFIN_IRQ(38)    /* Timer 6 */
+#define IRQ_TMR7               BFIN_IRQ(39)    /* Timer 7 */
+#define IRQ_PORTG_INTA         BFIN_IRQ(40)    /* Port G Interrupt A */
+#define IRQ_PORTG_INTB         BFIN_IRQ(41)    /* Port G Interrupt B */
+#define IRQ_MEM_DMA0           BFIN_IRQ(42)    /* MDMA Stream 0 */
+#define IRQ_MEM_DMA1           BFIN_IRQ(43)    /* MDMA Stream 1 */
+#define IRQ_WATCH              BFIN_IRQ(44)    /* Software Watchdog Timer */
+#define IRQ_PORTF_INTA         BFIN_IRQ(45)    /* Port F Interrupt A */
+#define IRQ_PORTF_INTB         BFIN_IRQ(46)    /* Port F Interrupt B */
+#define IRQ_SPI_ERROR          BFIN_IRQ(47)    /* SPI Status */
+#define IRQ_NFC_ERROR          BFIN_IRQ(48)    /* NAND Error */
+#define IRQ_HDMA_ERROR         BFIN_IRQ(49)    /* HDMA Error */
+#define IRQ_HDMA               BFIN_IRQ(50)    /* HDMA (TFI) */
+#define IRQ_USB_EINT           BFIN_IRQ(51)    /* USB_EINT Interrupt */
+#define IRQ_USB_INT0           BFIN_IRQ(52)    /* USB_INT0 Interrupt */
+#define IRQ_USB_INT1           BFIN_IRQ(53)    /* USB_INT1 Interrupt */
+#define IRQ_USB_INT2           BFIN_IRQ(54)    /* USB_INT2 Interrupt */
+#define IRQ_USB_DMA            BFIN_IRQ(55)    /* USB_DMAINT Interrupt */
+
+#define SYS_IRQS               BFIN_IRQ(63)    /* 70 */
+
+#define IRQ_PF0         71
+#define IRQ_PF1         72
+#define IRQ_PF2         73
+#define IRQ_PF3         74
+#define IRQ_PF4         75
+#define IRQ_PF5         76
+#define IRQ_PF6         77
+#define IRQ_PF7         78
+#define IRQ_PF8         79
+#define IRQ_PF9         80
+#define IRQ_PF10        81
+#define IRQ_PF11        82
+#define IRQ_PF12        83
+#define IRQ_PF13        84
+#define IRQ_PF14        85
+#define IRQ_PF15        86
+
+#define IRQ_PG0         87
+#define IRQ_PG1         88
+#define IRQ_PG2         89
+#define IRQ_PG3         90
+#define IRQ_PG4         91
+#define IRQ_PG5         92
+#define IRQ_PG6         93
+#define IRQ_PG7         94
+#define IRQ_PG8         95
+#define IRQ_PG9         96
+#define IRQ_PG10        97
+#define IRQ_PG11        98
+#define IRQ_PG12        99
+#define IRQ_PG13        100
+#define IRQ_PG14        101
+#define IRQ_PG15        102
+
+#define IRQ_PH0         103
+#define IRQ_PH1         104
+#define IRQ_PH2         105
+#define IRQ_PH3         106
+#define IRQ_PH4         107
+#define IRQ_PH5         108
+#define IRQ_PH6         109
+#define IRQ_PH7         110
+#define IRQ_PH8         111
+#define IRQ_PH9         112
+#define IRQ_PH10        113
+#define IRQ_PH11        114
+#define IRQ_PH12        115
+#define IRQ_PH13        116
+#define IRQ_PH14        117
+#define IRQ_PH15        118
+
+#define GPIO_IRQ_BASE  IRQ_PF0
+
+#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
+#define NR_IRQS     (IRQ_PH15+1)
+#else
+#define NR_IRQS     (SYS_IRQS+1)
+#endif
+
+#define IVG7            7
+#define IVG8            8
+#define IVG9            9
+#define IVG10           10
+#define IVG11           11
+#define IVG12           12
+#define IVG13           13
+#define IVG14           14
+#define IVG15           15
+
+/* IAR0 BIT FIELDS */
+#define IRQ_PLL_WAKEUP_POS     0
+#define IRQ_DMA0_ERROR_POS     4
+#define IRQ_DMAR0_BLK_POS      8
+#define IRQ_DMAR1_BLK_POS      12
+#define IRQ_DMAR0_OVR_POS      16
+#define IRQ_DMAR1_OVR_POS      20
+#define IRQ_PPI_ERROR_POS      24
+#define IRQ_MAC_ERROR_POS      28
+
+/* IAR1 BIT FIELDS */
+#define IRQ_SPORT0_ERROR_POS   0
+#define IRQ_SPORT1_ERROR_POS   4
+#define IRQ_UART0_ERROR_POS    16
+#define IRQ_UART1_ERROR_POS    20
+#define IRQ_RTC_POS            24
+#define IRQ_PPI_POS            28
+
+/* IAR2 BIT FIELDS */
+#define IRQ_SPORT0_RX_POS      0
+#define IRQ_SPORT0_TX_POS      4
+#define IRQ_SPORT1_RX_POS      8
+#define IRQ_SPORT1_TX_POS      12
+#define IRQ_TWI_POS            16
+#define IRQ_SPI_POS            20
+#define IRQ_UART0_RX_POS       24
+#define IRQ_UART0_TX_POS       28
+
+/* IAR3 BIT FIELDS */
+#define IRQ_UART1_RX_POS       0
+#define IRQ_UART1_TX_POS       4
+#define IRQ_OPTSEC_POS         8
+#define IRQ_CNT_POS            12
+#define IRQ_MAC_RX_POS         16
+#define IRQ_PORTH_INTA_POS     20
+#define IRQ_MAC_TX_POS         24
+#define IRQ_PORTH_INTB_POS     28
+
+/* IAR4 BIT FIELDS */
+#define IRQ_TMR0_POS           0
+#define IRQ_TMR1_POS           4
+#define IRQ_TMR2_POS           8
+#define IRQ_TMR3_POS           12
+#define IRQ_TMR4_POS           16
+#define IRQ_TMR5_POS           20
+#define IRQ_TMR6_POS           24
+#define IRQ_TMR7_POS           28
+
+/* IAR5 BIT FIELDS */
+#define IRQ_PORTG_INTA_POS     0
+#define IRQ_PORTG_INTB_POS     4
+#define IRQ_MEM_DMA0_POS       8
+#define IRQ_MEM_DMA1_POS       12
+#define IRQ_WATCH_POS          16
+#define IRQ_PORTF_INTA_POS     20
+#define IRQ_PORTF_INTB_POS     24
+#define IRQ_SPI_ERROR_POS      28
+
+/* IAR6 BIT FIELDS */
+#define IRQ_NFC_ERROR_POS      0
+#define IRQ_HDMA_ERROR_POS     4
+#define IRQ_HDMA_POS           8
+#define IRQ_USB_EINT_POS       12
+#define IRQ_USB_INT0_POS       16
+#define IRQ_USB_INT1_POS       20
+#define IRQ_USB_INT2_POS       24
+#define IRQ_USB_DMA_POS        28
+
+#endif                         /* _BF527_IRQ_H_ */
diff --git a/include/asm-blackfin/mach-bf527/mem_init.h b/include/asm-blackfin/mach-bf527/mem_init.h
new file mode 100644 (file)
index 0000000..008ca66
--- /dev/null
@@ -0,0 +1,337 @@
+/*
+ * File:         include/asm-blackfin/mach-bf527/mem_init.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:
+ *
+ * Modified:
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#if (CONFIG_MEM_MT48LC16M16A2TG_75 || CONFIG_MEM_MT48LC64M4A2FB_7E || CONFIG_MEM_MT48LC16M8A2TG_75 || CONFIG_MEM_GENERIC_BOARD || CONFIG_MEM_MT48LC32M8A2_75 || CONFIG_MEM_MT48LC32M16A2TG_75)
+#if (CONFIG_SCLK_HZ > 119402985)
+#define SDRAM_tRP       TRP_2
+#define SDRAM_tRP_num   2
+#define SDRAM_tRAS      TRAS_7
+#define SDRAM_tRAS_num  7
+#define SDRAM_tRCD      TRCD_2
+#define SDRAM_tWR       TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 104477612) && (CONFIG_SCLK_HZ <= 119402985)
+#define SDRAM_tRP       TRP_2
+#define SDRAM_tRP_num   2
+#define SDRAM_tRAS      TRAS_6
+#define SDRAM_tRAS_num  6
+#define SDRAM_tRCD      TRCD_2
+#define SDRAM_tWR       TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 89552239) && (CONFIG_SCLK_HZ <= 104477612)
+#define SDRAM_tRP       TRP_2
+#define SDRAM_tRP_num   2
+#define SDRAM_tRAS      TRAS_5
+#define SDRAM_tRAS_num  5
+#define SDRAM_tRCD      TRCD_2
+#define SDRAM_tWR       TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 74626866) && (CONFIG_SCLK_HZ <= 89552239)
+#define SDRAM_tRP       TRP_2
+#define SDRAM_tRP_num   2
+#define SDRAM_tRAS      TRAS_4
+#define SDRAM_tRAS_num  4
+#define SDRAM_tRCD      TRCD_2
+#define SDRAM_tWR       TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 66666667) && (CONFIG_SCLK_HZ <= 74626866)
+#define SDRAM_tRP       TRP_2
+#define SDRAM_tRP_num   2
+#define SDRAM_tRAS      TRAS_3
+#define SDRAM_tRAS_num  3
+#define SDRAM_tRCD      TRCD_2
+#define SDRAM_tWR       TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 59701493) && (CONFIG_SCLK_HZ <= 66666667)
+#define SDRAM_tRP       TRP_1
+#define SDRAM_tRP_num   1
+#define SDRAM_tRAS      TRAS_4
+#define SDRAM_tRAS_num  3
+#define SDRAM_tRCD      TRCD_1
+#define SDRAM_tWR       TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 44776119) && (CONFIG_SCLK_HZ <= 59701493)
+#define SDRAM_tRP       TRP_1
+#define SDRAM_tRP_num   1
+#define SDRAM_tRAS      TRAS_3
+#define SDRAM_tRAS_num  3
+#define SDRAM_tRCD      TRCD_1
+#define SDRAM_tWR       TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 29850746) && (CONFIG_SCLK_HZ <= 44776119)
+#define SDRAM_tRP       TRP_1
+#define SDRAM_tRP_num   1
+#define SDRAM_tRAS      TRAS_2
+#define SDRAM_tRAS_num  2
+#define SDRAM_tRCD      TRCD_1
+#define SDRAM_tWR       TWR_2
+#endif
+#if (CONFIG_SCLK_HZ <= 29850746)
+#define SDRAM_tRP       TRP_1
+#define SDRAM_tRP_num   1
+#define SDRAM_tRAS      TRAS_1
+#define SDRAM_tRAS_num  1
+#define SDRAM_tRCD      TRCD_1
+#define SDRAM_tWR       TWR_2
+#endif
+#endif
+
+#if (CONFIG_MEM_MT48LC16M16A2TG_75)
+  /*SDRAM INFORMATION: */
+#define SDRAM_Tref  64         /* Refresh period in milliseconds   */
+#define SDRAM_NRA   8192       /* Number of row addresses in SDRAM */
+#define SDRAM_CL    CL_3
+#endif
+
+#if (CONFIG_MEM_MT48LC16M8A2TG_75)
+  /*SDRAM INFORMATION: */
+#define SDRAM_Tref  64         /* Refresh period in milliseconds   */
+#define SDRAM_NRA   4096       /* Number of row addresses in SDRAM */
+#define SDRAM_CL    CL_3
+#endif
+
+#if (CONFIG_MEM_MT48LC32M8A2_75)
+  /*SDRAM INFORMATION: */
+#define SDRAM_Tref  64         /* Refresh period in milliseconds   */
+#define SDRAM_NRA   8192       /* Number of row addresses in SDRAM */
+#define SDRAM_CL    CL_3
+#endif
+
+#if (CONFIG_MEM_MT48LC64M4A2FB_7E)
+  /*SDRAM INFORMATION: */
+#define SDRAM_Tref  64         /* Refresh period in milliseconds   */
+#define SDRAM_NRA   8192       /* Number of row addresses in SDRAM */
+#define SDRAM_CL    CL_3
+#endif
+
+#if (CONFIG_MEM_GENERIC_BOARD)
+  /*SDRAM INFORMATION: Modify this for your board */
+#define SDRAM_Tref  64         /* Refresh period in milliseconds   */
+#define SDRAM_NRA   8192       /* Number of row addresses in SDRAM */
+#define SDRAM_CL    CL_3
+#endif
+
+#if (CONFIG_MEM_MT48LC32M16A2TG_75)
+  /*SDRAM INFORMATION: */
+#define SDRAM_Tref  64         /* Refresh period in milliseconds   */
+#define SDRAM_NRA   8192       /* Number of row addresses in SDRAM */
+#define SDRAM_CL    CL_3
+#endif
+
+#if (CONFIG_MEM_SIZE == 128)
+#define SDRAM_SIZE      EBSZ_128
+#endif
+#if (CONFIG_MEM_SIZE == 64)
+#define SDRAM_SIZE      EBSZ_64
+#endif
+#if (CONFIG_MEM_SIZE == 32)
+#define SDRAM_SIZE      EBSZ_32
+#endif
+#if (CONFIG_MEM_SIZE == 16)
+#define SDRAM_SIZE      EBSZ_16
+#endif
+#if (CONFIG_MEM_ADD_WIDTH == 11)
+#define SDRAM_WIDTH     EBCAW_11
+#endif
+#if (CONFIG_MEM_ADD_WIDTH == 10)
+#define SDRAM_WIDTH     EBCAW_10
+#endif
+#if (CONFIG_MEM_ADD_WIDTH == 9)
+#define SDRAM_WIDTH     EBCAW_9
+#endif
+#if (CONFIG_MEM_ADD_WIDTH == 8)
+#define SDRAM_WIDTH     EBCAW_8
+#endif
+
+#define mem_SDBCTL      (SDRAM_WIDTH | SDRAM_SIZE | EBE)
+
+/* Equation from section 17 (p17-46) of BF533 HRM */
+#define mem_SDRRC       (((CONFIG_SCLK_HZ / 1000) * SDRAM_Tref) / SDRAM_NRA) - (SDRAM_tRAS_num + SDRAM_tRP_num)
+
+/* Enable SCLK Out */
+#define mem_SDGCTL        (SCTLE | SDRAM_CL | SDRAM_tRAS | SDRAM_tRP | SDRAM_tRCD | SDRAM_tWR | PSS)
+
+#if defined CONFIG_CLKIN_HALF
+#define CLKIN_HALF       1
+#else
+#define CLKIN_HALF       0
+#endif
+
+#if defined CONFIG_PLL_BYPASS
+#define PLL_BYPASS      1
+#else
+#define PLL_BYPASS       0
+#endif
+
+/***************************************Currently Not Being Used *********************************/
+#define flash_EBIU_AMBCTL_WAT  ((CONFIG_FLASH_SPEED_BWAT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
+#define flash_EBIU_AMBCTL_RAT  ((CONFIG_FLASH_SPEED_BRAT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
+#define flash_EBIU_AMBCTL_HT   ((CONFIG_FLASH_SPEED_BHT  * 4) / (4000000000 / CONFIG_SCLK_HZ))
+#define flash_EBIU_AMBCTL_ST   ((CONFIG_FLASH_SPEED_BST  * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
+#define flash_EBIU_AMBCTL_TT   ((CONFIG_FLASH_SPEED_BTT  * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
+
+#if (flash_EBIU_AMBCTL_TT > 3)
+#define flash_EBIU_AMBCTL0_TT   B0TT_4
+#endif
+#if (flash_EBIU_AMBCTL_TT == 3)
+#define flash_EBIU_AMBCTL0_TT   B0TT_3
+#endif
+#if (flash_EBIU_AMBCTL_TT == 2)
+#define flash_EBIU_AMBCTL0_TT   B0TT_2
+#endif
+#if (flash_EBIU_AMBCTL_TT < 2)
+#define flash_EBIU_AMBCTL0_TT   B0TT_1
+#endif
+
+#if (flash_EBIU_AMBCTL_ST > 3)
+#define flash_EBIU_AMBCTL0_ST   B0ST_4
+#endif
+#if (flash_EBIU_AMBCTL_ST == 3)
+#define flash_EBIU_AMBCTL0_ST   B0ST_3
+#endif
+#if (flash_EBIU_AMBCTL_ST == 2)
+#define flash_EBIU_AMBCTL0_ST   B0ST_2
+#endif
+#if (flash_EBIU_AMBCTL_ST < 2)
+#define flash_EBIU_AMBCTL0_ST   B0ST_1
+#endif
+
+#if (flash_EBIU_AMBCTL_HT > 2)
+#define flash_EBIU_AMBCTL0_HT   B0HT_3
+#endif
+#if (flash_EBIU_AMBCTL_HT == 2)
+#define flash_EBIU_AMBCTL0_HT   B0HT_2
+#endif
+#if (flash_EBIU_AMBCTL_HT == 1)
+#define flash_EBIU_AMBCTL0_HT   B0HT_1
+#endif
+#if (flash_EBIU_AMBCTL_HT == 0 && CONFIG_FLASH_SPEED_BHT == 0)
+#define flash_EBIU_AMBCTL0_HT   B0HT_0
+#endif
+#if (flash_EBIU_AMBCTL_HT == 0 && CONFIG_FLASH_SPEED_BHT != 0)
+#define flash_EBIU_AMBCTL0_HT   B0HT_1
+#endif
+
+#if (flash_EBIU_AMBCTL_WAT > 14)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_15
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 14)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_14
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 13)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_13
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 12)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_12
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 11)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_11
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 10)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_10
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 9)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_9
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 8)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_8
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 7)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_7
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 6)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_6
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 5)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_5
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 4)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_4
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 3)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_3
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 2)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_2
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 1)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_1
+#endif
+
+#if (flash_EBIU_AMBCTL_RAT > 14)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_15
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 14)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_14
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 13)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_13
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 12)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_12
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 11)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_11
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 10)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_10
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 9)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_9
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 8)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_8
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 7)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_7
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 6)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_6
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 5)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_5
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 4)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_4
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 3)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_3
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 2)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_2
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 1)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_1
+#endif
+
+#define flash_EBIU_AMBCTL0  \
+       (flash_EBIU_AMBCTL0_WAT | flash_EBIU_AMBCTL0_RAT | flash_EBIU_AMBCTL0_HT | \
+        flash_EBIU_AMBCTL0_ST | flash_EBIU_AMBCTL0_TT | CONFIG_FLASH_SPEED_RDYEN)
diff --git a/include/asm-blackfin/mach-bf527/mem_map.h b/include/asm-blackfin/mach-bf527/mem_map.h
new file mode 100644 (file)
index 0000000..c5aa201
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * file:         include/asm-blackfin/mach-bf527/mem_map.h
+ * based on:   include/asm-blackfin/mach-bf537/mem_map.h
+ * author:     Michael Hennerich (michael.hennerich@analog.com)
+ *
+ * created:
+ * description:
+ *     Memory MAP Common header file for blackfin BF527/5/2 of processors.
+ * rev:
+ *
+ * modified:
+ *
+ * bugs:         enter bugs at http://blackfin.uclinux.org/
+ *
+ * this program is free software; you can redistribute it and/or modify
+ * it under the terms of the gnu general public license as published by
+ * the free software foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * this program is distributed in the hope that it will be useful,
+ * but without any warranty; without even the implied warranty of
+ * merchantability or fitness for a particular purpose.  see the
+ * gnu general public license for more details.
+ *
+ * you should have received a copy of the gnu general public license
+ * along with this program; see the file copying.
+ * if not, write to the free software foundation,
+ * 59 temple place - suite 330, boston, ma 02111-1307, usa.
+ */
+
+#ifndef _MEM_MAP_527_H_
+#define _MEM_MAP_527_H_
+
+#define COREMMR_BASE           0xFFE00000      /* Core MMRs */
+#define SYSMMR_BASE            0xFFC00000      /* System MMRs */
+
+/* Async Memory Banks */
+#define ASYNC_BANK3_BASE       0x20300000      /* Async Bank 3 */
+#define ASYNC_BANK3_SIZE       0x00100000      /* 1M */
+#define ASYNC_BANK2_BASE       0x20200000      /* Async Bank 2 */
+#define ASYNC_BANK2_SIZE       0x00100000      /* 1M */
+#define ASYNC_BANK1_BASE       0x20100000      /* Async Bank 1 */
+#define ASYNC_BANK1_SIZE       0x00100000      /* 1M */
+#define ASYNC_BANK0_BASE       0x20000000      /* Async Bank 0 */
+#define ASYNC_BANK0_SIZE       0x00100000      /* 1M */
+
+/* Boot ROM Memory */
+
+#define BOOT_ROM_START         0xEF000000
+
+/* Level 1 Memory */
+
+/* Memory Map for ADSP-BF527 ADSP-BF525 ADSP-BF522 processors */
+
+#ifdef CONFIG_BFIN_ICACHE
+#define BFIN_ICACHESIZE        (16*1024)
+#else
+#define BFIN_ICACHESIZE        (0*1024)
+#endif
+
+#define L1_CODE_START       0xFFA00000
+#define L1_DATA_A_START     0xFF800000
+#define L1_DATA_B_START     0xFF900000
+
+#define L1_CODE_LENGTH      0xC000
+
+#ifdef CONFIG_BFIN_DCACHE
+
+#ifdef CONFIG_BFIN_DCACHE_BANKA
+#define DMEM_CNTR (ACACHE_BSRAM | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH      (0x8000 - 0x4000)
+#define L1_DATA_B_LENGTH      0x8000
+#define BFIN_DCACHESIZE        (16*1024)
+#define BFIN_DSUPBANKS 1
+#else
+#define DMEM_CNTR (ACACHE_BCACHE | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH      (0x8000 - 0x4000)
+#define L1_DATA_B_LENGTH      (0x8000 - 0x4000)
+#define BFIN_DCACHESIZE        (32*1024)
+#define BFIN_DSUPBANKS 2
+#endif
+
+#else
+#define DMEM_CNTR (ASRAM_BSRAM | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH      0x8000
+#define L1_DATA_B_LENGTH      0x8000
+#define BFIN_DCACHESIZE        (0*1024)
+#define BFIN_DSUPBANKS 0
+#endif                         /*CONFIG_BFIN_DCACHE */
+
+/* Scratch Pad Memory */
+
+#if defined(CONFIG_BF527) || defined(CONFIG_BF536) || defined(CONFIG_BF534)
+#define L1_SCRATCH_START       0xFFB00000
+#define L1_SCRATCH_LENGTH      0x1000
+#endif
+
+#endif                         /* _MEM_MAP_527_H_ */
diff --git a/include/asm-blackfin/mach-bf527/portmux.h b/include/asm-blackfin/mach-bf527/portmux.h
new file mode 100644 (file)
index 0000000..dcf001a
--- /dev/null
@@ -0,0 +1,205 @@
+#ifndef _MACH_PORTMUX_H_
+#define _MACH_PORTMUX_H_
+
+#define P_PPI0_D0      (P_DEFINED | P_IDENT(GPIO_PF0) | P_FUNCT(0))
+#define P_PPI0_D1      (P_DEFINED | P_IDENT(GPIO_PF1) | P_FUNCT(0))
+#define P_PPI0_D2      (P_DEFINED | P_IDENT(GPIO_PF2) | P_FUNCT(0))
+#define P_PPI0_D3      (P_DEFINED | P_IDENT(GPIO_PF3) | P_FUNCT(0))
+#define P_PPI0_D4      (P_DEFINED | P_IDENT(GPIO_PF4) | P_FUNCT(0))
+#define P_PPI0_D5      (P_DEFINED | P_IDENT(GPIO_PF5) | P_FUNCT(0))
+#define P_PPI0_D6      (P_DEFINED | P_IDENT(GPIO_PF6) | P_FUNCT(0))
+#define P_PPI0_D7      (P_DEFINED | P_IDENT(GPIO_PF7) | P_FUNCT(0))
+#define P_PPI0_D8      (P_DEFINED | P_IDENT(GPIO_PF8) | P_FUNCT(0))
+#define P_PPI0_D9      (P_DEFINED | P_IDENT(GPIO_PF9) | P_FUNCT(0))
+#define P_PPI0_D10     (P_DEFINED | P_IDENT(GPIO_PF10) | P_FUNCT(0))
+#define P_PPI0_D11     (P_DEFINED | P_IDENT(GPIO_PF11) | P_FUNCT(0))
+#define P_PPI0_D12     (P_DEFINED | P_IDENT(GPIO_PF12) | P_FUNCT(0))
+#define P_PPI0_D13     (P_DEFINED | P_IDENT(GPIO_PF13) | P_FUNCT(0))
+#define P_PPI0_D14     (P_DEFINED | P_IDENT(GPIO_PF14) | P_FUNCT(0))
+#define P_PPI0_D15     (P_DEFINED | P_IDENT(GPIO_PF15) | P_FUNCT(0))
+
+#if defined(CONFIG_BF527_SPORT0_PORTF)
+#define P_SPORT0_DRPRI (P_DEFINED | P_IDENT(GPIO_PF0) | P_FUNCT(1))
+#define P_SPORT0_RFS   (P_DEFINED | P_IDENT(GPIO_PF1) | P_FUNCT(1))
+#define P_SPORT0_RSCLK (P_DEFINED | P_IDENT(GPIO_PF2) | P_FUNCT(1))
+#define P_SPORT0_DTPRI (P_DEFINED | P_IDENT(GPIO_PF3) | P_FUNCT(1))
+#define P_SPORT0_TFS   (P_DEFINED | P_IDENT(GPIO_PF4) | P_FUNCT(1))
+#define P_SPORT0_TSCLK (P_DEFINED | P_IDENT(GPIO_PF5) | P_FUNCT(1))
+#define P_SPORT0_DTSEC (P_DEFINED | P_IDENT(GPIO_PF6) | P_FUNCT(1))
+#define P_SPORT0_DRSEC (P_DEFINED | P_IDENT(GPIO_PF7) | P_FUNCT(1))
+#elif defined(CONFIG_BF527_SPORT0_PORTG)
+#define P_SPORT0_DTPRI (P_DEFINED | P_IDENT(GPIO_PG6) | P_FUNCT(0))
+#define P_SPORT0_DRSEC (P_DEFINED | P_IDENT(GPIO_PG3) | P_FUNCT(1))
+#define P_SPORT0_DTSEC (P_DEFINED | P_IDENT(GPIO_PG4) | P_FUNCT(1))
+#define P_SPORT0_DRPRI (P_DEFINED | P_IDENT(GPIO_PG7) | P_FUNCT(1))
+#define P_SPORT0_RFS   (P_DEFINED | P_IDENT(GPIO_PG8) | P_FUNCT(1))
+#define P_SPORT0_RSCLK (P_DEFINED | P_IDENT(GPIO_PG9) | P_FUNCT(1))
+#if defined(CONFIG_BF527_SPORT0_TSCLK_PG10)
+#define P_SPORT0_TSCLK (P_DEFINED | P_IDENT(GPIO_PG10) | P_FUNCT(1))
+#elif defined(CONFIG_BF527_SPORT0_TSCLK_PG14)
+#define P_SPORT0_TSCLK (P_DEFINED | P_IDENT(GPIO_PG14) | P_FUNCT(0))
+#endif
+#define P_SPORT0_TFS   (P_DEFINED | P_IDENT(GPIO_PG15) | P_FUNCT(0))
+#endif
+
+#define P_SPORT1_DRPRI (P_DEFINED | P_IDENT(GPIO_PF8) | P_FUNCT(1))
+#define P_SPORT1_RSCLK (P_DEFINED | P_IDENT(GPIO_PF9) | P_FUNCT(1))
+#define P_SPORT1_RFS   (P_DEFINED | P_IDENT(GPIO_PF10) | P_FUNCT(1))
+#define P_SPORT1_TFS   (P_DEFINED | P_IDENT(GPIO_PF11) | P_FUNCT(1))
+#define P_SPORT1_DTPRI (P_DEFINED | P_IDENT(GPIO_PF12) | P_FUNCT(1))
+#define P_SPORT1_TSCLK (P_DEFINED | P_IDENT(GPIO_PF13) | P_FUNCT(1))
+#define P_SPORT1_DTSEC (P_DEFINED | P_IDENT(GPIO_PF14) | P_FUNCT(1))
+#define P_SPORT1_DRSEC (P_DEFINED | P_IDENT(GPIO_PF15) | P_FUNCT(1))
+
+#define P_SPI0_SSEL6   (P_DEFINED | P_IDENT(GPIO_PF9) | P_FUNCT(2))
+#define P_SPI0_SSEL7   (P_DEFINED | P_IDENT(GPIO_PF10) | P_FUNCT(2))
+
+#define P_SPI0_SSEL2   (P_DEFINED | P_IDENT(GPIO_PF12) | P_FUNCT(2))
+#define P_SPI0_SSEL3   (P_DEFINED | P_IDENT(GPIO_PF13) | P_FUNCT(2))
+
+#if defined(CONFIG_BF527_UART1_PORTF)
+#define P_UART1_TX     (P_DEFINED | P_IDENT(GPIO_PF14) | P_FUNCT(2))
+#define P_UART1_RX     (P_DEFINED | P_IDENT(GPIO_PF15) | P_FUNCT(2))
+#elif defined(CONFIG_BF527_UART1_PORTG)
+#define P_UART1_TX     (P_DEFINED | P_IDENT(GPIO_PG12) | P_FUNCT(1))
+#define P_UART1_RX     (P_DEFINED | P_IDENT(GPIO_PG13) | P_FUNCT(1))
+#endif
+
+#define P_HWAIT                (P_DONTCARE)
+
+#define P_SPI0_SS      (P_DEFINED | P_IDENT(GPIO_PG1) | P_FUNCT(0))
+#define P_SPI0_SSEL1   (P_DEFINED | P_IDENT(GPIO_PG1) | P_FUNCT(2))
+#define P_SPI0_SCK     (P_DEFINED | P_IDENT(GPIO_PG2) | P_FUNCT(2))
+#define P_SPI0_MISO    (P_DEFINED | P_IDENT(GPIO_PG3) | P_FUNCT(2))
+#define P_SPI0_MOSI    (P_DEFINED | P_IDENT(GPIO_PG4) | P_FUNCT(2))
+#define P_TMR1         (P_DEFINED | P_IDENT(GPIO_PG5) | P_FUNCT(0))
+#define P_PPI0_FS2     (P_DEFINED | P_IDENT(GPIO_PG5) | P_FUNCT(0))
+#define P_TMR3         (P_DEFINED | P_IDENT(GPIO_PG7) | P_FUNCT(0))
+#define P_TMR4         (P_DEFINED | P_IDENT(GPIO_PG8) | P_FUNCT(0))
+#define P_TMR5         (P_DEFINED | P_IDENT(GPIO_PG9) | P_FUNCT(0))
+#define P_TMR6         (P_DEFINED | P_IDENT(GPIO_PG10) | P_FUNCT(0))
+/* #define P_TMR7              (P_DEFINED | P_IDENT(GPIO_PG11) | P_FUNCT(0)) */
+#define P_DMAR1                (P_DEFINED | P_IDENT(GPIO_PG12) | P_FUNCT(0))
+#define P_DMAR0                (P_DEFINED | P_IDENT(GPIO_PG13) | P_FUNCT(0))
+#define P_TMR2         (P_DEFINED | P_IDENT(GPIO_PG6) | P_FUNCT(1))
+#define P_TMR7         (P_DEFINED | P_IDENT(GPIO_PG11) | P_FUNCT(1))
+#define P_MDC          (P_DEFINED | P_IDENT(GPIO_PG14) | P_FUNCT(1))
+#define P_RMII0_MDINT  (P_DEFINED | P_IDENT(GPIO_PG15) | P_FUNCT(1))
+#define P_MII0_PHYINT  (P_DEFINED | P_IDENT(GPIO_PG15) | P_FUNCT(1))
+
+#define P_PPI0_FS3     (P_DEFINED | P_IDENT(GPIO_PG6) | P_FUNCT(2))
+#define P_UART0_TX     (P_DEFINED | P_IDENT(GPIO_PG7) | P_FUNCT(2))
+#define P_UART0_RX     (P_DEFINED | P_IDENT(GPIO_PG8) | P_FUNCT(2))
+
+#define P_HOST_WR      (P_DEFINED | P_IDENT(GPIO_PG11) | P_FUNCT(2))
+#define P_HOST_ACK     (P_DEFINED | P_IDENT(GPIO_PG12) | P_FUNCT(2))
+#define P_HOST_ADDR    (P_DEFINED | P_IDENT(GPIO_PG13) | P_FUNCT(2))
+#define P_HOST_RD      (P_DEFINED | P_IDENT(GPIO_PG14) | P_FUNCT(2))
+#define P_HOST_CE      (P_DEFINED | P_IDENT(GPIO_PG15) | P_FUNCT(2))
+
+#if defined(CONFIG_BF527_NAND_D_PORTF)
+#define P_NAND_D0      (P_DEFINED | P_IDENT(GPIO_PF0) | P_FUNCT(2))
+#define P_NAND_D1      (P_DEFINED | P_IDENT(GPIO_PF1) | P_FUNCT(2))
+#define P_NAND_D2      (P_DEFINED | P_IDENT(GPIO_PF2) | P_FUNCT(2))
+#define P_NAND_D3      (P_DEFINED | P_IDENT(GPIO_PF3) | P_FUNCT(2))
+#define P_NAND_D4      (P_DEFINED | P_IDENT(GPIO_PF4) | P_FUNCT(2))
+#define P_NAND_D5      (P_DEFINED | P_IDENT(GPIO_PF5) | P_FUNCT(2))
+#define P_NAND_D6      (P_DEFINED | P_IDENT(GPIO_PF6) | P_FUNCT(2))
+#define P_NAND_D7      (P_DEFINED | P_IDENT(GPIO_PF7) | P_FUNCT(2))
+#elif defined(CONFIG_BF527_NAND_D_PORTH)
+#define P_NAND_D0      (P_DEFINED | P_IDENT(GPIO_PH0) | P_FUNCT(0))
+#define P_NAND_D1      (P_DEFINED | P_IDENT(GPIO_PH1) | P_FUNCT(0))
+#define P_NAND_D2      (P_DEFINED | P_IDENT(GPIO_PH2) | P_FUNCT(0))
+#define P_NAND_D3      (P_DEFINED | P_IDENT(GPIO_PH3) | P_FUNCT(0))
+#define P_NAND_D4      (P_DEFINED | P_IDENT(GPIO_PH4) | P_FUNCT(0))
+#define P_NAND_D5      (P_DEFINED | P_IDENT(GPIO_PH5) | P_FUNCT(0))
+#define P_NAND_D6      (P_DEFINED | P_IDENT(GPIO_PH6) | P_FUNCT(0))
+#define P_NAND_D7      (P_DEFINED | P_IDENT(GPIO_PH7) | P_FUNCT(0))
+#endif
+
+#define P_SPI0_SSEL4   (P_DEFINED | P_IDENT(GPIO_PH8) | P_FUNCT(0))
+#define P_SPI0_SSEL5   (P_DEFINED | P_IDENT(GPIO_PH9) | P_FUNCT(0))
+#define P_NAND_CE      (P_DEFINED | P_IDENT(GPIO_PH10) | P_FUNCT(0))
+#define P_NAND_WE      (P_DEFINED | P_IDENT(GPIO_PH11) | P_FUNCT(0))
+#define P_NAND_RE      (P_DEFINED | P_IDENT(GPIO_PH12) | P_FUNCT(0))
+#define P_NAND_RB      (P_DEFINED | P_IDENT(GPIO_PH13) | P_FUNCT(0))
+#define P_NAND_CLE     (P_DEFINED | P_IDENT(GPIO_PH14) | P_FUNCT(0))
+#define P_NAND_ALE     (P_DEFINED | P_IDENT(GPIO_PH15) | P_FUNCT(0))
+
+#define P_HOST_D0      (P_DEFINED | P_IDENT(GPIO_PH0) | P_FUNCT(2))
+#define P_HOST_D1      (P_DEFINED | P_IDENT(GPIO_PH1) | P_FUNCT(2))
+#define P_HOST_D2      (P_DEFINED | P_IDENT(GPIO_PH2) | P_FUNCT(2))
+#define P_HOST_D3      (P_DEFINED | P_IDENT(GPIO_PH3) | P_FUNCT(2))
+#define P_HOST_D4      (P_DEFINED | P_IDENT(GPIO_PH4) | P_FUNCT(2))
+#define P_HOST_D5      (P_DEFINED | P_IDENT(GPIO_PH5) | P_FUNCT(2))
+#define P_HOST_D6      (P_DEFINED | P_IDENT(GPIO_PH6) | P_FUNCT(2))
+#define P_HOST_D7      (P_DEFINED | P_IDENT(GPIO_PH7) | P_FUNCT(2))
+#define P_HOST_D8      (P_DEFINED | P_IDENT(GPIO_PH8) | P_FUNCT(2))
+#define P_HOST_D9      (P_DEFINED | P_IDENT(GPIO_PH9) | P_FUNCT(2))
+#define P_HOST_D10     (P_DEFINED | P_IDENT(GPIO_PH10) | P_FUNCT(2))
+#define P_HOST_D11     (P_DEFINED | P_IDENT(GPIO_PH11) | P_FUNCT(2))
+#define P_HOST_D12     (P_DEFINED | P_IDENT(GPIO_PH12) | P_FUNCT(2))
+#define P_HOST_D13     (P_DEFINED | P_IDENT(GPIO_PH13) | P_FUNCT(2))
+#define P_HOST_D14     (P_DEFINED | P_IDENT(GPIO_PH14) | P_FUNCT(2))
+#define P_HOST_D15     (P_DEFINED | P_IDENT(GPIO_PH15) | P_FUNCT(2))
+
+#define P_MII0_ETxD0   (P_DEFINED | P_IDENT(GPIO_PH5) | P_FUNCT(1))
+#define P_MII0_ETxD1   (P_DEFINED | P_IDENT(GPIO_PH7) | P_FUNCT(1))
+#define P_MII0_ETxD2   (P_DEFINED | P_IDENT(GPIO_PH9) | P_FUNCT(1))
+#define P_MII0_ETxD3   (P_DEFINED | P_IDENT(GPIO_PH11) | P_FUNCT(1))
+#define P_MII0_ETxEN   (P_DEFINED | P_IDENT(GPIO_PH3) | P_FUNCT(1))
+#define P_MII0_TxCLK   (P_DEFINED | P_IDENT(GPIO_PH4) | P_FUNCT(1))
+#define P_MII0_COL     (P_DEFINED | P_IDENT(GPIO_PH15) | P_FUNCT(1))
+#define P_MII0_ERxD0   (P_DEFINED | P_IDENT(GPIO_PH6) | P_FUNCT(1))
+#define P_MII0_ERxD1   (P_DEFINED | P_IDENT(GPIO_PH8) | P_FUNCT(1))
+#define P_MII0_ERxD2   (P_DEFINED | P_IDENT(GPIO_PH10) | P_FUNCT(1))
+#define P_MII0_ERxD3   (P_DEFINED | P_IDENT(GPIO_PH12) | P_FUNCT(1))
+#define P_MII0_ERxDV   (P_DEFINED | P_IDENT(GPIO_PH14) | P_FUNCT(1))
+#define P_MII0_ERxCLK  (P_DEFINED | P_IDENT(GPIO_PH13) | P_FUNCT(1))
+#define P_MII0_ERxER   (P_DEFINED | P_IDENT(GPIO_PH1) | P_FUNCT(1))
+#define P_MII0_CRS     (P_DEFINED | P_IDENT(GPIO_PH0) | P_FUNCT(1))
+#define P_RMII0_REF_CLK        (P_DEFINED | P_IDENT(GPIO_PH4) | P_FUNCT(1))
+#define P_RMII0_CRS_DV (P_DEFINED | P_IDENT(GPIO_PH0) | P_FUNCT(1))
+#define P_MDIO         (P_DEFINED | P_IDENT(GPIO_PH2) | P_FUNCT(1))
+
+#define P_TWI0_SCL     (P_DONTCARE)
+#define P_TWI0_SDA     (P_DONTCARE)
+#define P_PPI0_FS1     (P_DONTCARE)
+#define P_TMR0         (P_DONTCARE)
+#define P_TMRCLK       (P_DONTCARE)
+#define P_PPI0_CLK     (P_DONTCARE)
+
+#define P_MII0 {\
+       P_MII0_ETxD0, \
+       P_MII0_ETxD1, \
+       P_MII0_ETxD2, \
+       P_MII0_ETxD3, \
+       P_MII0_ETxEN, \
+       P_MII0_TxCLK, \
+       P_MII0_PHYINT, \
+       P_MII0_COL, \
+       P_MII0_ERxD0, \
+       P_MII0_ERxD1, \
+       P_MII0_ERxD2, \
+       P_MII0_ERxD3, \
+       P_MII0_ERxDV, \
+       P_MII0_ERxCLK, \
+       P_MII0_ERxER, \
+       P_MII0_CRS, \
+       P_MDC, \
+       P_MDIO, 0}
+
+#define P_RMII0 {\
+       P_MII0_ETxD0, \
+       P_MII0_ETxD1, \
+       P_MII0_ETxEN, \
+       P_MII0_ERxD0, \
+       P_MII0_ERxD1, \
+       P_MII0_ERxER, \
+       P_RMII0_REF_CLK, \
+       P_RMII0_MDINT, \
+       P_RMII0_CRS_DV, \
+       P_MDC, \
+       P_MDIO, 0}
+
+#endif                         /* _MACH_PORTMUX_H_ */
index 50b3fe55ef0c182137ea6abd11c5c3a2ee5d3d26..4e46d657e50e8ad2c07013b101d4c6c3dd85ab2e 100644 (file)
 
 /* Bit masks for HOST_STATUS */
 
-#define                     READY  0x1        /* DMA Ready */
+#define                 DMA_READY  0x1        /* DMA Ready */
 #define                  FIFOFULL  0x2        /* FIFO Full */
 #define                 FIFOEMPTY  0x4        /* FIFO Empty */
 #define              DMA_COMPLETE  0x8        /* DMA Complete */
index e2632db74baa4605c2594872f4047a37ae32a543..1d365c844ffe54889bc3f547e5b38bb3ac6bb50e 100644 (file)
 /* Debug/MP/Emulation Registers (0xFFC00014 - 0xFFC00014) */
 
 #define                           CHIPID  0xffc00014
+/* CHIPID Masks */
+#define                   CHIPID_VERSION  0xF0000000
+#define                    CHIPID_FAMILY  0x0FFFF000
+#define               CHIPID_MANUFACTURE  0x00000FFE
 
 /* System Reset and Interrupt Controller (0xFFC00100 - 0xFFC00104) */
 
 
 #define                       MFD  0xf000     /* Multi channel Frame Delay */
 #define                      FSDR  0x80       /* Frame Sync to Data Relationship */
-#define                     MCMEM  0x10       /* Multi channel Frame Mode Enable */
+#define                  MCMEN  0x10       /* Multi channel Frame Mode Enable */
 #define                   MCDRXPE  0x8        /* Multi channel DMA Receive Packing */
 #define                   MCDTXPE  0x4        /* Multi channel DMA Transmit Packing */
 #define                     MCCRM  0x3        /* 2X Clock Recovery Mode */
index 14cb10cc24ae587cce7ec774ce57767e8f37cde3..4d97d3aa97cd938f5db367cfd84f28eaa742a3ae 100644 (file)
@@ -70,5 +70,5 @@
 #define MAX_BLACKFIN_DMA_CHANNEL 32
 
 extern int channel2irq(unsigned int channel);
-extern struct dma_register *base_addr[];
+extern struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL];
 #endif
index 6bb3e0d4705db8ab8234524a0e757cb22f6acc12..c571e958558cde4876c663a7a084ffa74883f489 100644 (file)
@@ -104,13 +104,13 @@ unsigned long get_wchan(struct task_struct *p);
 #define cpu_relax()            barrier()
 
 /* Get the Silicon Revision of the chip */
-static inline __attribute_pure__ uint32_t bfin_revid(void)
+static inline uint32_t __pure bfin_revid(void)
 {
        /* stored in the upper 4 bits */
        return bfin_read_CHIPID() >> 28;
 }
 
-static inline __attribute_pure__ uint32_t bfin_compiled_revid(void)
+static inline uint32_t __pure bfin_compiled_revid(void)
 {
 #if defined(CONFIG_BF_REV_0_0)
        return 0;
index 60e07b92044cdda56ec6834eba26d30f2f153f80..04f448711cd09eb1755875b87bfe2db353aff15f 100644 (file)
@@ -4,7 +4,10 @@
 #include <linux/mm.h>
 
 struct scatterlist {
-       struct page *page;
+#ifdef CONFIG_DEBUG_SG
+       unsigned long sg_magic;
+#endif
+       unsigned long page_link;
        unsigned int offset;
        dma_addr_t dma_address;
        unsigned int length;
@@ -17,7 +20,6 @@ struct scatterlist {
  * returns, or alternatively stop on the first sg_dma_len(sg) which
  * is 0.
  */
-#define sg_address(sg) (page_address((sg)->page) + (sg)->offset)
 #define sg_dma_address(sg)      ((sg)->dma_address)
 #define sg_dma_len(sg)          ((sg)->length)
 
index 2b3d47d0bbb692f62d9242adba7adec523cc0723..4a927379ee1ce9c5fdc006fe2a3bbed851f3d1eb 100644 (file)
@@ -128,9 +128,7 @@ extern unsigned long irq_flags;
 #define mb()   asm volatile (""   : : :"memory")
 #define rmb()  asm volatile (""   : : :"memory")
 #define wmb()  asm volatile (""   : : :"memory")
-#define set_rmb(var, value)    do { (void) xchg(&var, value); } while (0)
-#define set_mb(var, value)     set_rmb(var, value)
-#define set_wmb(var, value)    do { var = value; wmb(); } while (0)
+#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
 
 #define read_barrier_depends()                 do { } while(0)
 
index 10a07ba1e011b6f66bff7d34931d9fe97a2d31d1..277b400924b86f9c647e25b9d837fe4353cd643b 100644 (file)
@@ -53,10 +53,4 @@ static inline void flush_tlb_kernel_page(unsigned long addr)
        BUG();
 }
 
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-                                     unsigned long start, unsigned long end)
-{
-       BUG();
-}
-
 #endif
index 6590f657500dc1c6e7b1d3cd5e6eec265471dacb..11296170d057cf96abcced2b328874f963239f33 100644 (file)
@@ -54,7 +54,7 @@ static inline unsigned long ide_default_io_base(int index)
 #define SUPPORT_VLB_SYNC 0
 
 #define IDE_ARCH_ACK_INTR
-#define ide_ack_intr(hwif)     (hwif)->hw.ack_intr(hwif)
+#define ide_ack_intr(hwif)     ((hwif)->ack_intr(hwif))
 
 #endif /* __KERNEL__ */
 
index a569065113d916671f7562c946a8c7690de60fd7..e2f49c27ed297ab40dc7187de1639809fa1c9640 100644 (file)
 /* Currently this is unsuitable for consumption outside the kernel.  */
 #ifdef __KERNEL__ 
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <asm/arch/bitops.h>
 #include <asm/system.h>
 #include <asm/atomic.h>
@@ -154,6 +158,7 @@ static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
 #include <asm-generic/bitops/fls64.h>
 #include <asm-generic/bitops/hweight.h>
 #include <asm-generic/bitops/find.h>
+#include <asm-generic/bitops/lock.h>
 
 #include <asm-generic/bitops/ext2-non-atomic.h>
 
index 7b9ed22ab5dd6accf38fc93f79dc461c04cfdb08..92000d0c3f9753a645fdf14dbfd875cd22e9b91b 100644 (file)
@@ -52,7 +52,7 @@ typedef struct {
 } __kernel_fsid_t;
 
 #ifdef __KERNEL__
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 
 #undef __FD_SET
 #define __FD_SET(fd,fdsetp) set_bit(fd, (void *)(fdsetp))
index 4bdc44c4ac3d74a1477dc8654dc1f3f78b3ea5a1..faff53ad1f96cd56327caf8c182ad70c81fc161f 100644 (file)
@@ -2,11 +2,14 @@
 #define __ASM_CRIS_SCATTERLIST_H
 
 struct scatterlist {
+#ifdef CONFIG_DEBUG_SG
+       unsigned long sg_magic;
+#endif
        char *  address;    /* Location data is to be transferred to */
        unsigned int length;
 
        /* The following is i386 highmem junk - not used by us */
-       struct page * page; /* Location for highmem page, if any */
+       unsigned long page_link;
        unsigned int offset;/* for highmem, page offset */
 
 };
index 0569612477e3eddc1df7cbd7132b5238f19a14be..20697e7ef4f2091d594bb187b512cba4f4b88017 100644 (file)
@@ -38,13 +38,6 @@ static inline void flush_tlb_range(struct vm_area_struct * vma, unsigned long st
        flush_tlb_mm(vma->vm_mm);
 }
 
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-                                      unsigned long start, unsigned long end)
-{
-        /* CRIS does not keep any page table caches in TLB */
-}
-
-
 static inline void flush_tlb(void)
 {
        flush_tlb_mm(current->mm);
index f8560edf59ff8f30859b78c7142f461803bee1ee..e29de7131b79dcca7250aad73b3d603fb1f53458 100644 (file)
 
 #ifdef __KERNEL__
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <asm-generic/bitops/ffz.h>
 
 /*
@@ -302,6 +306,7 @@ int __ilog2_u64(u64 n)
 
 #include <asm-generic/bitops/sched.h>
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 
 #include <asm-generic/bitops/ext2-non-atomic.h>
 
index 8e827fa853f15b7f47742a8dd31624e02b6cfcff..99ba76edc42a4c94a333571e9c5c1d2658e465ca 100644 (file)
@@ -4,25 +4,28 @@
 #include <asm/types.h>
 
 /*
- * Drivers must set either ->address or (preferred) ->page and ->offset
+ * Drivers must set either ->address or (preferred) page and ->offset
  * to indicate where data must be transferred to/from.
  *
- * Using ->page is recommended since it handles highmem data as well as
+ * Using page is recommended since it handles highmem data as well as
  * low mem. ->address is restricted to data which has a virtual mapping, and
- * it will go away in the future. Updating to ->page can be automated very
+ * it will go away in the future. Updating to page can be automated very
  * easily -- something like
  *
  * sg->address = some_ptr;
  *
  * can be rewritten as
  *
- * sg->page = virt_to_page(some_ptr);
+ * sg_set_page(virt_to_page(some_ptr));
  * sg->offset = (unsigned long) some_ptr & ~PAGE_MASK;
  *
  * and that's it. There's no excuse for not highmem enabling YOUR driver. /jens
  */
 struct scatterlist {
-       struct page     *page;          /* Location for highmem page, if any */
+#ifdef CONFIG_DEBUG_SG
+       unsigned long   sg_magic;
+#endif
+       unsigned long   page_link;
        unsigned int    offset;         /* for highmem, page offset */
 
        dma_addr_t      dma_address;
index 8370f97e41ee57d0c782592db6f5d27263eac7f1..7ac5eafc5d9839c34c23c459075aa8c8b450629c 100644 (file)
@@ -57,7 +57,6 @@ do {                                                          \
 #define __flush_tlb_global()                   flush_tlb_all()
 #define flush_tlb()                            flush_tlb_all()
 #define flush_tlb_kernel_range(start, end)     flush_tlb_all()
-#define flush_tlb_pgtables(mm,start,end)       do { } while(0)
 
 #else
 
@@ -66,7 +65,6 @@ do {                                                          \
 #define flush_tlb_mm(mm)                       BUG()
 #define flush_tlb_page(vma,addr)               BUG()
 #define flush_tlb_range(mm,start,end)          BUG()
-#define flush_tlb_pgtables(mm,start,end)       BUG()
 #define flush_tlb_kernel_range(start, end)     BUG()
 
 #endif
index 1f9d99193df8ef368c70d8abb18ddcf3a885f91a..15e6f253dda4090622d93c0d688e4350da4411ad 100644 (file)
 
 #ifdef __KERNEL__
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <asm-generic/bitops/sched.h>
 #include <asm-generic/bitops/ffs.h>
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 
 #include <asm-generic/bitops/ext2-non-atomic.h>
 #include <asm-generic/bitops/ext2-atomic.h>
index cd8a9641bd668e5e0ae2da5bebac5d1e7bf8704f..4657f3e410fce4a71ca7e7903f97e92a92676bd9 100644 (file)
@@ -3,9 +3,6 @@
 
 #include <asm/types.h>
 
-#define BITOP_MASK(nr)         (1UL << ((nr) % BITS_PER_LONG))
-#define BITOP_WORD(nr)         ((nr) / BITS_PER_LONG)
-
 #ifdef CONFIG_SMP
 #include <asm/spinlock.h>
 #include <asm/cache.h>         /* we use L1_CACHE_BYTES */
@@ -66,8 +63,8 @@ extern raw_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned;
  */
 static inline void set_bit(int nr, volatile unsigned long *addr)
 {
-       unsigned long mask = BITOP_MASK(nr);
-       unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+       unsigned long mask = BIT_MASK(nr);
+       unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
        unsigned long flags;
 
        _atomic_spin_lock_irqsave(p, flags);
@@ -87,8 +84,8 @@ static inline void set_bit(int nr, volatile unsigned long *addr)
  */
 static inline void clear_bit(int nr, volatile unsigned long *addr)
 {
-       unsigned long mask = BITOP_MASK(nr);
-       unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+       unsigned long mask = BIT_MASK(nr);
+       unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
        unsigned long flags;
 
        _atomic_spin_lock_irqsave(p, flags);
@@ -108,8 +105,8 @@ static inline void clear_bit(int nr, volatile unsigned long *addr)
  */
 static inline void change_bit(int nr, volatile unsigned long *addr)
 {
-       unsigned long mask = BITOP_MASK(nr);
-       unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+       unsigned long mask = BIT_MASK(nr);
+       unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
        unsigned long flags;
 
        _atomic_spin_lock_irqsave(p, flags);
@@ -128,8 +125,8 @@ static inline void change_bit(int nr, volatile unsigned long *addr)
  */
 static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
 {
-       unsigned long mask = BITOP_MASK(nr);
-       unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+       unsigned long mask = BIT_MASK(nr);
+       unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
        unsigned long old;
        unsigned long flags;
 
@@ -152,8 +149,8 @@ static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
  */
 static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
 {
-       unsigned long mask = BITOP_MASK(nr);
-       unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+       unsigned long mask = BIT_MASK(nr);
+       unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
        unsigned long old;
        unsigned long flags;
 
@@ -175,8 +172,8 @@ static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
  */
 static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
 {
-       unsigned long mask = BITOP_MASK(nr);
-       unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+       unsigned long mask = BIT_MASK(nr);
+       unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
        unsigned long old;
        unsigned long flags;
 
diff --git a/include/asm-generic/bitops/lock.h b/include/asm-generic/bitops/lock.h
new file mode 100644 (file)
index 0000000..308a9e2
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef _ASM_GENERIC_BITOPS_LOCK_H_
+#define _ASM_GENERIC_BITOPS_LOCK_H_
+
+/**
+ * test_and_set_bit_lock - Set a bit and return its old value, for lock
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is atomic and provides acquire barrier semantics.
+ * It can be used to implement bit locks.
+ */
+#define test_and_set_bit_lock(nr, addr)        test_and_set_bit(nr, addr)
+
+/**
+ * clear_bit_unlock - Clear a bit in memory, for unlock
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * This operation is atomic and provides release barrier semantics.
+ */
+#define clear_bit_unlock(nr, addr)     \
+do {                                   \
+       smp_mb__before_clear_bit();     \
+       clear_bit(nr, addr);            \
+} while (0)
+
+/**
+ * __clear_bit_unlock - Clear a bit in memory, for unlock
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * This operation is like clear_bit_unlock, however it is not atomic.
+ * It does provide release barrier semantics so it can be used to unlock
+ * a bit lock, however it would only be used if no other CPU can modify
+ * any bits in the memory until the lock is released (a good example is
+ * if the bit lock itself protects access to the other bits in the word).
+ */
+#define __clear_bit_unlock(nr, addr)   \
+do {                                   \
+       smp_mb();                       \
+       __clear_bit(nr, addr);          \
+} while (0)
+
+#endif /* _ASM_GENERIC_BITOPS_LOCK_H_ */
+
index 46a825cf2ae12c5723106a098dc3228de1339df4..697cc2b7e0f0d90189aa3e1e9d6d8c8c44bb42be 100644 (file)
@@ -3,9 +3,6 @@
 
 #include <asm/types.h>
 
-#define BITOP_MASK(nr)         (1UL << ((nr) % BITS_PER_LONG))
-#define BITOP_WORD(nr)         ((nr) / BITS_PER_LONG)
-
 /**
  * __set_bit - Set a bit in memory
  * @nr: the bit to set
  */
 static inline void __set_bit(int nr, volatile unsigned long *addr)
 {
-       unsigned long mask = BITOP_MASK(nr);
-       unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+       unsigned long mask = BIT_MASK(nr);
+       unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
 
        *p  |= mask;
 }
 
 static inline void __clear_bit(int nr, volatile unsigned long *addr)
 {
-       unsigned long mask = BITOP_MASK(nr);
-       unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+       unsigned long mask = BIT_MASK(nr);
+       unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
 
        *p &= ~mask;
 }
@@ -42,8 +39,8 @@ static inline void __clear_bit(int nr, volatile unsigned long *addr)
  */
 static inline void __change_bit(int nr, volatile unsigned long *addr)
 {
-       unsigned long mask = BITOP_MASK(nr);
-       unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+       unsigned long mask = BIT_MASK(nr);
+       unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
 
        *p ^= mask;
 }
@@ -59,8 +56,8 @@ static inline void __change_bit(int nr, volatile unsigned long *addr)
  */
 static inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
 {
-       unsigned long mask = BITOP_MASK(nr);
-       unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+       unsigned long mask = BIT_MASK(nr);
+       unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
        unsigned long old = *p;
 
        *p = old | mask;
@@ -78,8 +75,8 @@ static inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
  */
 static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
 {
-       unsigned long mask = BITOP_MASK(nr);
-       unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+       unsigned long mask = BIT_MASK(nr);
+       unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
        unsigned long old = *p;
 
        *p = old & ~mask;
@@ -90,8 +87,8 @@ static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
 static inline int __test_and_change_bit(int nr,
                                            volatile unsigned long *addr)
 {
-       unsigned long mask = BITOP_MASK(nr);
-       unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+       unsigned long mask = BIT_MASK(nr);
+       unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
        unsigned long old = *p;
 
        *p = old ^ mask;
@@ -105,7 +102,7 @@ static inline int __test_and_change_bit(int nr,
  */
 static inline int test_bit(int nr, const volatile unsigned long *addr)
 {
-       return 1UL & (addr[BITOP_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
+       return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
 }
 
 #endif /* _ASM_GENERIC_BITOPS_NON_ATOMIC_H_ */
index 5615440027ec545b069f6477e61d85273b4a674a..9f584cc5c5fb48f9491b1cdbe8ceca5e01d844ca 100644 (file)
 /* .data section */
 #define DATA_DATA                                                      \
        *(.data)                                                        \
-       *(.data.init.refok)
+       *(.data.init.refok)                                             \
+       . = ALIGN(8);                                                   \
+       VMLINUX_SYMBOL(__start___markers) = .;                          \
+       *(__markers)                                                    \
+       VMLINUX_SYMBOL(__stop___markers) = .;
 
 #define RO_DATA(align)                                                 \
        . = ALIGN((align));                                             \
@@ -20,6 +24,7 @@
                VMLINUX_SYMBOL(__start_rodata) = .;                     \
                *(.rodata) *(.rodata.*)                                 \
                *(__vermagic)           /* Kernel version magic */      \
+               *(__markers_strings)    /* Markers: strings */          \
        }                                                               \
                                                                        \
        .rodata1          : AT(ADDR(.rodata1) - LOAD_OFFSET) {          \
index d76299c98b817ad0c492a276f79262bb22fea8d8..cb18e3b0aa948520b8f7321e6ead3d00eb1d5cf2 100644 (file)
 #include <asm/system.h>
 
 #ifdef __KERNEL__
+
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 /*
  * Function prototypes to keep gcc -Wall happy
  */
@@ -194,6 +199,7 @@ static __inline__ unsigned long __ffs(unsigned long word)
 #include <asm-generic/bitops/find.h>
 #include <asm-generic/bitops/sched.h>
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 #include <asm-generic/bitops/ext2-non-atomic.h>
 #include <asm-generic/bitops/ext2-atomic.h>
 #include <asm-generic/bitops/minix.h>
index 985fdf54eacad5c49d39f5082b9807456f18603b..d3ecdd87ac90b0ca8642d6d38886f6afc14a56fe 100644 (file)
@@ -4,7 +4,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-       struct page     *page;
+#ifdef CONFIG_DEBUG_SG
+       unsigned long   sg_magic;
+#endif
+       unsigned long   page_link;
        unsigned int    offset;
        dma_addr_t      dma_address;
        unsigned int    length;
index 7807018f85002cd201db14dc74926f469b3c11b5..2c1e83f7b4191568bcb1880cc5f423c7bdaa3773 100644 (file)
@@ -82,8 +82,7 @@ asmlinkage void resume(void);
 #define mb()   asm volatile (""   : : :"memory")
 #define rmb()  asm volatile (""   : : :"memory")
 #define wmb()  asm volatile (""   : : :"memory")
-#define set_rmb(var, value)    do { xchg(&var, value); } while (0)
-#define set_mb(var, value)     set_rmb(var, value)
+#define set_mb(var, value) do { xchg(&var, value); } while (0)
 
 #ifdef CONFIG_SMP
 #define smp_mb()       mb()
index 9a2c5c9fd700346ef514f37c57edba3f68a0dd57..41c148a9208ee202c74ab4f1ea7c444388d5a493 100644 (file)
@@ -52,10 +52,4 @@ static inline void flush_tlb_kernel_page(unsigned long addr)
        BUG();
 }
 
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-                                     unsigned long start, unsigned long end)
-{
-       BUG();
-}
-
 #endif /* _H8300_TLBFLUSH_H */
index 6cc517e212a92ee94e461c2e1944f3fe9af0c627..a977affaebeca34b02b1e9bb991f4ad83cd35281 100644 (file)
@@ -9,6 +9,10 @@
  * O(1) scheduler patch
  */
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <linux/compiler.h>
 #include <linux/types.h>
 #include <asm/intrinsics.h>
@@ -93,6 +97,38 @@ clear_bit (int nr, volatile void *addr)
        } while (cmpxchg_acq(m, old, new) != old);
 }
 
+/**
+ * clear_bit_unlock - Clears a bit in memory with release
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ *
+ * clear_bit_unlock() is atomic and may not be reordered.  It does
+ * contain a memory barrier suitable for unlock type operations.
+ */
+static __inline__ void
+clear_bit_unlock (int nr, volatile void *addr)
+{
+       __u32 mask, old, new;
+       volatile __u32 *m;
+       CMPXCHG_BUGCHECK_DECL
+
+       m = (volatile __u32 *) addr + (nr >> 5);
+       mask = ~(1 << (nr & 31));
+       do {
+               CMPXCHG_BUGCHECK(m);
+               old = *m;
+               new = old & mask;
+       } while (cmpxchg_rel(m, old, new) != old);
+}
+
+/**
+ * __clear_bit_unlock - Non-atomically clear a bit with release
+ *
+ * This is like clear_bit_unlock, but the implementation may use a non-atomic
+ * store (this one uses an atomic, however).
+ */
+#define __clear_bit_unlock clear_bit_unlock
+
 /**
  * __clear_bit - Clears a bit in memory (non-atomic version)
  */
@@ -169,6 +205,15 @@ test_and_set_bit (int nr, volatile void *addr)
        return (old & bit) != 0;
 }
 
+/**
+ * test_and_set_bit_lock - Set a bit and return its old value for lock
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This is the same as test_and_set_bit on ia64
+ */
+#define test_and_set_bit_lock test_and_set_bit
+
 /**
  * __test_and_set_bit - Set a bit and return its old value
  * @nr: Bit to set
index 4906916d715b5d3ea95d53659218234afe0f42f3..afcfbda76e20f3f5914b579d16e0dae9c7f83249 100644 (file)
@@ -7,8 +7,8 @@
  */
 
 #include <linux/page-flags.h>
+#include <linux/bitops.h>
 
-#include <asm/bitops.h>
 #include <asm/page.h>
 
 /*
index e928675de352b08f06799442fd9761ab0c341ea6..1ccf23809329e28b15be6c5967e697ef2b75014b 100644 (file)
@@ -46,7 +46,6 @@ static inline unsigned long ide_default_io_base(int index)
        }
 }
 
-#define IDE_ARCH_OBSOLETE_INIT
 #define ide_default_io_ctl(base)       ((base) + 0x206) /* obsolete */
 
 #ifdef CONFIG_PCI
index 3a62878e84f3f9d1d0e3310302bf4b773f490261..f93308f54b615ea673a669db653beca9c18c4ae6 100644 (file)
@@ -35,7 +35,7 @@ extern void find_memory (void);
 extern void reserve_memory (void);
 extern void find_initrd (void);
 extern int filter_rsvd_memory (unsigned long start, unsigned long end, void *arg);
-extern void efi_memmap_init(unsigned long *, unsigned long *);
+extern unsigned long efi_memmap_init(unsigned long *s, unsigned long *e);
 extern int find_max_min_low_pfn (unsigned long , unsigned long, void *);
 
 extern unsigned long vmcore_find_descriptor_size(unsigned long address);
index 0971ec90807e77201f2b77b93533c1ab7254341f..e6204f14f6142222cc3b7b06d469ffbf5a1d4a6e 100644 (file)
 # ifndef __ASSEMBLY__
 
 #include <linux/sched.h>       /* for mm_struct */
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 #include <asm/cacheflush.h>
 #include <asm/mmu_context.h>
 #include <asm/processor.h>
index 7d5234d50312d4cbf784c6d3b51a6eda93923194..d6f57874041d0f80e351dcfeafb27aed21d755a8 100644 (file)
@@ -9,7 +9,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-       struct page *page;
+#ifdef CONFIG_DEBUG_SG
+       unsigned long sg_magic;
+#endif
+       unsigned long page_link;
        unsigned int offset;
        unsigned int length;    /* buffer length */
 
index 1703c9d885bd0723b186f2ca8a673741b1d666cf..471cc2ee9ac4c10be30a3b6d772f53912593d90e 100644 (file)
@@ -14,8 +14,8 @@
 #include <linux/threads.h>
 #include <linux/kernel.h>
 #include <linux/cpumask.h>
+#include <linux/bitops.h>
 
-#include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/param.h>
 #include <asm/processor.h>
index ff857e31738a00dfbed4534ee1832528e231fb33..0229fb95fb3824f657452dc4adbd1bd4e52c48e1 100644 (file)
@@ -11,9 +11,9 @@
 
 #include <linux/compiler.h>
 #include <linux/kernel.h>
+#include <linux/bitops.h>
 
 #include <asm/atomic.h>
-#include <asm/bitops.h>
 #include <asm/intrinsics.h>
 #include <asm/system.h>
 
index e37f9fbf33af8babd7406b648219a1dca48bc152..80bcb0a38e8adfbb7022ea9fff1a8e0f08534cc8 100644 (file)
@@ -83,19 +83,6 @@ flush_tlb_page (struct vm_area_struct *vma, unsigned long addr)
 #endif
 }
 
-/*
- * Flush the TLB entries mapping the virtually mapped linear page
- * table corresponding to address range [START-END).
- */
-static inline void
-flush_tlb_pgtables (struct mm_struct *mm, unsigned long start, unsigned long end)
-{
-       /*
-        * Deprecated.  The virtual page table is now flushed via the normal gather/flush
-        * interface (see tlb.h).
-        */
-}
-
 /*
  * Flush the local TLB. Invoked from another cpu using an IPI.
  */
index 66ab672162cdc42b8f2b5725d64508e07aea1fb6..6dc9b81bf9f36544eeacfee071866629f220ce5c 100644 (file)
  *    Copyright (C) 2004  Hirokazu Takata <takata at linux-m32r.org>
  */
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <linux/compiler.h>
 #include <asm/assembler.h>
 #include <asm/system.h>
@@ -255,6 +259,7 @@ static __inline__ int test_and_change_bit(int nr, volatile void * addr)
 #include <asm-generic/bitops/find.h>
 #include <asm-generic/bitops/ffs.h>
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 
 #endif /* __KERNEL__ */
 
index 4672a49e8760546f3b835d627359b9c0d62fd418..5d2044e529abc0e562a8eee0338e70c06834eed8 100644 (file)
@@ -65,7 +65,6 @@ static __inline__ unsigned long ide_default_io_base(int index)
        }
 }
 
-#define IDE_ARCH_OBSOLETE_INIT
 #define ide_default_io_ctl(base)       ((base) + 0x206) /* obsolete */
 
 #ifdef CONFIG_BLK_DEV_IDEPCI
index 92d7266783fd1b9486818d678f1ae20d82090f06..86505387be0872b305cefdaa89796e3f67d04548 100644 (file)
@@ -21,9 +21,9 @@
 #ifndef __ASSEMBLY__
 
 #include <linux/threads.h>
+#include <linux/bitops.h>
 #include <asm/processor.h>
 #include <asm/addrspace.h>
-#include <asm/bitops.h>
 #include <asm/page.h>
 
 struct mm_struct;
index 352415ff5eb909837d80cd69118aa30e4f673bd6..1ed372c73d0bd9ef05f143289ccecc77cbc3ada5 100644 (file)
@@ -4,9 +4,12 @@
 #include <asm/types.h>
 
 struct scatterlist {
+#ifdef CONFIG_DEBUG_SG
+    unsigned long sg_magic;
+#endif
     char *  address;    /* Location data is to be transferred to, NULL for
                          * highmem page */
-    struct page * page; /* Location for highmem page, if any */
+    unsigned long page_link;
     unsigned int offset;/* for highmem, page offset */
 
     dma_addr_t dma_address;
index 3d37ac002bcc6e2a9329de1df0a644297aee9249..0ef95307784e0d9143cba8d2608d9f6cada5ca11 100644 (file)
@@ -12,7 +12,6 @@
  *  - flush_tlb_page(vma, vmaddr) flushes one page
  *  - flush_tlb_range(vma, start, end) flushes a range of pages
  *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
- *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
  */
 
 extern void local_flush_tlb_all(void);
@@ -93,8 +92,6 @@ static __inline__ void __flush_tlb_all(void)
        );
 }
 
-#define flush_tlb_pgtables(mm, start, end)     do { } while (0)
-
 extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
 
 #endif /* _ASM_M32R_TLBFLUSH_H */
index 1a61fdb56aaf671dc82e669d009d6fb6f3e64324..2976b5d68e96cbb5189cb1a348312939a699dab8 100644 (file)
@@ -8,6 +8,10 @@
  * for more details.
  */
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <linux/compiler.h>
 
 /*
@@ -314,6 +318,7 @@ static inline int fls(int x)
 #include <asm-generic/bitops/fls64.h>
 #include <asm-generic/bitops/sched.h>
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 
 /* Bitmap functions for the minix filesystem */
 
index f9ffb2cbbae826c571d0feaeee632b2eac68b5f5..909c6dfd3851169dae42ac87613a70fc912ece34 100644 (file)
@@ -137,7 +137,7 @@ ide_get_lock(irq_handler_t handler, void *data)
 #endif /* CONFIG_BLK_DEV_FALCON_IDE */
 
 #define IDE_ARCH_ACK_INTR
-#define ide_ack_intr(hwif)     ((hwif)->hw.ack_intr ? (hwif)->hw.ack_intr(hwif) : 1)
+#define ide_ack_intr(hwif)     ((hwif)->ack_intr ? (hwif)->ack_intr(hwif) : 1)
 
 #endif /* __KERNEL__ */
 #endif /* _M68K_IDE_H */
index 24887a2d9c7bd09290b6980fee23e4a1d74090fa..d3a7a0edfecab3d9ad3a04cc3e936cf1ca9faf50 100644 (file)
@@ -4,7 +4,10 @@
 #include <linux/types.h>
 
 struct scatterlist {
-       struct page *page;
+#ifdef CONFIG_DEBUG_SG
+       unsigned long sg_magic;
+#endif
+       unsigned long page_link;
        unsigned int offset;
        unsigned int length;
 
index 31678831ee470cb8409e5d24c194704a82943d02..17707ec315e2b0a93466aec670259e22befd23f4 100644 (file)
@@ -92,11 +92,6 @@ static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end
        flush_tlb_all();
 }
 
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-                                     unsigned long start, unsigned long end)
-{
-}
-
 #else
 
 
@@ -219,11 +214,6 @@ static inline void flush_tlb_kernel_page (unsigned long addr)
        sun3_put_segmap (addr & ~(SUN3_PMEG_SIZE - 1), SUN3_INVALID_PMEG);
 }
 
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-                                     unsigned long start, unsigned long end)
-{
-}
-
 #endif
 
 #endif /* _M68K_TLBFLUSH_H */
index 7d6075d9b5cb8998faa785d68a8392dd2115ab00..f8dfb7ba2e2573566a58cf97d01942adc48d4785 100644 (file)
 
 #ifdef __KERNEL__
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <asm-generic/bitops/ffs.h>
 #include <asm-generic/bitops/__ffs.h>
 #include <asm-generic/bitops/sched.h>
@@ -160,6 +164,7 @@ static __inline__ int __test_bit(int nr, const volatile unsigned long * addr)
 
 #include <asm-generic/bitops/find.h>
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 
 static __inline__ int ext2_set_bit(int nr, volatile void * addr)
 {
index 57e95cc01ad51a151dacce5cc69fc31b7bd2d2fa..2e45ab50b232c89b484caf7dfa697d37c5f2d73b 100644 (file)
@@ -1 +1,11 @@
-#include <asm-m68k/module.h>
+#ifndef ASM_M68KNOMMU_MODULE_H
+#define ASM_M68KNOMMU_MODULE_H
+
+struct mod_arch_specific {
+};
+
+#define Elf_Shdr Elf32_Shdr
+#define Elf_Sym Elf32_Sym
+#define Elf_Ehdr Elf32_Ehdr
+
+#endif /* ASM_M68KNOMMU_MODULE_H */
index 4da79d3d3f34d03f07c7b34529f4e30502e2e3bf..afc4788b0d2c2f2a9c629c3836ab5d6b0c88e7e8 100644 (file)
@@ -5,13 +5,15 @@
 #include <asm/types.h>
 
 struct scatterlist {
-       struct page     *page;
+#ifdef CONFIG_DEBUG_SG
+       unsigned long   sg_magic;
+#endif
+       unsigned long   page_link;
        unsigned int    offset;
        dma_addr_t      dma_address;
        unsigned int    length;
 };
 
-#define sg_address(sg)         (page_address((sg)->page) + (sg)->offset)
 #define sg_dma_address(sg)      ((sg)->dma_address)
 #define sg_dma_len(sg)          ((sg)->length)
 
index 1bd1142685e18f5dd916c0dcf838fe1e3c2435df..15b4c7d45c94a643865b511040cff2e5dcd0e04a 100644 (file)
@@ -104,8 +104,7 @@ asmlinkage void resume(void);
 #define mb()   asm volatile (""   : : :"memory")
 #define rmb()  asm volatile (""   : : :"memory")
 #define wmb()  asm volatile (""   : : :"memory")
-#define set_rmb(var, value)    do { xchg(&var, value); } while (0)
-#define set_mb(var, value)     set_rmb(var, value)
+#define set_mb(var, value) do { xchg(&var, value); } while (0)
 
 #ifdef CONFIG_SMP
 #define smp_mb()       mb()
index de858db28b00584a529ab81229559da8a2ad6b03..a470cfb803eba31bccfb27a8d28f3eb6bceaa91e 100644 (file)
@@ -52,10 +52,4 @@ static inline void flush_tlb_kernel_page(unsigned long addr)
        BUG();
 }
 
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-                                     unsigned long start, unsigned long end)
-{
-       BUG();
-}
-
 #endif /* _M68KNOMMU_TLBFLUSH_H */
index 9ed9169a88491f05b7abf3958723095f0922963c..68bbe9b312f149e5286068a90bbe59310176747b 100644 (file)
@@ -170,10 +170,12 @@ static inline long strnlen_user(const char *src, long n)
  */
 
 static inline unsigned long
-clear_user(void *to, unsigned long n)
+__clear_user(void *to, unsigned long n)
 {
        memset(to, 0, n);
        return 0;
 }
 
+#define        clear_user(to,n)        __clear_user(to,n)
+
 #endif /* _M68KNOMMU_UACCESS_H */
index 899357a72ac4e15faab61c77a89ae20e34e9dcc5..ec75ce4cdb8c3e90307e51350c2d7dc4b950a4d5 100644 (file)
@@ -9,6 +9,10 @@
 #ifndef _ASM_BITOPS_H
 #define _ASM_BITOPS_H
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <linux/compiler.h>
 #include <linux/irqflags.h>
 #include <linux/types.h>
@@ -171,6 +175,20 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
        }
 }
 
+/*
+ * clear_bit_unlock - Clears a bit in memory
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ *
+ * clear_bit() is atomic and implies release semantics before the memory
+ * operation. It can be used for an unlock.
+ */
+static inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *addr)
+{
+       smp_mb__before_clear_bit();
+       clear_bit(nr, addr);
+}
+
 /*
  * change_bit - Toggle a bit in memory
  * @nr: Bit to change
@@ -240,6 +258,8 @@ static inline int test_and_set_bit(unsigned long nr,
        unsigned short bit = nr & SZLONG_MASK;
        unsigned long res;
 
+       smp_llsc_mb();
+
        if (cpu_has_llsc && R10000_LLSC_WAR) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
                unsigned long temp;
@@ -294,6 +314,73 @@ static inline int test_and_set_bit(unsigned long nr,
        return res != 0;
 }
 
+/*
+ * test_and_set_bit_lock - Set a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is atomic and implies acquire ordering semantics
+ * after the memory operation.
+ */
+static inline int test_and_set_bit_lock(unsigned long nr,
+       volatile unsigned long *addr)
+{
+       unsigned short bit = nr & SZLONG_MASK;
+       unsigned long res;
+
+       if (cpu_has_llsc && R10000_LLSC_WAR) {
+               unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
+               unsigned long temp;
+
+               __asm__ __volatile__(
+               "       .set    mips3                                   \n"
+               "1:     " __LL "%0, %1          # test_and_set_bit      \n"
+               "       or      %2, %0, %3                              \n"
+               "       " __SC  "%2, %1                                 \n"
+               "       beqzl   %2, 1b                                  \n"
+               "       and     %2, %0, %3                              \n"
+               "       .set    mips0                                   \n"
+               : "=&r" (temp), "=m" (*m), "=&r" (res)
+               : "r" (1UL << bit), "m" (*m)
+               : "memory");
+       } else if (cpu_has_llsc) {
+               unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
+               unsigned long temp;
+
+               __asm__ __volatile__(
+               "       .set    push                                    \n"
+               "       .set    noreorder                               \n"
+               "       .set    mips3                                   \n"
+               "1:     " __LL "%0, %1          # test_and_set_bit      \n"
+               "       or      %2, %0, %3                              \n"
+               "       " __SC  "%2, %1                                 \n"
+               "       beqz    %2, 2f                                  \n"
+               "        and    %2, %0, %3                              \n"
+               "       .subsection 2                                   \n"
+               "2:     b       1b                                      \n"
+               "        nop                                            \n"
+               "       .previous                                       \n"
+               "       .set    pop                                     \n"
+               : "=&r" (temp), "=m" (*m), "=&r" (res)
+               : "r" (1UL << bit), "m" (*m)
+               : "memory");
+       } else {
+               volatile unsigned long *a = addr;
+               unsigned long mask;
+               unsigned long flags;
+
+               a += nr >> SZLONG_LOG;
+               mask = 1UL << bit;
+               raw_local_irq_save(flags);
+               res = (mask & *a);
+               *a |= mask;
+               raw_local_irq_restore(flags);
+       }
+
+       smp_llsc_mb();
+
+       return res != 0;
+}
 /*
  * test_and_clear_bit - Clear a bit and return its old value
  * @nr: Bit to clear
@@ -308,6 +395,8 @@ static inline int test_and_clear_bit(unsigned long nr,
        unsigned short bit = nr & SZLONG_MASK;
        unsigned long res;
 
+       smp_llsc_mb();
+
        if (cpu_has_llsc && R10000_LLSC_WAR) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
                unsigned long temp;
@@ -396,6 +485,8 @@ static inline int test_and_change_bit(unsigned long nr,
        unsigned short bit = nr & SZLONG_MASK;
        unsigned long res;
 
+       smp_llsc_mb();
+
        if (cpu_has_llsc && R10000_LLSC_WAR) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
                unsigned long temp;
@@ -452,6 +543,21 @@ static inline int test_and_change_bit(unsigned long nr,
 
 #include <asm-generic/bitops/non-atomic.h>
 
+/*
+ * __clear_bit_unlock - Clears a bit in memory
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ *
+ * __clear_bit() is non-atomic and implies release semantics before the memory
+ * operation. It can be used for an unlock if no other CPUs can concurrently
+ * modify other bits in the word.
+ */
+static inline void __clear_bit_unlock(unsigned long nr, volatile unsigned long *addr)
+{
+       smp_mb();
+       __clear_bit(nr, addr);
+}
+
 /*
  * Return the bit position (0..63) of the most significant 1 bit in a word
  * Returns -1 if no 1 bit exists
index 483685b1592e0f5d3a970db9cb352f10529e8745..e59d4c039661278a469df9caa5e2a74f6cee1a50 100644 (file)
 
 #include <linux/sched.h>
 #include <linux/thread_info.h>
+#include <linux/bitops.h>
 
 #include <asm/mipsregs.h>
 #include <asm/cpu.h>
 #include <asm/cpu-features.h>
 #include <asm/hazards.h>
-#include <asm/bitops.h>
 #include <asm/processor.h>
 #include <asm/current.h>
 
index 4bf8e28f8850c187e594806c8a0ab5ff18a58bdb..e64b41093c49006ef9e4752242675b9be0169c6b 100644 (file)
@@ -21,6 +21,8 @@
 #ifndef _ASM_GT64120_H
 #define _ASM_GT64120_H
 
+#include <linux/clocksource.h>
+
 #include <asm/addrspace.h>
 #include <asm/byteorder.h>
 
 #define GT_READ(ofs)           le32_to_cpu(__GT_READ(ofs))
 #define GT_WRITE(ofs, data)    __GT_WRITE(ofs, cpu_to_le32(data))
 
+extern void gt641xx_set_base_clock(unsigned int clock);
+extern int gt641xx_timer0_state(void);
+
 #endif /* _ASM_GT64120_H */
index 8f689d7df6b1c4563b02ac0d942ecdaf029e1815..affb32ce4af980e86502e9700a34da79e73503ff 100644 (file)
@@ -2,8 +2,8 @@
  *  Machine specific IO port address definition for generic.
  *  Written by Osamu Tomita <tomita@cinet.co.jp>
  */
-#ifndef _MACH_IO_PORTS_H
-#define _MACH_IO_PORTS_H
+#ifndef __ASM_I8253_H
+#define __ASM_I8253_H
 
 /* i8253A PIT registers */
 #define PIT_MODE               0x43
@@ -27,4 +27,4 @@
 
 extern void setup_pit_timer(void);
 
-#endif /* !_MACH_IO_PORTS_H */
+#endif /* __ASM_I8253_H */
index a13702fafa8580839917a7d8d963860f58971367..7c36b0e5b1c64b5879ea5546fd832de782887749 100644 (file)
@@ -17,9 +17,6 @@
  */
 #define CRIME_BASE     0x14000000      /* physical */
 
-#undef BIT
-#define BIT(x) (1UL << (x))
-
 struct sgi_crime {
        volatile unsigned long id;
 #define CRIME_ID_MASK                  0xff
index 990082c81f3957f04abab2b5f240647216bf4742..d08d7c6721394ea269eb0f41c29da264b3638a70 100644 (file)
@@ -17,9 +17,6 @@
  */
 #define MACE_BASE      0x1f000000      /* physical */
 
-#undef BIT
-#define BIT(x) (1UL << (x))
-
 /*
  * PCI interface
  */
index a77128362a7d392d512f082bcf89daaced8fd51c..4ec2b930dfbb3ec565abe1978a4f896ccaeea6e7 100644 (file)
@@ -98,7 +98,6 @@ static __inline__ unsigned long ide_default_io_base(int index)
        }
 }
 
-#define IDE_ARCH_OBSOLETE_INIT
 #define ide_default_io_ctl(base)       ((base) + 0x206) /* obsolete */
 
 #ifdef CONFIG_BLK_DEV_IDEPCI
index c1a10314b317ccf441b6a2aba38220e35c3e117a..624d66c7f290268d08916f056d43451c124aeefc 100644 (file)
        lh      t1, KV_RO_NASID_OFFSET(t0)
        lh      t2, KV_RW_NASID_OFFSET(t0)
        MAPPED_KERNEL_SETUP_TLB
-       ARC64_TWIDDLE_PC
+
+       /*
+        * We might not get launched at the address the kernel is linked to,
+        * so we jump there.
+        */
+       PTR_LA  t0, 0f
+       jr      t0
+0:
        .endm
 
 #endif /* __ASM_MACH_IP27_KERNEL_ENTRY_H */
index b84feebf2cefdf9e523c36d516db08409f8cc832..5f4b9d4e4114febd5679202355afe7a35ba4670b 100644 (file)
@@ -538,7 +538,7 @@ typedef struct bridge_err_cmdword_s {
                 BRIDGE_ISR_PMU_ESIZE_FAULT)
 
 /*
- * List of Errors which are fatal and kill the sytem
+ * List of Errors which are fatal and kill the system
  */
 #define BRIDGE_ISR_ERROR_FATAL         \
                ((BRIDGE_ISR_XTALK_ERROR & ~BRIDGE_ISR_XREAD_REQ_TIMEOUT)|\
index 7af104c95b205ce9ef2e093ae59327c79832bbfc..83d69fe17c9f1404e481e2d2cbb22985f0be2cf5 100644 (file)
@@ -4,7 +4,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-       struct page *   page;
+#ifdef CONFIG_DEBUG_SG
+       unsigned long   sg_magic;
+#endif
+       unsigned long   page_link;
        unsigned int    offset;
        dma_addr_t      dma_address;
        unsigned int    length;
index 494aa65dcfbd670d037e3e092aa6a14cd567d481..0dad844a3b5bba8384865abb1c584e7f0adf0cf9 100644 (file)
@@ -45,13 +45,11 @@ extern unsigned int soc_type;
 extern unsigned int periph_rev;
 extern unsigned int zbbus_mhz;
 
-extern void sb1250_hpt_setup(void);
 extern void sb1250_time_init(void);
 extern void sb1250_mask_irq(int cpu, int irq);
 extern void sb1250_unmask_irq(int cpu, int irq);
 extern void sb1250_smp_finish(void);
 
-extern void bcm1480_hpt_setup(void);
 extern void bcm1480_time_init(void);
 extern void bcm1480_mask_irq(int cpu, int irq);
 extern void bcm1480_unmask_irq(int cpu, int irq);
index 4d43dbb7f8b8514bac15fea1516a4223a286b827..af081457f8473e2f3cdbb1fdc18c71b864262b8d 100644 (file)
@@ -141,8 +141,6 @@ extern unsigned int sni_brd_type;
 #define A20R_PT_TIM0_ACK        0xbc050000
 #define A20R_PT_TIM1_ACK        0xbc060000
 
-#define SNI_MIPS_IRQ_CPU_TIMER  (MIPS_CPU_IRQ_BASE+7)
-
 #define SNI_A20R_IRQ_BASE       MIPS_CPU_IRQ_BASE
 #define SNI_A20R_IRQ_TIMER      (SNI_A20R_IRQ_BASE+5)
 
index 35555bd5c52d529a0720f216be336177ceef5620..bc47af313bcd7550bca9bb532ec27152988f3dda 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/ptrace.h>
 #include <linux/rtc.h>
 #include <linux/spinlock.h>
+#include <linux/clockchips.h>
 #include <linux/clocksource.h>
 
 extern spinlock_t rtc_lock;
@@ -40,7 +41,6 @@ extern int rtc_mips_set_mmss(unsigned long);
  * mips_timer_ack may be NULL if the interrupt is self-recoverable.
  */
 extern int (*mips_timer_state)(void);
-extern void (*mips_timer_ack)(void);
 
 /*
  * High precision timer clocksource.
@@ -76,6 +76,16 @@ extern int (*perf_irq)(void);
 /*
  * Initialize the calling CPU's compare interrupt as clockevent device
  */
+#ifdef CONFIG_CEVT_R4K
 extern void mips_clockevent_init(void);
+#else
+static inline void mips_clockevent_init(void)
+{
+}
+#endif
+
+extern void clocksource_set_clock(struct clocksource *cs, unsigned int clock);
+extern void clockevent_set_clock(struct clock_event_device *cd,
+               unsigned int clock);
 
 #endif /* _ASM_TIME_H */
index 730e841fb08a82d10427d881a8fd69b6434749b0..86b21de12e91314a68c30ddf4cb6d449bca86674 100644 (file)
@@ -11,7 +11,6 @@
  *  - flush_tlb_page(vma, vmaddr) flushes one page
  *  - flush_tlb_range(vma, start, end) flushes a range of pages
  *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
- *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
  */
 extern void local_flush_tlb_all(void);
 extern void local_flush_tlb_mm(struct mm_struct *mm);
@@ -45,10 +44,4 @@ extern void flush_tlb_one(unsigned long vaddr);
 
 #endif /* CONFIG_SMP */
 
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-       unsigned long start, unsigned long end)
-{
-       /* Nothing to do on MIPS.  */
-}
-
 #endif /* __ASM_TLBFLUSH_H */
index c68e1680da0173d5754d1a1df4944120a5239e58..f88b252e419cb504a3c0938e3d99d541e2113372 100644 (file)
@@ -1 +1,3 @@
 include include/asm-generic/Kbuild.asm
+
+unifdef-y += pdc.h
index 015cb0d379bd991d42c719d32bd2111f9573b63f..f8eebcbad01f81d57e0a222d4573d9044f114e96 100644 (file)
@@ -1,6 +1,10 @@
 #ifndef _PARISC_BITOPS_H
 #define _PARISC_BITOPS_H
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <linux/compiler.h>
 #include <asm/types.h>         /* for BITS_PER_LONG/SHIFT_PER_LONG */
 #include <asm/byteorder.h>
@@ -208,6 +212,7 @@ static __inline__ int fls(int x)
 
 #include <asm-generic/bitops/fls64.h>
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 #include <asm-generic/bitops/sched.h>
 
 #endif /* __KERNEL__ */
index b27bf7aeb2564697325a3509cee430e9a39a61de..be8760fbc8ee4042ded80ff196b4f9ce70335aa0 100644 (file)
@@ -17,7 +17,6 @@
 #define MAX_HWIFS      2
 #endif
 
-#define IDE_ARCH_OBSOLETE_INIT
 #define ide_default_io_ctl(base)       ((base) + 0x206) /* obsolete */
 
 #define ide_request_irq(irq,hand,flg,dev,id)   request_irq((irq),(hand),(flg),(dev),(id))
index 95f00e11c7b495d0b54202ff3eb5d2200d3934a6..55ddb1842107b8542735a4b1032d0c49dddf81e1 100644 (file)
@@ -138,7 +138,7 @@ extern void __iomem * __ioremap(unsigned long offset, unsigned long size, unsign
 /* Most machines react poorly to I/O-space being cacheable... Instead let's
  * define ioremap() in terms of ioremap_nocache().
  */
-extern inline void __iomem * ioremap(unsigned long offset, unsigned long size)
+static inline void __iomem * ioremap(unsigned long offset, unsigned long size)
 {
        return __ioremap(offset, size, _PAGE_NO_CACHE);
 }
index f6bba4c136649e8bfb9a363388cc6d6b0d23fdc4..b59a1504fc7ae30aaa7722c0427a09d7fd2dd73f 100644 (file)
@@ -3,6 +3,8 @@
 
 #ifdef __KERNEL__
 
+#include <linux/const.h>
+
 #if defined(CONFIG_PARISC_PAGE_SIZE_4KB)
 # define PAGE_SHIFT    12
 #elif defined(CONFIG_PARISC_PAGE_SIZE_16KB)
@@ -12,7 +14,7 @@
 #else
 # error "unknown default kernel page size"
 #endif
-#define PAGE_SIZE      (1UL << PAGE_SHIFT)
+#define PAGE_SIZE      (_AC(1,UL) << PAGE_SHIFT)
 #define PAGE_MASK      (~(PAGE_SIZE-1))
 
 
index 61fbd57a83232ae5d9d7b100d0341aeb22651986..4ba868f44a5e9277994c4ac711565b9064c1f259 100644 (file)
@@ -207,7 +207,7 @@ extern struct pci_bios_ops *pci_bios;
 extern void pcibios_register_hba(struct pci_hba_data *);
 extern void pcibios_set_master(struct pci_dev *);
 #else
-extern inline void pcibios_register_hba(struct pci_hba_data *x)
+static inline void pcibios_register_hba(struct pci_hba_data *x)
 {
 }
 #endif
index 876fd8116d4ae5c9a4c0313d383c5ee47c2cce62..5e0c3ca5450b02e0f626523e6f405590d2c51a24 100644 (file)
@@ -1,7 +1,6 @@
 #ifndef _PARISC_PDC_H
 #define _PARISC_PDC_H
 
-
 /*
  *     PDC return values ...
  *     All PDC calls return a subset of these errors. 
@@ -20,7 +19,6 @@
 #define PDC_BUS_POW_WARN       -12     /* Call could not complete in allowed power budget */
 #define PDC_NOT_NARROW         -17     /* Narrow mode not supported    */
 
-
 /*
  *     PDC entry points...
  */
 #define PDC_MODEL_DISPEC       5       /* disable specific option      */
 #define PDC_MODEL_CPU_ID       6       /* returns cpu-id (only newer machines!) */
 #define PDC_MODEL_CAPABILITIES 7       /* returns OS32/OS64-flags      */
+/* Values for PDC_MODEL_CAPABILITIES non-equivalent virtual aliasing support */
+#define  PDC_MODEL_IOPDIR_FDC          (1 << 2)
+#define  PDC_MODEL_NVA_MASK            (3 << 4)
+#define  PDC_MODEL_NVA_SUPPORTED       (0 << 4)
+#define  PDC_MODEL_NVA_SLOW            (1 << 4)
+#define  PDC_MODEL_NVA_UNSUPPORTED     (3 << 4)
 #define PDC_MODEL_GET_BOOT__OP 8       /* returns boot test options    */
 #define PDC_MODEL_SET_BOOT__OP 9       /* set boot test options        */
 
@@ -91,7 +95,7 @@
 #define PDC_TOD                9               /* time-of-day clock (TOD)      */
 #define PDC_TOD_READ           0       /* read TOD                     */
 #define PDC_TOD_WRITE          1       /* write TOD                    */
-#define PDC_TOD_ITIMER         2       /* calibrate Interval Timer (CR16) */
+
 
 #define PDC_STABLE     10              /* stable storage (sprockets)   */
 #define PDC_STABLE_READ                0
 #define PDC_MEM_RET_PDT_FULL           -11
 #define PDC_MEM_RET_INVALID_PHYSICAL_LOCATION ~0ULL
 
-#ifndef __ASSEMBLY__
-typedef struct {
-    unsigned long long baseAddr;
-    unsigned int       pages;
-    unsigned int       reserved;
-} MemAddrTable_t;
-#endif
-
-
 #define PDC_PSW                21              /* Get/Set default System Mask  */
 #define PDC_PSW_MASK           0       /* Return mask                  */
 #define PDC_PSW_GET_DEFAULTS   1       /* Return defaults              */
@@ -274,6 +269,43 @@ typedef struct {
 #define PDC_LINK_PCI_ENTRY_POINTS      0  /* list (Arg1) = 0 */
 #define PDC_LINK_USB_ENTRY_POINTS      1  /* list (Arg1) = 1 */
 
+/* cl_class
+ * page 3-33 of IO-Firmware ARS
+ * IODC ENTRY_INIT(Search first) RET[1]
+ */
+#define        CL_NULL         0       /* invalid */
+#define        CL_RANDOM       1       /* random access (as disk) */
+#define        CL_SEQU         2       /* sequential access (as tape) */
+#define        CL_DUPLEX       7       /* full-duplex point-to-point (RS-232, Net) */
+#define        CL_KEYBD        8       /* half-duplex console (HIL Keyboard) */
+#define        CL_DISPL        9       /* half-duplex console (display) */
+#define        CL_FC           10      /* FiberChannel access media */
+
+/* IODC ENTRY_INIT() */
+#define ENTRY_INIT_SRCH_FRST   2
+#define ENTRY_INIT_SRCH_NEXT   3
+#define ENTRY_INIT_MOD_DEV     4
+#define ENTRY_INIT_DEV         5
+#define ENTRY_INIT_MOD         6
+#define ENTRY_INIT_MSG         9
+
+/* IODC ENTRY_IO() */
+#define ENTRY_IO_BOOTIN                0
+#define ENTRY_IO_BOOTOUT       1
+#define ENTRY_IO_CIN           2
+#define ENTRY_IO_COUT          3
+#define ENTRY_IO_CLOSE         4
+#define ENTRY_IO_GETMSG                9
+#define ENTRY_IO_BBLOCK_IN     16
+#define ENTRY_IO_BBLOCK_OUT    17
+
+/* IODC ENTRY_SPA() */
+
+/* IODC ENTRY_CONFIG() */
+
+/* IODC ENTRY_TEST() */
+
+/* IODC ENTRY_TLB() */
 
 /* constants for OS (NVM...) */
 #define OS_ID_NONE             0       /* Undefined OS ID      */
@@ -295,7 +327,13 @@ typedef struct {
 #define OSTAT_RUN              6
 #define OSTAT_ON               7
 
-#ifndef __ASSEMBLY__
+/* Page Zero constant offsets used by the HPMC handler */
+#define BOOT_CONSOLE_HPA_OFFSET  0x3c0
+#define BOOT_CONSOLE_SPA_OFFSET  0x3c4
+#define BOOT_CONSOLE_PATH_OFFSET 0x3a8
+
+#if !defined(__ASSEMBLY__)
+#ifdef __KERNEL__
 
 #include <linux/types.h>
 
@@ -331,14 +369,6 @@ struct pdc_model {         /* for PDC_MODEL */
        unsigned long curr_key;
 };
 
-/* Values for PDC_MODEL_CAPABILITIES non-equivalent virtual aliasing support */
-
-#define PDC_MODEL_IOPDIR_FDC            (1 << 2)        /* see sba_iommu.c */
-#define PDC_MODEL_NVA_MASK             (3 << 4)
-#define PDC_MODEL_NVA_SUPPORTED                (0 << 4)
-#define PDC_MODEL_NVA_SLOW             (1 << 4)
-#define PDC_MODEL_NVA_UNSUPPORTED      (3 << 4)
-
 struct pdc_cache_cf {          /* for PDC_CACHE  (I/D-caches) */
     unsigned long
 #ifdef CONFIG_64BIT
@@ -558,15 +588,97 @@ struct pdc_hpmc_pim_20 { /* PDC_PIM */
        __u64 fr[32];
 };
 
-#endif /* __ASSEMBLY__ */
+void pdc_console_init(void);   /* in pdc_console.c */
+void pdc_console_restart(void);
+
+void setup_pdc(void);          /* in inventory.c */
+
+/* wrapper-functions from pdc.c */
+
+int pdc_add_valid(unsigned long address);
+int pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len);
+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_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,
+                            struct pdc_module_path *mod_path, long mod_index);
+int pdc_system_map_find_addrs(struct pdc_system_map_addr_info *pdc_addr_info,
+                             long mod_index, long addr_index);
+int pdc_model_info(struct pdc_model *model);
+int pdc_model_sysmodel(char *name);
+int pdc_model_cpuid(unsigned long *cpu_id);
+int pdc_model_versions(unsigned long *versions, int id);
+int pdc_model_capabilities(unsigned long *capabilities);
+int pdc_cache_info(struct pdc_cache_info *cache);
+int pdc_spaceid_bits(unsigned long *space_bits);
+#ifndef CONFIG_PA20
+int pdc_btlb_info(struct pdc_btlb_info *btlb);
+int pdc_mem_map_hpa(struct pdc_memory_map *r_addr, struct pdc_module_path *mod_path);
+#endif /* !CONFIG_PA20 */
+int pdc_lan_station_id(char *lan_addr, unsigned long net_hpa);
+
+int pdc_stable_read(unsigned long staddr, void *memaddr, unsigned long count);
+int pdc_stable_write(unsigned long staddr, void *memaddr, unsigned long count);
+int pdc_stable_get_size(unsigned long *size);
+int pdc_stable_verify_contents(void);
+int pdc_stable_initialize(void);
+
+int pdc_pci_irt_size(unsigned long *num_entries, unsigned long hpa);
+int pdc_pci_irt(unsigned long num_entries, unsigned long hpa, void *tbl);
+
+int pdc_get_initiator(struct hardware_path *, struct pdc_initiator *);
+int pdc_tod_read(struct pdc_tod *tod);
+int pdc_tod_set(unsigned long sec, unsigned long usec);
+
+#ifdef CONFIG_64BIT
+int pdc_mem_mem_table(struct pdc_memory_table_raddr *r_addr,
+               struct pdc_memory_table *tbl, unsigned long entries);
+#endif
+
+void set_firmware_width(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);
+int pdc_soft_power_button(int sw_control);
+void pdc_io_reset(void);
+void pdc_io_reset_devices(void);
+int pdc_iodc_getc(void);
+void pdc_iodc_putc(unsigned char c);
+void pdc_iodc_outc(unsigned char c);
+void pdc_printf(const char *fmt, ...);
+
+void pdc_emergency_unlock(void);
+int pdc_sti_call(unsigned long func, unsigned long flags,
+                 unsigned long inptr, unsigned long outputr,
+                 unsigned long glob_cfg);
+
+static inline char * os_id_to_string(u16 os_id) {
+       switch(os_id) {
+       case OS_ID_NONE:        return "No OS";
+       case OS_ID_HPUX:        return "HP-UX";
+       case OS_ID_MPEXL:       return "MPE-iX";
+       case OS_ID_OSF:         return "OSF";
+       case OS_ID_HPRT:        return "HP-RT";
+       case OS_ID_NOVEL:       return "Novell Netware";
+       case OS_ID_LINUX:       return "Linux";
+       default:        return "Unknown";
+       }
+}
+
+#endif /* __KERNEL__ */
+
+#define PAGE0   ((struct zeropage *)__PAGE_OFFSET)
+
+/* DEFINITION OF THE ZERO-PAGE (PAG0) */
+/* based on work by Jason Eckhardt (jason@equator.com) */
 
-/* flags of the device_path (see below) */
+/* flags of the device_path */
 #define        PF_AUTOBOOT     0x80
 #define        PF_AUTOSEARCH   0x40
 #define        PF_TIMER        0x0F
 
-#ifndef __ASSEMBLY__
-
 struct device_path {           /* page 1-69 */
        unsigned char flags;    /* flags see above! */
        unsigned char bc[6];    /* bus converter routing info */
@@ -586,63 +698,6 @@ struct pz_device {
        unsigned short cl_class;/* see below */
 } __attribute__((aligned(8))) ;
 
-#endif /* __ASSEMBLY__ */
-
-/* cl_class
- * page 3-33 of IO-Firmware ARS
- * IODC ENTRY_INIT(Search first) RET[1]
- */
-#define        CL_NULL         0       /* invalid */
-#define        CL_RANDOM       1       /* random access (as disk) */
-#define        CL_SEQU         2       /* sequential access (as tape) */
-#define        CL_DUPLEX       7       /* full-duplex point-to-point (RS-232, Net) */
-#define        CL_KEYBD        8       /* half-duplex console (HIL Keyboard) */
-#define        CL_DISPL        9       /* half-duplex console (display) */
-#define        CL_FC           10      /* FiberChannel access media */
-
-#if 0
-/* FIXME: DEVCLASS_* duplicates CL_* (above).  Delete DEVCLASS_*? */
-#define DEVCLASS_RANDOM                1
-#define DEVCLASS_SEQU          2
-#define DEVCLASS_DUPLEX                7
-#define DEVCLASS_KEYBD         8
-#define DEVCLASS_DISP          9
-#endif
-
-/* IODC ENTRY_INIT() */
-#define ENTRY_INIT_SRCH_FRST   2
-#define ENTRY_INIT_SRCH_NEXT   3
-#define ENTRY_INIT_MOD_DEV     4
-#define ENTRY_INIT_DEV         5
-#define ENTRY_INIT_MOD         6
-#define ENTRY_INIT_MSG         9
-
-/* IODC ENTRY_IO() */
-#define ENTRY_IO_BOOTIN                0
-#define ENTRY_IO_BOOTOUT       1
-#define ENTRY_IO_CIN           2
-#define ENTRY_IO_COUT          3
-#define ENTRY_IO_CLOSE         4
-#define ENTRY_IO_GETMSG                9
-#define ENTRY_IO_BBLOCK_IN     16
-#define ENTRY_IO_BBLOCK_OUT    17
-
-/* IODC ENTRY_SPA() */
-
-/* IODC ENTRY_CONFIG() */
-
-/* IODC ENTRY_TEST() */
-
-/* IODC ENTRY_TLB() */
-
-
-/* DEFINITION OF THE ZERO-PAGE (PAG0) */
-/* based on work by Jason Eckhardt (jason@equator.com) */
-
-#ifndef __ASSEMBLY__
-
-#define PAGE0   ((struct zeropage *)__PAGE_OFFSET)
-
 struct zeropage {
        /* [0x000] initialize vectors (VEC) */
        unsigned int    vec_special;            /* must be zero */
@@ -699,93 +754,6 @@ struct zeropage {
        __u32   pad608[126];
 };
 
-#endif /* __ASSEMBLY__ */
-
-/* Page Zero constant offsets used by the HPMC handler */
-
-#define BOOT_CONSOLE_HPA_OFFSET  0x3c0
-#define BOOT_CONSOLE_SPA_OFFSET  0x3c4
-#define BOOT_CONSOLE_PATH_OFFSET 0x3a8
-
-#ifndef __ASSEMBLY__
-void pdc_console_init(void);   /* in pdc_console.c */
-void pdc_console_restart(void);
-
-void setup_pdc(void);          /* in inventory.c */
-
-/* wrapper-functions from pdc.c */
-
-int pdc_add_valid(unsigned long address);
-int pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len);
-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_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,
-                            struct pdc_module_path *mod_path, long mod_index);
-int pdc_system_map_find_addrs(struct pdc_system_map_addr_info *pdc_addr_info, 
-                             long mod_index, long addr_index);
-int pdc_model_info(struct pdc_model *model);
-int pdc_model_sysmodel(char *name);
-int pdc_model_cpuid(unsigned long *cpu_id);
-int pdc_model_versions(unsigned long *versions, int id);
-int pdc_model_capabilities(unsigned long *capabilities);
-int pdc_cache_info(struct pdc_cache_info *cache);
-int pdc_spaceid_bits(unsigned long *space_bits);
-#ifndef CONFIG_PA20
-int pdc_btlb_info(struct pdc_btlb_info *btlb);
-int pdc_mem_map_hpa(struct pdc_memory_map *r_addr, struct pdc_module_path *mod_path);
-#endif /* !CONFIG_PA20 */
-int pdc_lan_station_id(char *lan_addr, unsigned long net_hpa);
-
-int pdc_stable_read(unsigned long staddr, void *memaddr, unsigned long count);
-int pdc_stable_write(unsigned long staddr, void *memaddr, unsigned long count);
-int pdc_stable_get_size(unsigned long *size);
-int pdc_stable_verify_contents(void);
-int pdc_stable_initialize(void);
-
-int pdc_pci_irt_size(unsigned long *num_entries, unsigned long hpa);
-int pdc_pci_irt(unsigned long num_entries, unsigned long hpa, void *tbl);
-
-int pdc_get_initiator(struct hardware_path *, struct pdc_initiator *);
-int pdc_tod_read(struct pdc_tod *tod);
-int pdc_tod_set(unsigned long sec, unsigned long usec);
-
-#ifdef CONFIG_64BIT
-int pdc_mem_mem_table(struct pdc_memory_table_raddr *r_addr,
-               struct pdc_memory_table *tbl, unsigned long entries);
-#endif
-
-void set_firmware_width(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);
-int pdc_soft_power_button(int sw_control);
-void pdc_io_reset(void);
-void pdc_io_reset_devices(void);
-int pdc_iodc_getc(void);
-void pdc_iodc_putc(unsigned char c);
-void pdc_iodc_outc(unsigned char c);
-void pdc_printf(const char *fmt, ...);
-
-void pdc_emergency_unlock(void);
-int pdc_sti_call(unsigned long func, unsigned long flags,
-                 unsigned long inptr, unsigned long outputr,
-                 unsigned long glob_cfg);
-
-static inline char * os_id_to_string(u16 os_id) {
-       switch(os_id) {
-       case OS_ID_NONE:        return "No OS";
-       case OS_ID_HPUX:        return "HP-UX";
-       case OS_ID_MPEXL:       return "MPE-iX";
-       case OS_ID_OSF:         return "OSF";
-       case OS_ID_HPRT:        return "HP-RT";
-       case OS_ID_NOVEL:       return "Novell Netware";
-       case OS_ID_LINUX:       return "Linux";
-       default:        return "Unknown";
-       }
-}
-#endif /* __ASSEMBLY__ */
+#endif /* !defined(__ASSEMBLY__) */
 
 #endif /* _PARISC_PDC_H */
index e88cacd63724f89674f45e8f69f18db1e9f78a16..cd0fa4f73320fdbe72dd63b9a9aae1d425978d17 100644 (file)
@@ -11,9 +11,9 @@
  */
 
 #include <linux/mm.h>          /* for vm_area_struct */
+#include <linux/bitops.h>
 #include <asm/processor.h>
 #include <asm/cache.h>
-#include <asm/bitops.h>
 
 /*
  * kern_addr_valid(ADDR) tests if ADDR is pointing to valid kernel
 #define pgd_ERROR(e) \
        printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, (unsigned long)pgd_val(e))
 
- /* Note: If you change ISTACK_SIZE, you need to change the corresponding
-  * values in vmlinux.lds and vmlinux64.lds (init_istack section). Also,
-  * the "order" and size need to agree.
-  */
-
-#define  ISTACK_SIZE  32768 /* Interrupt Stack Size */
-#define  ISTACK_ORDER 3
-
 /* This is the size of the initially mapped kernel memory */
 #ifdef CONFIG_64BIT
 #define KERNEL_INITIAL_ORDER   24      /* 0 to 1<<24 = 16MB */
@@ -325,27 +317,27 @@ static inline void pgd_clear(pgd_t *pgd) {
  * setup: the pgd is never bad, and a pmd always exists (as it's folded
  * into the pgd entry)
  */
-extern inline int pgd_none(pgd_t pgd)          { return 0; }
-extern inline int pgd_bad(pgd_t pgd)           { return 0; }
-extern inline int pgd_present(pgd_t pgd)       { return 1; }
-extern inline void pgd_clear(pgd_t * pgdp)     { }
+static inline int pgd_none(pgd_t pgd)          { return 0; }
+static inline int pgd_bad(pgd_t pgd)           { return 0; }
+static inline int pgd_present(pgd_t pgd)       { return 1; }
+static inline void pgd_clear(pgd_t * pgdp)     { }
 #endif
 
 /*
  * The following only work if pte_present() is true.
  * Undefined behaviour if not..
  */
-extern inline int pte_dirty(pte_t pte)         { return pte_val(pte) & _PAGE_DIRTY; }
-extern inline int pte_young(pte_t pte)         { return pte_val(pte) & _PAGE_ACCESSED; }
-extern inline int pte_write(pte_t pte)         { return pte_val(pte) & _PAGE_WRITE; }
-extern inline int pte_file(pte_t pte)          { return pte_val(pte) & _PAGE_FILE; }
-
-extern inline pte_t pte_mkclean(pte_t pte)     { pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
-extern inline pte_t pte_mkold(pte_t pte)       { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
-extern inline pte_t pte_wrprotect(pte_t pte)   { pte_val(pte) &= ~_PAGE_WRITE; return pte; }
-extern inline pte_t pte_mkdirty(pte_t pte)     { pte_val(pte) |= _PAGE_DIRTY; return pte; }
-extern inline pte_t pte_mkyoung(pte_t pte)     { pte_val(pte) |= _PAGE_ACCESSED; return pte; }
-extern inline pte_t pte_mkwrite(pte_t pte)     { pte_val(pte) |= _PAGE_WRITE; return pte; }
+static inline int pte_dirty(pte_t pte)         { return pte_val(pte) & _PAGE_DIRTY; }
+static inline int pte_young(pte_t pte)         { return pte_val(pte) & _PAGE_ACCESSED; }
+static inline int pte_write(pte_t pte)         { return pte_val(pte) & _PAGE_WRITE; }
+static inline int pte_file(pte_t pte)          { return pte_val(pte) & _PAGE_FILE; }
+
+static inline pte_t pte_mkclean(pte_t pte)     { pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
+static inline pte_t pte_mkold(pte_t pte)       { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
+static inline pte_t pte_wrprotect(pte_t pte)   { pte_val(pte) &= ~_PAGE_WRITE; return pte; }
+static inline pte_t pte_mkdirty(pte_t pte)     { pte_val(pte) |= _PAGE_DIRTY; return pte; }
+static inline pte_t pte_mkyoung(pte_t pte)     { pte_val(pte) |= _PAGE_ACCESSED; return pte; }
+static inline pte_t pte_mkwrite(pte_t pte)     { pte_val(pte) |= _PAGE_WRITE; return pte; }
 
 /*
  * Conversion functions: convert a page and protection to a page entry,
@@ -369,7 +361,7 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot)
        return pte;
 }
 
-extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 { pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
 
 /* Permanent address of a page.  On parisc we don't have highmem. */
index 5d021726fa33a4950121b118ea1ce8ca5b26db2e..c5edc60c059f08d0d7b610bdf9793a56db7af0f8 100644 (file)
@@ -19,7 +19,7 @@
 #ifdef CONFIG_PREFETCH
 
 #define ARCH_HAS_PREFETCH
-extern inline void prefetch(const void *addr)
+static inline void prefetch(const void *addr)
 {
        __asm__("ldw 0(%0), %%r0" : : "r" (addr));
 }
@@ -27,7 +27,7 @@ extern inline void prefetch(const void *addr)
 /* LDD is a PA2.0 addition. */
 #ifdef CONFIG_PA20
 #define ARCH_HAS_PREFETCHW
-extern inline void prefetchw(const void *addr)
+static inline void prefetchw(const void *addr)
 {
        __asm__("ldd 0(%0), %%r0" : : "r" (addr));
 }
index f4ebff11dcbd196dffa71edd820328079edd5331..099d641a42c2463158566684d5cc048cb4539f97 100644 (file)
@@ -50,10 +50,10 @@ static inline unsigned int get_rtc_time(struct rtc_time *wtime)
        long int days, rem, y;
        const unsigned short int *ip;
 
-       if(pdc_tod_read(&tod_data) < 0)
+       memset(wtime, 0, sizeof(*wtime));
+       if (pdc_tod_read(&tod_data) < 0)
                return RTC_24H | RTC_BATT_BAD;
 
-
        // most of the remainder of this function is:
 //     Copyright (C) 1991, 1993, 1997, 1998 Free Software Foundation, Inc.
 //     This was originally a part of the GNU C Library.
index e7211c748446d50cf38222395861fe684630e195..62269b31ebf4a89d404ec157cd653cba848de2f7 100644 (file)
@@ -5,7 +5,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-       struct page *page;
+#ifdef CONFIG_DEBUG_SG
+       unsigned long sg_magic;
+#endif
+       unsigned long page_link;
        unsigned int offset;
 
        unsigned int length;
@@ -15,7 +18,7 @@ struct scatterlist {
        __u32      iova_length; /* bytes mapped */
 };
 
-#define sg_virt_addr(sg) ((unsigned long)(page_address(sg->page) + sg->offset))
+#define sg_virt_addr(sg) ((unsigned long)sg_virt(sg))
 #define sg_dma_address(sg) ((sg)->iova)
 #define sg_dma_len(sg)     ((sg)->iova_length)
 
index b771dcfcfdd15fed26e8cee1e43ce375e418ea29..a16271cdc748831ae1cd3ad958f06b7e587f6d70 100644 (file)
@@ -54,7 +54,7 @@ struct semaphore {
 
 #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
 
-extern inline void sema_init (struct semaphore *sem, int val)
+static inline void sema_init (struct semaphore *sem, int val)
 {
        *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
 }
@@ -82,7 +82,7 @@ asmlinkage void __up(struct semaphore * sem);
  * interrupts while we're messing with the semaphore.  Sorry.
  */
 
-extern __inline__ void down(struct semaphore * sem)
+static inline void down(struct semaphore * sem)
 {
        might_sleep();
        spin_lock_irq(&sem->sentry);
@@ -94,7 +94,7 @@ extern __inline__ void down(struct semaphore * sem)
        spin_unlock_irq(&sem->sentry);
 }
 
-extern __inline__ int down_interruptible(struct semaphore * sem)
+static inline int down_interruptible(struct semaphore * sem)
 {
        int ret = 0;
        might_sleep();
@@ -112,7 +112,7 @@ extern __inline__ int down_interruptible(struct semaphore * sem)
  * down_trylock returns 0 on success, 1 if we failed to get the lock.
  * May not sleep, but must preserve irq state
  */
-extern __inline__ int down_trylock(struct semaphore * sem)
+static inline int down_trylock(struct semaphore * sem)
 {
        unsigned long flags;
        int count;
@@ -129,7 +129,7 @@ extern __inline__ int down_trylock(struct semaphore * sem)
  * Note! This is subtle. We jump to wake people up only if
  * the semaphore was negative (== somebody was waiting on it).
  */
-extern __inline__ void up(struct semaphore * sem)
+static inline void up(struct semaphore * sem)
 {
        unsigned long flags;
 
index 270cf309772bef396dfbe8d1531eab269367554d..b72ec66db699e56f0985ebd6d88d82a7ceb14411 100644 (file)
@@ -57,10 +57,6 @@ static inline void flush_tlb_mm(struct mm_struct *mm)
 #endif
 }
 
-extern __inline__ void flush_tlb_pgtables(struct mm_struct *mm, unsigned long start, unsigned long end)
-{
-}
 static inline void flush_tlb_page(struct vm_area_struct *vma,
        unsigned long addr)
 {
index f74099bdca3c11c6ee99e106146041c6587c0ad0..081b4ae6186682aeaeffff35a677eab29b869f95 100644 (file)
 #define __NR_signalfd          (__NR_Linux + 302)
 #define __NR_timerfd           (__NR_Linux + 303)
 #define __NR_eventfd           (__NR_Linux + 304)
+#define __NR_fallocate         (__NR_Linux + 305)
 
-#define __NR_Linux_syscalls    (__NR_eventfd + 1)
+#define __NR_Linux_syscalls    (__NR_fallocate + 1)
 
 
 #define __IGNORE_select                /* newselect */
index 8144a2788db67bc101e47b20545d8fecf03ded35..733b4af7f4f1e7e49269b17856bbf7e47924d7b6 100644 (file)
 
 #ifdef __KERNEL__
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <linux/compiler.h>
 #include <asm/asm-compat.h>
 #include <asm/synch.h>
@@ -86,6 +90,24 @@ static __inline__ void clear_bit(int nr, volatile unsigned long *addr)
        : "cc" );
 }
 
+static __inline__ void clear_bit_unlock(int nr, volatile unsigned long *addr)
+{
+       unsigned long old;
+       unsigned long mask = BITOP_MASK(nr);
+       unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+
+       __asm__ __volatile__(
+       LWSYNC_ON_SMP
+"1:"   PPC_LLARX "%0,0,%3      # clear_bit_unlock\n"
+       "andc   %0,%0,%2\n"
+       PPC405_ERR77(0,%3)
+       PPC_STLCX "%0,0,%3\n"
+       "bne-   1b"
+       : "=&r" (old), "+m" (*p)
+       : "r" (mask), "r" (p)
+       : "cc", "memory");
+}
+
 static __inline__ void change_bit(int nr, volatile unsigned long *addr)
 {
        unsigned long old;
@@ -125,6 +147,27 @@ static __inline__ int test_and_set_bit(unsigned long nr,
        return (old & mask) != 0;
 }
 
+static __inline__ int test_and_set_bit_lock(unsigned long nr,
+                                      volatile unsigned long *addr)
+{
+       unsigned long old, t;
+       unsigned long mask = BITOP_MASK(nr);
+       unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+
+       __asm__ __volatile__(
+"1:"   PPC_LLARX "%0,0,%3              # test_and_set_bit_lock\n"
+       "or     %1,%0,%2 \n"
+       PPC405_ERR77(0,%3)
+       PPC_STLCX "%1,0,%3 \n"
+       "bne-   1b"
+       ISYNC_ON_SMP
+       : "=&r" (old), "=&r" (t)
+       : "r" (mask), "r" (p)
+       : "cc", "memory");
+
+       return (old & mask) != 0;
+}
+
 static __inline__ int test_and_clear_bit(unsigned long nr,
                                         volatile unsigned long *addr)
 {
@@ -185,6 +228,12 @@ static __inline__ void set_bits(unsigned long mask, unsigned long *addr)
 
 #include <asm-generic/bitops/non-atomic.h>
 
+static __inline__ void __clear_bit_unlock(int nr, volatile unsigned long *addr)
+{
+       __asm__ __volatile__(LWSYNC_ON_SMP "" ::: "memory");
+       __clear_bit(nr, addr);
+}
+
 /*
  * Return the zero-based bit position (LE, not IBM bit numbering) of
  * the most significant 1-bit in a double word.
index 65be95dd03a57407db066b1317d9d6f0fc4c2e1f..ff52013c0e2d79bf75202c8bc034d00f8287a92c 100644 (file)
@@ -285,9 +285,9 @@ dma_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
        BUG_ON(direction == DMA_NONE);
 
        for_each_sg(sgl, sg, nents, i) {
-               BUG_ON(!sg->page);
-               __dma_sync_page(sg->page, sg->offset, sg->length, direction);
-               sg->dma_address = page_to_bus(sg->page) + sg->offset;
+               BUG_ON(!sg_page(sg));
+               __dma_sync_page(sg_page(sg), sg->offset, sg->length, direction);
+               sg->dma_address = page_to_bus(sg_page(sg)) + sg->offset;
        }
 
        return nents;
@@ -328,7 +328,7 @@ static inline void dma_sync_sg_for_cpu(struct device *dev,
        BUG_ON(direction == DMA_NONE);
 
        for_each_sg(sgl, sg, nents, i)
-               __dma_sync_page(sg->page, sg->offset, sg->length, direction);
+               __dma_sync_page(sg_page(sg), sg->offset, sg->length, direction);
 }
 
 static inline void dma_sync_sg_for_device(struct device *dev,
@@ -341,7 +341,7 @@ static inline void dma_sync_sg_for_device(struct device *dev,
        BUG_ON(direction == DMA_NONE);
 
        for_each_sg(sgl, sg, nents, i)
-               __dma_sync_page(sg->page, sg->offset, sg->length, direction);
+               __dma_sync_page(sg_page(sg), sg->offset, sg->length, direction);
 }
 
 static inline int dma_mapping_error(dma_addr_t dma_addr)
index 1644e44c8757667e575ec03268d02323b62e4145..fd7f5a430f0afdc91e934b0ebf54102e7559efcc 100644 (file)
@@ -69,12 +69,11 @@ static __inline__ unsigned long ide_default_io_base(int index)
 
 #ifdef CONFIG_BLK_DEV_MPC8xx_IDE
 #define IDE_ARCH_ACK_INTR  1
-#define ide_ack_intr(hwif) (hwif->hw.ack_intr ? hwif->hw.ack_intr(hwif) : 1)
+#define ide_ack_intr(hwif) ((hwif)->ack_intr ? (hwif)->ack_intr(hwif) : 1)
 #endif
 
 #endif /* __powerpc64__ */
 
-#define IDE_ARCH_OBSOLETE_INIT
 #define ide_default_io_ctl(base)       ((base) + 0x206) /* obsolete */
 
 #endif /* __KERNEL__ */
index bf14ab4ef4c9794b30432d5d415ec06660d8c121..e44cdfc8493a8f30a2b4a4644884c429f5b1f966 100644 (file)
@@ -522,7 +522,7 @@ static inline void name at                                  \
 #else
 /*
  * Enforce synchronisation of stores vs. spin_unlock
- * (this does it explicitely, though our implementation of spin_unlock
+ * (this does it explicitly, though our implementation of spin_unlock
  * does it implicitely too)
  */
 static inline void mmiowb(void)
index 870967e47204e32642106b61702eb4580be1e69e..4a82fdccee92a8fd57e5bde18439a05c5e48c02e 100644 (file)
@@ -26,9 +26,9 @@
 #include <linux/spinlock.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
+#include <linux/bitops.h>
 #include <asm/machdep.h>
 #include <asm/types.h>
-#include <asm/bitops.h>
 
 #define IOMMU_PAGE_SHIFT      12
 #define IOMMU_PAGE_SIZE       (ASM_CONST(1) << IOMMU_PAGE_SHIFT)
index f863ac21409e7b4166add8e1fea65c4e8ab05ac7..9102b8bf0ead02863ac30fcc0f055fa1cf41c743 100644 (file)
@@ -8,7 +8,7 @@
 
 #ifndef CONFIG_PPC64
 #include <asm/atomic.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 
 /*
  * On 32-bit PowerPC 6xx/7xx/7xxx CPUs, we use a set of 16 VSIDs
index 24751df791ac603519dc00d77175f99587a37948..fcb2ebbfddbcd2d0d4c2aa4704cdffed236207a9 100644 (file)
 #include <asm/prom.h>
 #endif /* __ASSEMBLY__ */
 
+#include <linux/suspend.h>
+
+/* Variants of the 5200(B) */
+#define MPC5200_SVR            0x80110010
+#define MPC5200_SVR_MASK       0xfffffff0
+#define MPC5200B_SVR           0x80110020
+#define MPC5200B_SVR_MASK      0xfffffff0
 
 /* ======================================================================== */
 /* Structures mapping of some unit register set                             */
@@ -242,6 +249,7 @@ struct mpc52xx_cdm {
 #ifndef __ASSEMBLY__
 
 extern void __iomem * mpc52xx_find_and_map(const char *);
+extern void __iomem * mpc52xx_find_and_map_path(const char *path);
 extern unsigned int mpc52xx_find_ipb_freq(struct device_node *node);
 extern void mpc5200_setup_xlb_arbiter(void);
 extern void mpc52xx_declare_of_platform_devices(void);
@@ -251,6 +259,9 @@ extern unsigned int mpc52xx_get_irq(void);
 
 extern int __init mpc52xx_add_bridge(struct device_node *node);
 
+extern void __init mpc52xx_map_wdt(void);
+extern void mpc52xx_restart(char *cmd);
+
 #endif /* __ASSEMBLY__ */
 
 #ifdef CONFIG_PM
@@ -267,9 +278,9 @@ extern int mpc52xx_set_wakeup_gpio(u8 pin, u8 level);
 extern int __init lite5200_pm_init(void);
 
 /* lite5200 calls mpc5200 suspend functions, so here they are */
-extern int mpc52xx_pm_prepare(suspend_state_t);
+extern int mpc52xx_pm_prepare(void);
 extern int mpc52xx_pm_enter(suspend_state_t);
-extern int mpc52xx_pm_finish(suspend_state_t);
+extern void mpc52xx_pm_finish(void);
 extern char saved_sram[0x4000]; /* reuse buffer from mpc52xx suspend */
 #endif
 #endif /* CONFIG_PM */
index fcd7b428ed0bbc01e13ee9b443b43076fbeed907..f6dfce025adfe4d117587321782b607028142bbf 100644 (file)
@@ -114,11 +114,12 @@ struct paca_struct {
        u64 user_time;                  /* accumulated usermode TB ticks */
        u64 system_time;                /* accumulated system TB ticks */
        u64 startpurr;                  /* PURR/TB value snapshot */
+       u64 startspurr;                 /* SPURR value snapshot */
+       u64 purrdelta;                  /* FIXME: document */
+       u64 spurrdelta;                 /* FIXME: document */
 };
 
 extern struct paca_struct paca[];
 
-void setup_boot_paca(void);
-
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_PACA_H */
index b075f619c3b7c4c21476d4f1cf5b79e7f530084a..fcf7d55afe4599e3049713156145997fa066e1e3 100644 (file)
 #include <asm/dma.h>
 
 struct scatterlist {
-       struct page *page;
+#ifdef CONFIG_DEBUG_SG
+       unsigned long sg_magic;
+#endif
+       unsigned long page_link;
        unsigned int offset;
        unsigned int length;
 
index a022f806bb21eba7eea83420b01442cef25f4872..b6b036ccee34f5fd5abbea69c712e4f273219d5a 100644 (file)
@@ -8,7 +8,6 @@
  *  - flush_tlb_page_nohash(vma, vmaddr) flushes one page if SW loaded TLB
  *  - flush_tlb_range(vma, start, end) flushes a range of pages
  *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
- *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
  *
  *  This program is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU General Public License
@@ -174,15 +173,5 @@ extern void __flush_hash_table_range(struct mm_struct *mm, unsigned long start,
  */
 extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
 
-/*
- * This is called in munmap when we have freed up some page-table
- * pages.  We don't need to do anything here, there's nothing special
- * about our page-table pages.  -- paulus
- */
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-                                     unsigned long start, unsigned long end)
-{
-}
-
 #endif /*__KERNEL__ */
 #endif /* _ASM_POWERPC_TLBFLUSH_H */
index a6441a063e5d7c20d1553e79aa898814052fe1d9..b2e25d8997bffdce4dc14f635646df600c1fce52 100644 (file)
@@ -2,8 +2,9 @@
 #ifndef __PPC_MMU_CONTEXT_H
 #define __PPC_MMU_CONTEXT_H
 
+#include <linux/bitops.h>
+
 #include <asm/atomic.h>
-#include <asm/bitops.h>
 #include <asm/mmu.h>
 #include <asm/cputable.h>
 #include <asm-generic/mm_hooks.h>
index cc45780421cac15412e44ef5fc62a425aa089fe8..51df94c73846c6d248c41e5743732efd5b1ae1f0 100644 (file)
@@ -33,6 +33,7 @@
 
 #define set_mb(var, value)     do { var = value; mb(); } while (0)
 
+#define AT_VECTOR_SIZE_ARCH 6 /* entries in ARCH_DLINFO */
 #ifdef CONFIG_SMP
 #define smp_mb()       mb()
 #define smp_rmb()      rmb()
index f7eadf6ac8063ddb6604a9cd09a5aba57abc1c2f..81dbcd43a501355bd90bceb8c1dc24a7f8c14f66 100644 (file)
@@ -57,7 +57,7 @@ static __inline__ void set_dec(unsigned int val)
 /* Accessor functions for the timebase (RTC on 601) registers. */
 /* If one day CONFIG_POWER is added just define __USE_RTC as 1 */
 #ifdef CONFIG_6xx
-extern __inline__ int __attribute_pure__ __USE_RTC(void) {
+extern __inline__ int __pure __USE_RTC(void) {
        return (mfspr(SPRN_PVR)>>16) == 1;
 }
 #else
index f79c9b792af1d88d0d54ed7f5762bc232c96b51d..34d9a6357c38941c70d7b638b2d2f19045291872 100644 (file)
 
 #ifdef __KERNEL__
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <linux/compiler.h>
 
 /*
@@ -746,6 +750,7 @@ static inline int sched_find_first_bit(unsigned long *b)
 #include <asm-generic/bitops/fls64.h>
 
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 
 /*
  * ATTENTION: intel byte ordering convention for ext2 and minix !!
diff --git a/include/asm-s390/cpu.h b/include/asm-s390/cpu.h
new file mode 100644 (file)
index 0000000..352dde1
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ *  include/asm-s390/cpu.h
+ *
+ *    Copyright IBM Corp. 2007
+ *    Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
+ */
+
+#ifndef _ASM_S390_CPU_H_
+#define _ASM_S390_CPU_H_
+
+#include <linux/types.h>
+#include <linux/percpu.h>
+#include <linux/spinlock.h>
+
+struct s390_idle_data {
+       spinlock_t lock;
+       unsigned int in_idle;
+       unsigned long long idle_count;
+       unsigned long long idle_enter;
+       unsigned long long idle_time;
+};
+
+DECLARE_PER_CPU(struct s390_idle_data, s390_idle);
+
+#endif /* _ASM_S390_CPU_H_ */
index 501cb9b0631460b0e2694d43ce4d9c32c6518b0a..05b842126b993295d95912c8f057f5cb182c5397 100644 (file)
 
 #ifndef __s390x__
 #define LCTL_OPCODE "lctl"
-#define PGTABLE_BITS (_SEGMENT_TABLE|USER_STD_MASK)
 #else
 #define LCTL_OPCODE "lctlg"
-#define PGTABLE_BITS (_REGION_TABLE|USER_STD_MASK)
 #endif
 
-static inline void enter_lazy_tlb(struct mm_struct *mm,
-                                  struct task_struct *tsk)
+static inline void update_mm(struct mm_struct *mm, struct task_struct *tsk)
 {
+       pgd_t *pgd = mm->pgd;
+       unsigned long asce_bits;
+
+       /* Calculate asce bits from the first pgd table entry. */
+       asce_bits = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS;
+#ifdef CONFIG_64BIT
+       asce_bits |= _ASCE_TYPE_REGION3;
+#endif
+       S390_lowcore.user_asce = asce_bits | __pa(pgd);
+       if (switch_amode) {
+               /* Load primary space page table origin. */
+               pgd_t *shadow_pgd = get_shadow_table(pgd) ? : pgd;
+               S390_lowcore.user_exec_asce = asce_bits | __pa(shadow_pgd);
+               asm volatile(LCTL_OPCODE" 1,1,%0\n"
+                            : : "m" (S390_lowcore.user_exec_asce) );
+       } else
+               /* Load home space page table origin. */
+               asm volatile(LCTL_OPCODE" 13,13,%0"
+                            : : "m" (S390_lowcore.user_asce) );
 }
 
 static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
                             struct task_struct *tsk)
 {
-       pgd_t *shadow_pgd = get_shadow_pgd(next->pgd);
-
-       if (prev != next) {
-               S390_lowcore.user_asce = (__pa(next->pgd) & PAGE_MASK) |
-                                        PGTABLE_BITS;
-               if (shadow_pgd) {
-                       /* Load primary/secondary space page table origin. */
-                       S390_lowcore.user_exec_asce =
-                               (__pa(shadow_pgd) & PAGE_MASK) | PGTABLE_BITS;
-                       asm volatile(LCTL_OPCODE" 1,1,%0\n"
-                                    LCTL_OPCODE" 7,7,%1"
-                                    : : "m" (S390_lowcore.user_exec_asce),
-                                        "m" (S390_lowcore.user_asce) );
-               } else if (switch_amode) {
-                       /* Load primary space page table origin. */
-                       asm volatile(LCTL_OPCODE" 1,1,%0"
-                                    : : "m" (S390_lowcore.user_asce) );
-               } else
-                       /* Load home space page table origin. */
-                       asm volatile(LCTL_OPCODE" 13,13,%0"
-                                    : : "m" (S390_lowcore.user_asce) );
-       }
+       if (unlikely(prev == next))
+               return;
        cpu_set(smp_processor_id(), next->cpu_vm_mask);
+       update_mm(next, tsk);
 }
 
+#define enter_lazy_tlb(mm,tsk) do { } while (0)
 #define deactivate_mm(tsk,mm)  do { } while (0)
 
 static inline void activate_mm(struct mm_struct *prev,
index ceec3826a67c03729d090d7251fc93db677f8d45..584d0ee3c7f60de6f2a0534dc39e2df4ddeaf1b4 100644 (file)
@@ -82,6 +82,7 @@ typedef struct { unsigned long pte; } pte_t;
 #ifndef __s390x__
 
 typedef struct { unsigned long pmd; } pmd_t;
+typedef struct { unsigned long pud; } pud_t;
 typedef struct {
         unsigned long pgd0;
         unsigned long pgd1;
@@ -90,6 +91,7 @@ typedef struct {
         } pgd_t;
 
 #define pmd_val(x)      ((x).pmd)
+#define pud_val(x)     ((x).pud)
 #define pgd_val(x)      ((x).pgd0)
 
 #else /* __s390x__ */
@@ -98,10 +100,12 @@ typedef struct {
         unsigned long pmd0;
         unsigned long pmd1; 
         } pmd_t;
+typedef struct { unsigned long pud; } pud_t;
 typedef struct { unsigned long pgd; } pgd_t;
 
 #define pmd_val(x)      ((x).pmd0)
 #define pmd_val1(x)     ((x).pmd1)
+#define pud_val(x)     ((x).pud)
 #define pgd_val(x)      ((x).pgd)
 
 #endif /* __s390x__ */
index e45d3c9a4b7ee65a99f684a4e24ddbd9d0e17432..709dd1740956b48407b8c3a58f8e762b9a52a543 100644 (file)
 
 #define check_pgt_cache()      do {} while (0)
 
-/*
- * Page allocation orders.
- */
-#ifndef __s390x__
-# define PTE_ALLOC_ORDER       0
-# define PMD_ALLOC_ORDER       0
-# define PGD_ALLOC_ORDER       1
-#else /* __s390x__ */
-# define PTE_ALLOC_ORDER       0
-# define PMD_ALLOC_ORDER       2
-# define PGD_ALLOC_ORDER       2
-#endif /* __s390x__ */
+unsigned long *crst_table_alloc(struct mm_struct *, int);
+void crst_table_free(unsigned long *);
 
-/*
- * Allocate and free page tables. The xxx_kernel() versions are
- * used to allocate a kernel page table - this turns on ASN bits
- * if any.
- */
+unsigned long *page_table_alloc(int);
+void page_table_free(unsigned long *);
 
-static inline pgd_t *pgd_alloc(struct mm_struct *mm)
+static inline void clear_table(unsigned long *s, unsigned long val, size_t n)
 {
-       pgd_t *pgd = (pgd_t *) __get_free_pages(GFP_KERNEL, PGD_ALLOC_ORDER);
-       int i;
-
-       if (!pgd)
-               return NULL;
-       if (s390_noexec) {
-               pgd_t *shadow_pgd = (pgd_t *)
-                       __get_free_pages(GFP_KERNEL, PGD_ALLOC_ORDER);
-               struct page *page = virt_to_page(pgd);
-
-               if (!shadow_pgd) {
-                       free_pages((unsigned long) pgd, PGD_ALLOC_ORDER);
-                       return NULL;
-               }
-               page->lru.next = (void *) shadow_pgd;
-       }
-       for (i = 0; i < PTRS_PER_PGD; i++)
-#ifndef __s390x__
-               pmd_clear(pmd_offset(pgd + i, i*PGDIR_SIZE));
+       *s = val;
+       n = (n / 256) - 1;
+       asm volatile(
+#ifdef CONFIG_64BIT
+               "       mvc     8(248,%0),0(%0)\n"
 #else
-               pgd_clear(pgd + i);
+               "       mvc     4(252,%0),0(%0)\n"
 #endif
-       return pgd;
+               "0:     mvc     256(256,%0),0(%0)\n"
+               "       la      %0,256(%0)\n"
+               "       brct    %1,0b\n"
+               : "+a" (s), "+d" (n));
 }
 
-static inline void pgd_free(pgd_t *pgd)
+static inline void crst_table_init(unsigned long *crst, unsigned long entry)
 {
-       pgd_t *shadow_pgd = get_shadow_pgd(pgd);
-
-       if (shadow_pgd)
-               free_pages((unsigned long) shadow_pgd, PGD_ALLOC_ORDER);
-       free_pages((unsigned long) pgd, PGD_ALLOC_ORDER);
+       clear_table(crst, entry, sizeof(unsigned long)*2048);
+       crst = get_shadow_table(crst);
+       if (crst)
+               clear_table(crst, entry, sizeof(unsigned long)*2048);
 }
 
 #ifndef __s390x__
-/*
- * page middle directory allocation/free routines.
- * We use pmd cache only on s390x, so these are dummy routines. This
- * code never triggers because the pgd will always be present.
- */
-#define pmd_alloc_one(mm,address)       ({ BUG(); ((pmd_t *)2); })
-#define pmd_free(x)                     do { } while (0)
-#define __pmd_free_tlb(tlb,x)          do { } while (0)
-#define pgd_populate(mm, pmd, pte)      BUG()
-#define pgd_populate_kernel(mm, pmd, pte)      BUG()
-#else /* __s390x__ */
-static inline pmd_t * pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr)
+
+static inline unsigned long pgd_entry_type(struct mm_struct *mm)
 {
-       pmd_t *pmd = (pmd_t *) __get_free_pages(GFP_KERNEL, PMD_ALLOC_ORDER);
-       int i;
-
-       if (!pmd)
-               return NULL;
-       if (s390_noexec) {
-               pmd_t *shadow_pmd = (pmd_t *)
-                       __get_free_pages(GFP_KERNEL, PMD_ALLOC_ORDER);
-               struct page *page = virt_to_page(pmd);
-
-               if (!shadow_pmd) {
-                       free_pages((unsigned long) pmd, PMD_ALLOC_ORDER);
-                       return NULL;
-               }
-               page->lru.next = (void *) shadow_pmd;
-       }
-       for (i=0; i < PTRS_PER_PMD; i++)
-               pmd_clear(pmd + i);
-       return pmd;
+       return _SEGMENT_ENTRY_EMPTY;
 }
 
-static inline void pmd_free (pmd_t *pmd)
+#define pud_alloc_one(mm,address)              ({ BUG(); ((pud_t *)2); })
+#define pud_free(x)                            do { } while (0)
+
+#define pmd_alloc_one(mm,address)              ({ BUG(); ((pmd_t *)2); })
+#define pmd_free(x)                            do { } while (0)
+
+#define pgd_populate(mm, pgd, pud)             BUG()
+#define pgd_populate_kernel(mm, pgd, pud)      BUG()
+
+#define pud_populate(mm, pud, pmd)             BUG()
+#define pud_populate_kernel(mm, pud, pmd)      BUG()
+
+#else /* __s390x__ */
+
+static inline unsigned long pgd_entry_type(struct mm_struct *mm)
 {
-       pmd_t *shadow_pmd = get_shadow_pmd(pmd);
+       return _REGION3_ENTRY_EMPTY;
+}
+
+#define pud_alloc_one(mm,address)              ({ BUG(); ((pud_t *)2); })
+#define pud_free(x)                            do { } while (0)
 
-       if (shadow_pmd)
-               free_pages((unsigned long) shadow_pmd, PMD_ALLOC_ORDER);
-       free_pages((unsigned long) pmd, PMD_ALLOC_ORDER);
+static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr)
+{
+       unsigned long *crst = crst_table_alloc(mm, s390_noexec);
+       if (crst)
+               crst_table_init(crst, _SEGMENT_ENTRY_EMPTY);
+       return (pmd_t *) crst;
 }
+#define pmd_free(pmd) crst_table_free((unsigned long *) pmd)
 
-#define __pmd_free_tlb(tlb,pmd)                        \
-       do {                                    \
-               tlb_flush_mmu(tlb, 0, 0);       \
-               pmd_free(pmd);                  \
-        } while (0)
+#define pgd_populate(mm, pgd, pud)             BUG()
+#define pgd_populate_kernel(mm, pgd, pud)      BUG()
 
-static inline void
-pgd_populate_kernel(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd)
+static inline void pud_populate_kernel(struct mm_struct *mm,
+                                      pud_t *pud, pmd_t *pmd)
 {
-       pgd_val(*pgd) = _PGD_ENTRY | __pa(pmd);
+       pud_val(*pud) = _REGION3_ENTRY | __pa(pmd);
 }
 
-static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd)
+static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
 {
-       pgd_t *shadow_pgd = get_shadow_pgd(pgd);
-       pmd_t *shadow_pmd = get_shadow_pmd(pmd);
+       pud_t *shadow_pud = get_shadow_table(pud);
+       pmd_t *shadow_pmd = get_shadow_table(pmd);
 
-       if (shadow_pgd && shadow_pmd)
-               pgd_populate_kernel(mm, shadow_pgd, shadow_pmd);
-       pgd_populate_kernel(mm, pgd, pmd);
+       if (shadow_pud && shadow_pmd)
+               pud_populate_kernel(mm, shadow_pud, shadow_pmd);
+       pud_populate_kernel(mm, pud, pmd);
 }
 
 #endif /* __s390x__ */
 
+static inline pgd_t *pgd_alloc(struct mm_struct *mm)
+{
+       unsigned long *crst = crst_table_alloc(mm, s390_noexec);
+       if (crst)
+               crst_table_init(crst, pgd_entry_type(mm));
+       return (pgd_t *) crst;
+}
+#define pgd_free(pgd) crst_table_free((unsigned long *) pgd)
+
 static inline void 
 pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
 {
 #ifndef __s390x__
-       pmd_val(pmd[0]) = _PAGE_TABLE + __pa(pte);
-       pmd_val(pmd[1]) = _PAGE_TABLE + __pa(pte+256);
-       pmd_val(pmd[2]) = _PAGE_TABLE + __pa(pte+512);
-       pmd_val(pmd[3]) = _PAGE_TABLE + __pa(pte+768);
+       pmd_val(pmd[0]) = _SEGMENT_ENTRY + __pa(pte);
+       pmd_val(pmd[1]) = _SEGMENT_ENTRY + __pa(pte+256);
+       pmd_val(pmd[2]) = _SEGMENT_ENTRY + __pa(pte+512);
+       pmd_val(pmd[3]) = _SEGMENT_ENTRY + __pa(pte+768);
 #else /* __s390x__ */
-       pmd_val(*pmd) = _PMD_ENTRY + __pa(pte);
-       pmd_val1(*pmd) = _PMD_ENTRY + __pa(pte+256);
+       pmd_val(*pmd) = _SEGMENT_ENTRY + __pa(pte);
+       pmd_val1(*pmd) = _SEGMENT_ENTRY + __pa(pte+256);
 #endif /* __s390x__ */
 }
 
@@ -160,7 +135,7 @@ static inline void
 pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *page)
 {
        pte_t *pte = (pte_t *)page_to_phys(page);
-       pmd_t *shadow_pmd = get_shadow_pmd(pmd);
+       pmd_t *shadow_pmd = get_shadow_table(pmd);
        pte_t *shadow_pte = get_shadow_pte(pte);
 
        pmd_populate_kernel(mm, pmd, pte);
@@ -171,67 +146,14 @@ pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *page)
 /*
  * page table entry allocation/free routines.
  */
-static inline pte_t *
-pte_alloc_one_kernel(struct mm_struct *mm, unsigned long vmaddr)
-{
-       pte_t *pte = (pte_t *) __get_free_page(GFP_KERNEL|__GFP_REPEAT);
-       int i;
-
-       if (!pte)
-               return NULL;
-       if (s390_noexec) {
-               pte_t *shadow_pte = (pte_t *)
-                       __get_free_page(GFP_KERNEL|__GFP_REPEAT);
-               struct page *page = virt_to_page(pte);
-
-               if (!shadow_pte) {
-                       free_page((unsigned long) pte);
-                       return NULL;
-               }
-               page->lru.next = (void *) shadow_pte;
-       }
-       for (i=0; i < PTRS_PER_PTE; i++) {
-               pte_clear(mm, vmaddr, pte + i);
-               vmaddr += PAGE_SIZE;
-       }
-       return pte;
-}
-
-static inline struct page *
-pte_alloc_one(struct mm_struct *mm, unsigned long vmaddr)
-{
-       pte_t *pte = pte_alloc_one_kernel(mm, vmaddr);
-       if (pte)
-               return virt_to_page(pte);
-       return NULL;
-}
-
-static inline void pte_free_kernel(pte_t *pte)
-{
-       pte_t *shadow_pte = get_shadow_pte(pte);
-
-       if (shadow_pte)
-               free_page((unsigned long) shadow_pte);
-       free_page((unsigned long) pte);
-}
-
-static inline void pte_free(struct page *pte)
-{
-       struct page *shadow_page = get_shadow_page(pte);
-
-       if (shadow_page)
-               __free_page(shadow_page);
-       __free_page(pte);
-}
-
-#define __pte_free_tlb(tlb, pte)                                       \
-({                                                                     \
-       struct mmu_gather *__tlb = (tlb);                               \
-       struct page *__pte = (pte);                                     \
-       struct page *shadow_page = get_shadow_page(__pte);              \
-       if (shadow_page)                                                \
-               tlb_remove_page(__tlb, shadow_page);                    \
-       tlb_remove_page(__tlb, __pte);                                  \
-})
+#define pte_alloc_one_kernel(mm, vmaddr) \
+       ((pte_t *) page_table_alloc(s390_noexec))
+#define pte_alloc_one(mm, vmaddr) \
+       virt_to_page(page_table_alloc(s390_noexec))
+
+#define pte_free_kernel(pte) \
+       page_table_free((unsigned long *) pte)
+#define pte_free(pte) \
+       page_table_free((unsigned long *) page_to_phys((struct page *) pte))
 
 #endif /* _S390_PGALLOC_H */
index 39bb5192dc3145aeecb7ed8f10fbd640d3aa85c9..f2cc25b74adf7edfc424ef84251051e558827053 100644 (file)
@@ -13,8 +13,6 @@
 #ifndef _ASM_S390_PGTABLE_H
 #define _ASM_S390_PGTABLE_H
 
-#include <asm-generic/4level-fixup.h>
-
 /*
  * The Linux memory management assumes a three-level page table setup. For
  * s390 31 bit we "fold" the mid level into the top-level page table, so
@@ -35,9 +33,6 @@
 #include <asm/bug.h>
 #include <asm/processor.h>
 
-struct vm_area_struct; /* forward declaration (include/linux/mm.h) */
-struct mm_struct;
-
 extern pgd_t swapper_pg_dir[] __attribute__ ((aligned (4096)));
 extern void paging_init(void);
 extern void vmem_map_init(void);
@@ -63,14 +58,18 @@ extern char empty_zero_page[PAGE_SIZE];
  */
 #ifndef __s390x__
 # define PMD_SHIFT     22
+# define PUD_SHIFT     22
 # define PGDIR_SHIFT   22
 #else /* __s390x__ */
 # define PMD_SHIFT     21
+# define PUD_SHIFT     31
 # define PGDIR_SHIFT   31
 #endif /* __s390x__ */
 
 #define PMD_SIZE        (1UL << PMD_SHIFT)
 #define PMD_MASK        (~(PMD_SIZE-1))
+#define PUD_SIZE       (1UL << PUD_SHIFT)
+#define PUD_MASK       (~(PUD_SIZE-1))
 #define PGDIR_SIZE      (1UL << PGDIR_SHIFT)
 #define PGDIR_MASK      (~(PGDIR_SIZE-1))
 
@@ -83,10 +82,12 @@ extern char empty_zero_page[PAGE_SIZE];
 #ifndef __s390x__
 # define PTRS_PER_PTE    1024
 # define PTRS_PER_PMD    1
+# define PTRS_PER_PUD  1
 # define PTRS_PER_PGD    512
 #else /* __s390x__ */
 # define PTRS_PER_PTE    512
 # define PTRS_PER_PMD    1024
+# define PTRS_PER_PUD  1
 # define PTRS_PER_PGD    2048
 #endif /* __s390x__ */
 
@@ -96,6 +97,8 @@ extern char empty_zero_page[PAGE_SIZE];
        printk("%s:%d: bad pte %p.\n", __FILE__, __LINE__, (void *) pte_val(e))
 #define pmd_ERROR(e) \
        printk("%s:%d: bad pmd %p.\n", __FILE__, __LINE__, (void *) pmd_val(e))
+#define pud_ERROR(e) \
+       printk("%s:%d: bad pud %p.\n", __FILE__, __LINE__, (void *) pud_val(e))
 #define pgd_ERROR(e) \
        printk("%s:%d: bad pgd %p.\n", __FILE__, __LINE__, (void *) pgd_val(e))
 
@@ -195,7 +198,7 @@ extern unsigned long vmalloc_end;
  * I Segment-Invalid Bit:    Segment is not available for address-translation
  * TT Type 01
  * TF
- * TL Table lenght
+ * TL Table length
  *
  * The 64 bit regiontable origin of S390 has following format:
  * |      region table origon                          |       DTTL
@@ -221,6 +224,8 @@ extern unsigned long vmalloc_end;
 /* Hardware bits in the page table entry */
 #define _PAGE_RO       0x200           /* HW read-only bit  */
 #define _PAGE_INVALID  0x400           /* HW invalid bit    */
+
+/* Software bits in the page table entry */
 #define _PAGE_SWT      0x001           /* SW pte type bit t */
 #define _PAGE_SWX      0x002           /* SW pte type bit x */
 
@@ -264,60 +269,75 @@ extern unsigned long vmalloc_end;
 
 #ifndef __s390x__
 
-/* Bits in the segment table entry */
-#define _PAGE_TABLE_LEN 0xf            /* only full page-tables            */
-#define _PAGE_TABLE_COM 0x10           /* common page-table                */
-#define _PAGE_TABLE_INV 0x20           /* invalid page-table               */
-#define _SEG_PRESENT    0x001          /* Software (overlap with PTL)      */
-
-/* Bits int the storage key */
-#define _PAGE_CHANGED    0x02          /* HW changed bit                   */
-#define _PAGE_REFERENCED 0x04          /* HW referenced bit                */
-
-#define _USER_SEG_TABLE_LEN    0x7f    /* user-segment-table up to 2 GB    */
-#define _KERNEL_SEG_TABLE_LEN  0x7f    /* kernel-segment-table up to 2 GB  */
-
-/*
- * User and Kernel pagetables are identical
- */
-#define _PAGE_TABLE    _PAGE_TABLE_LEN
-#define _KERNPG_TABLE  _PAGE_TABLE_LEN
-
-/*
- * The Kernel segment-tables includes the User segment-table
- */
+/* Bits in the segment table address-space-control-element */
+#define _ASCE_SPACE_SWITCH     0x80000000UL    /* space switch event       */
+#define _ASCE_ORIGIN_MASK      0x7ffff000UL    /* segment table origin     */
+#define _ASCE_PRIVATE_SPACE    0x100   /* private space control            */
+#define _ASCE_ALT_EVENT                0x80    /* storage alteration event control */
+#define _ASCE_TABLE_LENGTH     0x7f    /* 128 x 64 entries = 8k            */
 
-#define _SEGMENT_TABLE (_USER_SEG_TABLE_LEN|0x80000000|0x100)
-#define _KERNSEG_TABLE _KERNEL_SEG_TABLE_LEN
+/* Bits in the segment table entry */
+#define _SEGMENT_ENTRY_ORIGIN  0x7fffffc0UL    /* page table origin        */
+#define _SEGMENT_ENTRY_INV     0x20    /* invalid segment table entry      */
+#define _SEGMENT_ENTRY_COMMON  0x10    /* common segment bit               */
+#define _SEGMENT_ENTRY_PTL     0x0f    /* page table length                */
 
-#define USER_STD_MASK  0x00000080UL
+#define _SEGMENT_ENTRY         (_SEGMENT_ENTRY_PTL)
+#define _SEGMENT_ENTRY_EMPTY   (_SEGMENT_ENTRY_INV)
 
 #else /* __s390x__ */
 
+/* Bits in the segment/region table address-space-control-element */
+#define _ASCE_ORIGIN           ~0xfffUL/* segment table origin             */
+#define _ASCE_PRIVATE_SPACE    0x100   /* private space control            */
+#define _ASCE_ALT_EVENT                0x80    /* storage alteration event control */
+#define _ASCE_SPACE_SWITCH     0x40    /* space switch event               */
+#define _ASCE_REAL_SPACE       0x20    /* real space control               */
+#define _ASCE_TYPE_MASK                0x0c    /* asce table type mask             */
+#define _ASCE_TYPE_REGION1     0x0c    /* region first table type          */
+#define _ASCE_TYPE_REGION2     0x08    /* region second table type         */
+#define _ASCE_TYPE_REGION3     0x04    /* region third table type          */
+#define _ASCE_TYPE_SEGMENT     0x00    /* segment table type               */
+#define _ASCE_TABLE_LENGTH     0x03    /* region table length              */
+
+/* Bits in the region table entry */
+#define _REGION_ENTRY_ORIGIN   ~0xfffUL/* region/segment table origin      */
+#define _REGION_ENTRY_INV      0x20    /* invalid region table entry       */
+#define _REGION_ENTRY_TYPE_MASK        0x0c    /* region/segment table type mask   */
+#define _REGION_ENTRY_TYPE_R1  0x0c    /* region first table type          */
+#define _REGION_ENTRY_TYPE_R2  0x08    /* region second table type         */
+#define _REGION_ENTRY_TYPE_R3  0x04    /* region third table type          */
+#define _REGION_ENTRY_LENGTH   0x03    /* region third length              */
+
+#define _REGION1_ENTRY         (_REGION_ENTRY_TYPE_R1 | _REGION_ENTRY_LENGTH)
+#define _REGION1_ENTRY_EMPTY   (_REGION_ENTRY_TYPE_R1 | _REGION_ENTRY_INV)
+#define _REGION2_ENTRY         (_REGION_ENTRY_TYPE_R2 | _REGION_ENTRY_LENGTH)
+#define _REGION2_ENTRY_EMPTY   (_REGION_ENTRY_TYPE_R2 | _REGION_ENTRY_INV)
+#define _REGION3_ENTRY         (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_LENGTH)
+#define _REGION3_ENTRY_EMPTY   (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_INV)
+
 /* Bits in the segment table entry */
-#define _PMD_ENTRY_INV   0x20          /* invalid segment table entry      */
-#define _PMD_ENTRY       0x00        
+#define _SEGMENT_ENTRY_ORIGIN  ~0x7ffUL/* segment table origin             */
+#define _SEGMENT_ENTRY_RO      0x200   /* page protection bit              */
+#define _SEGMENT_ENTRY_INV     0x20    /* invalid segment table entry      */
+
+#define _SEGMENT_ENTRY         (0)
+#define _SEGMENT_ENTRY_EMPTY   (_SEGMENT_ENTRY_INV)
 
-/* Bits in the region third table entry */
-#define _PGD_ENTRY_INV   0x20          /* invalid region table entry       */
-#define _PGD_ENTRY       0x07
+#endif /* __s390x__ */
 
 /*
- * User and kernel page directory
+ * A user page table pointer has the space-switch-event bit, the
+ * private-space-control bit and the storage-alteration-event-control
+ * bit set. A kernel page table pointer doesn't need them.
  */
-#define _REGION_THIRD       0x4
-#define _REGION_THIRD_LEN   0x3 
-#define _REGION_TABLE       (_REGION_THIRD|_REGION_THIRD_LEN|0x40|0x100)
-#define _KERN_REGION_TABLE  (_REGION_THIRD|_REGION_THIRD_LEN)
-
-#define USER_STD_MASK           0x0000000000000080UL
+#define _ASCE_USER_BITS                (_ASCE_SPACE_SWITCH | _ASCE_PRIVATE_SPACE | \
+                                _ASCE_ALT_EVENT)
 
-/* Bits in the storage key */
+/* Bits int the storage key */
 #define _PAGE_CHANGED    0x02          /* HW changed bit                   */
 #define _PAGE_REFERENCED 0x04          /* HW referenced bit                */
 
-#endif /* __s390x__ */
-
 /*
  * Page protection definitions.
  */
@@ -358,65 +378,38 @@ extern unsigned long vmalloc_end;
 #define __S111 PAGE_EX_RW
 
 #ifndef __s390x__
-# define PMD_SHADOW_SHIFT      1
-# define PGD_SHADOW_SHIFT      1
+# define PxD_SHADOW_SHIFT      1
 #else /* __s390x__ */
-# define PMD_SHADOW_SHIFT      2
-# define PGD_SHADOW_SHIFT      2
+# define PxD_SHADOW_SHIFT      2
 #endif /* __s390x__ */
 
 static inline struct page *get_shadow_page(struct page *page)
 {
-       if (s390_noexec && !list_empty(&page->lru))
-               return virt_to_page(page->lru.next);
-       return NULL;
-}
-
-static inline pte_t *get_shadow_pte(pte_t *ptep)
-{
-       unsigned long pteptr = (unsigned long) (ptep);
-
-       if (s390_noexec) {
-               unsigned long offset = pteptr & (PAGE_SIZE - 1);
-               void *addr = (void *) (pteptr ^ offset);
-               struct page *page = virt_to_page(addr);
-               if (!list_empty(&page->lru))
-                       return (pte_t *) ((unsigned long) page->lru.next |
-                                                               offset);
-       }
+       if (s390_noexec && page->index)
+               return virt_to_page((void *)(addr_t) page->index);
        return NULL;
 }
 
-static inline pmd_t *get_shadow_pmd(pmd_t *pmdp)
+static inline void *get_shadow_pte(void *table)
 {
-       unsigned long pmdptr = (unsigned long) (pmdp);
+       unsigned long addr, offset;
+       struct page *page;
 
-       if (s390_noexec) {
-               unsigned long offset = pmdptr &
-                               ((PAGE_SIZE << PMD_SHADOW_SHIFT) - 1);
-               void *addr = (void *) (pmdptr ^ offset);
-               struct page *page = virt_to_page(addr);
-               if (!list_empty(&page->lru))
-                       return (pmd_t *) ((unsigned long) page->lru.next |
-                                                               offset);
-       }
-       return NULL;
+       addr = (unsigned long) table;
+       offset = addr & (PAGE_SIZE - 1);
+       page = virt_to_page((void *)(addr ^ offset));
+       return (void *)(addr_t)(page->index ? (page->index | offset) : 0UL);
 }
 
-static inline pgd_t *get_shadow_pgd(pgd_t *pgdp)
+static inline void *get_shadow_table(void *table)
 {
-       unsigned long pgdptr = (unsigned long) (pgdp);
+       unsigned long addr, offset;
+       struct page *page;
 
-       if (s390_noexec) {
-               unsigned long offset = pgdptr &
-                               ((PAGE_SIZE << PGD_SHADOW_SHIFT) - 1);
-               void *addr = (void *) (pgdptr ^ offset);
-               struct page *page = virt_to_page(addr);
-               if (!list_empty(&page->lru))
-                       return (pgd_t *) ((unsigned long) page->lru.next |
-                                                               offset);
-       }
-       return NULL;
+       addr = (unsigned long) table;
+       offset = addr & ((PAGE_SIZE << PxD_SHADOW_SHIFT) - 1);
+       page = virt_to_page((void *)(addr ^ offset));
+       return (void *)(addr_t)(page->index ? (page->index | offset) : 0UL);
 }
 
 /*
@@ -424,7 +417,8 @@ static inline pgd_t *get_shadow_pgd(pgd_t *pgdp)
  * within a page table are directly modified.  Thus, the following
  * hook is made available.
  */
-static inline void set_pte(pte_t *pteptr, pte_t pteval)
+static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
+                             pte_t *pteptr, pte_t pteval)
 {
        pte_t *shadow_pte = get_shadow_pte(pteptr);
 
@@ -437,7 +431,6 @@ static inline void set_pte(pte_t *pteptr, pte_t pteval)
                        pte_val(*shadow_pte) = _PAGE_TYPE_EMPTY;
        }
 }
-#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
 
 /*
  * pgd/pmd/pte query functions
@@ -448,47 +441,50 @@ static inline int pgd_present(pgd_t pgd) { return 1; }
 static inline int pgd_none(pgd_t pgd)    { return 0; }
 static inline int pgd_bad(pgd_t pgd)     { return 0; }
 
-static inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _SEG_PRESENT; }
-static inline int pmd_none(pmd_t pmd)    { return pmd_val(pmd) & _PAGE_TABLE_INV; }
-static inline int pmd_bad(pmd_t pmd)
-{
-       return (pmd_val(pmd) & (~PAGE_MASK & ~_PAGE_TABLE_INV)) != _PAGE_TABLE;
-}
+static inline int pud_present(pud_t pud) { return 1; }
+static inline int pud_none(pud_t pud)   { return 0; }
+static inline int pud_bad(pud_t pud)    { return 0; }
 
 #else /* __s390x__ */
 
-static inline int pgd_present(pgd_t pgd)
+static inline int pgd_present(pgd_t pgd) { return 1; }
+static inline int pgd_none(pgd_t pgd)   { return 0; }
+static inline int pgd_bad(pgd_t pgd)    { return 0; }
+
+static inline int pud_present(pud_t pud)
 {
-       return (pgd_val(pgd) & ~PAGE_MASK) == _PGD_ENTRY;
+       return pud_val(pud) & _REGION_ENTRY_ORIGIN;
 }
 
-static inline int pgd_none(pgd_t pgd)
+static inline int pud_none(pud_t pud)
 {
-       return pgd_val(pgd) & _PGD_ENTRY_INV;
+       return pud_val(pud) & _REGION_ENTRY_INV;
 }
 
-static inline int pgd_bad(pgd_t pgd)
+static inline int pud_bad(pud_t pud)
 {
-       return (pgd_val(pgd) & (~PAGE_MASK & ~_PGD_ENTRY_INV)) != _PGD_ENTRY;
+       unsigned long mask = ~_REGION_ENTRY_ORIGIN & ~_REGION_ENTRY_INV;
+       return (pud_val(pud) & mask) != _REGION3_ENTRY;
 }
 
+#endif /* __s390x__ */
+
 static inline int pmd_present(pmd_t pmd)
 {
-       return (pmd_val(pmd) & ~PAGE_MASK) == _PMD_ENTRY;
+       return pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN;
 }
 
 static inline int pmd_none(pmd_t pmd)
 {
-       return pmd_val(pmd) & _PMD_ENTRY_INV;
+       return pmd_val(pmd) & _SEGMENT_ENTRY_INV;
 }
 
 static inline int pmd_bad(pmd_t pmd)
 {
-       return (pmd_val(pmd) & (~PAGE_MASK & ~_PMD_ENTRY_INV)) != _PMD_ENTRY;
+       unsigned long mask = ~_SEGMENT_ENTRY_ORIGIN & ~_SEGMENT_ENTRY_INV;
+       return (pmd_val(pmd) & mask) != _SEGMENT_ENTRY;
 }
 
-#endif /* __s390x__ */
-
 static inline int pte_none(pte_t pte)
 {
        return (pte_val(pte) & _PAGE_INVALID) && !(pte_val(pte) & _PAGE_SWT);
@@ -508,7 +504,8 @@ static inline int pte_file(pte_t pte)
        return (pte_val(pte) & mask) == _PAGE_TYPE_FILE;
 }
 
-#define pte_same(a,b)  (pte_val(a) == pte_val(b))
+#define __HAVE_ARCH_PTE_SAME
+#define pte_same(a,b)  (pte_val(a) == pte_val(b))
 
 /*
  * query functions pte_write/pte_dirty/pte_young only work if
@@ -543,58 +540,52 @@ static inline int pte_young(pte_t pte)
 
 #ifndef __s390x__
 
-static inline void pgd_clear(pgd_t * pgdp)      { }
+#define pgd_clear(pgd)         do { } while (0)
+#define pud_clear(pud)         do { } while (0)
 
 static inline void pmd_clear_kernel(pmd_t * pmdp)
 {
-       pmd_val(pmdp[0]) = _PAGE_TABLE_INV;
-       pmd_val(pmdp[1]) = _PAGE_TABLE_INV;
-       pmd_val(pmdp[2]) = _PAGE_TABLE_INV;
-       pmd_val(pmdp[3]) = _PAGE_TABLE_INV;
-}
-
-static inline void pmd_clear(pmd_t * pmdp)
-{
-       pmd_t *shadow_pmd = get_shadow_pmd(pmdp);
-
-       pmd_clear_kernel(pmdp);
-       if (shadow_pmd)
-               pmd_clear_kernel(shadow_pmd);
+       pmd_val(pmdp[0]) = _SEGMENT_ENTRY_EMPTY;
+       pmd_val(pmdp[1]) = _SEGMENT_ENTRY_EMPTY;
+       pmd_val(pmdp[2]) = _SEGMENT_ENTRY_EMPTY;
+       pmd_val(pmdp[3]) = _SEGMENT_ENTRY_EMPTY;
 }
 
 #else /* __s390x__ */
 
-static inline void pgd_clear_kernel(pgd_t * pgdp)
+#define pgd_clear(pgd)         do { } while (0)
+
+static inline void pud_clear_kernel(pud_t *pud)
 {
-       pgd_val(*pgdp) = _PGD_ENTRY_INV | _PGD_ENTRY;
+       pud_val(*pud) = _REGION3_ENTRY_EMPTY;
 }
 
-static inline void pgd_clear(pgd_t * pgdp)
+static inline void pud_clear(pud_t * pud)
 {
-       pgd_t *shadow_pgd = get_shadow_pgd(pgdp);
+       pud_t *shadow = get_shadow_table(pud);
 
-       pgd_clear_kernel(pgdp);
-       if (shadow_pgd)
-               pgd_clear_kernel(shadow_pgd);
+       pud_clear_kernel(pud);
+       if (shadow)
+               pud_clear_kernel(shadow);
 }
 
 static inline void pmd_clear_kernel(pmd_t * pmdp)
 {
-       pmd_val(*pmdp) = _PMD_ENTRY_INV | _PMD_ENTRY;
-       pmd_val1(*pmdp) = _PMD_ENTRY_INV | _PMD_ENTRY;
+       pmd_val(*pmdp) = _SEGMENT_ENTRY_EMPTY;
+       pmd_val1(*pmdp) = _SEGMENT_ENTRY_EMPTY;
 }
 
+#endif /* __s390x__ */
+
 static inline void pmd_clear(pmd_t * pmdp)
 {
-       pmd_t *shadow_pmd = get_shadow_pmd(pmdp);
+       pmd_t *shadow_pmd = get_shadow_table(pmdp);
 
        pmd_clear_kernel(pmdp);
        if (shadow_pmd)
                pmd_clear_kernel(shadow_pmd);
 }
 
-#endif /* __s390x__ */
-
 static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
 {
        pte_t *shadow_pte = get_shadow_pte(ptep);
@@ -663,24 +654,19 @@ static inline pte_t pte_mkyoung(pte_t pte)
        return pte;
 }
 
-static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep)
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
+static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
+                                           unsigned long addr, pte_t *ptep)
 {
        return 0;
 }
 
-static inline int
-ptep_clear_flush_young(struct vm_area_struct *vma,
-                       unsigned long address, pte_t *ptep)
+#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
+static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
+                                        unsigned long address, pte_t *ptep)
 {
        /* No need to flush TLB; bits are in storage key */
-       return ptep_test_and_clear_young(vma, address, ptep);
-}
-
-static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
-{
-       pte_t pte = *ptep;
-       pte_clear(mm, addr, ptep);
-       return pte;
+       return 0;
 }
 
 static inline void __ptep_ipte(unsigned long address, pte_t *ptep)
@@ -709,6 +695,32 @@ static inline void ptep_invalidate(unsigned long address, pte_t *ptep)
                __ptep_ipte(address, ptep);
 }
 
+/*
+ * This is hard to understand. ptep_get_and_clear and ptep_clear_flush
+ * both clear the TLB for the unmapped pte. The reason is that
+ * ptep_get_and_clear is used in common code (e.g. change_pte_range)
+ * to modify an active pte. The sequence is
+ *   1) ptep_get_and_clear
+ *   2) set_pte_at
+ *   3) flush_tlb_range
+ * On s390 the tlb needs to get flushed with the modification of the pte
+ * if the pte is active. The only way how this can be implemented is to
+ * have ptep_get_and_clear do the tlb flush. In exchange flush_tlb_range
+ * is a nop.
+ */
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+#define ptep_get_and_clear(__mm, __address, __ptep)                    \
+({                                                                     \
+       pte_t __pte = *(__ptep);                                        \
+       if (atomic_read(&(__mm)->mm_users) > 1 ||                       \
+           (__mm) != current->active_mm)                               \
+               ptep_invalidate(__address, __ptep);                     \
+       else                                                            \
+               pte_clear((__mm), (__address), (__ptep));               \
+       __pte;                                                          \
+})
+
+#define __HAVE_ARCH_PTEP_CLEAR_FLUSH
 static inline pte_t ptep_clear_flush(struct vm_area_struct *vma,
                                     unsigned long address, pte_t *ptep)
 {
@@ -717,12 +729,40 @@ static inline pte_t ptep_clear_flush(struct vm_area_struct *vma,
        return pte;
 }
 
-static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+/*
+ * The batched pte unmap code uses ptep_get_and_clear_full to clear the
+ * ptes. Here an optimization is possible. tlb_gather_mmu flushes all
+ * tlbs of an mm if it can guarantee that the ptes of the mm_struct
+ * cannot be accessed while the batched unmap is running. In this case
+ * full==1 and a simple pte_clear is enough. See tlb.h.
+ */
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL
+static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm,
+                                           unsigned long addr,
+                                           pte_t *ptep, int full)
 {
-       pte_t old_pte = *ptep;
-       set_pte_at(mm, addr, ptep, pte_wrprotect(old_pte));
+       pte_t pte = *ptep;
+
+       if (full)
+               pte_clear(mm, addr, ptep);
+       else
+               ptep_invalidate(addr, ptep);
+       return pte;
 }
 
+#define __HAVE_ARCH_PTEP_SET_WRPROTECT
+#define ptep_set_wrprotect(__mm, __addr, __ptep)                       \
+({                                                                     \
+       pte_t __pte = *(__ptep);                                        \
+       if (pte_write(__pte)) {                                         \
+               if (atomic_read(&(__mm)->mm_users) > 1 ||               \
+                   (__mm) != current->active_mm)                       \
+                       ptep_invalidate(__addr, __ptep);                \
+               set_pte_at(__mm, __addr, __ptep, pte_wrprotect(__pte)); \
+       }                                                               \
+})
+
+#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
 #define ptep_set_access_flags(__vma, __addr, __ptep, __entry, __dirty) \
 ({                                                                     \
        int __changed = !pte_same(*(__ptep), __entry);                  \
@@ -740,11 +780,13 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
  * should therefore only be called if it is not mapped in any
  * address space.
  */
+#define __HAVE_ARCH_PAGE_TEST_DIRTY
 static inline int page_test_dirty(struct page *page)
 {
        return (page_get_storage_key(page_to_phys(page)) & _PAGE_CHANGED) != 0;
 }
 
+#define __HAVE_ARCH_PAGE_CLEAR_DIRTY
 static inline void page_clear_dirty(struct page *page)
 {
        page_set_storage_key(page_to_phys(page), PAGE_DEFAULT_KEY);
@@ -753,6 +795,7 @@ static inline void page_clear_dirty(struct page *page)
 /*
  * Test and clear referenced bit in storage key.
  */
+#define __HAVE_ARCH_PAGE_TEST_AND_CLEAR_YOUNG
 static inline int page_test_and_clear_young(struct page *page)
 {
        unsigned long physpage = page_to_phys(page);
@@ -784,63 +827,48 @@ static inline pte_t mk_pte(struct page *page, pgprot_t pgprot)
        return mk_pte_phys(physpage, pgprot);
 }
 
-static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot)
-{
-       unsigned long physpage = __pa((pfn) << PAGE_SHIFT);
-
-       return mk_pte_phys(physpage, pgprot);
-}
-
-#ifdef __s390x__
-
-static inline pmd_t pfn_pmd(unsigned long pfn, pgprot_t pgprot)
-{
-       unsigned long physpage = __pa((pfn) << PAGE_SHIFT);
-
-       return __pmd(physpage + pgprot_val(pgprot));
-}
-
-#endif /* __s390x__ */
-
-#define pte_pfn(x) (pte_val(x) >> PAGE_SHIFT)
-#define pte_page(x) pfn_to_page(pte_pfn(x))
+#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
+#define pud_index(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
+#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
+#define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE-1))
 
-#define pmd_page_vaddr(pmd) (pmd_val(pmd) & PAGE_MASK)
+#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
 
-#define pmd_page(pmd) pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)
+#ifndef __s390x__
 
-#define pgd_page_vaddr(pgd) (pgd_val(pgd) & PAGE_MASK)
+#define pmd_deref(pmd) (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN)
+#define pud_deref(pmd) ({ BUG(); 0UL; })
+#define pgd_deref(pmd) ({ BUG(); 0UL; })
 
-#define pgd_page(pgd) pfn_to_page(pgd_val(pgd) >> PAGE_SHIFT)
+#define pud_offset(pgd, address) ((pud_t *) pgd)
+#define pmd_offset(pud, address) ((pmd_t *) pud + pmd_index(address))
 
-/* to find an entry in a page-table-directory */
-#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
-#define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address))
+#else /* __s390x__ */
 
-/* to find an entry in a kernel page-table-directory */
-#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+#define pmd_deref(pmd) (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN)
+#define pud_deref(pud) (pud_val(pud) & _REGION_ENTRY_ORIGIN)
+#define pgd_deref(pgd) ({ BUG(); 0UL; })
 
-#ifndef __s390x__
+#define pud_offset(pgd, address) ((pud_t *) pgd)
 
-/* Find an entry in the second-level page table.. */
-static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
+static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address)
 {
-        return (pmd_t *) dir;
+       pmd_t *pmd = (pmd_t *) pud_deref(*pud);
+       return pmd + pmd_index(address);
 }
 
-#else /* __s390x__ */
+#endif /* __s390x__ */
 
-/* Find an entry in the second-level page table.. */
-#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
-#define pmd_offset(dir,addr) \
-       ((pmd_t *) pgd_page_vaddr(*(dir)) + pmd_index(addr))
+#define pfn_pte(pfn,pgprot) mk_pte_phys(__pa((pfn) << PAGE_SHIFT),(pgprot))
+#define pte_pfn(x) (pte_val(x) >> PAGE_SHIFT)
+#define pte_page(x) pfn_to_page(pte_pfn(x))
 
-#endif /* __s390x__ */
+#define pmd_page(pmd) pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)
 
-/* Find an entry in the third-level page table.. */
-#define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE-1))
-#define pte_offset_kernel(pmd, address) \
-       ((pte_t *) pmd_page_vaddr(*(pmd)) + pte_index(address))
+/* Find an entry in the lowest level page table.. */
+#define pte_offset(pmd, addr) ((pte_t *) pmd_deref(*(pmd)) + pte_index(addr))
+#define pte_offset_kernel(pmd, address) pte_offset(pmd,address)
 #define pte_offset_map(pmd, address) pte_offset_kernel(pmd, address)
 #define pte_offset_map_nested(pmd, address) pte_offset_kernel(pmd, address)
 #define pte_unmap(pte) do { } while (0)
@@ -930,17 +958,6 @@ extern int remove_shared_memory(unsigned long start, unsigned long size);
 #define __HAVE_ARCH_MEMMAP_INIT
 extern void memmap_init(unsigned long, int, unsigned long, unsigned long);
 
-#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
-#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
-#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
-#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
-#define __HAVE_ARCH_PTEP_CLEAR_FLUSH
-#define __HAVE_ARCH_PTEP_SET_WRPROTECT
-#define __HAVE_ARCH_PTE_SAME
-#define __HAVE_ARCH_PAGE_TEST_DIRTY
-#define __HAVE_ARCH_PAGE_CLEAR_DIRTY
-#define __HAVE_ARCH_PAGE_TEST_AND_CLEAR_YOUNG
 #include <asm-generic/pgtable.h>
 
 #endif /* _S390_PAGE_H */
-
index 3b972d4c6b296f6d8cfb4b51f0f55608832dc134..21d40a19355e75a2f1117f1ae5b47a25d94686b8 100644 (file)
@@ -93,7 +93,6 @@ struct thread_struct {
        s390_fp_regs fp_regs;
        unsigned int  acrs[NUM_ACRS];
         unsigned long ksp;              /* kernel stack pointer             */
-        unsigned long user_seg;         /* HSTD                             */
        mm_segment_t mm_segment;
         unsigned long prot_addr;        /* address of protection-excep.     */
         unsigned int error_code;        /* error-code of last prog-excep.   */
@@ -128,22 +127,9 @@ struct stack_frame {
 
 #define ARCH_MIN_TASKALIGN     8
 
-#ifndef __s390x__
-# define __SWAPPER_PG_DIR __pa(&swapper_pg_dir[0]) + _SEGMENT_TABLE
-#else /* __s390x__ */
-# define __SWAPPER_PG_DIR __pa(&swapper_pg_dir[0]) + _REGION_TABLE
-#endif /* __s390x__ */
-
-#define INIT_THREAD {{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, 0, 0, 0, 0, 0, 0, 0},         \
-                    sizeof(init_stack) + (unsigned long) &init_stack,         \
-                    __SWAPPER_PG_DIR,                                         \
-                    {0},                                                      \
-                    0,0,0,                                                    \
-                    (per_struct) {{{{0,}}},0,0,0,0,{{0,}}},                   \
-                    0, 0                                                      \
-} 
+#define INIT_THREAD {                                                  \
+       .ksp = sizeof(init_stack) + (unsigned long) &init_stack,        \
+}
 
 /*
  * Do necessary setup to start up a new thread.
index a43b3afc5e2da6bc919290f692bb44e50db9b44a..29ec8e28c8df375f1aa13e12b9edf2fa89752831 100644 (file)
@@ -2,7 +2,10 @@
 #define _ASMS390_SCATTERLIST_H
 
 struct scatterlist {
-    struct page *page;
+#ifdef CONFIG_DEBUG_SG
+    unsigned long sg_magic;
+#endif
+    unsigned long page_link;
     unsigned int offset;
     unsigned int length;
 };
index 51bd957b85bd23a25a9e5971e903c665d91d8934..618693cfc10f2047b710378210c4842d671f2678 100644 (file)
 #define _S390_TLB_H
 
 /*
- * s390 doesn't need any special per-pte or
- * per-vma handling..
+ * TLB flushing on s390 is complicated. The following requirement
+ * from the principles of operation is the most arduous:
+ *
+ * "A valid table entry must not be changed while it is attached
+ * to any CPU and may be used for translation by that CPU except to
+ * (1) invalidate the entry by using INVALIDATE PAGE TABLE ENTRY,
+ * or INVALIDATE DAT TABLE ENTRY, (2) alter bits 56-63 of a page
+ * table entry, or (3) make a change by means of a COMPARE AND SWAP
+ * AND PURGE instruction that purges the TLB."
+ *
+ * The modification of a pte of an active mm struct therefore is
+ * a two step process: i) invalidate the pte, ii) store the new pte.
+ * This is true for the page protection bit as well.
+ * The only possible optimization is to flush at the beginning of
+ * a tlb_gather_mmu cycle if the mm_struct is currently not in use.
+ *
+ * Pages used for the page tables is a different story. FIXME: more
  */
-#define tlb_start_vma(tlb, vma) do { } while (0)
-#define tlb_end_vma(tlb, vma) do { } while (0)
-#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)
+
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <asm/processor.h>
+#include <asm/pgalloc.h>
+#include <asm/smp.h>
+#include <asm/tlbflush.h>
+
+#ifndef CONFIG_SMP
+#define TLB_NR_PTRS    1
+#else
+#define TLB_NR_PTRS    508
+#endif
+
+struct mmu_gather {
+       struct mm_struct *mm;
+       unsigned int fullmm;
+       unsigned int nr_ptes;
+       unsigned int nr_pmds;
+       void *array[TLB_NR_PTRS];
+};
+
+DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
+
+static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm,
+                                               unsigned int full_mm_flush)
+{
+       struct mmu_gather *tlb = &get_cpu_var(mmu_gathers);
+
+       tlb->mm = mm;
+       tlb->fullmm = full_mm_flush || (num_online_cpus() == 1) ||
+               (atomic_read(&mm->mm_users) <= 1 && mm == current->active_mm);
+       tlb->nr_ptes = 0;
+       tlb->nr_pmds = TLB_NR_PTRS;
+       if (tlb->fullmm)
+               __tlb_flush_mm(mm);
+       return tlb;
+}
+
+static inline void tlb_flush_mmu(struct mmu_gather *tlb,
+                                unsigned long start, unsigned long end)
+{
+       if (!tlb->fullmm && (tlb->nr_ptes > 0 || tlb->nr_pmds < TLB_NR_PTRS))
+               __tlb_flush_mm(tlb->mm);
+       while (tlb->nr_ptes > 0)
+               pte_free(tlb->array[--tlb->nr_ptes]);
+       while (tlb->nr_pmds < TLB_NR_PTRS)
+               pmd_free((pmd_t *) tlb->array[tlb->nr_pmds++]);
+}
+
+static inline void tlb_finish_mmu(struct mmu_gather *tlb,
+                                 unsigned long start, unsigned long end)
+{
+       tlb_flush_mmu(tlb, start, end);
+
+       /* keep the page table cache within bounds */
+       check_pgt_cache();
+
+       put_cpu_var(mmu_gathers);
+}
 
 /*
- * .. because we flush the whole mm when it
- * fills up.
+ * Release the page cache reference for a pte removed by
+ * tlb_ptep_clear_flush. In both flush modes the tlb fo a page cache page
+ * has already been freed, so just do free_page_and_swap_cache.
  */
-#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
+static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
+{
+       free_page_and_swap_cache(page);
+}
 
-#include <asm-generic/tlb.h>
+/*
+ * pte_free_tlb frees a pte table and clears the CRSTE for the
+ * page table from the tlb.
+ */
+static inline void pte_free_tlb(struct mmu_gather *tlb, struct page *page)
+{
+       if (!tlb->fullmm) {
+               tlb->array[tlb->nr_ptes++] = page;
+               if (tlb->nr_ptes >= tlb->nr_pmds)
+                       tlb_flush_mmu(tlb, 0, 0);
+       } else
+               pte_free(page);
+}
 
+/*
+ * pmd_free_tlb frees a pmd table and clears the CRSTE for the
+ * segment table entry from the tlb.
+ */
+static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd)
+{
+#ifdef __s390x__
+       if (!tlb->fullmm) {
+               tlb->array[--tlb->nr_pmds] = (struct page *) pmd;
+               if (tlb->nr_ptes >= tlb->nr_pmds)
+                       tlb_flush_mmu(tlb, 0, 0);
+       } else
+               pmd_free(pmd);
 #endif
+}
+
+#define pud_free_tlb(tlb, pud)                 do { } while (0)
+
+#define tlb_start_vma(tlb, vma)                        do { } while (0)
+#define tlb_end_vma(tlb, vma)                  do { } while (0)
+#define tlb_remove_tlb_entry(tlb, ptep, addr)  do { } while (0)
+#define tlb_migrate_finish(mm)                 do { } while (0)
+
+#endif /* _S390_TLB_H */
index 66793f55c8b2dea7b61f8a7aeada359e252afa22..a69bd2490d52ceeb1af02f94dd0ba40eb958c593 100644 (file)
@@ -6,69 +6,19 @@
 #include <asm/pgalloc.h>
 
 /*
- * TLB flushing:
- *
- *  - flush_tlb() flushes the current mm struct TLBs
- *  - flush_tlb_all() flushes all processes TLBs 
- *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
- *  - flush_tlb_page(vma, vmaddr) flushes one page
- *  - flush_tlb_range(vma, start, end) flushes a range of pages
- *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
- *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
- */
-
-/*
- * S/390 has three ways of flushing TLBs
- * 'ptlb' does a flush of the local processor
- * 'csp' flushes the TLBs on all PUs of a SMP
- * 'ipte' invalidates a pte in a page table and flushes that out of
- * the TLBs of all PUs of a SMP
+ * Flush all tlb entries on the local cpu.
  */
-
-#define local_flush_tlb() \
-do {  asm volatile("ptlb": : :"memory"); } while (0)
-
-#ifndef CONFIG_SMP
-
-/*
- * We always need to flush, since s390 does not flush tlb
- * on each context switch
- */
-
-static inline void flush_tlb(void)
-{
-       local_flush_tlb();
-}
-static inline void flush_tlb_all(void)
-{
-       local_flush_tlb();
-}
-static inline void flush_tlb_mm(struct mm_struct *mm) 
+static inline void __tlb_flush_local(void)
 {
-       local_flush_tlb();
+       asm volatile("ptlb" : : : "memory");
 }
-static inline void flush_tlb_page(struct vm_area_struct *vma,
-                                 unsigned long addr)
-{
-       local_flush_tlb();
-}
-static inline void flush_tlb_range(struct vm_area_struct *vma,
-                                  unsigned long start, unsigned long end)
-{
-       local_flush_tlb();
-}
-
-#define flush_tlb_kernel_range(start, end) \
-       local_flush_tlb();
-
-#else
-
-#include <asm/smp.h>
-
-extern void smp_ptlb_all(void);
 
-static inline void global_flush_tlb(void)
+/*
+ * Flush all tlb entries on all cpus.
+ */
+static inline void __tlb_flush_global(void)
 {
+       extern void smp_ptlb_all(void);
        register unsigned long reg2 asm("2");
        register unsigned long reg3 asm("3");
        register unsigned long reg4 asm("4");
@@ -90,72 +40,75 @@ static inline void global_flush_tlb(void)
 }
 
 /*
- * We only have to do global flush of tlb if process run since last
- * flush on any other pu than current. 
- * If we have threads (mm->count > 1) we always do a global flush, 
- * since the process runs on more than one processor at the same time.
+ * Flush all tlb entries of a page table on all cpus.
  */
+static inline void __tlb_flush_idte(pgd_t *pgd)
+{
+       asm volatile(
+               "       .insn   rrf,0xb98e0000,0,%0,%1,0"
+               : : "a" (2048), "a" (__pa(pgd) & PAGE_MASK) : "cc" );
+}
 
-static inline void __flush_tlb_mm(struct mm_struct * mm)
+static inline void __tlb_flush_mm(struct mm_struct * mm)
 {
        cpumask_t local_cpumask;
 
        if (unlikely(cpus_empty(mm->cpu_vm_mask)))
                return;
+       /*
+        * If the machine has IDTE we prefer to do a per mm flush
+        * on all cpus instead of doing a local flush if the mm
+        * only ran on the local cpu.
+        */
        if (MACHINE_HAS_IDTE) {
-               pgd_t *shadow_pgd = get_shadow_pgd(mm->pgd);
+               pgd_t *shadow_pgd = get_shadow_table(mm->pgd);
 
-               if (shadow_pgd) {
-                       asm volatile(
-                               "       .insn   rrf,0xb98e0000,0,%0,%1,0"
-                               : : "a" (2048),
-                               "a" (__pa(shadow_pgd) & PAGE_MASK) : "cc" );
-               }
-               asm volatile(
-                       "       .insn   rrf,0xb98e0000,0,%0,%1,0"
-                       : : "a" (2048), "a" (__pa(mm->pgd)&PAGE_MASK) : "cc");
+               if (shadow_pgd)
+                       __tlb_flush_idte(shadow_pgd);
+               __tlb_flush_idte(mm->pgd);
                return;
        }
        preempt_disable();
+       /*
+        * If the process only ran on the local cpu, do a local flush.
+        */
        local_cpumask = cpumask_of_cpu(smp_processor_id());
        if (cpus_equal(mm->cpu_vm_mask, local_cpumask))
-               local_flush_tlb();
+               __tlb_flush_local();
        else
-               global_flush_tlb();
+               __tlb_flush_global();
        preempt_enable();
 }
 
-static inline void flush_tlb(void)
-{
-       __flush_tlb_mm(current->mm);
-}
-static inline void flush_tlb_all(void)
-{
-       global_flush_tlb();
-}
-static inline void flush_tlb_mm(struct mm_struct *mm) 
-{
-       __flush_tlb_mm(mm); 
-}
-static inline void flush_tlb_page(struct vm_area_struct *vma,
-                                 unsigned long addr)
+static inline void __tlb_flush_mm_cond(struct mm_struct * mm)
 {
-       __flush_tlb_mm(vma->vm_mm);
+       if (atomic_read(&mm->mm_users) <= 1 && mm == current->active_mm)
+               __tlb_flush_mm(mm);
 }
-static inline void flush_tlb_range(struct vm_area_struct *vma,
-                                  unsigned long start, unsigned long end)
-{
-       __flush_tlb_mm(vma->vm_mm); 
-}
-
-#define flush_tlb_kernel_range(start, end) global_flush_tlb()
 
-#endif
+/*
+ * TLB flushing:
+ *  flush_tlb() - flushes the current mm struct TLBs
+ *  flush_tlb_all() - flushes all processes TLBs
+ *  flush_tlb_mm(mm) - flushes the specified mm context TLB's
+ *  flush_tlb_page(vma, vmaddr) - flushes one page
+ *  flush_tlb_range(vma, start, end) - flushes a range of pages
+ *  flush_tlb_kernel_range(start, end) - flushes a range of kernel pages
+ */
 
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-                                      unsigned long start, unsigned long end)
-{
-        /* S/390 does not keep any page table caches in TLB */
-}
+/*
+ * flush_tlb_mm goes together with ptep_set_wrprotect for the
+ * copy_page_range operation and flush_tlb_range is related to
+ * ptep_get_and_clear for change_protection. ptep_set_wrprotect and
+ * ptep_get_and_clear do not flush the TLBs directly if the mm has
+ * only one user. At the end of the update the flush_tlb_mm and
+ * flush_tlb_range functions need to do the flush.
+ */
+#define flush_tlb()                            do { } while (0)
+#define flush_tlb_all()                                do { } while (0)
+#define flush_tlb_mm(mm)                       __tlb_flush_mm_cond(mm)
+#define flush_tlb_page(vma, addr)              do { } while (0)
+#define flush_tlb_range(vma, start, end)       __tlb_flush_mm_cond(mm)
+#define flush_tlb_kernel_range(start, end)     __tlb_flush_mm(&init_mm)
 
 #endif /* _S390_TLBFLUSH_H */
index 1c16792cee1dbaf239948ac8971dd2ad7290865e..df805f20b26786a3d74478a0c2fd6e10bf1777e5 100644 (file)
@@ -2,6 +2,11 @@
 #define __ASM_SH_BITOPS_H
 
 #ifdef __KERNEL__
+
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <asm/system.h>
 /* For __swab32 */
 #include <asm/byteorder.h>
@@ -137,6 +142,7 @@ static inline unsigned long __ffs(unsigned long word)
 #include <asm-generic/bitops/find.h>
 #include <asm-generic/bitops/ffs.h>
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 #include <asm-generic/bitops/sched.h>
 #include <asm-generic/bitops/ext2-non-atomic.h>
 #include <asm-generic/bitops/ext2-atomic.h>
index 84fefdaa01a53d8863fb145d0ff39e416328a597..fcea067f7a9ce08830c17971207b28c14d27dac8 100644 (file)
@@ -2,7 +2,7 @@
 #define __ASM_SH_DMA_MAPPING_H
 
 #include <linux/mm.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 #include <asm/cacheflush.h>
 #include <asm/io.h>
 
@@ -85,10 +85,9 @@ static inline int dma_map_sg(struct device *dev, struct scatterlist *sg,
 
        for (i = 0; i < nents; i++) {
 #if !defined(CONFIG_PCI) || defined(CONFIG_SH_PCIDMA_NONCOHERENT)
-               dma_cache_sync(dev, page_address(sg[i].page) + sg[i].offset,
-                              sg[i].length, dir);
+               dma_cache_sync(dev, sg_virt(&sg[i]), sg[i].length, dir);
 #endif
-               sg[i].dma_address = page_to_phys(sg[i].page) + sg[i].offset;
+               sg[i].dma_address = sg_phys(&sg[i]);
        }
 
        return nents;
@@ -138,10 +137,9 @@ static inline void dma_sync_sg(struct device *dev, struct scatterlist *sg,
 
        for (i = 0; i < nelems; i++) {
 #if !defined(CONFIG_PCI) || defined(CONFIG_SH_PCIDMA_NONCOHERENT)
-               dma_cache_sync(dev, page_address(sg[i].page) + sg[i].offset,
-                              sg[i].length, dir);
+               dma_cache_sync(dev, sg_virt(&sg[i]), sg[i].length, dir);
 #endif
-               sg[i].dma_address = page_to_phys(sg[i].page) + sg[i].offset;
+               sg[i].dma_address = sg_phys(&sg[i]);
        }
 }
 
index b9ae53c38365c3ac28b3a5269d9b561cf38a998f..a7d0d1856a993bae7cde541f6c4df72a6a464bf3 100644 (file)
@@ -4,7 +4,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page * page; /* Location for highmem page, if any */
+#ifdef CONFIG_DEBUG_SG
+    unsigned long sg_magic;
+#endif
+    unsigned long page_link;
     unsigned int offset;/* for highmem, page offset */
     dma_addr_t dma_address;
     unsigned int length;
index 02ca9347f0439136aeeb76d93023a211a5bf11aa..b36792ac5d6601827dd56f22ea7de6ec63fb7fa6 100644 (file)
@@ -36,7 +36,7 @@
 #define PA_LED         0xba000000      /* LED */
 #define        PA_BCR          0xbb000000      /* FPGA on the MS7751SE01 */
 
-#define PA_MRSHPC      0xb83fffe0      /* MR-SHPC-01 PCMCIA controler */
+#define PA_MRSHPC      0xb83fffe0      /* MR-SHPC-01 PCMCIA controller */
 #define PA_MRSHPC_MW1  0xb8400000      /* MR-SHPC-01 memory window base */
 #define PA_MRSHPC_MW2  0xb8500000      /* MR-SHPC-01 attribute window base */
 #define PA_MRSHPC_IO   0xb8600000      /* MR-SHPC-01 I/O window base */
index b143bb2a2ca757a8128f14185fc2b6eabf6f931d..4161122c84efd2afe7ca05f50b5219c823f3a9fc 100644 (file)
@@ -36,7 +36,7 @@
 #define PA_LED         0xba000000      /* LED */
 #define        PA_BCR          0xbb000000      /* FPGA on the MS7751SE01 */
 
-#define PA_MRSHPC      0xb83fffe0      /* MR-SHPC-01 PCMCIA controler */
+#define PA_MRSHPC      0xb83fffe0      /* MR-SHPC-01 PCMCIA controller */
 #define PA_MRSHPC_MW1  0xb8400000      /* MR-SHPC-01 memory window base */
 #define PA_MRSHPC_MW2  0xb8500000      /* MR-SHPC-01 attribute window base */
 #define PA_MRSHPC_IO   0xb8600000      /* MR-SHPC-01 I/O window base */
index 455fb8da441e6786abe3895c83faf73e633469a6..e0ac97221ae6bb6a6351331ce72b884fc229ecd1 100644 (file)
@@ -9,7 +9,6 @@
  *  - flush_tlb_page(vma, vmaddr) flushes one page
  *  - flush_tlb_range(vma, start, end) flushes a range of pages
  *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
- *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
  */
 extern void local_flush_tlb_all(void);
 extern void local_flush_tlb_mm(struct mm_struct *mm);
@@ -47,9 +46,4 @@ extern void flush_tlb_one(unsigned long asid, unsigned long page);
 
 #endif /* CONFIG_SMP */
 
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-                                     unsigned long start, unsigned long end)
-{
-       /* Nothing to do */
-}
 #endif /* __ASM_SH_TLBFLUSH_H */
index f3bdcdb5d0463089205783e876db06f73e096409..600c59efb4c29a6df194d7bcd574ed4537dc9b07 100644 (file)
  */
 
 #ifdef __KERNEL__
+
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <linux/compiler.h>
 #include <asm/system.h>
 /* For __swab32 */
@@ -136,6 +141,7 @@ static __inline__ unsigned long ffz(unsigned long word)
 #include <asm-generic/bitops/__ffs.h>
 #include <asm-generic/bitops/find.h>
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 #include <asm-generic/bitops/sched.h>
 #include <asm-generic/bitops/ffs.h>
 #include <asm-generic/bitops/ext2-non-atomic.h>
index e661857f98dc8e83bf60bc181e35c4464b343a57..1438b763a5ea64b2741d534415d4c5257cbaa05e 100644 (file)
@@ -2,7 +2,7 @@
 #define __ASM_SH_DMA_MAPPING_H
 
 #include <linux/mm.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 #include <asm/io.h>
 
 struct pci_dev;
@@ -71,10 +71,9 @@ static inline int dma_map_sg(struct device *dev, struct scatterlist *sg,
 
        for (i = 0; i < nents; i++) {
 #if !defined(CONFIG_PCI) || defined(CONFIG_SH_PCIDMA_NONCOHERENT)
-               dma_cache_sync(dev, page_address(sg[i].page) + sg[i].offset,
-                              sg[i].length, dir);
+               dma_cache_sync(dev, sg_virt(&sg[i]), sg[i].length, dir);
 #endif
-               sg[i].dma_address = page_to_phys(sg[i].page) + sg[i].offset;
+               sg[i].dma_address = sg_phys(&sg[i]);
        }
 
        return nents;
@@ -124,10 +123,9 @@ static inline void dma_sync_sg(struct device *dev, struct scatterlist *sg,
 
        for (i = 0; i < nelems; i++) {
 #if !defined(CONFIG_PCI) || defined(CONFIG_SH_PCIDMA_NONCOHERENT)
-               dma_cache_sync(dev, page_address(sg[i].page) + sg[i].offset,
-                              sg[i].length, dir);
+               dma_cache_sync(dev, sg_virt(&sg[i]), sg[i].length, dir);
 #endif
-               sg[i].dma_address = page_to_phys(sg[i].page) + sg[i].offset;
+               sg[i].dma_address = sg_phys(&sg[i]);
        }
 }
 
index c9d84d5f772edbe1eb2554135d659fb83598e41e..b6e31e8b941037a3a8a6ee6ff5a1362d91b2f2f1 100644 (file)
@@ -19,7 +19,6 @@
 /* Without this, the initialisation of PCI IDE cards end up calling
  * ide_init_hwif_ports, which won't work. */
 #ifdef CONFIG_BLK_DEV_IDEPCI
-#define IDE_ARCH_OBSOLETE_INIT 1
 #define ide_default_io_ctl(base)       (0)
 #endif
 
index 1c723f2d7a9516a2daa26fe3113d87a2eab44043..5109251970e7ca96fde9b68e6cc66d74662e1f72 100644 (file)
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page * page; /* Location for highmem page, if any */
+#ifdef CONFIG_DEBUG_SG
+    unsigned long sg_magic;
+#endif
+    unsigned long page_link;
     unsigned int offset;/* for highmem, page offset */
     dma_addr_t dma_address;
     unsigned int length;
index 5ff94644e8c87f4c47c0a24d5c539a9edcb07231..be2a15ffcc5535fb2e1c49db209b318a26047626 100644 (file)
@@ -62,8 +62,7 @@ extern void __xchg_called_with_bad_pointer(void);
 #define smp_read_barrier_depends()     do { } while (0)
 #endif /* CONFIG_SMP */
 
-#define set_rmb(var, value) do { (void)xchg(&var, value); } while (0)
-#define set_mb(var, value) set_rmb(var, value)
+#define set_mb(var, value) do { (void)xchg(&var, value); } while (0)
 
 /* Interrupt Control */
 #ifndef HARD_CLI
index e45beadc29ee860066996c8989893c497acfb550..16a164a237547631459e2a386bf447d9db0f88f0 100644 (file)
@@ -20,10 +20,6 @@ extern void flush_tlb_mm(struct mm_struct *mm);
 extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
                            unsigned long end);
 extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page);
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-                                     unsigned long start, unsigned long end)
-{
-}
 
 extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
 
index 329e696e77516c8511ec0a04972aeefafabf16d3..cb3cefab6e098e56dc1c1835fdb2a44212fea376 100644 (file)
 
 #ifdef __KERNEL__
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 extern unsigned long ___set_bit(unsigned long *addr, unsigned long mask);
 extern unsigned long ___clear_bit(unsigned long *addr, unsigned long mask);
 extern unsigned long ___change_bit(unsigned long *addr, unsigned long mask);
@@ -96,6 +100,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
 #include <asm-generic/bitops/fls.h>
 #include <asm-generic/bitops/fls64.h>
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 #include <asm-generic/bitops/find.h>
 #include <asm-generic/bitops/ext2-non-atomic.h>
 #include <asm-generic/bitops/ext2-atomic.h>
index a6d735a1310e32aa6a31a1dd453cd86fcff34a5e..404022765fc779effd65235d71e1c294b46c31ab 100644 (file)
@@ -18,7 +18,6 @@
 #undef  MAX_HWIFS
 #define MAX_HWIFS      2
 
-#define IDE_ARCH_OBSOLETE_INIT
 #define ide_default_io_ctl(base)       ((base) + 0x206) /* obsolete */
 
 #define __ide_insl(data_reg, buffer, wcount) \
index bdf77b0dfd8e5875cd4a50a1f9c2c8708f1c3e52..058c2064f706feabed5a7e10d9ef8790a185b2d7 100644 (file)
 #define TCSETS         _IOW('T', 9, struct termios)
 #define TCSETSW                _IOW('T', 10, struct termios)
 #define TCSETSF                _IOW('T', 11, struct termios)
+#define TCGETS2                _IOR('T', 12, struct termios2)
+#define TCSETS2                _IOW('T', 13, struct termios2)
+#define TCSETSW2       _IOW('T', 14, struct termios2)
+#define TCSETSF2       _IOW('T', 15, struct termios2)
 
 /* Note that all the ioctls that are not available in Linux have a 
  * double underscore on the front to: a) avoid some programs to
index 64a230064ef254c9d6aee2b797e666f0417e774a..d638737ff13c3097c97b80ec9b6469d95e431857 100644 (file)
 
 extern struct bus_type ebus_bus_type;
 extern struct bus_type sbus_bus_type;
-extern struct bus_type of_platform_bus_type;
+
 #define of_bus_type    of_platform_bus_type    /* for compatibility */
 
-extern int of_register_driver(struct of_platform_driver *drv,
-                             struct bus_type *bus);
-extern void of_unregister_driver(struct of_platform_driver *drv);
 extern struct of_device *of_platform_device_create(struct device_node *np,
                                                   const char *bus_id,
                                                   struct device *parent,
index 4055af90ad7e45ad92430d1cf6df03aa1e13c2ec..e08d3d775b08aff2fa7029aa592744cc78ed5ad4 100644 (file)
@@ -5,7 +5,10 @@
 #include <linux/types.h>
 
 struct scatterlist {
-       struct page *page;
+#ifdef CONFIG_DEBUG_SG
+       unsigned long sg_magic;
+#endif
+       unsigned long page_link;
        unsigned int offset;
 
        unsigned int length;
index 5eb00a105d7c0f70764223e162fc05a4e6d6054a..90cf2210118b809e19818d8334941c31252951ab 100644 (file)
@@ -31,6 +31,18 @@ struct termios {
 #endif
 };
 
+struct termios2 {
+       tcflag_t c_iflag;               /* input mode flags */
+       tcflag_t c_oflag;               /* output mode flags */
+       tcflag_t c_cflag;               /* control mode flags */
+       tcflag_t c_lflag;               /* local mode flags */
+       cc_t c_line;                    /* line discipline */
+       cc_t c_cc[NCCS];                /* control characters */
+       cc_t _x_cc[2];                  /* padding to match ktermios */
+       speed_t c_ispeed;               /* input speed */
+       speed_t c_ospeed;               /* output speed */
+};
+
 struct ktermios {
        tcflag_t c_iflag;               /* input mode flags */
        tcflag_t c_oflag;               /* output mode flags */
@@ -160,6 +172,7 @@ struct ktermios {
 #define CLOCAL   0x00000800
 #define CBAUDEX   0x00001000
 /* We'll never see these speeds with the Zilogs, but for completeness... */
+#define  BOTHER   0x00001000
 #define  B57600   0x00001001
 #define  B115200  0x00001002
 #define  B230400  0x00001003
@@ -189,6 +202,8 @@ struct ktermios {
 #define CMSPAR   0x40000000  /* mark or space (stick) parity */
 #define CRTSCTS          0x80000000  /* flow control */
 
+#define IBSHIFT          16            /* Shift from CBAUD to CIBAUD */
+
 /* c_lflag bits */
 #define ISIG   0x00000001
 #define ICANON 0x00000002
index d767f206ab33317988868a41a804d68054760019..4333232abb9f4e393619585086a408f243868b83 100644 (file)
@@ -107,6 +107,48 @@ struct winsize {
 })
 
 #define user_termios_to_kernel_termios(k, u) \
+({ \
+       int err; \
+       err  = get_user((k)->c_iflag, &(u)->c_iflag); \
+       err |= get_user((k)->c_oflag, &(u)->c_oflag); \
+       err |= get_user((k)->c_cflag, &(u)->c_cflag); \
+       err |= get_user((k)->c_lflag, &(u)->c_lflag); \
+       err |= get_user((k)->c_line,  &(u)->c_line); \
+       err |= copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \
+       if ((k)->c_lflag & ICANON) { \
+               err |= get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
+               err |= get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
+       } else { \
+               err |= get_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
+               err |= get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
+       } \
+       err |= get_user((k)->c_ispeed,  &(u)->c_ispeed); \
+       err |= get_user((k)->c_ospeed,  &(u)->c_ospeed); \
+       err; \
+})
+
+#define kernel_termios_to_user_termios(u, k) \
+({ \
+       int err; \
+       err  = put_user((k)->c_iflag, &(u)->c_iflag); \
+       err |= put_user((k)->c_oflag, &(u)->c_oflag); \
+       err |= put_user((k)->c_cflag, &(u)->c_cflag); \
+       err |= put_user((k)->c_lflag, &(u)->c_lflag); \
+       err |= put_user((k)->c_line, &(u)->c_line); \
+       err |= copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \
+       if (!((k)->c_lflag & ICANON)) { \
+               err |= put_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
+               err |= put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
+       } else { \
+               err |= put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
+               err |= put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
+       } \
+       err |= put_user((k)->c_ispeed, &(u)->c_ispeed); \
+       err |= put_user((k)->c_ospeed, &(u)->c_ospeed); \
+       err; \
+})
+
+#define user_termios_to_kernel_termios_1(k, u) \
 ({ \
        get_user((k)->c_iflag, &(u)->c_iflag); \
        get_user((k)->c_oflag, &(u)->c_oflag); \
@@ -114,7 +156,7 @@ struct winsize {
        get_user((k)->c_lflag, &(u)->c_lflag); \
        get_user((k)->c_line,  &(u)->c_line); \
        copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \
-       if((k)->c_lflag & ICANON) { \
+       if ((k)->c_lflag & ICANON) { \
                get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
                get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
        } else { \
@@ -124,7 +166,7 @@ struct winsize {
        0; \
 })
 
-#define kernel_termios_to_user_termios(u, k) \
+#define kernel_termios_to_user_termios_1(u, k) \
 ({ \
        put_user((k)->c_iflag, &(u)->c_iflag); \
        put_user((k)->c_oflag, &(u)->c_oflag); \
@@ -132,7 +174,7 @@ struct winsize {
        put_user((k)->c_lflag, &(u)->c_lflag); \
        put_user((k)->c_line, &(u)->c_line); \
        copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \
-       if(!((k)->c_lflag & ICANON)) { \
+       if (!((k)->c_lflag & ICANON)) { \
                put_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
                put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
        } else { \
index a619da5cfaa9f5d0e1b9321859692df34a9566b9..b957e29d2ae186510f627094e69699ea3ec41f18 100644 (file)
@@ -13,7 +13,6 @@
  *  - flush_tlb_page(vma, vmaddr) flushes one page
  *  - flush_tlb_range(vma, start, end) flushes a range of pages
  *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
- *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
  */
 
 #ifdef CONFIG_SMP
@@ -42,11 +41,6 @@ BTFIXUPDEF_CALL(void, flush_tlb_mm, struct mm_struct *)
 BTFIXUPDEF_CALL(void, flush_tlb_range, struct vm_area_struct *, unsigned long, unsigned long)
 BTFIXUPDEF_CALL(void, flush_tlb_page, struct vm_area_struct *, unsigned long)
 
-// Thanks to Anton Blanchard, our pagetables became uncached in 2.4. Wee!
-// extern void flush_tlb_pgtables(struct mm_struct *mm,
-//     unsigned long start, unsigned long end);
-#define flush_tlb_pgtables(mm, start, end)     do{ }while(0)
-
 #define flush_tlb_all() BTFIXUP_CALL(flush_tlb_all)()
 #define flush_tlb_mm(mm) BTFIXUP_CALL(flush_tlb_mm)(mm)
 #define flush_tlb_range(vma,start,end) BTFIXUP_CALL(flush_tlb_range)(vma,start,end)
diff --git a/include/asm-sparc64/backoff.h b/include/asm-sparc64/backoff.h
new file mode 100644 (file)
index 0000000..0e32f8b
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef _SPARC64_BACKOFF_H
+#define _SPARC64_BACKOFF_H
+
+#define BACKOFF_LIMIT  (4 * 1024)
+
+#ifdef CONFIG_SMP
+
+#define BACKOFF_SETUP(reg)     \
+       mov     1, reg
+
+#define BACKOFF_SPIN(reg, tmp, label)  \
+       mov     reg, tmp; \
+88:    brnz,pt tmp, 88b; \
+        sub    tmp, 1, tmp; \
+       cmp     reg, BACKOFF_LIMIT; \
+       bg,pn   %xcc, label; \
+        nop; \
+       ba,pt   %xcc, label; \
+        sllx   reg, 1, reg;
+
+#else
+
+#define BACKOFF_SETUP(reg)
+#define BACKOFF_SPIN(reg, tmp, label)
+
+#endif
+
+#endif /* _SPARC64_BACKOFF_H */
index 3d5e1af84723bade56ba80e46e98944d14d0e4d7..982ce8992b91fcae6a2d9e790235b718d7cfa1b1 100644 (file)
@@ -7,6 +7,10 @@
 #ifndef _SPARC64_BITOPS_H
 #define _SPARC64_BITOPS_H
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <linux/compiler.h>
 #include <asm/byteorder.h>
 
@@ -81,6 +85,7 @@ static inline unsigned int hweight8(unsigned int w)
 #include <asm-generic/bitops/hweight.h>
 
 #endif
+#include <asm-generic/bitops/lock.h>
 #endif /* __KERNEL__ */
 
 #include <asm-generic/bitops/find.h>
index 55149cf933c26bb8c61cbb4d760576ed3cedf0ef..ac7eb210b941edfbd69bbde7d4f4b45cc34e8289 100644 (file)
@@ -24,7 +24,6 @@
 # endif
 #endif
 
-#define IDE_ARCH_OBSOLETE_INIT
 #define ide_default_io_ctl(base)       ((base) + 0x206) /* obsolete */
 
 #define __ide_insl(data_reg, buffer, wcount) \
index 2223b6d0e5ed882c983b5717c9adff133bf013a2..083c9a0f37deb9907a149036ca5ea13e979d3fb3 100644 (file)
 #define TCSETS         _IOW('T', 9, struct termios)
 #define TCSETSW                _IOW('T', 10, struct termios)
 #define TCSETSF                _IOW('T', 11, struct termios)
+#define TCGETS2                _IOR('T', 12, struct termios2)
+#define TCSETS2                _IOW('T', 13, struct termios2)
+#define TCSETSW2       _IOW('T', 14, struct termios2)
+#define TCSETSF2       _IOW('T', 15, struct termios2)
 
 /* Note that all the ioctls that are not available in Linux have a 
  * double underscore on the front to: a) avoid some programs to
index f7c1f17c7d52bb4ced8ee5a347105cb037a502cd..f15cfa723916a3bac7180f6005a96f318b1e5d7f 100644 (file)
 extern struct bus_type isa_bus_type;
 extern struct bus_type ebus_bus_type;
 extern struct bus_type sbus_bus_type;
-extern struct bus_type of_platform_bus_type;
+
 #define of_bus_type    of_platform_bus_type    /* for compatibility */
 
-extern int of_register_driver(struct of_platform_driver *drv,
-                             struct bus_type *bus);
-extern void of_unregister_driver(struct of_platform_driver *drv);
 extern struct of_device *of_platform_device_create(struct device_node *np,
                                                   const char *bus_id,
                                                   struct device *parent,
index 703c5bbe6c8cdc4a06aa44f2a64c5d4bde5adc8d..6df23f070b1a31b6c916528ca870b52b538dc6f4 100644 (file)
@@ -6,7 +6,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-       struct page     *page;
+#ifdef CONFIG_DEBUG_SG
+       unsigned long   sg_magic;
+#endif
+       unsigned long   page_link;
        unsigned int    offset;
 
        unsigned int    length;
index 42c09949526cd53f3b259b4912463a77851edbee..1c1c5ea5cea5dea69e40cf4c4a96932f4d24d58b 100644 (file)
@@ -26,7 +26,7 @@
  *     Private routines/data
  */
  
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 #include <asm/atomic.h>
 #include <asm/percpu.h>
 
index 705cd44b41730d0bd8f5604f854c6fc53e76b922..ebe31c152f16f2c46e592dbd2f1c8fe257d99437 100644 (file)
@@ -5,8 +5,6 @@
 
 typedef unsigned char   cc_t;
 typedef unsigned int    speed_t;
-
-/* XXX is this right for sparc64?  it was an unsigned long... XXX */
 typedef unsigned int    tcflag_t;
 
 #define NCC 8
@@ -33,6 +31,18 @@ struct termios {
 #endif
 };
 
+struct termios2 {
+       tcflag_t c_iflag;               /* input mode flags */
+       tcflag_t c_oflag;               /* output mode flags */
+       tcflag_t c_cflag;               /* control mode flags */
+       tcflag_t c_lflag;               /* local mode flags */
+       cc_t c_line;                    /* line discipline */
+       cc_t c_cc[NCCS];                /* control characters */
+       cc_t _x_cc[2];                  /* padding to match ktermios */
+       speed_t c_ispeed;               /* input speed */
+       speed_t c_ospeed;               /* output speed */
+};
+
 struct ktermios {
        tcflag_t c_iflag;               /* input mode flags */
        tcflag_t c_oflag;               /* output mode flags */
@@ -161,6 +171,7 @@ struct ktermios {
 #define HUPCL    0x00000400
 #define CLOCAL   0x00000800
 #define CBAUDEX   0x00001000
+#define  BOTHER   0x00001000
 #define  B57600   0x00001001
 #define  B115200  0x00001002
 #define  B230400  0x00001003
@@ -190,6 +201,8 @@ struct ktermios {
 #define CMSPAR    0x40000000  /* mark or space (stick) parity */
 #define CRTSCTS          0x80000000  /* flow control */
 
+#define IBSHIFT          16            /* Shift from CBAUD to CIBAUD */
+
 /* c_lflag bits */
 #define ISIG   0x00000001
 #define ICANON 0x00000002
index f05d390993d5d4c953727a240577e28e6649efa2..ef527211f8a89a3a6e1e90cd44b7ddb753ef6483 100644 (file)
@@ -123,10 +123,52 @@ struct winsize {
                err |= get_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
                err |= get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
        } \
+       err |= get_user((k)->c_ispeed,  &(u)->c_ispeed); \
+       err |= get_user((k)->c_ospeed,  &(u)->c_ospeed); \
        err; \
 })
 
 #define kernel_termios_to_user_termios(u, k) \
+({ \
+       int err; \
+       err  = put_user((k)->c_iflag, &(u)->c_iflag); \
+       err |= put_user((k)->c_oflag, &(u)->c_oflag); \
+       err |= put_user((k)->c_cflag, &(u)->c_cflag); \
+       err |= put_user((k)->c_lflag, &(u)->c_lflag); \
+       err |= put_user((k)->c_line, &(u)->c_line); \
+       err |= copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \
+       if(!((k)->c_lflag & ICANON)) { \
+               err |= put_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
+               err |= put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
+       } else { \
+               err |= put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
+               err |= put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
+       } \
+       err |= put_user((k)->c_ispeed, &(u)->c_ispeed); \
+       err |= put_user((k)->c_ospeed, &(u)->c_ospeed); \
+       err; \
+})
+
+#define user_termios_to_kernel_termios_1(k, u) \
+({ \
+       int err; \
+       err  = get_user((k)->c_iflag, &(u)->c_iflag); \
+       err |= get_user((k)->c_oflag, &(u)->c_oflag); \
+       err |= get_user((k)->c_cflag, &(u)->c_cflag); \
+       err |= get_user((k)->c_lflag, &(u)->c_lflag); \
+       err |= get_user((k)->c_line,  &(u)->c_line); \
+       err |= copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \
+       if((k)->c_lflag & ICANON) { \
+               err |= get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
+               err |= get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
+       } else { \
+               err |= get_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
+               err |= get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
+       } \
+       err; \
+})
+
+#define kernel_termios_to_user_termios_1(u, k) \
 ({ \
        int err; \
        err  = put_user((k)->c_iflag, &(u)->c_iflag); \
index 3487328570edc1b5e86886ec29de371a72055136..fbb675dbe0c92abe8bead2c0a46c58451fa4d0e1 100644 (file)
@@ -41,11 +41,4 @@ do { flush_tsb_kernel_range(start,end); \
 
 #endif /* ! CONFIG_SMP */
 
-static inline void flush_tlb_pgtables(struct mm_struct *mm, unsigned long start, unsigned long end)
-{
-       /* We don't use virtual page tables for TLB miss processing
-        * any more.  Nowadays we use the TSB.
-        */
-}
-
 #endif /* _SPARC64_TLBFLUSH_H */
index 46d781953d3ad7c5fa42e92f3c0489bf5eeccf64..e4d38d437b97c4baefc2d1dc47bf34d61fc9ccf1 100644 (file)
@@ -1,6 +1,10 @@
 #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
index 9d647c55350b0774f1ea9b546d63ade3dbe13d34..614f2c0911781aebf9a62d3912272f4b640f99d1 100644 (file)
@@ -17,7 +17,6 @@
  *  - flush_tlb_page(vma, vmaddr) flushes one page
  *  - flush_tlb_kernel_vm() flushes the kernel vm area
  *  - flush_tlb_range(vma, start, end) flushes a range of pages
- *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
  */
 
 extern void flush_tlb_all(void);
@@ -29,9 +28,4 @@ extern void flush_tlb_kernel_vm(void);
 extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
 extern void __flush_tlb_one(unsigned long addr);
 
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-                                     unsigned long start, unsigned long end)
-{
-}
-
 #endif
index 1fa99baf4e25bbaf2f82daaf1960537bb59bfde8..f82f5b4a56e0d0526d3d2e53023e90ab65aeaab0 100644 (file)
@@ -13,6 +13,9 @@
 #ifndef __V850_BITOPS_H__
 #define __V850_BITOPS_H__
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
 
 #include <linux/compiler.h>    /* unlikely  */
 #include <asm/byteorder.h>     /* swab32 */
@@ -145,6 +148,7 @@ static inline int __test_bit (int nr, const void *addr)
 #include <asm-generic/bitops/find.h>
 #include <asm-generic/bitops/sched.h>
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 
 #include <asm-generic/bitops/ext2-non-atomic.h>
 #define ext2_set_bit_atomic(l,n,a)      test_and_set_bit(n,a)
index 56f402920db9b10c9ab4a48e728f63043a2e2eff..02d27b3fb061b1b47b84bf310c536ce3006d126a 100644 (file)
 #include <asm/types.h>
 
 struct scatterlist {
-       struct page     *page;
+#ifdef CONFIG_DEBUG_SG
+       unsigned long   sg_magic;
+#endif
+       unsigned long   page_link;
        unsigned        offset;
        dma_addr_t      dma_address;
        unsigned        length;
index 0de2481fd990dcb247e42488be480c8259b40a84..a34ddfafd56195bae8db73dfa08f987de2a73ed2 100644 (file)
@@ -66,8 +66,7 @@ static inline int irqs_disabled (void)
 #define rmb()                  mb ()
 #define wmb()                  mb ()
 #define read_barrier_depends() ((void)0)
-#define set_rmb(var, value)    do { xchg (&var, value); } while (0)
-#define set_mb(var, value)     set_rmb (var, value)
+#define set_mb(var, value)     do { xchg (&var, value); } while (0)
 
 #define smp_mb()       mb ()
 #define smp_rmb()      rmb ()
index 5f2f85f636ea74bc0fe019ef51c53e978ac9a348..c44aa64449c83779df8b05212e46799936264ad2 100644 (file)
@@ -61,10 +61,4 @@ static inline void flush_tlb_kernel_page(unsigned long addr)
        BUG ();
 }
 
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-                                     unsigned long start, unsigned long end)
-{
-       BUG ();
-}
-
 #endif /* __V850_TLBFLUSH_H__ */
index 559830ece755a5e783c4cd13d3b19506fe16cb76..5e3539c129b97a1cf9c28304b4b8562fa9b755b6 100644 (file)
@@ -1,6 +1,7 @@
 include include/asm-generic/Kbuild.asm
 
 header-y += boot.h
+header-y += bootparam.h
 header-y += debugreg.h
 header-y += ldt.h
 header-y += msr-index.h
@@ -14,8 +15,10 @@ unifdef-y += a.out_32.h
 unifdef-y += a.out_64.h
 unifdef-y += byteorder_32.h
 unifdef-y += byteorder_64.h
+unifdef-y += e820.h
 unifdef-y += elf_32.h
 unifdef-y += elf_64.h
+unifdef-y += ist.h
 unifdef-y += mce.h
 unifdef-y += msgbuf_32.h
 unifdef-y += msgbuf_64.h
index 125179adf0440976fc4face93804ebff7800c79a..723493e6c8510849d136b1e7fba5eeb65d0d3b50 100644 (file)
@@ -81,11 +81,7 @@ int __acpi_release_global_lock(unsigned int *lock);
         :"=r"(n_hi), "=r"(n_lo)     \
         :"0"(n_hi), "1"(n_lo))
 
-#ifdef CONFIG_X86_IO_APIC
-extern void check_acpi_pci(void);
-#else
-static inline void check_acpi_pci(void) { }
-#endif
+extern void early_quirks(void);
 
 #ifdef CONFIG_ACPI
 extern int acpi_lapic;
index a20fe9822f6002db96607331fd7ae50f0a95ee58..3268a341cf495177de5653c066dacfc81b7b52da 100644 (file)
@@ -5,6 +5,10 @@
  * Copyright 1992, Linus Torvalds.
  */
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <linux/compiler.h>
 #include <asm/alternative.h>
 
@@ -402,6 +406,7 @@ static inline int fls(int x)
 }
 
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 
 #endif /* __KERNEL__ */
 
index 1d7d9b4bcacb0846f44f72282008552f4582dba5..dacaa5f1febcb713d38cbe6114759ff61127dc11 100644 (file)
@@ -5,6 +5,10 @@
  * Copyright 1992, Linus Torvalds.
  */
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <asm/alternative.h>
 
 #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 1)
@@ -408,6 +412,7 @@ static __inline__ int fls(int x)
 #define ARCH_HAS_FAST_MULTIPLIER 1
 
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 
 #endif /* __KERNEL__ */
 
index ef67b59dbdb93ea61215628ab615d78d67f5f2d9..19f3ddf2df4be745426a0990770d30b591b3276e 100644 (file)
 #include <video/edid.h>
 
 struct setup_header {
-       u8      setup_sects;
-       u16     root_flags;
-       u32     syssize;
-       u16     ram_size;
+       __u8    setup_sects;
+       __u16   root_flags;
+       __u32   syssize;
+       __u16   ram_size;
 #define RAMDISK_IMAGE_START_MASK       0x07FF
 #define RAMDISK_PROMPT_FLAG            0x8000
 #define RAMDISK_LOAD_FLAG              0x4000
-       u16     vid_mode;
-       u16     root_dev;
-       u16     boot_flag;
-       u16     jump;
-       u32     header;
-       u16     version;
-       u32     realmode_swtch;
-       u16     start_sys;
-       u16     kernel_version;
-       u8      type_of_loader;
-       u8      loadflags;
-#define LOADED_HIGH    0x01
-#define CAN_USE_HEAP   0x80
-       u16     setup_move_size;
-       u32     code32_start;
-       u32     ramdisk_image;
-       u32     ramdisk_size;
-       u32     bootsect_kludge;
-       u16     heap_end_ptr;
-       u16     _pad1;
-       u32     cmd_line_ptr;
-       u32     initrd_addr_max;
-       u32     kernel_alignment;
-       u8      relocatable_kernel;
+       __u16   vid_mode;
+       __u16   root_dev;
+       __u16   boot_flag;
+       __u16   jump;
+       __u32   header;
+       __u16   version;
+       __u32   realmode_swtch;
+       __u16   start_sys;
+       __u16   kernel_version;
+       __u8    type_of_loader;
+       __u8    loadflags;
+#define LOADED_HIGH    (1<<0)
+#define KEEP_SEGMENTS  (1<<6)
+#define CAN_USE_HEAP   (1<<7)
+       __u16   setup_move_size;
+       __u32   code32_start;
+       __u32   ramdisk_image;
+       __u32   ramdisk_size;
+       __u32   bootsect_kludge;
+       __u16   heap_end_ptr;
+       __u16   _pad1;
+       __u32   cmd_line_ptr;
+       __u32   initrd_addr_max;
+       __u32   kernel_alignment;
+       __u8    relocatable_kernel;
+       __u8    _pad2[3];
+       __u32   cmdline_size;
+       __u32   hardware_subarch;
+       __u64   hardware_subarch_data;
 } __attribute__((packed));
 
 struct sys_desc_table {
-       u16 length;
-       u8  table[14];
+       __u16 length;
+       __u8  table[14];
 };
 
 struct efi_info {
-       u32 _pad1;
-       u32 efi_systab;
-       u32 efi_memdesc_size;
-       u32 efi_memdesc_version;
-       u32 efi_memmap;
-       u32 efi_memmap_size;
-       u32 _pad2[2];
+       __u32 _pad1;
+       __u32 efi_systab;
+       __u32 efi_memdesc_size;
+       __u32 efi_memdesc_version;
+       __u32 efi_memmap;
+       __u32 efi_memmap_size;
+       __u32 _pad2[2];
 };
 
 /* The so-called "zeropage" */
 struct boot_params {
        struct screen_info screen_info;                 /* 0x000 */
        struct apm_bios_info apm_bios_info;             /* 0x040 */
-       u8  _pad2[12];                                  /* 0x054 */
+       __u8  _pad2[12];                                /* 0x054 */
        struct ist_info ist_info;                       /* 0x060 */
-       u8  _pad3[16];                                  /* 0x070 */
-       u8  hd0_info[16];       /* obsolete! */         /* 0x080 */
-       u8  hd1_info[16];       /* obsolete! */         /* 0x090 */
+       __u8  _pad3[16];                                /* 0x070 */
+       __u8  hd0_info[16];     /* obsolete! */         /* 0x080 */
+       __u8  hd1_info[16];     /* obsolete! */         /* 0x090 */
        struct sys_desc_table sys_desc_table;           /* 0x0a0 */
-       u8  _pad4[144];                                 /* 0x0b0 */
+       __u8  _pad4[144];                               /* 0x0b0 */
        struct edid_info edid_info;                     /* 0x140 */
        struct efi_info efi_info;                       /* 0x1c0 */
-       u32 alt_mem_k;                                  /* 0x1e0 */
-       u32 scratch;            /* Scratch field! */    /* 0x1e4 */
-       u8  e820_entries;                               /* 0x1e8 */
-       u8  eddbuf_entries;                             /* 0x1e9 */
-       u8  edd_mbr_sig_buf_entries;                    /* 0x1ea */
-       u8  _pad6[6];                                   /* 0x1eb */
+       __u32 alt_mem_k;                                /* 0x1e0 */
+       __u32 scratch;          /* Scratch field! */    /* 0x1e4 */
+       __u8  e820_entries;                             /* 0x1e8 */
+       __u8  eddbuf_entries;                           /* 0x1e9 */
+       __u8  edd_mbr_sig_buf_entries;                  /* 0x1ea */
+       __u8  _pad6[6];                                 /* 0x1eb */
        struct setup_header hdr;    /* setup header */  /* 0x1f1 */
-       u8  _pad7[0x290-0x1f1-sizeof(struct setup_header)];
-       u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX];        /* 0x290 */
+       __u8  _pad7[0x290-0x1f1-sizeof(struct setup_header)];
+       __u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX];      /* 0x290 */
        struct e820entry e820_map[E820MAX];             /* 0x2d0 */
-       u8  _pad8[48];                                  /* 0xcd0 */
+       __u8  _pad8[48];                                /* 0xcd0 */
        struct edd_info eddbuf[EDDMAXNR];               /* 0xd00 */
-       u8  _pad9[276];                                 /* 0xeec */
+       __u8  _pad9[276];                               /* 0xeec */
 } __attribute__((packed));
 
 #endif /* _ASM_BOOTPARAM_H */
index b3d43de44c59ae13c390485bcbf6e7f3615f8a70..9411a2d3f19c2a77feed8d141ddc7c3bd9f13399 100644 (file)
@@ -27,6 +27,7 @@
 void global_flush_tlb(void);
 int change_page_attr(struct page *page, int numpages, pgprot_t prot);
 int change_page_attr_addr(unsigned long addr, int numpages, pgprot_t prot);
+void clflush_cache_range(void *addr, int size);
 
 #ifdef CONFIG_DEBUG_PAGEALLOC
 /* internal debugging function */
index 53cb96b68a62bcb1f040e78381e9e9e562cbb0f8..66ba7987184ae1dfae314010a321a4908b4b4e55 100644 (file)
@@ -6,6 +6,7 @@
  */
 #include <linux/types.h>
 #include <linux/sched.h>
+#include <asm/user32.h>
 
 #define COMPAT_USER_HZ 100
 
@@ -180,6 +181,11 @@ struct compat_shmid64_ds {
        compat_ulong_t __unused5;
 };
 
+/*
+ * The type of struct elf_prstatus.pr_reg in compatible core dumps.
+ */
+typedef struct user_regs_struct32 compat_elf_gregset_t;
+
 /*
  * A pointer passed in from user mode. This should not
  * be used for syscall parameters, just declare them
index ac991b5ca0fd501c0b294963031ca505016dbb9e..7d9c938e69fd296d1e493565fc2e4dca0265b291 100644 (file)
@@ -20,6 +20,16 @@ extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
 #define load_LDT_desc() asm volatile("lldt %w0"::"r" (GDT_ENTRY_LDT*8))
 #define clear_LDT()  asm volatile("lldt %w0"::"r" (0))
 
+static inline unsigned long __store_tr(void)
+{
+       unsigned long tr;
+
+       asm volatile ("str %w0":"=r" (tr));
+       return tr;
+}
+
+#define store_tr(tr) (tr) = __store_tr()
+
 /*
  * This is the ldt that every process will get unless we need
  * something other than this.
@@ -31,6 +41,16 @@ extern struct desc_ptr cpu_gdt_descr[];
 /* the cpu gdt accessor */
 #define cpu_gdt(_cpu) ((struct desc_struct *)cpu_gdt_descr[_cpu].address)
 
+static inline void load_gdt(const struct desc_ptr *ptr)
+{
+       asm volatile("lgdt %w0"::"m" (*ptr));
+}
+
+static inline void store_gdt(struct desc_ptr *ptr)
+{
+       asm("sgdt %w0":"=m" (*ptr));
+}
+
 static inline void _set_gate(void *adr, unsigned type, unsigned long func, unsigned dpl, unsigned ist)  
 {
        struct gate_struct s;   
@@ -71,6 +91,16 @@ static inline void set_system_gate_ist(int nr, void *func, unsigned ist)
        _set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 3, ist);
 }
 
+static inline void load_idt(const struct desc_ptr *ptr)
+{
+       asm volatile("lidt %w0"::"m" (*ptr));
+}
+
+static inline void store_idt(struct desc_ptr *dtr)
+{
+       asm("sidt %w0":"=m" (*dtr));
+}
+
 static inline void set_tssldt_descriptor(void *ptr, unsigned long tss, unsigned type, 
                                         unsigned size) 
 { 
index d9ee5e52e91b28b9418c5a0ad61ff291ea0d51c9..87a715367a1b11a9db24d569682d22f780352be7 100644 (file)
@@ -5,6 +5,9 @@ struct dev_archdata {
 #ifdef CONFIG_ACPI
        void    *acpi_handle;
 #endif
+#ifdef CONFIG_DMAR
+       void *iommu; /* hook for IOMMU specific extension */
+#endif
 };
 
 #endif /* _ASM_X86_DEVICE_H */
index 6a2d26cb5da641fc169be3cc9eea47fe30124448..55f01bd9e556f9c2519d90991475f9507e45f67a 100644 (file)
@@ -45,9 +45,9 @@ dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
        WARN_ON(nents == 0 || sglist[0].length == 0);
 
        for_each_sg(sglist, sg, nents, i) {
-               BUG_ON(!sg->page);
+               BUG_ON(!sg_page(sg));
 
-               sg->dma_address = page_to_phys(sg->page) + sg->offset;
+               sg->dma_address = sg_phys(sg);
        }
 
        flush_write_buffers();
index 5d4d2183e5db5b3ace16e06536cc098b198b5934..3e214f39fad3df2b9674d1b1f9cb1d8c9abd3338 100644 (file)
@@ -1,5 +1,33 @@
+#ifndef __ASM_E820_H
+#define __ASM_E820_H
+#define E820MAP        0x2d0           /* our map */
+#define E820MAX        128             /* number of entries in E820MAP */
+#define E820NR 0x1e8           /* # entries in E820MAP */
+
+#define E820_RAM       1
+#define E820_RESERVED  2
+#define E820_ACPI      3
+#define E820_NVS       4
+
+#ifndef __ASSEMBLY__
+struct e820entry {
+       __u64 addr;     /* start of memory segment */
+       __u64 size;     /* size of memory segment */
+       __u32 type;     /* type of memory segment */
+} __attribute__((packed));
+
+struct e820map {
+       __u32 nr_map;
+       struct e820entry map[E820MAX];
+};
+#endif /* __ASSEMBLY__ */
+
+#ifdef __KERNEL__
 #ifdef CONFIG_X86_32
 # include "e820_32.h"
 #else
 # include "e820_64.h"
 #endif
+#endif /* __KERNEL__ */
+
+#endif  /* __ASM_E820_H */
index cf67dbb1db79a21e8430be37597b3a42196ad948..03f60c690c8a147cdf1c9296e759023d1b17f054 100644 (file)
 #ifndef __E820_HEADER
 #define __E820_HEADER
 
-#define E820MAP        0x2d0           /* our map */
-#define E820MAX        128             /* number of entries in E820MAP */
-#define E820NR 0x1e8           /* # entries in E820MAP */
-
-#define E820_RAM       1
-#define E820_RESERVED  2
-#define E820_ACPI      3
-#define E820_NVS       4
-
 #define HIGH_MEMORY    (1024*1024)
 
 #ifndef __ASSEMBLY__
 
-struct e820entry {
-       u64 addr;       /* start of memory segment */
-       u64 size;       /* size of memory segment */
-       u32 type;       /* type of memory segment */
-} __attribute__((packed));
-
-struct e820map {
-       u32 nr_map;
-       struct e820entry map[E820MAX];
-};
-
 extern struct e820map e820;
 
 extern int e820_all_mapped(unsigned long start, unsigned long end,
@@ -56,5 +36,4 @@ static inline void e820_mark_nosave_regions(void)
 #endif
 
 #endif/*!__ASSEMBLY__*/
-
 #endif/*__E820_HEADER*/
index 3486e701bd8656f5e5a782cf60b892e656509756..0bd4787a5d575cf3675103ef114f3ce0ea0e9c8a 100644 (file)
 #ifndef __E820_HEADER
 #define __E820_HEADER
 
-#define E820MAP        0x2d0           /* our map */
-#define E820MAX        128             /* number of entries in E820MAP */
-#define E820NR 0x1e8           /* # entries in E820MAP */
-
-#define E820_RAM       1
-#define E820_RESERVED  2
-#define E820_ACPI      3
-#define E820_NVS       4
-
 #ifndef __ASSEMBLY__
-struct e820entry {
-       u64 addr;       /* start of memory segment */
-       u64 size;       /* size of memory segment */
-       u32 type;       /* type of memory segment */
-} __attribute__((packed));
-
-struct e820map {
-       u32 nr_map;
-       struct e820entry map[E820MAX];
-};
-
 extern unsigned long find_e820_area(unsigned long start, unsigned long end, 
                                    unsigned size);
 extern void add_memory_region(unsigned long start, unsigned long size, 
index d94898831bac6d2e66ecaaa75972789841048bd5..771af336734fc73aab39d03a8414f54cfadaad71 100644 (file)
@@ -38,6 +38,8 @@ extern int geode_get_dev_base(unsigned int dev);
 #define MSR_LBAR_ACPI          0x5140000E
 #define MSR_LBAR_PMS           0x5140000F
 
+#define MSR_DIVIL_SOFT_RESET   0x51400017
+
 #define MSR_PIC_YSEL_LOW       0x51400020
 #define MSR_PIC_YSEL_HIGH      0x51400021
 #define MSR_PIC_ZSEL_LOW       0x51400022
index d4ab6db050b6cc0646e564a1a29039853bde249e..b1f3c1ea55d959687f278b0107b63a96e9c69e8e 100644 (file)
@@ -3,12 +3,6 @@
 
 #ifdef CONFIG_HPET_TIMER
 
-/*
- * Documentation on HPET can be found at:
- *      http://www.intel.com/ial/home/sp/pcmmspec.htm
- *      ftp://download.intel.com/ial/home/sp/mmts098.pdf
- */
-
 #define HPET_MMAP_SIZE         1024
 
 #define HPET_ID                        0x000
@@ -64,6 +58,7 @@
 /* hpet memory map physical address */
 extern unsigned long hpet_address;
 extern unsigned long force_hpet_address;
+extern int hpet_force_user;
 extern int is_hpet_enabled(void);
 extern int hpet_enable(void);
 extern unsigned long hpet_readl(unsigned long a);
index e7817a3d6578009f29d750884010933266ca5f3c..42130adf9c7c36ce71a0e1d71da21b089974992a 100644 (file)
@@ -62,7 +62,6 @@ static __inline__ unsigned long ide_default_io_base(int index)
        }
 }
 
-#define IDE_ARCH_OBSOLETE_INIT
 #define ide_default_io_ctl(base)       ((base) + 0x206) /* obsolete */
 
 #ifdef CONFIG_BLK_DEV_IDEPCI
index d9f2e54324d508729e88c2195034937fc2e185b9..e2c13675ee4e8c84504e6a72a7cffaa8c9ae8b4b 100644 (file)
@@ -133,4 +133,6 @@ void enable_NMI_through_LVT0 (void * dummy);
 
 extern spinlock_t i8259A_lock;
 
+extern int timer_over_8254;
+
 #endif
index a7c75ea408a8072ed35aca77bf9be85b2ef525e5..6d011bd6067d8a0f60a10d4874576b98c64e9d7f 100644 (file)
@@ -119,7 +119,7 @@ static inline void send_IPI_mask_sequence(cpumask_t mask, int vector)
         */
        local_irq_save(flags);
        for_each_cpu_mask(query_cpu, mask) {
-               __send_IPI_dest_field(x86_cpu_to_apicid[query_cpu],
+               __send_IPI_dest_field(per_cpu(x86_cpu_to_apicid, query_cpu),
                                      vector, APIC_DEST_PHYSICAL);
        }
        local_irq_restore(flags);
index 36f310632c49a8bdc174f04a70c92841f7276f79..aca9c96e8e6b04308fcf10ecd817a046b853de39 100644 (file)
@@ -45,4 +45,7 @@ unsigned int do_IRQ(struct pt_regs *regs);
 void init_IRQ(void);
 void __init native_init_IRQ(void);
 
+/* Interrupt vector management */
+extern DECLARE_BITMAP(used_vectors, NR_VECTORS);
+
 #endif /* _ASM_IRQ_H */
index ef2003ebc6f9b3e588495125972db716bbe16af2..6ec6ceed95a718ec9d3c91f6004a459781dee74b 100644 (file)
  */
 
 
-#ifdef __KERNEL__
-
 #include <linux/types.h>
 
 struct ist_info {
-       u32 signature;
-       u32 command;
-       u32 event;
-       u32 perf_level;
+       __u32 signature;
+       __u32 command;
+       __u32 event;
+       __u32 perf_level;
 };
 
+#ifdef __KERNEL__
+
 extern struct ist_info ist_info;
 
 #endif /* __KERNEL__ */
diff --git a/include/asm-x86/lguest.h b/include/asm-x86/lguest.h
new file mode 100644 (file)
index 0000000..ccd3384
--- /dev/null
@@ -0,0 +1,86 @@
+#ifndef _X86_LGUEST_H
+#define _X86_LGUEST_H
+
+#define GDT_ENTRY_LGUEST_CS    10
+#define GDT_ENTRY_LGUEST_DS    11
+#define LGUEST_CS              (GDT_ENTRY_LGUEST_CS * 8)
+#define LGUEST_DS              (GDT_ENTRY_LGUEST_DS * 8)
+
+#ifndef __ASSEMBLY__
+#include <asm/desc.h>
+
+#define GUEST_PL 1
+
+/* Every guest maps the core switcher code. */
+#define SHARED_SWITCHER_PAGES \
+       DIV_ROUND_UP(end_switcher_text - start_switcher_text, PAGE_SIZE)
+/* Pages for switcher itself, then two pages per cpu */
+#define TOTAL_SWITCHER_PAGES (SHARED_SWITCHER_PAGES + 2 * NR_CPUS)
+
+/* We map at -4M for ease of mapping into the guest (one PTE page). */
+#define SWITCHER_ADDR 0xFFC00000
+
+/* Found in switcher.S */
+extern unsigned long default_idt_entries[];
+
+struct lguest_regs
+{
+       /* Manually saved part. */
+       unsigned long eax, ebx, ecx, edx;
+       unsigned long esi, edi, ebp;
+       unsigned long gs;
+       unsigned long fs, ds, es;
+       unsigned long trapnum, errcode;
+       /* Trap pushed part */
+       unsigned long eip;
+       unsigned long cs;
+       unsigned long eflags;
+       unsigned long esp;
+       unsigned long ss;
+};
+
+/* This is a guest-specific page (mapped ro) into the guest. */
+struct lguest_ro_state
+{
+       /* Host information we need to restore when we switch back. */
+       u32 host_cr3;
+       struct Xgt_desc_struct host_idt_desc;
+       struct Xgt_desc_struct host_gdt_desc;
+       u32 host_sp;
+
+       /* Fields which are used when guest is running. */
+       struct Xgt_desc_struct guest_idt_desc;
+       struct Xgt_desc_struct guest_gdt_desc;
+       struct i386_hw_tss guest_tss;
+       struct desc_struct guest_idt[IDT_ENTRIES];
+       struct desc_struct guest_gdt[GDT_ENTRIES];
+};
+
+struct lguest_arch
+{
+       /* The GDT entries copied into lguest_ro_state when running. */
+       struct desc_struct gdt[GDT_ENTRIES];
+
+       /* The IDT entries: some copied into lguest_ro_state when running. */
+       struct desc_struct idt[IDT_ENTRIES];
+
+       /* The address of the last guest-visible pagefault (ie. cr2). */
+       unsigned long last_pagefault;
+};
+
+static inline void lguest_set_ts(void)
+{
+       u32 cr0;
+
+       cr0 = read_cr0();
+       if (!(cr0 & 8))
+               write_cr0(cr0|8);
+}
+
+/* Full 4G segment descriptors, suitable for CS and DS. */
+#define FULL_EXEC_SEGMENT ((struct desc_struct){0x0000ffff, 0x00cf9b00})
+#define FULL_SEGMENT ((struct desc_struct){0x0000ffff, 0x00cf9300})
+
+#endif /* __ASSEMBLY__ */
+
+#endif
diff --git a/include/asm-x86/lguest_hcall.h b/include/asm-x86/lguest_hcall.h
new file mode 100644 (file)
index 0000000..f948491
--- /dev/null
@@ -0,0 +1,71 @@
+/* Architecture specific portion of the lguest hypercalls */
+#ifndef _X86_LGUEST_HCALL_H
+#define _X86_LGUEST_HCALL_H
+
+#define LHCALL_FLUSH_ASYNC     0
+#define LHCALL_LGUEST_INIT     1
+#define LHCALL_CRASH           2
+#define LHCALL_LOAD_GDT                3
+#define LHCALL_NEW_PGTABLE     4
+#define LHCALL_FLUSH_TLB       5
+#define LHCALL_LOAD_IDT_ENTRY  6
+#define LHCALL_SET_STACK       7
+#define LHCALL_TS              8
+#define LHCALL_SET_CLOCKEVENT  9
+#define LHCALL_HALT            10
+#define LHCALL_SET_PTE         14
+#define LHCALL_SET_PMD         15
+#define LHCALL_LOAD_TLS                16
+#define LHCALL_NOTIFY          17
+
+/*G:031 First, how does our Guest contact the Host to ask for privileged
+ * operations?  There are two ways: the direct way is to make a "hypercall",
+ * to make requests of the Host Itself.
+ *
+ * Our hypercall mechanism uses the highest unused trap code (traps 32 and
+ * above are used by real hardware interrupts).  Seventeen hypercalls are
+ * available: the hypercall number is put in the %eax register, and the
+ * arguments (when required) are placed in %edx, %ebx and %ecx.  If a return
+ * value makes sense, it's returned in %eax.
+ *
+ * Grossly invalid calls result in Sudden Death at the hands of the vengeful
+ * Host, rather than returning failure.  This reflects Winston Churchill's
+ * definition of a gentleman: "someone who is only rude intentionally". */
+#define LGUEST_TRAP_ENTRY 0x1F
+
+#ifndef __ASSEMBLY__
+#include <asm/hw_irq.h>
+
+static inline unsigned long
+hcall(unsigned long call,
+      unsigned long arg1, unsigned long arg2, unsigned long arg3)
+{
+       /* "int" is the Intel instruction to trigger a trap. */
+       asm volatile("int $" __stringify(LGUEST_TRAP_ENTRY)
+                      /* The call is in %eax (aka "a"), and can be replaced */
+                    : "=a"(call)
+                      /* The other arguments are in %eax, %edx, %ebx & %ecx */
+                    : "a"(call), "d"(arg1), "b"(arg2), "c"(arg3)
+                      /* "memory" means this might write somewhere in memory.
+                       * This isn't true for all calls, but it's safe to tell
+                       * gcc that it might happen so it doesn't get clever. */
+                    : "memory");
+       return call;
+}
+/*:*/
+
+void async_hcall(unsigned long call,
+                unsigned long arg1, unsigned long arg2, unsigned long arg3);
+
+/* Can't use our min() macro here: needs to be a constant */
+#define LGUEST_IRQS (NR_IRQS < 32 ? NR_IRQS: 32)
+
+#define LHCALL_RING_SIZE 64
+struct hcall_args
+{
+       /* These map directly onto eax, ebx, ecx, edx in struct lguest_regs */
+       unsigned long arg0, arg2, arg3, arg1;
+};
+
+#endif /* !__ASSEMBLY__ */
+#endif /* _I386_LGUEST_HCALL_H */
index a02eb2991349a699c74635ef6c9cd2ee2b87cf0d..a4944732be04d9fa1a75d66ab5799f8f96be6eda 100644 (file)
 #define MSR_P6_EVNTSEL0                        0x00000186
 #define MSR_P6_EVNTSEL1                        0x00000187
 
-/* K7/K8 MSRs. Not complete. See the architecture manual for a more
+/* AMD64 MSRs. Not complete. See the architecture manual for a more
    complete list. */
+
+#define MSR_AMD64_IBSFETCHCTL          0xc0011030
+#define MSR_AMD64_IBSFETCHLINAD                0xc0011031
+#define MSR_AMD64_IBSFETCHPHYSAD       0xc0011032
+#define MSR_AMD64_IBSOPCTL             0xc0011033
+#define MSR_AMD64_IBSOPRIP             0xc0011034
+#define MSR_AMD64_IBSOPDATA            0xc0011035
+#define MSR_AMD64_IBSOPDATA2           0xc0011036
+#define MSR_AMD64_IBSOPDATA3           0xc0011037
+#define MSR_AMD64_IBSDCLINAD           0xc0011038
+#define MSR_AMD64_IBSDCPHYSAD          0xc0011039
+#define MSR_AMD64_IBSCTL               0xc001103a
+
+/* K8 MSRs */
+#define MSR_K8_TOP_MEM1                        0xc001001a
+#define MSR_K8_TOP_MEM2                        0xc001001d
+#define MSR_K8_SYSCFG                  0xc0010010
+#define MSR_K8_HWCR                    0xc0010015
+#define MSR_K8_ENABLE_C1E              0xc0010055
+#define K8_MTRRFIXRANGE_DRAM_ENABLE    0x00040000 /* MtrrFixDramEn bit    */
+#define K8_MTRRFIXRANGE_DRAM_MODIFY    0x00080000 /* MtrrFixDramModEn bit */
+#define K8_MTRR_RDMEM_WRMEM_MASK       0x18181818 /* Mask: RdMem|WrMem    */
+
+/* K7 MSRs */
 #define MSR_K7_EVNTSEL0                        0xc0010000
 #define MSR_K7_PERFCTR0                        0xc0010004
 #define MSR_K7_EVNTSEL1                        0xc0010001
 #define MSR_K7_PERFCTR2                        0xc0010006
 #define MSR_K7_EVNTSEL3                        0xc0010003
 #define MSR_K7_PERFCTR3                        0xc0010007
-#define MSR_K8_TOP_MEM1                        0xc001001a
 #define MSR_K7_CLK_CTL                 0xc001001b
-#define MSR_K8_TOP_MEM2                        0xc001001d
-#define MSR_K8_SYSCFG                  0xc0010010
-
-#define K8_MTRRFIXRANGE_DRAM_ENABLE    0x00040000 /* MtrrFixDramEn bit    */
-#define K8_MTRRFIXRANGE_DRAM_MODIFY    0x00080000 /* MtrrFixDramModEn bit */
-#define K8_MTRR_RDMEM_WRMEM_MASK       0x18181818 /* Mask: RdMem|WrMem    */
-
 #define MSR_K7_HWCR                    0xc0010015
-#define MSR_K8_HWCR                    0xc0010015
 #define MSR_K7_FID_VID_CTL             0xc0010041
 #define MSR_K7_FID_VID_STATUS          0xc0010042
-#define MSR_K8_ENABLE_C1E              0xc0010055
 
 /* K6 MSRs */
 #define MSR_K6_EFER                    0xc0000080
index acd4b339c49b411b273949c0c70b799696844bd8..ed3e70d8d04bfc3a94a56f38b177850d756cad1a 100644 (file)
 #include <linux/threads.h>
 #include <asm/paravirt.h>
 
-#ifndef _I386_BITOPS_H
-#include <asm/bitops.h>
-#endif
-
+#include <linux/bitops.h>
 #include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
index a79f5355e3b06191287c6142291cfab3923a7743..9b0ff477b39e7dc2021196619148969bffe2b355 100644 (file)
@@ -9,7 +9,7 @@
  * the x86-64 page table tree.
  */
 #include <asm/processor.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 #include <linux/threads.h>
 #include <asm/pda.h>
 
index 83800e7496eef6767c0a6875b6da9b4ef1e56855..13976b0868376d13f2fa1ad58936948f5a05fab9 100644 (file)
@@ -79,6 +79,7 @@ struct cpuinfo_x86 {
        unsigned char booted_cores;     /* number of cores as seen by OS */
        __u8 phys_proc_id;              /* Physical processor id. */
        __u8 cpu_core_id;               /* Core id */
+       __u8 cpu_index;                 /* index into per_cpu list */
 #endif
 } __attribute__((__aligned__(SMP_CACHE_BYTES)));
 
@@ -103,14 +104,19 @@ extern struct tss_struct doublefault_tss;
 DECLARE_PER_CPU(struct tss_struct, init_tss);
 
 #ifdef CONFIG_SMP
-extern struct cpuinfo_x86 cpu_data[];
-#define current_cpu_data cpu_data[smp_processor_id()]
+DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info);
+#define cpu_data(cpu)          per_cpu(cpu_info, cpu)
+#define current_cpu_data       cpu_data(smp_processor_id())
 #else
-#define cpu_data (&boot_cpu_data)
-#define current_cpu_data boot_cpu_data
+#define cpu_data(cpu)          boot_cpu_data
+#define current_cpu_data       boot_cpu_data
 #endif
 
-extern int cpu_llc_id[NR_CPUS];
+/*
+ * the following now lives in the per cpu area:
+ * extern      int cpu_llc_id[NR_CPUS];
+ */
+DECLARE_PER_CPU(u8, cpu_llc_id);
 extern char ignore_fpu_irq;
 
 void __init cpu_detect(struct cpuinfo_x86 *c);
index f422becbddd9d3f91deb6da6f81a36a004744652..e4f19970a82b8bd9ac6de525dccbe8b662c7d3ab 100644 (file)
@@ -74,6 +74,7 @@ struct cpuinfo_x86 {
        __u8    booted_cores;   /* number of cores as seen by OS */
        __u8    phys_proc_id;   /* Physical Processor id. */
        __u8    cpu_core_id;    /* Core id. */
+       __u8    cpu_index;      /* index into per_cpu list */
 #endif
 } ____cacheline_aligned;
 
@@ -88,11 +89,12 @@ struct cpuinfo_x86 {
 #define X86_VENDOR_UNKNOWN 0xff
 
 #ifdef CONFIG_SMP
-extern struct cpuinfo_x86 cpu_data[];
-#define current_cpu_data cpu_data[smp_processor_id()]
+DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info);
+#define cpu_data(cpu)          per_cpu(cpu_info, cpu)
+#define current_cpu_data       cpu_data(smp_processor_id())
 #else
-#define cpu_data (&boot_cpu_data)
-#define current_cpu_data boot_cpu_data
+#define cpu_data(cpu)          boot_cpu_data
+#define current_cpu_data       boot_cpu_data
 #endif
 
 extern char ignore_irq13;
@@ -390,12 +392,6 @@ static inline void sync_core(void)
        asm volatile("cpuid" : "=a" (tmp) : "0" (1) : "ebx","ecx","edx","memory");
 } 
 
-#define ARCH_HAS_PREFETCH
-static inline void prefetch(void *x) 
-{ 
-       asm volatile("prefetcht0 (%0)" :: "r" (x));
-} 
-
 #define ARCH_HAS_PREFETCHW 1
 static inline void prefetchw(void *x) 
 { 
index c44a3a93b5a49f06c686eed86d508377b0156f49..dabba55f7ed8814543f546bbedebeedae48f4a38 100644 (file)
@@ -83,8 +83,6 @@ extern unsigned tsc_khz;
 extern int reboot_force;
 extern int notsc_setup(char *);
 
-extern int timer_over_8254;
-
 extern int gsi_irq_sharing(int gsi);
 
 extern int force_mwait;
index 6002597b9e12212b8e0986f9b7070d2d0b5ba041..78d063dabe0ae6589dbbe1c0e8613d27058d4b10 100644 (file)
@@ -55,6 +55,8 @@ static inline int v8086_mode(struct pt_regs *regs)
 }
 
 #define instruction_pointer(regs) ((regs)->eip)
+#define frame_pointer(regs) ((regs)->ebp)
+#define stack_pointer(regs) ((regs)->esp)
 #define regs_return_value(regs) ((regs)->eax)
 
 extern unsigned long profile_pc(struct pt_regs *regs);
index 7f166ccb0606786991e931c9995c6dfe9514809b..7bfe61e1b7052c5c1e74b03ae72db585104feb9d 100644 (file)
@@ -40,6 +40,8 @@ struct pt_regs {
 #define user_mode(regs) (!!((regs)->cs & 3))
 #define user_mode_vm(regs) user_mode(regs)
 #define instruction_pointer(regs) ((regs)->rip)
+#define frame_pointer(regs) ((regs)->rbp)
+#define stack_pointer(regs) ((regs)->rsp)
 #define regs_return_value(regs) ((regs)->rax)
 
 extern unsigned long profile_pc(struct pt_regs *regs);
index bd5164aa8f63e24f013b4b2dea3477a1df6f4e4f..0e7d997a34be7c4aaf16da9201c7b2700de4157e 100644 (file)
@@ -4,7 +4,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page                *page;
+#ifdef CONFIG_DEBUG_SG
+    unsigned long      sg_magic;
+#endif
+    unsigned long      page_link;
     unsigned int       offset;
     dma_addr_t         dma_address;
     unsigned int       length;
index ef3986ba4b7909ba91805cfa341b3f4690262e0f..1847c72befeb9aca69a3402c6a243c001b728c20 100644 (file)
@@ -4,7 +4,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page                *page;
+#ifdef CONFIG_DEBUG_SG
+    unsigned long      sg_magic;
+#endif
+    unsigned long      page_link;
     unsigned int       offset;
     unsigned int       length;
     dma_addr_t         dma_address;
index ee46038d126c07fac09499d7acdf99ac2dfdc684..7056d86845221c6d224545f7c8642a35c7cd028f 100644 (file)
@@ -11,7 +11,7 @@
 #endif
 
 #if defined(CONFIG_X86_LOCAL_APIC) && !defined(__ASSEMBLY__)
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 #include <asm/mpspec.h>
 #include <asm/apic.h>
 #ifdef CONFIG_X86_IO_APIC
@@ -39,9 +39,11 @@ extern void lock_ipi_call_lock(void);
 extern void unlock_ipi_call_lock(void);
 
 #define MAX_APICID 256
-extern u8 x86_cpu_to_apicid[];
+extern u8 __initdata x86_cpu_to_apicid_init[];
+extern void *x86_cpu_to_apicid_ptr;
+DECLARE_PER_CPU(u8, x86_cpu_to_apicid);
 
-#define cpu_physical_id(cpu)   x86_cpu_to_apicid[cpu]
+#define cpu_physical_id(cpu)   per_cpu(x86_cpu_to_apicid, cpu)
 
 extern void set_cpu_sibling_map(int cpu);
 
index d30e9b684fdd1730e5306313e9d82d2d3f2a95e2..6f0e0273b6462cf3ad9a4a3a55e4c3091ab91890 100644 (file)
@@ -37,6 +37,8 @@ extern void lock_ipi_call_lock(void);
 extern void unlock_ipi_call_lock(void);
 extern int smp_num_siblings;
 extern void smp_send_reschedule(int cpu);
+extern int smp_call_function_mask(cpumask_t mask, void (*func)(void *),
+                                 void *info, int wait);
 
 /*
  * cpu_sibling_map and cpu_core_map now live
@@ -47,7 +49,7 @@ extern void smp_send_reschedule(int cpu);
  */
 DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
 DECLARE_PER_CPU(cpumask_t, cpu_core_map);
-extern u8 cpu_llc_id[NR_CPUS];
+DECLARE_PER_CPU(u8, cpu_llc_id);
 
 #define SMP_TRAMPOLINE_BASE 0x6000
 
@@ -84,7 +86,9 @@ static inline int hard_smp_processor_id(void)
  * Some lowlevel functions might want to know about
  * the real APIC ID <-> CPU # mapping.
  */
-extern u8 x86_cpu_to_apicid[NR_CPUS];  /* physical ID */
+extern u8 __initdata x86_cpu_to_apicid_init[];
+extern void *x86_cpu_to_apicid_ptr;
+DECLARE_PER_CPU(u8, x86_cpu_to_apicid);        /* physical ID */
 extern u8 bios_cpu_apicid[];
 
 static inline int cpu_present_to_apicid(int mps_cpu)
@@ -115,8 +119,9 @@ static __inline int logical_smp_processor_id(void)
 }
 
 #ifdef CONFIG_SMP
-#define cpu_physical_id(cpu)           x86_cpu_to_apicid[cpu]
+#define cpu_physical_id(cpu)           per_cpu(x86_cpu_to_apicid, cpu)
 #else
+extern unsigned int boot_cpu_id;
 #define cpu_physical_id(cpu)           boot_cpu_id
 #endif /* !CONFIG_SMP */
 #endif
index b897e8cb55fbb7a73a43d4f1ac7a16a20f3d56d2..9440a7a1b99ab55fdb38e70333cdcdf9bc83e1d0 100644 (file)
@@ -53,3 +53,5 @@ extern unsigned long saved_rdi;
 
 /* routines for saving/restoring kernel state */
 extern int acpi_save_state_mem(void);
+extern char core_restore_code;
+extern char restore_registers;
index db6283eb5e46d6f53ff24d33b0a5ec091e5a9fd0..ef8468883bac59a4451562ce1fc190e81ea85bc6 100644 (file)
@@ -315,5 +315,6 @@ extern unsigned long arch_align_stack(unsigned long sp);
 extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
 
 void default_idle(void);
+void __show_registers(struct pt_regs *, int all);
 
 #endif
index a50fa6741486ae8cafb7525cd6335c7852d11930..2bd5b95e2048065ee2979319ef6c4bcf18e37b13 100644 (file)
@@ -78,7 +78,6 @@
  *  - flush_tlb_page(vma, vmaddr) flushes one page
  *  - flush_tlb_range(vma, start, end) flushes a range of pages
  *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
- *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
  *  - flush_tlb_others(cpumask, mm, va) flushes a TLBs on other cpus
  *
  * ..but the i386 has somewhat limited tlb flushing capabilities,
@@ -166,10 +165,4 @@ static inline void flush_tlb_kernel_range(unsigned long start,
        flush_tlb_all();
 }
 
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-                                     unsigned long start, unsigned long end)
-{
-       /* i386 does not keep any page table caches in TLB */
-}
-
 #endif /* _I386_TLBFLUSH_H */
index 888eb4abdd07a2fffa1c3ca3486962a3b56d7be5..7731fd23d572362fe08577649a0f33c6a5d5e308 100644 (file)
@@ -31,7 +31,6 @@ static inline void __flush_tlb_all(void)
  *  - flush_tlb_page(vma, vmaddr) flushes one page
  *  - flush_tlb_range(vma, start, end) flushes a range of pages
  *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
- *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
  *
  * x86-64 can only flush individual pages or full VMs. For a range flush
  * we always do the full VM. Might be worth trying if for a small
@@ -98,12 +97,4 @@ static inline void flush_tlb_kernel_range(unsigned long start,
        flush_tlb_all();
 }
 
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-                                     unsigned long start, unsigned long end)
-{
-       /* x86_64 does not keep any page table caches in a software TLB.
-          The CPUs do in their hardware TLBs, but they are handled
-          by the normal TLB flushing algorithms. */
-}
-
 #endif /* _X8664_TLBFLUSH_H */
index ae1074603c4b1e4508059fc40d08ef83d1ecb99a..9040f5a612780ff4421838bc152d29cab0be4f72 100644 (file)
@@ -28,8 +28,8 @@
 #define _ASM_I386_TOPOLOGY_H
 
 #ifdef CONFIG_X86_HT
-#define topology_physical_package_id(cpu)      (cpu_data[cpu].phys_proc_id)
-#define topology_core_id(cpu)                  (cpu_data[cpu].cpu_core_id)
+#define topology_physical_package_id(cpu)      (cpu_data(cpu).phys_proc_id)
+#define topology_core_id(cpu)                  (cpu_data(cpu).cpu_core_id)
 #define topology_core_siblings(cpu)            (per_cpu(cpu_core_map, cpu))
 #define topology_thread_siblings(cpu)          (per_cpu(cpu_sibling_map, cpu))
 #endif
index 848c17f922262d0e7fd9733c0baa1b7a58e347a0..a718dda037e097480bf7f49d4d2f566fb530582f 100644 (file)
@@ -5,7 +5,7 @@
 #ifdef CONFIG_NUMA
 
 #include <asm/mpspec.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 
 extern cpumask_t cpu_online_map;
 
@@ -56,8 +56,8 @@ extern int __node_distance(int, int);
 #endif
 
 #ifdef CONFIG_SMP
-#define topology_physical_package_id(cpu)      (cpu_data[cpu].phys_proc_id)
-#define topology_core_id(cpu)                  (cpu_data[cpu].cpu_core_id)
+#define topology_physical_package_id(cpu)      (cpu_data(cpu).phys_proc_id)
+#define topology_core_id(cpu)                  (cpu_data(cpu).cpu_core_id)
 #define topology_core_siblings(cpu)            (per_cpu(cpu_core_map, cpu))
 #define topology_thread_siblings(cpu)          (per_cpu(cpu_sibling_map, cpu))
 #define mc_capable()                   (boot_cpu_data.x86_max_cores > 1)
index 1c1e0d933eea8311db44907231d94a62b025c334..23261e8f2e5ac4c15cf36a23921f3cd9cb654b5f 100644 (file)
 
 #ifdef __KERNEL__
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <asm/processor.h>
 #include <asm/byteorder.h>
 #include <asm/system.h>
@@ -108,6 +112,7 @@ static inline int fls (unsigned int x)
 #endif
 
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 #include <asm-generic/bitops/sched.h>
 #include <asm-generic/bitops/minix.h>
 
index 82b03b3a2ee6a4103726e69006319ba84158fb1e..8bd9d2c02a24bacb50cebd103492331e500774b7 100644 (file)
@@ -58,11 +58,10 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
        BUG_ON(direction == DMA_NONE);
 
        for (i = 0; i < nents; i++, sg++ ) {
-               BUG_ON(!sg->page);
+               BUG_ON(!sg_page(sg));
 
-               sg->dma_address = page_to_phys(sg->page) + sg->offset;
-               consistent_sync(page_address(sg->page) + sg->offset,
-                               sg->length, direction);
+               sg->dma_address = sg_phys(sg);
+               consistent_sync(sg_virt(sg), sg->length, direction);
        }
 
        return nents;
@@ -128,8 +127,7 @@ dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
 {
        int i;
        for (i = 0; i < nelems; i++, sg++)
-               consistent_sync(page_address(sg->page) + sg->offset,
-                               sg->length, dir);
+               consistent_sync(sg_virt(sg), sg->length, dir);
 }
 
 static inline void
@@ -138,8 +136,7 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
 {
        int i;
        for (i = 0; i < nelems; i++, sg++)
-               consistent_sync(page_address(sg->page) + sg->offset,
-                               sg->length, dir);
+               consistent_sync(sg_virt(sg), sg->length, dir);
 }
 static inline int
 dma_mapping_error(dma_addr_t dma_addr)
index ca337a2942908d11e750e4c62d1651696c767cb8..810080bb0a2b2cfa498c39fed32c11d2897763bd 100644 (file)
 #include <asm/types.h>
 
 struct scatterlist {
-       struct page     *page;
+#ifdef CONFIG_DEBUG_SG
+       unsigned long   sg_magic;
+#endif
+       unsigned long   page_link;
        unsigned int    offset;
        dma_addr_t      dma_address;
        unsigned int    length;
index 7c637b3c352cf0fcae1a903057e17ee30567d7c0..46d240074f747aa622711b35d0b130cedba6b812 100644 (file)
@@ -41,17 +41,6 @@ extern void flush_tlb_range(struct vm_area_struct*,unsigned long,unsigned long);
 
 #define flush_tlb_kernel_range(start,end) flush_tlb_all()
 
-
-/* This is calld in munmap when we have freed up some page-table pages.
- * We don't need to do anything here, there's nothing special about our
- * page-table pages.
- */
-
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-                                      unsigned long start, unsigned long end)
-{
-}
-
 /* TLB operations. */
 
 static inline unsigned long itlb_probe(unsigned long addr)
index 7ac8303c8471d5cff03a82def3456af934f4c291..6a65231bc7855a8fc918ab22bcd3402cff3df218 100644 (file)
@@ -47,6 +47,7 @@ header-y += coda_psdev.h
 header-y += coff.h
 header-y += comstats.h
 header-y += const.h
+header-y += cgroupstats.h
 header-y += cycx_cfm.h
 header-y += dlm_device.h
 header-y += dlm_netlink.h
@@ -185,6 +186,7 @@ unifdef-y += cyclades.h
 unifdef-y += dccp.h
 unifdef-y += dirent.h
 unifdef-y += dlm.h
+unifdef-y += edd.h
 unifdef-y += elfcore.h
 unifdef-y += errno.h
 unifdef-y += errqueue.h
@@ -305,6 +307,7 @@ unifdef-y += rtc.h
 unifdef-y += rtnetlink.h
 unifdef-y += scc.h
 unifdef-y += sched.h
+unifdef-y += screen_info.h
 unifdef-y += sdla.h
 unifdef-y += selinux_netlink.h
 unifdef-y += sem.h
@@ -340,6 +343,9 @@ unifdef-y += user.h
 unifdef-y += utsname.h
 unifdef-y += videodev2.h
 unifdef-y += videodev.h
+unifdef-y += virtio_config.h
+unifdef-y += virtio_blk.h
+unifdef-y += virtio_net.h
 unifdef-y += wait.h
 unifdef-y += wanrouter.h
 unifdef-y += watchdog.h
index bf5e0009de75cd1f12c61e4f96a303f60dc907f0..8ccedf7a0a5af4ce4679294bfacb44f597eebb73 100644 (file)
@@ -189,32 +189,6 @@ extern int ec_transaction(u8 command,
 extern int acpi_blacklisted(void);
 extern void acpi_bios_year(char *s);
 
-#define        ACPI_CSTATE_LIMIT_DEFINED       /* for driver builds */
-#ifdef CONFIG_ACPI
-
-/*
- * Set highest legal C-state
- * 0: C0 okay, but not C1
- * 1: C1 okay, but not C2
- * 2: C2 okay, but not C3 etc.
- */
-
-extern unsigned int max_cstate;
-
-static inline unsigned int acpi_get_cstate_limit(void)
-{
-       return max_cstate;
-}
-static inline void acpi_set_cstate_limit(unsigned int new_limit)
-{
-       max_cstate = new_limit;
-       return;
-}
-#else
-static inline unsigned int acpi_get_cstate_limit(void) { return 0; }
-static inline void acpi_set_cstate_limit(unsigned int new_limit) { return; }
-#endif
-
 #ifdef CONFIG_ACPI_NUMA
 int acpi_get_pxm(acpi_handle handle);
 int acpi_get_node(acpi_handle *handle);
index d10e608f232d04e053aa3c2bd8b68a810df6aad8..7ef8de6620010b4a3b22981d8e88e2009235b915 100644 (file)
@@ -232,18 +232,6 @@ int FASTCALL(io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
                __put_ioctx(kioctx);                                    \
 } while (0)
 
-#define in_aio() (unlikely(!is_sync_wait(current->io_wait)))
-
-/* may be used for debugging */
-#define warn_if_async()                                                        \
-do {                                                                   \
-       if (in_aio()) {                                                 \
-               printk(KERN_ERR "%s(%s:%d) called in async context!\n", \
-                       __FUNCTION__, __FILE__, __LINE__);              \
-               dump_stack();                                           \
-       }                                                               \
-} while (0)
-
 #define io_wait_to_kiocb(wait) container_of(wait, struct kiocb, ki_wait)
 
 #include <linux/aio_abi.h>
index 5f921c84827ab19d1b29b779cb2865a4148554da..9754baa1492171fbd89e6512fdf3160eb1a9e279 100644 (file)
  * General Public License for more details.
  */
 
-typedef unsigned short apm_event_t;
-typedef unsigned short apm_eventinfo_t;
+#include <linux/types.h>
+
+struct apm_bios_info {
+       __u16   version;
+       __u16   cseg;
+       __u32   offset;
+       __u16   cseg_16;
+       __u16   dseg;
+       __u16   flags;
+       __u16   cseg_len;
+       __u16   cseg_16_len;
+       __u16   dseg_len;
+};
 
 #ifdef __KERNEL__
 
-#include <linux/types.h>
+typedef unsigned short apm_event_t;
+typedef unsigned short apm_eventinfo_t;
 
 #define APM_CS         (GDT_ENTRY_APMBIOS_BASE * 8)
 #define APM_CS_16      (APM_CS + 8)
 #define APM_DS         (APM_CS_16 + 8)
 
-struct apm_bios_info {
-       u16     version;
-       u16     cseg;
-       u32     offset;
-       u16     cseg_16;
-       u16     dseg;
-       u16     flags;
-       u16     cseg_len;
-       u16     cseg_16_len;
-       u16     dseg_len;
-};
-
 /* Results of APM Installation Check */
 #define APM_16_BIT_SUPPORT     0x0001
 #define APM_32_BIT_SUPPORT     0x0002
index 9ae740936a65268548acd512062dfc5c135f477a..c687816928380ab5e3bb031b05501f56fa6efc53 100644 (file)
@@ -63,6 +63,8 @@
 #define AUDIT_ADD_RULE         1011    /* Add syscall filtering rule */
 #define AUDIT_DEL_RULE         1012    /* Delete syscall filtering rule */
 #define AUDIT_LIST_RULES       1013    /* List syscall filtering rules */
+#define AUDIT_TRIM             1014    /* Trim junk from watched tree */
+#define AUDIT_MAKE_EQUIV       1015    /* Append to watched tree */
 #define AUDIT_TTY_GET          1016    /* Get TTY auditing status */
 #define AUDIT_TTY_SET          1017    /* Set TTY auditing status */
 
 #define AUDIT_SUCCESS   104    /* exit >= 0; value ignored */
 #define AUDIT_WATCH    105
 #define AUDIT_PERM     106
+#define AUDIT_DIR      107
 
 #define AUDIT_ARG0      200
 #define AUDIT_ARG1      (AUDIT_ARG0+1)
@@ -366,8 +369,8 @@ extern void audit_syscall_entry(int arch,
 extern void audit_syscall_exit(int failed, long return_code);
 extern void __audit_getname(const char *name);
 extern void audit_putname(const char *name);
-extern void __audit_inode(const char *name, const struct inode *inode);
-extern void __audit_inode_child(const char *dname, const struct inode *inode,
+extern void __audit_inode(const char *name, const struct dentry *dentry);
+extern void __audit_inode_child(const char *dname, const struct dentry *dentry,
                                const struct inode *parent);
 extern void __audit_ptrace(struct task_struct *t);
 
@@ -381,15 +384,15 @@ static inline void audit_getname(const char *name)
        if (unlikely(!audit_dummy_context()))
                __audit_getname(name);
 }
-static inline void audit_inode(const char *name, const struct inode *inode) {
+static inline void audit_inode(const char *name, const struct dentry *dentry) {
        if (unlikely(!audit_dummy_context()))
-               __audit_inode(name, inode);
+               __audit_inode(name, dentry);
 }
 static inline void audit_inode_child(const char *dname, 
-                                    const struct inode *inode,
+                                    const struct dentry *dentry,
                                     const struct inode *parent) {
        if (unlikely(!audit_dummy_context()))
-               __audit_inode_child(dname, inode, parent);
+               __audit_inode_child(dname, dentry, parent);
 }
 void audit_core_dumps(long signr);
 
@@ -477,9 +480,9 @@ extern int audit_signals;
 #define audit_dummy_context() 1
 #define audit_getname(n) do { ; } while (0)
 #define audit_putname(n) do { ; } while (0)
-#define __audit_inode(n,i) do { ; } while (0)
+#define __audit_inode(n,d) do { ; } while (0)
 #define __audit_inode_child(d,i,p) do { ; } while (0)
-#define audit_inode(n,i) do { ; } while (0)
+#define audit_inode(n,d) do { ; } while (0)
 #define audit_inode_child(d,i,p) do { ; } while (0)
 #define audit_core_dumps(i) do { ; } while (0)
 #define auditsc_get_stamp(c,t,s) do { BUG(); } while (0)
index 6b20af0bbb79d2037cfb3c5aa69d6b3cac2f2e59..7113a32a86ea9fd8816a32625197c8fa3700d2f2 100644 (file)
@@ -18,7 +18,7 @@ static inline void bit_spin_lock(int bitnum, unsigned long *addr)
         */
        preempt_disable();
 #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
-       while (test_and_set_bit(bitnum, addr)) {
+       while (unlikely(test_and_set_bit_lock(bitnum, addr))) {
                while (test_bit(bitnum, addr)) {
                        preempt_enable();
                        cpu_relax();
@@ -36,7 +36,7 @@ static inline int bit_spin_trylock(int bitnum, unsigned long *addr)
 {
        preempt_disable();
 #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
-       if (test_and_set_bit(bitnum, addr)) {
+       if (unlikely(test_and_set_bit_lock(bitnum, addr))) {
                preempt_enable();
                return 0;
        }
@@ -50,10 +50,28 @@ static inline int bit_spin_trylock(int bitnum, unsigned long *addr)
  */
 static inline void bit_spin_unlock(int bitnum, unsigned long *addr)
 {
+#ifdef CONFIG_DEBUG_SPINLOCK
+       BUG_ON(!test_bit(bitnum, addr));
+#endif
 #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+       clear_bit_unlock(bitnum, addr);
+#endif
+       preempt_enable();
+       __release(bitlock);
+}
+
+/*
+ *  bit-based spin_unlock()
+ *  non-atomic version, which can be used eg. if the bit lock itself is
+ *  protecting the rest of the flags in the word.
+ */
+static inline void __bit_spin_unlock(int bitnum, unsigned long *addr)
+{
+#ifdef CONFIG_DEBUG_SPINLOCK
        BUG_ON(!test_bit(bitnum, addr));
-       smp_mb__before_clear_bit();
-       clear_bit(bitnum, addr);
+#endif
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+       __clear_bit_unlock(bitnum, addr);
 #endif
        preempt_enable();
        __release(bitlock);
index 64b4641904fee0415c169d3f20e3bd4cdba71f5c..acad1105d94287af0cba3322e3368efe1b4f38fb 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/types.h>
 #include <linux/bitops.h>
 #include <linux/string.h>
+#include <linux/kernel.h>
 
 /*
  * bitmaps provide bit arrays that consume one or more unsigned
index b9fb8ee3308bd6b2b4699194d47e2a6ecfeb7144..69c1edb9fe54a345f061cf983fe8311805c83154 100644 (file)
@@ -2,6 +2,14 @@
 #define _LINUX_BITOPS_H
 #include <asm/types.h>
 
+#ifdef __KERNEL__
+#define BIT(nr)                        (1UL << (nr))
+#define BIT_MASK(nr)           (1UL << ((nr) % BITS_PER_LONG))
+#define BIT_WORD(nr)           ((nr) / BITS_PER_LONG)
+#define BITS_TO_LONGS(nr)      DIV_ROUND_UP(nr, BITS_PER_LONG)
+#define BITS_PER_BYTE          8
+#endif
+
 /*
  * Include this here because some architectures need generic_ffs/fls in
  * scope
index 8961e7fb755c34bc4f1ea346fbb83854286bc932..bb017edffd56816099064f7367f925c15277aa09 100644 (file)
@@ -56,10 +56,8 @@ typedef struct __user_cap_data_struct {
 
 struct vfs_cap_data {
        __u32 magic_etc;  /* Little endian */
-       struct {
-               __u32 permitted;    /* Little endian */
-               __u32 inheritable;  /* Little endian */
-       } data[1];
+       __u32 permitted;    /* Little endian */
+       __u32 inheritable;  /* Little endian */
 };
 
 #ifdef __KERNEL__
@@ -310,10 +308,6 @@ typedef __u32 kernel_cap_t;
 #define CAP_SETFCAP         31
 
 #ifdef __KERNEL__
-/*
- * Bounding set
- */
-extern kernel_cap_t cap_bset;
 
 /*
  * Internal kernel functions only
index 2b641b176e7f2c51708d0d99b91f5daf41be2549..c6d3e22c0624235e4d1db94d852f6baf5f11d2c7 100644 (file)
@@ -2,7 +2,7 @@
  * -- <linux/cdrom.h>
  * General header file for linux CD-ROM drivers 
  * Copyright (C) 1992         David Giller, rafetmad@oxy.edu
- *               1994, 1995   Eberhard Moenkeberg, emoenke@gwdg.de
+ *               1994, 1995   Eberhard Mönkeberg, emoenke@gwdg.de
  *               1996         David van Leeuwen, david@tm.tno.nl
  *               1997, 1998   Erik Andersen, andersee@debian.org
  *               1998-2002    Jens Axboe, axboe@suse.de
@@ -76,7 +76,7 @@
                                            (struct cdrom_multisession) */
 #define CDROM_GET_MCN          0x5311 /* Obtain the "Universal Product Code" 
                                            if available (struct cdrom_mcn) */
-#define CDROM_GET_UPC          CDROM_GET_MCN  /* This one is depricated, 
+#define CDROM_GET_UPC          CDROM_GET_MCN  /* This one is deprecated, 
                                           but here anyway for compatibility */
 #define CDROMRESET             0x5312 /* hard-reset the drive */
 #define CDROMVOLREAD           0x5313 /* Get the drive's volume setting 
@@ -506,7 +506,7 @@ struct cdrom_generic_command
 #define GPMODE_TO_PROTECT_PAGE         0x1d
 #define GPMODE_CAPABILITIES_PAGE       0x2a
 #define GPMODE_ALL_PAGES               0x3f
-/* Not in Mt. Fuji, but in ATAPI 2.6 -- depricated now in favor
+/* Not in Mt. Fuji, but in ATAPI 2.6 -- deprecated now in favor
  * of MODE_SENSE_POWER_PAGE */
 #define GPMODE_CDROM_PAGE              0x0d
 
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
new file mode 100644 (file)
index 0000000..8747932
--- /dev/null
@@ -0,0 +1,327 @@
+#ifndef _LINUX_CGROUP_H
+#define _LINUX_CGROUP_H
+/*
+ *  cgroup interface
+ *
+ *  Copyright (C) 2003 BULL SA
+ *  Copyright (C) 2004-2006 Silicon Graphics, Inc.
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/kref.h>
+#include <linux/cpumask.h>
+#include <linux/nodemask.h>
+#include <linux/rcupdate.h>
+#include <linux/cgroupstats.h>
+
+#ifdef CONFIG_CGROUPS
+
+struct cgroupfs_root;
+struct cgroup_subsys;
+struct inode;
+
+extern int cgroup_init_early(void);
+extern int cgroup_init(void);
+extern void cgroup_init_smp(void);
+extern void cgroup_lock(void);
+extern void cgroup_unlock(void);
+extern void cgroup_fork(struct task_struct *p);
+extern void cgroup_fork_callbacks(struct task_struct *p);
+extern void cgroup_post_fork(struct task_struct *p);
+extern void cgroup_exit(struct task_struct *p, int run_callbacks);
+extern int cgroupstats_build(struct cgroupstats *stats,
+                               struct dentry *dentry);
+
+extern struct file_operations proc_cgroup_operations;
+
+/* Define the enumeration of all cgroup subsystems */
+#define SUBSYS(_x) _x ## _subsys_id,
+enum cgroup_subsys_id {
+#include <linux/cgroup_subsys.h>
+       CGROUP_SUBSYS_COUNT
+};
+#undef SUBSYS
+
+/* Per-subsystem/per-cgroup state maintained by the system. */
+struct cgroup_subsys_state {
+       /* The cgroup that this subsystem is attached to. Useful
+        * for subsystems that want to know about the cgroup
+        * hierarchy structure */
+       struct cgroup *cgroup;
+
+       /* State maintained by the cgroup system to allow
+        * subsystems to be "busy". Should be accessed via css_get()
+        * and css_put() */
+
+       atomic_t refcnt;
+
+       unsigned long flags;
+};
+
+/* bits in struct cgroup_subsys_state flags field */
+enum {
+       CSS_ROOT, /* This CSS is the root of the subsystem */
+};
+
+/*
+ * Call css_get() to hold a reference on the cgroup;
+ *
+ */
+
+static inline void css_get(struct cgroup_subsys_state *css)
+{
+       /* We don't need to reference count the root state */
+       if (!test_bit(CSS_ROOT, &css->flags))
+               atomic_inc(&css->refcnt);
+}
+/*
+ * css_put() should be called to release a reference taken by
+ * css_get()
+ */
+
+extern void __css_put(struct cgroup_subsys_state *css);
+static inline void css_put(struct cgroup_subsys_state *css)
+{
+       if (!test_bit(CSS_ROOT, &css->flags))
+               __css_put(css);
+}
+
+struct cgroup {
+       unsigned long flags;            /* "unsigned long" so bitops work */
+
+       /* count users of this cgroup. >0 means busy, but doesn't
+        * necessarily indicate the number of tasks in the
+        * cgroup */
+       atomic_t count;
+
+       /*
+        * We link our 'sibling' struct into our parent's 'children'.
+        * Our children link their 'sibling' into our 'children'.
+        */
+       struct list_head sibling;       /* my parent's children */
+       struct list_head children;      /* my children */
+
+       struct cgroup *parent;  /* my parent */
+       struct dentry *dentry;          /* cgroup fs entry */
+
+       /* Private pointers for each registered subsystem */
+       struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT];
+
+       struct cgroupfs_root *root;
+       struct cgroup *top_cgroup;
+
+       /*
+        * List of cg_cgroup_links pointing at css_sets with
+        * tasks in this cgroup. Protected by css_set_lock
+        */
+       struct list_head css_sets;
+
+       /*
+        * Linked list running through all cgroups that can
+        * potentially be reaped by the release agent. Protected by
+        * release_list_lock
+        */
+       struct list_head release_list;
+};
+
+/* A css_set is a structure holding pointers to a set of
+ * cgroup_subsys_state objects. This saves space in the task struct
+ * object and speeds up fork()/exit(), since a single inc/dec and a
+ * list_add()/del() can bump the reference count on the entire
+ * cgroup set for a task.
+ */
+
+struct css_set {
+
+       /* Reference count */
+       struct kref ref;
+
+       /*
+        * List running through all cgroup groups. Protected by
+        * css_set_lock
+        */
+       struct list_head list;
+
+       /*
+        * List running through all tasks using this cgroup
+        * group. Protected by css_set_lock
+        */
+       struct list_head tasks;
+
+       /*
+        * List of cg_cgroup_link objects on link chains from
+        * cgroups referenced from this css_set. Protected by
+        * css_set_lock
+        */
+       struct list_head cg_links;
+
+       /*
+        * Set of subsystem states, one for each subsystem. This array
+        * is immutable after creation apart from the init_css_set
+        * during subsystem registration (at boot time).
+        */
+       struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT];
+
+};
+
+/* struct cftype:
+ *
+ * The files in the cgroup filesystem mostly have a very simple read/write
+ * handling, some common function will take care of it. Nevertheless some cases
+ * (read tasks) are special and therefore I define this structure for every
+ * kind of file.
+ *
+ *
+ * When reading/writing to a file:
+ *     - the cgroup to use in file->f_dentry->d_parent->d_fsdata
+ *     - the 'cftype' of the file is file->f_dentry->d_fsdata
+ */
+
+#define MAX_CFTYPE_NAME 64
+struct cftype {
+       /* By convention, the name should begin with the name of the
+        * subsystem, followed by a period */
+       char name[MAX_CFTYPE_NAME];
+       int private;
+       int (*open) (struct inode *inode, struct file *file);
+       ssize_t (*read) (struct cgroup *cont, struct cftype *cft,
+                        struct file *file,
+                        char __user *buf, size_t nbytes, loff_t *ppos);
+       /*
+        * read_uint() is a shortcut for the common case of returning a
+        * single integer. Use it in place of read()
+        */
+       u64 (*read_uint) (struct cgroup *cont, struct cftype *cft);
+       ssize_t (*write) (struct cgroup *cont, struct cftype *cft,
+                         struct file *file,
+                         const char __user *buf, size_t nbytes, loff_t *ppos);
+
+       /*
+        * write_uint() is a shortcut for the common case of accepting
+        * a single integer (as parsed by simple_strtoull) from
+        * userspace. Use in place of write(); return 0 or error.
+        */
+       int (*write_uint) (struct cgroup *cont, struct cftype *cft, u64 val);
+
+       int (*release) (struct inode *inode, struct file *file);
+};
+
+/* Add a new file to the given cgroup directory. Should only be
+ * called by subsystems from within a populate() method */
+int cgroup_add_file(struct cgroup *cont, struct cgroup_subsys *subsys,
+                      const struct cftype *cft);
+
+/* Add a set of new files to the given cgroup directory. Should
+ * only be called by subsystems from within a populate() method */
+int cgroup_add_files(struct cgroup *cont,
+                       struct cgroup_subsys *subsys,
+                       const struct cftype cft[],
+                       int count);
+
+int cgroup_is_removed(const struct cgroup *cont);
+
+int cgroup_path(const struct cgroup *cont, char *buf, int buflen);
+
+int cgroup_task_count(const struct cgroup *cont);
+
+/* Return true if the cgroup is a descendant of the current cgroup */
+int cgroup_is_descendant(const struct cgroup *cont);
+
+/* Control Group subsystem type. See Documentation/cgroups.txt for details */
+
+struct cgroup_subsys {
+       struct cgroup_subsys_state *(*create)(struct cgroup_subsys *ss,
+                                                 struct cgroup *cont);
+       void (*destroy)(struct cgroup_subsys *ss, struct cgroup *cont);
+       int (*can_attach)(struct cgroup_subsys *ss,
+                         struct cgroup *cont, struct task_struct *tsk);
+       void (*attach)(struct cgroup_subsys *ss, struct cgroup *cont,
+                       struct cgroup *old_cont, struct task_struct *tsk);
+       void (*fork)(struct cgroup_subsys *ss, struct task_struct *task);
+       void (*exit)(struct cgroup_subsys *ss, struct task_struct *task);
+       int (*populate)(struct cgroup_subsys *ss,
+                       struct cgroup *cont);
+       void (*post_clone)(struct cgroup_subsys *ss, struct cgroup *cont);
+       void (*bind)(struct cgroup_subsys *ss, struct cgroup *root);
+       int subsys_id;
+       int active;
+       int early_init;
+#define MAX_CGROUP_TYPE_NAMELEN 32
+       const char *name;
+
+       /* Protected by RCU */
+       struct cgroupfs_root *root;
+
+       struct list_head sibling;
+
+       void *private;
+};
+
+#define SUBSYS(_x) extern struct cgroup_subsys _x ## _subsys;
+#include <linux/cgroup_subsys.h>
+#undef SUBSYS
+
+static inline struct cgroup_subsys_state *cgroup_subsys_state(
+       struct cgroup *cont, int subsys_id)
+{
+       return cont->subsys[subsys_id];
+}
+
+static inline struct cgroup_subsys_state *task_subsys_state(
+       struct task_struct *task, int subsys_id)
+{
+       return rcu_dereference(task->cgroups->subsys[subsys_id]);
+}
+
+static inline struct cgroup* task_cgroup(struct task_struct *task,
+                                              int subsys_id)
+{
+       return task_subsys_state(task, subsys_id)->cgroup;
+}
+
+int cgroup_path(const struct cgroup *cont, char *buf, int buflen);
+
+int cgroup_clone(struct task_struct *tsk, struct cgroup_subsys *ss);
+
+/* A cgroup_iter should be treated as an opaque object */
+struct cgroup_iter {
+       struct list_head *cg_link;
+       struct list_head *task;
+};
+
+/* To iterate across the tasks in a cgroup:
+ *
+ * 1) call cgroup_iter_start to intialize an iterator
+ *
+ * 2) call cgroup_iter_next() to retrieve member tasks until it
+ *    returns NULL or until you want to end the iteration
+ *
+ * 3) call cgroup_iter_end() to destroy the iterator.
+ */
+void cgroup_iter_start(struct cgroup *cont, struct cgroup_iter *it);
+struct task_struct *cgroup_iter_next(struct cgroup *cont,
+                                       struct cgroup_iter *it);
+void cgroup_iter_end(struct cgroup *cont, struct cgroup_iter *it);
+
+#else /* !CONFIG_CGROUPS */
+
+static inline int cgroup_init_early(void) { return 0; }
+static inline int cgroup_init(void) { return 0; }
+static inline void cgroup_init_smp(void) {}
+static inline void cgroup_fork(struct task_struct *p) {}
+static inline void cgroup_fork_callbacks(struct task_struct *p) {}
+static inline void cgroup_post_fork(struct task_struct *p) {}
+static inline void cgroup_exit(struct task_struct *p, int callbacks) {}
+
+static inline void cgroup_lock(void) {}
+static inline void cgroup_unlock(void) {}
+static inline int cgroupstats_build(struct cgroupstats *stats,
+                                       struct dentry *dentry)
+{
+       return -EINVAL;
+}
+
+#endif /* !CONFIG_CGROUPS */
+
+#endif /* _LINUX_CGROUP_H */
diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h
new file mode 100644 (file)
index 0000000..0b9bfbd
--- /dev/null
@@ -0,0 +1,38 @@
+/* Add subsystem definitions of the form SUBSYS(<name>) in this
+ * file. Surround each one by a line of comment markers so that
+ * patches don't collide
+ */
+
+/* */
+
+/* */
+
+#ifdef CONFIG_CPUSETS
+SUBSYS(cpuset)
+#endif
+
+/* */
+
+#ifdef CONFIG_CGROUP_CPUACCT
+SUBSYS(cpuacct)
+#endif
+
+/* */
+
+#ifdef CONFIG_CGROUP_DEBUG
+SUBSYS(debug)
+#endif
+
+/* */
+
+#ifdef CONFIG_CGROUP_NS
+SUBSYS(ns)
+#endif
+
+/* */
+
+#ifdef CONFIG_FAIR_CGROUP_SCHED
+SUBSYS(cpu_cgroup)
+#endif
+
+/* */
diff --git a/include/linux/cgroupstats.h b/include/linux/cgroupstats.h
new file mode 100644 (file)
index 0000000..4f53abf
--- /dev/null
@@ -0,0 +1,70 @@
+/* cgroupstats.h - exporting per-cgroup statistics
+ *
+ * Copyright IBM Corporation, 2007
+ * Author Balbir Singh <balbir@linux.vnet.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _LINUX_CGROUPSTATS_H
+#define _LINUX_CGROUPSTATS_H
+
+#include <linux/taskstats.h>
+
+/*
+ * Data shared between user space and kernel space on a per cgroup
+ * basis. This data is shared using taskstats.
+ *
+ * Most of these states are derived by looking at the task->state value
+ * For the nr_io_wait state, a flag in the delay accounting structure
+ * indicates that the task is waiting on IO
+ *
+ * Each member is aligned to a 8 byte boundary.
+ */
+struct cgroupstats {
+       __u64   nr_sleeping;            /* Number of tasks sleeping */
+       __u64   nr_running;             /* Number of tasks running */
+       __u64   nr_stopped;             /* Number of tasks in stopped state */
+       __u64   nr_uninterruptible;     /* Number of tasks in uninterruptible */
+                                       /* state */
+       __u64   nr_io_wait;             /* Number of tasks waiting on IO */
+};
+
+/*
+ * Commands sent from userspace
+ * Not versioned. New commands should only be inserted at the enum's end
+ * prior to __CGROUPSTATS_CMD_MAX
+ */
+
+enum {
+       CGROUPSTATS_CMD_UNSPEC = __TASKSTATS_CMD_MAX,   /* Reserved */
+       CGROUPSTATS_CMD_GET,            /* user->kernel request/get-response */
+       CGROUPSTATS_CMD_NEW,            /* kernel->user event */
+       __CGROUPSTATS_CMD_MAX,
+};
+
+#define CGROUPSTATS_CMD_MAX (__CGROUPSTATS_CMD_MAX - 1)
+
+enum {
+       CGROUPSTATS_TYPE_UNSPEC = 0,    /* Reserved */
+       CGROUPSTATS_TYPE_CGROUP_STATS,  /* contains name + stats */
+       __CGROUPSTATS_TYPE_MAX,
+};
+
+#define CGROUPSTATS_TYPE_MAX (__CGROUPSTATS_TYPE_MAX - 1)
+
+enum {
+       CGROUPSTATS_CMD_ATTR_UNSPEC = 0,
+       CGROUPSTATS_CMD_ATTR_FD,
+       __CGROUPSTATS_CMD_ATTR_MAX,
+};
+
+#define CGROUPSTATS_CMD_ATTR_MAX (__CGROUPSTATS_CMD_ATTR_MAX - 1)
+
+#endif /* _LINUX_CGROUPSTATS_H */
index 16ea3374dddf7a543501fca71718c5d72b885e07..107787aacb647c95c37f53bf94d2660486d687a3 100644 (file)
@@ -221,10 +221,15 @@ extern void clocksource_resume(void);
 
 #ifdef CONFIG_GENERIC_TIME_VSYSCALL
 extern void update_vsyscall(struct timespec *ts, struct clocksource *c);
+extern void update_vsyscall_tz(void);
 #else
 static inline void update_vsyscall(struct timespec *ts, struct clocksource *c)
 {
 }
+
+static inline void update_vsyscall_tz(void)
+{
+}
 #endif
 
 #endif /* _LINUX_CLOCKSOURCE_H */
index acd583384bd9dffb50a097eae3370caf5704d78c..fe23792f05c1077149718fd783458e8d4d12c5db 100644 (file)
 #define __weak                         __attribute__((weak))
 #define __naked                                __attribute__((naked))
 #define __noreturn                     __attribute__((noreturn))
+
+/*
+ * From the GCC manual:
+ *
+ * Many functions have no effects except the return value and their
+ * return value depends only on the parameters and/or global
+ * variables.  Such a function can be subject to common subexpression
+ * elimination and loop optimization just as an arithmetic operator
+ * would be.
+ * [...]
+ */
 #define __pure                         __attribute__((pure))
 #define __aligned(x)                   __attribute__((aligned(x)))
 #define __printf(a,b)                  __attribute__((format(printf,a,b)))
 #define  noinline                      __attribute__((noinline))
-#define __attribute_pure__             __attribute__((pure))
 #define __attribute_const__            __attribute__((__const__))
 #define __maybe_unused                 __attribute__((unused))
index 86f9a3a6137debd41bdb03b8988580cbeb6d1ca7..c811c8b979ac29643669b7e3788b089df9fc5331 100644 (file)
@@ -132,20 +132,6 @@ extern void __chk_io_ptr(const volatile void __iomem *);
 # define __maybe_unused                /* unimplemented */
 #endif
 
-/*
- * From the GCC manual:
- *
- * Many functions have no effects except the return value and their
- * return value depends only on the parameters and/or global
- * variables.  Such a function can be subject to common subexpression
- * elimination and loop optimization just as an arithmetic operator
- * would be.
- * [...]
- */
-#ifndef __attribute_pure__
-# define __attribute_pure__    /* unimplemented */
-#endif
-
 #ifndef noinline
 #define noinline
 #endif
index 0a4542ddb73dab19ceb9477e22241dc3bc0fe33e..a5f88a6a259d84a92e93a905a7937b03b7501dbf 100644 (file)
@@ -122,14 +122,11 @@ extern void console_stop(struct console *);
 extern void console_start(struct console *);
 extern int is_console_locked(void);
 
-#ifndef CONFIG_DISABLE_CONSOLE_SUSPEND
+extern int console_suspend_enabled;
+
 /* Suspend and resume console messages over PM events */
 extern void suspend_console(void);
 extern void resume_console(void);
-#else
-static inline void suspend_console(void) {}
-static inline void resume_console(void) {}
-#endif /* CONFIG_DISABLE_CONSOLE_SUSPEND */
 
 int mda_console_init(void);
 void prom_con_init(void);
index 0ad72c4cf312a8bb9dc18bb6f39ad54b36fac941..b79c5756936728ca8a576c3ea13142f71f333f4c 100644 (file)
@@ -119,8 +119,9 @@ static inline void cpuhotplug_mutex_unlock(struct mutex *cpu_hp_mutex)
 #define lock_cpu_hotplug()     do { } while (0)
 #define unlock_cpu_hotplug()   do { } while (0)
 #define hotcpu_notifier(fn, pri)       do { (void)(fn); } while (0)
-#define register_hotcpu_notifier(nb)   do { (void)(nb); } while (0)
-#define unregister_hotcpu_notifier(nb) do { (void)(nb); } while (0)
+/* These aren't inline functions due to a GCC bug. */
+#define register_hotcpu_notifier(nb)   ({ (void)(nb); 0; })
+#define unregister_hotcpu_notifier(nb) ({ (void)(nb); })
 
 /* CPUs don't go offline once they're online w/o CONFIG_HOTPLUG_CPU */
 static inline int cpu_is_offline(int cpu) { return 0; }
diff --git a/include/linux/cpu_acct.h b/include/linux/cpu_acct.h
new file mode 100644 (file)
index 0000000..6b5fd8a
--- /dev/null
@@ -0,0 +1,14 @@
+
+#ifndef _LINUX_CPU_ACCT_H
+#define _LINUX_CPU_ACCT_H
+
+#include <linux/cgroup.h>
+#include <asm/cputime.h>
+
+#ifdef CONFIG_CGROUP_CPUACCT
+extern void cpuacct_charge(struct task_struct *, cputime_t cputime);
+#else
+static void inline cpuacct_charge(struct task_struct *p, cputime_t cputime) {}
+#endif
+
+#endif
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
new file mode 100644 (file)
index 0000000..16a5154
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * cpuidle.h - a generic framework for CPU idle power management
+ *
+ * (C) 2007 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ *          Shaohua Li <shaohua.li@intel.com>
+ *          Adam Belay <abelay@novell.com>
+ *
+ * This code is licenced under the GPL.
+ */
+
+#ifndef _LINUX_CPUIDLE_H
+#define _LINUX_CPUIDLE_H
+
+#include <linux/percpu.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/kobject.h>
+#include <linux/completion.h>
+
+#define CPUIDLE_STATE_MAX      8
+#define CPUIDLE_NAME_LEN       16
+
+struct cpuidle_device;
+
+
+/****************************
+ * CPUIDLE DEVICE INTERFACE *
+ ****************************/
+
+struct cpuidle_state {
+       char            name[CPUIDLE_NAME_LEN];
+       void            *driver_data;
+
+       unsigned int    flags;
+       unsigned int    exit_latency; /* in US */
+       unsigned int    power_usage; /* in mW */
+       unsigned int    target_residency; /* in US */
+
+       unsigned int    usage;
+       unsigned int    time; /* in US */
+
+       int (*enter)    (struct cpuidle_device *dev,
+                        struct cpuidle_state *state);
+};
+
+/* Idle State Flags */
+#define CPUIDLE_FLAG_TIME_VALID        (0x01) /* is residency time measurable? */
+#define CPUIDLE_FLAG_CHECK_BM  (0x02) /* BM activity will exit state */
+#define CPUIDLE_FLAG_SHALLOW   (0x10) /* low latency, minimal savings */
+#define CPUIDLE_FLAG_BALANCED  (0x20) /* medium latency, moderate savings */
+#define CPUIDLE_FLAG_DEEP      (0x40) /* high latency, large savings */
+
+#define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000)
+
+/**
+ * cpuidle_get_statedata - retrieves private driver state data
+ * @state: the state
+ */
+static inline void * cpuidle_get_statedata(struct cpuidle_state *state)
+{
+       return state->driver_data;
+}
+
+/**
+ * cpuidle_set_statedata - stores private driver state data
+ * @state: the state
+ * @data: the private data
+ */
+static inline void
+cpuidle_set_statedata(struct cpuidle_state *state, void *data)
+{
+       state->driver_data = data;
+}
+
+struct cpuidle_state_kobj {
+       struct cpuidle_state *state;
+       struct completion kobj_unregister;
+       struct kobject kobj;
+};
+
+struct cpuidle_device {
+       int                     enabled:1;
+       unsigned int            cpu;
+
+       int                     last_residency;
+       int                     state_count;
+       struct cpuidle_state    states[CPUIDLE_STATE_MAX];
+       struct cpuidle_state_kobj *kobjs[CPUIDLE_STATE_MAX];
+       struct cpuidle_state    *last_state;
+
+       struct list_head        device_list;
+       struct kobject          kobj;
+       struct completion       kobj_unregister;
+       void                    *governor_data;
+};
+
+DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices);
+
+/**
+ * cpuidle_get_last_residency - retrieves the last state's residency time
+ * @dev: the target CPU
+ *
+ * NOTE: this value is invalid if CPUIDLE_FLAG_TIME_VALID isn't set
+ */
+static inline int cpuidle_get_last_residency(struct cpuidle_device *dev)
+{
+       return dev->last_residency;
+}
+
+
+/****************************
+ * CPUIDLE DRIVER INTERFACE *
+ ****************************/
+
+struct cpuidle_driver {
+       char                    name[CPUIDLE_NAME_LEN];
+       struct module           *owner;
+};
+
+#ifdef CONFIG_CPU_IDLE
+
+extern int cpuidle_register_driver(struct cpuidle_driver *drv);
+extern void cpuidle_unregister_driver(struct cpuidle_driver *drv);
+extern int cpuidle_register_device(struct cpuidle_device *dev);
+extern void cpuidle_unregister_device(struct cpuidle_device *dev);
+
+extern void cpuidle_pause_and_lock(void);
+extern void cpuidle_resume_and_unlock(void);
+extern int cpuidle_enable_device(struct cpuidle_device *dev);
+extern void cpuidle_disable_device(struct cpuidle_device *dev);
+
+#else
+
+static inline int cpuidle_register_driver(struct cpuidle_driver *drv)
+{return 0;}
+static inline void cpuidle_unregister_driver(struct cpuidle_driver *drv) { }
+static inline int cpuidle_register_device(struct cpuidle_device *dev)
+{return 0;}
+static inline void cpuidle_unregister_device(struct cpuidle_device *dev) { }
+
+static inline void cpuidle_pause_and_lock(void) { }
+static inline void cpuidle_resume_and_unlock(void) { }
+static inline int cpuidle_enable_device(struct cpuidle_device *dev)
+{return 0;}
+static inline void cpuidle_disable_device(struct cpuidle_device *dev) { }
+
+#endif
+
+/******************************
+ * CPUIDLE GOVERNOR INTERFACE *
+ ******************************/
+
+struct cpuidle_governor {
+       char                    name[CPUIDLE_NAME_LEN];
+       struct list_head        governor_list;
+       unsigned int            rating;
+
+       int  (*enable)          (struct cpuidle_device *dev);
+       void (*disable)         (struct cpuidle_device *dev);
+
+       int  (*select)          (struct cpuidle_device *dev);
+       void (*reflect)         (struct cpuidle_device *dev);
+
+       struct module           *owner;
+};
+
+#ifdef CONFIG_CPU_IDLE
+
+extern int cpuidle_register_governor(struct cpuidle_governor *gov);
+extern void cpuidle_unregister_governor(struct cpuidle_governor *gov);
+
+#else
+
+static inline int cpuidle_register_governor(struct cpuidle_governor *gov)
+{return 0;}
+static inline void cpuidle_unregister_governor(struct cpuidle_governor *gov) { }
+
+#endif
+
+#endif /* _LINUX_CPUIDLE_H */
index ea44d2e768a042902e566273173a83ee337b7f0b..ecae585ec3da97fce87fa5703e64d51519522d59 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/sched.h>
 #include <linux/cpumask.h>
 #include <linux/nodemask.h>
+#include <linux/cgroup.h>
 
 #ifdef CONFIG_CPUSETS
 
@@ -19,9 +20,8 @@ extern int number_of_cpusets; /* How many cpusets are defined in system? */
 extern int cpuset_init_early(void);
 extern int cpuset_init(void);
 extern void cpuset_init_smp(void);
-extern void cpuset_fork(struct task_struct *p);
-extern void cpuset_exit(struct task_struct *p);
 extern cpumask_t cpuset_cpus_allowed(struct task_struct *p);
+extern cpumask_t cpuset_cpus_allowed_locked(struct task_struct *p);
 extern nodemask_t cpuset_mems_allowed(struct task_struct *p);
 #define cpuset_current_mems_allowed (current->mems_allowed)
 void cpuset_init_current_mems_allowed(void);
@@ -76,18 +76,22 @@ static inline int cpuset_do_slab_mem_spread(void)
 
 extern void cpuset_track_online_nodes(void);
 
+extern int current_cpuset_is_being_rebound(void);
+
 #else /* !CONFIG_CPUSETS */
 
 static inline int cpuset_init_early(void) { return 0; }
 static inline int cpuset_init(void) { return 0; }
 static inline void cpuset_init_smp(void) {}
-static inline void cpuset_fork(struct task_struct *p) {}
-static inline void cpuset_exit(struct task_struct *p) {}
 
 static inline cpumask_t cpuset_cpus_allowed(struct task_struct *p)
 {
        return cpu_possible_map;
 }
+static inline cpumask_t cpuset_cpus_allowed_locked(struct task_struct *p)
+{
+       return cpu_possible_map;
+}
 
 static inline nodemask_t cpuset_mems_allowed(struct task_struct *p)
 {
@@ -148,6 +152,11 @@ static inline int cpuset_do_slab_mem_spread(void)
 
 static inline void cpuset_track_online_nodes(void) {}
 
+static inline int current_cpuset_is_being_rebound(void)
+{
+       return 0;
+}
+
 #endif /* !CONFIG_CPUSETS */
 
 #endif /* _LINUX_CPUSET_H */
index fc32694287e21cee1b2508f0456bbd29552479a1..f3110ebe894a090254ac4b48f0d9ef98205c5eaf 100644 (file)
@@ -6,7 +6,7 @@
  * Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au>
  *
  * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
- * and Nettle, by Niels Möller.
+ * and Nettle, by Niels Möller.
  * 
  * 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
index 72aa00cc4b2db49e4d036955d6a72d16f6a1b224..8f3dcd30828fbb149ef7ee30c788ebf2e312e6e6 100644 (file)
@@ -512,11 +512,11 @@ struct cyclades_card {
     void __iomem *base_addr;
     void __iomem *ctl_addr;
     int irq;
-    int num_chips;     /* 0 if card absent, -1 if Z/PCI, else Y */
-    int first_line;    /* minor number of first channel on card */
-    int nports;                /* Number of ports in the card */
-    int bus_index;     /* address shift - 0 for ISA, 1 for PCI */
-    int        intr_enabled;   /* FW Interrupt flag - 0 disabled, 1 enabled */
+    unsigned int num_chips;    /* 0 if card absent, -1 if Z/PCI, else Y */
+    unsigned int first_line;   /* minor number of first channel on card */
+    unsigned int nports;       /* Number of ports in the card */
+    int bus_index;             /* address shift - 0 for ISA, 1 for PCI */
+    int intr_enabled;          /* FW Interrupt flag - 0 disabled, 1 enabled */
     spinlock_t card_lock;
     struct cyclades_port *ports;
 };
@@ -566,10 +566,9 @@ struct cyclades_port {
        int                     rtsdtr_inv;
        int                     chip_rev;
        int                     custom_divisor;
-       int                     x_char; /* to be pushed out ASAP */
+       u8                      x_char; /* to be pushed out ASAP */
        int                     close_delay;
        unsigned short          closing_wait;
-       unsigned long           event;
        int                     count;  /* # of fd on device */
        int                     breakon;
        int                     breakoff;
@@ -584,7 +583,6 @@ struct cyclades_port {
        struct cyclades_monitor mon;
        struct cyclades_idle_stats      idle_stats;
        struct cyclades_icount  icount;
-       struct work_struct      tqueue;
        wait_queue_head_t       open_wait;
        wait_queue_head_t       close_wait;
        struct completion       shutdown_wait;
@@ -592,19 +590,6 @@ struct cyclades_port {
        int throttle;
 };
 
-/*
- * Events are used to schedule things to happen at timer-interrupt
- * time, instead of at cy interrupt time.
- */
-#define Cy_EVENT_READ_PROCESS          0
-#define Cy_EVENT_WRITE_WAKEUP          1
-#define Cy_EVENT_HANGUP                        2
-#define Cy_EVENT_BREAK                 3
-#define Cy_EVENT_OPEN_WAKEUP           4
-#define Cy_EVENT_SHUTDOWN_WAKEUP       5
-#define        Cy_EVENT_DELTA_WAKEUP           6
-#define        Cy_EVENT_Z_RX_FULL              7
-
 #define        CLOSING_WAIT_DELAY      30*HZ
 #define CY_CLOSING_WAIT_NONE   65535
 #define CY_CLOSING_WAIT_INF    0
index aab53df4fafa338e46b96919d61e77ed2b20ff78..c2c153f97e8f83b233c2e5d2ea0fb19de640b4d2 100644 (file)
@@ -178,6 +178,7 @@ d_iput:             no              no              no       yes
 #define DCACHE_INOTIFY_PARENT_WATCHED  0x0020 /* Parent inode is watched */
 
 extern spinlock_t dcache_lock;
+extern seqlock_t rename_lock;
 
 /**
  * d_drop - drop a dentry
index 55d1ca5e60f54f11efcfe7078a5e02cf3bb450fd..ab94bc083558c329c8a59e49ff3c7af6076627ca 100644 (file)
@@ -26,6 +26,7 @@
  * Used to set current->delays->flags
  */
 #define DELAYACCT_PF_SWAPIN    0x00000001      /* I am doing a swapin */
+#define DELAYACCT_PF_BLKIO     0x00000002      /* I am waiting on IO */
 
 #ifdef CONFIG_TASK_DELAY_ACCT
 
@@ -39,6 +40,14 @@ extern void __delayacct_blkio_end(void);
 extern int __delayacct_add_tsk(struct taskstats *, struct task_struct *);
 extern __u64 __delayacct_blkio_ticks(struct task_struct *);
 
+static inline int delayacct_is_task_waiting_on_io(struct task_struct *p)
+{
+       if (p->delays)
+               return (p->delays->flags & DELAYACCT_PF_BLKIO);
+       else
+               return 0;
+}
+
 static inline void delayacct_set_flag(int flag)
 {
        if (current->delays)
@@ -71,6 +80,7 @@ static inline void delayacct_tsk_free(struct task_struct *tsk)
 
 static inline void delayacct_blkio_start(void)
 {
+       delayacct_set_flag(DELAYACCT_PF_BLKIO);
        if (current->delays)
                __delayacct_blkio_start();
 }
@@ -79,6 +89,7 @@ static inline void delayacct_blkio_end(void)
 {
        if (current->delays)
                __delayacct_blkio_end();
+       delayacct_clear_flag(DELAYACCT_PF_BLKIO);
 }
 
 static inline int delayacct_add_tsk(struct taskstats *d,
@@ -116,6 +127,8 @@ static inline int delayacct_add_tsk(struct taskstats *d,
 { return 0; }
 static inline __u64 delayacct_blkio_ticks(struct task_struct *tsk)
 { return 0; }
+static inline int delayacct_is_task_waiting_on_io(struct task_struct *p)
+{ return 0; }
 #endif /* CONFIG_TASK_DELAY_ACCT */
 
 #endif
index 499f5373e2134d7a1a0fa8b9a84bddc3ad23b26b..37c66d1254b5383795f3f559a7a232325dd16c13 100644 (file)
@@ -183,11 +183,14 @@ int dm_resume(struct mapped_device *md);
  */
 uint32_t dm_get_event_nr(struct mapped_device *md);
 int dm_wait_event(struct mapped_device *md, int event_nr);
+uint32_t dm_next_uevent_seq(struct mapped_device *md);
+void dm_uevent_add(struct mapped_device *md, struct list_head *elist);
 
 /*
  * Info functions.
  */
 const char *dm_device_name(struct mapped_device *md);
+int dm_copy_name_and_uuid(struct mapped_device *md, char *name, char *uuid);
 struct gendisk *dm_disk(struct mapped_device *md);
 int dm_suspended(struct mapped_device *md);
 int dm_noflush_suspending(struct dm_target *ti);
index b9348610782181429e24bc682627612d1bae7184..523281c5b7f55fa964534b4d38061b6c7b172d8a 100644 (file)
@@ -131,6 +131,7 @@ struct dm_ioctl {
        char name[DM_NAME_LEN]; /* device name */
        char uuid[DM_UUID_LEN]; /* unique identifier for
                                 * the block device */
+       char data[7];           /* padding or data */
 };
 
 /*
@@ -285,9 +286,9 @@ typedef char ioctl_struct[308];
 #define DM_DEV_SET_GEOMETRY    _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
 
 #define DM_VERSION_MAJOR       4
-#define DM_VERSION_MINOR       11
+#define DM_VERSION_MINOR       12
 #define DM_VERSION_PATCHLEVEL  0
-#define DM_VERSION_EXTRA       "-ioctl (2006-10-12)"
+#define DM_VERSION_EXTRA       "-ioctl (2007-10-02)"
 
 /* Status bits */
 #define DM_READONLY_FLAG       (1 << 0) /* In/Out */
index 0ebfafbd338ca56fc89f781c2848a9c16b81cb6d..101a2d4636befbd1248b7642c38a87ff77243f07 100644 (file)
@@ -13,16 +13,26 @@ enum dma_data_direction {
        DMA_NONE = 3,
 };
 
-#define DMA_64BIT_MASK 0xffffffffffffffffULL
-#define DMA_48BIT_MASK 0x0000ffffffffffffULL
-#define DMA_40BIT_MASK 0x000000ffffffffffULL
-#define DMA_39BIT_MASK 0x0000007fffffffffULL
-#define DMA_32BIT_MASK 0x00000000ffffffffULL
-#define DMA_31BIT_MASK 0x000000007fffffffULL
-#define DMA_30BIT_MASK 0x000000003fffffffULL
-#define DMA_29BIT_MASK 0x000000001fffffffULL
-#define DMA_28BIT_MASK 0x000000000fffffffULL
-#define DMA_24BIT_MASK 0x0000000000ffffffULL
+#define DMA_BIT_MASK(n)        (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
+
+/*
+ * NOTE: do not use the below macros in new code and do not add new definitions
+ * here.
+ *
+ * Instead, just open-code DMA_BIT_MASK(n) within your driver
+ */
+#define DMA_64BIT_MASK DMA_BIT_MASK(64)
+#define DMA_48BIT_MASK DMA_BIT_MASK(48)
+#define DMA_47BIT_MASK DMA_BIT_MASK(47)
+#define DMA_40BIT_MASK DMA_BIT_MASK(40)
+#define DMA_39BIT_MASK DMA_BIT_MASK(39)
+#define DMA_35BIT_MASK DMA_BIT_MASK(35)
+#define DMA_32BIT_MASK DMA_BIT_MASK(32)
+#define DMA_31BIT_MASK DMA_BIT_MASK(31)
+#define DMA_30BIT_MASK DMA_BIT_MASK(30)
+#define DMA_29BIT_MASK DMA_BIT_MASK(29)
+#define DMA_28BIT_MASK DMA_BIT_MASK(28)
+#define DMA_24BIT_MASK DMA_BIT_MASK(24)
 
 #define DMA_MASK_NONE  0x0ULL
 
diff --git a/include/linux/dmar.h b/include/linux/dmar.h
new file mode 100644 (file)
index 0000000..ffb6439
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Copyright (C) Ashok Raj <ashok.raj@intel.com>
+ * Copyright (C) Shaohua Li <shaohua.li@intel.com>
+ */
+
+#ifndef __DMAR_H__
+#define __DMAR_H__
+
+#include <linux/acpi.h>
+#include <linux/types.h>
+#include <linux/msi.h>
+
+#ifdef CONFIG_DMAR
+struct intel_iommu;
+
+extern char *dmar_get_fault_reason(u8 fault_reason);
+
+/* Can't use the common MSI interrupt functions
+ * since DMAR is not a pci device
+ */
+extern void dmar_msi_unmask(unsigned int irq);
+extern void dmar_msi_mask(unsigned int irq);
+extern void dmar_msi_read(int irq, struct msi_msg *msg);
+extern void dmar_msi_write(int irq, struct msi_msg *msg);
+extern int dmar_set_interrupt(struct intel_iommu *iommu);
+extern int arch_setup_dmar_msi(unsigned int irq);
+
+/* Intel IOMMU detection and initialization functions */
+extern void detect_intel_iommu(void);
+extern int intel_iommu_init(void);
+
+extern int dmar_table_init(void);
+extern int early_dmar_detect(void);
+
+extern struct list_head dmar_drhd_units;
+extern struct list_head dmar_rmrr_units;
+
+struct dmar_drhd_unit {
+       struct list_head list;          /* list of drhd units   */
+       u64     reg_base_addr;          /* register base address*/
+       struct  pci_dev **devices;      /* target device array  */
+       int     devices_cnt;            /* target device count  */
+       u8      ignored:1;              /* ignore drhd          */
+       u8      include_all:1;
+       struct intel_iommu *iommu;
+};
+
+struct dmar_rmrr_unit {
+       struct list_head list;          /* list of rmrr units   */
+       u64     base_address;           /* reserved base address*/
+       u64     end_address;            /* reserved end address */
+       struct pci_dev **devices;       /* target devices */
+       int     devices_cnt;            /* target device count */
+};
+
+#define for_each_drhd_unit(drhd) \
+       list_for_each_entry(drhd, &dmar_drhd_units, list)
+#define for_each_rmrr_units(rmrr) \
+       list_for_each_entry(rmrr, &dmar_rmrr_units, list)
+#else
+static inline void detect_intel_iommu(void)
+{
+       return;
+}
+static inline int intel_iommu_init(void)
+{
+       return -ENODEV;
+}
+
+#endif /* !CONFIG_DMAR */
+#endif /* __DMAR_H__ */
index 7b647822d6dc67f6d95e003455076e80c98a156c..5d747c5cd0fea267a01ae33de179988f79dd13c5 100644 (file)
 #define EDD_INFO_USE_INT13_FN50                (1 << 7)
 
 struct edd_device_params {
-       u16 length;
-       u16 info_flags;
-       u32 num_default_cylinders;
-       u32 num_default_heads;
-       u32 sectors_per_track;
-       u64 number_of_sectors;
-       u16 bytes_per_sector;
-       u32 dpte_ptr;           /* 0xFFFFFFFF for our purposes */
-       u16 key;                /* = 0xBEDD */
-       u8 device_path_info_length;     /* = 44 */
-       u8 reserved2;
-       u16 reserved3;
-       u8 host_bus_type[4];
-       u8 interface_type[8];
+       __u16 length;
+       __u16 info_flags;
+       __u32 num_default_cylinders;
+       __u32 num_default_heads;
+       __u32 sectors_per_track;
+       __u64 number_of_sectors;
+       __u16 bytes_per_sector;
+       __u32 dpte_ptr;         /* 0xFFFFFFFF for our purposes */
+       __u16 key;              /* = 0xBEDD */
+       __u8 device_path_info_length;   /* = 44 */
+       __u8 reserved2;
+       __u16 reserved3;
+       __u8 host_bus_type[4];
+       __u8 interface_type[8];
        union {
                struct {
-                       u16 base_address;
-                       u16 reserved1;
-                       u32 reserved2;
+                       __u16 base_address;
+                       __u16 reserved1;
+                       __u32 reserved2;
                } __attribute__ ((packed)) isa;
                struct {
-                       u8 bus;
-                       u8 slot;
-                       u8 function;
-                       u8 channel;
-                       u32 reserved;
+                       __u8 bus;
+                       __u8 slot;
+                       __u8 function;
+                       __u8 channel;
+                       __u32 reserved;
                } __attribute__ ((packed)) pci;
                /* pcix is same as pci */
                struct {
-                       u64 reserved;
+                       __u64 reserved;
                } __attribute__ ((packed)) ibnd;
                struct {
-                       u64 reserved;
+                       __u64 reserved;
                } __attribute__ ((packed)) xprs;
                struct {
-                       u64 reserved;
+                       __u64 reserved;
                } __attribute__ ((packed)) htpt;
                struct {
-                       u64 reserved;
+                       __u64 reserved;
                } __attribute__ ((packed)) unknown;
        } interface_path;
        union {
                struct {
-                       u8 device;
-                       u8 reserved1;
-                       u16 reserved2;
-                       u32 reserved3;
-                       u64 reserved4;
+                       __u8 device;
+                       __u8 reserved1;
+                       __u16 reserved2;
+                       __u32 reserved3;
+                       __u64 reserved4;
                } __attribute__ ((packed)) ata;
                struct {
-                       u8 device;
-                       u8 lun;
-                       u8 reserved1;
-                       u8 reserved2;
-                       u32 reserved3;
-                       u64 reserved4;
+                       __u8 device;
+                       __u8 lun;
+                       __u8 reserved1;
+                       __u8 reserved2;
+                       __u32 reserved3;
+                       __u64 reserved4;
                } __attribute__ ((packed)) atapi;
                struct {
-                       u16 id;
-                       u64 lun;
-                       u16 reserved1;
-                       u32 reserved2;
+                       __u16 id;
+                       __u64 lun;
+                       __u16 reserved1;
+                       __u32 reserved2;
                } __attribute__ ((packed)) scsi;
                struct {
-                       u64 serial_number;
-                       u64 reserved;
+                       __u64 serial_number;
+                       __u64 reserved;
                } __attribute__ ((packed)) usb;
                struct {
-                       u64 eui;
-                       u64 reserved;
+                       __u64 eui;
+                       __u64 reserved;
                } __attribute__ ((packed)) i1394;
                struct {
-                       u64 wwid;
-                       u64 lun;
+                       __u64 wwid;
+                       __u64 lun;
                } __attribute__ ((packed)) fibre;
                struct {
-                       u64 identity_tag;
-                       u64 reserved;
+                       __u64 identity_tag;
+                       __u64 reserved;
                } __attribute__ ((packed)) i2o;
                struct {
-                       u32 array_number;
-                       u32 reserved1;
-                       u64 reserved2;
+                       __u32 array_number;
+                       __u32 reserved1;
+                       __u64 reserved2;
                } __attribute__ ((packed)) raid;
                struct {
-                       u8 device;
-                       u8 reserved1;
-                       u16 reserved2;
-                       u32 reserved3;
-                       u64 reserved4;
+                       __u8 device;
+                       __u8 reserved1;
+                       __u16 reserved2;
+                       __u32 reserved3;
+                       __u64 reserved4;
                } __attribute__ ((packed)) sata;
                struct {
-                       u64 reserved1;
-                       u64 reserved2;
+                       __u64 reserved1;
+                       __u64 reserved2;
                } __attribute__ ((packed)) unknown;
        } device_path;
-       u8 reserved4;
-       u8 checksum;
+       __u8 reserved4;
+       __u8 checksum;
 } __attribute__ ((packed));
 
 struct edd_info {
-       u8 device;
-       u8 version;
-       u16 interface_support;
-       u16 legacy_max_cylinder;
-       u8 legacy_max_head;
-       u8 legacy_sectors_per_track;
+       __u8 device;
+       __u8 version;
+       __u16 interface_support;
+       __u16 legacy_max_cylinder;
+       __u8 legacy_max_head;
+       __u8 legacy_sectors_per_track;
        struct edd_device_params params;
 } __attribute__ ((packed));
 
@@ -184,8 +184,9 @@ struct edd {
        unsigned char edd_info_nr;
 };
 
+#ifdef __KERNEL__
 extern struct edd edd;
-
+#endif /* __KERNEL__ */
 #endif                         /*!__ASSEMBLY__ */
 
 #endif                         /* _LINUX_EDD_H */
index 0b9579a4cd424d03d95a6ba4a397ee22f4e23b3d..14813b5958022bbc608430999729b6519a58a246 100644 (file)
@@ -298,7 +298,7 @@ extern int efi_mem_attribute_range (unsigned long phys_addr, unsigned long size,
                                    u64 attr);
 extern int __init efi_uart_console_only (void);
 extern void efi_initialize_iomem_resources(struct resource *code_resource,
-                                       struct resource *data_resource);
+               struct resource *data_resource, struct resource *bss_resource);
 extern unsigned long efi_get_time(void);
 extern int efi_set_rtc_mmss(unsigned long nowtime);
 extern int is_available_memory(efi_memory_desc_t * md);
index 16cb25cbf7c563eef970be145403a51ed3fa6933..dd57fe523e97572490adb3339c854d4d8ca3266d 100644 (file)
@@ -35,6 +35,7 @@ static inline struct efs_sb_info *SUPER_INFO(struct super_block *sb)
 }
 
 struct statfs;
+struct fid;
 
 extern const struct inode_operations efs_dir_inode_operations;
 extern const struct file_operations efs_dir_operations;
@@ -45,7 +46,10 @@ extern efs_block_t efs_map_block(struct inode *, efs_block_t);
 extern int efs_get_block(struct inode *, sector_t, struct buffer_head *, int);
 
 extern struct dentry *efs_lookup(struct inode *, struct dentry *, struct nameidata *);
-extern struct dentry *efs_get_dentry(struct super_block *sb, void *vobjp);
+extern struct dentry *efs_fh_to_dentry(struct super_block *sb, struct fid *fid,
+               int fh_len, int fh_type);
+extern struct dentry *efs_fh_to_parent(struct super_block *sb, struct fid *fid,
+               int fh_len, int fh_type);
 extern struct dentry *efs_get_parent(struct dentry *);
 extern int efs_bmap(struct inode *, int);
 
index 8872fe8392d6f367b443a8b6997ee5aac0894f0a..51d214138814a509803e22db093c8a9f91108227 100644 (file)
@@ -4,9 +4,48 @@
 #include <linux/types.h>
 
 struct dentry;
+struct inode;
 struct super_block;
 struct vfsmount;
 
+/*
+ * The fileid_type identifies how the file within the filesystem is encoded.
+ * In theory this is freely set and parsed by the filesystem, but we try to
+ * stick to conventions so we can share some generic code and don't confuse
+ * sniffers like ethereal/wireshark.
+ *
+ * The filesystem must not use the value '0' or '0xff'.
+ */
+enum fid_type {
+       /*
+        * The root, or export point, of the filesystem.
+        * (Never actually passed down to the filesystem.
+        */
+       FILEID_ROOT = 0,
+
+       /*
+        * 32bit inode number, 32 bit generation number.
+        */
+       FILEID_INO32_GEN = 1,
+
+       /*
+        * 32bit inode number, 32 bit generation number,
+        * 32 bit parent directory inode number.
+        */
+       FILEID_INO32_GEN_PARENT = 2,
+};
+
+struct fid {
+       union {
+               struct {
+                       u32 ino;
+                       u32 gen;
+                       u32 parent_ino;
+                       u32 parent_gen;
+               } i32;
+               __u32 raw[6];
+       };
+};
 
 /**
  * struct export_operations - for nfsd to communicate with file systems
@@ -15,43 +54,9 @@ struct vfsmount;
  * @get_name:       find the name for a given inode in a given directory
  * @get_parent:     find the parent of a given directory
  * @get_dentry:     find a dentry for the inode given a file handle sub-fragment
- * @find_exported_dentry:
- *     set by the exporting module to a standard helper function.
- *
- * Description:
- *    The export_operations structure provides a means for nfsd to communicate
- *    with a particular exported file system  - particularly enabling nfsd and
- *    the filesystem to co-operate when dealing with file handles.
- *
- *    export_operations contains two basic operation for dealing with file
- *    handles, decode_fh() and encode_fh(), and allows for some other
- *    operations to be defined which standard helper routines use to get
- *    specific information from the filesystem.
- *
- *    nfsd encodes information use to determine which filesystem a filehandle
- *    applies to in the initial part of the file handle.  The remainder, termed
- *    a file handle fragment, is controlled completely by the filesystem.  The
- *    standard helper routines assume that this fragment will contain one or
- *    two sub-fragments, one which identifies the file, and one which may be
- *    used to identify the (a) directory containing the file.
  *
- *    In some situations, nfsd needs to get a dentry which is connected into a
- *    specific part of the file tree.  To allow for this, it passes the
- *    function acceptable() together with a @context which can be used to see
- *    if the dentry is acceptable.  As there can be multiple dentrys for a
- *    given file, the filesystem should check each one for acceptability before
- *    looking for the next.  As soon as an acceptable one is found, it should
- *    be returned.
- *
- * decode_fh:
- *    @decode_fh is given a &struct super_block (@sb), a file handle fragment
- *    (@fh, @fh_len) and an acceptability testing function (@acceptable,
- *    @context).  It should return a &struct dentry which refers to the same
- *    file that the file handle fragment refers to,  and which passes the
- *    acceptability test.  If it cannot, it should return a %NULL pointer if
- *    the file was found but no acceptable &dentries were available, or a
- *    %ERR_PTR error code indicating why it couldn't be found (e.g. %ENOENT or
- *    %ENOMEM).
+ * See Documentation/filesystems/Exporting for details on how to use
+ * this interface correctly.
  *
  * encode_fh:
  *    @encode_fh should store in the file handle fragment @fh (using at most
@@ -63,6 +68,21 @@ struct vfsmount;
  *    the filehandle fragment.  encode_fh() should return the number of bytes
  *    stored or a negative error code such as %-ENOSPC
  *
+ * fh_to_dentry:
+ *    @fh_to_dentry is given a &struct super_block (@sb) and a file handle
+ *    fragment (@fh, @fh_len). It should return a &struct dentry which refers
+ *    to the same file that the file handle fragment refers to.  If it cannot,
+ *    it should return a %NULL pointer if the file was found but no acceptable
+ *    &dentries were available, or an %ERR_PTR error code indicating why it
+ *    couldn't be found (e.g. %ENOENT or %ENOMEM).  Any suitable dentry can be
+ *    returned including, if necessary, a new dentry created with d_alloc_root.
+ *    The caller can then find any other extant dentries by following the
+ *    d_alias links.
+ *
+ * fh_to_parent:
+ *    Same as @fh_to_dentry, except that it returns a pointer to the parent
+ *    dentry if it was encoded into the filehandle fragment by @encode_fh.
+ *
  * get_name:
  *    @get_name should find a name for the given @child in the given @parent
  *    directory.  The name should be stored in the @name (with the
@@ -75,52 +95,37 @@ struct vfsmount;
  *    is also a directory.  In the event that it cannot be found, or storage
  *    space cannot be allocated, a %ERR_PTR should be returned.
  *
- * get_dentry:
- *    Given a &super_block (@sb) and a pointer to a file-system specific inode
- *    identifier, possibly an inode number, (@inump) get_dentry() should find
- *    the identified inode and return a dentry for that inode.  Any suitable
- *    dentry can be returned including, if necessary, a new dentry created with
- *    d_alloc_root.  The caller can then find any other extant dentrys by
- *    following the d_alias links.  If a new dentry was created using
- *    d_alloc_root, DCACHE_NFSD_DISCONNECTED should be set, and the dentry
- *    should be d_rehash()ed.
- *
- *    If the inode cannot be found, either a %NULL pointer or an %ERR_PTR code
- *    can be returned.  The @inump will be whatever was passed to
- *    nfsd_find_fh_dentry() in either the @obj or @parent parameters.
- *
  * Locking rules:
  *    get_parent is called with child->d_inode->i_mutex down
  *    get_name is not (which is possibly inconsistent)
  */
 
 struct export_operations {
-       struct dentry *(*decode_fh)(struct super_block *sb, __u32 *fh,
-                       int fh_len, int fh_type,
-                       int (*acceptable)(void *context, struct dentry *de),
-                       void *context);
        int (*encode_fh)(struct dentry *de, __u32 *fh, int *max_len,
                        int connectable);
+       struct dentry * (*fh_to_dentry)(struct super_block *sb, struct fid *fid,
+                       int fh_len, int fh_type);
+       struct dentry * (*fh_to_parent)(struct super_block *sb, struct fid *fid,
+                       int fh_len, int fh_type);
        int (*get_name)(struct dentry *parent, char *name,
                        struct dentry *child);
        struct dentry * (*get_parent)(struct dentry *child);
-       struct dentry * (*get_dentry)(struct super_block *sb, void *inump);
-
-       /* This is set by the exporting module to a standard helper */
-       struct dentry * (*find_exported_dentry)(
-                       struct super_block *sb, void *obj, void *parent,
-                       int (*acceptable)(void *context, struct dentry *de),
-                       void *context);
 };
 
-extern struct dentry *find_exported_dentry(struct super_block *sb, void *obj,
-       void *parent, int (*acceptable)(void *context, struct dentry *de),
-       void *context);
-
-extern int exportfs_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len,
-       int connectable);
-extern struct dentry *exportfs_decode_fh(struct vfsmount *mnt, __u32 *fh,
+extern int exportfs_encode_fh(struct dentry *dentry, struct fid *fid,
+       int *max_len, int connectable);
+extern struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
        int fh_len, int fileid_type, int (*acceptable)(void *, struct dentry *),
        void *context);
 
+/*
+ * Generic helpers for filesystems.
+ */
+extern struct dentry *generic_fh_to_dentry(struct super_block *sb,
+       struct fid *fid, int fh_len, int fh_type,
+       struct inode *(*get_inode) (struct super_block *sb, u64 ino, u32 gen));
+extern struct dentry *generic_fh_to_parent(struct super_block *sb,
+       struct fid *fid, int fh_len, int fh_type,
+       struct inode *(*get_inode) (struct super_block *sb, u64 ino, u32 gen));
+
 #endif /* LINUX_EXPORTFS_H */
index c77c3bbfe4bb480c273a72f89bad409fa23609d0..0f6c86c634fd601482c6cca840999b89c5ca4b4f 100644 (file)
@@ -561,6 +561,7 @@ enum {
 #define EXT2_DIR_ROUND                         (EXT2_DIR_PAD - 1)
 #define EXT2_DIR_REC_LEN(name_len)     (((name_len) + 8 + EXT2_DIR_ROUND) & \
                                         ~EXT2_DIR_ROUND)
+#define EXT2_MAX_REC_LEN               ((1<<16)-1)
 
 static inline ext2_fsblk_t
 ext2_group_first_block_no(struct super_block *sb, unsigned long group_no)
index 589b0b355d84d1967eac403c390f23e428eb33c2..64134456ed8cf33782e3d4a83757f4c46515f644 100644 (file)
@@ -72,8 +72,8 @@
  * Macro-instructions used to manage several block sizes
  */
 #define EXT3_MIN_BLOCK_SIZE            1024
-#define        EXT3_MAX_BLOCK_SIZE             4096
-#define EXT3_MIN_BLOCK_LOG_SIZE                  10
+#define        EXT3_MAX_BLOCK_SIZE             65536
+#define EXT3_MIN_BLOCK_LOG_SIZE                10
 #ifdef __KERNEL__
 # define EXT3_BLOCK_SIZE(s)            ((s)->s_blocksize)
 #else
index cdee7aaa57aa60952281c54320f7a9bf0fa936fb..97dd409d5f4a1194fa6034242793d03290968f59 100644 (file)
 /*max window size: 1024(direct blocks) + 3([t,d]indirect blocks) */
 #define EXT4_MAX_RESERVE_BLOCKS                1027
 #define EXT4_RESERVE_WINDOW_NOT_ALLOCATED 0
-/*
- * Always enable hashed directories
- */
-#define CONFIG_EXT4_INDEX
 
 /*
  * Debug code
 #endif
 #define EXT4_BLOCK_ALIGN(size, blkbits)                ALIGN((size), (1 << (blkbits)))
 
-/*
- * Macro-instructions used to manage fragments
- */
-#define EXT4_MIN_FRAG_SIZE             1024
-#define        EXT4_MAX_FRAG_SIZE              4096
-#define EXT4_MIN_FRAG_LOG_SIZE           10
-#ifdef __KERNEL__
-# define EXT4_FRAG_SIZE(s)             (EXT4_SB(s)->s_frag_size)
-# define EXT4_FRAGS_PER_BLOCK(s)       (EXT4_SB(s)->s_frags_per_block)
-#else
-# define EXT4_FRAG_SIZE(s)             (EXT4_MIN_FRAG_SIZE << (s)->s_log_frag_size)
-# define EXT4_FRAGS_PER_BLOCK(s)       (EXT4_BLOCK_SIZE(s) / EXT4_FRAG_SIZE(s))
-#endif
-
 /*
  * Structure of a blocks group descriptor
  */
 struct ext4_group_desc
 {
-       __le32  bg_block_bitmap;                /* Blocks bitmap block */
-       __le32  bg_inode_bitmap;                /* Inodes bitmap block */
-       __le32  bg_inode_table;         /* Inodes table block */
+       __le32  bg_block_bitmap_lo;     /* Blocks bitmap block */
+       __le32  bg_inode_bitmap_lo;     /* Inodes bitmap block */
+       __le32  bg_inode_table_lo;      /* Inodes table block */
        __le16  bg_free_blocks_count;   /* Free blocks count */
        __le16  bg_free_inodes_count;   /* Free inodes count */
        __le16  bg_used_dirs_count;     /* Directories count */
-       __u16   bg_flags;
-       __u32   bg_reserved[3];
+       __le16  bg_flags;               /* EXT4_BG_flags (INODE_UNINIT, etc) */
+       __u32   bg_reserved[2];         /* Likely block/inode bitmap checksum */
+       __le16  bg_itable_unused;       /* Unused inodes count */
+       __le16  bg_checksum;            /* crc16(sb_uuid+group+desc) */
        __le32  bg_block_bitmap_hi;     /* Blocks bitmap block MSB */
        __le32  bg_inode_bitmap_hi;     /* Inodes bitmap block MSB */
        __le32  bg_inode_table_hi;      /* Inodes table block MSB */
 };
 
+#define EXT4_BG_INODE_UNINIT   0x0001 /* Inode table/bitmap not in use */
+#define EXT4_BG_BLOCK_UNINIT   0x0002 /* Block bitmap not in use */
+#define EXT4_BG_INODE_ZEROED   0x0004 /* On-disk itable initialized to zero */
+
 #ifdef __KERNEL__
 #include <linux/ext4_fs_i.h>
 #include <linux/ext4_fs_sb.h>
@@ -311,27 +299,24 @@ struct ext4_inode {
        __le32  i_generation;   /* File version (for NFS) */
        __le32  i_file_acl;     /* File ACL */
        __le32  i_dir_acl;      /* Directory ACL */
-       __le32  i_faddr;        /* Fragment address */
+       __le32  i_obso_faddr;   /* Obsoleted fragment address */
        union {
                struct {
-                       __u8    l_i_frag;       /* Fragment number */
-                       __u8    l_i_fsize;      /* Fragment size */
+                       __le16  l_i_reserved1;  /* Obsoleted fragment number/size which are removed in ext4 */
                        __le16  l_i_file_acl_high;
                        __le16  l_i_uid_high;   /* these 2 fields */
                        __le16  l_i_gid_high;   /* were reserved2[0] */
                        __u32   l_i_reserved2;
                } linux2;
                struct {
-                       __u8    h_i_frag;       /* Fragment number */
-                       __u8    h_i_fsize;      /* Fragment size */
+                       __le16  h_i_reserved1;  /* Obsoleted fragment number/size which are removed in ext4 */
                        __u16   h_i_mode_high;
                        __u16   h_i_uid_high;
                        __u16   h_i_gid_high;
                        __u32   h_i_author;
                } hurd2;
                struct {
-                       __u8    m_i_frag;       /* Fragment number */
-                       __u8    m_i_fsize;      /* Fragment size */
+                       __le16  h_i_reserved1;  /* Obsoleted fragment number/size which are removed in ext4 */
                        __le16  m_i_file_acl_high;
                        __u32   m_i_reserved2[2];
                } masix2;
@@ -419,8 +404,6 @@ do {                                                                               \
 
 #if defined(__KERNEL__) || defined(__linux__)
 #define i_reserved1    osd1.linux1.l_i_reserved1
-#define i_frag         osd2.linux2.l_i_frag
-#define i_fsize                osd2.linux2.l_i_fsize
 #define i_file_acl_high        osd2.linux2.l_i_file_acl_high
 #define i_uid_low      i_uid
 #define i_gid_low      i_gid
@@ -431,8 +414,6 @@ do {                                                                               \
 #elif defined(__GNU__)
 
 #define i_translator   osd1.hurd1.h_i_translator
-#define i_frag         osd2.hurd2.h_i_frag;
-#define i_fsize                osd2.hurd2.h_i_fsize;
 #define i_uid_high     osd2.hurd2.h_i_uid_high
 #define i_gid_high     osd2.hurd2.h_i_gid_high
 #define i_author       osd2.hurd2.h_i_author
@@ -440,8 +421,6 @@ do {                                                                               \
 #elif defined(__masix__)
 
 #define i_reserved1    osd1.masix1.m_i_reserved1
-#define i_frag         osd2.masix2.m_i_frag
-#define i_fsize                osd2.masix2.m_i_fsize
 #define i_file_acl_high        osd2.masix2.m_i_file_acl_high
 #define i_reserved2    osd2.masix2.m_i_reserved2
 
@@ -522,15 +501,15 @@ do {                                                                             \
  */
 struct ext4_super_block {
 /*00*/ __le32  s_inodes_count;         /* Inodes count */
-       __le32  s_blocks_count;         /* Blocks count */
-       __le32  s_r_blocks_count;       /* Reserved blocks count */
-       __le32  s_free_blocks_count;    /* Free blocks count */
+       __le32  s_blocks_count_lo;      /* Blocks count */
+       __le32  s_r_blocks_count_lo;    /* Reserved blocks count */
+       __le32  s_free_blocks_count_lo; /* Free blocks count */
 /*10*/ __le32  s_free_inodes_count;    /* Free inodes count */
        __le32  s_first_data_block;     /* First Data Block */
        __le32  s_log_block_size;       /* Block size */
-       __le32  s_log_frag_size;        /* Fragment size */
+       __le32  s_obso_log_frag_size;   /* Obsoleted fragment size */
 /*20*/ __le32  s_blocks_per_group;     /* # Blocks per group */
-       __le32  s_frags_per_group;      /* # Fragments per group */
+       __le32  s_obso_frags_per_group; /* Obsoleted fragments per group */
        __le32  s_inodes_per_group;     /* # Inodes per group */
        __le32  s_mtime;                /* Mount time */
 /*30*/ __le32  s_wtime;                /* Write time */
@@ -595,13 +574,13 @@ struct ext4_super_block {
 /*150*/        __le32  s_blocks_count_hi;      /* Blocks count */
        __le32  s_r_blocks_count_hi;    /* Reserved blocks count */
        __le32  s_free_blocks_count_hi; /* Free blocks count */
-       __u16   s_min_extra_isize;      /* All inodes have at least # bytes */
-       __u16   s_want_extra_isize;     /* New inodes should reserve # bytes */
-       __u32   s_flags;                /* Miscellaneous flags */
-       __u16   s_raid_stride;          /* RAID stride */
-       __u16   s_mmp_interval;         /* # seconds to wait in MMP checking */
-       __u64   s_mmp_block;            /* Block for multi-mount protection */
-       __u32   s_raid_stripe_width;    /* blocks on all data disks (N*stride)*/
+       __le16  s_min_extra_isize;      /* All inodes have at least # bytes */
+       __le16  s_want_extra_isize;     /* New inodes should reserve # bytes */
+       __le32  s_flags;                /* Miscellaneous flags */
+       __le16  s_raid_stride;          /* RAID stride */
+       __le16  s_mmp_interval;         /* # seconds to wait in MMP checking */
+       __le64  s_mmp_block;            /* Block for multi-mount protection */
+       __le32  s_raid_stripe_width;    /* blocks on all data disks (N*stride)*/
        __u32   s_reserved[163];        /* Padding to the end of the block */
 };
 
@@ -692,6 +671,7 @@ static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
 #define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER    0x0001
 #define EXT4_FEATURE_RO_COMPAT_LARGE_FILE      0x0002
 #define EXT4_FEATURE_RO_COMPAT_BTREE_DIR       0x0004
+#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM                0x0010
 #define EXT4_FEATURE_RO_COMPAT_DIR_NLINK       0x0020
 #define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE     0x0040
 
@@ -702,15 +682,18 @@ static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
 #define EXT4_FEATURE_INCOMPAT_META_BG          0x0010
 #define EXT4_FEATURE_INCOMPAT_EXTENTS          0x0040 /* extents support */
 #define EXT4_FEATURE_INCOMPAT_64BIT            0x0080
+#define EXT4_FEATURE_INCOMPAT_FLEX_BG          0x0200
 
 #define EXT4_FEATURE_COMPAT_SUPP       EXT2_FEATURE_COMPAT_EXT_ATTR
 #define EXT4_FEATURE_INCOMPAT_SUPP     (EXT4_FEATURE_INCOMPAT_FILETYPE| \
                                         EXT4_FEATURE_INCOMPAT_RECOVER| \
                                         EXT4_FEATURE_INCOMPAT_META_BG| \
                                         EXT4_FEATURE_INCOMPAT_EXTENTS| \
-                                        EXT4_FEATURE_INCOMPAT_64BIT)
+                                        EXT4_FEATURE_INCOMPAT_64BIT| \
+                                        EXT4_FEATURE_INCOMPAT_FLEX_BG)
 #define EXT4_FEATURE_RO_COMPAT_SUPP    (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \
                                         EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \
+                                        EXT4_FEATURE_RO_COMPAT_GDT_CSUM| \
                                         EXT4_FEATURE_RO_COMPAT_DIR_NLINK | \
                                         EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE | \
                                         EXT4_FEATURE_RO_COMPAT_BTREE_DIR)
@@ -789,17 +772,11 @@ struct ext4_dir_entry_2 {
  * (c) Daniel Phillips, 2001
  */
 
-#ifdef CONFIG_EXT4_INDEX
-  #define is_dx(dir) (EXT4_HAS_COMPAT_FEATURE(dir->i_sb, \
-                                             EXT4_FEATURE_COMPAT_DIR_INDEX) && \
+#define is_dx(dir) (EXT4_HAS_COMPAT_FEATURE(dir->i_sb, \
+                                     EXT4_FEATURE_COMPAT_DIR_INDEX) && \
                      (EXT4_I(dir)->i_flags & EXT4_INDEX_FL))
 #define EXT4_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT4_LINK_MAX)
 #define EXT4_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1)
-#else
-  #define is_dx(dir) 0
-#define EXT4_DIR_LINK_MAX(dir) ((dir)->i_nlink >= EXT4_LINK_MAX)
-#define EXT4_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2)
-#endif
 
 /* Legal values for the dx_root hash_version field: */
 
@@ -1004,39 +981,39 @@ extern void ext4_inode_table_set(struct super_block *sb,
 static inline ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es)
 {
        return ((ext4_fsblk_t)le32_to_cpu(es->s_blocks_count_hi) << 32) |
-               le32_to_cpu(es->s_blocks_count);
+               le32_to_cpu(es->s_blocks_count_lo);
 }
 
 static inline ext4_fsblk_t ext4_r_blocks_count(struct ext4_super_block *es)
 {
        return ((ext4_fsblk_t)le32_to_cpu(es->s_r_blocks_count_hi) << 32) |
-               le32_to_cpu(es->s_r_blocks_count);
+               le32_to_cpu(es->s_r_blocks_count_lo);
 }
 
 static inline ext4_fsblk_t ext4_free_blocks_count(struct ext4_super_block *es)
 {
        return ((ext4_fsblk_t)le32_to_cpu(es->s_free_blocks_count_hi) << 32) |
-               le32_to_cpu(es->s_free_blocks_count);
+               le32_to_cpu(es->s_free_blocks_count_lo);
 }
 
 static inline void ext4_blocks_count_set(struct ext4_super_block *es,
                                         ext4_fsblk_t blk)
 {
-       es->s_blocks_count = cpu_to_le32((u32)blk);
+       es->s_blocks_count_lo = cpu_to_le32((u32)blk);
        es->s_blocks_count_hi = cpu_to_le32(blk >> 32);
 }
 
 static inline void ext4_free_blocks_count_set(struct ext4_super_block *es,
                                              ext4_fsblk_t blk)
 {
-       es->s_free_blocks_count = cpu_to_le32((u32)blk);
+       es->s_free_blocks_count_lo = cpu_to_le32((u32)blk);
        es->s_free_blocks_count_hi = cpu_to_le32(blk >> 32);
 }
 
 static inline void ext4_r_blocks_count_set(struct ext4_super_block *es,
                                           ext4_fsblk_t blk)
 {
-       es->s_r_blocks_count = cpu_to_le32((u32)blk);
+       es->s_r_blocks_count_lo = cpu_to_le32((u32)blk);
        es->s_r_blocks_count_hi = cpu_to_le32(blk >> 32);
 }
 
index 81406f3655d4bd162c0ed0aade00c19de8666371..d2045a26195d6ebf576b922dd050b3c1a433d60d 100644 (file)
@@ -74,7 +74,7 @@ struct ext4_extent {
        __le32  ee_block;       /* first logical block extent covers */
        __le16  ee_len;         /* number of blocks covered by extent */
        __le16  ee_start_hi;    /* high 16 bits of physical block */
-       __le32  ee_start;       /* low 32 bits of physical block */
+       __le32  ee_start_lo;    /* low 32 bits of physical block */
 };
 
 /*
@@ -83,7 +83,7 @@ struct ext4_extent {
  */
 struct ext4_extent_idx {
        __le32  ei_block;       /* index covers logical blocks from 'block' */
-       __le32  ei_leaf;        /* pointer to the physical block of the next *
+       __le32  ei_leaf_lo;     /* pointer to the physical block of the next *
                                 * level. leaf or next index could be there */
        __le16  ei_leaf_hi;     /* high 16 bits of physical block */
        __u16   ei_unused;
index 1a511e9905aa2ae7d5c38a23da98644632eb6977..86ddfe2089f30ed1d2d14e7f5d976fde318b03f9 100644 (file)
@@ -78,11 +78,6 @@ struct ext4_ext_cache {
 struct ext4_inode_info {
        __le32  i_data[15];     /* unconverted */
        __u32   i_flags;
-#ifdef EXT4_FRAGMENTS
-       __u32   i_faddr;
-       __u8    i_frag_no;
-       __u8    i_frag_size;
-#endif
        ext4_fsblk_t    i_file_acl;
        __u32   i_dir_acl;
        __u32   i_dtime;
index 0a8e47d47c91ce11b2dbc6d4f99f3de004201111..b40e827cd4954f7ecead22be34f2259c8f81b915 100644 (file)
  * third extended-fs super-block data in memory
  */
 struct ext4_sb_info {
-       unsigned long s_frag_size;      /* Size of a fragment in bytes */
        unsigned long s_desc_size;      /* Size of a group descriptor in bytes */
-       unsigned long s_frags_per_block;/* Number of fragments per block */
        unsigned long s_inodes_per_block;/* Number of inodes per block */
-       unsigned long s_frags_per_group;/* Number of fragments in a group */
        unsigned long s_blocks_per_group;/* Number of blocks in a group */
        unsigned long s_inodes_per_group;/* Number of inodes in a group */
        unsigned long s_itb_per_group;  /* Number of inode table blocks per group */
index d716e6392cf6e7e5d6215da354b20a1c96e1d495..38c71d3c8dbf39efff5278fa9c58272d70c4554b 100644 (file)
@@ -12,8 +12,8 @@
  * Ext4-specific journaling extensions.
  */
 
-#ifndef _LINUX_EXT4_JBD_H
-#define _LINUX_EXT4_JBD_H
+#ifndef _LINUX_EXT4_JBD2_H
+#define _LINUX_EXT4_JBD2_H
 
 #include <linux/fs.h>
 #include <linux/jbd2.h>
@@ -228,4 +228,4 @@ static inline int ext4_should_writeback_data(struct inode *inode)
        return 0;
 }
 
-#endif /* _LINUX_EXT4_JBD_H */
+#endif /* _LINUX_EXT4_JBD2_H */
index 91b2e3b9251eb67ee57b19dd44ba0f84bb8fcb94..ddfa0372a3b723d978823bea9a3d4e267abf0506 100644 (file)
@@ -146,6 +146,7 @@ struct sock;
 
 extern unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen);
 extern int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk);
+extern int sk_detach_filter(struct sock *sk);
 extern int sk_chk_filter(struct sock_filter *filter, int flen);
 #endif /* __KERNEL__ */
 
index efded00ad08c5003bebd89964bb8b8619630a2c2..08934995c7ab5463e5f4064f4e2fff5ccfb4af94 100644 (file)
@@ -4,6 +4,7 @@
 #define FREEZER_H_INCLUDED
 
 #include <linux/sched.h>
+#include <linux/wait.h>
 
 #ifdef CONFIG_PM_SLEEP
 /*
@@ -126,6 +127,36 @@ static inline void set_freezable(void)
        current->flags &= ~PF_NOFREEZE;
 }
 
+/*
+ * Freezer-friendly wrappers around wait_event_interruptible() and
+ * wait_event_interruptible_timeout(), originally defined in <linux/wait.h>
+ */
+
+#define wait_event_freezable(wq, condition)                            \
+({                                                                     \
+       int __retval;                                                   \
+       do {                                                            \
+               __retval = wait_event_interruptible(wq,                 \
+                               (condition) || freezing(current));      \
+               if (__retval && !freezing(current))                     \
+                       break;                                          \
+               else if (!(condition))                                  \
+                       __retval = -ERESTARTSYS;                        \
+       } while (try_to_freeze());                                      \
+       __retval;                                                       \
+})
+
+
+#define wait_event_freezable_timeout(wq, condition, timeout)           \
+({                                                                     \
+       long __retval = timeout;                                        \
+       do {                                                            \
+               __retval = wait_event_interruptible_timeout(wq,         \
+                               (condition) || freezing(current),       \
+                               __retval);                              \
+       } while (try_to_freeze());                                      \
+       __retval;                                                       \
+})
 #else /* !CONFIG_PM_SLEEP */
 static inline int frozen(struct task_struct *p) { return 0; }
 static inline int freezing(struct task_struct *p) { return 0; }
@@ -143,6 +174,13 @@ static inline void freezer_do_not_count(void) {}
 static inline void freezer_count(void) {}
 static inline int freezer_should_skip(struct task_struct *p) { return 0; }
 static inline void set_freezable(void) {}
+
+#define wait_event_freezable(wq, condition)                            \
+               wait_event_interruptible(wq, condition)
+
+#define wait_event_freezable_timeout(wq, condition, timeout)           \
+               wait_event_interruptible_timeout(wq, condition, timeout)
+
 #endif /* !CONFIG_PM_SLEEP */
 
 #endif /* FREEZER_H_INCLUDED */
index e3fc5dbb22460ad7d265f5fb47d8839ea4fe32f5..b3ec4a496d64faa3a380827abed7b54d9d8bd7da 100644 (file)
@@ -123,6 +123,7 @@ extern int dir_notify_enable;
 #define MS_SLAVE       (1<<19) /* change to slave */
 #define MS_SHARED      (1<<20) /* change to shared */
 #define MS_RELATIME    (1<<21) /* Update atime relative to mtime/ctime. */
+#define MS_KERNMOUNT   (1<<22) /* this is a kern_mount call */
 #define MS_ACTIVE      (1<<30)
 #define MS_NOUSER      (1<<31)
 
@@ -330,6 +331,7 @@ typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
 #define ATTR_KILL_SGID 4096
 #define ATTR_FILE      8192
 #define ATTR_KILL_PRIV 16384
+#define ATTR_OPEN      32768   /* Truncating from open(O_TRUNC) */
 
 /*
  * This is the Inode Attributes structure, used for notify_change().  It
@@ -985,7 +987,7 @@ struct super_block {
        const struct super_operations   *s_op;
        struct dquot_operations *dq_op;
        struct quotactl_ops     *s_qcop;
-       struct export_operations *s_export_op;
+       const struct export_operations *s_export_op;
        unsigned long           s_flags;
        unsigned long           s_magic;
        struct dentry           *s_root;
@@ -1458,7 +1460,8 @@ void unnamed_dev_init(void);
 
 extern int register_filesystem(struct file_system_type *);
 extern int unregister_filesystem(struct file_system_type *);
-extern struct vfsmount *kern_mount(struct file_system_type *);
+extern struct vfsmount *kern_mount_data(struct file_system_type *, void *data);
+#define kern_mount(type) kern_mount_data(type, NULL)
 extern int may_umount_tree(struct vfsmount *);
 extern int may_umount(struct vfsmount *);
 extern void umount_tree(struct vfsmount *, int, struct list_head *);
@@ -1467,6 +1470,8 @@ extern long do_mount(char *, char *, char *, unsigned long, void *);
 extern struct vfsmount *copy_tree(struct vfsmount *, struct dentry *, int);
 extern void mnt_set_mountpoint(struct vfsmount *, struct dentry *,
                                  struct vfsmount *);
+extern struct vfsmount *collect_mounts(struct vfsmount *, struct dentry *);
+extern void drop_collected_mounts(struct vfsmount *);
 
 extern int vfs_statfs(struct dentry *, struct kstatfs *);
 
@@ -1533,7 +1538,7 @@ static inline int break_lease(struct inode *inode, unsigned int mode)
 
 extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
                       struct file *filp);
-extern long do_sys_open(int fdf, const char __user *filename, int flags,
+extern long do_sys_open(int dfd, const char __user *filename, int flags,
                        int mode);
 extern struct file *filp_open(const char *, int, int);
 extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
@@ -1921,6 +1926,8 @@ extern int vfs_fstat(unsigned int, struct kstat *);
 
 extern int vfs_ioctl(struct file *, unsigned int, unsigned int, unsigned long);
 
+extern void get_filesystem(struct file_system_type *fs);
+extern void put_filesystem(struct file_system_type *fs);
 extern struct file_system_type *get_fs_type(const char *name);
 extern struct super_block *get_super(struct block_device *);
 extern struct super_block *user_get_super(dev_t);
index dfc4e4f68da4b3a301080463e4ef41c52f8d604b..2bd31fa623b6a7b12c3aa8ac9369cc698b0746d2 100644 (file)
@@ -41,8 +41,9 @@ static inline void fsnotify_d_move(struct dentry *entry)
  */
 static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir,
                                 const char *old_name, const char *new_name,
-                                int isdir, struct inode *target, struct inode *source)
+                                int isdir, struct inode *target, struct dentry *moved)
 {
+       struct inode *source = moved->d_inode;
        u32 cookie = inotify_get_cookie();
 
        if (old_dir == new_dir)
@@ -67,7 +68,7 @@ static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir,
        if (source) {
                inotify_inode_queue_event(source, IN_MOVE_SELF, 0, NULL, NULL);
        }
-       audit_inode_child(new_name, source, new_dir);
+       audit_inode_child(new_name, moved, new_dir);
 }
 
 /*
@@ -98,7 +99,7 @@ static inline void fsnotify_create(struct inode *inode, struct dentry *dentry)
        inode_dir_notify(inode, DN_CREATE);
        inotify_inode_queue_event(inode, IN_CREATE, 0, dentry->d_name.name,
                                  dentry->d_inode);
-       audit_inode_child(dentry->d_name.name, dentry->d_inode, inode);
+       audit_inode_child(dentry->d_name.name, dentry, inode);
 }
 
 /*
@@ -109,7 +110,7 @@ static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry)
        inode_dir_notify(inode, DN_CREATE);
        inotify_inode_queue_event(inode, IN_CREATE | IN_ISDIR, 0, 
                                  dentry->d_name.name, dentry->d_inode);
-       audit_inode_child(dentry->d_name.name, dentry->d_inode, inode);
+       audit_inode_child(dentry->d_name.name, dentry, inode);
 }
 
 /*
index 9fbe9d258e2259b196fc752213dd84ea03a2f5d4..d0c437028c80a18b1cace46c89bf59b92a39f59e 100644 (file)
@@ -6,7 +6,17 @@
     See the file COPYING.
 */
 
-/* This file defines the kernel interface of FUSE */
+/*
+ * This file defines the kernel interface of FUSE
+ *
+ * Protocol changelog:
+ *
+ * 7.9:
+ *  - new fuse_getattr_in input argument of GETATTR
+ *  - add lk_flags in fuse_lk_in
+ *  - add lock_owner field to fuse_setattr_in, fuse_read_in and fuse_write_in
+ *  - add blksize field to fuse_attr
+ */
 
 #include <asm/types.h>
 #include <linux/major.h>
@@ -15,7 +25,7 @@
 #define FUSE_KERNEL_VERSION 7
 
 /** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 8
+#define FUSE_KERNEL_MINOR_VERSION 9
 
 /** The node ID of the root inode */
 #define FUSE_ROOT_ID 1
@@ -44,6 +54,8 @@ struct fuse_attr {
        __u32   uid;
        __u32   gid;
        __u32   rdev;
+       __u32   blksize;
+       __u32   padding;
 };
 
 struct fuse_kstatfs {
@@ -76,6 +88,9 @@ struct fuse_file_lock {
 #define FATTR_ATIME    (1 << 4)
 #define FATTR_MTIME    (1 << 5)
 #define FATTR_FH       (1 << 6)
+#define FATTR_ATIME_NOW        (1 << 7)
+#define FATTR_MTIME_NOW        (1 << 8)
+#define FATTR_LOCKOWNER        (1 << 9)
 
 /**
  * Flags returned by the OPEN request
@@ -91,12 +106,38 @@ struct fuse_file_lock {
  */
 #define FUSE_ASYNC_READ                (1 << 0)
 #define FUSE_POSIX_LOCKS       (1 << 1)
+#define FUSE_FILE_OPS          (1 << 2)
+#define FUSE_ATOMIC_O_TRUNC    (1 << 3)
 
 /**
  * Release flags
  */
 #define FUSE_RELEASE_FLUSH     (1 << 0)
 
+/**
+ * Getattr flags
+ */
+#define FUSE_GETATTR_FH                (1 << 0)
+
+/**
+ * Lock flags
+ */
+#define FUSE_LK_FLOCK          (1 << 0)
+
+/**
+ * WRITE flags
+ *
+ * FUSE_WRITE_CACHE: delayed write from page cache, file handle is guessed
+ * FUSE_WRITE_LOCKOWNER: lock_owner field is valid
+ */
+#define FUSE_WRITE_CACHE       (1 << 0)
+#define FUSE_WRITE_LOCKOWNER   (1 << 1)
+
+/**
+ * Read flags
+ */
+#define FUSE_READ_LOCKOWNER    (1 << 1)
+
 enum fuse_opcode {
        FUSE_LOOKUP        = 1,
        FUSE_FORGET        = 2,  /* no reply */
@@ -139,6 +180,8 @@ enum fuse_opcode {
 /* The read buffer is required to be at least 8k, but may be much larger */
 #define FUSE_MIN_READ_BUFFER 8192
 
+#define FUSE_COMPAT_ENTRY_OUT_SIZE 120
+
 struct fuse_entry_out {
        __u64   nodeid;         /* Inode ID */
        __u64   generation;     /* Inode generation: nodeid:gen must
@@ -154,6 +197,14 @@ struct fuse_forget_in {
        __u64   nlookup;
 };
 
+struct fuse_getattr_in {
+       __u32   getattr_flags;
+       __u32   dummy;
+       __u64   fh;
+};
+
+#define FUSE_COMPAT_ATTR_OUT_SIZE 96
+
 struct fuse_attr_out {
        __u64   attr_valid;     /* Cache timeout for the attributes */
        __u32   attr_valid_nsec;
@@ -184,7 +235,7 @@ struct fuse_setattr_in {
        __u32   padding;
        __u64   fh;
        __u64   size;
-       __u64   unused1;
+       __u64   lock_owner;
        __u64   atime;
        __u64   mtime;
        __u64   unused2;
@@ -227,14 +278,18 @@ struct fuse_read_in {
        __u64   fh;
        __u64   offset;
        __u32   size;
-       __u32   padding;
+       __u32   read_flags;
+       __u64   lock_owner;
 };
 
+#define FUSE_COMPAT_WRITE_IN_SIZE 24
+
 struct fuse_write_in {
        __u64   fh;
        __u64   offset;
        __u32   size;
        __u32   write_flags;
+       __u64   lock_owner;
 };
 
 struct fuse_write_out {
@@ -273,6 +328,8 @@ struct fuse_lk_in {
        __u64   fh;
        __u64   owner;
        struct fuse_file_lock lk;
+       __u32   lk_flags;
+       __u32   padding;
 };
 
 struct fuse_lk_out {
index edb8024d744bff94c1fa4c3d3abc4adaaf863802..6e35b92b1d2caeb6ee4b24f8cf7a8c7c0f158899 100644 (file)
@@ -469,8 +469,8 @@ struct hid_device {                                                 /* device report descriptor */
        /* handler for raw output data, used by hidraw */
        int (*hid_output_raw_report) (struct hid_device *, __u8 *, size_t);
 #ifdef CONFIG_USB_HIDINPUT_POWERBOOK
-       unsigned long pb_pressed_fn[NBITS(KEY_MAX)];
-       unsigned long pb_pressed_numlock[NBITS(KEY_MAX)];
+       unsigned long pb_pressed_fn[BITS_TO_LONGS(KEY_CNT)];
+       unsigned long pb_pressed_numlock[BITS_TO_LONGS(KEY_CNT)];
 #endif
 };
 
index 540799bc85f864ad7569b50804ac7843ccdbe750..7a9398e1970432a500f5a660bf458c26f0158554 100644 (file)
@@ -300,7 +300,7 @@ hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval);
 
 /* Precise sleep: */
 extern long hrtimer_nanosleep(struct timespec *rqtp,
-                             struct timespec __user *rmtp,
+                             struct timespec *rmtp,
                              const enum hrtimer_mode mode,
                              const clockid_t clockid);
 extern long hrtimer_nanosleep_restart(struct restart_block *restart_block);
diff --git a/include/linux/i8042.h b/include/linux/i8042.h
new file mode 100644 (file)
index 0000000..7907a72
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef _LINUX_I8042_H
+#define _LINUX_I8042_H
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+
+/*
+ * Standard commands.
+ */
+
+#define I8042_CMD_CTL_RCTR     0x0120
+#define I8042_CMD_CTL_WCTR     0x1060
+#define I8042_CMD_CTL_TEST     0x01aa
+
+#define I8042_CMD_KBD_DISABLE  0x00ad
+#define I8042_CMD_KBD_ENABLE   0x00ae
+#define I8042_CMD_KBD_TEST     0x01ab
+#define I8042_CMD_KBD_LOOP     0x11d2
+
+#define I8042_CMD_AUX_DISABLE  0x00a7
+#define I8042_CMD_AUX_ENABLE   0x00a8
+#define I8042_CMD_AUX_TEST     0x01a9
+#define I8042_CMD_AUX_SEND     0x10d4
+#define I8042_CMD_AUX_LOOP     0x11d3
+
+#define I8042_CMD_MUX_PFX      0x0090
+#define I8042_CMD_MUX_SEND     0x1090
+
+int i8042_command(unsigned char *param, int command);
+
+#endif
index e39ee2fa260720a48236815c9ba6de334339de84..4ed4777bba67abcd5ecba17bb3c8c2ca19e999f9 100644 (file)
@@ -192,22 +192,20 @@ typedef unsigned char     byte;   /* used everywhere */
 struct hwif_s;
 typedef int (ide_ack_intr_t)(struct hwif_s *);
 
-#ifndef NO_DMA
-#define NO_DMA  255
-#endif
-
 /*
  * hwif_chipset_t is used to keep track of the specific hardware
  * chipset used by each IDE interface, if known.
  */
-typedef enum { ide_unknown,    ide_generic,    ide_pci,
+enum {         ide_unknown,    ide_generic,    ide_pci,
                ide_cmd640,     ide_dtc2278,    ide_ali14xx,
                ide_qd65xx,     ide_umc8672,    ide_ht6560b,
                ide_rz1000,     ide_trm290,
                ide_cmd646,     ide_cy82c693,   ide_4drives,
                ide_pmac,       ide_etrax100,   ide_acorn,
                ide_au1xxx, ide_forced
-} hwif_chipset_t;
+};
+
+typedef u8 hwif_chipset_t;
 
 /*
  * Structure to hold all information about the location of this port
@@ -215,22 +213,16 @@ typedef enum {    ide_unknown,    ide_generic,    ide_pci,
 typedef struct hw_regs_s {
        unsigned long   io_ports[IDE_NR_PORTS]; /* task file registers */
        int             irq;                    /* our irq number */
-       int             dma;                    /* our dma entry */
        ide_ack_intr_t  *ack_intr;              /* acknowledge interrupt */
        hwif_chipset_t  chipset;
        struct device   *dev;
 } hw_regs_t;
 
-/*
- * Register new hardware with ide
- */
-int ide_register_hw(hw_regs_t *, int, struct hwif_s **);
-int ide_register_hw_with_fixup(hw_regs_t *, int, struct hwif_s **,
-                              void (*)(struct hwif_s *));
+struct hwif_s * ide_find_port(unsigned long);
+
+int ide_register_hw(hw_regs_t *, void (*)(struct hwif_s *), int,
+                   struct hwif_s **);
 
-/*
- * Set up hw_regs_t structure before calling ide_register_hw (optional)
- */
 void ide_setup_ports(  hw_regs_t *hw,
                        unsigned long base,
                        int *offsets,
@@ -268,11 +260,7 @@ static inline void ide_std_init_ports(hw_regs_t *hw,
 # define ide_init_default_irq(base)    (0)
 #endif
 
-/*
- * ide_init_hwif_ports() is OBSOLETE and will be removed in 2.7 series.
- * New ports shouldn't define IDE_ARCH_OBSOLETE_INIT in <asm/ide.h>.
- */
-#ifdef IDE_ARCH_OBSOLETE_INIT
+#ifdef CONFIG_IDE_ARCH_OBSOLETE_INIT
 static inline void ide_init_hwif_ports(hw_regs_t *hw,
                                       unsigned long io_addr,
                                       unsigned long ctl_addr,
@@ -302,7 +290,7 @@ static inline void ide_init_hwif_ports(hw_regs_t *hw,
        if (io_addr || ctl_addr)
                printk(KERN_WARNING "%s: must not be called\n", __FUNCTION__);
 }
-#endif /* IDE_ARCH_OBSOLETE_INIT */
+#endif /* CONFIG_IDE_ARCH_OBSOLETE_INIT */
 
 /* Currently only m68k, apus and m8xx need it */
 #ifndef IDE_ARCH_ACK_INTR
@@ -363,7 +351,6 @@ typedef union {
  * ATA DATA Register Special.
  * ATA NSECTOR Count Register().
  * ATAPI Byte Count Register.
- * Channel index ordering pairs.
  */
 typedef union {
        unsigned all                    :16;
@@ -378,7 +365,7 @@ typedef union {
 #error "Please fix <asm/byteorder.h>"
 #endif
        } b;
-} ata_nsector_t, ata_data_t, atapi_bcount_t, ata_index_t;
+} ata_nsector_t, ata_data_t, atapi_bcount_t;
 
 /*
  * ATA-IDE Select Register, aka Device-Head
@@ -657,7 +644,7 @@ typedef struct ide_drive_s {
     ((1<<ide_pci)|(1<<ide_cmd646)|(1<<ide_ali14xx))
 #define IDE_CHIPSET_IS_PCI(c)  ((IDE_CHIPSET_PCI_MASK >> (c)) & 1)
 
-struct ide_pci_device_s;
+struct ide_port_info;
 
 typedef struct hwif_s {
        struct hwif_s *next;            /* for linked-list in ide_hwgroup_t */
@@ -672,7 +659,6 @@ typedef struct hwif_s {
        unsigned long   sata_scr[SATA_NR_PORTS];
        unsigned long   sata_misc[SATA_NR_PORTS];
 
-       hw_regs_t       hw;             /* Hardware info */
        ide_drive_t     drives[MAX_DRIVES];     /* drive info */
 
        u8 major;       /* our major number */
@@ -681,11 +667,10 @@ typedef struct hwif_s {
        u8 straight8;   /* Alan's straight 8 check */
        u8 bus_state;   /* power state of the IDE bus */
 
-       u16 host_flags;
+       u32 host_flags;
 
        u8 pio_mask;
 
-       u8 atapi_dma;   /* host supports atapi_dma */
        u8 ultra_mask;
        u8 mwdma_mask;
        u8 swdma_mask;
@@ -695,7 +680,9 @@ typedef struct hwif_s {
        hwif_chipset_t chipset; /* sub-module for tuning.. */
 
        struct pci_dev  *pci_dev;       /* for pci chipsets */
-       struct ide_pci_device_s *cds;   /* chipset device struct */
+       const struct ide_port_info *cds;        /* chipset device struct */
+
+       ide_ack_intr_t *ack_intr;
 
        void (*rw_disk)(ide_drive_t *, struct request *);
 
@@ -726,6 +713,8 @@ typedef struct hwif_s {
        u8 (*mdma_filter)(ide_drive_t *);
        u8 (*udma_filter)(ide_drive_t *);
 
+       void (*fixup)(struct hwif_s *);
+
        void (*ata_input_data)(ide_drive_t *, void *, u32);
        void (*ata_output_data)(ide_drive_t *, void *, u32);
 
@@ -797,12 +786,9 @@ typedef struct hwif_s {
        unsigned        serialized : 1; /* serialized all channel operation */
        unsigned        sharing_irq: 1; /* 1 = sharing irq with another hwif */
        unsigned        reset      : 1; /* reset after probe */
-       unsigned        no_lba48   : 1; /* 1 = cannot do LBA48 */
-       unsigned        no_lba48_dma : 1; /* 1 = cannot do LBA48 DMA */
        unsigned        auto_poll  : 1; /* supports nop auto-poll */
        unsigned        sg_mapped  : 1; /* sg_table and sg_nents are ready */
        unsigned        no_io_32bit : 1; /* 1 = can not do 32-bit IO ops */
-       unsigned        err_stops_fifo : 1; /* 1=data FIFO is cleared by an error */
        unsigned        mmio       : 1; /* host uses MMIO */
 
        struct device   gendev;
@@ -845,8 +831,6 @@ typedef struct hwgroup_s {
 
                /* for pci chipsets */
        struct pci_dev *pci_dev;
-               /* chipset device struct */
-       struct ide_pci_device_s *cds;
 
                /* current request */
        struct request *rq;
@@ -1034,36 +1018,16 @@ extern int ide_end_request (ide_drive_t *drive, int uptodate, int nrsecs);
 int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq,
                             int uptodate, int nr_sectors);
 
-/*
- * This is used on exit from the driver to designate the next irq handler
- * and also to start the safety timer.
- */
 extern void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry);
 
-/*
- * This is used on exit from the driver to designate the next irq handler
- * and start the safety time safely and atomically from the IRQ handler
- * with respect to the command issue (which it also does)
- */
 extern void ide_execute_command(ide_drive_t *, task_ioreg_t cmd, ide_handler_t *, unsigned int, ide_expiry_t *);
 
 ide_startstop_t __ide_error(ide_drive_t *, struct request *, u8, u8);
 
-/*
- * ide_error() takes action based on the error returned by the controller.
- * The caller should return immediately after invoking this.
- *
- * (drive, msg, status)
- */
 ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, byte stat);
 
 ide_startstop_t __ide_abort(ide_drive_t *, struct request *);
 
-/*
- * Abort a running command on the controller triggering the abort
- * from a host side, non error situation
- * (drive, msg)
- */
 extern ide_startstop_t ide_abort(ide_drive_t *, const char *);
 
 extern void ide_fix_driveid(struct hd_driveid *);
@@ -1079,15 +1043,8 @@ extern void ide_fixstring(u8 *, const int, const int);
 
 int ide_wait_stat(ide_startstop_t *, ide_drive_t *, u8, u8, unsigned long);
 
-/*
- * Start a reset operation for an IDE interface.
- * The caller should return immediately after invoking this.
- */
 extern ide_startstop_t ide_do_reset (ide_drive_t *);
 
-/*
- * This function is intended to be used prior to invoking ide_do_drive_cmd().
- */
 extern void ide_init_drive_cmd (struct request *rq);
 
 /*
@@ -1102,13 +1059,6 @@ typedef enum {
 
 extern int ide_do_drive_cmd(ide_drive_t *, struct request *, ide_action_t);
 
-/*
- * Clean up after success/failure of an explicit drive cmd.
- * stat/err are used only when (HWGROUP(drive)->rq->cmd == IDE_DRIVE_CMD).
- * stat/err are used only when (HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASK_MASK).
- *
- * (ide_drive_t *drive, u8 stat, u8 err)
- */
 extern void ide_end_drive_cmd(ide_drive_t *, u8, u8);
 
 /*
@@ -1181,10 +1131,6 @@ extern int taskfile_lib_get_identify(ide_drive_t *drive, u8 *);
 
 extern int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout);
 
-/*
- * ide_stall_queue() can be used by a drive to give excess bandwidth back
- * to the hwgroup by sleeping for timeout jiffies.
- */
 extern void ide_stall_queue(ide_drive_t *drive, unsigned long timeout);
 
 extern int ide_spin_wait_hwgroup(ide_drive_t *);
@@ -1204,26 +1150,13 @@ extern int __ide_pci_register_driver(struct pci_driver *driver, struct module *o
 #define ide_pci_register_driver(d) pci_register_driver(d)
 #endif
 
-void ide_pci_setup_ports(struct pci_dev *, struct ide_pci_device_s *, int, ata_index_t *);
-extern void ide_setup_pci_noise (struct pci_dev *dev, struct ide_pci_device_s *d);
+void ide_pci_setup_ports(struct pci_dev *, const struct ide_port_info *, int, u8 *);
+void ide_setup_pci_noise(struct pci_dev *, const struct ide_port_info *);
 
 extern void default_hwif_iops(ide_hwif_t *);
 extern void default_hwif_mmiops(ide_hwif_t *);
 extern void default_hwif_transport(ide_hwif_t *);
 
-#define ON_BOARD               1
-#define NEVER_BOARD            0
-
-#ifdef CONFIG_BLK_DEV_OFFBOARD
-#  define OFF_BOARD            ON_BOARD
-#else /* CONFIG_BLK_DEV_OFFBOARD */
-#  define OFF_BOARD            NEVER_BOARD
-#endif /* CONFIG_BLK_DEV_OFFBOARD */
-
-#define NODMA 0
-#define NOAUTODMA 1
-#define AUTODMA 2
-
 typedef struct ide_pci_enablebit_s {
        u8      reg;    /* byte pci reg holding the enable-bit */
        u8      mask;   /* mask to isolate the enable-bit */
@@ -1258,29 +1191,61 @@ enum {
        IDE_HFLAG_TRUST_BIOS_FOR_DMA    = (1 << 10),
        /* host uses VDMA */
        IDE_HFLAG_VDMA                  = (1 << 11),
+       /* ATAPI DMA is unsupported */
+       IDE_HFLAG_NO_ATAPI_DMA          = (1 << 12),
+       /* set if host is a "bootable" controller */
+       IDE_HFLAG_BOOTABLE              = (1 << 13),
+       /* host doesn't support DMA */
+       IDE_HFLAG_NO_DMA                = (1 << 14),
+       /* check if host is PCI IDE device before allowing DMA */
+       IDE_HFLAG_NO_AUTODMA            = (1 << 15),
+       /* host is CS5510/CS5520 */
+       IDE_HFLAG_CS5520                = (1 << 16),
+       /* no LBA48 */
+       IDE_HFLAG_NO_LBA48              = (1 << 17),
+       /* no LBA48 DMA */
+       IDE_HFLAG_NO_LBA48_DMA          = (1 << 18),
+       /* data FIFO is cleared by an error */
+       IDE_HFLAG_ERROR_STOPS_FIFO      = (1 << 19),
+       /* serialize ports */
+       IDE_HFLAG_SERIALIZE             = (1 << 20),
+       /* use legacy IRQs */
+       IDE_HFLAG_LEGACY_IRQS           = (1 << 21),
+       /* force use of legacy IRQs */
+       IDE_HFLAG_FORCE_LEGACY_IRQS     = (1 << 22),
+       /* limit LBA48 requests to 256 sectors */
+       IDE_HFLAG_RQSIZE_256            = (1 << 23),
+       /* use 32-bit I/O ops */
+       IDE_HFLAG_IO_32BIT              = (1 << 24),
+       /* unmask IRQs */
+       IDE_HFLAG_UNMASK_IRQS           = (1 << 25),
 };
 
-typedef struct ide_pci_device_s {
+#ifdef CONFIG_BLK_DEV_OFFBOARD
+# define IDE_HFLAG_OFF_BOARD   IDE_HFLAG_BOOTABLE
+#else
+# define IDE_HFLAG_OFF_BOARD   0
+#endif
+
+struct ide_port_info {
        char                    *name;
-       int                     (*init_setup)(struct pci_dev *, struct ide_pci_device_s *);
-       void                    (*init_setup_dma)(struct pci_dev *, struct ide_pci_device_s *, ide_hwif_t *);
        unsigned int            (*init_chipset)(struct pci_dev *, const char *);
        void                    (*init_iops)(ide_hwif_t *);
        void                    (*init_hwif)(ide_hwif_t *);
        void                    (*init_dma)(ide_hwif_t *, unsigned long);
        void                    (*fixup)(ide_hwif_t *);
-       u8                      autodma;
        ide_pci_enablebit_t     enablebits[2];
-       u8                      bootable;
+       hwif_chipset_t          chipset;
        unsigned int            extra;
-       struct ide_pci_device_s *next;
-       u16                     host_flags;
+       u32                     host_flags;
        u8                      pio_mask;
+       u8                      swdma_mask;
+       u8                      mwdma_mask;
        u8                      udma_mask;
-} ide_pci_device_t;
+};
 
-extern int ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
-extern int ide_setup_pci_devices(struct pci_dev *, struct pci_dev *, ide_pci_device_t *);
+int ide_setup_pci_device(struct pci_dev *, const struct ide_port_info *);
+int ide_setup_pci_devices(struct pci_dev *, struct pci_dev *, const struct ide_port_info *);
 
 void ide_map_sg(ide_drive_t *, struct request *);
 void ide_init_sg_cmd(ide_drive_t *, struct request *);
@@ -1363,8 +1328,7 @@ void ide_unregister_region(struct gendisk *);
 
 void ide_undecoded_slave(ide_hwif_t *);
 
-int probe_hwif_init_with_fixup(ide_hwif_t *, void (*)(ide_hwif_t *));
-extern int probe_hwif_init(ide_hwif_t *);
+int ide_device_add(u8 idx[4]);
 
 static inline void *ide_get_hwifdata (ide_hwif_t * hwif)
 {
@@ -1454,4 +1418,11 @@ static inline int hwif_to_node(ide_hwif_t *hwif)
        return dev ? pcibus_to_node(dev->bus) : -1;
 }
 
+static inline ide_drive_t *ide_get_paired_drive(ide_drive_t *drive)
+{
+       ide_hwif_t *hwif        = HWIF(drive);
+
+       return &hwif->drives[(drive->dn ^ 1) & 1];
+}
+
 #endif /* _IDE_H */
index d4b2f1c76e12c528b8701111445bd864ef5ea062..cae35b6b9aecf9a849085a3c67a56da6c57d69cb 100644 (file)
@@ -67,9 +67,6 @@
        .posix_timers    = LIST_HEAD_INIT(sig.posix_timers),            \
        .cpu_timers     = INIT_CPU_TIMERS(sig.cpu_timers),              \
        .rlim           = INIT_RLIMITS,                                 \
-       .pgrp           = 0,                                            \
-       .tty_old_pgrp   = NULL,                                         \
-       { .__session      = 0},                                         \
 }
 
 extern struct nsproxy init_nsproxy;
@@ -94,15 +91,18 @@ extern struct group_info init_groups;
 
 #define INIT_STRUCT_PID {                                              \
        .count          = ATOMIC_INIT(1),                               \
-       .nr             = 0,                                            \
-       /* Don't put this struct pid in pid_hash */                     \
-       .pid_chain      = { .next = NULL, .pprev = NULL },              \
        .tasks          = {                                             \
                { .first = &init_task.pids[PIDTYPE_PID].node },         \
                { .first = &init_task.pids[PIDTYPE_PGID].node },        \
                { .first = &init_task.pids[PIDTYPE_SID].node },         \
        },                                                              \
        .rcu            = RCU_HEAD_INIT,                                \
+       .level          = 0,                                            \
+       .numbers        = { {                                           \
+               .nr             = 0,                                    \
+               .ns             = &init_pid_ns,                         \
+               .pid_chain      = { .next = NULL, .pprev = NULL },      \
+       }, }                                                            \
 }
 
 #define INIT_PID_LINK(type)                                    \
index d4f48c6402e6ffd615b81a50a65ea7c41b47dcaf..742b917e7d1b274e5582ec30d387b4d881fe5915 100644 (file)
@@ -120,6 +120,8 @@ extern __s32 inotify_find_update_watch(struct inotify_handle *, struct inode *,
                                       u32);
 extern __s32 inotify_add_watch(struct inotify_handle *, struct inotify_watch *,
                               struct inode *, __u32);
+extern __s32 inotify_clone_watch(struct inotify_watch *, struct inotify_watch *);
+extern void inotify_evict_watch(struct inotify_watch *);
 extern int inotify_rm_watch(struct inotify_handle *, struct inotify_watch *);
 extern int inotify_rm_wd(struct inotify_handle *, __u32);
 extern void inotify_remove_watch_locked(struct inotify_handle *,
index f30da6fc08e3775dfa5b0945004711baae879a47..62268929856c9d26c8a9be4b134e4d7704796aac 100644 (file)
@@ -98,6 +98,7 @@ struct input_absinfo {
 #define EV_PWR                 0x16
 #define EV_FF_STATUS           0x17
 #define EV_MAX                 0x1f
+#define EV_CNT                 (EV_MAX+1)
 
 /*
  * Synchronization events.
@@ -567,6 +568,7 @@ struct input_absinfo {
 /* We avoid low common keys in module aliases so they don't get huge. */
 #define KEY_MIN_INTERESTING    KEY_MUTE
 #define KEY_MAX                        0x1ff
+#define KEY_CNT                        (KEY_MAX+1)
 
 /*
  * Relative axes
@@ -583,6 +585,7 @@ struct input_absinfo {
 #define REL_WHEEL              0x08
 #define REL_MISC               0x09
 #define REL_MAX                        0x0f
+#define REL_CNT                        (REL_MAX+1)
 
 /*
  * Absolute axes
@@ -615,6 +618,7 @@ struct input_absinfo {
 #define ABS_VOLUME             0x20
 #define ABS_MISC               0x28
 #define ABS_MAX                        0x3f
+#define ABS_CNT                        (ABS_MAX+1)
 
 /*
  * Switch events
@@ -625,6 +629,7 @@ struct input_absinfo {
 #define SW_HEADPHONE_INSERT    0x02  /* set = inserted */
 #define SW_RADIO               0x03  /* set = radio enabled */
 #define SW_MAX                 0x0f
+#define SW_CNT                 (SW_MAX+1)
 
 /*
  * Misc events
@@ -636,6 +641,7 @@ struct input_absinfo {
 #define MSC_RAW                        0x03
 #define MSC_SCAN               0x04
 #define MSC_MAX                        0x07
+#define MSC_CNT                        (MSC_MAX+1)
 
 /*
  * LEDs
@@ -653,6 +659,7 @@ struct input_absinfo {
 #define LED_MAIL               0x09
 #define LED_CHARGING           0x0a
 #define LED_MAX                        0x0f
+#define LED_CNT                        (LED_MAX+1)
 
 /*
  * Autorepeat values
@@ -670,6 +677,7 @@ struct input_absinfo {
 #define SND_BELL               0x01
 #define SND_TONE               0x02
 #define SND_MAX                        0x07
+#define SND_CNT                        (SND_MAX+1)
 
 /*
  * IDs.
@@ -920,6 +928,7 @@ struct ff_effect {
 #define FF_AUTOCENTER  0x61
 
 #define FF_MAX         0x7f
+#define FF_CNT         (FF_MAX+1)
 
 #ifdef __KERNEL__
 
@@ -932,10 +941,6 @@ struct ff_effect {
 #include <linux/timer.h>
 #include <linux/mod_devicetable.h>
 
-#define NBITS(x) (((x)/BITS_PER_LONG)+1)
-#define BIT(x) (1UL<<((x)%BITS_PER_LONG))
-#define LONG(x) ((x)/BITS_PER_LONG)
-
 /**
  * struct input_dev - represents an input device
  * @name: name of the device
@@ -1005,28 +1010,30 @@ struct ff_effect {
  * @going_away: marks devices that are in a middle of unregistering and
  *     causes input_open_device*() fail with -ENODEV.
  * @dev: driver model's view of this device
+ * @cdev: union for struct device pointer
  * @h_list: list of input handles associated with the device. When
  *     accessing the list dev->mutex must be held
  * @node: used to place the device onto input_dev_list
  */
 struct input_dev {
-
+       /* private: */
        void *private;  /* do not use */
+       /* public: */
 
        const char *name;
        const char *phys;
        const char *uniq;
        struct input_id id;
 
-       unsigned long evbit[NBITS(EV_MAX)];
-       unsigned long keybit[NBITS(KEY_MAX)];
-       unsigned long relbit[NBITS(REL_MAX)];
-       unsigned long absbit[NBITS(ABS_MAX)];
-       unsigned long mscbit[NBITS(MSC_MAX)];
-       unsigned long ledbit[NBITS(LED_MAX)];
-       unsigned long sndbit[NBITS(SND_MAX)];
-       unsigned long ffbit[NBITS(FF_MAX)];
-       unsigned long swbit[NBITS(SW_MAX)];
+       unsigned long evbit[BITS_TO_LONGS(EV_CNT)];
+       unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];
+       unsigned long relbit[BITS_TO_LONGS(REL_CNT)];
+       unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];
+       unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];
+       unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];
+       unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];
+       unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];
+       unsigned long swbit[BITS_TO_LONGS(SW_CNT)];
 
        unsigned int keycodemax;
        unsigned int keycodesize;
@@ -1044,10 +1051,10 @@ struct input_dev {
        int abs[ABS_MAX + 1];
        int rep[REP_MAX + 1];
 
-       unsigned long key[NBITS(KEY_MAX)];
-       unsigned long led[NBITS(LED_MAX)];
-       unsigned long snd[NBITS(SND_MAX)];
-       unsigned long sw[NBITS(SW_MAX)];
+       unsigned long key[BITS_TO_LONGS(KEY_CNT)];
+       unsigned long led[BITS_TO_LONGS(LED_CNT)];
+       unsigned long snd[BITS_TO_LONGS(SND_CNT)];
+       unsigned long sw[BITS_TO_LONGS(SW_CNT)];
 
        int absmax[ABS_MAX + 1];
        int absmin[ABS_MAX + 1];
@@ -1291,7 +1298,7 @@ static inline void input_set_abs_params(struct input_dev *dev, int axis, int min
        dev->absfuzz[axis] = fuzz;
        dev->absflat[axis] = flat;
 
-       dev->absbit[LONG(axis)] |= BIT(axis);
+       dev->absbit[BIT_WORD(axis)] |= BIT_MASK(axis);
 }
 
 extern struct class input_class;
@@ -1332,7 +1339,7 @@ struct ff_device {
 
        void *private;
 
-       unsigned long ffbit[NBITS(FF_MAX)];
+       unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];
 
        struct mutex mutex;
 
index ee111834091cf99752fc3679281ef9c86adbbf45..408696ea51892f0deaf7a866f7e5ec99619c5770 100644 (file)
@@ -89,6 +89,7 @@ struct kern_ipc_perm
 {
        spinlock_t      lock;
        int             deleted;
+       int             id;
        key_t           key;
        uid_t           uid;
        gid_t           gid;
@@ -110,6 +111,8 @@ struct ipc_namespace {
        int             msg_ctlmax;
        int             msg_ctlmnb;
        int             msg_ctlmni;
+       atomic_t        msg_bytes;
+       atomic_t        msg_hdrs;
 
        size_t          shm_ctlmax;
        size_t          shm_ctlall;
index 7a9db390c56a491e3221ed8154ac76ed89295c8f..c5bd28b69aec469087da75e93e28e7c789a4ca3f 100644 (file)
@@ -364,6 +364,16 @@ int ipmi_request_supply_msgs(ipmi_user_t          user,
                             struct ipmi_recv_msg *supplied_recv,
                             int                  priority);
 
+/*
+ * Poll the IPMI interface for the user.  This causes the IPMI code to
+ * do an immediate check for information from the driver and handle
+ * anything that is immediately pending.  This will not block in any
+ * way.  This is useful if you need to implement polling from the user
+ * for things like modifying the watchdog timeout when a panic occurs
+ * or disabling the watchdog timer on a reboot.
+ */
+void ipmi_poll_interface(ipmi_user_t user);
+
 /*
  * When commands come in to the SMS, the user can register to receive
  * them.  Only one user can be listening on a specific netfn/cmd/chan tuple
index c0633108d05dc3c4f5addcee52b5d44a66d86af4..56ae438ae5105033b55a9576cb77d3f291cd9f40 100644 (file)
@@ -118,7 +118,7 @@ struct ipmi_smi_handlers
        /* Enable/disable firmware maintenance mode.  Note that this
           is *not* the modes defined, this is simply an on/off
           setting.  The message handler does the mode handling.  Note
-          that this is called from interupt context, so it cannot
+          that this is called from interrupt context, so it cannot
           block. */
        void (*set_maintenance_mode)(void *send_info, int enable);
 
@@ -148,26 +148,46 @@ struct ipmi_device_id {
 
 /* Take a pointer to a raw data buffer and a length and extract device
    id information from it.  The first byte of data must point to the
-   byte from the get device id response after the completion code.
-   The caller is responsible for making sure the length is at least
-   11 and the command completed without error. */
-static inline void ipmi_demangle_device_id(unsigned char *data,
-                                          unsigned int  data_len,
-                                          struct ipmi_device_id *id)
+   netfn << 2, the data should be of the format:
+      netfn << 2, cmd, completion code, data
+   as normally comes from a device interface. */
+static inline int ipmi_demangle_device_id(const unsigned char *data,
+                                         unsigned int data_len,
+                                         struct ipmi_device_id *id)
 {
+       if (data_len < 9)
+               return -EINVAL;
+       if (data[0] != IPMI_NETFN_APP_RESPONSE << 2 ||
+           data[1] != IPMI_GET_DEVICE_ID_CMD)
+               /* Strange, didn't get the response we expected. */
+               return -EINVAL;
+       if (data[2] != 0)
+               /* That's odd, it shouldn't be able to fail. */
+               return -EINVAL;
+
+       data += 3;
+       data_len -= 3;
        id->device_id = data[0];
        id->device_revision = data[1];
        id->firmware_revision_1 = data[2];
        id->firmware_revision_2 = data[3];
        id->ipmi_version = data[4];
        id->additional_device_support = data[5];
-       id->manufacturer_id = data[6] | (data[7] << 8) | (data[8] << 16);
-       id->product_id = data[9] | (data[10] << 8);
+       if (data_len >= 6) {
+               id->manufacturer_id = (data[6] | (data[7] << 8) |
+                                      (data[8] << 16));
+               id->product_id = data[9] | (data[10] << 8);
+       } else {
+               id->manufacturer_id = 0;
+               id->product_id = 0;
+       }
        if (data_len >= 15) {
                memcpy(id->aux_firmware_revision, data+11, 4);
                id->aux_firmware_revision_set = 1;
        } else
                id->aux_firmware_revision_set = 0;
+
+       return 0;
 }
 
 /* Add a low-level interface to the IPMI driver.  Note that if the
index 72f522372924b302501e3c99b5c7d35bb3d7d5f5..16e7ed855a18d9a1bc7fafd58d70f01e0753ae19 100644 (file)
@@ -58,7 +58,7 @@
  * CONFIG_JBD_DEBUG is on.
  */
 #define JBD_EXPENSIVE_CHECKING
-extern int journal_enable_debug;
+extern u8 journal_enable_debug;
 
 #define jbd_debug(n, f, a...)                                          \
        do {                                                            \
@@ -72,14 +72,15 @@ extern int journal_enable_debug;
 #define jbd_debug(f, a...)     /**/
 #endif
 
-extern void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry);
-extern void * jbd_slab_alloc(size_t size, gfp_t flags);
-extern void jbd_slab_free(void *ptr, size_t size);
+static inline void *jbd_alloc(size_t size, gfp_t flags)
+{
+       return (void *)__get_free_pages(flags, get_order(size));
+}
 
-#define jbd_kmalloc(size, flags) \
-       __jbd_kmalloc(__FUNCTION__, (size), (flags), journal_oom_retry)
-#define jbd_rep_kmalloc(size, flags) \
-       __jbd_kmalloc(__FUNCTION__, (size), (flags), 1)
+static inline void jbd_free(void *ptr, size_t size)
+{
+       free_pages((unsigned long)ptr, get_order(size));
+};
 
 #define JFS_MIN_JOURNAL_BLOCKS 1024
 
@@ -247,17 +248,7 @@ typedef struct journal_superblock_s
 #include <linux/fs.h>
 #include <linux/sched.h>
 
-#define JBD_ASSERTIONS
-#ifdef JBD_ASSERTIONS
-#define J_ASSERT(assert)                                               \
-do {                                                                   \
-       if (!(assert)) {                                                \
-               printk (KERN_EMERG                                      \
-                       "Assertion failure in %s() at %s:%d: \"%s\"\n", \
-                       __FUNCTION__, __FILE__, __LINE__, # assert);    \
-               BUG();                                                  \
-       }                                                               \
-} while (0)
+#define J_ASSERT(assert)       BUG_ON(!(assert))
 
 #if defined(CONFIG_BUFFER_DEBUG)
 void buffer_assertion_failure(struct buffer_head *bh);
@@ -273,10 +264,6 @@ void buffer_assertion_failure(struct buffer_head *bh);
 #define J_ASSERT_JH(jh, expr)  J_ASSERT(expr)
 #endif
 
-#else
-#define J_ASSERT(assert)       do { } while (0)
-#endif         /* JBD_ASSERTIONS */
-
 #if defined(JBD_PARANOID_IOFAIL)
 #define J_EXPECT(expr, why...)         J_ASSERT(expr)
 #define J_EXPECT_BH(bh, expr, why...)  J_ASSERT_BH(bh, expr)
index 260d6d76c5f3b898cfafad1cbc67ca7e8015bba1..06ef114570518e338ead34f6fce5c00b0420fc7b 100644 (file)
@@ -13,8 +13,8 @@
  * filesystem journaling support.
  */
 
-#ifndef _LINUX_JBD_H
-#define _LINUX_JBD_H
+#ifndef _LINUX_JBD2_H
+#define _LINUX_JBD2_H
 
 /* Allow this file to be included directly into e2fsprogs */
 #ifndef __KERNEL__
 #define journal_oom_retry 1
 
 /*
- * Define JBD_PARANIOD_IOFAIL to cause a kernel BUG() if ext3 finds
+ * Define JBD2_PARANIOD_IOFAIL to cause a kernel BUG() if ext4 finds
  * certain classes of error which can occur due to failed IOs.  Under
- * normal use we want ext3 to continue after such errors, because
+ * normal use we want ext4 to continue after such errors, because
  * hardware _can_ fail, but for debugging purposes when running tests on
  * known-good hardware we may want to trap these errors.
  */
-#undef JBD_PARANOID_IOFAIL
+#undef JBD2_PARANOID_IOFAIL
 
 /*
  * The default maximum commit age, in seconds.
  */
-#define JBD_DEFAULT_MAX_COMMIT_AGE 5
+#define JBD2_DEFAULT_MAX_COMMIT_AGE 5
 
 #ifdef CONFIG_JBD2_DEBUG
 /*
- * Define JBD_EXPENSIVE_CHECKING to enable more expensive internal
+ * Define JBD2_EXPENSIVE_CHECKING to enable more expensive internal
  * consistency checks.  By default we don't do this unless
  * CONFIG_JBD2_DEBUG is on.
  */
-#define JBD_EXPENSIVE_CHECKING
+#define JBD2_EXPENSIVE_CHECKING
 extern u8 jbd2_journal_enable_debug;
 
 #define jbd_debug(n, f, a...)                                          \
@@ -71,14 +71,15 @@ extern u8 jbd2_journal_enable_debug;
 #define jbd_debug(f, a...)     /**/
 #endif
 
-extern void * __jbd2_kmalloc (const char *where, size_t size, gfp_t flags, int retry);
-extern void * jbd2_slab_alloc(size_t size, gfp_t flags);
-extern void jbd2_slab_free(void *ptr, size_t size);
+static inline void *jbd2_alloc(size_t size, gfp_t flags)
+{
+       return (void *)__get_free_pages(flags, get_order(size));
+}
 
-#define jbd_kmalloc(size, flags) \
-       __jbd2_kmalloc(__FUNCTION__, (size), (flags), journal_oom_retry)
-#define jbd_rep_kmalloc(size, flags) \
-       __jbd2_kmalloc(__FUNCTION__, (size), (flags), 1)
+static inline void jbd2_free(void *ptr, size_t size)
+{
+       free_pages((unsigned long)ptr, get_order(size));
+};
 
 #define JBD2_MIN_JOURNAL_BLOCKS 1024
 
@@ -162,8 +163,8 @@ typedef struct journal_block_tag_s
        __be32          t_blocknr_high; /* most-significant high 32bits. */
 } journal_block_tag_t;
 
-#define JBD_TAG_SIZE32 (offsetof(journal_block_tag_t, t_blocknr_high))
-#define JBD_TAG_SIZE64 (sizeof(journal_block_tag_t))
+#define JBD2_TAG_SIZE32 (offsetof(journal_block_tag_t, t_blocknr_high))
+#define JBD2_TAG_SIZE64 (sizeof(journal_block_tag_t))
 
 /*
  * The revoke descriptor: used on disk to describe a series of blocks to
@@ -255,8 +256,8 @@ typedef struct journal_superblock_s
 #include <linux/fs.h>
 #include <linux/sched.h>
 
-#define JBD_ASSERTIONS
-#ifdef JBD_ASSERTIONS
+#define JBD2_ASSERTIONS
+#ifdef JBD2_ASSERTIONS
 #define J_ASSERT(assert)                                               \
 do {                                                                   \
        if (!(assert)) {                                                \
@@ -283,9 +284,9 @@ void buffer_assertion_failure(struct buffer_head *bh);
 
 #else
 #define J_ASSERT(assert)       do { } while (0)
-#endif         /* JBD_ASSERTIONS */
+#endif         /* JBD2_ASSERTIONS */
 
-#if defined(JBD_PARANOID_IOFAIL)
+#if defined(JBD2_PARANOID_IOFAIL)
 #define J_EXPECT(expr, why...)         J_ASSERT(expr)
 #define J_EXPECT_BH(bh, expr, why...)  J_ASSERT_BH(bh, expr)
 #define J_EXPECT_JH(jh, expr, why...)  J_ASSERT_JH(jh, expr)
@@ -959,12 +960,12 @@ void jbd2_journal_put_journal_head(struct journal_head *jh);
  */
 extern struct kmem_cache *jbd2_handle_cache;
 
-static inline handle_t *jbd_alloc_handle(gfp_t gfp_flags)
+static inline handle_t *jbd2_alloc_handle(gfp_t gfp_flags)
 {
        return kmem_cache_alloc(jbd2_handle_cache, gfp_flags);
 }
 
-static inline void jbd_free_handle(handle_t *handle)
+static inline void jbd2_free_handle(handle_t *handle)
 {
        kmem_cache_free(jbd2_handle_cache, handle);
 }
@@ -1103,4 +1104,4 @@ extern int jbd_blocks_per_page(struct inode *inode);
 
 #endif /* __KERNEL__ */
 
-#endif /* _LINUX_JBD_H */
+#endif /* _LINUX_JBD2_H */
index 12bf44f083f53355ca785a663bd76422dafcdfc1..e8ffce898bf913c7c12943b0a40785354dde6834 100644 (file)
@@ -53,7 +53,9 @@ static inline int kstat_irqs(int irq)
 }
 
 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);
+extern void account_system_time_scaled(struct task_struct *, cputime_t);
 extern void account_steal_time(struct task_struct *, cputime_t);
 
 #endif /* _LINUX_KERNEL_STAT_H */
index ad4b82ce84af13ffac6e2f3b381242f4bdde43d8..2d9c448d8c52f4c21f61e36890e1219dc074e591 100644 (file)
@@ -187,6 +187,8 @@ extern u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE/4];
 extern size_t vmcoreinfo_size;
 extern size_t vmcoreinfo_max_size;
 
+int __init parse_crashkernel(char *cmdline, unsigned long long system_ram,
+               unsigned long long *crash_size, unsigned long long *crash_base);
 
 #else /* !CONFIG_KEXEC */
 struct pt_regs;
index 33b5c2e325b92b3d14800ad83b8e1c2406103654..65c2d70853e96557dc13c3f8e0a2e1420b4ccbf0 100644 (file)
 #define MAX_NR_OF_USER_KEYMAPS 256     /* should be at least 7 */
 
 #ifdef __KERNEL__
+struct notifier_block;
 extern const int NR_TYPES;
 extern const int max_vals[];
 extern unsigned short *key_maps[MAX_NR_KEYMAPS];
 extern unsigned short plain_map[NR_KEYS];
+
+struct keyboard_notifier_param {
+       struct vc_data *vc;     /* VC on which the keyboard press was done */
+       int down;               /* Pressure of the key? */
+       int shift;              /* Current shift mask */
+       unsigned int value;     /* keycode, unicode value or keysym */
+};
+
+extern int register_keyboard_notifier(struct notifier_block *nb);
+extern int unregister_keyboard_notifier(struct notifier_block *nb);
 #endif
 
 #define MAX_NR_FUNC    256     /* max nr of strings assigned to keys */
index 157ad64aa7ce8e020759db4498a7288d31345662..8beb2913462682c8850dac18aa6dab11f2184b42 100644 (file)
@@ -1,76 +1,16 @@
 /* Things the lguest guest needs to know.  Note: like all lguest interfaces,
  * this is subject to wild and random change between versions. */
-#ifndef _ASM_LGUEST_H
-#define _ASM_LGUEST_H
+#ifndef _LINUX_LGUEST_H
+#define _LINUX_LGUEST_H
 
 #ifndef __ASSEMBLY__
+#include <linux/time.h>
 #include <asm/irq.h>
-
-#define LHCALL_FLUSH_ASYNC     0
-#define LHCALL_LGUEST_INIT     1
-#define LHCALL_CRASH           2
-#define LHCALL_LOAD_GDT                3
-#define LHCALL_NEW_PGTABLE     4
-#define LHCALL_FLUSH_TLB       5
-#define LHCALL_LOAD_IDT_ENTRY  6
-#define LHCALL_SET_STACK       7
-#define LHCALL_TS              8
-#define LHCALL_SET_CLOCKEVENT  9
-#define LHCALL_HALT            10
-#define LHCALL_BIND_DMA                12
-#define LHCALL_SEND_DMA                13
-#define LHCALL_SET_PTE         14
-#define LHCALL_SET_PMD         15
-#define LHCALL_LOAD_TLS                16
+#include <asm/lguest_hcall.h>
 
 #define LG_CLOCK_MIN_DELTA     100UL
 #define LG_CLOCK_MAX_DELTA     ULONG_MAX
 
-/*G:031 First, how does our Guest contact the Host to ask for privileged
- * operations?  There are two ways: the direct way is to make a "hypercall",
- * to make requests of the Host Itself.
- *
- * Our hypercall mechanism uses the highest unused trap code (traps 32 and
- * above are used by real hardware interrupts).  Seventeen hypercalls are
- * available: the hypercall number is put in the %eax register, and the
- * arguments (when required) are placed in %edx, %ebx and %ecx.  If a return
- * value makes sense, it's returned in %eax.
- *
- * Grossly invalid calls result in Sudden Death at the hands of the vengeful
- * Host, rather than returning failure.  This reflects Winston Churchill's
- * definition of a gentleman: "someone who is only rude intentionally". */
-#define LGUEST_TRAP_ENTRY 0x1F
-
-static inline unsigned long
-hcall(unsigned long call,
-      unsigned long arg1, unsigned long arg2, unsigned long arg3)
-{
-       /* "int" is the Intel instruction to trigger a trap. */
-       asm volatile("int $" __stringify(LGUEST_TRAP_ENTRY)
-                      /* The call is in %eax (aka "a"), and can be replaced */
-                    : "=a"(call)
-                      /* The other arguments are in %eax, %edx, %ebx & %ecx */
-                    : "a"(call), "d"(arg1), "b"(arg2), "c"(arg3)
-                      /* "memory" means this might write somewhere in memory.
-                       * This isn't true for all calls, but it's safe to tell
-                       * gcc that it might happen so it doesn't get clever. */
-                    : "memory");
-       return call;
-}
-/*:*/
-
-void async_hcall(unsigned long call,
-                unsigned long arg1, unsigned long arg2, unsigned long arg3);
-
-/* Can't use our min() macro here: needs to be a constant */
-#define LGUEST_IRQS (NR_IRQS < 32 ? NR_IRQS: 32)
-
-#define LHCALL_RING_SIZE 64
-struct hcall_ring
-{
-       u32 eax, edx, ebx, ecx;
-};
-
 /*G:032 The second method of communicating with the Host is to via "struct
  * lguest_data".  The Guest's very first hypercall is to tell the Host where
  * this is, and then the Guest and Host both publish information in it. :*/
@@ -97,20 +37,24 @@ struct lguest_data
        /* 0xFF == done (set by Host), 0 == pending (set by Guest). */
        u8 hcall_status[LHCALL_RING_SIZE];
        /* The actual registers for the hypercalls. */
-       struct hcall_ring hcalls[LHCALL_RING_SIZE];
+       struct hcall_args hcalls[LHCALL_RING_SIZE];
 
 /* Fields initialized by the Host at boot: */
        /* Memory not to try to access */
        unsigned long reserve_mem;
-       /* ID of this Guest (used by network driver to set ethernet address) */
-       u16 guestid;
        /* KHz for the TSC clock. */
        u32 tsc_khz;
+       /* Page where the top-level pagetable is */
+       unsigned long pgdir;
 
 /* Fields initialized by the Guest at boot: */
        /* Instruction range to suppress interrupts even if enabled */
        unsigned long noirq_start, noirq_end;
+       /* Address above which page tables are all identical. */
+       unsigned long kernel_address;
+       /* The vector to try to use for system calls (0x40 or 0x80). */
+       unsigned int syscall_vec;
 };
 extern struct lguest_data lguest_data;
 #endif /* __ASSEMBLY__ */
-#endif /* _ASM_LGUEST_H */
+#endif /* _LINUX_LGUEST_H */
diff --git a/include/linux/lguest_bus.h b/include/linux/lguest_bus.h
deleted file mode 100644 (file)
index d27853d..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef _ASM_LGUEST_DEVICE_H
-#define _ASM_LGUEST_DEVICE_H
-/* Everything you need to know about lguest devices. */
-#include <linux/device.h>
-#include <linux/lguest.h>
-#include <linux/lguest_launcher.h>
-
-struct lguest_device {
-       /* Unique busid, and index into lguest_page->devices[] */
-       unsigned int index;
-
-       struct device dev;
-
-       /* Driver can hang data off here. */
-       void *private;
-};
-
-/*D:380 Since interrupt numbers are arbitrary, we use a convention: each device
- * can use the interrupt number corresponding to its index.  The +1 is because
- * interrupt 0 is not usable (it's actually the timer interrupt). */
-static inline int lgdev_irq(const struct lguest_device *dev)
-{
-       return dev->index + 1;
-}
-/*:*/
-
-/* dma args must not be vmalloced! */
-void lguest_send_dma(unsigned long key, struct lguest_dma *dma);
-int lguest_bind_dma(unsigned long key, struct lguest_dma *dmas,
-                   unsigned int num, u8 irq);
-void lguest_unbind_dma(unsigned long key, struct lguest_dma *dmas);
-
-/* Map the virtual device space */
-void *lguest_map(unsigned long phys_addr, unsigned long pages);
-void lguest_unmap(void *);
-
-struct lguest_driver {
-       const char *name;
-       struct module *owner;
-       u16 device_type;
-       int (*probe)(struct lguest_device *dev);
-       void (*remove)(struct lguest_device *dev);
-
-       struct device_driver drv;
-};
-
-extern int register_lguest_driver(struct lguest_driver *drv);
-extern void unregister_lguest_driver(struct lguest_driver *drv);
-
-extern struct lguest_device_desc *lguest_devices; /* Just past max_pfn */
-#endif /* _ASM_LGUEST_DEVICE_H */
index 6416705794466bea3c1a4e2091ca03e79d980bfa..61e1e3e6b1ccb534cbfeeffe62f3d50d79b7459a 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef _ASM_LGUEST_USER
 #define _ASM_LGUEST_USER
 /* Everything the "lguest" userspace program needs to know. */
+#include <linux/types.h>
 /* They can register up to 32 arrays of lguest_dma. */
 #define LGUEST_MAX_DMA         32
 /* At most we can dma 16 lguest_dma in one op. */
@@ -9,66 +10,6 @@
 /* How many devices?  Assume each one wants up to two dma arrays per device. */
 #define LGUEST_MAX_DEVICES (LGUEST_MAX_DMA/2)
 
-/*D:200
- * Lguest I/O
- *
- * The lguest I/O mechanism is the only way Guests can talk to devices.  There
- * are two hypercalls involved: SEND_DMA for output and BIND_DMA for input.  In
- * each case, "struct lguest_dma" describes the buffer: this contains 16
- * addr/len pairs, and if there are fewer buffer elements the len array is
- * terminated with a 0.
- *
- * I/O is organized by keys: BIND_DMA attaches buffers to a particular key, and
- * SEND_DMA transfers to buffers bound to particular key.  By convention, keys
- * correspond to a physical address within the device's page.  This means that
- * devices will never accidentally end up with the same keys, and allows the
- * Host use The Futex Trick (as we'll see later in our journey).
- *
- * SEND_DMA simply indicates a key to send to, and the physical address of the
- * "struct lguest_dma" to send.  The Host will write the number of bytes
- * transferred into the "struct lguest_dma"'s used_len member.
- *
- * BIND_DMA indicates a key to bind to, a pointer to an array of "struct
- * lguest_dma"s ready for receiving, the size of that array, and an interrupt
- * to trigger when data is received.  The Host will only allow transfers into
- * buffers with a used_len of zero: it then sets used_len to the number of
- * bytes transferred and triggers the interrupt for the Guest to process the
- * new input. */
-struct lguest_dma
-{
-       /* 0 if free to be used, filled by the Host. */
-       u32 used_len;
-       unsigned long addr[LGUEST_MAX_DMA_SECTIONS];
-       u16 len[LGUEST_MAX_DMA_SECTIONS];
-};
-/*:*/
-
-/*D:460 This is the layout of a block device memory page.  The Launcher sets up
- * the num_sectors initially to tell the Guest the size of the disk.  The Guest
- * puts the type, sector and length of the request in the first three fields,
- * then DMAs to the Host.  The Host processes the request, sets up the result,
- * then DMAs back to the Guest. */
-struct lguest_block_page
-{
-       /* 0 is a read, 1 is a write. */
-       int type;
-       u32 sector;     /* Offset in device = sector * 512. */
-       u32 bytes;      /* Length expected to be read/written in bytes */
-       /* 0 = pending, 1 = done, 2 = done, error */
-       int result;
-       u32 num_sectors; /* Disk length = num_sectors * 512 */
-};
-
-/*D:520 The network device is basically a memory page where all the Guests on
- * the network publish their MAC (ethernet) addresses: it's an array of "struct
- * lguest_net": */
-struct lguest_net
-{
-       /* Simply the mac address (with multicast bit meaning promisc). */
-       unsigned char mac[6];
-};
-/*:*/
-
 /* Where the Host expects the Guest to SEND_DMA console output to. */
 #define LGUEST_CONSOLE_DMA_KEY 0
 
@@ -81,38 +22,29 @@ struct lguest_net
  * complex burden for the Host and suboptimal for the Guest, so we have our own
  * "lguest" bus and simple drivers.
  *
- * Devices are described by an array of LGUEST_MAX_DEVICES of these structs,
- * placed by the Launcher just above the top of physical memory:
+ * Devices are described by a simplified ID, a status byte, and some "config"
+ * bytes which describe this device's configuration.  This is placed by the
+ * Launcher just above the top of physical memory:
  */
 struct lguest_device_desc {
-       /* The device type: console, network, disk etc. */
-       u16 type;
-#define LGUEST_DEVICE_T_CONSOLE        1
-#define LGUEST_DEVICE_T_NET    2
-#define LGUEST_DEVICE_T_BLOCK  3
-
-       /* The specific features of this device: these depends on device type
-        * except for LGUEST_DEVICE_F_RANDOMNESS. */
-       u16 features;
-#define LGUEST_NET_F_NOCSUM            0x4000 /* Don't bother checksumming */
-#define LGUEST_DEVICE_F_RANDOMNESS     0x8000 /* IRQ is fairly random */
-
-       /* This is how the Guest reports status of the device: the Host can set
-        * LGUEST_DEVICE_S_REMOVED to indicate removal, but the rest are only
-        * ever manipulated by the Guest, and only ever set. */
-       u16 status;
-/* 256 and above are device specific. */
-#define LGUEST_DEVICE_S_ACKNOWLEDGE    1 /* We have seen device. */
-#define LGUEST_DEVICE_S_DRIVER         2 /* We have found a driver */
-#define LGUEST_DEVICE_S_DRIVER_OK      4 /* Driver says OK! */
-#define LGUEST_DEVICE_S_REMOVED                8 /* Device has gone away. */
-#define LGUEST_DEVICE_S_REMOVED_ACK    16 /* Driver has been told. */
-#define LGUEST_DEVICE_S_FAILED         128 /* Something actually failed */
+       /* The device type: console, network, disk etc.  Type 0 terminates. */
+       __u8 type;
+       /* The number of bytes of the config array. */
+       __u8 config_len;
+       /* A status byte, written by the Guest. */
+       __u8 status;
+       __u8 config[0];
+};
 
-       /* Each device exists somewhere in Guest physical memory, over some
-        * number of pages. */
-       u16 num_pages;
-       u32 pfn;
+/*D:135 This is how we expect the device configuration field for a virtqueue
+ * (type VIRTIO_CONFIG_F_VIRTQUEUE) to be laid out: */
+struct lguest_vqconfig {
+       /* The number of entries in the virtio_ring */
+       __u16 num;
+       /* The interrupt we get when something happens. */
+       __u16 irq;
+       /* The page number of the virtio ring for this device. */
+       __u32 pfn;
 };
 /*:*/
 
@@ -120,7 +52,7 @@ struct lguest_device_desc {
 enum lguest_req
 {
        LHREQ_INITIALIZE, /* + pfnlimit, pgdir, start, pageoffset */
-       LHREQ_GETDMA, /* + addr (returns &lguest_dma, irq in ->used_len) */
+       LHREQ_GETDMA, /* No longer used */
        LHREQ_IRQ, /* + irq */
        LHREQ_BREAK, /* + on/off flag (on blocks until someone does off) */
 };
index 377e6d4d9be38664320510c77fddc4c5d9cd95ba..bc3b6fc7b98d2bf757a4a5c2a13efe80f93a298e 100644 (file)
@@ -1037,18 +1037,6 @@ extern void ata_port_pbar_desc(struct ata_port *ap, int bar, ssize_t offset,
 /*
  * qc helpers
  */
-static inline int
-ata_sg_is_last(struct scatterlist *sg, struct ata_queued_cmd *qc)
-{
-       if (sg == &qc->pad_sgent)
-               return 1;
-       if (qc->pad_len)
-               return 0;
-       if (qc->n_iter == qc->n_elem)
-               return 1;
-       return 0;
-}
-
 static inline struct scatterlist *
 ata_qc_first_sg(struct ata_queued_cmd *qc)
 {
index 6c9873f8828751d9c48c3c2a5b0eeef793855233..ff203dd029191d5b578707ce184655bcc02967da 100644 (file)
   name:
 #endif
 
+#ifndef WEAK
+#define WEAK(name)        \
+       .weak name;        \
+       name:
+#endif
+
 #define KPROBE_ENTRY(name) \
   .pushsection .kprobes.text, "ax"; \
   ENTRY(name)
index b0cf0135fe3edec0f7054e6602ca7f54572d592f..75ce2cb4ff6ebc92a8fcaa557a9bd7b6b9b9b1b6 100644 (file)
@@ -478,8 +478,7 @@ static inline void list_splice_init_rcu(struct list_head *list,
                pos = n, n = pos->next)
 
 /**
- * list_for_each_prev_safe - iterate over a list backwards safe against removal
-                       of list entry
+ * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
  * @pos:       the &struct list_head to use as a loop cursor.
  * @n:         another &struct list_head to use as temporary storage
  * @head:      the head for your list.
index f6279f68a8270c143196c1c0c09afbea2cff02be..4c4d236ded1885415066c774877abc9fc39592f7 100644 (file)
@@ -275,6 +275,14 @@ extern void lockdep_init_map(struct lockdep_map *lock, const char *name,
                lockdep_init_map(&(lock)->dep_map, #lock, \
                                 (lock)->dep_map.key, sub)
 
+/*
+ * To initialize a lockdep_map statically use this macro.
+ * Note that _name must not be NULL.
+ */
+#define STATIC_LOCKDEP_MAP_INIT(_name, _key) \
+       { .name = (_name), .key = (void *)(_key), }
+
+
 /*
  * Acquire a lock.
  *
index 722d4755060f7deee6f403ee7a5aafed5a914c25..1fa0c2ce4dec09456f5cb6c2480f6be5e5eb908a 100644 (file)
@@ -37,6 +37,7 @@
 
 #define SMB_SUPER_MAGIC                0x517B
 #define USBDEVICE_SUPER_MAGIC  0x9fa2
+#define CGROUP_SUPER_MAGIC     0x27e0eb
 
 #define FUTEXFS_SUPER_MAGIC    0xBAD1DEA
 #define INOTIFYFS_SUPER_MAGIC  0x2BAD1DEA
diff --git a/include/linux/marker.h b/include/linux/marker.h
new file mode 100644 (file)
index 0000000..5f36cf9
--- /dev/null
@@ -0,0 +1,129 @@
+#ifndef _LINUX_MARKER_H
+#define _LINUX_MARKER_H
+
+/*
+ * Code markup for dynamic and static tracing.
+ *
+ * See Documentation/marker.txt.
+ *
+ * (C) Copyright 2006 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
+#include <linux/types.h>
+
+struct module;
+struct marker;
+
+/**
+ * marker_probe_func - Type of a marker probe function
+ * @mdata: pointer of type struct marker
+ * @private_data: caller site private data
+ * @fmt: format string
+ * @...: variable argument list
+ *
+ * Type of marker probe functions. They receive the mdata and need to parse the
+ * format string to recover the variable argument list.
+ */
+typedef void marker_probe_func(const struct marker *mdata,
+       void *private_data, const char *fmt, ...);
+
+struct marker {
+       const char *name;       /* Marker name */
+       const char *format;     /* Marker format string, describing the
+                                * variable argument list.
+                                */
+       char state;             /* Marker state. */
+       marker_probe_func *call;/* Probe handler function pointer */
+       void *private;          /* Private probe data */
+} __attribute__((aligned(8)));
+
+#ifdef CONFIG_MARKERS
+
+/*
+ * Note : the empty asm volatile with read constraint is used here instead of a
+ * "used" attribute to fix a gcc 4.1.x bug.
+ * Make sure the alignment of the structure in the __markers 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 __trace_mark(name, call_data, format, args...)                 \
+       do {                                                            \
+               static const char __mstrtab_name_##name[]               \
+               __attribute__((section("__markers_strings")))           \
+               = #name;                                                \
+               static const char __mstrtab_format_##name[]             \
+               __attribute__((section("__markers_strings")))           \
+               = format;                                               \
+               static struct marker __mark_##name                      \
+               __attribute__((section("__markers"), aligned(8))) =     \
+               { __mstrtab_name_##name, __mstrtab_format_##name,       \
+               0, __mark_empty_function, NULL };                       \
+               __mark_check_format(format, ## args);                   \
+               if (unlikely(__mark_##name.state)) {                    \
+                       preempt_disable();                              \
+                       (*__mark_##name.call)                           \
+                               (&__mark_##name, call_data,             \
+                               format, ## args);                       \
+                       preempt_enable();                               \
+               }                                                       \
+       } while (0)
+
+extern void marker_update_probe_range(struct marker *begin,
+       struct marker *end, struct module *probe_module, int *refcount);
+#else /* !CONFIG_MARKERS */
+#define __trace_mark(name, call_data, format, args...) \
+               __mark_check_format(format, ## args)
+static inline void marker_update_probe_range(struct marker *begin,
+       struct marker *end, struct module *probe_module, int *refcount)
+{ }
+#endif /* CONFIG_MARKERS */
+
+/**
+ * trace_mark - Marker
+ * @name: marker name, not quoted.
+ * @format: format string
+ * @args...: variable argument list
+ *
+ * Places a marker.
+ */
+#define trace_mark(name, format, args...) \
+       __trace_mark(name, NULL, format, ## args)
+
+#define MARK_MAX_FORMAT_LEN    1024
+
+/**
+ * MARK_NOARGS - Format string for a marker with no argument.
+ */
+#define MARK_NOARGS " "
+
+/* To be used for string format validity checking with gcc */
+static inline void __printf(1, 2) __mark_check_format(const char *fmt, ...)
+{
+}
+
+extern marker_probe_func __mark_empty_function;
+
+/*
+ * Connect a probe to a marker.
+ * private data pointer must be a valid allocated memory address, or NULL.
+ */
+extern int marker_probe_register(const char *name, const char *format,
+                               marker_probe_func *probe, void *private);
+
+/*
+ * Returns the private data given to marker_probe_register.
+ */
+extern void *marker_probe_unregister(const char *name);
+/*
+ * Unregister a marker by providing the registered private data.
+ */
+extern void *marker_probe_unregister_private_data(void *private);
+
+extern int marker_arm(const char *name);
+extern int marker_disarm(const char *name);
+extern void *marker_get_private_data(const char *name);
+
+#endif
index 654ef55448780905fbdfb31d7eda298afb805b97..33f0ff0cf63483cc776d4878d1ec24f1ab45e437 100644 (file)
@@ -41,18 +41,15 @@ struct memory_block {
 #define        MEM_ONLINE              (1<<0) /* exposed to userspace */
 #define        MEM_GOING_OFFLINE       (1<<1) /* exposed to userspace */
 #define        MEM_OFFLINE             (1<<2) /* exposed to userspace */
+#define        MEM_GOING_ONLINE        (1<<3)
+#define        MEM_CANCEL_ONLINE       (1<<4)
+#define        MEM_CANCEL_OFFLINE      (1<<5)
 
-/*
- * All of these states are currently kernel-internal for notifying
- * kernel components and architectures.
- *
- * For MEM_MAPPING_INVALID, all notifier chains with priority >0
- * are called before pfn_to_page() becomes invalid.  The priority=0
- * entry is reserved for the function that actually makes
- * pfn_to_page() stop working.  Any notifiers that want to be called
- * after that should have priority <0.
- */
-#define        MEM_MAPPING_INVALID     (1<<3)
+struct memory_notify {
+       unsigned long start_pfn;
+       unsigned long nr_pages;
+       int status_change_nid;
+};
 
 struct notifier_block;
 struct mem_section;
@@ -69,21 +66,31 @@ static inline int register_memory_notifier(struct notifier_block *nb)
 static inline void unregister_memory_notifier(struct notifier_block *nb)
 {
 }
+static inline int memory_notify(unsigned long val, void *v)
+{
+       return 0;
+}
 #else
+extern int register_memory_notifier(struct notifier_block *nb);
+extern void unregister_memory_notifier(struct notifier_block *nb);
 extern int register_new_memory(struct mem_section *);
 extern int unregister_memory_section(struct mem_section *);
 extern int memory_dev_init(void);
 extern int remove_memory_block(unsigned long, struct mem_section *, int);
-
+extern int memory_notify(unsigned long val, void *v);
 #define CONFIG_MEM_BLOCK_SIZE  (PAGES_PER_SECTION<<PAGE_SHIFT)
 
 
 #endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */
 
+#ifdef CONFIG_MEMORY_HOTPLUG
 #define hotplug_memory_notifier(fn, pri) {                     \
        static struct notifier_block fn##_mem_nb =              \
                { .notifier_call = fn, .priority = pri };       \
        register_memory_notifier(&fn##_mem_nb);                 \
 }
+#else
+#define hotplug_memory_notifier(fn, pri) do { } while (0)
+#endif
 
 #endif /* _LINUX_MEMORY_H_ */
index 38c04d61ee069f5d5443a6c514d6dc4eb23424f9..59c4865bc85f13fbe36beefd959ab499f1d5aaaf 100644 (file)
@@ -148,14 +148,6 @@ extern void mpol_rebind_task(struct task_struct *tsk,
                                        const nodemask_t *new);
 extern void mpol_rebind_mm(struct mm_struct *mm, nodemask_t *new);
 extern void mpol_fix_fork_child_flag(struct task_struct *p);
-#define set_cpuset_being_rebound(x) (cpuset_being_rebound = (x))
-
-#ifdef CONFIG_CPUSETS
-#define current_cpuset_is_being_rebound() \
-                               (cpuset_being_rebound == current->cpuset)
-#else
-#define current_cpuset_is_being_rebound() 0
-#endif
 
 extern struct mempolicy default_policy;
 extern struct zonelist *huge_zonelist(struct vm_area_struct *vma,
@@ -173,8 +165,6 @@ static inline void check_highest_zone(enum zone_type k)
 int do_migrate_pages(struct mm_struct *mm,
        const nodemask_t *from_nodes, const nodemask_t *to_nodes, int flags);
 
-extern void *cpuset_being_rebound;     /* Trigger mpol_copy vma rebind */
-
 #else
 
 struct mempolicy {};
@@ -248,8 +238,6 @@ static inline void mpol_fix_fork_child_flag(struct task_struct *p)
 {
 }
 
-#define set_cpuset_being_rebound(x) do {} while (0)
-
 static inline struct zonelist *huge_zonelist(struct vm_area_struct *vma,
                unsigned long addr, gfp_t gfp_flags, struct mempolicy **mpol)
 {
index 3f2da442d7cb1712a9bdd7848b72bb675a8b8911..f31bba270aa27408002fec082fb05187d286a6f9 100644 (file)
 #define MLX4_INIT_DOORBELL_LOCK(ptr)    do { } while (0)
 #define MLX4_GET_DOORBELL_LOCK(ptr)      (NULL)
 
-static inline void mlx4_write64_raw(__be64 val, void __iomem *dest)
-{
-       __raw_writeq((__force u64) val, dest);
-}
-
 static inline void mlx4_write64(__be32 val[2], void __iomem *dest,
                                spinlock_t *doorbell_lock)
 {
@@ -75,12 +70,6 @@ static inline void mlx4_write64(__be32 val[2], void __iomem *dest,
 #define MLX4_INIT_DOORBELL_LOCK(ptr)     spin_lock_init(ptr)
 #define MLX4_GET_DOORBELL_LOCK(ptr)      (ptr)
 
-static inline void mlx4_write64_raw(__be64 val, void __iomem *dest)
-{
-       __raw_writel(((__force u32 *) &val)[0], dest);
-       __raw_writel(((__force u32 *) &val)[1], dest + 4);
-}
-
 static inline void mlx4_write64(__be32 val[2], void __iomem *dest,
                                spinlock_t *doorbell_lock)
 {
index 522b0dd836cf84672ff16d4b40247b9bfb80642b..e9fddb42f26cdee8199d8d4f1d1fc31ce61a6a95 100644 (file)
@@ -361,4 +361,10 @@ struct ssb_device_id {
 #define SSB_ANY_ID             0xFFFF
 #define SSB_ANY_REV            0xFF
 
+struct virtio_device_id {
+       __u32 device;
+       __u32 vendor;
+};
+#define VIRTIO_DEV_ANY_ID      0xffffffff
+
 #endif /* LINUX_MOD_DEVICETABLE_H */
index 642f325e4917fe16cf95660be6ff8b733c7e599d..2cbc0b87e329d30d0ec72b03c83f5d7f123b8a05 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/stringify.h>
 #include <linux/kobject.h>
 #include <linux/moduleparam.h>
+#include <linux/marker.h>
 #include <asm/local.h>
 
 #include <asm/module.h>
@@ -354,6 +355,10 @@ struct module
        /* The command line arguments (may be mangled).  People like
           keeping pointers to this stuff */
        char *args;
+#ifdef CONFIG_MARKERS
+       struct marker *markers;
+       unsigned int num_markers;
+#endif
 };
 #ifndef MODULE_ARCH_INIT
 #define MODULE_ARCH_INIT {}
@@ -457,6 +462,8 @@ int unregister_module_notifier(struct notifier_block * nb);
 
 extern void print_modules(void);
 
+extern void module_update_markers(struct module *probe_module, int *refcount);
+
 #else /* !CONFIG_MODULES... */
 #define EXPORT_SYMBOL(sym)
 #define EXPORT_SYMBOL_GPL(sym)
@@ -556,6 +563,11 @@ static inline void print_modules(void)
 {
 }
 
+static inline void module_update_markers(struct module *probe_module,
+               int *refcount)
+{
+}
+
 #endif /* CONFIG_MODULES */
 
 struct device_driver;
index f1b60740d641c5a61daaed95f68b12e465b331ed..10a3d5a1abffb30fd9b158148b26379416cd1fe0 100644 (file)
@@ -77,7 +77,6 @@ struct msg_msg {
 /* one msq_queue structure for each present queue on the system */
 struct msg_queue {
        struct kern_ipc_perm q_perm;
-       int q_id;
        time_t q_stime;                 /* last msgsnd time */
        time_t q_rtime;                 /* last msgrcv time */
        time_t q_ctime;                 /* last change time */
index c136abce7ef628291325c5ce00a49a1763db6101..dd79cdb8c4cf76fb7a7fe794ca32083fc9fe0be3 100644 (file)
@@ -313,6 +313,10 @@ static const struct proto_ops name##_ops = {                       \
 #define MODULE_ALIAS_NET_PF_PROTO(pf, proto) \
        MODULE_ALIAS("net-pf-" __stringify(pf) "-proto-" __stringify(proto))
 
+#define MODULE_ALIAS_NET_PF_PROTO_TYPE(pf, proto, type) \
+       MODULE_ALIAS("net-pf-" __stringify(pf) "-proto-" __stringify(proto) \
+                    "-type-" __stringify(type))
+
 #ifdef CONFIG_SYSCTL
 #include <linux/sysctl.h>
 extern ctl_table net_table[];
index 39dd83b183a91d0f8fa9ce27a4f8ed84c8a238a8..4a3f54e358e52f7505a8d13aa2a9938941233746 100644 (file)
@@ -407,6 +407,24 @@ static inline void napi_enable(struct napi_struct *n)
        clear_bit(NAPI_STATE_SCHED, &n->state);
 }
 
+#ifdef CONFIG_SMP
+/**
+ *     napi_synchronize - wait until NAPI is not running
+ *     @n: napi context
+ *
+ * Wait until NAPI is done being scheduled on this context.
+ * Waits till any outstanding processing completes but
+ * does not disable future activations.
+ */
+static inline void napi_synchronize(const struct napi_struct *n)
+{
+       while (test_bit(NAPI_STATE_SCHED, &n->state))
+               msleep(1);
+}
+#else
+# define napi_synchronize(n)   barrier()
+#endif
+
 /*
  *     The DEVICE structure.
  *     Actually, this whole structure is a big mistake.  It mixes I/O
@@ -827,7 +845,7 @@ static inline int dev_parse_header(const struct sk_buff *skb,
 {
        const struct net_device *dev = skb->dev;
 
-       if (!dev->header_ops->parse)
+       if (!dev->header_ops || !dev->header_ops->parse)
                return 0;
        return dev->header_ops->parse(skb, haddr);
 }
@@ -978,7 +996,7 @@ static inline void netif_stop_subqueue(struct net_device *dev, u16 queue_index)
  *
  * Check individual transmit queue of a device with multiple transmit queues.
  */
-static inline int netif_subqueue_stopped(const struct net_device *dev,
+static inline int __netif_subqueue_stopped(const struct net_device *dev,
                                         u16 queue_index)
 {
 #ifdef CONFIG_NETDEVICES_MULTIQUEUE
@@ -989,6 +1007,11 @@ static inline int netif_subqueue_stopped(const struct net_device *dev,
 #endif
 }
 
+static inline int netif_subqueue_stopped(const struct net_device *dev,
+                                        struct sk_buff *skb)
+{
+       return __netif_subqueue_stopped(dev, skb_get_queue_mapping(skb));
+}
 
 /**
  *     netif_wake_subqueue - allow sending packets on subqueue
index b157897e7792106842988ba0357600a1497d36c9..dd5a4fd4cfd3c9a2635b891bffed564cf659d66d 100644 (file)
@@ -7,9 +7,6 @@
 
 #define XT_SCTP_VALID_FLAGS            0x07
 
-#define ELEMCOUNT(x) (sizeof(x)/sizeof(x[0]))
-
-
 struct xt_sctp_flag_info {
        u_int8_t chunktype;
        u_int8_t flag;
@@ -59,21 +56,21 @@ struct xt_sctp_info {
 #define SCTP_CHUNKMAP_RESET(chunkmap)                          \
        do {                                                    \
                int i;                                          \
-               for (i = 0; i < ELEMCOUNT(chunkmap); i++)       \
+               for (i = 0; i < ARRAY_SIZE(chunkmap); i++)      \
                        chunkmap[i] = 0;                        \
        } while (0)
 
 #define SCTP_CHUNKMAP_SET_ALL(chunkmap)                        \
        do {                                                    \
                int i;                                          \
-               for (i = 0; i < ELEMCOUNT(chunkmap); i++)       \
+               for (i = 0; i < ARRAY_SIZE(chunkmap); i++)      \
                        chunkmap[i] = ~0;                       \
        } while (0)
 
 #define SCTP_CHUNKMAP_COPY(destmap, srcmap)                    \
        do {                                                    \
                int i;                                          \
-               for (i = 0; i < ELEMCOUNT(chunkmap); i++)       \
+               for (i = 0; i < ARRAY_SIZE(srcmap); i++)        \
                        destmap[i] = srcmap[i];                 \
        } while (0)
 
@@ -81,7 +78,7 @@ struct xt_sctp_info {
 ({                                                     \
        int i;                                          \
        int flag = 1;                                   \
-       for (i = 0; i < ELEMCOUNT(chunkmap); i++) {     \
+       for (i = 0; i < ARRAY_SIZE(chunkmap); i++) {    \
                if (chunkmap[i]) {                      \
                        flag = 0;                       \
                        break;                          \
@@ -94,7 +91,7 @@ struct xt_sctp_info {
 ({                                                     \
        int i;                                          \
        int flag = 1;                                   \
-       for (i = 0; i < ELEMCOUNT(chunkmap); i++) {     \
+       for (i = 0; i < ARRAY_SIZE(chunkmap); i++) {    \
                if (chunkmap[i] != ~0) {                \
                        flag = 0;                       \
                                break;                  \
index c5164c257f71aa17ec51dda414a1921053d8ac5d..e82a6ebc725d7b18a76fdccc9d58853b42a8bdba 100644 (file)
@@ -160,6 +160,12 @@ struct nfs_inode {
        /* Open contexts for shared mmap writes */
        struct list_head        open_files;
 
+       /* Number of in-flight sillydelete RPC calls */
+       atomic_t                silly_count;
+       /* List of deferred sillydelete requests */
+       struct hlist_head       silly_list;
+       wait_queue_head_t       waitqueue;
+
 #ifdef CONFIG_NFS_V4
        struct nfs4_cached_acl  *nfs4_acl;
         /* NFSv4 state */
@@ -394,6 +400,8 @@ extern void nfs_release_automount_timer(void);
  */
 extern int  nfs_async_unlink(struct inode *dir, struct dentry *dentry);
 extern void nfs_complete_unlink(struct dentry *dentry, struct inode *);
+extern void nfs_block_sillyrename(struct dentry *dentry);
+extern void nfs_unblock_sillyrename(struct dentry *dentry);
 
 /*
  * linux/fs/nfs/write.c
index fad7ff17e468ded82fc2e797bc42f6bb4a2f95fe..0c40cc0b4a362034fbe444a929ab1d9a0ecdb749 100644 (file)
@@ -231,5 +231,22 @@ static inline int notifier_to_errno(int ret)
 #define PM_SUSPEND_PREPARE     0x0003 /* Going to suspend the system */
 #define PM_POST_SUSPEND                0x0004 /* Suspend finished */
 
+/* Console keyboard events.
+ * Note: KBD_KEYCODE is always sent before KBD_UNBOUND_KEYCODE, KBD_UNICODE and
+ * KBD_KEYSYM. */
+#define KBD_KEYCODE            0x0001 /* Keyboard keycode, called before any other */
+#define KBD_UNBOUND_KEYCODE    0x0002 /* Keyboard keycode which is not bound to any other */
+#define KBD_UNICODE            0x0003 /* Keyboard unicode */
+#define KBD_KEYSYM             0x0004 /* Keyboard keysym */
+#define KBD_POST_KEYSYM                0x0005 /* Called after keyboard keysym interpretation */
+
+extern struct blocking_notifier_head reboot_notifier_list;
+
+/* Virtual Terminal events. */
+#define VT_ALLOCATE            0x0001 /* Console got allocated */
+#define VT_DEALLOCATE          0x0002 /* Console will be deallocated */
+#define VT_WRITE               0x0003 /* A char got output */
+#define VT_UPDATE              0x0004 /* A bigger update occurred */
+
 #endif /* __KERNEL__ */
 #endif /* _LINUX_NOTIFIER_H */
index 033a648709b620be45ad76db17c1bfa8fe31fcf1..0e66b57631fc767f202c32771f2ab5c8194c34cd 100644 (file)
@@ -32,8 +32,39 @@ struct nsproxy {
 };
 extern struct nsproxy init_nsproxy;
 
+/*
+ * the namespaces access rules are:
+ *
+ *  1. only current task is allowed to change tsk->nsproxy pointer or
+ *     any pointer on the nsproxy itself
+ *
+ *  2. when accessing (i.e. reading) current task's namespaces - no
+ *     precautions should be taken - just dereference the pointers
+ *
+ *  3. the access to other task namespaces is performed like this
+ *     rcu_read_lock();
+ *     nsproxy = task_nsproxy(tsk);
+ *     if (nsproxy != NULL) {
+ *             / *
+ *               * work with the namespaces here
+ *               * e.g. get the reference on one of them
+ *               * /
+ *     } / *
+ *         * NULL task_nsproxy() means that this task is
+ *         * almost dead (zombie)
+ *         * /
+ *     rcu_read_unlock();
+ *
+ */
+
+static inline struct nsproxy *task_nsproxy(struct task_struct *tsk)
+{
+       return rcu_dereference(tsk->nsproxy);
+}
+
 int copy_namespaces(unsigned long flags, struct task_struct *tsk);
-void get_task_namespaces(struct task_struct *tsk);
+void exit_task_namespaces(struct task_struct *tsk);
+void switch_task_namespaces(struct task_struct *tsk, struct nsproxy *new);
 void free_nsproxy(struct nsproxy *ns);
 int unshare_nsproxy_namespaces(unsigned long, struct nsproxy **,
        struct fs_struct *);
@@ -45,14 +76,15 @@ static inline void put_nsproxy(struct nsproxy *ns)
        }
 }
 
-static inline void exit_task_namespaces(struct task_struct *p)
+static inline void get_nsproxy(struct nsproxy *ns)
 {
-       struct nsproxy *ns = p->nsproxy;
-       if (ns) {
-               task_lock(p);
-               p->nsproxy = NULL;
-               task_unlock(p);
-               put_nsproxy(ns);
-       }
+       atomic_inc(&ns->count);
 }
+
+#ifdef CONFIG_CGROUP_NS
+int ns_cgroup_clone(struct task_struct *tsk);
+#else
+static inline int ns_cgroup_clone(struct task_struct *tsk) { return 0; }
+#endif
+
 #endif
index 6df80e9859147973ecd06d6c2863d400b838d71a..5c39b9270ff7007b359df90a7cfc407607ddb7ab 100644 (file)
@@ -16,8 +16,8 @@
  * 2 of the License, or (at your option) any later version.
  */
 #include <linux/types.h>
+#include <linux/bitops.h>
 
-#include <asm/bitops.h>
 #include <asm/prom.h>
 
 /* flag descriptions */
index 448f70b30a0c81fd2148b0b04bbe150bec69e60c..a8efcfeea7323365b65ac3b6098e053af3f14de7 100644 (file)
@@ -48,6 +48,10 @@ struct of_platform_driver
 #define        to_of_platform_driver(drv) \
        container_of(drv,struct of_platform_driver, driver)
 
+extern int of_register_driver(struct of_platform_driver *drv,
+                             struct bus_type *bus);
+extern void of_unregister_driver(struct of_platform_driver *drv);
+
 #include <asm/of_platform.h>
 
 extern struct of_device *of_find_device_by_node(struct device_node *np);
index 9cdd6943e01b8145c7d105d7d89b17c63d40c604..ec3f76598327c69e70f7e2dc67dc701db4969558 100644 (file)
@@ -510,7 +510,6 @@ extern struct pardevice *parport_open (int devnum, const char *name,
                                       int flags, void *handle);
 extern void parport_close (struct pardevice *dev);
 extern ssize_t parport_device_id (int devnum, char *buffer, size_t len);
-extern int parport_device_num (int parport, int mux, int daisy);
 extern void parport_daisy_deselect_all (struct parport *port);
 extern int parport_daisy_select (struct parport *port, int daisy, int mode);
 
index 768b93359f9034268dc8db53923d63bec3d86df4..5d2281f661f77e70a13090d7508f8adcdbba9584 100644 (file)
@@ -141,6 +141,7 @@ struct pci_dev {
        unsigned int    class;          /* 3 bytes: (base,sub,prog-if) */
        u8              revision;       /* PCI revision, low byte of class word */
        u8              hdr_type;       /* PCI header type (`multi' flag masked out) */
+       u8              pcie_type;      /* PCI-E device/port type */
        u8              rom_base_reg;   /* which config register controls the ROM */
        u8              pin;            /* which interrupt pin this device uses */
 
@@ -183,6 +184,7 @@ struct pci_dev {
        unsigned int    msi_enabled:1;
        unsigned int    msix_enabled:1;
        unsigned int    is_managed:1;
+       unsigned int    is_pcie:1;
        atomic_t        enable_cnt;     /* pci_enable_device has been called */
 
        u32             saved_config_space[16]; /* config space saved at suspend time */
index df948b44edadd7b951b01794231df00ee39d6908..4e10a074ca56dce7351fd105537941bffdaf3888 100644 (file)
 #define PCI_DEVICE_ID_TIGON3_5720      0x1658
 #define PCI_DEVICE_ID_TIGON3_5721      0x1659
 #define PCI_DEVICE_ID_TIGON3_5722      0x165a
+#define PCI_DEVICE_ID_TIGON3_5723      0x165b
 #define PCI_DEVICE_ID_TIGON3_5705M     0x165d
 #define PCI_DEVICE_ID_TIGON3_5705M_2   0x165e
 #define PCI_DEVICE_ID_TIGON3_5714      0x1668
index d3ebbfae6903ede052b71731536c0cc8d903a195..96f4048a6cc37bd1a8970c30a1037c1f5f27ad04 100644 (file)
@@ -30,7 +30,11 @@ struct phm_regs {
 #define PHN_SET_REG            _IOW (PH_IOC_MAGIC, 1, struct phm_reg *)
 #define PHN_GET_REGS           _IOWR(PH_IOC_MAGIC, 2, struct phm_regs *)
 #define PHN_SET_REGS           _IOW (PH_IOC_MAGIC, 3, struct phm_regs *)
-#define PH_IOC_MAXNR           3
+/* this ioctl tells the driver, that the caller is not OpenHaptics and might
+ * use improved registers update (no more phantom switchoffs when using
+ * libphantom) */
+#define PHN_NOT_OH             _IO  (PH_IOC_MAGIC, 4)
+#define PH_IOC_MAXNR           4
 
 #define PHN_CONTROL            0x6     /* control byte in iaddr space */
 #define PHN_CTL_AMP            0x1     /*   switch after torques change */
index 1e0e4e3423a628a7983520762b7364038fbbe628..e29a900a84992f308ced20ed5ce4e9a4f2685f09 100644 (file)
@@ -40,15 +40,28 @@ enum pid_type
  * processes.
  */
 
-struct pid
-{
-       atomic_t count;
+
+/*
+ * struct upid is used to get the id of the struct pid, as it is
+ * seen in particular namespace. Later the struct pid is found with
+ * find_pid_ns() using the int nr and struct pid_namespace *ns.
+ */
+
+struct upid {
        /* Try to keep pid_chain in the same cacheline as nr for find_pid */
        int nr;
+       struct pid_namespace *ns;
        struct hlist_node pid_chain;
+};
+
+struct pid
+{
+       atomic_t count;
        /* lists of tasks that use this pid */
        struct hlist_head tasks[PIDTYPE_MAX];
        struct rcu_head rcu;
+       int level;
+       struct upid numbers[1];
 };
 
 extern struct pid init_struct_pid;
@@ -83,26 +96,60 @@ extern void FASTCALL(detach_pid(struct task_struct *task, enum pid_type));
 extern void FASTCALL(transfer_pid(struct task_struct *old,
                                  struct task_struct *new, enum pid_type));
 
+struct pid_namespace;
+extern struct pid_namespace init_pid_ns;
+
 /*
  * look up a PID in the hash table. Must be called with the tasklist_lock
  * or rcu_read_lock() held.
+ *
+ * find_pid_ns() finds the pid in the namespace specified
+ * find_pid() find the pid by its global id, i.e. in the init namespace
+ * find_vpid() finr the pid by its virtual id, i.e. in the current namespace
+ *
+ * see also find_task_by_pid() set in include/linux/sched.h
  */
-extern struct pid *FASTCALL(find_pid(int nr));
+extern struct pid *FASTCALL(find_pid_ns(int nr, struct pid_namespace *ns));
+extern struct pid *find_vpid(int nr);
+extern struct pid *find_pid(int nr);
 
 /*
  * Lookup a PID in the hash table, and return with it's count elevated.
  */
 extern struct pid *find_get_pid(int nr);
-extern struct pid *find_ge_pid(int nr);
+extern struct pid *find_ge_pid(int nr, struct pid_namespace *);
 
-extern struct pid *alloc_pid(void);
+extern struct pid *alloc_pid(struct pid_namespace *ns);
 extern void FASTCALL(free_pid(struct pid *pid));
+extern void zap_pid_ns_processes(struct pid_namespace *pid_ns);
+
+/*
+ * the helpers to get the pid's id seen from different namespaces
+ *
+ * pid_nr()    : global id, i.e. the id seen from the init namespace;
+ * pid_vnr()   : virtual id, i.e. the id seen from the namespace this pid
+ *               belongs to. this only makes sence when called in the
+ *               context of the task that belongs to the same namespace;
+ * pid_nr_ns() : id seen from the ns specified.
+ *
+ * see also task_xid_nr() etc in include/linux/sched.h
+ */
 
 static inline pid_t pid_nr(struct pid *pid)
 {
        pid_t nr = 0;
        if (pid)
-               nr = pid->nr;
+               nr = pid->numbers[0].nr;
+       return nr;
+}
+
+pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns);
+
+static inline pid_t pid_vnr(struct pid *pid)
+{
+       pid_t nr = 0;
+       if (pid)
+               nr = pid->numbers[pid->level].nr;
        return nr;
 }
 
index b9a17e08ff0fa6cd24202defde59f46f31da351e..0135c76c76c6dc8005d4cb2d42353fd3320624b1 100644 (file)
@@ -4,7 +4,6 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/threads.h>
-#include <linux/pid.h>
 #include <linux/nsproxy.h>
 #include <linux/kref.h>
 
@@ -20,13 +19,21 @@ struct pid_namespace {
        struct pidmap pidmap[PIDMAP_ENTRIES];
        int last_pid;
        struct task_struct *child_reaper;
+       struct kmem_cache *pid_cachep;
+       int level;
+       struct pid_namespace *parent;
+#ifdef CONFIG_PROC_FS
+       struct vfsmount *proc_mnt;
+#endif
 };
 
 extern struct pid_namespace init_pid_ns;
 
-static inline void get_pid_ns(struct pid_namespace *ns)
+static inline struct pid_namespace *get_pid_ns(struct pid_namespace *ns)
 {
-       kref_get(&ns->kref);
+       if (ns != &init_pid_ns)
+               kref_get(&ns->kref);
+       return ns;
 }
 
 extern struct pid_namespace *copy_pid_ns(unsigned long flags, struct pid_namespace *ns);
@@ -34,12 +41,19 @@ extern void free_pid_ns(struct kref *kref);
 
 static inline void put_pid_ns(struct pid_namespace *ns)
 {
-       kref_put(&ns->kref, free_pid_ns);
+       if (ns != &init_pid_ns)
+               kref_put(&ns->kref, free_pid_ns);
 }
 
-static inline struct task_struct *child_reaper(struct task_struct *tsk)
+static inline struct pid_namespace *task_active_pid_ns(struct task_struct *tsk)
 {
-       return init_pid_ns.child_reaper;
+       return tsk->nsproxy->pid_ns;
+}
+
+static inline struct task_struct *task_child_reaper(struct task_struct *tsk)
+{
+       BUG_ON(tsk != current);
+       return tsk->nsproxy->pid_ns->child_reaper;
 }
 
 #endif /* _LINUX_PID_NS_H */
index 48b71badfb4c837969fedf91f90cba2cce369587..09a309b7b5d2d4565b48b1eb5f59acd5c13265fe 100644 (file)
@@ -104,104 +104,6 @@ extern void (*pm_idle)(void);
 extern void (*pm_power_off)(void);
 extern void (*pm_power_off_prepare)(void);
 
-typedef int __bitwise suspend_state_t;
-
-#define PM_SUSPEND_ON          ((__force suspend_state_t) 0)
-#define PM_SUSPEND_STANDBY     ((__force suspend_state_t) 1)
-#define PM_SUSPEND_MEM         ((__force suspend_state_t) 3)
-#define PM_SUSPEND_MAX         ((__force suspend_state_t) 4)
-
-/**
- * struct pm_ops - Callbacks for managing platform dependent system sleep
- *     states.
- *
- * @valid: Callback to determine if given system sleep state is supported by
- *     the platform.
- *     Valid (ie. supported) states are advertised in /sys/power/state.  Note
- *     that it still may be impossible to enter given system sleep state if the
- *     conditions aren't right.
- *     There is the %pm_valid_only_mem function available that can be assigned
- *     to this if the platform only supports mem sleep.
- *
- * @set_target: Tell the platform which system sleep state is going to be
- *     entered.
- *     @set_target() is executed right prior to suspending devices.  The
- *     information conveyed to the platform code by @set_target() should be
- *     disregarded by the platform as soon as @finish() is executed and if
- *     @prepare() fails.  If @set_target() fails (ie. returns nonzero),
- *     @prepare(), @enter() and @finish() will not be called by the PM core.
- *     This callback is optional.  However, if it is implemented, the argument
- *     passed to @prepare(), @enter() and @finish() is meaningless and should
- *     be ignored.
- *
- * @prepare: Prepare the platform for entering the system sleep state indicated
- *     by @set_target() or represented by the argument if @set_target() is not
- *     implemented.
- *     @prepare() is called right after devices have been suspended (ie. the
- *     appropriate .suspend() method has been executed for each device) and
- *     before the nonboot CPUs are disabled (it is executed with IRQs enabled).
- *     This callback is optional.  It returns 0 on success or a negative
- *     error code otherwise, in which case the system cannot enter the desired
- *     sleep state (@enter() and @finish() will not be called in that case).
- *
- * @enter: Enter the system sleep state indicated by @set_target() or
- *     represented by the argument if @set_target() is not implemented.
- *     This callback is mandatory.  It returns 0 on success or a negative
- *     error code otherwise, in which case the system cannot enter the desired
- *     sleep state.
- *
- * @finish: Called when the system has just left a sleep state, right after
- *     the nonboot CPUs have been enabled and before devices are resumed (it is
- *     executed with IRQs enabled).  If @set_target() is not implemented, the
- *     argument represents the sleep state being left.
- *     This callback is optional, but should be implemented by the platforms
- *     that implement @prepare().  If implemented, it is always called after
- *     @enter() (even if @enter() fails).
- */
-struct pm_ops {
-       int (*valid)(suspend_state_t state);
-       int (*set_target)(suspend_state_t state);
-       int (*prepare)(suspend_state_t state);
-       int (*enter)(suspend_state_t state);
-       int (*finish)(suspend_state_t state);
-};
-
-#ifdef CONFIG_SUSPEND
-extern struct pm_ops *pm_ops;
-
-/**
- * pm_set_ops - set platform dependent power management ops
- * @pm_ops: The new power management operations to set.
- */
-extern void pm_set_ops(struct pm_ops *pm_ops);
-extern int pm_valid_only_mem(suspend_state_t state);
-
-/**
- * arch_suspend_disable_irqs - disable IRQs for suspend
- *
- * Disables IRQs (in the default case). This is a weak symbol in the common
- * code and thus allows architectures to override it if more needs to be
- * done. Not called for suspend to disk.
- */
-extern void arch_suspend_disable_irqs(void);
-
-/**
- * arch_suspend_enable_irqs - enable IRQs after suspend
- *
- * Enables IRQs (in the default case). This is a weak symbol in the common
- * code and thus allows architectures to override it if more needs to be
- * done. Not called for suspend to disk.
- */
-extern void arch_suspend_enable_irqs(void);
-
-extern int pm_suspend(suspend_state_t state);
-#else /* !CONFIG_SUSPEND */
-#define suspend_valid_only_mem NULL
-
-static inline void pm_set_ops(struct pm_ops *pm_ops) {}
-static inline int pm_suspend(suspend_state_t state) { return -ENOSYS; }
-#endif /* !CONFIG_SUSPEND */
-
 /*
  * Device power management
  */
index d93c300a3449ba81bf38f9aec6c95eb5942cb9ab..a9c31be7052c4bcbd4593963ebf32303b338e04f 100644 (file)
@@ -36,7 +36,8 @@
  */
 
 /********** fs/jbd/journal.c **********/
-#define JBD_POISON_FREE        0x5b
+#define JBD_POISON_FREE                0x5b
+#define JBD2_POISON_FREE       0x5c
 
 /********** drivers/base/dmapool.c **********/
 #define        POOL_POISON_FREED       0xa7    /* !inuse */
index 1adfe668d031ff62485cd2fb5071bdfa85b7b952..af7c36a5a521e8048238b30521470b0b0b73e27c 100644 (file)
        
 */
 
-/*
- *     These cannot be do{}while(0) macros. See the mental gymnastics in
- *     the loop macro.
- */
 #ifndef ARCH_HAS_PREFETCH
-static inline void prefetch(const void *x) {;}
+#define prefetch(x) __builtin_prefetch(x)
 #endif
 
 #ifndef ARCH_HAS_PREFETCHW
-static inline void prefetchw(const void *x) {;}
+#define prefetchw(x) __builtin_prefetch(x,1)
 #endif
 
 #ifndef ARCH_HAS_SPINLOCK_PREFETCH
diff --git a/include/linux/prio_heap.h b/include/linux/prio_heap.h
new file mode 100644 (file)
index 0000000..0809435
--- /dev/null
@@ -0,0 +1,58 @@
+#ifndef _LINUX_PRIO_HEAP_H
+#define _LINUX_PRIO_HEAP_H
+
+/*
+ * Simple insertion-only static-sized priority heap containing
+ * pointers, based on CLR, chapter 7
+ */
+
+#include <linux/gfp.h>
+
+/**
+ * struct ptr_heap - simple static-sized priority heap
+ * @ptrs - pointer to data area
+ * @max - max number of elements that can be stored in @ptrs
+ * @size - current number of valid elements in @ptrs (in the range 0..@size-1
+ * @gt: comparison operator, which should implement "greater than"
+ */
+struct ptr_heap {
+       void **ptrs;
+       int max;
+       int size;
+       int (*gt)(void *, void *);
+};
+
+/**
+ * heap_init - initialize an empty heap with a given memory size
+ * @heap: the heap structure to be initialized
+ * @size: amount of memory to use in bytes
+ * @gfp_mask: mask to pass to kmalloc()
+ * @gt: comparison operator, which should implement "greater than"
+ */
+extern int heap_init(struct ptr_heap *heap, size_t size, gfp_t gfp_mask,
+                    int (*gt)(void *, void *));
+
+/**
+ * heap_free - release a heap's storage
+ * @heap: the heap structure whose data should be released
+ */
+void heap_free(struct ptr_heap *heap);
+
+/**
+ * heap_insert - insert a value into the heap and return any overflowed value
+ * @heap: the heap to be operated on
+ * @p: the pointer to be inserted
+ *
+ * Attempts to insert the given value into the priority heap. If the
+ * heap is full prior to the insertion, then the resulting heap will
+ * consist of the smallest @max elements of the original heap and the
+ * new element; the greatest element will be removed from the heap and
+ * returned. Note that the returned element will be the new element
+ * (i.e. no change to the heap) if the new element is greater than all
+ * elements currently in the heap.
+ */
+extern void *heap_insert(struct ptr_heap *heap, void *p);
+
+
+
+#endif /* _LINUX_PRIO_HEAP_H */
index 20741f668f7bebbba1cd018a07bab5810ae93428..1ff461672060ebc52d882156e0659250944d4110 100644 (file)
@@ -125,7 +125,8 @@ extern struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
 extern void remove_proc_entry(const char *name, struct proc_dir_entry *parent);
 
 extern struct vfsmount *proc_mnt;
-extern int proc_fill_super(struct super_block *,void *,int);
+struct pid_namespace;
+extern int proc_fill_super(struct super_block *);
 extern struct inode *proc_get_inode(struct super_block *, unsigned int, struct proc_dir_entry *);
 
 /*
@@ -142,6 +143,9 @@ extern const struct file_operations proc_kcore_operations;
 extern const struct file_operations proc_kmsg_operations;
 extern const struct file_operations ppc_htab_operations;
 
+extern int pid_ns_prepare_proc(struct pid_namespace *ns);
+extern void pid_ns_release_proc(struct pid_namespace *ns);
+
 /*
  * proc_tty.c
  */
@@ -207,7 +211,9 @@ extern void proc_net_remove(struct net *net, const char *name);
 #define proc_net_create(net, name, mode, info) ({ (void)(mode), NULL; })
 static inline void proc_net_remove(struct net *net, const char *name) {}
 
-static inline void proc_flush_task(struct task_struct *task) { }
+static inline void proc_flush_task(struct task_struct *task)
+{
+}
 
 static inline struct proc_dir_entry *create_proc_entry(const char *name,
        mode_t mode, struct proc_dir_entry *parent) { return NULL; }
@@ -232,6 +238,15 @@ static inline void proc_tty_unregister_driver(struct tty_driver *driver) {};
 
 extern struct proc_dir_entry proc_root;
 
+static inline int pid_ns_prepare_proc(struct pid_namespace *ns)
+{
+       return 0;
+}
+
+static inline void pid_ns_release_proc(struct pid_namespace *ns)
+{
+}
+
 #endif /* CONFIG_PROC_FS */
 
 #if !defined(CONFIG_PROC_KCORE)
index 8dcf237d3386e901fedfb98553e11e2ebf796d32..422eab4958a6996b3f9a57a6ee6fa44217fcddc9 100644 (file)
@@ -28,6 +28,8 @@
 #include <linux/reiserfs_fs_sb.h>
 #endif
 
+struct fid;
+
 /*
  *  include/linux/reiser_fs.h
  *
@@ -85,7 +87,7 @@ void reiserfs_warning(struct super_block *s, const char *fmt, ...);
 if( !( cond ) )                                                                \
   reiserfs_panic( NULL, "reiserfs[%i]: assertion " scond " failed at " \
                  __FILE__ ":%i:%s: " format "\n",              \
-                 in_interrupt() ? -1 : current -> pid, __LINE__ , __FUNCTION__ , ##args )
+                 in_interrupt() ? -1 : task_pid_nr(current), __LINE__ , __FUNCTION__ , ##args )
 
 #define RASSERT(cond, format, args...) __RASSERT(cond, #cond, format, ##args)
 
@@ -283,6 +285,18 @@ static inline struct reiserfs_sb_info *REISERFS_SB(const struct super_block *sb)
        return sb->s_fs_info;
 }
 
+/* Don't trust REISERFS_SB(sb)->s_bmap_nr, it's a u16
+ * which overflows on large file systems. */
+static inline u32 reiserfs_bmap_count(struct super_block *sb)
+{
+       return (SB_BLOCK_COUNT(sb) - 1) / (sb->s_blocksize * 8) + 1;
+}
+
+static inline int bmap_would_wrap(unsigned bmap_nr)
+{
+       return bmap_nr > ((1LL << 16) - 1);
+}
+
 /** this says about version of key of all items (but stat data) the
     object consists of */
 #define get_inode_item_key_version( inode )                                    \
@@ -1734,8 +1748,8 @@ int journal_end_sync(struct reiserfs_transaction_handle *, struct super_block *,
 int journal_mark_freed(struct reiserfs_transaction_handle *,
                       struct super_block *, b_blocknr_t blocknr);
 int journal_transaction_should_end(struct reiserfs_transaction_handle *, int);
-int reiserfs_in_journal(struct super_block *p_s_sb, int bmap_nr, int bit_nr,
-                       int searchall, b_blocknr_t * next);
+int reiserfs_in_journal(struct super_block *p_s_sb, unsigned int bmap_nr,
+                       int bit_nr, int searchall, b_blocknr_t *next);
 int journal_begin(struct reiserfs_transaction_handle *,
                  struct super_block *p_s_sb, unsigned long);
 int journal_join_abort(struct reiserfs_transaction_handle *,
@@ -1743,7 +1757,7 @@ int journal_join_abort(struct reiserfs_transaction_handle *,
 void reiserfs_journal_abort(struct super_block *sb, int errno);
 void reiserfs_abort(struct super_block *sb, int errno, const char *fmt, ...);
 int reiserfs_allocate_list_bitmaps(struct super_block *s,
-                                  struct reiserfs_list_bitmap *, int);
+                                  struct reiserfs_list_bitmap *, unsigned int);
 
 void add_save_link(struct reiserfs_transaction_handle *th,
                   struct inode *inode, int truncate);
@@ -1865,12 +1879,10 @@ void reiserfs_delete_inode(struct inode *inode);
 int reiserfs_write_inode(struct inode *inode, int);
 int reiserfs_get_block(struct inode *inode, sector_t block,
                       struct buffer_head *bh_result, int create);
-struct dentry *reiserfs_get_dentry(struct super_block *, void *);
-struct dentry *reiserfs_decode_fh(struct super_block *sb, __u32 * data,
-                                 int len, int fhtype,
-                                 int (*acceptable) (void *contect,
-                                                    struct dentry * de),
-                                 void *context);
+struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
+                                    int fh_len, int fh_type);
+struct dentry *reiserfs_fh_to_parent(struct super_block *sb, struct fid *fid,
+                                    int fh_len, int fh_type);
 int reiserfs_encode_fh(struct dentry *dentry, __u32 * data, int *lenp,
                       int connectable);
 
@@ -2041,7 +2053,7 @@ struct buffer_head *get_FEB(struct tree_balance *);
  * arguments, such as node, search path, transaction_handle, etc. */
 struct __reiserfs_blocknr_hint {
        struct inode *inode;    /* inode passed to allocator, if we allocate unf. nodes */
-       long block;             /* file offset, in blocks */
+       sector_t block;         /* file offset, in blocks */
        struct in_core_key key;
        struct treepath *path;  /* search path, used by allocator to deternine search_start by
                                 * various ways */
@@ -2099,7 +2111,8 @@ static inline int reiserfs_new_form_blocknrs(struct tree_balance *tb,
 static inline int reiserfs_new_unf_blocknrs(struct reiserfs_transaction_handle
                                            *th, struct inode *inode,
                                            b_blocknr_t * new_blocknrs,
-                                           struct treepath *path, long block)
+                                           struct treepath *path,
+                                           sector_t block)
 {
        reiserfs_blocknr_hint_t hint = {
                .th = th,
@@ -2116,7 +2129,8 @@ static inline int reiserfs_new_unf_blocknrs(struct reiserfs_transaction_handle
 static inline int reiserfs_new_unf_blocknrs2(struct reiserfs_transaction_handle
                                             *th, struct inode *inode,
                                             b_blocknr_t * new_blocknrs,
-                                            struct treepath *path, long block)
+                                            struct treepath *path,
+                                            sector_t block)
 {
        reiserfs_blocknr_hint_t hint = {
                .th = th,
index ff9e9234f8ba64b77f2b7316e34fc69781919e2f..10fa0c832018c870a7bac82b428cdb976cb34449 100644 (file)
@@ -265,9 +265,7 @@ enum journal_state_bits {
 typedef __u32(*hashf_t) (const signed char *, int);
 
 struct reiserfs_bitmap_info {
-       // FIXME: Won't work with block sizes > 8K
-       __u16 first_zero_hint;
-       __u16 free_count;
+       __u32 free_count;
 };
 
 struct proc_dir_entry;
index 2dc7464cce5245a0a41e458567372e9401bd58d3..df7ddcee7c4bdcef4ea5f80ed99c8719c025fc27 100644 (file)
 #include <asm/scatterlist.h>
 #include <linux/mm.h>
 #include <linux/string.h>
+#include <asm/io.h>
 
+/*
+ * Notes on SG table design.
+ *
+ * Architectures must provide an unsigned long page_link field in the
+ * scatterlist struct. We use that to place the page pointer AND encode
+ * information about the sg table as well. The two lower bits are reserved
+ * for this information.
+ *
+ * If bit 0 is set, then the page_link contains a pointer to the next sg
+ * table list. Otherwise the next entry is at sg + 1.
+ *
+ * If bit 1 is set, then this sg entry is the last element in a list.
+ *
+ * See sg_next().
+ *
+ */
+
+#define SG_MAGIC       0x87654321
+
+/**
+ * sg_set_page - Set sg entry to point at given page
+ * @sg:                 SG entry
+ * @page:       The page
+ *
+ * Description:
+ *   Use this function to set an sg entry pointing at a page, never assign
+ *   the page directly. We encode sg table information in the lower bits
+ *   of the page pointer. See sg_page() for looking up the page belonging
+ *   to an sg entry.
+ *
+ **/
+static inline void sg_set_page(struct scatterlist *sg, struct page *page)
+{
+       unsigned long page_link = sg->page_link & 0x3;
+
+       /*
+        * In order for the low bit stealing approach to work, pages
+        * must be aligned at a 32-bit boundary as a minimum.
+        */
+       BUG_ON((unsigned long) page & 0x03);
+#ifdef CONFIG_DEBUG_SG
+       BUG_ON(sg->sg_magic != SG_MAGIC);
+#endif
+       sg->page_link = page_link | (unsigned long) page;
+}
+
+#define sg_page(sg)    ((struct page *) ((sg)->page_link & ~0x3))
+
+/**
+ * sg_set_buf - Set sg entry to point at given data
+ * @sg:                 SG entry
+ * @buf:        Data
+ * @buflen:     Data length
+ *
+ **/
 static inline void sg_set_buf(struct scatterlist *sg, const void *buf,
                              unsigned int buflen)
 {
-       sg->page = virt_to_page(buf);
+       sg_set_page(sg, virt_to_page(buf));
        sg->offset = offset_in_page(buf);
        sg->length = buflen;
 }
 
-static inline void sg_init_one(struct scatterlist *sg, const void *buf,
-                              unsigned int buflen)
-{
-       memset(sg, 0, sizeof(*sg));
-       sg_set_buf(sg, buf, buflen);
-}
-
 /*
  * We overload the LSB of the page pointer to indicate whether it's
  * a valid sg entry, or whether it points to the start of a new scatterlist.
  * Those low bits are there for everyone! (thanks mason :-)
  */
-#define sg_is_chain(sg)                ((unsigned long) (sg)->page & 0x01)
+#define sg_is_chain(sg)                ((sg)->page_link & 0x01)
+#define sg_is_last(sg)         ((sg)->page_link & 0x02)
 #define sg_chain_ptr(sg)       \
-       ((struct scatterlist *) ((unsigned long) (sg)->page & ~0x01))
+       ((struct scatterlist *) ((sg)->page_link & ~0x03))
 
 /**
  * sg_next - return the next scatterlist entry in a list
  * @sg:                The current sg entry
  *
- * Usually the next entry will be @sg@ + 1, but if this sg element is part
- * of a chained scatterlist, it could jump to the start of a new
- * scatterlist array.
- *
- * Note that the caller must ensure that there are further entries after
- * the current entry, this function will NOT return NULL for an end-of-list.
+ * Description:
+ *   Usually the next entry will be @sg@ + 1, but if this sg element is part
+ *   of a chained scatterlist, it could jump to the start of a new
+ *   scatterlist array.
  *
- */
+ **/
 static inline struct scatterlist *sg_next(struct scatterlist *sg)
 {
-       sg++;
+#ifdef CONFIG_DEBUG_SG
+       BUG_ON(sg->sg_magic != SG_MAGIC);
+#endif
+       if (sg_is_last(sg))
+               return NULL;
 
+       sg++;
        if (unlikely(sg_is_chain(sg)))
                sg = sg_chain_ptr(sg);
 
@@ -62,14 +115,15 @@ static inline struct scatterlist *sg_next(struct scatterlist *sg)
  * @sgl:       First entry in the scatterlist
  * @nents:     Number of entries in the scatterlist
  *
- * Should only be used casually, it (currently) scan the entire list
- * to get the last entry.
+ * Description:
+ *   Should only be used casually, it (currently) scan the entire list
+ *   to get the last entry.
  *
- * Note that the @sgl@ pointer passed in need not be the first one,
- * the important bit is that @nents@ denotes the number of entries that
- * exist from @sgl@.
+ *   Note that the @sgl@ pointer passed in need not be the first one,
+ *   the important bit is that @nents@ denotes the number of entries that
+ *   exist from @sgl@.
  *
- */
+ **/
 static inline struct scatterlist *sg_last(struct scatterlist *sgl,
                                          unsigned int nents)
 {
@@ -82,6 +136,10 @@ static inline struct scatterlist *sg_last(struct scatterlist *sgl,
        for_each_sg(sgl, sg, nents, i)
                ret = sg;
 
+#endif
+#ifdef CONFIG_DEBUG_SG
+       BUG_ON(sgl[0].sg_magic != SG_MAGIC);
+       BUG_ON(!sg_is_last(ret));
 #endif
        return ret;
 }
@@ -92,16 +150,111 @@ static inline struct scatterlist *sg_last(struct scatterlist *sgl,
  * @prv_nents: Number of entries in prv
  * @sgl:       Second scatterlist
  *
- * Links @prv@ and @sgl@ together, to form a longer scatterlist.
+ * Description:
+ *   Links @prv@ and @sgl@ together, to form a longer scatterlist.
  *
- */
+ **/
 static inline void sg_chain(struct scatterlist *prv, unsigned int prv_nents,
                            struct scatterlist *sgl)
 {
 #ifndef ARCH_HAS_SG_CHAIN
        BUG();
 #endif
-       prv[prv_nents - 1].page = (struct page *) ((unsigned long) sgl | 0x01);
+       prv[prv_nents - 1].page_link = (unsigned long) sgl | 0x01;
+}
+
+/**
+ * sg_mark_end - Mark the end of the scatterlist
+ * @sgl:       Scatterlist
+ * @nents:     Number of entries in sgl
+ *
+ * Description:
+ *   Marks the last entry as the termination point for sg_next()
+ *
+ **/
+static inline void sg_mark_end(struct scatterlist *sgl, unsigned int nents)
+{
+       sgl[nents - 1].page_link = 0x02;
+}
+
+static inline void __sg_mark_end(struct scatterlist *sg)
+{
+       sg->page_link |= 0x02;
+}
+
+/**
+ * sg_init_one - Initialize a single entry sg list
+ * @sg:                 SG entry
+ * @buf:        Virtual address for IO
+ * @buflen:     IO length
+ *
+ * Notes:
+ *   This should not be used on a single entry that is part of a larger
+ *   table. Use sg_init_table() for that.
+ *
+ **/
+static inline void sg_init_one(struct scatterlist *sg, const void *buf,
+                              unsigned int buflen)
+{
+       memset(sg, 0, sizeof(*sg));
+#ifdef CONFIG_DEBUG_SG
+       sg->sg_magic = SG_MAGIC;
+#endif
+       sg_mark_end(sg, 1);
+       sg_set_buf(sg, buf, buflen);
+}
+
+/**
+ * sg_init_table - Initialize SG table
+ * @sgl:          The SG table
+ * @nents:        Number of entries in table
+ *
+ * Notes:
+ *   If this is part of a chained sg table, sg_mark_end() should be
+ *   used only on the last table part.
+ *
+ **/
+static inline void sg_init_table(struct scatterlist *sgl, unsigned int nents)
+{
+       memset(sgl, 0, sizeof(*sgl) * nents);
+       sg_mark_end(sgl, nents);
+#ifdef CONFIG_DEBUG_SG
+       {
+               int i;
+               for (i = 0; i < nents; i++)
+                       sgl[i].sg_magic = SG_MAGIC;
+       }
+#endif
+}
+
+/**
+ * sg_phys - Return physical address of an sg entry
+ * @sg:             SG entry
+ *
+ * Description:
+ *   This calls page_to_phys() on the page in this sg entry, and adds the
+ *   sg offset. The caller must know that it is legal to call page_to_phys()
+ *   on the sg page.
+ *
+ **/
+static inline unsigned long sg_phys(struct scatterlist *sg)
+{
+       return page_to_phys(sg_page(sg)) + sg->offset;
+}
+
+/**
+ * sg_virt - Return virtual address of an sg entry
+ * @sg:      SG entry
+ *
+ * Description:
+ *   This calls page_address() on the page in this sg entry, and adds the
+ *   sg offset. The caller must know that the sg page has a valid virtual
+ *   mapping.
+ *
+ **/
+static inline void *sg_virt(struct scatterlist *sg)
+{
+       return page_address(sg_page(sg)) + sg->offset;
 }
 
 #endif /* _LINUX_SCATTERLIST_H */
index c204ab0d4df16a2200962bd07a6a62637154832f..13df99fb27693b159d1bbc272ed406fc87a10e3b 100644 (file)
@@ -25,6 +25,7 @@
 #define CLONE_NEWUTS           0x04000000      /* New utsname group? */
 #define CLONE_NEWIPC           0x08000000      /* New ipcs */
 #define CLONE_NEWUSER          0x10000000      /* New user namespace */
+#define CLONE_NEWPID           0x20000000      /* New pid namespace */
 #define CLONE_NEWNET           0x40000000      /* New network namespace */
 
 /*
@@ -428,7 +429,17 @@ struct signal_struct {
        cputime_t it_prof_incr, it_virt_incr;
 
        /* job control IDs */
-       pid_t pgrp;
+
+       /*
+        * pgrp and session fields are deprecated.
+        * use the task_session_Xnr and task_pgrp_Xnr routines below
+        */
+
+       union {
+               pid_t pgrp __deprecated;
+               pid_t __pgrp;
+       };
+
        struct pid *tty_old_pgrp;
 
        union {
@@ -569,7 +580,7 @@ struct sched_info {
                           last_queued; /* when we were last queued to run */
 #ifdef CONFIG_SCHEDSTATS
        /* BKL stats */
-       unsigned long bkl_count;
+       unsigned int bkl_count;
 #endif
 };
 #endif /* defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) */
@@ -705,37 +716,39 @@ struct sched_domain {
 
 #ifdef CONFIG_SCHEDSTATS
        /* load_balance() stats */
-       unsigned long lb_count[CPU_MAX_IDLE_TYPES];
-       unsigned long lb_failed[CPU_MAX_IDLE_TYPES];
-       unsigned long lb_balanced[CPU_MAX_IDLE_TYPES];
-       unsigned long lb_imbalance[CPU_MAX_IDLE_TYPES];
-       unsigned long lb_gained[CPU_MAX_IDLE_TYPES];
-       unsigned long lb_hot_gained[CPU_MAX_IDLE_TYPES];
-       unsigned long lb_nobusyg[CPU_MAX_IDLE_TYPES];
-       unsigned long lb_nobusyq[CPU_MAX_IDLE_TYPES];
+       unsigned int lb_count[CPU_MAX_IDLE_TYPES];
+       unsigned int lb_failed[CPU_MAX_IDLE_TYPES];
+       unsigned int lb_balanced[CPU_MAX_IDLE_TYPES];
+       unsigned int lb_imbalance[CPU_MAX_IDLE_TYPES];
+       unsigned int lb_gained[CPU_MAX_IDLE_TYPES];
+       unsigned int lb_hot_gained[CPU_MAX_IDLE_TYPES];
+       unsigned int lb_nobusyg[CPU_MAX_IDLE_TYPES];
+       unsigned int lb_nobusyq[CPU_MAX_IDLE_TYPES];
 
        /* Active load balancing */
-       unsigned long alb_count;
-       unsigned long alb_failed;
-       unsigned long alb_pushed;
+       unsigned int alb_count;
+       unsigned int alb_failed;
+       unsigned int alb_pushed;
 
        /* SD_BALANCE_EXEC stats */
-       unsigned long sbe_count;
-       unsigned long sbe_balanced;
-       unsigned long sbe_pushed;
+       unsigned int sbe_count;
+       unsigned int sbe_balanced;
+       unsigned int sbe_pushed;
 
        /* SD_BALANCE_FORK stats */
-       unsigned long sbf_count;
-       unsigned long sbf_balanced;
-       unsigned long sbf_pushed;
+       unsigned int sbf_count;
+       unsigned int sbf_balanced;
+       unsigned int sbf_pushed;
 
        /* try_to_wake_up() stats */
-       unsigned long ttwu_wake_remote;
-       unsigned long ttwu_move_affine;
-       unsigned long ttwu_move_balance;
+       unsigned int ttwu_wake_remote;
+       unsigned int ttwu_move_affine;
+       unsigned int ttwu_move_balance;
 #endif
 };
 
+extern void partition_sched_domains(int ndoms_new, cpumask_t *doms_new);
+
 #endif /* CONFIG_SMP */
 
 /*
@@ -756,8 +769,6 @@ static inline int above_background_load(void)
 }
 
 struct io_context;                     /* See blkdev.h */
-struct cpuset;
-
 #define NGROUPS_SMALL          32
 #define NGROUPS_PER_BLOCK      ((int)(PAGE_SIZE / sizeof(gid_t)))
 struct group_info {
@@ -991,7 +1002,7 @@ struct task_struct {
        int __user *clear_child_tid;            /* CLONE_CHILD_CLEARTID */
 
        unsigned int rt_priority;
-       cputime_t utime, stime;
+       cputime_t utime, stime, utimescaled, stimescaled;
        cputime_t gtime;
        unsigned long nvcsw, nivcsw; /* context switch counts */
        struct timespec start_time;             /* monotonic time */
@@ -1110,13 +1121,6 @@ struct task_struct {
 
        unsigned long ptrace_message;
        siginfo_t *last_siginfo; /* For ptrace use.  */
-/*
- * current io wait handle: wait queue entry to use for io waits
- * If this thread is processing aio, this points at the waitqueue
- * inside the currently handled kiocb. It may be NULL (i.e. default
- * to a stack based synchronous wait) if its doing sync IO.
- */
-       wait_queue_t *io_wait;
 #ifdef CONFIG_TASK_XACCT
 /* i/o counters(bytes read/written, #syscalls */
        u64 rchar, wchar, syscr, syscw;
@@ -1132,11 +1136,16 @@ struct task_struct {
        short il_next;
 #endif
 #ifdef CONFIG_CPUSETS
-       struct cpuset *cpuset;
        nodemask_t mems_allowed;
        int cpuset_mems_generation;
        int cpuset_mem_spread_rotor;
 #endif
+#ifdef CONFIG_CGROUPS
+       /* Control Group info protected by css_set_lock */
+       struct css_set *cgroups;
+       /* cg_list protected by css_set_lock and tsk->alloc_lock */
+       struct list_head cg_list;
+#endif
 #ifdef CONFIG_FUTEX
        struct robust_list_head __user *robust_list;
 #ifdef CONFIG_COMPAT
@@ -1192,24 +1201,14 @@ static inline int rt_task(struct task_struct *p)
        return rt_prio(p->prio);
 }
 
-static inline pid_t process_group(struct task_struct *tsk)
-{
-       return tsk->signal->pgrp;
-}
-
-static inline pid_t signal_session(struct signal_struct *sig)
+static inline void set_task_session(struct task_struct *tsk, pid_t session)
 {
-       return sig->__session;
+       tsk->signal->__session = session;
 }
 
-static inline pid_t process_session(struct task_struct *tsk)
+static inline void set_task_pgrp(struct task_struct *tsk, pid_t pgrp)
 {
-       return signal_session(tsk->signal);
-}
-
-static inline void set_signal_session(struct signal_struct *sig, pid_t session)
-{
-       sig->__session = session;
+       tsk->signal->__pgrp = pgrp;
 }
 
 static inline struct pid *task_pid(struct task_struct *task)
@@ -1232,6 +1231,88 @@ static inline struct pid *task_session(struct task_struct *task)
        return task->group_leader->pids[PIDTYPE_SID].pid;
 }
 
+struct pid_namespace;
+
+/*
+ * the helpers to get the task's different pids as they are seen
+ * from various namespaces
+ *
+ * task_xid_nr()     : global id, i.e. the id seen from the init namespace;
+ * task_xid_vnr()    : virtual id, i.e. the id seen from the namespace the task
+ *                     belongs to. this only makes sence when called in the
+ *                     context of the task that belongs to the same namespace;
+ * task_xid_nr_ns()  : id seen from the ns specified;
+ *
+ * set_task_vxid()   : assigns a virtual id to a task;
+ *
+ * task_ppid_nr_ns() : the parent's id as seen from the namespace specified.
+ *                     the result depends on the namespace and whether the
+ *                     task in question is the namespace's init. e.g. for the
+ *                     namespace's init this will return 0 when called from
+ *                     the namespace of this init, or appropriate id otherwise.
+ *
+ *
+ * see also pid_nr() etc in include/linux/pid.h
+ */
+
+static inline pid_t task_pid_nr(struct task_struct *tsk)
+{
+       return tsk->pid;
+}
+
+pid_t task_pid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns);
+
+static inline pid_t task_pid_vnr(struct task_struct *tsk)
+{
+       return pid_vnr(task_pid(tsk));
+}
+
+
+static inline pid_t task_tgid_nr(struct task_struct *tsk)
+{
+       return tsk->tgid;
+}
+
+pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns);
+
+static inline pid_t task_tgid_vnr(struct task_struct *tsk)
+{
+       return pid_vnr(task_tgid(tsk));
+}
+
+
+static inline pid_t task_pgrp_nr(struct task_struct *tsk)
+{
+       return tsk->signal->__pgrp;
+}
+
+pid_t task_pgrp_nr_ns(struct task_struct *tsk, struct pid_namespace *ns);
+
+static inline pid_t task_pgrp_vnr(struct task_struct *tsk)
+{
+       return pid_vnr(task_pgrp(tsk));
+}
+
+
+static inline pid_t task_session_nr(struct task_struct *tsk)
+{
+       return tsk->signal->__session;
+}
+
+pid_t task_session_nr_ns(struct task_struct *tsk, struct pid_namespace *ns);
+
+static inline pid_t task_session_vnr(struct task_struct *tsk)
+{
+       return pid_vnr(task_session(tsk));
+}
+
+
+static inline pid_t task_ppid_nr_ns(struct task_struct *tsk,
+               struct pid_namespace *ns)
+{
+       return pid_nr_ns(task_pid(rcu_dereference(tsk->real_parent)), ns);
+}
+
 /**
  * pid_alive - check that a task structure is not stale
  * @p: Task structure to be checked.
@@ -1246,16 +1327,22 @@ static inline int pid_alive(struct task_struct *p)
 }
 
 /**
- * is_init - check if a task structure is init
+ * is_global_init - check if a task structure is init
  * @tsk: Task structure to be checked.
  *
  * Check if a task structure is the first user space task the kernel created.
  */
-static inline int is_init(struct task_struct *tsk)
+static inline int is_global_init(struct task_struct *tsk)
 {
        return tsk->pid == 1;
 }
 
+/*
+ * is_container_init:
+ * check whether in the task is init in its own pid namespace.
+ */
+extern int is_container_init(struct task_struct *tsk);
+
 extern struct pid *cad_pid;
 
 extern void free_task(struct task_struct *tsk);
@@ -1427,8 +1514,32 @@ extern struct task_struct init_task;
 
 extern struct   mm_struct init_mm;
 
-#define find_task_by_pid(nr)   find_task_by_pid_type(PIDTYPE_PID, nr)
-extern struct task_struct *find_task_by_pid_type(int type, int pid);
+extern struct pid_namespace init_pid_ns;
+
+/*
+ * find a task by one of its numerical ids
+ *
+ * find_task_by_pid_type_ns():
+ *      it is the most generic call - it finds a task by all id,
+ *      type and namespace specified
+ * find_task_by_pid_ns():
+ *      finds a task by its pid in the specified namespace
+ * find_task_by_vpid():
+ *      finds a task by its virtual pid
+ * find_task_by_pid():
+ *      finds a task by its global pid
+ *
+ * see also find_pid() etc in include/linux/pid.h
+ */
+
+extern struct task_struct *find_task_by_pid_type_ns(int type, int pid,
+               struct pid_namespace *ns);
+
+extern struct task_struct *find_task_by_pid(pid_t nr);
+extern struct task_struct *find_task_by_vpid(pid_t nr);
+extern struct task_struct *find_task_by_pid_ns(pid_t nr,
+               struct pid_namespace *ns);
+
 extern void __set_special_pids(pid_t session, pid_t pgrp);
 
 /* per-UID process charging. */
@@ -1615,6 +1726,12 @@ static inline int has_group_leader_pid(struct task_struct *p)
        return p->pid == p->tgid;
 }
 
+static inline
+int same_thread_group(struct task_struct *p1, struct task_struct *p2)
+{
+       return p1->tgid == p2->tgid;
+}
+
 static inline struct task_struct *next_thread(const struct task_struct *p)
 {
        return list_entry(rcu_dereference(p->thread_group.next),
@@ -1632,7 +1749,8 @@ static inline int thread_group_empty(struct task_struct *p)
 /*
  * Protects ->fs, ->files, ->mm, ->group_info, ->comm, keyring
  * subscriptions and synchronises with wait4().  Also used in procfs.  Also
- * pins the final release of task.io_context.  Also protects ->cpuset.
+ * pins the final release of task.io_context.  Also protects ->cpuset and
+ * ->cgroup.subsys[].
  *
  * Nests both inside and outside of read_lock(&tasklist_lock).
  * It must not be nested with write_lock_irq(&tasklist_lock),
index ba81ffe9958a3c48d55cb16be1e18a0524e27dd0..827b85bbf388213304c6614eee4d0a57bd2b1845 100644 (file)
@@ -8,45 +8,43 @@
  */
 
 struct screen_info {
-       u8  orig_x;             /* 0x00 */
-       u8  orig_y;             /* 0x01 */
-       u16 ext_mem_k;          /* 0x02 */
-       u16 orig_video_page;    /* 0x04 */
-       u8  orig_video_mode;    /* 0x06 */
-       u8  orig_video_cols;    /* 0x07 */
-       u16 unused2;            /* 0x08 */
-       u16 orig_video_ega_bx;  /* 0x0a */
-       u16 unused3;            /* 0x0c */
-       u8  orig_video_lines;   /* 0x0e */
-       u8  orig_video_isVGA;   /* 0x0f */
-       u16 orig_video_points;  /* 0x10 */
+       __u8  orig_x;           /* 0x00 */
+       __u8  orig_y;           /* 0x01 */
+       __u16 ext_mem_k;        /* 0x02 */
+       __u16 orig_video_page;  /* 0x04 */
+       __u8  orig_video_mode;  /* 0x06 */
+       __u8  orig_video_cols;  /* 0x07 */
+       __u16 unused2;          /* 0x08 */
+       __u16 orig_video_ega_bx;/* 0x0a */
+       __u16 unused3;          /* 0x0c */
+       __u8  orig_video_lines; /* 0x0e */
+       __u8  orig_video_isVGA; /* 0x0f */
+       __u16 orig_video_points;/* 0x10 */
 
        /* VESA graphic mode -- linear frame buffer */
-       u16 lfb_width;          /* 0x12 */
-       u16 lfb_height;         /* 0x14 */
-       u16 lfb_depth;          /* 0x16 */
-       u32 lfb_base;           /* 0x18 */
-       u32 lfb_size;           /* 0x1c */
-       u16 cl_magic, cl_offset; /* 0x20 */
-       u16 lfb_linelength;     /* 0x24 */
-       u8  red_size;           /* 0x26 */
-       u8  red_pos;            /* 0x27 */
-       u8  green_size;         /* 0x28 */
-       u8  green_pos;          /* 0x29 */
-       u8  blue_size;          /* 0x2a */
-       u8  blue_pos;           /* 0x2b */
-       u8  rsvd_size;          /* 0x2c */
-       u8  rsvd_pos;           /* 0x2d */
-       u16 vesapm_seg;         /* 0x2e */
-       u16 vesapm_off;         /* 0x30 */
-       u16 pages;              /* 0x32 */
-       u16 vesa_attributes;    /* 0x34 */
-       u32 capabilities;       /* 0x36 */
-       u8  _reserved[6];       /* 0x3a */
+       __u16 lfb_width;        /* 0x12 */
+       __u16 lfb_height;       /* 0x14 */
+       __u16 lfb_depth;        /* 0x16 */
+       __u32 lfb_base;         /* 0x18 */
+       __u32 lfb_size;         /* 0x1c */
+       __u16 cl_magic, cl_offset; /* 0x20 */
+       __u16 lfb_linelength;   /* 0x24 */
+       __u8  red_size;         /* 0x26 */
+       __u8  red_pos;          /* 0x27 */
+       __u8  green_size;       /* 0x28 */
+       __u8  green_pos;        /* 0x29 */
+       __u8  blue_size;        /* 0x2a */
+       __u8  blue_pos;         /* 0x2b */
+       __u8  rsvd_size;        /* 0x2c */
+       __u8  rsvd_pos;         /* 0x2d */
+       __u16 vesapm_seg;       /* 0x2e */
+       __u16 vesapm_off;       /* 0x30 */
+       __u16 pages;            /* 0x32 */
+       __u16 vesa_attributes;  /* 0x34 */
+       __u32 capabilities;     /* 0x36 */
+       __u8  _reserved[6];     /* 0x3a */
 } __attribute__((packed));
 
-extern struct screen_info screen_info;
-
 #define VIDEO_TYPE_MDA         0x10    /* Monochrome Text Display      */
 #define VIDEO_TYPE_CGA         0x11    /* CGA Display                  */
 #define VIDEO_TYPE_EGAM                0x20    /* EGA/VGA in Monochrome Mode   */
@@ -65,4 +63,17 @@ extern struct screen_info screen_info;
 
 #define VIDEO_TYPE_PMAC                0x60    /* PowerMacintosh frame buffer. */
 
+#ifdef __KERNEL__
+extern struct screen_info screen_info;
+
+#define ORIG_X                 (screen_info.orig_x)
+#define ORIG_Y                 (screen_info.orig_y)
+#define ORIG_VIDEO_MODE                (screen_info.orig_video_mode)
+#define ORIG_VIDEO_COLS        (screen_info.orig_video_cols)
+#define ORIG_VIDEO_EGA_BX      (screen_info.orig_video_ega_bx)
+#define ORIG_VIDEO_LINES       (screen_info.orig_video_lines)
+#define ORIG_VIDEO_ISVGA       (screen_info.orig_video_isVGA)
+#define ORIG_VIDEO_POINTS       (screen_info.orig_video_points)
+#endif /* __KERNEL__ */
+
 #endif /* _SCREEN_INFO_H */
index 9b0b63c50f445717c8645962c7a06c77042115d6..ac050830a873b044ba1d23144c88fb99a975c934 100644 (file)
 #include <linux/xfrm.h>
 #include <net/flow.h>
 
+/*
+ * Bounding set
+ */
+extern kernel_cap_t cap_bset;
+
+extern unsigned securebits;
+
 struct ctl_table;
 
 /*
@@ -825,9 +832,11 @@ struct request_sock;
  *     incoming sk_buff @skb has been associated with a particular socket, @sk.
  *     @sk contains the sock (not socket) associated with the incoming sk_buff.
  *     @skb contains the incoming network data.
- * @socket_getpeersec:
+ * @socket_getpeersec_stream:
  *     This hook allows the security module to provide peer socket security
- *     state to userspace via getsockopt SO_GETPEERSEC.
+ *     state for unix or connected tcp sockets to userspace via getsockopt
+ *     SO_GETPEERSEC.  For tcp sockets this can be meaningful if the
+ *     socket is associated with an ipsec SA.
  *     @sock is the local socket.
  *     @optval userspace memory where the security state is to be copied.
  *     @optlen userspace int where the module should copy the actual length
@@ -836,6 +845,17 @@ struct request_sock;
  *     by the caller.
  *     Return 0 if all is well, otherwise, typical getsockopt return
  *     values.
+ * @socket_getpeersec_dgram:
+ *     This hook allows the security module to provide peer socket security
+ *     state for udp sockets on a per-packet basis to userspace via
+ *     getsockopt SO_GETPEERSEC.  The application must first have indicated
+ *     the IP_PASSSEC option via getsockopt.  It can then retrieve the
+ *     security state returned by this hook for a packet via the SCM_SECURITY
+ *     ancillary message type.
+ *     @skb is the skbuff for the packet being queried
+ *     @secdata is a pointer to a buffer in which to copy the security data
+ *     @seclen is the maximum length for @secdata
+ *     Return 0 on success, error on failure.
  * @sk_alloc_security:
  *      Allocate and attach a security structure to the sk->sk_security field,
  *      which is used to copy security attributes between local stream sockets.
index 9aaffb0b1d81e9ebfee3c9731209a23fac42223e..c8eaad9e4b72afacb1725204abbda308df0b3d45 100644 (file)
@@ -90,7 +90,6 @@ struct sem {
 /* One sem_array data structure for each set of semaphores in the system. */
 struct sem_array {
        struct kern_ipc_perm    sem_perm;       /* permissions .. see ipc.h */
-       int                     sem_id;
        time_t                  sem_otime;      /* last semop time */
        time_t                  sem_ctime;      /* last change time */
        struct sem              *sem_base;      /* ptr to first semaphore in array */
index bea65d9c93ef1c9da525bf5c6fb79a206f2e51f7..eeaed921a1dc02d02f3a61cec5ea0c62873ecfad 100644 (file)
@@ -79,7 +79,6 @@ struct shmid_kernel /* private to the kernel */
 {      
        struct kern_ipc_perm    shm_perm;
        struct file *           shm_file;
-       int                     id;
        unsigned long           shm_nattch;
        unsigned long           shm_segsz;
        time_t                  shm_atim;
index f93f22b3d2ffabf991c0f4f44c4d3f6076f4f4f3..fd4e12f24270d608951328fec3c09ed791188893 100644 (file)
@@ -41,8 +41,7 @@
 #define SKB_DATA_ALIGN(X)      (((X) + (SMP_CACHE_BYTES - 1)) & \
                                 ~(SMP_CACHE_BYTES - 1))
 #define SKB_WITH_OVERHEAD(X)   \
-       (((X) - sizeof(struct skb_shared_info)) & \
-        ~(SMP_CACHE_BYTES - 1))
+       ((X) - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
 #define SKB_MAX_ORDER(X, ORDER) \
        SKB_WITH_OVERHEAD((PAGE_SIZE << (ORDER)) - (X))
 #define SKB_MAX_HEAD(X)                (SKB_MAX_ORDER((X), 0))
@@ -301,8 +300,9 @@ struct sk_buff {
 #endif
 
        int                     iif;
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
        __u16                   queue_mapping;
-
+#endif
 #ifdef CONFIG_NET_SCHED
        __u16                   tc_index;       /* traffic control index */
 #ifdef CONFIG_NET_CLS_ACT
@@ -1770,6 +1770,15 @@ static inline void skb_set_queue_mapping(struct sk_buff *skb, u16 queue_mapping)
 #endif
 }
 
+static inline u16 skb_get_queue_mapping(struct sk_buff *skb)
+{
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+       return skb->queue_mapping;
+#else
+       return 0;
+#endif
+}
+
 static inline void skb_copy_queue_mapping(struct sk_buff *to, const struct sk_buff *from)
 {
 #ifdef CONFIG_NETDEVICES_MULTIQUEUE
index f852e1afd65a74ee34400b7bc4d9ef668d38a62c..c22ef1c1afb803e651a2b656a0add216e5d98590 100644 (file)
@@ -291,6 +291,7 @@ struct ucred {
 #define SOL_TIPC       271
 #define SOL_RXRPC      272
 #define SOL_PPPOL2TP   273
+#define SOL_BLUETOOTH  274
 
 /* IPX options */
 #define IPX_TYPE       1
index 388cace9751f06b9ee9496e2824a79e4bb9d839f..4360e0816956e536d929d7fffd23fedaab14fd46 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _LINUX_SWSUSP_H
-#define _LINUX_SWSUSP_H
+#ifndef _LINUX_SUSPEND_H
+#define _LINUX_SUSPEND_H
 
 #if defined(CONFIG_X86) || defined(CONFIG_FRV) || defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
 #include <asm/suspend.h>
@@ -9,6 +9,108 @@
 #include <linux/init.h>
 #include <linux/pm.h>
 #include <linux/mm.h>
+#include <asm/errno.h>
+
+#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE)
+extern int pm_prepare_console(void);
+extern void pm_restore_console(void);
+#else
+static inline int pm_prepare_console(void) { return 0; }
+static inline void pm_restore_console(void) {}
+#endif
+
+typedef int __bitwise suspend_state_t;
+
+#define PM_SUSPEND_ON          ((__force suspend_state_t) 0)
+#define PM_SUSPEND_STANDBY     ((__force suspend_state_t) 1)
+#define PM_SUSPEND_MEM         ((__force suspend_state_t) 3)
+#define PM_SUSPEND_MAX         ((__force suspend_state_t) 4)
+
+/**
+ * struct platform_suspend_ops - Callbacks for managing platform dependent
+ *     system sleep states.
+ *
+ * @valid: Callback to determine if given system sleep state is supported by
+ *     the platform.
+ *     Valid (ie. supported) states are advertised in /sys/power/state.  Note
+ *     that it still may be impossible to enter given system sleep state if the
+ *     conditions aren't right.
+ *     There is the %suspend_valid_only_mem function available that can be
+ *     assigned to this if the platform only supports mem sleep.
+ *
+ * @set_target: Tell the platform which system sleep state is going to be
+ *     entered.
+ *     @set_target() is executed right prior to suspending devices.  The
+ *     information conveyed to the platform code by @set_target() should be
+ *     disregarded by the platform as soon as @finish() is executed and if
+ *     @prepare() fails.  If @set_target() fails (ie. returns nonzero),
+ *     @prepare(), @enter() and @finish() will not be called by the PM core.
+ *     This callback is optional.  However, if it is implemented, the argument
+ *     passed to @enter() is meaningless and should be ignored.
+ *
+ * @prepare: Prepare the platform for entering the system sleep state indicated
+ *     by @set_target().
+ *     @prepare() is called right after devices have been suspended (ie. the
+ *     appropriate .suspend() method has been executed for each device) and
+ *     before the nonboot CPUs are disabled (it is executed with IRQs enabled).
+ *     This callback is optional.  It returns 0 on success or a negative
+ *     error code otherwise, in which case the system cannot enter the desired
+ *     sleep state (@enter() and @finish() will not be called in that case).
+ *
+ * @enter: Enter the system sleep state indicated by @set_target() or
+ *     represented by the argument if @set_target() is not implemented.
+ *     This callback is mandatory.  It returns 0 on success or a negative
+ *     error code otherwise, in which case the system cannot enter the desired
+ *     sleep state.
+ *
+ * @finish: Called when the system has just left a sleep state, right after
+ *     the nonboot CPUs have been enabled and before devices are resumed (it is
+ *     executed with IRQs enabled).
+ *     This callback is optional, but should be implemented by the platforms
+ *     that implement @prepare().  If implemented, it is always called after
+ *     @enter() (even if @enter() fails).
+ */
+struct platform_suspend_ops {
+       int (*valid)(suspend_state_t state);
+       int (*set_target)(suspend_state_t state);
+       int (*prepare)(void);
+       int (*enter)(suspend_state_t state);
+       void (*finish)(void);
+};
+
+#ifdef CONFIG_SUSPEND
+/**
+ * suspend_set_ops - set platform dependent suspend operations
+ * @ops: The new suspend operations to set.
+ */
+extern void suspend_set_ops(struct platform_suspend_ops *ops);
+extern int suspend_valid_only_mem(suspend_state_t state);
+
+/**
+ * arch_suspend_disable_irqs - disable IRQs for suspend
+ *
+ * Disables IRQs (in the default case). This is a weak symbol in the common
+ * code and thus allows architectures to override it if more needs to be
+ * done. Not called for suspend to disk.
+ */
+extern void arch_suspend_disable_irqs(void);
+
+/**
+ * arch_suspend_enable_irqs - enable IRQs after suspend
+ *
+ * Enables IRQs (in the default case). This is a weak symbol in the common
+ * code and thus allows architectures to override it if more needs to be
+ * done. Not called for suspend to disk.
+ */
+extern void arch_suspend_enable_irqs(void);
+
+extern int pm_suspend(suspend_state_t state);
+#else /* !CONFIG_SUSPEND */
+#define suspend_valid_only_mem NULL
+
+static inline void suspend_set_ops(struct platform_suspend_ops *ops) {}
+static inline int pm_suspend(suspend_state_t state) { return -ENOSYS; }
+#endif /* !CONFIG_SUSPEND */
 
 /* struct pbe is used for creating lists of pages that should be restored
  * atomically during the resume from disk, because the page frames they have
@@ -24,32 +126,57 @@ struct pbe {
 extern void drain_local_pages(void);
 extern void mark_free_pages(struct zone *zone);
 
-#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE)
-extern int pm_prepare_console(void);
-extern void pm_restore_console(void);
-#else
-static inline int pm_prepare_console(void) { return 0; }
-static inline void pm_restore_console(void) {}
-#endif
-
 /**
- * struct hibernation_ops - hibernation platform support
+ * struct platform_hibernation_ops - hibernation platform support
  *
  * The methods in this structure allow a platform to override the default
  * mechanism of shutting down the machine during a hibernation transition.
  *
  * All three methods must be assigned.
  *
- * @prepare: prepare system for hibernation
- * @enter: shut down system after state has been saved to disk
- * @finish: finish/clean up after state has been reloaded
- * @pre_restore: prepare system for the restoration from a hibernation image
- * @restore_cleanup: clean up after a failing image restoration
+ * @start: Tell the platform driver that we're starting hibernation.
+ *     Called right after shrinking memory and before freezing devices.
+ *
+ * @pre_snapshot: Prepare the platform for creating the hibernation image.
+ *     Called right after devices have been frozen and before the nonboot
+ *     CPUs are disabled (runs with IRQs on).
+ *
+ * @finish: Restore the previous state of the platform after the hibernation
+ *     image has been created *or* put the platform into the normal operation
+ *     mode after the hibernation (the same method is executed in both cases).
+ *     Called right after the nonboot CPUs have been enabled and before
+ *     thawing devices (runs with IRQs on).
+ *
+ * @prepare: Prepare the platform for entering the low power state.
+ *     Called right after the hibernation image has been saved and before
+ *     devices are prepared for entering the low power state.
+ *
+ * @enter: Put the system into the low power state after the hibernation image
+ *     has been saved to disk.
+ *     Called after the nonboot CPUs have been disabled and all of the low
+ *     level devices have been shut down (runs with IRQs off).
+ *
+ * @leave: Perform the first stage of the cleanup after the system sleep state
+ *     indicated by @set_target() has been left.
+ *     Called right after the control has been passed from the boot kernel to
+ *     the image kernel, before the nonboot CPUs are enabled and before devices
+ *     are resumed.  Executed with interrupts disabled.
+ *
+ * @pre_restore: Prepare system for the restoration from a hibernation image.
+ *     Called right after devices have been frozen and before the nonboot
+ *     CPUs are disabled (runs with IRQs on).
+ *
+ * @restore_cleanup: Clean up after a failing image restoration.
+ *     Called right after the nonboot CPUs have been enabled and before
+ *     thawing devices (runs with IRQs on).
  */
-struct hibernation_ops {
+struct platform_hibernation_ops {
+       int (*start)(void);
+       int (*pre_snapshot)(void);
+       void (*finish)(void);
        int (*prepare)(void);
        int (*enter)(void);
-       void (*finish)(void);
+       void (*leave)(void);
        int (*pre_restore)(void);
        void (*restore_cleanup)(void);
 };
@@ -70,14 +197,14 @@ extern void swsusp_set_page_free(struct page *);
 extern void swsusp_unset_page_free(struct page *);
 extern unsigned long get_safe_page(gfp_t gfp_mask);
 
-extern void hibernation_set_ops(struct hibernation_ops *ops);
+extern void hibernation_set_ops(struct platform_hibernation_ops *ops);
 extern int hibernate(void);
 #else /* CONFIG_HIBERNATION */
 static inline int swsusp_page_is_forbidden(struct page *p) { return 0; }
 static inline void swsusp_set_page_free(struct page *p) {}
 static inline void swsusp_unset_page_free(struct page *p) {}
 
-static inline void hibernation_set_ops(struct hibernation_ops *ops) {}
+static inline void hibernation_set_ops(struct platform_hibernation_ops *ops) {}
 static inline int hibernate(void) { return -ENOSYS; }
 #endif /* CONFIG_HIBERNATION */
 
@@ -130,4 +257,4 @@ static inline void register_nosave_region_late(unsigned long b, unsigned long e)
 }
 #endif
 
-#endif /* _LINUX_SWSUSP_H */
+#endif /* _LINUX_SUSPEND_H */
index 483050c924c305038a96cbcc4985f3f25b3cfe42..e99171f01b4cf482c2cd8720dea2f0921c08b4e2 100644 (file)
@@ -238,6 +238,7 @@ enum
        NET_LLC=18,
        NET_NETFILTER=19,
        NET_DCCP=20,
+       NET_IRDA=412,
 };
 
 /* /proc/sys/kernel/random */
@@ -795,6 +796,25 @@ enum {
        NET_BRIDGE_NF_FILTER_PPPOE_TAGGED = 5,
 };
 
+/* proc/sys/net/irda */
+enum {
+       NET_IRDA_DISCOVERY=1,
+       NET_IRDA_DEVNAME=2,
+       NET_IRDA_DEBUG=3,
+       NET_IRDA_FAST_POLL=4,
+       NET_IRDA_DISCOVERY_SLOTS=5,
+       NET_IRDA_DISCOVERY_TIMEOUT=6,
+       NET_IRDA_SLOT_TIMEOUT=7,
+       NET_IRDA_MAX_BAUD_RATE=8,
+       NET_IRDA_MIN_TX_TURN_TIME=9,
+       NET_IRDA_MAX_TX_DATA_SIZE=10,
+       NET_IRDA_MAX_TX_WINDOW=11,
+       NET_IRDA_MAX_NOREPLY_TIME=12,
+       NET_IRDA_WARN_NOREPLY_TIME=13,
+       NET_IRDA_LAP_KEEPALIVE_TIME=14,
+};
+
+
 /* CTL_FS names: */
 enum
 {
@@ -937,41 +957,42 @@ extern int sysctl_perm(struct ctl_table *table, int op);
 
 typedef struct ctl_table ctl_table;
 
-typedef int ctl_handler (ctl_table *table, int __user *name, int nlen,
+typedef int ctl_handler (struct ctl_table *table, int __user *name, int nlen,
                         void __user *oldval, size_t __user *oldlenp,
                         void __user *newval, size_t newlen);
 
-typedef int proc_handler (ctl_table *ctl, int write, struct file * filp,
+typedef int proc_handler (struct ctl_table *ctl, int write, struct file * filp,
                          void __user *buffer, size_t *lenp, loff_t *ppos);
 
-extern int proc_dostring(ctl_table *, int, struct file *,
+extern int proc_dostring(struct ctl_table *, int, struct file *,
                         void __user *, size_t *, loff_t *);
-extern int proc_dointvec(ctl_table *, int, struct file *,
+extern int proc_dointvec(struct ctl_table *, int, struct file *,
                         void __user *, size_t *, loff_t *);
-extern int proc_dointvec_bset(ctl_table *, int, struct file *,
+extern int proc_dointvec_bset(struct ctl_table *, int, struct file *,
                              void __user *, size_t *, loff_t *);
-extern int proc_dointvec_minmax(ctl_table *, int, struct file *,
+extern int proc_dointvec_minmax(struct ctl_table *, int, struct file *,
                                void __user *, size_t *, loff_t *);
-extern int proc_dointvec_jiffies(ctl_table *, int, struct file *,
+extern int proc_dointvec_jiffies(struct ctl_table *, int, struct file *,
                                 void __user *, size_t *, loff_t *);
-extern int proc_dointvec_userhz_jiffies(ctl_table *, int, struct file *,
+extern int proc_dointvec_userhz_jiffies(struct ctl_table *, int, struct file *,
                                        void __user *, size_t *, loff_t *);
-extern int proc_dointvec_ms_jiffies(ctl_table *, int, struct file *,
+extern int proc_dointvec_ms_jiffies(struct ctl_table *, int, struct file *,
                                    void __user *, size_t *, loff_t *);
-extern int proc_doulongvec_minmax(ctl_table *, int, struct file *,
+extern int proc_doulongvec_minmax(struct ctl_table *, int, struct file *,
                                  void __user *, size_t *, loff_t *);
-extern int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int,
+extern int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int,
                                      struct file *, void __user *, size_t *, loff_t *);
 
 extern int do_sysctl (int __user *name, int nlen,
                      void __user *oldval, size_t __user *oldlenp,
                      void __user *newval, size_t newlen);
 
-extern int do_sysctl_strategy (ctl_table *table, 
+extern int do_sysctl_strategy (struct ctl_table *table,
                               int __user *name, int nlen,
                               void __user *oldval, size_t __user *oldlenp,
                               void __user *newval, size_t newlen);
 
+extern ctl_handler sysctl_data;
 extern ctl_handler sysctl_string;
 extern ctl_handler sysctl_intvec;
 extern ctl_handler sysctl_jiffies;
@@ -980,7 +1001,7 @@ extern ctl_handler sysctl_ms_jiffies;
 
 /*
  * Register a set of sysctl names by calling register_sysctl_table
- * with an initialised array of ctl_table's.  An entry with zero
+ * with an initialised array of struct ctl_table's.  An entry with zero
  * ctl_name and NULL procname terminates the table.  table->de will be
  * set up by the registration and need not be initialised in advance.
  *
@@ -1026,8 +1047,8 @@ struct ctl_table
        void *data;
        int maxlen;
        mode_t mode;
-       ctl_table *child;
-       ctl_table *parent;              /* Automatically set */
+       struct ctl_table *child;
+       struct ctl_table *parent;       /* Automatically set */
        proc_handler *proc_handler;     /* Callback for text formatting */
        ctl_handler *strategy;          /* Callback function for all r/w */
        void *extra1;
@@ -1035,18 +1056,19 @@ struct ctl_table
 };
 
 /* struct ctl_table_header is used to maintain dynamic lists of
-   ctl_table trees. */
+   struct ctl_table trees. */
 struct ctl_table_header
 {
-       ctl_table *ctl_table;
+       struct ctl_table *ctl_table;
        struct list_head ctl_entry;
        int used;
        struct completion *unregistering;
 };
 
-struct ctl_table_header * register_sysctl_table(ctl_table * table);
+struct ctl_table_header *register_sysctl_table(struct ctl_table * table);
 
 void unregister_sysctl_table(struct ctl_table_header * table);
+int sysctl_check_table(struct ctl_table *table);
 
 #else /* __KERNEL__ */
 
index dce1ed2049727a9b7a3576abc0c075440bc121e6..5d69c0744fff60283c74fbd4ca7a8c28ee4715cf 100644 (file)
@@ -31,7 +31,7 @@
  */
 
 
-#define TASKSTATS_VERSION      5
+#define TASKSTATS_VERSION      6
 #define TS_COMM_LEN            32      /* should be >= TASK_COMM_LEN
                                         * in linux/sched.h */
 
@@ -152,6 +152,11 @@ struct taskstats {
 
        __u64  nvcsw;                   /* voluntary_ctxt_switches */
        __u64  nivcsw;                  /* nonvoluntary_ctxt_switches */
+
+       /* time accounting for SMT machines */
+       __u64   ac_utimescaled;         /* utime scaled on frequency etc */
+       __u64   ac_stimescaled;         /* stime scaled on frequency etc */
+       __u64   cpu_scaled_run_real_total; /* scaled cpu_run_real_total */
 };
 
 
index 9a7252e089b96a56175c0fb38990efbda3e84e50..f4a1395e05ff368d7bd9b807e6ed05e3859f50f7 100644 (file)
@@ -40,6 +40,7 @@ enum tick_nohz_mode {
  * @idle_sleeps:       Number of idle calls, where the sched tick was stopped
  * @idle_entrytime:    Time when the idle call was entered
  * @idle_sleeptime:    Sum of the time slept in idle with sched tick stopped
+ * @sleep_length:      Duration of the current idle sleep
  */
 struct tick_sched {
        struct hrtimer                  sched_timer;
@@ -52,6 +53,7 @@ struct tick_sched {
        unsigned long                   idle_sleeps;
        ktime_t                         idle_entrytime;
        ktime_t                         idle_sleeptime;
+       ktime_t                         sleep_length;
        unsigned long                   last_jiffies;
        unsigned long                   next_jiffies;
        ktime_t                         idle_expires;
@@ -100,10 +102,17 @@ static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
 extern void tick_nohz_stop_sched_tick(void);
 extern void tick_nohz_restart_sched_tick(void);
 extern void tick_nohz_update_jiffies(void);
+extern ktime_t tick_nohz_get_sleep_length(void);
 # else
 static inline void tick_nohz_stop_sched_tick(void) { }
 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;
+}
 # endif /* !NO_HZ */
 
 #endif
index 0351bf2fac85779839842a60ae8012e3fbaf81c6..4f0dad21c91702a86acdcd22ca1b556e84ed1203 100644 (file)
@@ -3,12 +3,9 @@
 
 #ifdef __KERNEL__
 
-#define BITS_TO_LONGS(bits) \
-       (((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)
 #define DECLARE_BITMAP(name,bits) \
        unsigned long name[BITS_TO_LONGS(bits)]
 
-#define BITS_PER_BYTE 8
 #endif
 
 #include <linux/posix_types.h>
index a6c1e8eed2265e914f90b6611902974eed726fa0..15ddd4483b09b9b94b47a9130bc0579c31468c74 100644 (file)
@@ -162,10 +162,6 @@ struct uinput_ff_erase {
 #define UI_FF_UPLOAD           1
 #define UI_FF_ERASE            2
 
-#ifndef NBITS
-#define NBITS(x) ((((x)-1)/(sizeof(long)*8))+1)
-#endif /* NBITS */
-
 #define UINPUT_MAX_NAME_SIZE   80
 struct uinput_user_dev {
        char name[UINPUT_MAX_NAME_SIZE];
index 8dba97a291f67dda20e69bd7d35f11a43881587b..52e3d5fd5be45438193873ff938c5871b1890f39 100644 (file)
@@ -294,48 +294,6 @@ struct video_code
 #define VID_PLAY_RESET                 13
 #define VID_PLAY_END_MARK              14
 
-
-
-#define VID_HARDWARE_BT848     1
-#define VID_HARDWARE_QCAM_BW   2
-#define VID_HARDWARE_PMS       3
-#define VID_HARDWARE_QCAM_C    4
-#define VID_HARDWARE_PSEUDO    5
-#define VID_HARDWARE_SAA5249   6
-#define VID_HARDWARE_AZTECH    7
-#define VID_HARDWARE_SF16MI    8
-#define VID_HARDWARE_RTRACK    9
-#define VID_HARDWARE_ZOLTRIX   10
-#define VID_HARDWARE_SAA7146    11
-#define VID_HARDWARE_VIDEUM    12      /* Reserved for Winnov videum */
-#define VID_HARDWARE_RTRACK2   13
-#define VID_HARDWARE_PERMEDIA2 14      /* Reserved for Permedia2 */
-#define VID_HARDWARE_RIVA128   15      /* Reserved for RIVA 128 */
-#define VID_HARDWARE_PLANB     16      /* PowerMac motherboard video-in */
-#define VID_HARDWARE_BROADWAY  17      /* Broadway project */
-#define VID_HARDWARE_GEMTEK    18
-#define VID_HARDWARE_TYPHOON   19
-#define VID_HARDWARE_VINO      20      /* SGI Indy Vino */
-#define VID_HARDWARE_CADET     21      /* Cadet radio */
-#define VID_HARDWARE_TRUST     22      /* Trust FM Radio */
-#define VID_HARDWARE_TERRATEC  23      /* TerraTec ActiveRadio */
-#define VID_HARDWARE_CPIA      24
-#define VID_HARDWARE_ZR36120   25      /* Zoran ZR36120/ZR36125 */
-#define VID_HARDWARE_ZR36067   26      /* Zoran ZR36067/36060 */
-#define VID_HARDWARE_OV511     27
-#define VID_HARDWARE_ZR356700  28      /* Zoran 36700 series */
-#define VID_HARDWARE_W9966     29
-#define VID_HARDWARE_SE401     30      /* SE401 USB webcams */
-#define VID_HARDWARE_PWC       31      /* Philips webcams */
-#define VID_HARDWARE_MEYE      32      /* Sony Vaio MotionEye cameras */
-#define VID_HARDWARE_CPIA2     33
-#define VID_HARDWARE_VICAM      34
-#define VID_HARDWARE_SF16FMR2  35
-#define VID_HARDWARE_W9968CF   36
-#define VID_HARDWARE_SAA7114H   37
-#define VID_HARDWARE_SN9C102   38
-#define VID_HARDWARE_ARV       39
-
 #endif /* CONFIG_VIDEO_V4L1_COMPAT */
 
 #endif /* __LINUX_VIDEODEV_H */
index 1f503e94eff1491f6a9d98bc92a3e970c226d00f..439474f24e34b63f568828ea76ed5614b34afd9b 100644 (file)
@@ -441,94 +441,6 @@ struct v4l2_timecode
 #define V4L2_TC_USERBITS_8BITCHARS     0x0008
 /* The above is based on SMPTE timecodes */
 
-#ifdef __KERNEL__
-/*
- *     M P E G   C O M P R E S S I O N   P A R A M E T E R S
- *
- *  ### WARNING: This experimental MPEG compression API is obsolete.
- *  ###          It is replaced by the MPEG controls API.
- *  ###          This old API will disappear in the near future!
- *
- */
-enum v4l2_bitrate_mode {
-       V4L2_BITRATE_NONE = 0,  /* not specified */
-       V4L2_BITRATE_CBR,       /* constant bitrate */
-       V4L2_BITRATE_VBR,       /* variable bitrate */
-};
-struct v4l2_bitrate {
-       /* rates are specified in kbit/sec */
-       enum v4l2_bitrate_mode  mode;
-       __u32                   min;
-       __u32                   target;  /* use this one for CBR */
-       __u32                   max;
-};
-
-enum v4l2_mpeg_streamtype {
-       V4L2_MPEG_SS_1,         /* MPEG-1 system stream */
-       V4L2_MPEG_PS_2,         /* MPEG-2 program stream */
-       V4L2_MPEG_TS_2,         /* MPEG-2 transport stream */
-       V4L2_MPEG_PS_DVD,       /* MPEG-2 program stream with DVD header fixups */
-};
-enum v4l2_mpeg_audiotype {
-       V4L2_MPEG_AU_2_I,       /* MPEG-2 layer 1 */
-       V4L2_MPEG_AU_2_II,      /* MPEG-2 layer 2 */
-       V4L2_MPEG_AU_2_III,     /* MPEG-2 layer 3 */
-       V4L2_MPEG_AC3,          /* AC3 */
-       V4L2_MPEG_LPCM,         /* LPCM */
-};
-enum v4l2_mpeg_videotype {
-       V4L2_MPEG_VI_1,         /* MPEG-1 */
-       V4L2_MPEG_VI_2,         /* MPEG-2 */
-};
-enum v4l2_mpeg_aspectratio {
-       V4L2_MPEG_ASPECT_SQUARE = 1,   /* square pixel */
-       V4L2_MPEG_ASPECT_4_3    = 2,   /*  4 : 3       */
-       V4L2_MPEG_ASPECT_16_9   = 3,   /* 16 : 9       */
-       V4L2_MPEG_ASPECT_1_221  = 4,   /*  1 : 2,21    */
-};
-
-struct v4l2_mpeg_compression {
-       /* general */
-       enum v4l2_mpeg_streamtype       st_type;
-       struct v4l2_bitrate             st_bitrate;
-
-       /* transport streams */
-       __u16                           ts_pid_pmt;
-       __u16                           ts_pid_audio;
-       __u16                           ts_pid_video;
-       __u16                           ts_pid_pcr;
-
-       /* program stream */
-       __u16                           ps_size;
-       __u16                           reserved_1;    /* align */
-
-       /* audio */
-       enum v4l2_mpeg_audiotype        au_type;
-       struct v4l2_bitrate             au_bitrate;
-       __u32                           au_sample_rate;
-       __u8                            au_pesid;
-       __u8                            reserved_2[3]; /* align */
-
-       /* video */
-       enum v4l2_mpeg_videotype        vi_type;
-       enum v4l2_mpeg_aspectratio      vi_aspect_ratio;
-       struct v4l2_bitrate             vi_bitrate;
-       __u32                           vi_frame_rate;
-       __u16                           vi_frames_per_gop;
-       __u16                           vi_bframes_count;
-       __u8                            vi_pesid;
-       __u8                            reserved_3[3]; /* align */
-
-       /* misc flags */
-       __u32                           closed_gops:1;
-       __u32                           pulldown:1;
-       __u32                           reserved_4:30; /* align */
-
-       /* I don't expect the above being perfect yet ;) */
-       __u32                           reserved_5[8];
-};
-#endif
-
 struct v4l2_jpegcompression
 {
        int quality;
@@ -1420,10 +1332,6 @@ struct v4l2_chip_ident {
 #define VIDIOC_ENUM_FMT         _IOWR ('V',  2, struct v4l2_fmtdesc)
 #define VIDIOC_G_FMT           _IOWR ('V',  4, struct v4l2_format)
 #define VIDIOC_S_FMT           _IOWR ('V',  5, struct v4l2_format)
-#ifdef __KERNEL__
-#define VIDIOC_G_MPEGCOMP       _IOR  ('V',  6, struct v4l2_mpeg_compression)
-#define VIDIOC_S_MPEGCOMP      _IOW  ('V',  7, struct v4l2_mpeg_compression)
-#endif
 #define VIDIOC_REQBUFS         _IOWR ('V',  8, struct v4l2_requestbuffers)
 #define VIDIOC_QUERYBUF                _IOWR ('V',  9, struct v4l2_buffer)
 #define VIDIOC_G_FBUF          _IOR  ('V', 10, struct v4l2_framebuffer)
diff --git a/include/linux/virtio.h b/include/linux/virtio.h
new file mode 100644 (file)
index 0000000..14e1379
--- /dev/null
@@ -0,0 +1,110 @@
+#ifndef _LINUX_VIRTIO_H
+#define _LINUX_VIRTIO_H
+/* Everything a virtio driver needs to work with any particular virtio
+ * implementation. */
+#include <linux/types.h>
+#include <linux/scatterlist.h>
+#include <linux/spinlock.h>
+#include <linux/device.h>
+#include <linux/mod_devicetable.h>
+
+/**
+ * virtqueue - a queue to register buffers for sending or receiving.
+ * @callback: the function to call when buffers are consumed (can be NULL).
+ *    If this returns false, callbacks are suppressed until vq_ops->restart
+ *    is called.
+ * @vdev: the virtio device this queue was created for.
+ * @vq_ops: the operations for this virtqueue (see below).
+ * @priv: a pointer for the virtqueue implementation to use.
+ */
+struct virtqueue
+{
+       bool (*callback)(struct virtqueue *vq);
+       struct virtio_device *vdev;
+       struct virtqueue_ops *vq_ops;
+       void *priv;
+};
+
+/**
+ * virtqueue_ops - operations for virtqueue abstraction layer
+ * @add_buf: expose buffer to other end
+ *     vq: the struct virtqueue we're talking about.
+ *     sg: the description of the buffer(s).
+ *     out_num: the number of sg readable by other side
+ *     in_num: the number of sg which are writable (after readable ones)
+ *     data: the token identifying the buffer.
+ *      Returns 0 or an error.
+ * @kick: update after add_buf
+ *     vq: the struct virtqueue
+ *     After one or more add_buf calls, invoke this to kick the other side.
+ * @get_buf: get the next used buffer
+ *     vq: the struct virtqueue we're talking about.
+ *     len: the length written into the buffer
+ *     Returns NULL or the "data" token handed to add_buf.
+ * @restart: restart callbacks after callback returned false.
+ *     vq: the struct virtqueue we're talking about.
+ *     This returns "false" (and doesn't re-enable) if there are pending
+ *     buffers in the queue, to avoid a race.
+ * @shutdown: "unadd" all buffers.
+ *     vq: the struct virtqueue we're talking about.
+ *     Remove everything from the queue.
+ *
+ * Locking rules are straightforward: the driver is responsible for
+ * locking.  No two operations may be invoked simultaneously.
+ *
+ * All operations can be called in any context.
+ */
+struct virtqueue_ops {
+       int (*add_buf)(struct virtqueue *vq,
+                      struct scatterlist sg[],
+                      unsigned int out_num,
+                      unsigned int in_num,
+                      void *data);
+
+       void (*kick)(struct virtqueue *vq);
+
+       void *(*get_buf)(struct virtqueue *vq, unsigned int *len);
+
+       bool (*restart)(struct virtqueue *vq);
+
+       void (*shutdown)(struct virtqueue *vq);
+};
+
+/**
+ * virtio_device - representation of a device using virtio
+ * @index: unique position on the virtio bus
+ * @dev: underlying device.
+ * @id: the device type identification (used to match it with a driver).
+ * @config: the configuration ops for this device.
+ * @priv: private pointer for the driver's use.
+ */
+struct virtio_device
+{
+       int index;
+       struct device dev;
+       struct virtio_device_id id;
+       struct virtio_config_ops *config;
+       void *priv;
+};
+
+int register_virtio_device(struct virtio_device *dev);
+void unregister_virtio_device(struct virtio_device *dev);
+
+/**
+ * virtio_driver - operations for a virtio I/O driver
+ * @driver: underlying device driver (populate name and owner).
+ * @id_table: the ids serviced by this driver.
+ * @probe: the function to call when a device is found.  Returns a token for
+ *    remove, or PTR_ERR().
+ * @remove: the function when a device is removed.
+ */
+struct virtio_driver {
+       struct device_driver driver;
+       const struct virtio_device_id *id_table;
+       int (*probe)(struct virtio_device *dev);
+       void (*remove)(struct virtio_device *dev);
+};
+
+int register_virtio_driver(struct virtio_driver *drv);
+void unregister_virtio_driver(struct virtio_driver *drv);
+#endif /* _LINUX_VIRTIO_H */
diff --git a/include/linux/virtio_9p.h b/include/linux/virtio_9p.h
new file mode 100644 (file)
index 0000000..8eff0b5
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef _LINUX_VIRTIO_9P_H
+#define _LINUX_VIRTIO_9P_H
+#include <linux/virtio_config.h>
+
+/* The ID for virtio console */
+#define VIRTIO_ID_9P   9
+/* Maximum number of virtio channels per partition (1 for now) */
+#define MAX_9P_CHAN    1
+
+#endif /* _LINUX_VIRTIO_9P_H */
diff --git a/include/linux/virtio_blk.h b/include/linux/virtio_blk.h
new file mode 100644 (file)
index 0000000..7bd2bce
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef _LINUX_VIRTIO_BLK_H
+#define _LINUX_VIRTIO_BLK_H
+#include <linux/virtio_config.h>
+
+/* The ID for virtio_block */
+#define VIRTIO_ID_BLOCK        2
+
+/* Feature bits */
+#define VIRTIO_CONFIG_BLK_F    0x40
+#define VIRTIO_BLK_F_BARRIER   1       /* Does host support barriers? */
+
+/* The capacity (in 512-byte sectors). */
+#define VIRTIO_CONFIG_BLK_F_CAPACITY   0x41
+/* The maximum segment size. */
+#define VIRTIO_CONFIG_BLK_F_SIZE_MAX   0x42
+/* The maximum number of segments. */
+#define VIRTIO_CONFIG_BLK_F_SEG_MAX    0x43
+
+/* These two define direction. */
+#define VIRTIO_BLK_T_IN                0
+#define VIRTIO_BLK_T_OUT       1
+
+/* This bit says it's a scsi command, not an actual read or write. */
+#define VIRTIO_BLK_T_SCSI_CMD  2
+
+/* Barrier before this op. */
+#define VIRTIO_BLK_T_BARRIER   0x80000000
+
+/* This is the first element of the read scatter-gather list. */
+struct virtio_blk_outhdr
+{
+       /* VIRTIO_BLK_T* */
+       __u32 type;
+       /* io priority. */
+       __u32 ioprio;
+       /* Sector (ie. 512 byte offset) */
+       __u64 sector;
+       /* Where to put reply. */
+       __u64 id;
+};
+
+#define VIRTIO_BLK_S_OK                0
+#define VIRTIO_BLK_S_IOERR     1
+#define VIRTIO_BLK_S_UNSUPP    2
+
+/* This is the first element of the write scatter-gather list */
+struct virtio_blk_inhdr
+{
+       unsigned char status;
+};
+#endif /* _LINUX_VIRTIO_BLK_H */
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
new file mode 100644 (file)
index 0000000..bcc0188
--- /dev/null
@@ -0,0 +1,111 @@
+#ifndef _LINUX_VIRTIO_CONFIG_H
+#define _LINUX_VIRTIO_CONFIG_H
+/* Virtio devices use a standardized configuration space to define their
+ * features and pass configuration information, but each implementation can
+ * store and access that space differently. */
+#include <linux/types.h>
+
+/* Status byte for guest to report progress, and synchronize config. */
+/* We have seen device and processed generic fields (VIRTIO_CONFIG_F_VIRTIO) */
+#define VIRTIO_CONFIG_S_ACKNOWLEDGE    1
+/* We have found a driver for the device. */
+#define VIRTIO_CONFIG_S_DRIVER         2
+/* Driver has used its parts of the config, and is happy */
+#define VIRTIO_CONFIG_S_DRIVER_OK      4
+/* We've given up on this device. */
+#define VIRTIO_CONFIG_S_FAILED         0x80
+
+/* Feature byte (actually 7 bits availabe): */
+/* Requirements/features of the virtio implementation. */
+#define VIRTIO_CONFIG_F_VIRTIO 1
+/* Requirements/features of the virtqueue (may have more than one). */
+#define VIRTIO_CONFIG_F_VIRTQUEUE 2
+
+#ifdef __KERNEL__
+struct virtio_device;
+
+/**
+ * virtio_config_ops - operations for configuring a virtio device
+ * @find: search for the next configuration field of the given type.
+ *     vdev: the virtio_device
+ *     type: the feature type
+ *     len: the (returned) length of the field if found.
+ *     Returns a token if found, or NULL.  Never returnes the same field twice
+ *     (ie. it's used up).
+ * @get: read the value of a configuration field after find().
+ *     vdev: the virtio_device
+ *     token: the token returned from find().
+ *     buf: the buffer to write the field value into.
+ *     len: the length of the buffer (given by find()).
+ *     Note that contents are conventionally little-endian.
+ * @set: write the value of a configuration field after find().
+ *     vdev: the virtio_device
+ *     token: the token returned from find().
+ *     buf: the buffer to read the field value from.
+ *     len: the length of the buffer (given by find()).
+ *     Note that contents are conventionally little-endian.
+ * @get_status: read the status byte
+ *     vdev: the virtio_device
+ *     Returns the status byte
+ * @set_status: write the status byte
+ *     vdev: the virtio_device
+ *     status: the new status byte
+ * @find_vq: find the first VIRTIO_CONFIG_F_VIRTQUEUE and create a virtqueue.
+ *     vdev: the virtio_device
+ *     callback: the virqtueue callback
+ *     Returns the new virtqueue or ERR_PTR().
+ * @del_vq: free a virtqueue found by find_vq().
+ */
+struct virtio_config_ops
+{
+       void *(*find)(struct virtio_device *vdev, u8 type, unsigned *len);
+       void (*get)(struct virtio_device *vdev, void *token,
+                   void *buf, unsigned len);
+       void (*set)(struct virtio_device *vdev, void *token,
+                   const void *buf, unsigned len);
+       u8 (*get_status)(struct virtio_device *vdev);
+       void (*set_status)(struct virtio_device *vdev, u8 status);
+       struct virtqueue *(*find_vq)(struct virtio_device *vdev,
+                                    bool (*callback)(struct virtqueue *));
+       void (*del_vq)(struct virtqueue *vq);
+};
+
+/**
+ * virtio_config_val - get a single virtio config and mark it used.
+ * @config: the virtio config space
+ * @type: the type to search for.
+ * @val: a pointer to the value to fill in.
+ *
+ * Once used, the config type is marked with VIRTIO_CONFIG_F_USED so it can't
+ * be found again.  This version does endian conversion. */
+#define virtio_config_val(vdev, type, v) ({                            \
+       int _err = __virtio_config_val((vdev),(type),(v),sizeof(*(v))); \
+                                                                       \
+       BUILD_BUG_ON(sizeof(*(v)) != 1 && sizeof(*(v)) != 2             \
+                    && sizeof(*(v)) != 4 && sizeof(*(v)) != 8);        \
+       if (!_err) {                                                    \
+               switch (sizeof(*(v))) {                                 \
+               case 2: le16_to_cpus((__u16 *) v); break;               \
+               case 4: le32_to_cpus((__u32 *) v); break;               \
+               case 8: le64_to_cpus((__u64 *) v); break;               \
+               }                                                       \
+       }                                                               \
+       _err;                                                           \
+})
+
+int __virtio_config_val(struct virtio_device *dev,
+                       u8 type, void *val, size_t size);
+
+/**
+ * virtio_use_bit - helper to use a feature bit in a bitfield value.
+ * @dev: the virtio device
+ * @token: the token as returned from vdev->config->find().
+ * @len: the length of the field.
+ * @bitnum: the bit to test.
+ *
+ * If handed a NULL token, it returns false, otherwise returns bit status.
+ * If it's one, it sets the mirroring acknowledgement bit. */
+int virtio_use_bit(struct virtio_device *vdev,
+                  void *token, unsigned int len, unsigned int bitnum);
+#endif /* __KERNEL__ */
+#endif /* _LINUX_VIRTIO_CONFIG_H */
diff --git a/include/linux/virtio_console.h b/include/linux/virtio_console.h
new file mode 100644 (file)
index 0000000..ed2d4ea
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef _LINUX_VIRTIO_CONSOLE_H
+#define _LINUX_VIRTIO_CONSOLE_H
+#include <linux/virtio_config.h>
+
+/* The ID for virtio console */
+#define VIRTIO_ID_CONSOLE      3
+
+#ifdef __KERNEL__
+int __init virtio_cons_early_init(int (*put_chars)(u32, const char *, int));
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_VIRTIO_CONSOLE_H */
diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h
new file mode 100644 (file)
index 0000000..ae469ae
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef _LINUX_VIRTIO_NET_H
+#define _LINUX_VIRTIO_NET_H
+#include <linux/virtio_config.h>
+
+/* The ID for virtio_net */
+#define VIRTIO_ID_NET  1
+
+/* The bitmap of config for virtio net */
+#define VIRTIO_CONFIG_NET_F    0x40
+#define VIRTIO_NET_F_NO_CSUM   0
+#define VIRTIO_NET_F_TSO4      1
+#define VIRTIO_NET_F_UFO       2
+#define VIRTIO_NET_F_TSO4_ECN  3
+#define VIRTIO_NET_F_TSO6      4
+
+/* The config defining mac address. */
+#define VIRTIO_CONFIG_NET_MAC_F        0x41
+
+/* This is the first element of the scatter-gather list.  If you don't
+ * specify GSO or CSUM features, you can simply ignore the header. */
+struct virtio_net_hdr
+{
+#define VIRTIO_NET_HDR_F_NEEDS_CSUM    1       // Use csum_start, csum_offset
+      __u8 flags;
+#define VIRTIO_NET_HDR_GSO_NONE                0       // Not a GSO frame
+#define VIRTIO_NET_HDR_GSO_TCPV4       1       // GSO frame, IPv4 TCP (TSO)
+/* FIXME: Do we need this?  If they said they can handle ECN, do they care? */
+#define VIRTIO_NET_HDR_GSO_TCPV4_ECN   2       // GSO frame, IPv4 TCP w/ ECN
+#define VIRTIO_NET_HDR_GSO_UDP         3       // GSO frame, IPv4 UDP (UFO)
+#define VIRTIO_NET_HDR_GSO_TCPV6       4       // GSO frame, IPv6 TCP
+      __u8 gso_type;
+      __u16 gso_size;
+      __u16 csum_start;
+      __u16 csum_offset;
+};
+#endif /* _LINUX_VIRTIO_NET_H */
diff --git a/include/linux/virtio_ring.h b/include/linux/virtio_ring.h
new file mode 100644 (file)
index 0000000..ac69e7b
--- /dev/null
@@ -0,0 +1,119 @@
+#ifndef _LINUX_VIRTIO_RING_H
+#define _LINUX_VIRTIO_RING_H
+/* An interface for efficient virtio implementation, currently for use by KVM
+ * and lguest, but hopefully others soon.  Do NOT change this since it will
+ * break existing servers and clients.
+ *
+ * This header is BSD licensed so anyone can use the definitions to implement
+ * compatible drivers/servers.
+ *
+ * Copyright Rusty Russell IBM Corporation 2007. */
+#include <linux/types.h>
+
+/* This marks a buffer as continuing via the next field. */
+#define VRING_DESC_F_NEXT      1
+/* This marks a buffer as write-only (otherwise read-only). */
+#define VRING_DESC_F_WRITE     2
+
+/* This means don't notify other side when buffer added. */
+#define VRING_USED_F_NO_NOTIFY 1
+/* This means don't interrupt guest when buffer consumed. */
+#define VRING_AVAIL_F_NO_INTERRUPT     1
+
+/* Virtio ring descriptors: 16 bytes.  These can chain together via "next". */
+struct vring_desc
+{
+       /* Address (guest-physical). */
+       __u64 addr;
+       /* Length. */
+       __u32 len;
+       /* The flags as indicated above. */
+       __u16 flags;
+       /* We chain unused descriptors via this, too */
+       __u16 next;
+};
+
+struct vring_avail
+{
+       __u16 flags;
+       __u16 idx;
+       __u16 ring[];
+};
+
+/* u32 is used here for ids for padding reasons. */
+struct vring_used_elem
+{
+       /* Index of start of used descriptor chain. */
+       __u32 id;
+       /* Total length of the descriptor chain which was used (written to) */
+       __u32 len;
+};
+
+struct vring_used
+{
+       __u16 flags;
+       __u16 idx;
+       struct vring_used_elem ring[];
+};
+
+struct vring {
+       unsigned int num;
+
+       struct vring_desc *desc;
+
+       struct vring_avail *avail;
+
+       struct vring_used *used;
+};
+
+/* The standard layout for the ring is a continuous chunk of memory which looks
+ * like this.  The used fields will be aligned to a "num+1" boundary.
+ *
+ * struct vring
+ * {
+ *     // The actual descriptors (16 bytes each)
+ *     struct vring_desc desc[num];
+ *
+ *     // A ring of available descriptor heads with free-running index.
+ *     __u16 avail_flags;
+ *     __u16 avail_idx;
+ *     __u16 available[num];
+ *
+ *     // Padding so a correctly-chosen num value will cache-align used_idx.
+ *     char pad[sizeof(struct vring_desc) - sizeof(avail_flags)];
+ *
+ *     // A ring of used descriptor heads with free-running index.
+ *     __u16 used_flags;
+ *     __u16 used_idx;
+ *     struct vring_used_elem used[num];
+ * };
+ */
+static inline void vring_init(struct vring *vr, unsigned int num, void *p)
+{
+       vr->num = num;
+       vr->desc = p;
+       vr->avail = p + num*sizeof(struct vring);
+       vr->used = p + (num+1)*(sizeof(struct vring) + sizeof(__u16));
+}
+
+static inline unsigned vring_size(unsigned int num)
+{
+       return (num + 1) * (sizeof(struct vring_desc) + sizeof(__u16))
+               + sizeof(__u32) + num * sizeof(struct vring_used_elem);
+}
+
+#ifdef __KERNEL__
+#include <linux/irqreturn.h>
+struct virtio_device;
+struct virtqueue;
+
+struct virtqueue *vring_new_virtqueue(unsigned int num,
+                                     struct virtio_device *vdev,
+                                     void *pages,
+                                     void (*notify)(struct virtqueue *vq),
+                                     bool (*callback)(struct virtqueue *vq));
+void vring_del_virtqueue(struct virtqueue *vq);
+
+irqreturn_t vring_interrupt(int irq, void *_vq);
+#endif /* __KERNEL__ */
+#endif /* _LINUX_VIRTIO_RING_H */
index ba806e8711beb42129534649e8270c9b4bd35ba9..02c1c02887703b6d044af1bc57685729cb242278 100644 (file)
@@ -1,6 +1,18 @@
 #ifndef _LINUX_VT_H
 #define _LINUX_VT_H
 
+#ifdef __KERNEL__
+struct notifier_block;
+
+struct vt_notifier_param {
+       struct vc_data *vc;     /* VC on which the update happened */
+       unsigned int c;         /* Printed char */
+};
+
+extern int register_vt_notifier(struct notifier_block *nb);
+extern int unregister_vt_notifier(struct notifier_block *nb);
+#endif
+
 /*
  * These constants are also useful for user-level apps (e.g., VC
  * resizing).
index ce6badc98f6dcb3f2b78615cd4aa382d6d956abd..7daafdc2514b9657a0e0d9d0325785cc65c934b2 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/timer.h>
 #include <linux/linkage.h>
 #include <linux/bitops.h>
+#include <linux/lockdep.h>
 #include <asm/atomic.h>
 
 struct workqueue_struct;
@@ -28,6 +29,9 @@ struct work_struct {
 #define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK)
        struct list_head entry;
        work_func_t func;
+#ifdef CONFIG_LOCKDEP
+       struct lockdep_map lockdep_map;
+#endif
 };
 
 #define WORK_DATA_INIT()       ATOMIC_LONG_INIT(0)
@@ -41,10 +45,23 @@ struct execute_work {
        struct work_struct work;
 };
 
+#ifdef CONFIG_LOCKDEP
+/*
+ * NB: because we have to copy the lockdep_map, setting _key
+ * here is required, otherwise it could get initialised to the
+ * copy of the lockdep_map!
+ */
+#define __WORK_INIT_LOCKDEP_MAP(n, k) \
+       .lockdep_map = STATIC_LOCKDEP_MAP_INIT(n, k),
+#else
+#define __WORK_INIT_LOCKDEP_MAP(n, k)
+#endif
+
 #define __WORK_INITIALIZER(n, f) {                             \
        .data = WORK_DATA_INIT(),                               \
        .entry  = { &(n).entry, &(n).entry },                   \
        .func = (f),                                            \
+       __WORK_INIT_LOCKDEP_MAP(#n, &(n))                       \
        }
 
 #define __DELAYED_WORK_INITIALIZER(n, f) {                     \
@@ -76,12 +93,24 @@ struct execute_work {
  * assignment of the work data initializer allows the compiler
  * to generate better code.
  */
+#ifdef CONFIG_LOCKDEP
+#define INIT_WORK(_work, _func)                                                \
+       do {                                                            \
+               static struct lock_class_key __key;                     \
+                                                                       \
+               (_work)->data = (atomic_long_t) WORK_DATA_INIT();       \
+               lockdep_init_map(&(_work)->lockdep_map, #_work, &__key, 0);\
+               INIT_LIST_HEAD(&(_work)->entry);                        \
+               PREPARE_WORK((_work), (_func));                         \
+       } while (0)
+#else
 #define INIT_WORK(_work, _func)                                                \
        do {                                                            \
                (_work)->data = (atomic_long_t) WORK_DATA_INIT();       \
                INIT_LIST_HEAD(&(_work)->entry);                        \
                PREPARE_WORK((_work), (_func));                         \
        } while (0)
+#endif
 
 #define INIT_DELAYED_WORK(_work, _func)                                \
        do {                                                    \
@@ -118,9 +147,23 @@ struct execute_work {
        clear_bit(WORK_STRUCT_PENDING, work_data_bits(work))
 
 
-extern struct workqueue_struct *__create_workqueue(const char *name,
-                                                   int singlethread,
-                                                   int freezeable);
+extern struct workqueue_struct *
+__create_workqueue_key(const char *name, int singlethread,
+                      int freezeable, struct lock_class_key *key);
+
+#ifdef CONFIG_LOCKDEP
+#define __create_workqueue(name, singlethread, freezeable)     \
+({                                                             \
+       static struct lock_class_key __key;                     \
+                                                               \
+       __create_workqueue_key((name), (singlethread),          \
+                              (freezeable), &__key);           \
+})
+#else
+#define __create_workqueue(name, singlethread, freezeable)     \
+       __create_workqueue_key((name), (singlethread), (freezeable), 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)
index cd3ff2c29d5e04828dc6a7d5ddb1da5f7f83fe4c..88b2b5a619aaf21ebf98811d02df6c50ef7b8e50 100644 (file)
@@ -12,6 +12,7 @@
 #include <asm/io.h>            /* for accessing devices */
 #include <linux/stringify.h>
 #include <linux/mutex.h>
+#include <linux/scatterlist.h>
 
 #include <linux/vmalloc.h>     /* for vmalloc() */
 #include <linux/mm.h>          /* for vmalloc_to_page() */
index e75d5e6c4cea083ed8429b1fe1adaa09d6e63cd9..c544c6f90893085ad4f73e664dcafdce269653da 100644 (file)
@@ -94,7 +94,6 @@ struct video_device
        char name[32];
        int type;       /* v4l1 */
        int type2;      /* v4l2 */
-       int hardware;
        int minor;
 
        int debug;      /* Activates debug level*/
@@ -272,10 +271,6 @@ struct video_device
        int (*vidioc_s_crop)           (struct file *file, void *fh,
                                        struct v4l2_crop *a);
        /* Compression ioctls */
-       int (*vidioc_g_mpegcomp)       (struct file *file, void *fh,
-                                       struct v4l2_mpeg_compression *a);
-       int (*vidioc_s_mpegcomp)       (struct file *file, void *fh,
-                                       struct v4l2_mpeg_compression *a);
        int (*vidioc_g_jpegcomp)       (struct file *file, void *fh,
                                        struct v4l2_jpegcompression *a);
        int (*vidioc_s_jpegcomp)       (struct file *file, void *fh,
index 686425a97b0f63b1be45a6b59aa2a3c5c044068c..625346c47ee2e276dd6eb413a96672bbb75014fb 100644 (file)
@@ -44,7 +44,7 @@ extern unsigned int p9_debug_level;
 do {  \
        if ((p9_debug_level & level) == level) \
                printk(KERN_NOTICE "-- %s (%d): " \
-               format , __FUNCTION__, current->pid , ## arg); \
+               format , __FUNCTION__, task_pid_nr(current) , ## arg); \
 } while (0)
 
 #define PRINT_FCALL_ERROR(s, fcall) P9_DPRINTK(P9_DEBUG_ERROR,   \
@@ -59,7 +59,7 @@ do {  \
 #define P9_EPRINTK(level, format, arg...) \
 do { \
        printk(level "9p: %s (%d): " \
-               format , __FUNCTION__, current->pid , ## arg); \
+               format , __FUNCTION__, task_pid_nr(current), ## arg); \
 } while (0)
 
 
index ebfb96b41106a0c3c7df7ac247cb3994bf1083b1..a8a9eb6af966da9726813f461f562053e25b54c6 100644 (file)
@@ -200,119 +200,18 @@ enum {
 #define HCI_LM_SECURE  0x0020
 
 /* -----  HCI Commands ---- */
-/* OGF & OCF values */
-
-/* Informational Parameters */
-#define OGF_INFO_PARAM 0x04
-
-#define OCF_READ_LOCAL_VERSION 0x0001
-struct hci_rp_read_loc_version {
-       __u8     status;
-       __u8     hci_ver;
-       __le16   hci_rev;
-       __u8     lmp_ver;
-       __le16   manufacturer;
-       __le16   lmp_subver;
-} __attribute__ ((packed));
-
-#define OCF_READ_LOCAL_FEATURES        0x0003
-struct hci_rp_read_local_features {
-       __u8 status;
-       __u8 features[8];
-} __attribute__ ((packed));
-
-#define OCF_READ_BUFFER_SIZE   0x0005
-struct hci_rp_read_buffer_size {
-       __u8     status;
-       __le16   acl_mtu;
-       __u8     sco_mtu;
-       __le16   acl_max_pkt;
-       __le16   sco_max_pkt;
-} __attribute__ ((packed));
-
-#define OCF_READ_BD_ADDR       0x0009
-struct hci_rp_read_bd_addr {
-       __u8     status;
-       bdaddr_t bdaddr;
-} __attribute__ ((packed));
-
-/* Host Controller and Baseband */
-#define OGF_HOST_CTL   0x03
-#define OCF_RESET              0x0003
-#define OCF_READ_AUTH_ENABLE   0x001F
-#define OCF_WRITE_AUTH_ENABLE  0x0020
-       #define AUTH_DISABLED           0x00
-       #define AUTH_ENABLED            0x01
-
-#define OCF_READ_ENCRYPT_MODE  0x0021
-#define OCF_WRITE_ENCRYPT_MODE 0x0022
-       #define ENCRYPT_DISABLED        0x00
-       #define ENCRYPT_P2P             0x01
-       #define ENCRYPT_BOTH            0x02
-
-#define OCF_WRITE_CA_TIMEOUT   0x0016  
-#define OCF_WRITE_PG_TIMEOUT   0x0018
-
-#define OCF_WRITE_SCAN_ENABLE  0x001A
-       #define SCAN_DISABLED           0x00
-       #define SCAN_INQUIRY            0x01
-       #define SCAN_PAGE               0x02
-
-#define OCF_SET_EVENT_FLT      0x0005
-struct hci_cp_set_event_flt {
-       __u8     flt_type;
-       __u8     cond_type;
-       __u8     condition[0];
-} __attribute__ ((packed));
-
-/* Filter types */
-#define HCI_FLT_CLEAR_ALL      0x00
-#define HCI_FLT_INQ_RESULT     0x01
-#define HCI_FLT_CONN_SETUP     0x02
-
-/* CONN_SETUP Condition types */
-#define HCI_CONN_SETUP_ALLOW_ALL       0x00
-#define HCI_CONN_SETUP_ALLOW_CLASS     0x01
-#define HCI_CONN_SETUP_ALLOW_BDADDR    0x02
-
-/* CONN_SETUP Conditions */
-#define HCI_CONN_SETUP_AUTO_OFF        0x01
-#define HCI_CONN_SETUP_AUTO_ON 0x02
-
-#define OCF_READ_CLASS_OF_DEV  0x0023
-struct hci_rp_read_dev_class {
-       __u8     status;
-       __u8     dev_class[3];
-} __attribute__ ((packed));
-
-#define OCF_WRITE_CLASS_OF_DEV 0x0024
-struct hci_cp_write_dev_class {
-       __u8     dev_class[3];
-} __attribute__ ((packed));
-
-#define OCF_READ_VOICE_SETTING 0x0025
-struct hci_rp_read_voice_setting {
-       __u8     status;
-       __le16   voice_setting;
+#define HCI_OP_INQUIRY                 0x0401
+struct hci_cp_inquiry {
+       __u8     lap[3];
+       __u8     length;
+       __u8     num_rsp;
 } __attribute__ ((packed));
 
-#define OCF_WRITE_VOICE_SETTING        0x0026
-struct hci_cp_write_voice_setting {
-       __le16   voice_setting;
-} __attribute__ ((packed));
+#define HCI_OP_INQUIRY_CANCEL          0x0402
 
-#define OCF_HOST_BUFFER_SIZE   0x0033
-struct hci_cp_host_buffer_size {
-       __le16   acl_mtu;
-       __u8     sco_mtu;
-       __le16   acl_max_pkt;
-       __le16   sco_max_pkt;
-} __attribute__ ((packed));
-
-/* Link Control */
-#define OGF_LINK_CTL   0x01 
+#define HCI_OP_EXIT_PERIODIC_INQ       0x0404
 
-#define OCF_CREATE_CONN                0x0005
+#define HCI_OP_CREATE_CONN             0x0405
 struct hci_cp_create_conn {
        bdaddr_t bdaddr;
        __le16   pkt_type;
@@ -322,105 +221,138 @@ struct hci_cp_create_conn {
        __u8     role_switch;
 } __attribute__ ((packed));
 
-#define OCF_CREATE_CONN_CANCEL 0x0008
-struct hci_cp_create_conn_cancel {
-       bdaddr_t bdaddr;
-} __attribute__ ((packed));
-
-#define OCF_ACCEPT_CONN_REQ    0x0009
-struct hci_cp_accept_conn_req {
-       bdaddr_t bdaddr;
-       __u8     role;
-} __attribute__ ((packed));
-
-#define OCF_REJECT_CONN_REQ    0x000a
-struct hci_cp_reject_conn_req {
-       bdaddr_t bdaddr;
-       __u8     reason;
-} __attribute__ ((packed));
-
-#define OCF_DISCONNECT 0x0006
+#define HCI_OP_DISCONNECT              0x0406
 struct hci_cp_disconnect {
        __le16   handle;
        __u8     reason;
 } __attribute__ ((packed));
 
-#define OCF_ADD_SCO    0x0007
+#define HCI_OP_ADD_SCO                 0x0407
 struct hci_cp_add_sco {
        __le16   handle;
        __le16   pkt_type;
 } __attribute__ ((packed));
 
-#define OCF_INQUIRY            0x0001
-struct hci_cp_inquiry {
-       __u8     lap[3];
-       __u8     length;
-       __u8     num_rsp;
+#define HCI_OP_CREATE_CONN_CANCEL      0x0408
+struct hci_cp_create_conn_cancel {
+       bdaddr_t bdaddr;
 } __attribute__ ((packed));
 
-#define OCF_INQUIRY_CANCEL     0x0002
+#define HCI_OP_ACCEPT_CONN_REQ         0x0409
+struct hci_cp_accept_conn_req {
+       bdaddr_t bdaddr;
+       __u8     role;
+} __attribute__ ((packed));
 
-#define OCF_EXIT_PERIODIC_INQ  0x0004
+#define HCI_OP_REJECT_CONN_REQ         0x040a
+struct hci_cp_reject_conn_req {
+       bdaddr_t bdaddr;
+       __u8     reason;
+} __attribute__ ((packed));
 
-#define OCF_LINK_KEY_REPLY     0x000B
+#define HCI_OP_LINK_KEY_REPLY          0x040b
 struct hci_cp_link_key_reply {
        bdaddr_t bdaddr;
        __u8     link_key[16];
 } __attribute__ ((packed));
 
-#define OCF_LINK_KEY_NEG_REPLY 0x000C
+#define HCI_OP_LINK_KEY_NEG_REPLY      0x040c
 struct hci_cp_link_key_neg_reply {
        bdaddr_t bdaddr;
 } __attribute__ ((packed));
 
-#define OCF_PIN_CODE_REPLY     0x000D
+#define HCI_OP_PIN_CODE_REPLY          0x040d
 struct hci_cp_pin_code_reply {
        bdaddr_t bdaddr;
        __u8     pin_len;
        __u8     pin_code[16];
 } __attribute__ ((packed));
 
-#define OCF_PIN_CODE_NEG_REPLY 0x000E
+#define HCI_OP_PIN_CODE_NEG_REPLY      0x040e
 struct hci_cp_pin_code_neg_reply {
        bdaddr_t bdaddr;
 } __attribute__ ((packed));
 
-#define OCF_CHANGE_CONN_PTYPE  0x000F
+#define HCI_OP_CHANGE_CONN_PTYPE       0x040f
 struct hci_cp_change_conn_ptype {
        __le16   handle;
        __le16   pkt_type;
 } __attribute__ ((packed));
 
-#define OCF_AUTH_REQUESTED     0x0011
+#define HCI_OP_AUTH_REQUESTED          0x0411
 struct hci_cp_auth_requested {
        __le16   handle;
 } __attribute__ ((packed));
 
-#define OCF_SET_CONN_ENCRYPT   0x0013
+#define HCI_OP_SET_CONN_ENCRYPT                0x0413
 struct hci_cp_set_conn_encrypt {
        __le16   handle;
        __u8     encrypt;
 } __attribute__ ((packed));
 
-#define OCF_CHANGE_CONN_LINK_KEY 0x0015
+#define HCI_OP_CHANGE_CONN_LINK_KEY    0x0415
 struct hci_cp_change_conn_link_key {
        __le16   handle;
 } __attribute__ ((packed));
 
-#define OCF_READ_REMOTE_FEATURES 0x001B
+#define HCI_OP_REMOTE_NAME_REQ         0x0419
+struct hci_cp_remote_name_req {
+       bdaddr_t bdaddr;
+       __u8     pscan_rep_mode;
+       __u8     pscan_mode;
+       __le16   clock_offset;
+} __attribute__ ((packed));
+
+#define HCI_OP_REMOTE_NAME_REQ_CANCEL  0x041a
+struct hci_cp_remote_name_req_cancel {
+       bdaddr_t bdaddr;
+} __attribute__ ((packed));
+
+#define HCI_OP_READ_REMOTE_FEATURES    0x041b
 struct hci_cp_read_remote_features {
        __le16   handle;
 } __attribute__ ((packed));
 
-#define OCF_READ_REMOTE_VERSION 0x001D
+#define HCI_OP_READ_REMOTE_EXT_FEATURES        0x041c
+struct hci_cp_read_remote_ext_features {
+       __le16   handle;
+       __u8     page;
+} __attribute__ ((packed));
+
+#define HCI_OP_READ_REMOTE_VERSION     0x041d
 struct hci_cp_read_remote_version {
        __le16   handle;
 } __attribute__ ((packed));
 
-/* Link Policy */
-#define OGF_LINK_POLICY        0x02   
+#define HCI_OP_SETUP_SYNC_CONN         0x0428
+struct hci_cp_setup_sync_conn {
+       __le16   handle;
+       __le32   tx_bandwidth;
+       __le32   rx_bandwidth;
+       __le16   max_latency;
+       __le16   voice_setting;
+       __u8     retrans_effort;
+       __le16   pkt_type;
+} __attribute__ ((packed));
 
-#define OCF_SNIFF_MODE         0x0003
+#define HCI_OP_ACCEPT_SYNC_CONN_REQ    0x0429
+struct hci_cp_accept_sync_conn_req {
+       bdaddr_t bdaddr;
+       __le32   tx_bandwidth;
+       __le32   rx_bandwidth;
+       __le16   max_latency;
+       __le16   content_format;
+       __u8     retrans_effort;
+       __le16   pkt_type;
+} __attribute__ ((packed));
+
+#define HCI_OP_REJECT_SYNC_CONN_REQ    0x042a
+struct hci_cp_reject_sync_conn_req {
+       bdaddr_t bdaddr;
+       __u8     reason;
+} __attribute__ ((packed));
+
+#define HCI_OP_SNIFF_MODE              0x0803
 struct hci_cp_sniff_mode {
        __le16   handle;
        __le16   max_interval;
@@ -429,12 +361,12 @@ struct hci_cp_sniff_mode {
        __le16   timeout;
 } __attribute__ ((packed));
 
-#define OCF_EXIT_SNIFF_MODE    0x0004
+#define HCI_OP_EXIT_SNIFF_MODE         0x0804
 struct hci_cp_exit_sniff_mode {
        __le16   handle;
 } __attribute__ ((packed));
 
-#define OCF_ROLE_DISCOVERY     0x0009
+#define HCI_OP_ROLE_DISCOVERY          0x0809
 struct hci_cp_role_discovery {
        __le16   handle;
 } __attribute__ ((packed));
@@ -444,7 +376,13 @@ struct hci_rp_role_discovery {
        __u8     role;
 } __attribute__ ((packed));
 
-#define OCF_READ_LINK_POLICY   0x000C
+#define HCI_OP_SWITCH_ROLE             0x080b
+struct hci_cp_switch_role {
+       bdaddr_t bdaddr;
+       __u8     role;
+} __attribute__ ((packed));
+
+#define HCI_OP_READ_LINK_POLICY                0x080c
 struct hci_cp_read_link_policy {
        __le16   handle;
 } __attribute__ ((packed));
@@ -454,13 +392,7 @@ struct hci_rp_read_link_policy {
        __le16   policy;
 } __attribute__ ((packed));
 
-#define OCF_SWITCH_ROLE                0x000B
-struct hci_cp_switch_role {
-       bdaddr_t bdaddr;
-       __u8     role;
-} __attribute__ ((packed));
-
-#define OCF_WRITE_LINK_POLICY  0x000D
+#define HCI_OP_WRITE_LINK_POLICY       0x080d
 struct hci_cp_write_link_policy {
        __le16   handle;
        __le16   policy;
@@ -470,7 +402,7 @@ struct hci_rp_write_link_policy {
        __le16   handle;
 } __attribute__ ((packed));
 
-#define OCF_SNIFF_SUBRATE      0x0011
+#define HCI_OP_SNIFF_SUBRATE           0x0811
 struct hci_cp_sniff_subrate {
        __le16   handle;
        __le16   max_latency;
@@ -478,59 +410,156 @@ struct hci_cp_sniff_subrate {
        __le16   min_local_timeout;
 } __attribute__ ((packed));
 
-/* Status params */
-#define OGF_STATUS_PARAM       0x05
+#define HCI_OP_SET_EVENT_MASK          0x0c01
+struct hci_cp_set_event_mask {
+       __u8     mask[8];
+} __attribute__ ((packed));
 
-/* Testing commands */
-#define OGF_TESTING_CMD                0x3E
+#define HCI_OP_RESET                   0x0c03
 
-/* Vendor specific commands */
-#define OGF_VENDOR_CMD         0x3F
+#define HCI_OP_SET_EVENT_FLT           0x0c05
+struct hci_cp_set_event_flt {
+       __u8     flt_type;
+       __u8     cond_type;
+       __u8     condition[0];
+} __attribute__ ((packed));
 
-/* ---- HCI Events ---- */
-#define HCI_EV_INQUIRY_COMPLETE        0x01
+/* Filter types */
+#define HCI_FLT_CLEAR_ALL      0x00
+#define HCI_FLT_INQ_RESULT     0x01
+#define HCI_FLT_CONN_SETUP     0x02
 
-#define HCI_EV_INQUIRY_RESULT  0x02
-struct inquiry_info {
-       bdaddr_t bdaddr;
-       __u8     pscan_rep_mode;
-       __u8     pscan_period_mode;
-       __u8     pscan_mode;
+/* CONN_SETUP Condition types */
+#define HCI_CONN_SETUP_ALLOW_ALL       0x00
+#define HCI_CONN_SETUP_ALLOW_CLASS     0x01
+#define HCI_CONN_SETUP_ALLOW_BDADDR    0x02
+
+/* CONN_SETUP Conditions */
+#define HCI_CONN_SETUP_AUTO_OFF        0x01
+#define HCI_CONN_SETUP_AUTO_ON 0x02
+
+#define HCI_OP_WRITE_LOCAL_NAME                0x0c13
+struct hci_cp_write_local_name {
+       __u8     name[248];
+} __attribute__ ((packed));
+
+#define HCI_OP_READ_LOCAL_NAME         0x0c14
+struct hci_rp_read_local_name {
+       __u8     status;
+       __u8     name[248];
+} __attribute__ ((packed));
+
+#define HCI_OP_WRITE_CA_TIMEOUT                0x0c16
+
+#define HCI_OP_WRITE_PG_TIMEOUT                0x0c18
+
+#define HCI_OP_WRITE_SCAN_ENABLE       0x0c1a
+       #define SCAN_DISABLED           0x00
+       #define SCAN_INQUIRY            0x01
+       #define SCAN_PAGE               0x02
+
+#define HCI_OP_READ_AUTH_ENABLE                0x0c1f
+
+#define HCI_OP_WRITE_AUTH_ENABLE       0x0c20
+       #define AUTH_DISABLED           0x00
+       #define AUTH_ENABLED            0x01
+
+#define HCI_OP_READ_ENCRYPT_MODE       0x0c21
+
+#define HCI_OP_WRITE_ENCRYPT_MODE      0x0c22
+       #define ENCRYPT_DISABLED        0x00
+       #define ENCRYPT_P2P             0x01
+       #define ENCRYPT_BOTH            0x02
+
+#define HCI_OP_READ_CLASS_OF_DEV       0x0c23
+struct hci_rp_read_class_of_dev {
+       __u8     status;
        __u8     dev_class[3];
-       __le16   clock_offset;
 } __attribute__ ((packed));
 
-#define HCI_EV_INQUIRY_RESULT_WITH_RSSI        0x22
-struct inquiry_info_with_rssi {
-       bdaddr_t bdaddr;
-       __u8     pscan_rep_mode;
-       __u8     pscan_period_mode;
+#define HCI_OP_WRITE_CLASS_OF_DEV      0x0c24
+struct hci_cp_write_class_of_dev {
        __u8     dev_class[3];
-       __le16   clock_offset;
-       __s8     rssi;
 } __attribute__ ((packed));
-struct inquiry_info_with_rssi_and_pscan_mode {
+
+#define HCI_OP_READ_VOICE_SETTING      0x0c25
+struct hci_rp_read_voice_setting {
+       __u8     status;
+       __le16   voice_setting;
+} __attribute__ ((packed));
+
+#define HCI_OP_WRITE_VOICE_SETTING     0x0c26
+struct hci_cp_write_voice_setting {
+       __le16   voice_setting;
+} __attribute__ ((packed));
+
+#define HCI_OP_HOST_BUFFER_SIZE                0x0c33
+struct hci_cp_host_buffer_size {
+       __le16   acl_mtu;
+       __u8     sco_mtu;
+       __le16   acl_max_pkt;
+       __le16   sco_max_pkt;
+} __attribute__ ((packed));
+
+#define HCI_OP_READ_LOCAL_VERSION      0x1001
+struct hci_rp_read_local_version {
+       __u8     status;
+       __u8     hci_ver;
+       __le16   hci_rev;
+       __u8     lmp_ver;
+       __le16   manufacturer;
+       __le16   lmp_subver;
+} __attribute__ ((packed));
+
+#define HCI_OP_READ_LOCAL_COMMANDS     0x1002
+struct hci_rp_read_local_commands {
+       __u8     status;
+       __u8     commands[64];
+} __attribute__ ((packed));
+
+#define HCI_OP_READ_LOCAL_FEATURES     0x1003
+struct hci_rp_read_local_features {
+       __u8     status;
+       __u8     features[8];
+} __attribute__ ((packed));
+
+#define HCI_OP_READ_LOCAL_EXT_FEATURES 0x1004
+struct hci_rp_read_local_ext_features {
+       __u8     status;
+       __u8     page;
+       __u8     max_page;
+       __u8     features[8];
+} __attribute__ ((packed));
+
+#define HCI_OP_READ_BUFFER_SIZE                0x1005
+struct hci_rp_read_buffer_size {
+       __u8     status;
+       __le16   acl_mtu;
+       __u8     sco_mtu;
+       __le16   acl_max_pkt;
+       __le16   sco_max_pkt;
+} __attribute__ ((packed));
+
+#define HCI_OP_READ_BD_ADDR            0x1009
+struct hci_rp_read_bd_addr {
+       __u8     status;
        bdaddr_t bdaddr;
-       __u8     pscan_rep_mode;
-       __u8     pscan_period_mode;
-       __u8     pscan_mode;
-       __u8     dev_class[3];
-       __le16   clock_offset;
-       __s8     rssi;
 } __attribute__ ((packed));
 
-#define HCI_EV_EXTENDED_INQUIRY_RESULT 0x2F
-struct extended_inquiry_info {
+/* ---- HCI Events ---- */
+#define HCI_EV_INQUIRY_COMPLETE                0x01
+
+#define HCI_EV_INQUIRY_RESULT          0x02
+struct inquiry_info {
        bdaddr_t bdaddr;
        __u8     pscan_rep_mode;
        __u8     pscan_period_mode;
+       __u8     pscan_mode;
        __u8     dev_class[3];
        __le16   clock_offset;
-       __s8     rssi;
-       __u8     data[240];
 } __attribute__ ((packed));
 
-#define HCI_EV_CONN_COMPLETE   0x03
+#define HCI_EV_CONN_COMPLETE           0x03
 struct hci_ev_conn_complete {
        __u8     status;
        __le16   handle;
@@ -539,40 +568,63 @@ struct hci_ev_conn_complete {
        __u8     encr_mode;
 } __attribute__ ((packed));
 
-#define HCI_EV_CONN_REQUEST    0x04
+#define HCI_EV_CONN_REQUEST            0x04
 struct hci_ev_conn_request {
        bdaddr_t bdaddr;
        __u8     dev_class[3];
        __u8     link_type;
 } __attribute__ ((packed));
 
-#define HCI_EV_DISCONN_COMPLETE        0x05
+#define HCI_EV_DISCONN_COMPLETE                0x05
 struct hci_ev_disconn_complete {
        __u8     status;
        __le16   handle;
        __u8     reason;
 } __attribute__ ((packed));
 
-#define HCI_EV_AUTH_COMPLETE   0x06
+#define HCI_EV_AUTH_COMPLETE           0x06
 struct hci_ev_auth_complete {
        __u8     status;
        __le16   handle;
 } __attribute__ ((packed));
 
-#define HCI_EV_ENCRYPT_CHANGE  0x08
+#define HCI_EV_REMOTE_NAME             0x07
+struct hci_ev_remote_name {
+       __u8     status;
+       bdaddr_t bdaddr;
+       __u8     name[248];
+} __attribute__ ((packed));
+
+#define HCI_EV_ENCRYPT_CHANGE          0x08
 struct hci_ev_encrypt_change {
        __u8     status;
        __le16   handle;
        __u8     encrypt;
 } __attribute__ ((packed));
 
-#define HCI_EV_CHANGE_CONN_LINK_KEY_COMPLETE   0x09
-struct hci_ev_change_conn_link_key_complete {
+#define HCI_EV_CHANGE_LINK_KEY_COMPLETE        0x09
+struct hci_ev_change_link_key_complete {
+       __u8     status;
+       __le16   handle;
+} __attribute__ ((packed));
+
+#define HCI_EV_REMOTE_FEATURES         0x0b
+struct hci_ev_remote_features {
+       __u8     status;
+       __le16   handle;
+       __u8     features[8];
+} __attribute__ ((packed));
+
+#define HCI_EV_REMOTE_VERSION          0x0c
+struct hci_ev_remote_version {
        __u8     status;
        __le16   handle;
+       __u8     lmp_ver;
+       __le16   manufacturer;
+       __le16   lmp_subver;
 } __attribute__ ((packed));
 
-#define HCI_EV_QOS_SETUP_COMPLETE      0x0D
+#define HCI_EV_QOS_SETUP_COMPLETE      0x0d
 struct hci_qos {
        __u8     service_type;
        __u32    token_rate;
@@ -586,33 +638,33 @@ struct hci_ev_qos_setup_complete {
        struct   hci_qos qos;
 } __attribute__ ((packed));
 
-#define HCI_EV_CMD_COMPLETE    0x0E
+#define HCI_EV_CMD_COMPLETE            0x0e
 struct hci_ev_cmd_complete {
        __u8     ncmd;
        __le16   opcode;
 } __attribute__ ((packed));
 
-#define HCI_EV_CMD_STATUS      0x0F
+#define HCI_EV_CMD_STATUS              0x0f
 struct hci_ev_cmd_status {
        __u8     status;
        __u8     ncmd;
        __le16   opcode;
 } __attribute__ ((packed));
 
-#define HCI_EV_NUM_COMP_PKTS   0x13
-struct hci_ev_num_comp_pkts {
-       __u8     num_hndl;
-       /* variable length part */
-} __attribute__ ((packed));
-
-#define HCI_EV_ROLE_CHANGE     0x12
+#define HCI_EV_ROLE_CHANGE             0x12
 struct hci_ev_role_change {
        __u8     status;
        bdaddr_t bdaddr;
        __u8     role;
 } __attribute__ ((packed));
 
-#define HCI_EV_MODE_CHANGE     0x14
+#define HCI_EV_NUM_COMP_PKTS           0x13
+struct hci_ev_num_comp_pkts {
+       __u8     num_hndl;
+       /* variable length part */
+} __attribute__ ((packed));
+
+#define HCI_EV_MODE_CHANGE             0x14
 struct hci_ev_mode_change {
        __u8     status;
        __le16   handle;
@@ -620,53 +672,88 @@ struct hci_ev_mode_change {
        __le16   interval;
 } __attribute__ ((packed));
 
-#define HCI_EV_PIN_CODE_REQ    0x16
+#define HCI_EV_PIN_CODE_REQ            0x16
 struct hci_ev_pin_code_req {
        bdaddr_t bdaddr;
 } __attribute__ ((packed));
 
-#define HCI_EV_LINK_KEY_REQ    0x17
+#define HCI_EV_LINK_KEY_REQ            0x17
 struct hci_ev_link_key_req {
        bdaddr_t bdaddr;
 } __attribute__ ((packed));
 
-#define HCI_EV_LINK_KEY_NOTIFY 0x18
+#define HCI_EV_LINK_KEY_NOTIFY         0x18
 struct hci_ev_link_key_notify {
        bdaddr_t bdaddr;
-       __u8     link_key[16];
-       __u8     key_type;
+       __u8     link_key[16];
+       __u8     key_type;
 } __attribute__ ((packed));
 
-#define HCI_EV_REMOTE_FEATURES 0x0B
-struct hci_ev_remote_features {
+#define HCI_EV_CLOCK_OFFSET            0x1c
+struct hci_ev_clock_offset {
        __u8     status;
        __le16   handle;
-       __u8     features[8];
+       __le16   clock_offset;
 } __attribute__ ((packed));
 
-#define HCI_EV_REMOTE_VERSION  0x0C
-struct hci_ev_remote_version {
+#define HCI_EV_PSCAN_REP_MODE          0x20
+struct hci_ev_pscan_rep_mode {
+       bdaddr_t bdaddr;
+       __u8     pscan_rep_mode;
+} __attribute__ ((packed));
+
+#define HCI_EV_INQUIRY_RESULT_WITH_RSSI        0x22
+struct inquiry_info_with_rssi {
+       bdaddr_t bdaddr;
+       __u8     pscan_rep_mode;
+       __u8     pscan_period_mode;
+       __u8     dev_class[3];
+       __le16   clock_offset;
+       __s8     rssi;
+} __attribute__ ((packed));
+struct inquiry_info_with_rssi_and_pscan_mode {
+       bdaddr_t bdaddr;
+       __u8     pscan_rep_mode;
+       __u8     pscan_period_mode;
+       __u8     pscan_mode;
+       __u8     dev_class[3];
+       __le16   clock_offset;
+       __s8     rssi;
+} __attribute__ ((packed));
+
+#define HCI_EV_REMOTE_EXT_FEATURES     0x23
+struct hci_ev_remote_ext_features {
        __u8     status;
        __le16   handle;
-       __u8     lmp_ver;
-       __le16   manufacturer;
-       __le16   lmp_subver;
+       __u8     page;
+       __u8     max_page;
+       __u8     features[8];
 } __attribute__ ((packed));
 
-#define HCI_EV_CLOCK_OFFSET    0x01C
-struct hci_ev_clock_offset {
+#define HCI_EV_SYNC_CONN_COMPLETE      0x2c
+struct hci_ev_sync_conn_complete {
        __u8     status;
        __le16   handle;
-       __le16   clock_offset;
+       bdaddr_t bdaddr;
+       __u8     link_type;
+       __u8     tx_interval;
+       __u8     retrans_window;
+       __le16   rx_pkt_len;
+       __le16   tx_pkt_len;
+       __u8     air_mode;
 } __attribute__ ((packed));
 
-#define HCI_EV_PSCAN_REP_MODE  0x20
-struct hci_ev_pscan_rep_mode {
-       bdaddr_t bdaddr;
-       __u8     pscan_rep_mode;
+#define HCI_EV_SYNC_CONN_CHANGED       0x2d
+struct hci_ev_sync_conn_changed {
+       __u8     status;
+       __le16   handle;
+       __u8     tx_interval;
+       __u8     retrans_window;
+       __le16   rx_pkt_len;
+       __le16   tx_pkt_len;
 } __attribute__ ((packed));
 
-#define HCI_EV_SNIFF_SUBRATE   0x2E
+#define HCI_EV_SNIFF_SUBRATE           0x2e
 struct hci_ev_sniff_subrate {
        __u8     status;
        __le16   handle;
@@ -676,14 +763,25 @@ struct hci_ev_sniff_subrate {
        __le16   max_local_timeout;
 } __attribute__ ((packed));
 
+#define HCI_EV_EXTENDED_INQUIRY_RESULT 0x2f
+struct extended_inquiry_info {
+       bdaddr_t bdaddr;
+       __u8     pscan_rep_mode;
+       __u8     pscan_period_mode;
+       __u8     dev_class[3];
+       __le16   clock_offset;
+       __s8     rssi;
+       __u8     data[240];
+} __attribute__ ((packed));
+
 /* Internal events generated by Bluetooth stack */
-#define HCI_EV_STACK_INTERNAL  0xFD
+#define HCI_EV_STACK_INTERNAL  0xfd
 struct hci_ev_stack_internal {
        __u16    type;
        __u8     data[0];
 } __attribute__ ((packed));
 
-#define HCI_EV_SI_DEVICE       0x01
+#define HCI_EV_SI_DEVICE       0x01
 struct hci_ev_si_device {
        __u16    event;
        __u16    dev_id;
@@ -704,40 +802,40 @@ struct hci_ev_si_security {
 #define HCI_SCO_HDR_SIZE     3
 
 struct hci_command_hdr {
-       __le16  opcode;         /* OCF & OGF */
+       __le16  opcode;         /* OCF & OGF */
        __u8    plen;
 } __attribute__ ((packed));
 
 struct hci_event_hdr {
-       __u8    evt;
-       __u8    plen;
+       __u8    evt;
+       __u8    plen;
 } __attribute__ ((packed));
 
 struct hci_acl_hdr {
-       __le16  handle;         /* Handle & Flags(PB, BC) */
-       __le16  dlen;
+       __le16  handle;         /* Handle & Flags(PB, BC) */
+       __le16  dlen;
 } __attribute__ ((packed));
 
 struct hci_sco_hdr {
-       __le16  handle;
-       __u8    dlen;
+       __le16  handle;
+       __u8    dlen;
 } __attribute__ ((packed));
 
 #ifdef __KERNEL__
 #include <linux/skbuff.h>
 static inline struct hci_event_hdr *hci_event_hdr(const struct sk_buff *skb)
 {
-       return (struct hci_event_hdr *)skb->data;
+       return (struct hci_event_hdr *) skb->data;
 }
 
 static inline struct hci_acl_hdr *hci_acl_hdr(const struct sk_buff *skb)
 {
-       return (struct hci_acl_hdr *)skb->data;
+       return (struct hci_acl_hdr *) skb->data;
 }
 
 static inline struct hci_sco_hdr *hci_sco_hdr(const struct sk_buff *skb)
 {
-       return (struct hci_sco_hdr *)skb->data;
+       return (struct hci_sco_hdr *) skb->data;
 }
 #endif
 
@@ -771,13 +869,13 @@ struct sockaddr_hci {
 struct hci_filter {
        unsigned long type_mask;
        unsigned long event_mask[2];
-       __le16   opcode;
+       __le16 opcode;
 };
 
 struct hci_ufilter {
-       __u32   type_mask;
-       __u32   event_mask[2];
-       __le16   opcode;
+       __u32  type_mask;
+       __u32  event_mask[2];
+       __le16 opcode;
 };
 
 #define HCI_FLT_TYPE_BITS      31
@@ -825,15 +923,15 @@ struct hci_dev_info {
 struct hci_conn_info {
        __u16    handle;
        bdaddr_t bdaddr;
-       __u8     type;
-       __u8     out;
-       __u16    state;
-       __u32    link_mode;
+       __u8     type;
+       __u8     out;
+       __u16    state;
+       __u32    link_mode;
 };
 
 struct hci_dev_req {
-       __u16 dev_id;
-       __u32 dev_opt;
+       __u16  dev_id;
+       __u32  dev_opt;
 };
 
 struct hci_dev_list_req {
index 8f67c8a7169beffc42667697b6c91c2f5459c602..ea13baa3851b177c477ceef3279e3dd4395a68a6 100644 (file)
@@ -71,7 +71,10 @@ struct hci_dev {
        __u16           id;
        __u8            type;
        bdaddr_t        bdaddr;
+       __u8            dev_name[248];
+       __u8            dev_class[3];
        __u8            features[8];
+       __u8            commands[64];
        __u8            hci_ver;
        __u16           hci_rev;
        __u16           manufacturer;
@@ -310,10 +313,12 @@ static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev,
 void hci_acl_connect(struct hci_conn *conn);
 void hci_acl_disconn(struct hci_conn *conn, __u8 reason);
 void hci_add_sco(struct hci_conn *conn, __u16 handle);
+void hci_setup_sync(struct hci_conn *conn, __u16 handle);
 
 struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst);
-int    hci_conn_del(struct hci_conn *conn);
-void   hci_conn_hash_flush(struct hci_dev *hdev);
+int hci_conn_del(struct hci_conn *conn);
+void hci_conn_hash_flush(struct hci_dev *hdev);
+void hci_conn_check_pending(struct hci_dev *hdev);
 
 struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *src);
 int hci_conn_auth(struct hci_conn *conn);
@@ -617,11 +622,11 @@ int hci_unregister_cb(struct hci_cb *hcb);
 int hci_register_notifier(struct notifier_block *nb);
 int hci_unregister_notifier(struct notifier_block *nb);
 
-int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *param);
+int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param);
 int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
 int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
 
-void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf);
+void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode);
 
 void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data);
 
index 70e70f5d3dd61e26a54f46c7c9e59ff8db6c0bf0..73e115bc12dda4f688555c087d0c98558373d576 100644 (file)
@@ -29,7 +29,8 @@
 #define L2CAP_DEFAULT_MTU      672
 #define L2CAP_DEFAULT_FLUSH_TO 0xFFFF
 
-#define L2CAP_CONN_TIMEOUT     (HZ * 40)
+#define L2CAP_CONN_TIMEOUT     (40000) /* 40 seconds */
+#define L2CAP_INFO_TIMEOUT     (4000)  /*  4 seconds */
 
 /* L2CAP socket address */
 struct sockaddr_l2 {
@@ -148,6 +149,19 @@ struct l2cap_conf_opt {
 
 #define L2CAP_CONF_MAX_SIZE    22
 
+struct l2cap_conf_rfc {
+       __u8       mode;
+       __u8       txwin_size;
+       __u8       max_transmit;
+       __le16     retrans_timeout;
+       __le16     monitor_timeout;
+       __le16     max_pdu_size;
+} __attribute__ ((packed));
+
+#define L2CAP_MODE_BASIC       0x00
+#define L2CAP_MODE_RETRANS     0x01
+#define L2CAP_MODE_FLOWCTL     0x02
+
 struct l2cap_disconn_req {
        __le16     dcid;
        __le16     scid;
@@ -160,7 +174,6 @@ struct l2cap_disconn_rsp {
 
 struct l2cap_info_req {
        __le16      type;
-       __u8        data[0];
 } __attribute__ ((packed));
 
 struct l2cap_info_rsp {
@@ -192,6 +205,13 @@ struct l2cap_conn {
 
        unsigned int    mtu;
 
+       __u32           feat_mask;
+
+       __u8            info_state;
+       __u8            info_ident;
+
+       struct timer_list info_timer;
+
        spinlock_t      lock;
 
        struct sk_buff *rx_skb;
@@ -202,6 +222,9 @@ struct l2cap_conn {
        struct l2cap_chan_list chan_list;
 };
 
+#define L2CAP_INFO_CL_MTU_REQ_SENT     0x01
+#define L2CAP_INFO_FEAT_MASK_REQ_SENT  0x02
+
 /* ----- L2CAP channel and socket info ----- */
 #define l2cap_pi(sk) ((struct l2cap_pinfo *) sk)
 
@@ -221,7 +244,6 @@ struct l2cap_pinfo {
        __u8            conf_len;
        __u8            conf_state;
        __u8            conf_retry;
-       __u16           conf_mtu;
 
        __u8            ident;
 
@@ -232,10 +254,11 @@ struct l2cap_pinfo {
        struct sock             *prev_c;
 };
 
-#define L2CAP_CONF_REQ_SENT    0x01
-#define L2CAP_CONF_INPUT_DONE  0x02
-#define L2CAP_CONF_OUTPUT_DONE 0x04
-#define L2CAP_CONF_MAX_RETRIES 2
+#define L2CAP_CONF_REQ_SENT    0x01
+#define L2CAP_CONF_INPUT_DONE  0x02
+#define L2CAP_CONF_OUTPUT_DONE 0x04
+
+#define L2CAP_CONF_MAX_RETRIES 2
 
 void l2cap_load(void);
 
index 911c2cd02941cda559bb176af22f11adfda6915e..954def408975a13a11b6e57cbeb3624346f0328c 100644 (file)
@@ -39,8 +39,13 @@ struct inet_frags {
        struct inet_frags_ctl   *ctl;
 
        unsigned int            (*hashfn)(struct inet_frag_queue *);
+       void                    (*constructor)(struct inet_frag_queue *q,
+                                               void *arg);
        void                    (*destructor)(struct inet_frag_queue *);
        void                    (*skb_free)(struct sk_buff *);
+       int                     (*match)(struct inet_frag_queue *q,
+                                               void *arg);
+       void                    (*frag_expire)(unsigned long data);
 };
 
 void inet_frags_init(struct inet_frags *);
@@ -50,6 +55,8 @@ void inet_frag_kill(struct inet_frag_queue *q, struct inet_frags *f);
 void inet_frag_destroy(struct inet_frag_queue *q,
                                struct inet_frags *f, int *work);
 int inet_frag_evictor(struct inet_frags *f);
+struct inet_frag_queue *inet_frag_find(struct inet_frags *f, void *key,
+               unsigned int hash);
 
 static inline void inet_frag_put(struct inet_frag_queue *q, struct inet_frags *f)
 {
index cc796cbc1b26e5c292d649b8a26b2364dc7e0eef..ae328b680ff2a5e5de0cd41955f7476efae95035 100644 (file)
@@ -377,6 +377,17 @@ static inline int ipv6_prefix_equal(const struct in6_addr *a1,
                                   prefixlen);
 }
 
+struct inet_frag_queue;
+
+struct ip6_create_arg {
+       __be32 id;
+       struct in6_addr *src;
+       struct in6_addr *dst;
+};
+
+void ip6_frag_init(struct inet_frag_queue *q, void *a);
+int ip6_frag_match(struct inet_frag_queue *q, void *a);
+
 static inline int ipv6_addr_any(const struct in6_addr *a)
 {
        return ((a->s6_addr32[0] | a->s6_addr32[1] | 
index cf80c1af5854a4d7c9351bb8922fd3892884a887..32c385dd9e06a94ab6cf77988537d02cc47835ad 100644 (file)
@@ -56,7 +56,7 @@
 
 /* Receive queue sizes */
 /* Minimum of credit that the peer should hold.
- * If the peer has less credits than 9 frames, we will explicitely send
+ * If the peer has less credits than 9 frames, we will explicitly send
  * him some credits (through irttp_give_credit() and a specific frame).
  * Note that when we give credits it's likely that it won't be sent in
  * this LAP window, but in the next one. So, we make sure that the peer
@@ -66,7 +66,7 @@
 /* This is the default maximum number of credits held by the peer, so the
  * default maximum number of frames he can send us before needing flow
  * control answer from us (this may be negociated differently at TSAP setup).
- * We want to minimise the number of times we have to explicitely send some
+ * We want to minimise the number of times we have to explicitly send some
  * credit to the peer, hoping we can piggyback it on the return data. In
  * particular, it doesn't make sense for us to send credit more than once
  * per LAP window.
index 423cb1d5ac2530dcd4a742f286b7d416be6b8f6e..06df126103cab8224d6cf7ae64c7f00e75f06e12 100644 (file)
@@ -4,6 +4,8 @@
 #include <linux/limits.h>
 #include <linux/net.h>
 #include <linux/security.h>
+#include <linux/pid.h>
+#include <linux/nsproxy.h>
 
 /* Well, we should have at least one descriptor open
  * to accept passed FDs 8)
@@ -54,7 +56,7 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
        struct task_struct *p = current;
        scm->creds.uid = p->uid;
        scm->creds.gid = p->gid;
-       scm->creds.pid = p->tgid;
+       scm->creds.pid = task_tgid_vnr(p);
        scm->fp = NULL;
        scm->seq = 0;
        unix_get_peersec_dgram(sock, scm);
index 453c79d0915ba00ca8b33ff160ba64cb7c58a521..43fc3fa50d6237227e5bec82bc0b4e8e0d4ce8b7 100644 (file)
@@ -904,16 +904,6 @@ static inline int sk_filter(struct sock *sk, struct sk_buff *skb)
        return err;
 }
 
-/**
- *     sk_filter_rcu_free: Free a socket filter
- *     @rcu: rcu_head that contains the sk_filter to free
- */
-static inline void sk_filter_rcu_free(struct rcu_head *rcu)
-{
-       struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu);
-       kfree(fp);
-}
-
 /**
  *     sk_filter_release: Release a socket filter
  *     @sk: socket
@@ -922,14 +912,18 @@ static inline void sk_filter_rcu_free(struct rcu_head *rcu)
  *     Remove a filter from a socket and release its resources.
  */
 
-static inline void sk_filter_release(struct sock *sk, struct sk_filter *fp)
+static inline void sk_filter_release(struct sk_filter *fp)
+{
+       if (atomic_dec_and_test(&fp->refcnt))
+               kfree(fp);
+}
+
+static inline void sk_filter_uncharge(struct sock *sk, struct sk_filter *fp)
 {
        unsigned int size = sk_filter_len(fp);
 
        atomic_sub(size, &sk->sk_omem_alloc);
-
-       if (atomic_dec_and_test(&fp->refcnt))
-               call_rcu_bh(&fp->rcu, sk_filter_rcu_free);
+       sk_filter_release(fp);
 }
 
 static inline void sk_filter_charge(struct sock *sk, struct sk_filter *fp)
index 0e844845f3f4f5e12ee64daccaadea4c4879efa0..688f6f5d3285bf1cc6ae88850c7008ff1fd6d5a2 100644 (file)
@@ -186,7 +186,8 @@ struct xfrm_state
        /* Reference to data common to all the instances of this
         * transformer. */
        struct xfrm_type        *type;
-       struct xfrm_mode        *mode;
+       struct xfrm_mode        *inner_mode;
+       struct xfrm_mode        *outer_mode;
 
        /* Security context */
        struct xfrm_sec_ctx     *security;
@@ -228,8 +229,6 @@ struct xfrm_type;
 struct xfrm_dst;
 struct xfrm_policy_afinfo {
        unsigned short          family;
-       struct xfrm_type        *type_map[IPPROTO_MAX];
-       struct xfrm_mode        *mode_map[XFRM_MODE_MAX];
        struct dst_ops          *dst_ops;
        void                    (*garbage_collect)(void);
        int                     (*dst_lookup)(struct xfrm_dst **dst, struct flowi *fl);
@@ -255,7 +254,10 @@ extern void km_state_expired(struct xfrm_state *x, int hard, u32 pid);
 extern int __xfrm_state_delete(struct xfrm_state *x);
 
 struct xfrm_state_afinfo {
-       unsigned short          family;
+       unsigned int            family;
+       struct module           *owner;
+       struct xfrm_type        *type_map[IPPROTO_MAX];
+       struct xfrm_mode        *mode_map[XFRM_MODE_MAX];
        int                     (*init_flags)(struct xfrm_state *x);
        void                    (*init_tempsel)(struct xfrm_state *x, struct flowi *fl,
                                                struct xfrm_tmpl *tmpl,
@@ -267,8 +269,6 @@ struct xfrm_state_afinfo {
 
 extern int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo);
 extern int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo);
-extern struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family);
-extern void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo);
 
 extern void xfrm_state_delete_tunnel(struct xfrm_state *x);
 
@@ -295,8 +295,6 @@ struct xfrm_type
 
 extern int xfrm_register_type(struct xfrm_type *type, unsigned short family);
 extern int xfrm_unregister_type(struct xfrm_type *type, unsigned short family);
-extern struct xfrm_type *xfrm_get_type(u8 proto, unsigned short family);
-extern void xfrm_put_type(struct xfrm_type *type);
 
 struct xfrm_mode {
        int (*input)(struct xfrm_state *x, struct sk_buff *skb);
@@ -314,14 +312,19 @@ struct xfrm_mode {
         */
        int (*output)(struct xfrm_state *x,struct sk_buff *skb);
 
+       struct xfrm_state_afinfo *afinfo;
        struct module *owner;
        unsigned int encap;
+       int flags;
+};
+
+/* Flags for xfrm_mode. */
+enum {
+       XFRM_MODE_FLAG_TUNNEL = 1,
 };
 
 extern int xfrm_register_mode(struct xfrm_mode *mode, int family);
 extern int xfrm_unregister_mode(struct xfrm_mode *mode, int family);
-extern struct xfrm_mode *xfrm_get_mode(unsigned int encap, int family);
-extern void xfrm_put_mode(struct xfrm_mode *mode);
 
 struct xfrm_tmpl
 {
@@ -1046,11 +1049,19 @@ extern void xfrm_replay_notify(struct xfrm_state *x, int event);
 extern int xfrm_state_mtu(struct xfrm_state *x, int mtu);
 extern int xfrm_init_state(struct xfrm_state *x);
 extern int xfrm_output(struct sk_buff *skb);
+extern int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
+                          int encap_type);
 extern int xfrm4_rcv(struct sk_buff *skb);
+
+static inline int xfrm4_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
+{
+       return xfrm4_rcv_encap(skb, nexthdr, spi, 0);
+}
+
 extern int xfrm4_output(struct sk_buff *skb);
 extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family);
 extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family);
-extern int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi);
+extern int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi);
 extern int xfrm6_rcv(struct sk_buff *skb);
 extern int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
                            xfrm_address_t *saddr, u8 proto);
index 8d4a8dd892373e63d1ce518c2bdb61ecf0192514..a2be8ad8894b2d7386104ac6fa3193e1ddf61abe 100644 (file)
@@ -1,3 +1,3 @@
 /* include/version.h.  Generated by alsa/ksync script.  */
 #define CONFIG_SND_VERSION "1.0.15"
-#define CONFIG_SND_DATE " (Tue Oct 16 14:57:44 2007 UTC)"
+#define CONFIG_SND_DATE " (Tue Oct 23 06:09:18 2007 UTC)"
index 53a6c7310e61b92ed3bdd73d79b4f0e36d7cc17c..0e406f730c2f6fabafb8d4aeff0ed42e5c1239a1 100644 (file)
@@ -1 +1,2 @@
 unifdef-y += sisfb.h uvesafb.h
+unifdef-y += edid.h
index f6a42d6c2e2d6e22daade1d3680cc1a088f26d26..928c342b33d65040be5d2bfd958447d21074e92f 100644 (file)
@@ -1,17 +1,16 @@
 #ifndef __linux_video_edid_h__
 #define __linux_video_edid_h__
 
-#ifdef __KERNEL__
-
+#if !defined(__KERNEL__) || defined(CONFIG_X86)
 
-#ifdef CONFIG_X86
 struct edid_info {
        unsigned char dummy[128];
 };
 
+#ifdef __KERNEL__
 extern struct edid_info edid_info;
-#endif /* CONFIG_X86 */
-
 #endif /* __KERNEL__ */
 
+#endif
+
 #endif /* __linux_video_edid_h__ */
index baa163f770abd7ceba1d7aa273b8b5450bd4916d..b52f07381243efdcd125a1c5a6c3a8d090dbd4e5 100644 (file)
@@ -68,7 +68,6 @@
 #  define print_var(X,Y...)
 #endif
 
-#define BIT(x)         (1ul<<(x))
 #define POW2(x)                (1ul<<(x))
 
 /*
index 05b63c2a5abcfd8f061204e1c1f2021783b2fba7..7431d9681e57280b740db748257d168077eb3e1a 100644 (file)
@@ -79,8 +79,6 @@
 
 /* register bitfields (not all, only as needed) */
 
-#define BIT(x) (1UL << (x))
-
 /* COMMAND_2D reg. values */
 #define TDFX_ROP_COPY          0xcc    /* src */
 #define TDFX_ROP_INVERT                0x55    /* NOT dst */
index a29a688c47d3128dc63fed1c70e799351ca38449..b7dffa837926f451e163e1c5c7027f7cbe5a8183 100644 (file)
@@ -234,6 +234,10 @@ config AUDITSYSCALL
          such as SELinux.  To use audit's filesystem watch feature, please
          ensure that INOTIFY is configured.
 
+config AUDIT_TREE
+       def_bool y
+       depends on AUDITSYSCALL && INOTIFY
+
 config IKCONFIG
        tristate "Kernel .config support"
        ---help---
@@ -270,9 +274,43 @@ config LOG_BUF_SHIFT
                     13 =>  8 KB
                     12 =>  4 KB
 
+config CGROUPS
+       bool "Control Group support"
+       help
+         This option will let you use process cgroup subsystems
+         such as Cpusets
+
+         Say N if unsure.
+
+config CGROUP_DEBUG
+       bool "Example debug cgroup subsystem"
+       depends on CGROUPS
+       help
+         This option enables a simple cgroup subsystem that
+         exports useful debugging information about the cgroups
+         framework
+
+         Say N if unsure
+
+config CGROUP_NS
+        bool "Namespace cgroup subsystem"
+        depends on CGROUPS
+        help
+          Provides a simple namespace cgroup subsystem to
+          provide hierarchical naming of sets of namespaces,
+          for instance virtual servers and checkpoint/restart
+          jobs.
+
+config CGROUP_CPUACCT
+       bool "Simple CPU accounting cgroup subsystem"
+       depends on CGROUPS
+       help
+         Provides a simple Resource Controller for monitoring the
+         total CPU consumed by the tasks in a cgroup
+
 config CPUSETS
        bool "Cpuset support"
-       depends on SMP
+       depends on SMP && CGROUPS
        help
          This option will let you create and manage CPUSETs which
          allow dynamically partitioning a system into sets of CPUs and
@@ -300,6 +338,16 @@ config FAIR_USER_SCHED
          This option will choose userid as the basis for grouping
          tasks, thus providing equal CPU bandwidth to each user.
 
+config FAIR_CGROUP_SCHED
+       bool "Control groups"
+       depends on CGROUPS
+       help
+         This option allows you to create arbitrary task groups
+         using the "cgroup" pseudo filesystem and control
+         the cpu bandwidth allocated to each such task group.
+         Refer to Documentation/cgroups.txt for more information
+         on "cgroup" pseudo filesystem.
+
 endchoice
 
 config SYSFS_DEPRECATED
@@ -322,6 +370,11 @@ config SYSFS_DEPRECATED
          If you are using a distro that was released in 2006 or later,
          it should be safe to say N here.
 
+config PROC_PID_CPUSET
+       bool "Include legacy /proc/<pid>/cpuset file"
+       depends on CPUSETS
+       default y
+
 config RELAY
        bool "Kernel->user space relay support (formerly relayfs)"
        help
index ed652f40f075a68e2b41b68911a97a0f5224ed96..3ac5904d1b124c1584b0308b0c42712d9a86cc20 100644 (file)
@@ -57,7 +57,7 @@ identify_ramdisk_image(int fd, int start_block)
        unsigned char *buf;
 
        buf = kmalloc(size, GFP_KERNEL);
-       if (buf == 0)
+       if (!buf)
                return -1;
 
        minixsb = (struct minix_super_block *) buf;
@@ -407,12 +407,12 @@ static int __init crd_load(int in_fd, int out_fd)
        crd_infd = in_fd;
        crd_outfd = out_fd;
        inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
-       if (inbuf == 0) {
+       if (!inbuf) {
                printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
                return -1;
        }
        window = kmalloc(WSIZE, GFP_KERNEL);
-       if (window == 0) {
+       if (!window) {
                printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
                kfree(inbuf);
                return -1;
index 9def935ab13a27c829e28bb2830cdbe2c6fd900d..f605a969ea6141281891bb007edc41938c63e3f1 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/writeback.h>
 #include <linux/cpu.h>
 #include <linux/cpuset.h>
+#include <linux/cgroup.h>
 #include <linux/efi.h>
 #include <linux/tick.h>
 #include <linux/interrupt.h>
 /*
  * This is one of the first .c files built. Error out early if we have compiler
  * trouble.
- *
- * Versions of gcc older than that listed below may actually compile and link
- * okay, but the end product can have subtle run time bugs.  To avoid associated
- * bogus bug reports, we flatly refuse to compile with a gcc that is known to be
- * too old from the very beginning.
  */
-#if (__GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 2)
-#error Sorry, your GCC is too old. It builds incorrect kernels.
-#endif
 
 #if __GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ == 0
 #warning gcc-4.1.0 is known to miscompile the kernel.  A different compiler version is recommended.
@@ -287,7 +280,7 @@ static int __init unknown_bootoption(char *param, char *val)
                return 0;
 
        /*
-        * Preemptive maintenance for "why didn't my mispelled command
+        * Preemptive maintenance for "why didn't my misspelled command
         * line work?"
         */
        if (strchr(param, '.') && (!val || strchr(param, '.') < val)) {
@@ -523,6 +516,7 @@ asmlinkage void __init start_kernel(void)
         */
        unwind_init();
        lockdep_init();
+       cgroup_init_early();
 
        local_irq_disable();
        early_boot_irqs_off();
@@ -640,6 +634,7 @@ asmlinkage void __init start_kernel(void)
 #ifdef CONFIG_PROC_FS
        proc_root_init();
 #endif
+       cgroup_init();
        cpuset_init();
        taskstats_init_early();
        delayacct_init();
index 774843cff756fe169948b8a084649d5f36dcb7fa..bfa274ba9ed40267201bee1f6fc45c4d5a5f213b 100644 (file)
@@ -29,6 +29,8 @@
 #include <linux/audit.h>
 #include <linux/signal.h>
 #include <linux/mutex.h>
+#include <linux/nsproxy.h>
+#include <linux/pid.h>
 
 #include <net/sock.h>
 #include "util.h"
 #define STATE_PENDING  1
 #define STATE_READY    2
 
-/* used by sysctl */
-#define FS_MQUEUE      1
-#define CTL_QUEUESMAX  2
-#define CTL_MSGMAX     3
-#define CTL_MSGSIZEMAX         4
-
 /* default values */
 #define DFLT_QUEUESMAX 256     /* max number of message queues */
 #define DFLT_MSGMAX    10      /* max number of messages in each queue */
@@ -336,7 +332,8 @@ static ssize_t mqueue_read_file(struct file *filp, char __user *u_data,
                        (info->notify_owner &&
                         info->notify.sigev_notify == SIGEV_SIGNAL) ?
                                info->notify.sigev_signo : 0,
-                       pid_nr(info->notify_owner));
+                       pid_nr_ns(info->notify_owner,
+                               current->nsproxy->pid_ns));
        spin_unlock(&info->lock);
        buffer[sizeof(buffer)-1] = '\0';
        slen = strlen(buffer)+1;
@@ -513,7 +510,7 @@ static void __do_notify(struct mqueue_inode_info *info)
                        sig_i.si_errno = 0;
                        sig_i.si_code = SI_MESGQ;
                        sig_i.si_value = info->notify.sigev_value;
-                       sig_i.si_pid = current->tgid;
+                       sig_i.si_pid = task_pid_vnr(current);
                        sig_i.si_uid = current->uid;
 
                        kill_pid_info(info->notify.sigev_signo,
@@ -679,7 +676,7 @@ asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode,
 
        if (oflag & O_CREAT) {
                if (dentry->d_inode) {  /* entry already exists */
-                       audit_inode(name, dentry->d_inode);
+                       audit_inode(name, dentry);
                        error = -EEXIST;
                        if (oflag & O_EXCL)
                                goto out;
@@ -692,7 +689,7 @@ asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode,
                error = -ENOENT;
                if (!dentry->d_inode)
                        goto out;
-               audit_inode(name, dentry->d_inode);
+               audit_inode(name, dentry);
                filp = do_open(dentry, oflag);
        }
 
@@ -840,7 +837,7 @@ asmlinkage long sys_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr,
        if (unlikely(filp->f_op != &mqueue_file_operations))
                goto out_fput;
        info = MQUEUE_I(inode);
-       audit_inode(NULL, inode);
+       audit_inode(NULL, filp->f_path.dentry);
 
        if (unlikely(!(filp->f_mode & FMODE_WRITE)))
                goto out_fput;
@@ -924,7 +921,7 @@ asmlinkage ssize_t sys_mq_timedreceive(mqd_t mqdes, char __user *u_msg_ptr,
        if (unlikely(filp->f_op != &mqueue_file_operations))
                goto out_fput;
        info = MQUEUE_I(inode);
-       audit_inode(NULL, inode);
+       audit_inode(NULL, filp->f_path.dentry);
 
        if (unlikely(!(filp->f_mode & FMODE_READ)))
                goto out_fput;
@@ -1196,7 +1193,6 @@ static int msg_maxsize_limit_max = INT_MAX;
 
 static ctl_table mq_sysctls[] = {
        {
-               .ctl_name       = CTL_QUEUESMAX,
                .procname       = "queues_max",
                .data           = &queues_max,
                .maxlen         = sizeof(int),
@@ -1204,7 +1200,6 @@ static ctl_table mq_sysctls[] = {
                .proc_handler   = &proc_dointvec,
        },
        {
-               .ctl_name       = CTL_MSGMAX,
                .procname       = "msg_max",
                .data           = &msg_max,
                .maxlen         = sizeof(int),
@@ -1214,7 +1209,6 @@ static ctl_table mq_sysctls[] = {
                .extra2         = &msg_max_limit_max,
        },
        {
-               .ctl_name       = CTL_MSGSIZEMAX,
                .procname       = "msgsize_max",
                .data           = &msgsize_max,
                .maxlen         = sizeof(int),
@@ -1228,7 +1222,6 @@ static ctl_table mq_sysctls[] = {
 
 static ctl_table mq_sysctl_dir[] = {
        {
-               .ctl_name       = FS_MQUEUE,
                .procname       = "mqueue",
                .mode           = 0555,
                .child          = mq_sysctls,
index a03fcb522fff827df275ab75a7e2c76610e229b7..fdf3db5731ce8df2cfd038f40c69710243d85338 100644 (file)
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -34,7 +34,7 @@
 #include <linux/syscalls.h>
 #include <linux/audit.h>
 #include <linux/seq_file.h>
-#include <linux/mutex.h>
+#include <linux/rwsem.h>
 #include <linux/nsproxy.h>
 
 #include <asm/current.h>
@@ -66,23 +66,15 @@ struct msg_sender {
 #define SEARCH_NOTEQUAL                3
 #define SEARCH_LESSEQUAL       4
 
-static atomic_t msg_bytes =    ATOMIC_INIT(0);
-static atomic_t msg_hdrs =     ATOMIC_INIT(0);
-
 static struct ipc_ids init_msg_ids;
 
 #define msg_ids(ns)    (*((ns)->ids[IPC_MSG_IDS]))
 
-#define msg_lock(ns, id)       ((struct msg_queue*)ipc_lock(&msg_ids(ns), id))
 #define msg_unlock(msq)                ipc_unlock(&(msq)->q_perm)
-#define msg_rmid(ns, id)       ((struct msg_queue*)ipc_rmid(&msg_ids(ns), id))
-#define msg_checkid(ns, msq, msgid)    \
-       ipc_checkid(&msg_ids(ns), &msq->q_perm, msgid)
-#define msg_buildid(ns, id, seq) \
-       ipc_buildid(&msg_ids(ns), id, seq)
-
-static void freeque (struct ipc_namespace *ns, struct msg_queue *msq, int id);
-static int newque (struct ipc_namespace *ns, key_t key, int msgflg);
+#define msg_buildid(id, seq)   ipc_buildid(id, seq)
+
+static void freeque(struct ipc_namespace *, struct msg_queue *);
+static int newque(struct ipc_namespace *, struct ipc_params *);
 #ifdef CONFIG_PROC_FS
 static int sysvipc_msg_proc_show(struct seq_file *s, void *it);
 #endif
@@ -93,7 +85,9 @@ static void __msg_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids)
        ns->msg_ctlmax = MSGMAX;
        ns->msg_ctlmnb = MSGMNB;
        ns->msg_ctlmni = MSGMNI;
-       ipc_init_ids(ids, ns->msg_ctlmni);
+       atomic_set(&ns->msg_bytes, 0);
+       atomic_set(&ns->msg_hdrs, 0);
+       ipc_init_ids(ids);
 }
 
 int msg_init_ns(struct ipc_namespace *ns)
@@ -110,20 +104,25 @@ int msg_init_ns(struct ipc_namespace *ns)
 
 void msg_exit_ns(struct ipc_namespace *ns)
 {
-       int i;
        struct msg_queue *msq;
+       int next_id;
+       int total, in_use;
+
+       down_write(&msg_ids(ns).rw_mutex);
+
+       in_use = msg_ids(ns).in_use;
 
-       mutex_lock(&msg_ids(ns).mutex);
-       for (i = 0; i <= msg_ids(ns).max_id; i++) {
-               msq = msg_lock(ns, i);
+       for (total = 0, next_id = 0; total < in_use; next_id++) {
+               msq = idr_find(&msg_ids(ns).ipcs_idr, next_id);
                if (msq == NULL)
                        continue;
-
-               freeque(ns, msq, i);
+               ipc_lock_by_ptr(&msq->q_perm);
+               freeque(ns, msq);
+               total++;
        }
-       mutex_unlock(&msg_ids(ns).mutex);
 
-       ipc_fini_ids(ns->ids[IPC_MSG_IDS]);
+       up_write(&msg_ids(ns).rw_mutex);
+
        kfree(ns->ids[IPC_MSG_IDS]);
        ns->ids[IPC_MSG_IDS] = NULL;
 }
@@ -136,10 +135,55 @@ void __init msg_init(void)
                                IPC_MSG_IDS, sysvipc_msg_proc_show);
 }
 
-static int newque (struct ipc_namespace *ns, key_t key, int msgflg)
+/*
+ * This routine is called in the paths where the rw_mutex is held to protect
+ * access to the idr tree.
+ */
+static inline struct msg_queue *msg_lock_check_down(struct ipc_namespace *ns,
+                                               int id)
+{
+       struct kern_ipc_perm *ipcp = ipc_lock_check_down(&msg_ids(ns), id);
+
+       return container_of(ipcp, struct msg_queue, q_perm);
+}
+
+/*
+ * msg_lock_(check_) routines are called in the paths where the rw_mutex
+ * is not held.
+ */
+static inline struct msg_queue *msg_lock(struct ipc_namespace *ns, int id)
+{
+       struct kern_ipc_perm *ipcp = ipc_lock(&msg_ids(ns), id);
+
+       return container_of(ipcp, struct msg_queue, q_perm);
+}
+
+static inline struct msg_queue *msg_lock_check(struct ipc_namespace *ns,
+                                               int id)
+{
+       struct kern_ipc_perm *ipcp = ipc_lock_check(&msg_ids(ns), id);
+
+       return container_of(ipcp, struct msg_queue, q_perm);
+}
+
+static inline void msg_rmid(struct ipc_namespace *ns, struct msg_queue *s)
+{
+       ipc_rmid(&msg_ids(ns), &s->q_perm);
+}
+
+/**
+ * newque - Create a new msg queue
+ * @ns: namespace
+ * @params: ptr to the structure that contains the key and msgflg
+ *
+ * Called with msg_ids.rw_mutex held (writer)
+ */
+static int newque(struct ipc_namespace *ns, struct ipc_params *params)
 {
        struct msg_queue *msq;
        int id, retval;
+       key_t key = params->key;
+       int msgflg = params->flg;
 
        msq = ipc_rcu_alloc(sizeof(*msq));
        if (!msq)
@@ -155,14 +199,17 @@ static int newque (struct ipc_namespace *ns, key_t key, int msgflg)
                return retval;
        }
 
+       /*
+        * ipc_addid() locks msq
+        */
        id = ipc_addid(&msg_ids(ns), &msq->q_perm, ns->msg_ctlmni);
-       if (id == -1) {
+       if (id < 0) {
                security_msg_queue_free(msq);
                ipc_rcu_putref(msq);
-               return -ENOSPC;
+               return id;
        }
 
-       msq->q_id = msg_buildid(ns, id, msq->q_perm.seq);
+       msq->q_perm.id = msg_buildid(id, msq->q_perm.seq);
        msq->q_stime = msq->q_rtime = 0;
        msq->q_ctime = get_seconds();
        msq->q_cbytes = msq->q_qnum = 0;
@@ -171,9 +218,10 @@ static int newque (struct ipc_namespace *ns, key_t key, int msgflg)
        INIT_LIST_HEAD(&msq->q_messages);
        INIT_LIST_HEAD(&msq->q_receivers);
        INIT_LIST_HEAD(&msq->q_senders);
+
        msg_unlock(msq);
 
-       return msq->q_id;
+       return msq->q_perm.id;
 }
 
 static inline void ss_add(struct msg_queue *msq, struct msg_sender *mss)
@@ -224,19 +272,19 @@ static void expunge_all(struct msg_queue *msq, int res)
 
 /*
  * freeque() wakes up waiters on the sender and receiver waiting queue,
- * removes the message queue from message queue ID
- * array, and cleans up all the messages associated with this queue.
+ * removes the message queue from message queue ID IDR, and cleans up all the
+ * messages associated with this queue.
  *
- * msg_ids.mutex and the spinlock for this message queue is hold
- * before freeque() is called. msg_ids.mutex remains locked on exit.
+ * msg_ids.rw_mutex (writer) and the spinlock for this message queue are held
+ * before freeque() is called. msg_ids.rw_mutex remains locked on exit.
  */
-static void freeque(struct ipc_namespace *ns, struct msg_queue *msq, int id)
+static void freeque(struct ipc_namespace *ns, struct msg_queue *msq)
 {
        struct list_head *tmp;
 
        expunge_all(msq, -EIDRM);
        ss_wakeup(&msq->q_senders, 1);
-       msq = msg_rmid(ns, id);
+       msg_rmid(ns, msq);
        msg_unlock(msq);
 
        tmp = msq->q_messages.next;
@@ -244,49 +292,40 @@ static void freeque(struct ipc_namespace *ns, struct msg_queue *msq, int id)
                struct msg_msg *msg = list_entry(tmp, struct msg_msg, m_list);
 
                tmp = tmp->next;
-               atomic_dec(&msg_hdrs);
+               atomic_dec(&ns->msg_hdrs);
                free_msg(msg);
        }
-       atomic_sub(msq->q_cbytes, &msg_bytes);
+       atomic_sub(msq->q_cbytes, &ns->msg_bytes);
        security_msg_queue_free(msq);
        ipc_rcu_putref(msq);
 }
 
+/*
+ * Called with msg_ids.rw_mutex and ipcp locked.
+ */
+static inline int msg_security(struct kern_ipc_perm *ipcp, int msgflg)
+{
+       struct msg_queue *msq = container_of(ipcp, struct msg_queue, q_perm);
+
+       return security_msg_queue_associate(msq, msgflg);
+}
+
 asmlinkage long sys_msgget(key_t key, int msgflg)
 {
-       struct msg_queue *msq;
-       int id, ret = -EPERM;
        struct ipc_namespace *ns;
+       struct ipc_ops msg_ops;
+       struct ipc_params msg_params;
 
        ns = current->nsproxy->ipc_ns;
-       
-       mutex_lock(&msg_ids(ns).mutex);
-       if (key == IPC_PRIVATE) 
-               ret = newque(ns, key, msgflg);
-       else if ((id = ipc_findkey(&msg_ids(ns), key)) == -1) { /* key not used */
-               if (!(msgflg & IPC_CREAT))
-                       ret = -ENOENT;
-               else
-                       ret = newque(ns, key, msgflg);
-       } else if (msgflg & IPC_CREAT && msgflg & IPC_EXCL) {
-               ret = -EEXIST;
-       } else {
-               msq = msg_lock(ns, id);
-               BUG_ON(msq == NULL);
-               if (ipcperms(&msq->q_perm, msgflg))
-                       ret = -EACCES;
-               else {
-                       int qid = msg_buildid(ns, id, msq->q_perm.seq);
-
-                       ret = security_msg_queue_associate(msq, msgflg);
-                       if (!ret)
-                               ret = qid;
-               }
-               msg_unlock(msq);
-       }
-       mutex_unlock(&msg_ids(ns).mutex);
 
-       return ret;
+       msg_ops.getnew = newque;
+       msg_ops.associate = msg_security;
+       msg_ops.more_checks = NULL;
+
+       msg_params.key = key;
+       msg_params.flg = msgflg;
+
+       return ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
 }
 
 static inline unsigned long
@@ -420,23 +459,23 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
                msginfo.msgmnb = ns->msg_ctlmnb;
                msginfo.msgssz = MSGSSZ;
                msginfo.msgseg = MSGSEG;
-               mutex_lock(&msg_ids(ns).mutex);
+               down_read(&msg_ids(ns).rw_mutex);
                if (cmd == MSG_INFO) {
                        msginfo.msgpool = msg_ids(ns).in_use;
-                       msginfo.msgmap = atomic_read(&msg_hdrs);
-                       msginfo.msgtql = atomic_read(&msg_bytes);
+                       msginfo.msgmap = atomic_read(&ns->msg_hdrs);
+                       msginfo.msgtql = atomic_read(&ns->msg_bytes);
                } else {
                        msginfo.msgmap = MSGMAP;
                        msginfo.msgpool = MSGPOOL;
                        msginfo.msgtql = MSGTQL;
                }
-               max_id = msg_ids(ns).max_id;
-               mutex_unlock(&msg_ids(ns).mutex);
+               max_id = ipc_get_maxid(&msg_ids(ns));
+               up_read(&msg_ids(ns).rw_mutex);
                if (copy_to_user(buf, &msginfo, sizeof(struct msginfo)))
                        return -EFAULT;
                return (max_id < 0) ? 0 : max_id;
        }
-       case MSG_STAT:
+       case MSG_STAT:  /* msqid is an index rather than a msg queue id */
        case IPC_STAT:
        {
                struct msqid64_ds tbuf;
@@ -444,21 +483,16 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
 
                if (!buf)
                        return -EFAULT;
-               if (cmd == MSG_STAT && msqid >= msg_ids(ns).entries->size)
-                       return -EINVAL;
-
-               memset(&tbuf, 0, sizeof(tbuf));
-
-               msq = msg_lock(ns, msqid);
-               if (msq == NULL)
-                       return -EINVAL;
 
                if (cmd == MSG_STAT) {
-                       success_return = msg_buildid(ns, msqid, msq->q_perm.seq);
+                       msq = msg_lock(ns, msqid);
+                       if (IS_ERR(msq))
+                               return PTR_ERR(msq);
+                       success_return = msq->q_perm.id;
                } else {
-                       err = -EIDRM;
-                       if (msg_checkid(ns, msq, msqid))
-                               goto out_unlock;
+                       msq = msg_lock_check(ns, msqid);
+                       if (IS_ERR(msq))
+                               return PTR_ERR(msq);
                        success_return = 0;
                }
                err = -EACCES;
@@ -469,6 +503,8 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
                if (err)
                        goto out_unlock;
 
+               memset(&tbuf, 0, sizeof(tbuf));
+
                kernel_to_ipc64_perm(&msq->q_perm, &tbuf.msg_perm);
                tbuf.msg_stime  = msq->q_stime;
                tbuf.msg_rtime  = msq->q_rtime;
@@ -495,15 +531,13 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
                return  -EINVAL;
        }
 
-       mutex_lock(&msg_ids(ns).mutex);
-       msq = msg_lock(ns, msqid);
-       err = -EINVAL;
-       if (msq == NULL)
+       down_write(&msg_ids(ns).rw_mutex);
+       msq = msg_lock_check_down(ns, msqid);
+       if (IS_ERR(msq)) {
+               err = PTR_ERR(msq);
                goto out_up;
+       }
 
-       err = -EIDRM;
-       if (msg_checkid(ns, msq, msqid))
-               goto out_unlock_up;
        ipcp = &msq->q_perm;
 
        err = audit_ipc_obj(ipcp);
@@ -552,12 +586,12 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
                break;
        }
        case IPC_RMID:
-               freeque(ns, msq, msqid);
+               freeque(ns, msq);
                break;
        }
        err = 0;
 out_up:
-       mutex_unlock(&msg_ids(ns).mutex);
+       up_write(&msg_ids(ns).rw_mutex);
        return err;
 out_unlock_up:
        msg_unlock(msq);
@@ -611,7 +645,7 @@ static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg)
                                msr->r_msg = ERR_PTR(-E2BIG);
                        } else {
                                msr->r_msg = NULL;
-                               msq->q_lrpid = msr->r_tsk->pid;
+                               msq->q_lrpid = task_pid_vnr(msr->r_tsk);
                                msq->q_rtime = get_seconds();
                                wake_up_process(msr->r_tsk);
                                smp_mb();
@@ -646,14 +680,11 @@ long do_msgsnd(int msqid, long mtype, void __user *mtext,
        msg->m_type = mtype;
        msg->m_ts = msgsz;
 
-       msq = msg_lock(ns, msqid);
-       err = -EINVAL;
-       if (msq == NULL)
+       msq = msg_lock_check(ns, msqid);
+       if (IS_ERR(msq)) {
+               err = PTR_ERR(msq);
                goto out_free;
-
-       err= -EIDRM;
-       if (msg_checkid(ns, msq, msqid))
-               goto out_unlock_free;
+       }
 
        for (;;) {
                struct msg_sender s;
@@ -695,7 +726,7 @@ long do_msgsnd(int msqid, long mtype, void __user *mtext,
                }
        }
 
-       msq->q_lspid = current->tgid;
+       msq->q_lspid = task_tgid_vnr(current);
        msq->q_stime = get_seconds();
 
        if (!pipelined_send(msq, msg)) {
@@ -703,8 +734,8 @@ long do_msgsnd(int msqid, long mtype, void __user *mtext,
                list_add_tail(&msg->m_list, &msq->q_messages);
                msq->q_cbytes += msgsz;
                msq->q_qnum++;
-               atomic_add(msgsz, &msg_bytes);
-               atomic_inc(&msg_hdrs);
+               atomic_add(msgsz, &ns->msg_bytes);
+               atomic_inc(&ns->msg_hdrs);
        }
 
        err = 0;
@@ -760,13 +791,9 @@ long do_msgrcv(int msqid, long *pmtype, void __user *mtext,
        mode = convert_mode(&msgtyp, msgflg);
        ns = current->nsproxy->ipc_ns;
 
-       msq = msg_lock(ns, msqid);
-       if (msq == NULL)
-               return -EINVAL;
-
-       msg = ERR_PTR(-EIDRM);
-       if (msg_checkid(ns, msq, msqid))
-               goto out_unlock;
+       msq = msg_lock_check(ns, msqid);
+       if (IS_ERR(msq))
+               return PTR_ERR(msq);
 
        for (;;) {
                struct msg_receiver msr_d;
@@ -810,10 +837,10 @@ long do_msgrcv(int msqid, long *pmtype, void __user *mtext,
                        list_del(&msg->m_list);
                        msq->q_qnum--;
                        msq->q_rtime = get_seconds();
-                       msq->q_lrpid = current->tgid;
+                       msq->q_lrpid = task_tgid_vnr(current);
                        msq->q_cbytes -= msg->m_ts;
-                       atomic_sub(msg->m_ts, &msg_bytes);
-                       atomic_dec(&msg_hdrs);
+                       atomic_sub(msg->m_ts, &ns->msg_bytes);
+                       atomic_dec(&ns->msg_hdrs);
                        ss_wakeup(&msq->q_senders, 0);
                        msg_unlock(msq);
                        break;
@@ -926,7 +953,7 @@ static int sysvipc_msg_proc_show(struct seq_file *s, void *it)
        return seq_printf(s,
                        "%10d %10d  %4o  %10lu %10lu %5u %5u %5u %5u %5u %5u %10lu %10lu %10lu\n",
                        msq->q_perm.key,
-                       msq->q_id,
+                       msq->q_perm.id,
                        msq->q_perm.mode,
                        msq->q_cbytes,
                        msq->q_qnum,
index b676fef6d208b563dfe52929f6ef8a491860a928..35952c0bae4629cac017c4c62623c91a022ebee5 100644 (file)
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -80,7 +80,7 @@
 #include <linux/audit.h>
 #include <linux/capability.h>
 #include <linux/seq_file.h>
-#include <linux/mutex.h>
+#include <linux/rwsem.h>
 #include <linux/nsproxy.h>
 
 #include <asm/uaccess.h>
 
 #define sem_ids(ns)    (*((ns)->ids[IPC_SEM_IDS]))
 
-#define sem_lock(ns, id)       ((struct sem_array*)ipc_lock(&sem_ids(ns), id))
 #define sem_unlock(sma)                ipc_unlock(&(sma)->sem_perm)
-#define sem_rmid(ns, id)       ((struct sem_array*)ipc_rmid(&sem_ids(ns), id))
-#define sem_checkid(ns, sma, semid)    \
-       ipc_checkid(&sem_ids(ns),&sma->sem_perm,semid)
-#define sem_buildid(ns, id, seq) \
-       ipc_buildid(&sem_ids(ns), id, seq)
+#define sem_checkid(sma, semid)        ipc_checkid(&sma->sem_perm, semid)
+#define sem_buildid(id, seq)   ipc_buildid(id, seq)
 
 static struct ipc_ids init_sem_ids;
 
-static int newary(struct ipc_namespace *, key_t, int, int);
-static void freeary(struct ipc_namespace *ns, struct sem_array *sma, int id);
+static int newary(struct ipc_namespace *, struct ipc_params *);
+static void freeary(struct ipc_namespace *, struct sem_array *);
 #ifdef CONFIG_PROC_FS
 static int sysvipc_sem_proc_show(struct seq_file *s, void *it);
 #endif
@@ -129,7 +125,7 @@ static void __sem_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids)
        ns->sc_semopm = SEMOPM;
        ns->sc_semmni = SEMMNI;
        ns->used_sems = 0;
-       ipc_init_ids(ids, ns->sc_semmni);
+       ipc_init_ids(ids);
 }
 
 int sem_init_ns(struct ipc_namespace *ns)
@@ -146,20 +142,24 @@ int sem_init_ns(struct ipc_namespace *ns)
 
 void sem_exit_ns(struct ipc_namespace *ns)
 {
-       int i;
        struct sem_array *sma;
+       int next_id;
+       int total, in_use;
 
-       mutex_lock(&sem_ids(ns).mutex);
-       for (i = 0; i <= sem_ids(ns).max_id; i++) {
-               sma = sem_lock(ns, i);
+       down_write(&sem_ids(ns).rw_mutex);
+
+       in_use = sem_ids(ns).in_use;
+
+       for (total = 0, next_id = 0; total < in_use; next_id++) {
+               sma = idr_find(&sem_ids(ns).ipcs_idr, next_id);
                if (sma == NULL)
                        continue;
-
-               freeary(ns, sma, i);
+               ipc_lock_by_ptr(&sma->sem_perm);
+               freeary(ns, sma);
+               total++;
        }
-       mutex_unlock(&sem_ids(ns).mutex);
+       up_write(&sem_ids(ns).rw_mutex);
 
-       ipc_fini_ids(ns->ids[IPC_SEM_IDS]);
        kfree(ns->ids[IPC_SEM_IDS]);
        ns->ids[IPC_SEM_IDS] = NULL;
 }
@@ -172,6 +172,42 @@ void __init sem_init (void)
                                IPC_SEM_IDS, sysvipc_sem_proc_show);
 }
 
+/*
+ * This routine is called in the paths where the rw_mutex is held to protect
+ * access to the idr tree.
+ */
+static inline struct sem_array *sem_lock_check_down(struct ipc_namespace *ns,
+                                               int id)
+{
+       struct kern_ipc_perm *ipcp = ipc_lock_check_down(&sem_ids(ns), id);
+
+       return container_of(ipcp, struct sem_array, sem_perm);
+}
+
+/*
+ * sem_lock_(check_) routines are called in the paths where the rw_mutex
+ * is not held.
+ */
+static inline struct sem_array *sem_lock(struct ipc_namespace *ns, int id)
+{
+       struct kern_ipc_perm *ipcp = ipc_lock(&sem_ids(ns), id);
+
+       return container_of(ipcp, struct sem_array, sem_perm);
+}
+
+static inline struct sem_array *sem_lock_check(struct ipc_namespace *ns,
+                                               int id)
+{
+       struct kern_ipc_perm *ipcp = ipc_lock_check(&sem_ids(ns), id);
+
+       return container_of(ipcp, struct sem_array, sem_perm);
+}
+
+static inline void sem_rmid(struct ipc_namespace *ns, struct sem_array *s)
+{
+       ipc_rmid(&sem_ids(ns), &s->sem_perm);
+}
+
 /*
  * Lockless wakeup algorithm:
  * Without the check/retry algorithm a lockless wakeup is possible:
@@ -206,12 +242,23 @@ void __init sem_init (void)
  */
 #define IN_WAKEUP      1
 
-static int newary (struct ipc_namespace *ns, key_t key, int nsems, int semflg)
+/**
+ * newary - Create a new semaphore set
+ * @ns: namespace
+ * @params: ptr to the structure that contains key, semflg and nsems
+ *
+ * Called with sem_ids.rw_mutex held (as a writer)
+ */
+
+static int newary(struct ipc_namespace *ns, struct ipc_params *params)
 {
        int id;
        int retval;
        struct sem_array *sma;
        int size;
+       key_t key = params->key;
+       int nsems = params->u.nsems;
+       int semflg = params->flg;
 
        if (!nsems)
                return -EINVAL;
@@ -236,14 +283,14 @@ static int newary (struct ipc_namespace *ns, key_t key, int nsems, int semflg)
        }
 
        id = ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni);
-       if(id == -1) {
+       if (id < 0) {
                security_sem_free(sma);
                ipc_rcu_putref(sma);
-               return -ENOSPC;
+               return id;
        }
        ns->used_sems += nsems;
 
-       sma->sem_id = sem_buildid(ns, id, sma->sem_perm.seq);
+       sma->sem_perm.id = sem_buildid(id, sma->sem_perm.seq);
        sma->sem_base = (struct sem *) &sma[1];
        /* sma->sem_pending = NULL; */
        sma->sem_pending_last = &sma->sem_pending;
@@ -252,48 +299,56 @@ static int newary (struct ipc_namespace *ns, key_t key, int nsems, int semflg)
        sma->sem_ctime = get_seconds();
        sem_unlock(sma);
 
-       return sma->sem_id;
+       return sma->sem_perm.id;
+}
+
+
+/*
+ * Called with sem_ids.rw_mutex and ipcp locked.
+ */
+static inline int sem_security(struct kern_ipc_perm *ipcp, int semflg)
+{
+       struct sem_array *sma;
+
+       sma = container_of(ipcp, struct sem_array, sem_perm);
+       return security_sem_associate(sma, semflg);
 }
 
-asmlinkage long sys_semget (key_t key, int nsems, int semflg)
+/*
+ * Called with sem_ids.rw_mutex and ipcp locked.
+ */
+static inline int sem_more_checks(struct kern_ipc_perm *ipcp,
+                               struct ipc_params *params)
 {
-       int id, err = -EINVAL;
        struct sem_array *sma;
+
+       sma = container_of(ipcp, struct sem_array, sem_perm);
+       if (params->u.nsems > sma->sem_nsems)
+               return -EINVAL;
+
+       return 0;
+}
+
+asmlinkage long sys_semget(key_t key, int nsems, int semflg)
+{
        struct ipc_namespace *ns;
+       struct ipc_ops sem_ops;
+       struct ipc_params sem_params;
 
        ns = current->nsproxy->ipc_ns;
 
        if (nsems < 0 || nsems > ns->sc_semmsl)
                return -EINVAL;
-       mutex_lock(&sem_ids(ns).mutex);
-       
-       if (key == IPC_PRIVATE) {
-               err = newary(ns, key, nsems, semflg);
-       } else if ((id = ipc_findkey(&sem_ids(ns), key)) == -1) {  /* key not used */
-               if (!(semflg & IPC_CREAT))
-                       err = -ENOENT;
-               else
-                       err = newary(ns, key, nsems, semflg);
-       } else if (semflg & IPC_CREAT && semflg & IPC_EXCL) {
-               err = -EEXIST;
-       } else {
-               sma = sem_lock(ns, id);
-               BUG_ON(sma==NULL);
-               if (nsems > sma->sem_nsems)
-                       err = -EINVAL;
-               else if (ipcperms(&sma->sem_perm, semflg))
-                       err = -EACCES;
-               else {
-                       int semid = sem_buildid(ns, id, sma->sem_perm.seq);
-                       err = security_sem_associate(sma, semflg);
-                       if (!err)
-                               err = semid;
-               }
-               sem_unlock(sma);
-       }
 
-       mutex_unlock(&sem_ids(ns).mutex);
-       return err;
+       sem_ops.getnew = newary;
+       sem_ops.associate = sem_security;
+       sem_ops.more_checks = sem_more_checks;
+
+       sem_params.key = key;
+       sem_params.flg = semflg;
+       sem_params.u.nsems = nsems;
+
+       return ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
 }
 
 /* Manage the doubly linked list sma->sem_pending as a FIFO:
@@ -487,15 +542,14 @@ static int count_semzcnt (struct sem_array * sma, ushort semnum)
        return semzcnt;
 }
 
-/* Free a semaphore set. freeary() is called with sem_ids.mutex locked and
- * the spinlock for this semaphore set hold. sem_ids.mutex remains locked
- * on exit.
+/* Free a semaphore set. freeary() is called with sem_ids.rw_mutex locked
+ * as a writer and the spinlock for this semaphore set hold. sem_ids.rw_mutex
+ * remains locked on exit.
  */
-static void freeary (struct ipc_namespace *ns, struct sem_array *sma, int id)
+static void freeary(struct ipc_namespace *ns, struct sem_array *sma)
 {
        struct sem_undo *un;
        struct sem_queue *q;
-       int size;
 
        /* Invalidate the existing undo structures for this semaphore set.
         * (They will be freed without any further action in exit_sem()
@@ -518,12 +572,11 @@ static void freeary (struct ipc_namespace *ns, struct sem_array *sma, int id)
                q = n;
        }
 
-       /* Remove the semaphore set from the ID array*/
-       sma = sem_rmid(ns, id);
+       /* Remove the semaphore set from the ID*/
+       sem_rmid(ns, sma);
        sem_unlock(sma);
 
        ns->used_sems -= sma->sem_nsems;
-       size = sizeof (*sma) + sma->sem_nsems * sizeof (struct sem);
        security_sem_free(sma);
        ipc_rcu_putref(sma);
 }
@@ -576,7 +629,7 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid, int semnum,
                seminfo.semmnu = SEMMNU;
                seminfo.semmap = SEMMAP;
                seminfo.semume = SEMUME;
-               mutex_lock(&sem_ids(ns).mutex);
+               down_read(&sem_ids(ns).rw_mutex);
                if (cmd == SEM_INFO) {
                        seminfo.semusz = sem_ids(ns).in_use;
                        seminfo.semaem = ns->used_sems;
@@ -584,8 +637,8 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid, int semnum,
                        seminfo.semusz = SEMUSZ;
                        seminfo.semaem = SEMAEM;
                }
-               max_id = sem_ids(ns).max_id;
-               mutex_unlock(&sem_ids(ns).mutex);
+               max_id = ipc_get_maxid(&sem_ids(ns));
+               up_read(&sem_ids(ns).rw_mutex);
                if (copy_to_user (arg.__buf, &seminfo, sizeof(struct seminfo))) 
                        return -EFAULT;
                return (max_id < 0) ? 0: max_id;
@@ -595,14 +648,9 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid, int semnum,
                struct semid64_ds tbuf;
                int id;
 
-               if(semid >= sem_ids(ns).entries->size)
-                       return -EINVAL;
-
-               memset(&tbuf,0,sizeof(tbuf));
-
                sma = sem_lock(ns, semid);
-               if(sma == NULL)
-                       return -EINVAL;
+               if (IS_ERR(sma))
+                       return PTR_ERR(sma);
 
                err = -EACCES;
                if (ipcperms (&sma->sem_perm, S_IRUGO))
@@ -612,7 +660,9 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid, int semnum,
                if (err)
                        goto out_unlock;
 
-               id = sem_buildid(ns, semid, sma->sem_perm.seq);
+               id = sma->sem_perm.id;
+
+               memset(&tbuf, 0, sizeof(tbuf));
 
                kernel_to_ipc64_perm(&sma->sem_perm, &tbuf.sem_perm);
                tbuf.sem_otime  = sma->sem_otime;
@@ -642,16 +692,12 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
        ushort* sem_io = fast_sem_io;
        int nsems;
 
-       sma = sem_lock(ns, semid);
-       if(sma==NULL)
-               return -EINVAL;
+       sma = sem_lock_check(ns, semid);
+       if (IS_ERR(sma))
+               return PTR_ERR(sma);
 
        nsems = sma->sem_nsems;
 
-       err=-EIDRM;
-       if (sem_checkid(ns,sma,semid))
-               goto out_unlock;
-
        err = -EACCES;
        if (ipcperms (&sma->sem_perm, (cmd==SETVAL||cmd==SETALL)?S_IWUGO:S_IRUGO))
                goto out_unlock;
@@ -795,7 +841,7 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
                for (un = sma->undo; un; un = un->id_next)
                        un->semadj[semnum] = 0;
                curr->semval = val;
-               curr->sempid = current->tgid;
+               curr->sempid = task_tgid_vnr(current);
                sma->sem_ctime = get_seconds();
                /* maybe some queued-up processes were waiting for this */
                update_queue(sma);
@@ -863,14 +909,10 @@ static int semctl_down(struct ipc_namespace *ns, int semid, int semnum,
                if(copy_semid_from_user (&setbuf, arg.buf, version))
                        return -EFAULT;
        }
-       sma = sem_lock(ns, semid);
-       if(sma==NULL)
-               return -EINVAL;
+       sma = sem_lock_check_down(ns, semid);
+       if (IS_ERR(sma))
+               return PTR_ERR(sma);
 
-       if (sem_checkid(ns,sma,semid)) {
-               err=-EIDRM;
-               goto out_unlock;
-       }       
        ipcp = &sma->sem_perm;
 
        err = audit_ipc_obj(ipcp);
@@ -894,7 +936,7 @@ static int semctl_down(struct ipc_namespace *ns, int semid, int semnum,
 
        switch(cmd){
        case IPC_RMID:
-               freeary(ns, sma, semid);
+               freeary(ns, sma);
                err = 0;
                break;
        case IPC_SET:
@@ -948,45 +990,15 @@ asmlinkage long sys_semctl (int semid, int semnum, int cmd, union semun arg)
                return err;
        case IPC_RMID:
        case IPC_SET:
-               mutex_lock(&sem_ids(ns).mutex);
+               down_write(&sem_ids(ns).rw_mutex);
                err = semctl_down(ns,semid,semnum,cmd,version,arg);
-               mutex_unlock(&sem_ids(ns).mutex);
+               up_write(&sem_ids(ns).rw_mutex);
                return err;
        default:
                return -EINVAL;
        }
 }
 
-static inline void lock_semundo(void)
-{
-       struct sem_undo_list *undo_list;
-
-       undo_list = current->sysvsem.undo_list;
-       if (undo_list)
-               spin_lock(&undo_list->lock);
-}
-
-/* This code has an interaction with copy_semundo().
- * Consider; two tasks are sharing the undo_list. task1
- * acquires the undo_list lock in lock_semundo().  If task2 now
- * exits before task1 releases the lock (by calling
- * unlock_semundo()), then task1 will never call spin_unlock().
- * This leave the sem_undo_list in a locked state.  If task1 now creats task3
- * and once again shares the sem_undo_list, the sem_undo_list will still be
- * locked, and future SEM_UNDO operations will deadlock.  This case is
- * dealt with in copy_semundo() by having it reinitialize the spin lock when 
- * the refcnt goes from 1 to 2.
- */
-static inline void unlock_semundo(void)
-{
-       struct sem_undo_list *undo_list;
-
-       undo_list = current->sysvsem.undo_list;
-       if (undo_list)
-               spin_unlock(&undo_list->lock);
-}
-
-
 /* If the task doesn't already have a undo_list, then allocate one
  * here.  We guarantee there is only one thread using this undo list,
  * and current is THE ONE
@@ -1047,22 +1059,17 @@ static struct sem_undo *find_undo(struct ipc_namespace *ns, int semid)
        if (error)
                return ERR_PTR(error);
 
-       lock_semundo();
+       spin_lock(&ulp->lock);
        un = lookup_undo(ulp, semid);
-       unlock_semundo();
+       spin_unlock(&ulp->lock);
        if (likely(un!=NULL))
                goto out;
 
        /* no undo structure around - allocate one. */
-       sma = sem_lock(ns, semid);
-       un = ERR_PTR(-EINVAL);
-       if(sma==NULL)
-               goto out;
-       un = ERR_PTR(-EIDRM);
-       if (sem_checkid(ns,sma,semid)) {
-               sem_unlock(sma);
-               goto out;
-       }
+       sma = sem_lock_check(ns, semid);
+       if (IS_ERR(sma))
+               return ERR_PTR(PTR_ERR(sma));
+
        nsems = sma->sem_nsems;
        ipc_rcu_getref(sma);
        sem_unlock(sma);
@@ -1077,10 +1084,10 @@ static struct sem_undo *find_undo(struct ipc_namespace *ns, int semid)
        new->semadj = (short *) &new[1];
        new->semid = semid;
 
-       lock_semundo();
+       spin_lock(&ulp->lock);
        un = lookup_undo(ulp, semid);
        if (un) {
-               unlock_semundo();
+               spin_unlock(&ulp->lock);
                kfree(new);
                ipc_lock_by_ptr(&sma->sem_perm);
                ipc_rcu_putref(sma);
@@ -1091,7 +1098,7 @@ static struct sem_undo *find_undo(struct ipc_namespace *ns, int semid)
        ipc_rcu_putref(sma);
        if (sma->sem_perm.deleted) {
                sem_unlock(sma);
-               unlock_semundo();
+               spin_unlock(&ulp->lock);
                kfree(new);
                un = ERR_PTR(-EIDRM);
                goto out;
@@ -1102,7 +1109,7 @@ static struct sem_undo *find_undo(struct ipc_namespace *ns, int semid)
        sma->undo = new;
        sem_unlock(sma);
        un = new;
-       unlock_semundo();
+       spin_unlock(&ulp->lock);
 out:
        return un;
 }
@@ -1168,15 +1175,14 @@ retry_undos:
        } else
                un = NULL;
 
-       sma = sem_lock(ns, semid);
-       error=-EINVAL;
-       if(sma==NULL)
+       sma = sem_lock_check(ns, semid);
+       if (IS_ERR(sma)) {
+               error = PTR_ERR(sma);
                goto out_free;
-       error = -EIDRM;
-       if (sem_checkid(ns,sma,semid))
-               goto out_unlock_free;
+       }
+
        /*
-        * semid identifies are not unique - find_undo may have
+        * semid identifiers are not unique - find_undo may have
         * allocated an undo structure, it was invalidated by an RMID
         * and now a new array with received the same id. Check and retry.
         */
@@ -1196,7 +1202,7 @@ retry_undos:
        if (error)
                goto out_unlock_free;
 
-       error = try_atomic_semop (sma, sops, nsops, un, current->tgid);
+       error = try_atomic_semop (sma, sops, nsops, un, task_tgid_vnr(current));
        if (error <= 0) {
                if (alter && error == 0)
                        update_queue (sma);
@@ -1211,7 +1217,7 @@ retry_undos:
        queue.sops = sops;
        queue.nsops = nsops;
        queue.undo = un;
-       queue.pid = current->tgid;
+       queue.pid = task_tgid_vnr(current);
        queue.id = semid;
        queue.alter = alter;
        if (alter)
@@ -1242,7 +1248,7 @@ retry_undos:
        }
 
        sma = sem_lock(ns, semid);
-       if(sma==NULL) {
+       if (IS_ERR(sma)) {
                BUG_ON(queue.prev != NULL);
                error = -EIDRM;
                goto out_free;
@@ -1279,10 +1285,6 @@ asmlinkage long sys_semop (int semid, struct sembuf __user *tsops, unsigned nsop
 
 /* If CLONE_SYSVSEM is set, establish sharing of SEM_UNDO state between
  * parent and child tasks.
- *
- * See the notes above unlock_semundo() regarding the spin_lock_init()
- * in this code.  Initialize the undo_list->lock here instead of get_undo_list()
- * because of the reasoning in the comment above unlock_semundo.
  */
 
 int copy_semundo(unsigned long clone_flags, struct task_struct *tsk)
@@ -1342,13 +1344,13 @@ void exit_sem(struct task_struct *tsk)
                if(semid == -1)
                        continue;
                sma = sem_lock(ns, semid);
-               if (sma == NULL)
+               if (IS_ERR(sma))
                        continue;
 
                if (u->semid == -1)
                        goto next_entry;
 
-               BUG_ON(sem_checkid(ns,sma,u->semid));
+               BUG_ON(sem_checkid(sma, u->semid));
 
                /* remove u from the sma->undo list */
                for (unp = &sma->undo; (un = *unp); unp = &un->id_next) {
@@ -1382,7 +1384,7 @@ found:
                                        semaphore->semval = 0;
                                if (semaphore->semval > SEMVMX)
                                        semaphore->semval = SEMVMX;
-                               semaphore->sempid = current->tgid;
+                               semaphore->sempid = task_tgid_vnr(current);
                        }
                }
                sma->sem_otime = get_seconds();
@@ -1402,7 +1404,7 @@ static int sysvipc_sem_proc_show(struct seq_file *s, void *it)
        return seq_printf(s,
                          "%10d %10d  %4o %10lu %5u %5u %5u %5u %10lu %10lu\n",
                          sma->sem_perm.key,
-                         sma->sem_id,
+                         sma->sem_perm.id,
                          sma->sem_perm.mode,
                          sma->sem_nsems,
                          sma->sem_perm.uid,
index 5fc5cf50cf1b847fc630cf2e127f37005337bb94..3818fae625c5252363380fa9c7a521e8b5c1a7d1 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -35,7 +35,7 @@
 #include <linux/capability.h>
 #include <linux/ptrace.h>
 #include <linux/seq_file.h>
-#include <linux/mutex.h>
+#include <linux/rwsem.h>
 #include <linux/nsproxy.h>
 #include <linux/mount.h>
 
@@ -59,17 +59,11 @@ static struct ipc_ids init_shm_ids;
 
 #define shm_ids(ns)    (*((ns)->ids[IPC_SHM_IDS]))
 
-#define shm_lock(ns, id)               \
-       ((struct shmid_kernel*)ipc_lock(&shm_ids(ns),id))
 #define shm_unlock(shp)                        \
        ipc_unlock(&(shp)->shm_perm)
-#define shm_get(ns, id)                        \
-       ((struct shmid_kernel*)ipc_get(&shm_ids(ns),id))
-#define shm_buildid(ns, id, seq)       \
-       ipc_buildid(&shm_ids(ns), id, seq)
+#define shm_buildid(id, seq)   ipc_buildid(id, seq)
 
-static int newseg (struct ipc_namespace *ns, key_t key,
-               int shmflg, size_t size);
+static int newseg(struct ipc_namespace *, struct ipc_params *);
 static void shm_open(struct vm_area_struct *vma);
 static void shm_close(struct vm_area_struct *vma);
 static void shm_destroy (struct ipc_namespace *ns, struct shmid_kernel *shp);
@@ -84,9 +78,13 @@ static void __shm_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids)
        ns->shm_ctlall = SHMALL;
        ns->shm_ctlmni = SHMMNI;
        ns->shm_tot = 0;
-       ipc_init_ids(ids, 1);
+       ipc_init_ids(ids);
 }
 
+/*
+ * Called with shm_ids.rw_mutex (writer) and the shp structure locked.
+ * Only shm_ids.rw_mutex remains locked on exit.
+ */
 static void do_shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *shp)
 {
        if (shp->shm_nattch){
@@ -112,20 +110,24 @@ int shm_init_ns(struct ipc_namespace *ns)
 
 void shm_exit_ns(struct ipc_namespace *ns)
 {
-       int i;
        struct shmid_kernel *shp;
+       int next_id;
+       int total, in_use;
+
+       down_write(&shm_ids(ns).rw_mutex);
 
-       mutex_lock(&shm_ids(ns).mutex);
-       for (i = 0; i <= shm_ids(ns).max_id; i++) {
-               shp = shm_lock(ns, i);
+       in_use = shm_ids(ns).in_use;
+
+       for (total = 0, next_id = 0; total < in_use; next_id++) {
+               shp = idr_find(&shm_ids(ns).ipcs_idr, next_id);
                if (shp == NULL)
                        continue;
-
+               ipc_lock_by_ptr(&shp->shm_perm);
                do_shm_rmid(ns, shp);
+               total++;
        }
-       mutex_unlock(&shm_ids(ns).mutex);
+       up_write(&shm_ids(ns).rw_mutex);
 
-       ipc_fini_ids(ns->ids[IPC_SHM_IDS]);
        kfree(ns->ids[IPC_SHM_IDS]);
        ns->ids[IPC_SHM_IDS] = NULL;
 }
@@ -138,17 +140,49 @@ void __init shm_init (void)
                                IPC_SHM_IDS, sysvipc_shm_proc_show);
 }
 
-static inline int shm_checkid(struct ipc_namespace *ns,
-               struct shmid_kernel *s, int id)
+/*
+ * shm_lock_(check_)down routines are called in the paths where the rw_mutex
+ * is held to protect access to the idr tree.
+ */
+static inline struct shmid_kernel *shm_lock_down(struct ipc_namespace *ns,
+                                               int id)
 {
-       if (ipc_checkid(&shm_ids(ns), &s->shm_perm, id))
-               return -EIDRM;
-       return 0;
+       struct kern_ipc_perm *ipcp = ipc_lock_down(&shm_ids(ns), id);
+
+       return container_of(ipcp, struct shmid_kernel, shm_perm);
+}
+
+static inline struct shmid_kernel *shm_lock_check_down(
+                                               struct ipc_namespace *ns,
+                                               int id)
+{
+       struct kern_ipc_perm *ipcp = ipc_lock_check_down(&shm_ids(ns), id);
+
+       return container_of(ipcp, struct shmid_kernel, shm_perm);
+}
+
+/*
+ * shm_lock_(check_) routines are called in the paths where the rw_mutex
+ * is not held.
+ */
+static inline struct shmid_kernel *shm_lock(struct ipc_namespace *ns, int id)
+{
+       struct kern_ipc_perm *ipcp = ipc_lock(&shm_ids(ns), id);
+
+       return container_of(ipcp, struct shmid_kernel, shm_perm);
+}
+
+static inline struct shmid_kernel *shm_lock_check(struct ipc_namespace *ns,
+                                               int id)
+{
+       struct kern_ipc_perm *ipcp = ipc_lock_check(&shm_ids(ns), id);
+
+       return container_of(ipcp, struct shmid_kernel, shm_perm);
 }
 
-static inline struct shmid_kernel *shm_rmid(struct ipc_namespace *ns, int id)
+static inline void shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *s)
 {
-       return (struct shmid_kernel *)ipc_rmid(&shm_ids(ns), id);
+       ipc_rmid(&shm_ids(ns), &s->shm_perm);
 }
 
 static inline int shm_addid(struct ipc_namespace *ns, struct shmid_kernel *shp)
@@ -166,9 +200,9 @@ static void shm_open(struct vm_area_struct *vma)
        struct shmid_kernel *shp;
 
        shp = shm_lock(sfd->ns, sfd->id);
-       BUG_ON(!shp);
+       BUG_ON(IS_ERR(shp));
        shp->shm_atim = get_seconds();
-       shp->shm_lprid = current->tgid;
+       shp->shm_lprid = task_tgid_vnr(current);
        shp->shm_nattch++;
        shm_unlock(shp);
 }
@@ -176,15 +210,16 @@ static void shm_open(struct vm_area_struct *vma)
 /*
  * shm_destroy - free the struct shmid_kernel
  *
+ * @ns: namespace
  * @shp: struct to free
  *
- * It has to be called with shp and shm_ids.mutex locked,
+ * It has to be called with shp and shm_ids.rw_mutex (writer) locked,
  * but returns with shp unlocked and freed.
  */
 static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
 {
        ns->shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
-       shm_rmid(ns, shp->id);
+       shm_rmid(ns, shp);
        shm_unlock(shp);
        if (!is_file_hugepages(shp->shm_file))
                shmem_lock(shp->shm_file, 0, shp->mlock_user);
@@ -209,11 +244,11 @@ static void shm_close(struct vm_area_struct *vma)
        struct shmid_kernel *shp;
        struct ipc_namespace *ns = sfd->ns;
 
-       mutex_lock(&shm_ids(ns).mutex);
+       down_write(&shm_ids(ns).rw_mutex);
        /* remove from the list of attaches of the shm segment */
-       shp = shm_lock(ns, sfd->id);
-       BUG_ON(!shp);
-       shp->shm_lprid = current->tgid;
+       shp = shm_lock_down(ns, sfd->id);
+       BUG_ON(IS_ERR(shp));
+       shp->shm_lprid = task_tgid_vnr(current);
        shp->shm_dtim = get_seconds();
        shp->shm_nattch--;
        if(shp->shm_nattch == 0 &&
@@ -221,7 +256,7 @@ static void shm_close(struct vm_area_struct *vma)
                shm_destroy(ns, shp);
        else
                shm_unlock(shp);
-       mutex_unlock(&shm_ids(ns).mutex);
+       up_write(&shm_ids(ns).rw_mutex);
 }
 
 static int shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
@@ -337,8 +372,19 @@ static struct vm_operations_struct shm_vm_ops = {
 #endif
 };
 
-static int newseg (struct ipc_namespace *ns, key_t key, int shmflg, size_t size)
+/**
+ * newseg - Create a new shared memory segment
+ * @ns: namespace
+ * @params: ptr to the structure that contains key, size and shmflg
+ *
+ * Called with shm_ids.rw_mutex held as a writer.
+ */
+
+static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
 {
+       key_t key = params->key;
+       int shmflg = params->flg;
+       size_t size = params->u.size;
        int error;
        struct shmid_kernel *shp;
        int numpages = (size + PAGE_SIZE -1) >> PAGE_SHIFT;
@@ -387,28 +433,30 @@ static int newseg (struct ipc_namespace *ns, key_t key, int shmflg, size_t size)
        if (IS_ERR(file))
                goto no_file;
 
-       error = -ENOSPC;
        id = shm_addid(ns, shp);
-       if(id == -1) 
+       if (id < 0) {
+               error = id;
                goto no_id;
+       }
 
-       shp->shm_cprid = current->tgid;
+       shp->shm_cprid = task_tgid_vnr(current);
        shp->shm_lprid = 0;
        shp->shm_atim = shp->shm_dtim = 0;
        shp->shm_ctim = get_seconds();
        shp->shm_segsz = size;
        shp->shm_nattch = 0;
-       shp->id = shm_buildid(ns, id, shp->shm_perm.seq);
+       shp->shm_perm.id = shm_buildid(id, shp->shm_perm.seq);
        shp->shm_file = file;
        /*
         * shmid gets reported as "inode#" in /proc/pid/maps.
         * proc-ps tools use this. Changing this will break them.
         */
-       file->f_dentry->d_inode->i_ino = shp->id;
+       file->f_dentry->d_inode->i_ino = shp->shm_perm.id;
 
        ns->shm_tot += numpages;
+       error = shp->shm_perm.id;
        shm_unlock(shp);
-       return shp->id;
+       return error;
 
 no_id:
        fput(file);
@@ -418,42 +466,49 @@ no_file:
        return error;
 }
 
-asmlinkage long sys_shmget (key_t key, size_t size, int shmflg)
+/*
+ * Called with shm_ids.rw_mutex and ipcp locked.
+ */
+static inline int shm_security(struct kern_ipc_perm *ipcp, int shmflg)
 {
        struct shmid_kernel *shp;
-       int err, id = 0;
+
+       shp = container_of(ipcp, struct shmid_kernel, shm_perm);
+       return security_shm_associate(shp, shmflg);
+}
+
+/*
+ * Called with shm_ids.rw_mutex and ipcp locked.
+ */
+static inline int shm_more_checks(struct kern_ipc_perm *ipcp,
+                               struct ipc_params *params)
+{
+       struct shmid_kernel *shp;
+
+       shp = container_of(ipcp, struct shmid_kernel, shm_perm);
+       if (shp->shm_segsz < params->u.size)
+               return -EINVAL;
+
+       return 0;
+}
+
+asmlinkage long sys_shmget (key_t key, size_t size, int shmflg)
+{
        struct ipc_namespace *ns;
+       struct ipc_ops shm_ops;
+       struct ipc_params shm_params;
 
        ns = current->nsproxy->ipc_ns;
 
-       mutex_lock(&shm_ids(ns).mutex);
-       if (key == IPC_PRIVATE) {
-               err = newseg(ns, key, shmflg, size);
-       } else if ((id = ipc_findkey(&shm_ids(ns), key)) == -1) {
-               if (!(shmflg & IPC_CREAT))
-                       err = -ENOENT;
-               else
-                       err = newseg(ns, key, shmflg, size);
-       } else if ((shmflg & IPC_CREAT) && (shmflg & IPC_EXCL)) {
-               err = -EEXIST;
-       } else {
-               shp = shm_lock(ns, id);
-               BUG_ON(shp==NULL);
-               if (shp->shm_segsz < size)
-                       err = -EINVAL;
-               else if (ipcperms(&shp->shm_perm, shmflg))
-                       err = -EACCES;
-               else {
-                       int shmid = shm_buildid(ns, id, shp->shm_perm.seq);
-                       err = security_shm_associate(shp, shmflg);
-                       if (!err)
-                               err = shmid;
-               }
-               shm_unlock(shp);
-       }
-       mutex_unlock(&shm_ids(ns).mutex);
+       shm_ops.getnew = newseg;
+       shm_ops.associate = shm_security;
+       shm_ops.more_checks = shm_more_checks;
 
-       return err;
+       shm_params.key = key;
+       shm_params.flg = shmflg;
+       shm_params.u.size = size;
+
+       return ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
 }
 
 static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_ds *in, int version)
@@ -547,20 +602,26 @@ static inline unsigned long copy_shminfo_to_user(void __user *buf, struct shminf
        }
 }
 
+/*
+ * Called with shm_ids.rw_mutex held as a reader
+ */
 static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss,
                unsigned long *swp)
 {
-       int i;
+       int next_id;
+       int total, in_use;
 
        *rss = 0;
        *swp = 0;
 
-       for (i = 0; i <= shm_ids(ns).max_id; i++) {
+       in_use = shm_ids(ns).in_use;
+
+       for (total = 0, next_id = 0; total < in_use; next_id++) {
                struct shmid_kernel *shp;
                struct inode *inode;
 
-               shp = shm_get(ns, i);
-               if(!shp)
+               shp = idr_find(&shm_ids(ns).ipcs_idr, next_id);
+               if (shp == NULL)
                        continue;
 
                inode = shp->shm_file->f_path.dentry->d_inode;
@@ -575,6 +636,8 @@ static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss,
                        *swp += info->swapped;
                        spin_unlock(&info->lock);
                }
+
+               total++;
        }
 }
 
@@ -610,8 +673,11 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
                shminfo.shmmin = SHMMIN;
                if(copy_shminfo_to_user (buf, &shminfo, version))
                        return -EFAULT;
-               /* reading a integer is always atomic */
-               err= shm_ids(ns).max_id;
+
+               down_read(&shm_ids(ns).rw_mutex);
+               err = ipc_get_maxid(&shm_ids(ns));
+               up_read(&shm_ids(ns).rw_mutex);
+
                if(err<0)
                        err = 0;
                goto out;
@@ -625,14 +691,14 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
                        return err;
 
                memset(&shm_info,0,sizeof(shm_info));
-               mutex_lock(&shm_ids(ns).mutex);
+               down_read(&shm_ids(ns).rw_mutex);
                shm_info.used_ids = shm_ids(ns).in_use;
                shm_get_stat (ns, &shm_info.shm_rss, &shm_info.shm_swp);
                shm_info.shm_tot = ns->shm_tot;
                shm_info.swap_attempts = 0;
                shm_info.swap_successes = 0;
-               err = shm_ids(ns).max_id;
-               mutex_unlock(&shm_ids(ns).mutex);
+               err = ipc_get_maxid(&shm_ids(ns));
+               up_read(&shm_ids(ns).rw_mutex);
                if(copy_to_user (buf, &shm_info, sizeof(shm_info))) {
                        err = -EFAULT;
                        goto out;
@@ -646,20 +712,25 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
        {
                struct shmid64_ds tbuf;
                int result;
-               memset(&tbuf, 0, sizeof(tbuf));
-               shp = shm_lock(ns, shmid);
-               if(shp==NULL) {
-                       err = -EINVAL;
+
+               if (!buf) {
+                       err = -EFAULT;
                        goto out;
-               } else if(cmd==SHM_STAT) {
-                       err = -EINVAL;
-                       if (shmid > shm_ids(ns).max_id)
-                               goto out_unlock;
-                       result = shm_buildid(ns, shmid, shp->shm_perm.seq);
+               }
+
+               if (cmd == SHM_STAT) {
+                       shp = shm_lock(ns, shmid);
+                       if (IS_ERR(shp)) {
+                               err = PTR_ERR(shp);
+                               goto out;
+                       }
+                       result = shp->shm_perm.id;
                } else {
-                       err = shm_checkid(ns, shp,shmid);
-                       if(err)
-                               goto out_unlock;
+                       shp = shm_lock_check(ns, shmid);
+                       if (IS_ERR(shp)) {
+                               err = PTR_ERR(shp);
+                               goto out;
+                       }
                        result = 0;
                }
                err=-EACCES;
@@ -668,6 +739,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
                err = security_shm_shmctl(shp, cmd);
                if (err)
                        goto out_unlock;
+               memset(&tbuf, 0, sizeof(tbuf));
                kernel_to_ipc64_perm(&shp->shm_perm, &tbuf.shm_perm);
                tbuf.shm_segsz  = shp->shm_segsz;
                tbuf.shm_atime  = shp->shm_atim;
@@ -686,14 +758,11 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
        case SHM_LOCK:
        case SHM_UNLOCK:
        {
-               shp = shm_lock(ns, shmid);
-               if(shp==NULL) {
-                       err = -EINVAL;
+               shp = shm_lock_check(ns, shmid);
+               if (IS_ERR(shp)) {
+                       err = PTR_ERR(shp);
                        goto out;
                }
-               err = shm_checkid(ns, shp,shmid);
-               if(err)
-                       goto out_unlock;
 
                err = audit_ipc_obj(&(shp->shm_perm));
                if (err)
@@ -742,14 +811,12 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
                 *      Instead we set a destroyed flag, and then blow
                 *      the name away when the usage hits zero.
                 */
-               mutex_lock(&shm_ids(ns).mutex);
-               shp = shm_lock(ns, shmid);
-               err = -EINVAL;
-               if (shp == NULL) 
+               down_write(&shm_ids(ns).rw_mutex);
+               shp = shm_lock_check_down(ns, shmid);
+               if (IS_ERR(shp)) {
+                       err = PTR_ERR(shp);
                        goto out_up;
-               err = shm_checkid(ns, shp, shmid);
-               if(err)
-                       goto out_unlock_up;
+               }
 
                err = audit_ipc_obj(&(shp->shm_perm));
                if (err)
@@ -767,24 +834,27 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
                        goto out_unlock_up;
 
                do_shm_rmid(ns, shp);
-               mutex_unlock(&shm_ids(ns).mutex);
+               up_write(&shm_ids(ns).rw_mutex);
                goto out;
        }
 
        case IPC_SET:
        {
+               if (!buf) {
+                       err = -EFAULT;
+                       goto out;
+               }
+
                if (copy_shmid_from_user (&setbuf, buf, version)) {
                        err = -EFAULT;
                        goto out;
                }
-               mutex_lock(&shm_ids(ns).mutex);
-               shp = shm_lock(ns, shmid);
-               err=-EINVAL;
-               if(shp==NULL)
+               down_write(&shm_ids(ns).rw_mutex);
+               shp = shm_lock_check_down(ns, shmid);
+               if (IS_ERR(shp)) {
+                       err = PTR_ERR(shp);
                        goto out_up;
-               err = shm_checkid(ns, shp,shmid);
-               if(err)
-                       goto out_unlock_up;
+               }
                err = audit_ipc_obj(&(shp->shm_perm));
                if (err)
                        goto out_unlock_up;
@@ -819,7 +889,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
 out_unlock_up:
        shm_unlock(shp);
 out_up:
-       mutex_unlock(&shm_ids(ns).mutex);
+       up_write(&shm_ids(ns).rw_mutex);
        goto out;
 out_unlock:
        shm_unlock(shp);
@@ -890,13 +960,11 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
         * additional creator id...
         */
        ns = current->nsproxy->ipc_ns;
-       shp = shm_lock(ns, shmid);
-       if(shp == NULL)
+       shp = shm_lock_check(ns, shmid);
+       if (IS_ERR(shp)) {
+               err = PTR_ERR(shp);
                goto out;
-
-       err = shm_checkid(ns, shp,shmid);
-       if (err)
-               goto out_unlock;
+       }
 
        err = -EACCES;
        if (ipcperms(&shp->shm_perm, acc_mode))
@@ -925,7 +993,7 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
 
        file->private_data = sfd;
        file->f_mapping = shp->shm_file->f_mapping;
-       sfd->id = shp->id;
+       sfd->id = shp->shm_perm.id;
        sfd->ns = get_ipc_ns(ns);
        sfd->file = shp->shm_file;
        sfd->vm_ops = NULL;
@@ -955,16 +1023,16 @@ invalid:
        fput(file);
 
 out_nattch:
-       mutex_lock(&shm_ids(ns).mutex);
-       shp = shm_lock(ns, shmid);
-       BUG_ON(!shp);
+       down_write(&shm_ids(ns).rw_mutex);
+       shp = shm_lock_down(ns, shmid);
+       BUG_ON(IS_ERR(shp));
        shp->shm_nattch--;
        if(shp->shm_nattch == 0 &&
           shp->shm_perm.mode & SHM_DEST)
                shm_destroy(ns, shp);
        else
                shm_unlock(shp);
-       mutex_unlock(&shm_ids(ns).mutex);
+       up_write(&shm_ids(ns).rw_mutex);
 
 out:
        return err;
@@ -1094,7 +1162,7 @@ static int sysvipc_shm_proc_show(struct seq_file *s, void *it)
                format = BIG_STRING;
        return seq_printf(s, format,
                          shp->shm_perm.key,
-                         shp->id,
+                         shp->shm_perm.id,
                          shp->shm_perm.mode,
                          shp->shm_segsz,
                          shp->shm_cprid,
index 44e5135aee4785e2da26de92e0d3b52b02246842..1aa0ebf71bac7e5c30559eb0f60a89bdc6688efb 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/proc_fs.h>
 #include <linux/audit.h>
 #include <linux/nsproxy.h>
+#include <linux/rwsem.h>
 
 #include <asm/unistd.h>
 
@@ -129,23 +130,16 @@ __initcall(ipc_init);
 /**
  *     ipc_init_ids            -       initialise IPC identifiers
  *     @ids: Identifier set
- *     @size: Number of identifiers
  *
- *     Given a size for the ipc identifier range (limited below IPCMNI)
- *     set up the sequence range to use then allocate and initialise the
- *     array itself. 
+ *     Set up the sequence range to use for the ipc identifier range (limited
+ *     below IPCMNI) then initialise the ids idr.
  */
  
-void ipc_init_ids(struct ipc_ids* ids, int size)
+void ipc_init_ids(struct ipc_ids *ids)
 {
-       int i;
+       init_rwsem(&ids->rw_mutex);
 
-       mutex_init(&ids->mutex);
-
-       if(size > IPCMNI)
-               size = IPCMNI;
        ids->in_use = 0;
-       ids->max_id = -1;
        ids->seq = 0;
        {
                int seq_limit = INT_MAX/SEQ_MULTIPLIER;
@@ -155,17 +149,7 @@ void ipc_init_ids(struct ipc_ids* ids, int size)
                        ids->seq_max = seq_limit;
        }
 
-       ids->entries = ipc_rcu_alloc(sizeof(struct kern_ipc_perm *)*size +
-                                    sizeof(struct ipc_id_ary));
-
-       if(ids->entries == NULL) {
-               printk(KERN_ERR "ipc_init_ids() failed, ipc service disabled.\n");
-               size = 0;
-               ids->entries = &ids->nullentry;
-       }
-       ids->entries->size = size;
-       for(i=0;i<size;i++)
-               ids->entries->p[i] = NULL;
+       idr_init(&ids->ipcs_idr);
 }
 
 #ifdef CONFIG_PROC_FS
@@ -208,99 +192,96 @@ void __init ipc_init_proc_interface(const char *path, const char *header,
  *     @ids: Identifier set
  *     @key: The key to find
  *     
- *     Requires ipc_ids.mutex locked.
- *     Returns the identifier if found or -1 if not.
+ *     Requires ipc_ids.rw_mutex locked.
+ *     Returns the LOCKED pointer to the ipc structure if found or NULL
+ *     if not.
+ *     If key is found ipc points to the owning ipc structure
  */
  
-int ipc_findkey(struct ipc_ids* ids, key_t key)
+static struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key)
 {
-       int id;
-       struct kern_ipc_perm* p;
-       int max_id = ids->max_id;
+       struct kern_ipc_perm *ipc;
+       int next_id;
+       int total;
 
-       /*
-        * rcu_dereference() is not needed here
-        * since ipc_ids.mutex is held
-        */
-       for (id = 0; id <= max_id; id++) {
-               p = ids->entries->p[id];
-               if(p==NULL)
+       for (total = 0, next_id = 0; total < ids->in_use; next_id++) {
+               ipc = idr_find(&ids->ipcs_idr, next_id);
+
+               if (ipc == NULL)
+                       continue;
+
+               if (ipc->key != key) {
+                       total++;
                        continue;
-               if (key == p->key)
-                       return id;
+               }
+
+               ipc_lock_by_ptr(ipc);
+               return ipc;
        }
-       return -1;
+
+       return NULL;
 }
 
-/*
- * Requires ipc_ids.mutex locked
+/**
+ *     ipc_get_maxid   -       get the last assigned id
+ *     @ids: IPC identifier set
+ *
+ *     Called with ipc_ids.rw_mutex held.
  */
-static int grow_ary(struct ipc_ids* ids, int newsize)
-{
-       struct ipc_id_ary* new;
-       struct ipc_id_ary* old;
-       int i;
-       int size = ids->entries->size;
-
-       if(newsize > IPCMNI)
-               newsize = IPCMNI;
-       if(newsize <= size)
-               return newsize;
-
-       new = ipc_rcu_alloc(sizeof(struct kern_ipc_perm *)*newsize +
-                           sizeof(struct ipc_id_ary));
-       if(new == NULL)
-               return size;
-       new->size = newsize;
-       memcpy(new->p, ids->entries->p, sizeof(struct kern_ipc_perm *)*size);
-       for(i=size;i<newsize;i++) {
-               new->p[i] = NULL;
-       }
-       old = ids->entries;
 
-       /*
-        * Use rcu_assign_pointer() to make sure the memcpyed contents
-        * of the new array are visible before the new array becomes visible.
-        */
-       rcu_assign_pointer(ids->entries, new);
+int ipc_get_maxid(struct ipc_ids *ids)
+{
+       struct kern_ipc_perm *ipc;
+       int max_id = -1;
+       int total, id;
+
+       if (ids->in_use == 0)
+               return -1;
 
-       __ipc_fini_ids(ids, old);
-       return newsize;
+       if (ids->in_use == IPCMNI)
+               return IPCMNI - 1;
+
+       /* Look for the last assigned id */
+       total = 0;
+       for (id = 0; id < IPCMNI && total < ids->in_use; id++) {
+               ipc = idr_find(&ids->ipcs_idr, id);
+               if (ipc != NULL) {
+                       max_id = id;
+                       total++;
+               }
+       }
+       return max_id;
 }
 
 /**
  *     ipc_addid       -       add an IPC identifier
  *     @ids: IPC identifier set
  *     @new: new IPC permission set
- *     @size: new size limit for the id array
+ *     @size: limit for the number of used ids
  *
- *     Add an entry 'new' to the IPC arrays. The permissions object is
+ *     Add an entry 'new' to the IPC ids idr. The permissions object is
  *     initialised and the first free entry is set up and the id assigned
- *     is returned. The list is returned in a locked state on success.
- *     On failure the list is not locked and -1 is returned.
+ *     is returned. The 'new' entry is returned in a locked state on success.
+ *     On failure the entry is not locked and a negative err-code is returned.
  *
- *     Called with ipc_ids.mutex held.
+ *     Called with ipc_ids.rw_mutex held as a writer.
  */
  
 int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
 {
-       int id;
+       int id, err;
 
-       size = grow_ary(ids,size);
+       if (size > IPCMNI)
+               size = IPCMNI;
+
+       if (ids->in_use >= size)
+               return -ENOSPC;
+
+       err = idr_get_new(&ids->ipcs_idr, new, &id);
+       if (err)
+               return err;
 
-       /*
-        * rcu_dereference()() is not needed here since
-        * ipc_ids.mutex is held
-        */
-       for (id = 0; id < size; id++) {
-               if(ids->entries->p[id] == NULL)
-                       goto found;
-       }
-       return -1;
-found:
        ids->in_use++;
-       if (id > ids->max_id)
-               ids->max_id = id;
 
        new->cuid = new->uid = current->euid;
        new->gid = new->cgid = current->egid;
@@ -313,48 +294,153 @@ found:
        new->deleted = 0;
        rcu_read_lock();
        spin_lock(&new->lock);
-       ids->entries->p[id] = new;
        return id;
 }
 
+/**
+ *     ipcget_new      -       create a new ipc object
+ *     @ns: namespace
+ *     @ids: IPC identifer set
+ *     @ops: the actual creation routine to call
+ *     @params: its parameters
+ *
+ *     This routine is called by sys_msgget, sys_semget() and sys_shmget()
+ *     when the key is IPC_PRIVATE.
+ */
+int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids,
+               struct ipc_ops *ops, struct ipc_params *params)
+{
+       int err;
+retry:
+       err = idr_pre_get(&ids->ipcs_idr, GFP_KERNEL);
+
+       if (!err)
+               return -ENOMEM;
+
+       down_write(&ids->rw_mutex);
+       err = ops->getnew(ns, params);
+       up_write(&ids->rw_mutex);
+
+       if (err == -EAGAIN)
+               goto retry;
+
+       return err;
+}
+
+/**
+ *     ipc_check_perms -       check security and permissions for an IPC
+ *     @ipcp: ipc permission set
+ *     @ops: the actual security routine to call
+ *     @params: its parameters
+ *
+ *     This routine is called by sys_msgget(), sys_semget() and sys_shmget()
+ *      when the key is not IPC_PRIVATE and that key already exists in the
+ *      ids IDR.
+ *
+ *     On success, the IPC id is returned.
+ *
+ *     It is called with ipc_ids.rw_mutex and ipcp->lock held.
+ */
+static int ipc_check_perms(struct kern_ipc_perm *ipcp, struct ipc_ops *ops,
+                       struct ipc_params *params)
+{
+       int err;
+
+       if (ipcperms(ipcp, params->flg))
+               err = -EACCES;
+       else {
+               err = ops->associate(ipcp, params->flg);
+               if (!err)
+                       err = ipcp->id;
+       }
+
+       return err;
+}
+
+/**
+ *     ipcget_public   -       get an ipc object or create a new one
+ *     @ns: namespace
+ *     @ids: IPC identifer set
+ *     @ops: the actual creation routine to call
+ *     @params: its parameters
+ *
+ *     This routine is called by sys_msgget, sys_semget() and sys_shmget()
+ *     when the key is not IPC_PRIVATE.
+ *     It adds a new entry if the key is not found and does some permission
+ *      / security checkings if the key is found.
+ *
+ *     On success, the ipc id is returned.
+ */
+int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids,
+               struct ipc_ops *ops, struct ipc_params *params)
+{
+       struct kern_ipc_perm *ipcp;
+       int flg = params->flg;
+       int err;
+retry:
+       err = idr_pre_get(&ids->ipcs_idr, GFP_KERNEL);
+
+       /*
+        * Take the lock as a writer since we are potentially going to add
+        * a new entry + read locks are not "upgradable"
+        */
+       down_write(&ids->rw_mutex);
+       ipcp = ipc_findkey(ids, params->key);
+       if (ipcp == NULL) {
+               /* key not used */
+               if (!(flg & IPC_CREAT))
+                       err = -ENOENT;
+               else if (!err)
+                       err = -ENOMEM;
+               else
+                       err = ops->getnew(ns, params);
+       } else {
+               /* ipc object has been locked by ipc_findkey() */
+
+               if (flg & IPC_CREAT && flg & IPC_EXCL)
+                       err = -EEXIST;
+               else {
+                       err = 0;
+                       if (ops->more_checks)
+                               err = ops->more_checks(ipcp, params);
+                       if (!err)
+                               /*
+                                * ipc_check_perms returns the IPC id on
+                                * success
+                                */
+                               err = ipc_check_perms(ipcp, ops, params);
+               }
+               ipc_unlock(ipcp);
+       }
+       up_write(&ids->rw_mutex);
+
+       if (err == -EAGAIN)
+               goto retry;
+
+       return err;
+}
+
+
 /**
  *     ipc_rmid        -       remove an IPC identifier
- *     @ids: identifier set
- *     @id: Identifier to remove
+ *     @ids: IPC identifier set
+ *     @ipcp: ipc perm structure containing the identifier to remove
  *
- *     The identifier must be valid, and in use. The kernel will panic if
- *     fed an invalid identifier. The entry is removed and internal
- *     variables recomputed. The object associated with the identifier
- *     is returned.
- *     ipc_ids.mutex and the spinlock for this ID is hold before this function
- *     is called, and remain locked on the exit.
+ *     ipc_ids.rw_mutex (as a writer) and the spinlock for this ID are held
+ *     before this function is called, and remain locked on the exit.
  */
  
-struct kern_ipc_perm* ipc_rmid(struct ipc_ids* ids, int id)
+void ipc_rmid(struct ipc_ids *ids, struct kern_ipc_perm *ipcp)
 {
-       struct kern_ipc_perm* p;
-       int lid = id % SEQ_MULTIPLIER;
-       BUG_ON(lid >= ids->entries->size);
+       int lid = ipcid_to_idx(ipcp->id);
+
+       idr_remove(&ids->ipcs_idr, lid);
 
-       /* 
-        * do not need a rcu_dereference()() here to force ordering
-        * on Alpha, since the ipc_ids.mutex is held.
-        */     
-       p = ids->entries->p[lid];
-       ids->entries->p[lid] = NULL;
-       BUG_ON(p==NULL);
        ids->in_use--;
 
-       if (lid == ids->max_id) {
-               do {
-                       lid--;
-                       if(lid == -1)
-                               break;
-               } while (ids->entries->p[lid] == NULL);
-               ids->max_id = lid;
-       }
-       p->deleted = 1;
-       return p;
+       ipcp->deleted = 1;
+
+       return;
 }
 
 /**
@@ -491,10 +577,12 @@ static void ipc_do_vfree(struct work_struct *work)
  */
 static void ipc_schedule_free(struct rcu_head *head)
 {
-       struct ipc_rcu_grace *grace =
-               container_of(head, struct ipc_rcu_grace, rcu);
-       struct ipc_rcu_sched *sched =
-                       container_of(&(grace->data[0]), struct ipc_rcu_sched, data[0]);
+       struct ipc_rcu_grace *grace;
+       struct ipc_rcu_sched *sched;
+
+       grace = container_of(head, struct ipc_rcu_grace, rcu);
+       sched = container_of(&(grace->data[0]), struct ipc_rcu_sched,
+                               data[0]);
 
        INIT_WORK(&sched->work, ipc_do_vfree);
        schedule_work(&sched->work);
@@ -583,7 +671,7 @@ void kernel_to_ipc64_perm (struct kern_ipc_perm *in, struct ipc64_perm *out)
 }
 
 /**
- *     ipc64_perm_to_ipc_perm  -       convert old ipc permissions to new
+ *     ipc64_perm_to_ipc_perm  -       convert new ipc permissions to old
  *     @in: new style IPC permissions
  *     @out: old style IPC permissions
  *
@@ -602,44 +690,37 @@ void ipc64_perm_to_ipc_perm (struct ipc64_perm *in, struct ipc_perm *out)
        out->seq        = in->seq;
 }
 
-/*
- * So far only shm_get_stat() calls ipc_get() via shm_get(), so ipc_get()
- * is called with shm_ids.mutex locked.  Since grow_ary() is also called with
- * shm_ids.mutex down(for Shared Memory), there is no need to add read
- * barriers here to gurantee the writes in grow_ary() are seen in order 
- * here (for Alpha).
+/**
+ * ipc_lock - Lock an ipc structure without rw_mutex held
+ * @ids: IPC identifier set
+ * @id: ipc id to look for
+ *
+ * Look for an id in the ipc ids idr and lock the associated ipc object.
  *
- * However ipc_get() itself does not necessary require ipc_ids.mutex down. So
- * if in the future ipc_get() is used by other places without ipc_ids.mutex
- * down, then ipc_get() needs read memery barriers as ipc_lock() does.
+ * The ipc object is locked on exit.
+ *
+ * This is the routine that should be called when the rw_mutex is not already
+ * held, i.e. idr tree not protected: it protects the idr tree in read mode
+ * during the idr_find().
  */
-struct kern_ipc_perm* ipc_get(struct ipc_ids* ids, int id)
-{
-       struct kern_ipc_perm* out;
-       int lid = id % SEQ_MULTIPLIER;
-       if(lid >= ids->entries->size)
-               return NULL;
-       out = ids->entries->p[lid];
-       return out;
-}
 
-struct kern_ipc_perm* ipc_lock(struct ipc_ids* ids, int id)
+struct kern_ipc_perm *ipc_lock(struct ipc_ids *ids, int id)
 {
-       struct kern_ipc_perm* out;
-       int lid = id % SEQ_MULTIPLIER;
-       struct ipc_id_ary* entries;
+       struct kern_ipc_perm *out;
+       int lid = ipcid_to_idx(id);
+
+       down_read(&ids->rw_mutex);
 
        rcu_read_lock();
-       entries = rcu_dereference(ids->entries);
-       if(lid >= entries->size) {
-               rcu_read_unlock();
-               return NULL;
-       }
-       out = entries->p[lid];
-       if(out == NULL) {
+       out = idr_find(&ids->ipcs_idr, lid);
+       if (out == NULL) {
                rcu_read_unlock();
-               return NULL;
+               up_read(&ids->rw_mutex);
+               return ERR_PTR(-EINVAL);
        }
+
+       up_read(&ids->rw_mutex);
+
        spin_lock(&out->lock);
        
        /* ipc_rmid() may have already freed the ID while ipc_lock
@@ -648,33 +729,44 @@ struct kern_ipc_perm* ipc_lock(struct ipc_ids* ids, int id)
        if (out->deleted) {
                spin_unlock(&out->lock);
                rcu_read_unlock();
-               return NULL;
+               return ERR_PTR(-EINVAL);
        }
+
        return out;
 }
 
-void ipc_lock_by_ptr(struct kern_ipc_perm *perm)
-{
-       rcu_read_lock();
-       spin_lock(&perm->lock);
-}
+/**
+ * ipc_lock_down - Lock an ipc structure with rw_sem held
+ * @ids: IPC identifier set
+ * @id: ipc id to look for
+ *
+ * Look for an id in the ipc ids idr and lock the associated ipc object.
+ *
+ * The ipc object is locked on exit.
+ *
+ * This is the routine that should be called when the rw_mutex is already
+ * held, i.e. idr tree protected.
+ */
 
-void ipc_unlock(struct kern_ipc_perm* perm)
+struct kern_ipc_perm *ipc_lock_down(struct ipc_ids *ids, int id)
 {
-       spin_unlock(&perm->lock);
-       rcu_read_unlock();
-}
+       struct kern_ipc_perm *out;
+       int lid = ipcid_to_idx(id);
 
-int ipc_buildid(struct ipc_ids* ids, int id, int seq)
-{
-       return SEQ_MULTIPLIER*seq + id;
-}
+       rcu_read_lock();
+       out = idr_find(&ids->ipcs_idr, lid);
+       if (out == NULL) {
+               rcu_read_unlock();
+               return ERR_PTR(-EINVAL);
+       }
 
-int ipc_checkid(struct ipc_ids* ids, struct kern_ipc_perm* ipcp, int uid)
-{
-       if(uid/SEQ_MULTIPLIER != ipcp->seq)
-               return 1;
-       return 0;
+       spin_lock(&out->lock);
+
+       /*
+        * No need to verify that the structure is still valid since the
+        * rw_mutex is held.
+        */
+       return out;
 }
 
 #ifdef __ARCH_WANT_IPC_PARSE_VERSION
@@ -707,27 +799,30 @@ struct ipc_proc_iter {
        struct ipc_proc_iface *iface;
 };
 
-static void *sysvipc_proc_next(struct seq_file *s, void *it, loff_t *pos)
+/*
+ * This routine locks the ipc structure found at least at position pos.
+ */
+struct kern_ipc_perm *sysvipc_find_ipc(struct ipc_ids *ids, loff_t pos,
+                                       loff_t *new_pos)
 {
-       struct ipc_proc_iter *iter = s->private;
-       struct ipc_proc_iface *iface = iter->iface;
-       struct kern_ipc_perm *ipc = it;
-       loff_t p;
-       struct ipc_ids *ids;
+       struct kern_ipc_perm *ipc;
+       int total, id;
 
-       ids = iter->ns->ids[iface->ids];
+       total = 0;
+       for (id = 0; id < pos && total < ids->in_use; id++) {
+               ipc = idr_find(&ids->ipcs_idr, id);
+               if (ipc != NULL)
+                       total++;
+       }
 
-       /* If we had an ipc id locked before, unlock it */
-       if (ipc && ipc != SEQ_START_TOKEN)
-               ipc_unlock(ipc);
+       if (total >= ids->in_use)
+               return NULL;
 
-       /*
-        * p = *pos - 1 (because id 0 starts at position 1)
-        *          + 1 (because we increment the position by one)
-        */
-       for (p = *pos; p <= ids->max_id; p++) {
-               if ((ipc = ipc_lock(ids, p)) != NULL) {
-                       *pos = p + 1;
+       for ( ; pos < IPCMNI; pos++) {
+               ipc = idr_find(&ids->ipcs_idr, pos);
+               if (ipc != NULL) {
+                       *new_pos = pos + 1;
+                       ipc_lock_by_ptr(ipc);
                        return ipc;
                }
        }
@@ -736,16 +831,27 @@ static void *sysvipc_proc_next(struct seq_file *s, void *it, loff_t *pos)
        return NULL;
 }
 
+static void *sysvipc_proc_next(struct seq_file *s, void *it, loff_t *pos)
+{
+       struct ipc_proc_iter *iter = s->private;
+       struct ipc_proc_iface *iface = iter->iface;
+       struct kern_ipc_perm *ipc = it;
+
+       /* If we had an ipc id locked before, unlock it */
+       if (ipc && ipc != SEQ_START_TOKEN)
+               ipc_unlock(ipc);
+
+       return sysvipc_find_ipc(iter->ns->ids[iface->ids], *pos, pos);
+}
+
 /*
- * File positions: pos 0 -> header, pos n -> ipc id + 1.
- * SeqFile iterator: iterator value locked shp or SEQ_TOKEN_START.
+ * File positions: pos 0 -> header, pos n -> ipc id = n - 1.
+ * SeqFile iterator: iterator value locked ipc pointer or SEQ_TOKEN_START.
  */
 static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos)
 {
        struct ipc_proc_iter *iter = s->private;
        struct ipc_proc_iface *iface = iter->iface;
-       struct kern_ipc_perm *ipc;
-       loff_t p;
        struct ipc_ids *ids;
 
        ids = iter->ns->ids[iface->ids];
@@ -754,7 +860,7 @@ static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos)
         * Take the lock - this will be released by the corresponding
         * call to stop().
         */
-       mutex_lock(&ids->mutex);
+       down_read(&ids->rw_mutex);
 
        /* pos < 0 is invalid */
        if (*pos < 0)
@@ -765,13 +871,7 @@ static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos)
                return SEQ_START_TOKEN;
 
        /* Find the (pos-1)th ipc */
-       for (p = *pos - 1; p <= ids->max_id; p++) {
-               if ((ipc = ipc_lock(ids, p)) != NULL) {
-                       *pos = p + 1;
-                       return ipc;
-               }
-       }
-       return NULL;
+       return sysvipc_find_ipc(ids, *pos - 1, pos);
 }
 
 static void sysvipc_proc_stop(struct seq_file *s, void *it)
@@ -781,13 +881,13 @@ static void sysvipc_proc_stop(struct seq_file *s, void *it)
        struct ipc_proc_iface *iface = iter->iface;
        struct ipc_ids *ids;
 
-       /* If we had a locked segment, release it */
+       /* If we had a locked structure, release it */
        if (ipc && ipc != SEQ_START_TOKEN)
                ipc_unlock(ipc);
 
        ids = iter->ns->ids[iface->ids];
        /* Release the lock we took in start() */
-       mutex_unlock(&ids->mutex);
+       up_read(&ids->rw_mutex);
 }
 
 static int sysvipc_proc_show(struct seq_file *s, void *it)
index 333e891bcaca838cf71bfb27d5d9c6296a6102bd..9ffea40457cedb17eca4cc9df13ed1b3a5f1a3f7 100644 (file)
@@ -10,6 +10,9 @@
 #ifndef _IPC_UTIL_H
 #define _IPC_UTIL_H
 
+#include <linux/idr.h>
+#include <linux/err.h>
+
 #define USHRT_MAX 0xffff
 #define SEQ_MULTIPLIER (IPCMNI)
 
@@ -25,24 +28,46 @@ void sem_exit_ns(struct ipc_namespace *ns);
 void msg_exit_ns(struct ipc_namespace *ns);
 void shm_exit_ns(struct ipc_namespace *ns);
 
-struct ipc_id_ary {
-       int size;
-       struct kern_ipc_perm *p[0];
-};
-
 struct ipc_ids {
        int in_use;
-       int max_id;
        unsigned short seq;
        unsigned short seq_max;
-       struct mutex mutex;
-       struct ipc_id_ary nullentry;
-       struct ipc_id_ary* entries;
+       struct rw_semaphore rw_mutex;
+       struct idr ipcs_idr;
+};
+
+/*
+ * Structure that holds the parameters needed by the ipc operations
+ * (see after)
+ */
+struct ipc_params {
+       key_t key;
+       int flg;
+       union {
+               size_t size;    /* for shared memories */
+               int nsems;      /* for semaphores */
+       } u;                    /* holds the getnew() specific param */
+};
+
+/*
+ * Structure that holds some ipc operations. This structure is used to unify
+ * the calls to sys_msgget(), sys_semget(), sys_shmget()
+ *      . routine to call to create a new ipc object. Can be one of newque,
+ *        newary, newseg
+ *      . routine to call to check permissions for a new ipc object.
+ *        Can be one of security_msg_associate, security_sem_associate,
+ *        security_shm_associate
+ *      . routine to call for an extra check if needed
+ */
+struct ipc_ops {
+       int (*getnew) (struct ipc_namespace *, struct ipc_params *);
+       int (*associate) (struct kern_ipc_perm *, int);
+       int (*more_checks) (struct kern_ipc_perm *, struct ipc_params *);
 };
 
 struct seq_file;
 
-void ipc_init_ids(struct ipc_ids *ids, int size);
+void ipc_init_ids(struct ipc_ids *);
 #ifdef CONFIG_PROC_FS
 void __init ipc_init_proc_interface(const char *path, const char *header,
                int ids, int (*show)(struct seq_file *, void *));
@@ -54,14 +79,19 @@ void __init ipc_init_proc_interface(const char *path, const char *header,
 #define IPC_MSG_IDS    1
 #define IPC_SHM_IDS    2
 
-/* must be called with ids->mutex acquired.*/
-int ipc_findkey(struct ipc_ids* ids, key_t key);
-int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size);
+#define ipcid_to_idx(id) ((id) % SEQ_MULTIPLIER)
+
+/* must be called with ids->rw_mutex acquired for writing */
+int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int);
+
+/* must be called with ids->rw_mutex acquired for reading */
+int ipc_get_maxid(struct ipc_ids *);
 
 /* must be called with both locks acquired. */
-struct kern_ipc_perm* ipc_rmid(struct ipc_ids* ids, int id);
+void ipc_rmid(struct ipc_ids *, struct kern_ipc_perm *);
 
-int ipcperms (struct kern_ipc_perm *ipcp, short flg);
+/* must be called with ipcp locked */
+int ipcperms(struct kern_ipc_perm *ipcp, short flg);
 
 /* for rare, potentially huge allocations.
  * both function can sleep
@@ -79,24 +109,12 @@ void* ipc_rcu_alloc(int size);
 void ipc_rcu_getref(void *ptr);
 void ipc_rcu_putref(void *ptr);
 
-static inline void __ipc_fini_ids(struct ipc_ids *ids,
-               struct ipc_id_ary *entries)
-{
-       if (entries != &ids->nullentry)
-               ipc_rcu_putref(entries);
-}
-
-static inline void ipc_fini_ids(struct ipc_ids *ids)
-{
-       __ipc_fini_ids(ids, ids->entries);
-}
-
-struct kern_ipc_perm* ipc_get(struct ipc_ids* ids, int id);
-struct kern_ipc_perm* ipc_lock(struct ipc_ids* ids, int id);
-void ipc_lock_by_ptr(struct kern_ipc_perm *ipcp);
-void ipc_unlock(struct kern_ipc_perm* perm);
-int ipc_buildid(struct ipc_ids* ids, int id, int seq);
-int ipc_checkid(struct ipc_ids* ids, struct kern_ipc_perm* ipcp, int uid);
+/*
+ * ipc_lock_down: called with rw_mutex held
+ * ipc_lock: called without that lock held
+ */
+struct kern_ipc_perm *ipc_lock_down(struct ipc_ids *, int);
+struct kern_ipc_perm *ipc_lock(struct ipc_ids *, int);
 
 void kernel_to_ipc64_perm(struct kern_ipc_perm *in, struct ipc64_perm *out);
 void ipc64_perm_to_ipc_perm(struct ipc64_perm *in, struct ipc_perm *out);
@@ -111,5 +129,89 @@ int ipc_parse_version (int *cmd);
 extern void free_msg(struct msg_msg *msg);
 extern struct msg_msg *load_msg(const void __user *src, int len);
 extern int store_msg(void __user *dest, struct msg_msg *msg, int len);
+extern int ipcget_new(struct ipc_namespace *, struct ipc_ids *,
+                       struct ipc_ops *, struct ipc_params *);
+extern int ipcget_public(struct ipc_namespace *, struct ipc_ids *,
+                       struct ipc_ops *, struct ipc_params *);
+
+static inline int ipc_buildid(int id, int seq)
+{
+       return SEQ_MULTIPLIER * seq + id;
+}
+
+/*
+ * Must be called with ipcp locked
+ */
+static inline int ipc_checkid(struct kern_ipc_perm *ipcp, int uid)
+{
+       if (uid / SEQ_MULTIPLIER != ipcp->seq)
+               return 1;
+       return 0;
+}
+
+static inline void ipc_lock_by_ptr(struct kern_ipc_perm *perm)
+{
+       rcu_read_lock();
+       spin_lock(&perm->lock);
+}
+
+static inline void ipc_unlock(struct kern_ipc_perm *perm)
+{
+       spin_unlock(&perm->lock);
+       rcu_read_unlock();
+}
+
+static inline struct kern_ipc_perm *ipc_lock_check_down(struct ipc_ids *ids,
+                                               int id)
+{
+       struct kern_ipc_perm *out;
+
+       out = ipc_lock_down(ids, id);
+       if (IS_ERR(out))
+               return out;
+
+       if (ipc_checkid(out, id)) {
+               ipc_unlock(out);
+               return ERR_PTR(-EIDRM);
+       }
+
+       return out;
+}
+
+static inline struct kern_ipc_perm *ipc_lock_check(struct ipc_ids *ids,
+                                               int id)
+{
+       struct kern_ipc_perm *out;
+
+       out = ipc_lock(ids, id);
+       if (IS_ERR(out))
+               return out;
+
+       if (ipc_checkid(out, id)) {
+               ipc_unlock(out);
+               return ERR_PTR(-EIDRM);
+       }
+
+       return out;
+}
+
+/**
+ * ipcget - Common sys_*get() code
+ * @ns : namsepace
+ * @ids : IPC identifier set
+ * @ops : operations to be called on ipc object creation, permission checks
+ *        and further checks
+ * @params : the parameters needed by the previous operations.
+ *
+ * Common routine called by sys_msgget(), sys_semget() and sys_shmget().
+ */
+static inline int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids,
+                       struct ipc_ops *ops, struct ipc_params *params)
+{
+       if (params->key == IPC_PRIVATE)
+               return ipcget_new(ns, ids, ops, params);
+       else
+               return ipcget_public(ns, ids, ops, params);
+}
 
 #endif
diff --git a/kernel/Kconfig.instrumentation b/kernel/Kconfig.instrumentation
new file mode 100644 (file)
index 0000000..f5f2c76
--- /dev/null
@@ -0,0 +1,49 @@
+menuconfig INSTRUMENTATION
+       bool "Instrumentation Support"
+       default y
+       ---help---
+         Say Y here to get to see options related to performance measurement,
+         system-wide debugging, and testing. This option alone does not add any
+         kernel code.
+
+         If you say N, all options in this submenu will be skipped and
+         disabled. If you're trying to debug the kernel itself, go see the
+         Kernel Hacking menu.
+
+if INSTRUMENTATION
+
+config PROFILING
+       bool "Profiling support (EXPERIMENTAL)"
+       help
+         Say Y here to enable the extended profiling support mechanisms used
+         by profilers such as OProfile.
+
+config OPROFILE
+       tristate "OProfile system profiling (EXPERIMENTAL)"
+       depends on PROFILING
+       depends on ALPHA || ARM || BLACKFIN || X86_32 || IA64 || M32R || MIPS || PARISC || PPC || S390 || SUPERH || SPARC || X86_64
+       help
+         OProfile is a profiling system capable of profiling the
+         whole system, include the kernel, kernel modules, libraries,
+         and applications.
+
+         If unsure, say N.
+
+config KPROBES
+       bool "Kprobes"
+       depends on KALLSYMS && MODULES
+       depends on X86_32 || IA64 || PPC || S390 || SPARC64 || X86_64 || AVR32
+       help
+         Kprobes allows you to trap at almost any kernel address and
+         execute a callback function.  register_kprobe() establishes
+         a probepoint and specifies the callback.  Kprobes is useful
+         for kernel debugging, non-intrusive instrumentation and testing.
+         If in doubt, say "N".
+
+config MARKERS
+       bool "Activate markers"
+       help
+         Place an empty function call at each marker site. Can be
+         dynamically changed for a probe function.
+
+endif # INSTRUMENTATION
index 2a999836ca18092e172280d346a63c4a6763d776..f60afe74259912d0f5c57d41736a812bd44eef2f 100644 (file)
@@ -8,9 +8,10 @@ obj-y     = sched.o fork.o exec_domain.o panic.o printk.o profile.o \
            signal.o sys.o kmod.o workqueue.o pid.o \
            rcupdate.o extable.o params.o posix-timers.o \
            kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
-           hrtimer.o rwsem.o latency.o nsproxy.o srcu.o die_notifier.o \
-           utsname.o
+           hrtimer.o rwsem.o latency.o nsproxy.o srcu.o \
+           utsname.o notifier.o
 
+obj-$(CONFIG_SYSCTL) += sysctl_check.o
 obj-$(CONFIG_STACKTRACE) += stacktrace.o
 obj-y += time/
 obj-$(CONFIG_DEBUG_MUTEXES) += mutex-debug.o
@@ -36,11 +37,16 @@ obj-$(CONFIG_PM) += power/
 obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
 obj-$(CONFIG_KEXEC) += kexec.o
 obj-$(CONFIG_COMPAT) += compat.o
+obj-$(CONFIG_CGROUPS) += cgroup.o
+obj-$(CONFIG_CGROUP_DEBUG) += cgroup_debug.o
 obj-$(CONFIG_CPUSETS) += cpuset.o
+obj-$(CONFIG_CGROUP_CPUACCT) += cpu_acct.o
+obj-$(CONFIG_CGROUP_NS) += ns_cgroup.o
 obj-$(CONFIG_IKCONFIG) += configs.o
 obj-$(CONFIG_STOP_MACHINE) += stop_machine.o
 obj-$(CONFIG_AUDIT) += audit.o auditfilter.o
 obj-$(CONFIG_AUDITSYSCALL) += auditsc.o
+obj-$(CONFIG_AUDIT_TREE) += audit_tree.o
 obj-$(CONFIG_KPROBES) += kprobes.o
 obj-$(CONFIG_SYSFS) += ksysfs.o
 obj-$(CONFIG_DETECT_SOFTLOCKUP) += softlockup.o
@@ -51,6 +57,7 @@ obj-$(CONFIG_RELAY) += relay.o
 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
 
 ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y)
 # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
index 24f0f8b2ba724567861b6b8983b554f8f0473b90..fce53d8df8a7ade114a002885a8cbfc1cdbedc49 100644 (file)
@@ -329,16 +329,16 @@ static comp_t encode_comp_t(unsigned long value)
        }
 
        /*
-         * If we need to round up, do it (and handle overflow correctly).
-         */
+        * If we need to round up, do it (and handle overflow correctly).
+        */
        if (rnd && (++value > MAXFRACT)) {
                value >>= EXPSIZE;
                exp++;
        }
 
        /*
-         * Clean it up and polish it off.
-         */
+        * Clean it up and polish it off.
+        */
        exp <<= MANTSIZE;               /* Shift the exponent into place */
        exp += value;                   /* and add on the mantissa. */
        return exp;
@@ -361,30 +361,30 @@ static comp_t encode_comp_t(unsigned long value)
 
 static comp2_t encode_comp2_t(u64 value)
 {
-        int exp, rnd;
-
-        exp = (value > (MAXFRACT2>>1));
-        rnd = 0;
-        while (value > MAXFRACT2) {
-                rnd = value & 1;
-                value >>= 1;
-                exp++;
-        }
-
-        /*
-         * If we need to round up, do it (and handle overflow correctly).
-         */
-        if (rnd && (++value > MAXFRACT2)) {
-                value >>= 1;
-                exp++;
-        }
-
-        if (exp > MAXEXP2) {
-                /* Overflow. Return largest representable number instead. */
-                return (1ul << (MANTSIZE2+EXPSIZE2-1)) - 1;
-        } else {
-                return (value & (MAXFRACT2>>1)) | (exp << (MANTSIZE2-1));
-        }
+       int exp, rnd;
+
+       exp = (value > (MAXFRACT2>>1));
+       rnd = 0;
+       while (value > MAXFRACT2) {
+               rnd = value & 1;
+               value >>= 1;
+               exp++;
+       }
+
+       /*
+        * If we need to round up, do it (and handle overflow correctly).
+        */
+       if (rnd && (++value > MAXFRACT2)) {
+               value >>= 1;
+               exp++;
+       }
+
+       if (exp > MAXEXP2) {
+               /* Overflow. Return largest representable number instead. */
+               return (1ul << (MANTSIZE2+EXPSIZE2-1)) - 1;
+       } else {
+               return (value & (MAXFRACT2>>1)) | (exp << (MANTSIZE2-1));
+       }
 }
 #endif
 
@@ -501,14 +501,14 @@ static void do_acct_process(struct file *file)
        ac.ac_swaps = encode_comp_t(0);
 
        /*
-         * Kernel segment override to datasegment and write it
-         * to the accounting file.
-         */
+        * Kernel segment override to datasegment and write it
+        * to the accounting file.
+        */
        fs = get_fs();
        set_fs(KERNEL_DS);
        /*
-        * Accounting records are not subject to resource limits.
-        */
+        * Accounting records are not subject to resource limits.
+        */
        flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
        current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
        file->f_op->write(file, (char *)&ac,
index 2924251a6547bebb25d952dc64ea5590848b1bce..f93c2713017da93b90e5e8d67d029c1b754ffaa0 100644 (file)
@@ -468,6 +468,21 @@ int audit_send_list(void *_dest)
        return 0;
 }
 
+#ifdef CONFIG_AUDIT_TREE
+static int prune_tree_thread(void *unused)
+{
+       mutex_lock(&audit_cmd_mutex);
+       audit_prune_trees();
+       mutex_unlock(&audit_cmd_mutex);
+       return 0;
+}
+
+void audit_schedule_prune(void)
+{
+       kthread_run(prune_tree_thread, NULL, "audit_prune_tree");
+}
+#endif
+
 struct sk_buff *audit_make_reply(int pid, int seq, int type, int done,
                                 int multi, void *payload, int size)
 {
@@ -540,6 +555,8 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
        case AUDIT_SIGNAL_INFO:
        case AUDIT_TTY_GET:
        case AUDIT_TTY_SET:
+       case AUDIT_TRIM:
+       case AUDIT_MAKE_EQUIV:
                if (security_netlink_recv(skb, CAP_AUDIT_CONTROL))
                        err = -EPERM;
                break;
@@ -664,11 +681,11 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                                if (sid) {
                                        if (selinux_sid_to_string(
                                                        sid, &ctx, &len)) {
-                                               audit_log_format(ab, 
+                                               audit_log_format(ab,
                                                        " ssid=%u", sid);
                                                /* Maybe call audit_panic? */
                                        } else
-                                               audit_log_format(ab, 
+                                               audit_log_format(ab,
                                                        " subj=%s", ctx);
                                        kfree(ctx);
                                }
@@ -756,6 +773,76 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                                           uid, seq, data, nlmsg_len(nlh),
                                           loginuid, sid);
                break;
+       case AUDIT_TRIM:
+               audit_trim_trees();
+               ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
+               if (!ab)
+                       break;
+               audit_log_format(ab, "auid=%u", loginuid);
+               if (sid) {
+                       u32 len;
+                       ctx = NULL;
+                       if (selinux_sid_to_string(sid, &ctx, &len))
+                               audit_log_format(ab, " ssid=%u", sid);
+                       else
+                               audit_log_format(ab, " subj=%s", ctx);
+                       kfree(ctx);
+               }
+               audit_log_format(ab, " op=trim res=1");
+               audit_log_end(ab);
+               break;
+       case AUDIT_MAKE_EQUIV: {
+               void *bufp = data;
+               u32 sizes[2];
+               size_t len = nlmsg_len(nlh);
+               char *old, *new;
+
+               err = -EINVAL;
+               if (len < 2 * sizeof(u32))
+                       break;
+               memcpy(sizes, bufp, 2 * sizeof(u32));
+               bufp += 2 * sizeof(u32);
+               len -= 2 * sizeof(u32);
+               old = audit_unpack_string(&bufp, &len, sizes[0]);
+               if (IS_ERR(old)) {
+                       err = PTR_ERR(old);
+                       break;
+               }
+               new = audit_unpack_string(&bufp, &len, sizes[1]);
+               if (IS_ERR(new)) {
+                       err = PTR_ERR(new);
+                       kfree(old);
+                       break;
+               }
+               /* OK, here comes... */
+               err = audit_tag_tree(old, new);
+
+               ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
+               if (!ab) {
+                       kfree(old);
+                       kfree(new);
+                       break;
+               }
+               audit_log_format(ab, "auid=%u", loginuid);
+               if (sid) {
+                       u32 len;
+                       ctx = NULL;
+                       if (selinux_sid_to_string(sid, &ctx, &len))
+                               audit_log_format(ab, " ssid=%u", sid);
+                       else
+                               audit_log_format(ab, " subj=%s", ctx);
+                       kfree(ctx);
+               }
+               audit_log_format(ab, " op=make_equiv old=");
+               audit_log_untrustedstring(ab, old);
+               audit_log_format(ab, " new=");
+               audit_log_untrustedstring(ab, new);
+               audit_log_format(ab, " res=%d", !err);
+               audit_log_end(ab);
+               kfree(old);
+               kfree(new);
+               break;
+       }
        case AUDIT_SIGNAL_INFO:
                err = selinux_sid_to_string(audit_sig_sid, &ctx, &len);
                if (err)
@@ -769,7 +856,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                sig_data->pid = audit_sig_pid;
                memcpy(sig_data->ctx, ctx, len);
                kfree(ctx);
-               audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO, 
+               audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO,
                                0, 0, sig_data, sizeof(*sig_data) + len);
                kfree(sig_data);
                break;
@@ -1005,7 +1092,7 @@ unsigned int audit_serial(void)
        return ret;
 }
 
-static inline void audit_get_stamp(struct audit_context *ctx, 
+static inline void audit_get_stamp(struct audit_context *ctx,
                                   struct timespec *t, unsigned int *serial)
 {
        if (ctx)
@@ -1056,7 +1143,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
        if (gfp_mask & __GFP_WAIT)
                reserve = 0;
        else
-               reserve = 5; /* Allow atomic callers to go up to five 
+               reserve = 5; /* Allow atomic callers to go up to five
                                entries over the normal backlog limit */
 
        while (audit_backlog_limit
@@ -1319,7 +1406,7 @@ void audit_log_d_path(struct audit_buffer *ab, const char *prefix,
        if (IS_ERR(p)) { /* Should never happen since we send PATH_MAX */
                /* FIXME: can we save some information here? */
                audit_log_format(ab, "<too long>");
-       } else 
+       } else
                audit_log_untrustedstring(ab, p);
        kfree(path);
 }
@@ -1365,7 +1452,7 @@ void audit_log_end(struct audit_buffer *ab)
  * audit_log_vformat, and audit_log_end.  It may be called
  * in any context.
  */
-void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type, 
+void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type,
               const char *fmt, ...)
 {
        struct audit_buffer *ab;
index 95877435c347c06a58caeca23de249cdc24a1301..2554bd524fd1a67cdb694ef7ff230f8e3dc809cf 100644 (file)
@@ -73,6 +73,9 @@ struct audit_field {
        struct selinux_audit_rule       *se_rule;
 };
 
+struct audit_tree;
+struct audit_chunk;
+
 struct audit_krule {
        int                     vers_ops;
        u32                     flags;
@@ -86,7 +89,8 @@ struct audit_krule {
        struct audit_field      *arch_f; /* quick access to arch field */
        struct audit_field      *inode_f; /* quick access to an inode field */
        struct audit_watch      *watch; /* associated watch */
-       struct list_head        rlist;  /* entry in audit_watch.rules list */
+       struct audit_tree       *tree;  /* associated watched tree */
+       struct list_head        rlist;  /* entry in audit_{watch,tree}.rules list */
 };
 
 struct audit_entry {
@@ -130,6 +134,34 @@ extern void audit_handle_ievent(struct inotify_watch *, u32, u32, u32,
                                const char *, struct inode *);
 extern int selinux_audit_rule_update(void);
 
+extern struct mutex audit_filter_mutex;
+extern void audit_free_rule_rcu(struct rcu_head *);
+
+#ifdef CONFIG_AUDIT_TREE
+extern struct audit_chunk *audit_tree_lookup(const struct inode *);
+extern void audit_put_chunk(struct audit_chunk *);
+extern int audit_tree_match(struct audit_chunk *, struct audit_tree *);
+extern int audit_make_tree(struct audit_krule *, char *, u32);
+extern int audit_add_tree_rule(struct audit_krule *);
+extern int audit_remove_tree_rule(struct audit_krule *);
+extern void audit_trim_trees(void);
+extern int audit_tag_tree(char *old, char *new);
+extern void audit_schedule_prune(void);
+extern void audit_prune_trees(void);
+extern const char *audit_tree_path(struct audit_tree *);
+extern void audit_put_tree(struct audit_tree *);
+#else
+#define audit_remove_tree_rule(rule) BUG()
+#define audit_add_tree_rule(rule) -EINVAL
+#define audit_make_tree(rule, str, op) -EINVAL
+#define audit_trim_trees() (void)0
+#define audit_put_tree(tree) (void)0
+#define audit_tag_tree(old, new) -EINVAL
+#define audit_tree_path(rule) ""       /* never called */
+#endif
+
+extern char *audit_unpack_string(void **, size_t *, size_t);
+
 #ifdef CONFIG_AUDITSYSCALL
 extern int __audit_signal_info(int sig, struct task_struct *t);
 static inline int audit_signal_info(int sig, struct task_struct *t)
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
new file mode 100644 (file)
index 0000000..f4fcf58
--- /dev/null
@@ -0,0 +1,903 @@
+#include "audit.h"
+#include <linux/inotify.h>
+#include <linux/namei.h>
+#include <linux/mount.h>
+
+struct audit_tree;
+struct audit_chunk;
+
+struct audit_tree {
+       atomic_t count;
+       int goner;
+       struct audit_chunk *root;
+       struct list_head chunks;
+       struct list_head rules;
+       struct list_head list;
+       struct list_head same_root;
+       struct rcu_head head;
+       char pathname[];
+};
+
+struct audit_chunk {
+       struct list_head hash;
+       struct inotify_watch watch;
+       struct list_head trees;         /* with root here */
+       int dead;
+       int count;
+       struct rcu_head head;
+       struct node {
+               struct list_head list;
+               struct audit_tree *owner;
+               unsigned index;         /* index; upper bit indicates 'will prune' */
+       } owners[];
+};
+
+static LIST_HEAD(tree_list);
+static LIST_HEAD(prune_list);
+
+/*
+ * One struct chunk is attached to each inode of interest.
+ * We replace struct chunk on tagging/untagging.
+ * Rules have pointer to struct audit_tree.
+ * Rules have struct list_head rlist forming a list of rules over
+ * the same tree.
+ * References to struct chunk are collected at audit_inode{,_child}()
+ * time and used in AUDIT_TREE rule matching.
+ * These references are dropped at the same time we are calling
+ * audit_free_names(), etc.
+ *
+ * Cyclic lists galore:
+ * tree.chunks anchors chunk.owners[].list                     hash_lock
+ * tree.rules anchors rule.rlist                               audit_filter_mutex
+ * chunk.trees anchors tree.same_root                          hash_lock
+ * chunk.hash is a hash with middle bits of watch.inode as
+ * a hash function.                                            RCU, hash_lock
+ *
+ * tree is refcounted; one reference for "some rules on rules_list refer to
+ * it", one for each chunk with pointer to it.
+ *
+ * chunk is refcounted by embedded inotify_watch.
+ *
+ * node.index allows to get from node.list to containing chunk.
+ * MSB of that sucker is stolen to mark taggings that we might have to
+ * revert - several operations have very unpleasant cleanup logics and
+ * that makes a difference.  Some.
+ */
+
+static struct inotify_handle *rtree_ih;
+
+static struct audit_tree *alloc_tree(const char *s)
+{
+       struct audit_tree *tree;
+
+       tree = kmalloc(sizeof(struct audit_tree) + strlen(s) + 1, GFP_KERNEL);
+       if (tree) {
+               atomic_set(&tree->count, 1);
+               tree->goner = 0;
+               INIT_LIST_HEAD(&tree->chunks);
+               INIT_LIST_HEAD(&tree->rules);
+               INIT_LIST_HEAD(&tree->list);
+               INIT_LIST_HEAD(&tree->same_root);
+               tree->root = NULL;
+               strcpy(tree->pathname, s);
+       }
+       return tree;
+}
+
+static inline void get_tree(struct audit_tree *tree)
+{
+       atomic_inc(&tree->count);
+}
+
+static void __put_tree(struct rcu_head *rcu)
+{
+       struct audit_tree *tree = container_of(rcu, struct audit_tree, head);
+       kfree(tree);
+}
+
+static inline void put_tree(struct audit_tree *tree)
+{
+       if (atomic_dec_and_test(&tree->count))
+               call_rcu(&tree->head, __put_tree);
+}
+
+/* to avoid bringing the entire thing in audit.h */
+const char *audit_tree_path(struct audit_tree *tree)
+{
+       return tree->pathname;
+}
+
+static struct audit_chunk *alloc_chunk(int count)
+{
+       struct audit_chunk *chunk;
+       size_t size;
+       int i;
+
+       size = offsetof(struct audit_chunk, owners) + count * sizeof(struct node);
+       chunk = kzalloc(size, GFP_KERNEL);
+       if (!chunk)
+               return NULL;
+
+       INIT_LIST_HEAD(&chunk->hash);
+       INIT_LIST_HEAD(&chunk->trees);
+       chunk->count = count;
+       for (i = 0; i < count; i++) {
+               INIT_LIST_HEAD(&chunk->owners[i].list);
+               chunk->owners[i].index = i;
+       }
+       inotify_init_watch(&chunk->watch);
+       return chunk;
+}
+
+static void __free_chunk(struct rcu_head *rcu)
+{
+       struct audit_chunk *chunk = container_of(rcu, struct audit_chunk, head);
+       int i;
+
+       for (i = 0; i < chunk->count; i++) {
+               if (chunk->owners[i].owner)
+                       put_tree(chunk->owners[i].owner);
+       }
+       kfree(chunk);
+}
+
+static inline void free_chunk(struct audit_chunk *chunk)
+{
+       call_rcu(&chunk->head, __free_chunk);
+}
+
+void audit_put_chunk(struct audit_chunk *chunk)
+{
+       put_inotify_watch(&chunk->watch);
+}
+
+enum {HASH_SIZE = 128};
+static struct list_head chunk_hash_heads[HASH_SIZE];
+static __cacheline_aligned_in_smp DEFINE_SPINLOCK(hash_lock);
+
+static inline struct list_head *chunk_hash(const struct inode *inode)
+{
+       unsigned long n = (unsigned long)inode / L1_CACHE_BYTES;
+       return chunk_hash_heads + n % HASH_SIZE;
+}
+
+/* hash_lock is held by caller */
+static void insert_hash(struct audit_chunk *chunk)
+{
+       struct list_head *list = chunk_hash(chunk->watch.inode);
+       list_add_rcu(&chunk->hash, list);
+}
+
+/* called under rcu_read_lock */
+struct audit_chunk *audit_tree_lookup(const struct inode *inode)
+{
+       struct list_head *list = chunk_hash(inode);
+       struct list_head *pos;
+
+       list_for_each_rcu(pos, list) {
+               struct audit_chunk *p = container_of(pos, struct audit_chunk, hash);
+               if (p->watch.inode == inode) {
+                       get_inotify_watch(&p->watch);
+                       return p;
+               }
+       }
+       return NULL;
+}
+
+int audit_tree_match(struct audit_chunk *chunk, struct audit_tree *tree)
+{
+       int n;
+       for (n = 0; n < chunk->count; n++)
+               if (chunk->owners[n].owner == tree)
+                       return 1;
+       return 0;
+}
+
+/* tagging and untagging inodes with trees */
+
+static void untag_chunk(struct audit_chunk *chunk, struct node *p)
+{
+       struct audit_chunk *new;
+       struct audit_tree *owner;
+       int size = chunk->count - 1;
+       int i, j;
+
+       mutex_lock(&chunk->watch.inode->inotify_mutex);
+       if (chunk->dead) {
+               mutex_unlock(&chunk->watch.inode->inotify_mutex);
+               return;
+       }
+
+       owner = p->owner;
+
+       if (!size) {
+               chunk->dead = 1;
+               spin_lock(&hash_lock);
+               list_del_init(&chunk->trees);
+               if (owner->root == chunk)
+                       owner->root = NULL;
+               list_del_init(&p->list);
+               list_del_rcu(&chunk->hash);
+               spin_unlock(&hash_lock);
+               inotify_evict_watch(&chunk->watch);
+               mutex_unlock(&chunk->watch.inode->inotify_mutex);
+               put_inotify_watch(&chunk->watch);
+               return;
+       }
+
+       new = alloc_chunk(size);
+       if (!new)
+               goto Fallback;
+       if (inotify_clone_watch(&chunk->watch, &new->watch) < 0) {
+               free_chunk(new);
+               goto Fallback;
+       }
+
+       chunk->dead = 1;
+       spin_lock(&hash_lock);
+       list_replace_init(&chunk->trees, &new->trees);
+       if (owner->root == chunk) {
+               list_del_init(&owner->same_root);
+               owner->root = NULL;
+       }
+
+       for (i = j = 0; i < size; i++, j++) {
+               struct audit_tree *s;
+               if (&chunk->owners[j] == p) {
+                       list_del_init(&p->list);
+                       i--;
+                       continue;
+               }
+               s = chunk->owners[j].owner;
+               new->owners[i].owner = s;
+               new->owners[i].index = chunk->owners[j].index - j + i;
+               if (!s) /* result of earlier fallback */
+                       continue;
+               get_tree(s);
+               list_replace_init(&chunk->owners[i].list, &new->owners[j].list);
+       }
+
+       list_replace_rcu(&chunk->hash, &new->hash);
+       list_for_each_entry(owner, &new->trees, same_root)
+               owner->root = new;
+       spin_unlock(&hash_lock);
+       inotify_evict_watch(&chunk->watch);
+       mutex_unlock(&chunk->watch.inode->inotify_mutex);
+       put_inotify_watch(&chunk->watch);
+       return;
+
+Fallback:
+       // do the best we can
+       spin_lock(&hash_lock);
+       if (owner->root == chunk) {
+               list_del_init(&owner->same_root);
+               owner->root = NULL;
+       }
+       list_del_init(&p->list);
+       p->owner = NULL;
+       put_tree(owner);
+       spin_unlock(&hash_lock);
+       mutex_unlock(&chunk->watch.inode->inotify_mutex);
+}
+
+static int create_chunk(struct inode *inode, struct audit_tree *tree)
+{
+       struct audit_chunk *chunk = alloc_chunk(1);
+       if (!chunk)
+               return -ENOMEM;
+
+       if (inotify_add_watch(rtree_ih, &chunk->watch, inode, IN_IGNORED | IN_DELETE_SELF) < 0) {
+               free_chunk(chunk);
+               return -ENOSPC;
+       }
+
+       mutex_lock(&inode->inotify_mutex);
+       spin_lock(&hash_lock);
+       if (tree->goner) {
+               spin_unlock(&hash_lock);
+               chunk->dead = 1;
+               inotify_evict_watch(&chunk->watch);
+               mutex_unlock(&inode->inotify_mutex);
+               put_inotify_watch(&chunk->watch);
+               return 0;
+       }
+       chunk->owners[0].index = (1U << 31);
+       chunk->owners[0].owner = tree;
+       get_tree(tree);
+       list_add(&chunk->owners[0].list, &tree->chunks);
+       if (!tree->root) {
+               tree->root = chunk;
+               list_add(&tree->same_root, &chunk->trees);
+       }
+       insert_hash(chunk);
+       spin_unlock(&hash_lock);
+       mutex_unlock(&inode->inotify_mutex);
+       return 0;
+}
+
+/* the first tagged inode becomes root of tree */
+static int tag_chunk(struct inode *inode, struct audit_tree *tree)
+{
+       struct inotify_watch *watch;
+       struct audit_tree *owner;
+       struct audit_chunk *chunk, *old;
+       struct node *p;
+       int n;
+
+       if (inotify_find_watch(rtree_ih, inode, &watch) < 0)
+               return create_chunk(inode, tree);
+
+       old = container_of(watch, struct audit_chunk, watch);
+
+       /* are we already there? */
+       spin_lock(&hash_lock);
+       for (n = 0; n < old->count; n++) {
+               if (old->owners[n].owner == tree) {
+                       spin_unlock(&hash_lock);
+                       put_inotify_watch(watch);
+                       return 0;
+               }
+       }
+       spin_unlock(&hash_lock);
+
+       chunk = alloc_chunk(old->count + 1);
+       if (!chunk)
+               return -ENOMEM;
+
+       mutex_lock(&inode->inotify_mutex);
+       if (inotify_clone_watch(&old->watch, &chunk->watch) < 0) {
+               mutex_unlock(&inode->inotify_mutex);
+               free_chunk(chunk);
+               return -ENOSPC;
+       }
+       spin_lock(&hash_lock);
+       if (tree->goner) {
+               spin_unlock(&hash_lock);
+               chunk->dead = 1;
+               inotify_evict_watch(&chunk->watch);
+               mutex_unlock(&inode->inotify_mutex);
+               put_inotify_watch(&chunk->watch);
+               return 0;
+       }
+       list_replace_init(&old->trees, &chunk->trees);
+       for (n = 0, p = chunk->owners; n < old->count; n++, p++) {
+               struct audit_tree *s = old->owners[n].owner;
+               p->owner = s;
+               p->index = old->owners[n].index;
+               if (!s) /* result of fallback in untag */
+                       continue;
+               get_tree(s);
+               list_replace_init(&old->owners[n].list, &p->list);
+       }
+       p->index = (chunk->count - 1) | (1U<<31);
+       p->owner = tree;
+       get_tree(tree);
+       list_add(&p->list, &tree->chunks);
+       list_replace_rcu(&old->hash, &chunk->hash);
+       list_for_each_entry(owner, &chunk->trees, same_root)
+               owner->root = chunk;
+       old->dead = 1;
+       if (!tree->root) {
+               tree->root = chunk;
+               list_add(&tree->same_root, &chunk->trees);
+       }
+       spin_unlock(&hash_lock);
+       inotify_evict_watch(&old->watch);
+       mutex_unlock(&inode->inotify_mutex);
+       put_inotify_watch(&old->watch);
+       return 0;
+}
+
+static struct audit_chunk *find_chunk(struct node *p)
+{
+       int index = p->index & ~(1U<<31);
+       p -= index;
+       return container_of(p, struct audit_chunk, owners[0]);
+}
+
+static void kill_rules(struct audit_tree *tree)
+{
+       struct audit_krule *rule, *next;
+       struct audit_entry *entry;
+       struct audit_buffer *ab;
+
+       list_for_each_entry_safe(rule, next, &tree->rules, rlist) {
+               entry = container_of(rule, struct audit_entry, rule);
+
+               list_del_init(&rule->rlist);
+               if (rule->tree) {
+                       /* not a half-baked one */
+                       ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
+                       audit_log_format(ab, "op=remove rule dir=");
+                       audit_log_untrustedstring(ab, rule->tree->pathname);
+                       if (rule->filterkey) {
+                               audit_log_format(ab, " key=");
+                               audit_log_untrustedstring(ab, rule->filterkey);
+                       } else
+                               audit_log_format(ab, " key=(null)");
+                       audit_log_format(ab, " list=%d res=1", rule->listnr);
+                       audit_log_end(ab);
+                       rule->tree = NULL;
+                       list_del_rcu(&entry->list);
+                       call_rcu(&entry->rcu, audit_free_rule_rcu);
+               }
+       }
+}
+
+/*
+ * finish killing struct audit_tree
+ */
+static void prune_one(struct audit_tree *victim)
+{
+       spin_lock(&hash_lock);
+       while (!list_empty(&victim->chunks)) {
+               struct node *p;
+               struct audit_chunk *chunk;
+
+               p = list_entry(victim->chunks.next, struct node, list);
+               chunk = find_chunk(p);
+               get_inotify_watch(&chunk->watch);
+               spin_unlock(&hash_lock);
+
+               untag_chunk(chunk, p);
+
+               put_inotify_watch(&chunk->watch);
+               spin_lock(&hash_lock);
+       }
+       spin_unlock(&hash_lock);
+       put_tree(victim);
+}
+
+/* trim the uncommitted chunks from tree */
+
+static void trim_marked(struct audit_tree *tree)
+{
+       struct list_head *p, *q;
+       spin_lock(&hash_lock);
+       if (tree->goner) {
+               spin_unlock(&hash_lock);
+               return;
+       }
+       /* reorder */
+       for (p = tree->chunks.next; p != &tree->chunks; p = q) {
+               struct node *node = list_entry(p, struct node, list);
+               q = p->next;
+               if (node->index & (1U<<31)) {
+                       list_del_init(p);
+                       list_add(p, &tree->chunks);
+               }
+       }
+
+       while (!list_empty(&tree->chunks)) {
+               struct node *node;
+               struct audit_chunk *chunk;
+
+               node = list_entry(tree->chunks.next, struct node, list);
+
+               /* have we run out of marked? */
+               if (!(node->index & (1U<<31)))
+                       break;
+
+               chunk = find_chunk(node);
+               get_inotify_watch(&chunk->watch);
+               spin_unlock(&hash_lock);
+
+               untag_chunk(chunk, node);
+
+               put_inotify_watch(&chunk->watch);
+               spin_lock(&hash_lock);
+       }
+       if (!tree->root && !tree->goner) {
+               tree->goner = 1;
+               spin_unlock(&hash_lock);
+               mutex_lock(&audit_filter_mutex);
+               kill_rules(tree);
+               list_del_init(&tree->list);
+               mutex_unlock(&audit_filter_mutex);
+               prune_one(tree);
+       } else {
+               spin_unlock(&hash_lock);
+       }
+}
+
+/* called with audit_filter_mutex */
+int audit_remove_tree_rule(struct audit_krule *rule)
+{
+       struct audit_tree *tree;
+       tree = rule->tree;
+       if (tree) {
+               spin_lock(&hash_lock);
+               list_del_init(&rule->rlist);
+               if (list_empty(&tree->rules) && !tree->goner) {
+                       tree->root = NULL;
+                       list_del_init(&tree->same_root);
+                       tree->goner = 1;
+                       list_move(&tree->list, &prune_list);
+                       rule->tree = NULL;
+                       spin_unlock(&hash_lock);
+                       audit_schedule_prune();
+                       return 1;
+               }
+               rule->tree = NULL;
+               spin_unlock(&hash_lock);
+               return 1;
+       }
+       return 0;
+}
+
+void audit_trim_trees(void)
+{
+       struct list_head cursor;
+
+       mutex_lock(&audit_filter_mutex);
+       list_add(&cursor, &tree_list);
+       while (cursor.next != &tree_list) {
+               struct audit_tree *tree;
+               struct nameidata nd;
+               struct vfsmount *root_mnt;
+               struct node *node;
+               struct list_head list;
+               int err;
+
+               tree = container_of(cursor.next, struct audit_tree, list);
+               get_tree(tree);
+               list_del(&cursor);
+               list_add(&cursor, &tree->list);
+               mutex_unlock(&audit_filter_mutex);
+
+               err = path_lookup(tree->pathname, 0, &nd);
+               if (err)
+                       goto skip_it;
+
+               root_mnt = collect_mounts(nd.mnt, nd.dentry);
+               path_release(&nd);
+               if (!root_mnt)
+                       goto skip_it;
+
+               list_add_tail(&list, &root_mnt->mnt_list);
+               spin_lock(&hash_lock);
+               list_for_each_entry(node, &tree->chunks, list) {
+                       struct audit_chunk *chunk = find_chunk(node);
+                       struct inode *inode = chunk->watch.inode;
+                       struct vfsmount *mnt;
+                       node->index |= 1U<<31;
+                       list_for_each_entry(mnt, &list, mnt_list) {
+                               if (mnt->mnt_root->d_inode == inode) {
+                                       node->index &= ~(1U<<31);
+                                       break;
+                               }
+                       }
+               }
+               spin_unlock(&hash_lock);
+               trim_marked(tree);
+               put_tree(tree);
+               list_del_init(&list);
+               drop_collected_mounts(root_mnt);
+skip_it:
+               mutex_lock(&audit_filter_mutex);
+       }
+       list_del(&cursor);
+       mutex_unlock(&audit_filter_mutex);
+}
+
+static int is_under(struct vfsmount *mnt, struct dentry *dentry,
+                   struct nameidata *nd)
+{
+       if (mnt != nd->mnt) {
+               for (;;) {
+                       if (mnt->mnt_parent == mnt)
+                               return 0;
+                       if (mnt->mnt_parent == nd->mnt)
+                                       break;
+                       mnt = mnt->mnt_parent;
+               }
+               dentry = mnt->mnt_mountpoint;
+       }
+       return is_subdir(dentry, nd->dentry);
+}
+
+int audit_make_tree(struct audit_krule *rule, char *pathname, u32 op)
+{
+
+       if (pathname[0] != '/' ||
+           rule->listnr != AUDIT_FILTER_EXIT ||
+           op & ~AUDIT_EQUAL ||
+           rule->inode_f || rule->watch || rule->tree)
+               return -EINVAL;
+       rule->tree = alloc_tree(pathname);
+       if (!rule->tree)
+               return -ENOMEM;
+       return 0;
+}
+
+void audit_put_tree(struct audit_tree *tree)
+{
+       put_tree(tree);
+}
+
+/* called with audit_filter_mutex */
+int audit_add_tree_rule(struct audit_krule *rule)
+{
+       struct audit_tree *seed = rule->tree, *tree;
+       struct nameidata nd;
+       struct vfsmount *mnt, *p;
+       struct list_head list;
+       int err;
+
+       list_for_each_entry(tree, &tree_list, list) {
+               if (!strcmp(seed->pathname, tree->pathname)) {
+                       put_tree(seed);
+                       rule->tree = tree;
+                       list_add(&rule->rlist, &tree->rules);
+                       return 0;
+               }
+       }
+       tree = seed;
+       list_add(&tree->list, &tree_list);
+       list_add(&rule->rlist, &tree->rules);
+       /* do not set rule->tree yet */
+       mutex_unlock(&audit_filter_mutex);
+
+       err = path_lookup(tree->pathname, 0, &nd);
+       if (err)
+               goto Err;
+       mnt = collect_mounts(nd.mnt, nd.dentry);
+       path_release(&nd);
+       if (!mnt) {
+               err = -ENOMEM;
+               goto Err;
+       }
+       list_add_tail(&list, &mnt->mnt_list);
+
+       get_tree(tree);
+       list_for_each_entry(p, &list, mnt_list) {
+               err = tag_chunk(p->mnt_root->d_inode, tree);
+               if (err)
+                       break;
+       }
+
+       list_del(&list);
+       drop_collected_mounts(mnt);
+
+       if (!err) {
+               struct node *node;
+               spin_lock(&hash_lock);
+               list_for_each_entry(node, &tree->chunks, list)
+                       node->index &= ~(1U<<31);
+               spin_unlock(&hash_lock);
+       } else {
+               trim_marked(tree);
+               goto Err;
+       }
+
+       mutex_lock(&audit_filter_mutex);
+       if (list_empty(&rule->rlist)) {
+               put_tree(tree);
+               return -ENOENT;
+       }
+       rule->tree = tree;
+       put_tree(tree);
+
+       return 0;
+Err:
+       mutex_lock(&audit_filter_mutex);
+       list_del_init(&tree->list);
+       list_del_init(&tree->rules);
+       put_tree(tree);
+       return err;
+}
+
+int audit_tag_tree(char *old, char *new)
+{
+       struct list_head cursor, barrier;
+       int failed = 0;
+       struct nameidata nd;
+       struct vfsmount *tagged;
+       struct list_head list;
+       struct vfsmount *mnt;
+       struct dentry *dentry;
+       int err;
+
+       err = path_lookup(new, 0, &nd);
+       if (err)
+               return err;
+       tagged = collect_mounts(nd.mnt, nd.dentry);
+       path_release(&nd);
+       if (!tagged)
+               return -ENOMEM;
+
+       err = path_lookup(old, 0, &nd);
+       if (err) {
+               drop_collected_mounts(tagged);
+               return err;
+       }
+       mnt = mntget(nd.mnt);
+       dentry = dget(nd.dentry);
+       path_release(&nd);
+
+       if (dentry == tagged->mnt_root && dentry == mnt->mnt_root)
+               follow_up(&mnt, &dentry);
+
+       list_add_tail(&list, &tagged->mnt_list);
+
+       mutex_lock(&audit_filter_mutex);
+       list_add(&barrier, &tree_list);
+       list_add(&cursor, &barrier);
+
+       while (cursor.next != &tree_list) {
+               struct audit_tree *tree;
+               struct vfsmount *p;
+
+               tree = container_of(cursor.next, struct audit_tree, list);
+               get_tree(tree);
+               list_del(&cursor);
+               list_add(&cursor, &tree->list);
+               mutex_unlock(&audit_filter_mutex);
+
+               err = path_lookup(tree->pathname, 0, &nd);
+               if (err) {
+                       put_tree(tree);
+                       mutex_lock(&audit_filter_mutex);
+                       continue;
+               }
+
+               spin_lock(&vfsmount_lock);
+               if (!is_under(mnt, dentry, &nd)) {
+                       spin_unlock(&vfsmount_lock);
+                       path_release(&nd);
+                       put_tree(tree);
+                       mutex_lock(&audit_filter_mutex);
+                       continue;
+               }
+               spin_unlock(&vfsmount_lock);
+               path_release(&nd);
+
+               list_for_each_entry(p, &list, mnt_list) {
+                       failed = tag_chunk(p->mnt_root->d_inode, tree);
+                       if (failed)
+                               break;
+               }
+
+               if (failed) {
+                       put_tree(tree);
+                       mutex_lock(&audit_filter_mutex);
+                       break;
+               }
+
+               mutex_lock(&audit_filter_mutex);
+               spin_lock(&hash_lock);
+               if (!tree->goner) {
+                       list_del(&tree->list);
+                       list_add(&tree->list, &tree_list);
+               }
+               spin_unlock(&hash_lock);
+               put_tree(tree);
+       }
+
+       while (barrier.prev != &tree_list) {
+               struct audit_tree *tree;
+
+               tree = container_of(barrier.prev, struct audit_tree, list);
+               get_tree(tree);
+               list_del(&tree->list);
+               list_add(&tree->list, &barrier);
+               mutex_unlock(&audit_filter_mutex);
+
+               if (!failed) {
+                       struct node *node;
+                       spin_lock(&hash_lock);
+                       list_for_each_entry(node, &tree->chunks, list)
+                               node->index &= ~(1U<<31);
+                       spin_unlock(&hash_lock);
+               } else {
+                       trim_marked(tree);
+               }
+
+               put_tree(tree);
+               mutex_lock(&audit_filter_mutex);
+       }
+       list_del(&barrier);
+       list_del(&cursor);
+       list_del(&list);
+       mutex_unlock(&audit_filter_mutex);
+       dput(dentry);
+       mntput(mnt);
+       drop_collected_mounts(tagged);
+       return failed;
+}
+
+/*
+ * That gets run when evict_chunk() ends up needing to kill audit_tree.
+ * Runs from a separate thread, with audit_cmd_mutex held.
+ */
+void audit_prune_trees(void)
+{
+       mutex_lock(&audit_filter_mutex);
+
+       while (!list_empty(&prune_list)) {
+               struct audit_tree *victim;
+
+               victim = list_entry(prune_list.next, struct audit_tree, list);
+               list_del_init(&victim->list);
+
+               mutex_unlock(&audit_filter_mutex);
+
+               prune_one(victim);
+
+               mutex_lock(&audit_filter_mutex);
+       }
+
+       mutex_unlock(&audit_filter_mutex);
+}
+
+/*
+ *  Here comes the stuff asynchronous to auditctl operations
+ */
+
+/* inode->inotify_mutex is locked */
+static void evict_chunk(struct audit_chunk *chunk)
+{
+       struct audit_tree *owner;
+       int n;
+
+       if (chunk->dead)
+               return;
+
+       chunk->dead = 1;
+       mutex_lock(&audit_filter_mutex);
+       spin_lock(&hash_lock);
+       while (!list_empty(&chunk->trees)) {
+               owner = list_entry(chunk->trees.next,
+                                  struct audit_tree, same_root);
+               owner->goner = 1;
+               owner->root = NULL;
+               list_del_init(&owner->same_root);
+               spin_unlock(&hash_lock);
+               kill_rules(owner);
+               list_move(&owner->list, &prune_list);
+               audit_schedule_prune();
+               spin_lock(&hash_lock);
+       }
+       list_del_rcu(&chunk->hash);
+       for (n = 0; n < chunk->count; n++)
+               list_del_init(&chunk->owners[n].list);
+       spin_unlock(&hash_lock);
+       mutex_unlock(&audit_filter_mutex);
+}
+
+static void handle_event(struct inotify_watch *watch, u32 wd, u32 mask,
+                         u32 cookie, const char *dname, struct inode *inode)
+{
+       struct audit_chunk *chunk = container_of(watch, struct audit_chunk, watch);
+
+       if (mask & IN_IGNORED) {
+               evict_chunk(chunk);
+               put_inotify_watch(watch);
+       }
+}
+
+static void destroy_watch(struct inotify_watch *watch)
+{
+       struct audit_chunk *chunk = container_of(watch, struct audit_chunk, watch);
+       free_chunk(chunk);
+}
+
+static const struct inotify_operations rtree_inotify_ops = {
+       .handle_event   = handle_event,
+       .destroy_watch  = destroy_watch,
+};
+
+static int __init audit_tree_init(void)
+{
+       int i;
+
+       rtree_ih = inotify_init(&rtree_inotify_ops);
+       if (IS_ERR(rtree_ih))
+               audit_panic("cannot initialize inotify handle for rectree watches");
+
+       for (i = 0; i < HASH_SIZE; i++)
+               INIT_LIST_HEAD(&chunk_hash_heads[i]);
+
+       return 0;
+}
+__initcall(audit_tree_init);
index 359645cff5b2cd662ea209458203eef6b1e96976..5d96f2cc7be8137164f8881d830ad013f39da949 100644 (file)
@@ -87,7 +87,7 @@ struct list_head audit_filter_list[AUDIT_NR_FILTERS] = {
 #endif
 };
 
-static DEFINE_MUTEX(audit_filter_mutex);
+DEFINE_MUTEX(audit_filter_mutex);
 
 /* Inotify handle */
 extern struct inotify_handle *audit_ih;
@@ -145,7 +145,7 @@ static inline void audit_free_rule(struct audit_entry *e)
        kfree(e);
 }
 
-static inline void audit_free_rule_rcu(struct rcu_head *head)
+void audit_free_rule_rcu(struct rcu_head *head)
 {
        struct audit_entry *e = container_of(head, struct audit_entry, rcu);
        audit_free_rule(e);
@@ -217,7 +217,7 @@ static inline struct audit_entry *audit_init_entry(u32 field_count)
 
 /* Unpack a filter field's string representation from user-space
  * buffer. */
-static char *audit_unpack_string(void **bufp, size_t *remain, size_t len)
+char *audit_unpack_string(void **bufp, size_t *remain, size_t len)
 {
        char *str;
 
@@ -247,7 +247,7 @@ static inline int audit_to_inode(struct audit_krule *krule,
                                 struct audit_field *f)
 {
        if (krule->listnr != AUDIT_FILTER_EXIT ||
-           krule->watch || krule->inode_f)
+           krule->watch || krule->inode_f || krule->tree)
                return -EINVAL;
 
        krule->inode_f = f;
@@ -266,7 +266,7 @@ static int audit_to_watch(struct audit_krule *krule, char *path, int len,
        if (path[0] != '/' || path[len-1] == '/' ||
            krule->listnr != AUDIT_FILTER_EXIT ||
            op & ~AUDIT_EQUAL ||
-           krule->inode_f || krule->watch) /* 1 inode # per rule, for hash */
+           krule->inode_f || krule->watch || krule->tree)
                return -EINVAL;
 
        watch = audit_init_watch(path);
@@ -622,6 +622,17 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
                                goto exit_free;
                        }
                        break;
+               case AUDIT_DIR:
+                       str = audit_unpack_string(&bufp, &remain, f->val);
+                       if (IS_ERR(str))
+                               goto exit_free;
+                       entry->rule.buflen += f->val;
+
+                       err = audit_make_tree(&entry->rule, str, f->op);
+                       kfree(str);
+                       if (err)
+                               goto exit_free;
+                       break;
                case AUDIT_INODE:
                        err = audit_to_inode(&entry->rule, f);
                        if (err)
@@ -668,7 +679,7 @@ exit_free:
 }
 
 /* Pack a filter field's string representation into data block. */
-static inline size_t audit_pack_string(void **bufp, char *str)
+static inline size_t audit_pack_string(void **bufp, const char *str)
 {
        size_t len = strlen(str);
 
@@ -747,6 +758,11 @@ static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule)
                        data->buflen += data->values[i] =
                                audit_pack_string(&bufp, krule->watch->path);
                        break;
+               case AUDIT_DIR:
+                       data->buflen += data->values[i] =
+                               audit_pack_string(&bufp,
+                                                 audit_tree_path(krule->tree));
+                       break;
                case AUDIT_FILTERKEY:
                        data->buflen += data->values[i] =
                                audit_pack_string(&bufp, krule->filterkey);
@@ -795,6 +811,11 @@ static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b)
                        if (strcmp(a->watch->path, b->watch->path))
                                return 1;
                        break;
+               case AUDIT_DIR:
+                       if (strcmp(audit_tree_path(a->tree),
+                                  audit_tree_path(b->tree)))
+                               return 1;
+                       break;
                case AUDIT_FILTERKEY:
                        /* both filterkeys exist based on above type compare */
                        if (strcmp(a->filterkey, b->filterkey))
@@ -897,6 +918,14 @@ static struct audit_entry *audit_dupe_rule(struct audit_krule *old,
        new->inode_f = old->inode_f;
        new->watch = NULL;
        new->field_count = old->field_count;
+       /*
+        * note that we are OK with not refcounting here; audit_match_tree()
+        * never dereferences tree and we can't get false positives there
+        * since we'd have to have rule gone from the list *and* removed
+        * before the chunks found by lookup had been allocated, i.e. before
+        * the beginning of list scan.
+        */
+       new->tree = old->tree;
        memcpy(new->fields, old->fields, sizeof(struct audit_field) * fcount);
 
        /* deep copy this information, updating the se_rule fields, because
@@ -1217,6 +1246,7 @@ static inline int audit_add_rule(struct audit_entry *entry,
        struct audit_entry *e;
        struct audit_field *inode_f = entry->rule.inode_f;
        struct audit_watch *watch = entry->rule.watch;
+       struct audit_tree *tree = entry->rule.tree;
        struct nameidata *ndp = NULL, *ndw = NULL;
        int h, err;
 #ifdef CONFIG_AUDITSYSCALL
@@ -1238,6 +1268,9 @@ static inline int audit_add_rule(struct audit_entry *entry,
        mutex_unlock(&audit_filter_mutex);
        if (e) {
                err = -EEXIST;
+               /* normally audit_add_tree_rule() will free it on failure */
+               if (tree)
+                       audit_put_tree(tree);
                goto error;
        }
 
@@ -1259,6 +1292,13 @@ static inline int audit_add_rule(struct audit_entry *entry,
                h = audit_hash_ino((u32)watch->ino);
                list = &audit_inode_hash[h];
        }
+       if (tree) {
+               err = audit_add_tree_rule(&entry->rule);
+               if (err) {
+                       mutex_unlock(&audit_filter_mutex);
+                       goto error;
+               }
+       }
 
        if (entry->rule.flags & AUDIT_FILTER_PREPEND) {
                list_add_rcu(&entry->list, list);
@@ -1292,6 +1332,7 @@ static inline int audit_del_rule(struct audit_entry *entry,
        struct audit_entry  *e;
        struct audit_field *inode_f = entry->rule.inode_f;
        struct audit_watch *watch, *tmp_watch = entry->rule.watch;
+       struct audit_tree *tree = entry->rule.tree;
        LIST_HEAD(inotify_list);
        int h, ret = 0;
 #ifdef CONFIG_AUDITSYSCALL
@@ -1336,6 +1377,9 @@ static inline int audit_del_rule(struct audit_entry *entry,
                }
        }
 
+       if (e->rule.tree)
+               audit_remove_tree_rule(&e->rule);
+
        list_del_rcu(&e->list);
        call_rcu(&e->rcu, audit_free_rule_rcu);
 
@@ -1354,6 +1398,8 @@ static inline int audit_del_rule(struct audit_entry *entry,
 out:
        if (tmp_watch)
                audit_put_watch(tmp_watch); /* match initial get */
+       if (tree)
+               audit_put_tree(tree);   /* that's the temporary one */
 
        return ret;
 }
@@ -1498,7 +1544,7 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
                 * auditctl to read from it... which isn't ever going to
                 * happen if we're actually running in the context of auditctl
                 * trying to _send_ the stuff */
-                
+
                dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL);
                if (!dest)
                        return -ENOMEM;
@@ -1678,7 +1724,7 @@ int audit_filter_type(int type)
 {
        struct audit_entry *e;
        int result = 0;
-       
+
        rcu_read_lock();
        if (list_empty(&audit_filter_list[AUDIT_FILTER_TYPE]))
                goto unlock_and_return;
@@ -1737,6 +1783,7 @@ int selinux_audit_rule_update(void)
 {
        struct audit_entry *entry, *n, *nentry;
        struct audit_watch *watch;
+       struct audit_tree *tree;
        int i, err = 0;
 
        /* audit_filter_mutex synchronizes the writers */
@@ -1748,6 +1795,7 @@ int selinux_audit_rule_update(void)
                                continue;
 
                        watch = entry->rule.watch;
+                       tree = entry->rule.tree;
                        nentry = audit_dupe_rule(&entry->rule, watch);
                        if (unlikely(IS_ERR(nentry))) {
                                /* save the first error encountered for the
@@ -1763,7 +1811,9 @@ int selinux_audit_rule_update(void)
                                        list_add(&nentry->rule.rlist,
                                                 &watch->rules);
                                        list_del(&entry->rule.rlist);
-                               }
+                               } else if (tree)
+                                       list_replace_init(&entry->rule.rlist,
+                                                    &nentry->rule.rlist);
                                list_replace_rcu(&entry->list, &nentry->list);
                        }
                        call_rcu(&entry->rcu, audit_free_rule_rcu);
index 938e60a61882008d732bcdf83377fc29d3fa8368..bce9ecdb771240885bd3d1c0c30f7565ebbd1eb5 100644 (file)
@@ -65,6 +65,7 @@
 #include <linux/binfmts.h>
 #include <linux/highmem.h>
 #include <linux/syscalls.h>
+#include <linux/inotify.h>
 
 #include "audit.h"
 
@@ -179,6 +180,11 @@ struct audit_aux_data_pids {
        int                     pid_count;
 };
 
+struct audit_tree_refs {
+       struct audit_tree_refs *next;
+       struct audit_chunk *c[31];
+};
+
 /* The per-task audit context. */
 struct audit_context {
        int                 dummy;      /* must be the first element */
@@ -211,6 +217,9 @@ struct audit_context {
        pid_t               target_pid;
        u32                 target_sid;
 
+       struct audit_tree_refs *trees, *first_trees;
+       int tree_count;
+
 #if AUDIT_DEBUG
        int                 put_count;
        int                 ino_count;
@@ -265,6 +274,117 @@ static int audit_match_perm(struct audit_context *ctx, int mask)
        }
 }
 
+/*
+ * We keep a linked list of fixed-sized (31 pointer) arrays of audit_chunk *;
+ * ->first_trees points to its beginning, ->trees - to the current end of data.
+ * ->tree_count is the number of free entries in array pointed to by ->trees.
+ * Original condition is (NULL, NULL, 0); as soon as it grows we never revert to NULL,
+ * "empty" becomes (p, p, 31) afterwards.  We don't shrink the list (and seriously,
+ * it's going to remain 1-element for almost any setup) until we free context itself.
+ * References in it _are_ dropped - at the same time we free/drop aux stuff.
+ */
+
+#ifdef CONFIG_AUDIT_TREE
+static int put_tree_ref(struct audit_context *ctx, struct audit_chunk *chunk)
+{
+       struct audit_tree_refs *p = ctx->trees;
+       int left = ctx->tree_count;
+       if (likely(left)) {
+               p->c[--left] = chunk;
+               ctx->tree_count = left;
+               return 1;
+       }
+       if (!p)
+               return 0;
+       p = p->next;
+       if (p) {
+               p->c[30] = chunk;
+               ctx->trees = p;
+               ctx->tree_count = 30;
+               return 1;
+       }
+       return 0;
+}
+
+static int grow_tree_refs(struct audit_context *ctx)
+{
+       struct audit_tree_refs *p = ctx->trees;
+       ctx->trees = kzalloc(sizeof(struct audit_tree_refs), GFP_KERNEL);
+       if (!ctx->trees) {
+               ctx->trees = p;
+               return 0;
+       }
+       if (p)
+               p->next = ctx->trees;
+       else
+               ctx->first_trees = ctx->trees;
+       ctx->tree_count = 31;
+       return 1;
+}
+#endif
+
+static void unroll_tree_refs(struct audit_context *ctx,
+                     struct audit_tree_refs *p, int count)
+{
+#ifdef CONFIG_AUDIT_TREE
+       struct audit_tree_refs *q;
+       int n;
+       if (!p) {
+               /* we started with empty chain */
+               p = ctx->first_trees;
+               count = 31;
+               /* if the very first allocation has failed, nothing to do */
+               if (!p)
+                       return;
+       }
+       n = count;
+       for (q = p; q != ctx->trees; q = q->next, n = 31) {
+               while (n--) {
+                       audit_put_chunk(q->c[n]);
+                       q->c[n] = NULL;
+               }
+       }
+       while (n-- > ctx->tree_count) {
+               audit_put_chunk(q->c[n]);
+               q->c[n] = NULL;
+       }
+       ctx->trees = p;
+       ctx->tree_count = count;
+#endif
+}
+
+static void free_tree_refs(struct audit_context *ctx)
+{
+       struct audit_tree_refs *p, *q;
+       for (p = ctx->first_trees; p; p = q) {
+               q = p->next;
+               kfree(p);
+       }
+}
+
+static int match_tree_refs(struct audit_context *ctx, struct audit_tree *tree)
+{
+#ifdef CONFIG_AUDIT_TREE
+       struct audit_tree_refs *p;
+       int n;
+       if (!tree)
+               return 0;
+       /* full ones */
+       for (p = ctx->first_trees; p != ctx->trees; p = p->next) {
+               for (n = 0; n < 31; n++)
+                       if (audit_tree_match(p->c[n], tree))
+                               return 1;
+       }
+       /* partial */
+       if (p) {
+               for (n = ctx->tree_count; n < 31; n++)
+                       if (audit_tree_match(p->c[n], tree))
+                               return 1;
+       }
+#endif
+       return 0;
+}
+
 /* Determine if any context name data matches a rule's watch data */
 /* Compare a task_struct with an audit_rule.  Return 1 on match, 0
  * otherwise. */
@@ -320,7 +440,7 @@ static int audit_filter_rules(struct task_struct *tsk,
                        result = audit_comparator(tsk->personality, f->op, f->val);
                        break;
                case AUDIT_ARCH:
-                       if (ctx)
+                       if (ctx)
                                result = audit_comparator(ctx->arch, f->op, f->val);
                        break;
 
@@ -379,6 +499,10 @@ static int audit_filter_rules(struct task_struct *tsk,
                                result = (name->dev == rule->watch->dev &&
                                          name->ino == rule->watch->ino);
                        break;
+               case AUDIT_DIR:
+                       if (ctx)
+                               result = match_tree_refs(ctx, rule->tree);
+                       break;
                case AUDIT_LOGINUID:
                        result = 0;
                        if (ctx)
@@ -727,6 +851,8 @@ static inline void audit_free_context(struct audit_context *context)
                               context->name_count, count);
                }
                audit_free_names(context);
+               unroll_tree_refs(context, NULL, 0);
+               free_tree_refs(context);
                audit_free_aux(context);
                kfree(context->filterkey);
                kfree(context);
@@ -898,7 +1024,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
        if (context->personality != PER_LINUX)
                audit_log_format(ab, " per=%lx", context->personality);
        if (context->return_valid)
-               audit_log_format(ab, " success=%s exit=%ld", 
+               audit_log_format(ab, " success=%s exit=%ld",
                                 (context->return_valid==AUDITSC_SUCCESS)?"yes":"no",
                                 context->return_code);
 
@@ -1135,8 +1261,8 @@ void audit_free(struct task_struct *tsk)
                return;
 
        /* Check for system calls that do not go through the exit
-        * function (e.g., exit_group), then free context block. 
-        * We use GFP_ATOMIC here because we might be doing this 
+        * function (e.g., exit_group), then free context block.
+        * We use GFP_ATOMIC here because we might be doing this
         * in the context of the idle thread */
        /* that can happen only if we are called from do_exit() */
        if (context->in_syscall && context->auditable)
@@ -1270,6 +1396,7 @@ void audit_syscall_exit(int valid, long return_code)
                tsk->audit_context = new_context;
        } else {
                audit_free_names(context);
+               unroll_tree_refs(context, NULL, 0);
                audit_free_aux(context);
                context->aux = NULL;
                context->aux_pids = NULL;
@@ -1281,6 +1408,95 @@ void audit_syscall_exit(int valid, long return_code)
        }
 }
 
+static inline void handle_one(const struct inode *inode)
+{
+#ifdef CONFIG_AUDIT_TREE
+       struct audit_context *context;
+       struct audit_tree_refs *p;
+       struct audit_chunk *chunk;
+       int count;
+       if (likely(list_empty(&inode->inotify_watches)))
+               return;
+       context = current->audit_context;
+       p = context->trees;
+       count = context->tree_count;
+       rcu_read_lock();
+       chunk = audit_tree_lookup(inode);
+       rcu_read_unlock();
+       if (!chunk)
+               return;
+       if (likely(put_tree_ref(context, chunk)))
+               return;
+       if (unlikely(!grow_tree_refs(context))) {
+               printk(KERN_WARNING "out of memory, audit has lost a tree reference");
+               audit_set_auditable(context);
+               audit_put_chunk(chunk);
+               unroll_tree_refs(context, p, count);
+               return;
+       }
+       put_tree_ref(context, chunk);
+#endif
+}
+
+static void handle_path(const struct dentry *dentry)
+{
+#ifdef CONFIG_AUDIT_TREE
+       struct audit_context *context;
+       struct audit_tree_refs *p;
+       const struct dentry *d, *parent;
+       struct audit_chunk *drop;
+       unsigned long seq;
+       int count;
+
+       context = current->audit_context;
+       p = context->trees;
+       count = context->tree_count;
+retry:
+       drop = NULL;
+       d = dentry;
+       rcu_read_lock();
+       seq = read_seqbegin(&rename_lock);
+       for(;;) {
+               struct inode *inode = d->d_inode;
+               if (inode && unlikely(!list_empty(&inode->inotify_watches))) {
+                       struct audit_chunk *chunk;
+                       chunk = audit_tree_lookup(inode);
+                       if (chunk) {
+                               if (unlikely(!put_tree_ref(context, chunk))) {
+                                       drop = chunk;
+                                       break;
+                               }
+                       }
+               }
+               parent = d->d_parent;
+               if (parent == d)
+                       break;
+               d = parent;
+       }
+       if (unlikely(read_seqretry(&rename_lock, seq) || drop)) {  /* in this order */
+               rcu_read_unlock();
+               if (!drop) {
+                       /* just a race with rename */
+                       unroll_tree_refs(context, p, count);
+                       goto retry;
+               }
+               audit_put_chunk(drop);
+               if (grow_tree_refs(context)) {
+                       /* OK, got more space */
+                       unroll_tree_refs(context, p, count);
+                       goto retry;
+               }
+               /* too bad */
+               printk(KERN_WARNING
+                       "out of memory, audit has lost a tree reference");
+               unroll_tree_refs(context, p, count);
+               audit_set_auditable(context);
+               return;
+       }
+       rcu_read_unlock();
+#endif
+}
+
 /**
  * audit_getname - add a name to the list
  * @name: name to add
@@ -1316,7 +1532,7 @@ void __audit_getname(const char *name)
                context->pwdmnt = mntget(current->fs->pwdmnt);
                read_unlock(&current->fs->lock);
        }
-               
+
 }
 
 /* audit_putname - intercept a putname request
@@ -1399,14 +1615,15 @@ static void audit_copy_inode(struct audit_names *name, const struct inode *inode
 /**
  * audit_inode - store the inode and device from a lookup
  * @name: name being audited
- * @inode: inode being audited
+ * @dentry: dentry being audited
  *
  * Called from fs/namei.c:path_lookup().
  */
-void __audit_inode(const char *name, const struct inode *inode)
+void __audit_inode(const char *name, const struct dentry *dentry)
 {
        int idx;
        struct audit_context *context = current->audit_context;
+       const struct inode *inode = dentry->d_inode;
 
        if (!context->in_syscall)
                return;
@@ -1426,13 +1643,14 @@ void __audit_inode(const char *name, const struct inode *inode)
                idx = context->name_count - 1;
                context->names[idx].name = NULL;
        }
+       handle_path(dentry);
        audit_copy_inode(&context->names[idx], inode);
 }
 
 /**
  * audit_inode_child - collect inode info for created/removed objects
  * @dname: inode's dentry name
- * @inode: inode being audited
+ * @dentry: dentry being audited
  * @parent: inode of dentry parent
  *
  * For syscalls that create or remove filesystem objects, audit_inode
@@ -1443,17 +1661,20 @@ void __audit_inode(const char *name, const struct inode *inode)
  * must be hooked prior, in order to capture the target inode during
  * unsuccessful attempts.
  */
-void __audit_inode_child(const char *dname, const struct inode *inode,
+void __audit_inode_child(const char *dname, const struct dentry *dentry,
                         const struct inode *parent)
 {
        int idx;
        struct audit_context *context = current->audit_context;
        const char *found_parent = NULL, *found_child = NULL;
+       const struct inode *inode = dentry->d_inode;
        int dirlen = 0;
 
        if (!context->in_syscall)
                return;
 
+       if (inode)
+               handle_one(inode);
        /* determine matching parent */
        if (!dname)
                goto add_names;
index 4e350a36ed6a177a5422cf097c8120269490d785..efbd9cdce1322d8a6e0c93ada872d68aadacf38e 100644 (file)
@@ -3,20 +3,18 @@
  *
  * Copyright (C) 1997  Andrew Main <zefram@fysh.org>
  *
- * Integrated into 2.1.97+,  Andrew G. Morgan <morgan@transmeta.com>
+ * Integrated into 2.1.97+,  Andrew G. Morgan <morgan@kernel.org>
  * 30 May 2002:        Cleanup, Robert M. Love <rml@tech9.net>
- */ 
+ */
 
 #include <linux/capability.h>
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/security.h>
 #include <linux/syscalls.h>
+#include <linux/pid_namespace.h>
 #include <asm/uaccess.h>
 
-unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
-kernel_cap_t cap_bset = CAP_INIT_EFF_SET;
-
 /*
  * This lock protects task->cap_* for all tasks including current.
  * Locking rule: acquire this prior to tasklist_lock.
@@ -40,49 +38,49 @@ static DEFINE_SPINLOCK(task_capability_lock);
  */
 asmlinkage long sys_capget(cap_user_header_t header, cap_user_data_t dataptr)
 {
-     int ret = 0;
-     pid_t pid;
-     __u32 version;
-     struct task_struct *target;
-     struct __user_cap_data_struct data;
-
-     if (get_user(version, &header->version))
-            return -EFAULT;
-
-     if (version != _LINUX_CAPABILITY_VERSION) {
-            if (put_user(_LINUX_CAPABILITY_VERSION, &header->version))
-                    return -EFAULT; 
-             return -EINVAL;
-     }
+       int ret = 0;
+       pid_t pid;
+       __u32 version;
+       struct task_struct *target;
+       struct __user_cap_data_struct data;
+
+       if (get_user(version, &header->version))
+               return -EFAULT;
+
+       if (version != _LINUX_CAPABILITY_VERSION) {
+               if (put_user(_LINUX_CAPABILITY_VERSION, &header->version))
+                       return -EFAULT;
+               return -EINVAL;
+       }
 
-     if (get_user(pid, &header->pid))
-            return -EFAULT;
+       if (get_user(pid, &header->pid))
+               return -EFAULT;
 
-     if (pid < 0) 
-             return -EINVAL;
+       if (pid < 0)
+               return -EINVAL;
 
-     spin_lock(&task_capability_lock);
-     read_lock(&tasklist_lock); 
+       spin_lock(&task_capability_lock);
+       read_lock(&tasklist_lock);
 
-     if (pid && pid != current->pid) {
-            target = find_task_by_pid(pid);
-            if (!target) {
-                 ret = -ESRCH;
-                 goto out;
-            }
-     } else
-            target = current;
+       if (pid && pid != task_pid_vnr(current)) {
+               target = find_task_by_vpid(pid);
+               if (!target) {
+                       ret = -ESRCH;
+                       goto out;
+               }
+       } else
+               target = current;
 
-     ret = security_capget(target, &data.effective, &data.inheritable, &data.permitted);
+       ret = security_capget(target, &data.effective, &data.inheritable, &data.permitted);
 
 out:
-     read_unlock(&tasklist_lock); 
-     spin_unlock(&task_capability_lock);
+       read_unlock(&tasklist_lock);
+       spin_unlock(&task_capability_lock);
 
-     if (!ret && copy_to_user(dataptr, &data, sizeof data))
-          return -EFAULT; 
+       if (!ret && copy_to_user(dataptr, &data, sizeof data))
+               return -EFAULT;
 
-     return ret;
+       return ret;
 }
 
 /*
@@ -98,7 +96,7 @@ static inline int cap_set_pg(int pgrp_nr, kernel_cap_t *effective,
        int found = 0;
        struct pid *pgrp;
 
-       pgrp = find_pid(pgrp_nr);
+       pgrp = find_vpid(pgrp_nr);
        do_each_pid_task(pgrp, PIDTYPE_PGID, g) {
                target = g;
                while_each_thread(g, target) {
@@ -115,7 +113,7 @@ static inline int cap_set_pg(int pgrp_nr, kernel_cap_t *effective,
        } while_each_pid_task(pgrp, PIDTYPE_PGID, g);
 
        if (!found)
-            ret = 0;
+               ret = 0;
        return ret;
 }
 
@@ -132,7 +130,7 @@ static inline int cap_set_all(kernel_cap_t *effective,
      int found = 0;
 
      do_each_thread(g, target) {
-             if (target == current || is_init(target))
+             if (target == current || is_container_init(target->group_leader))
                      continue;
              found = 1;
             if (security_capset_check(target, effective, inheritable,
@@ -169,68 +167,68 @@ static inline int cap_set_all(kernel_cap_t *effective,
  */
 asmlinkage long sys_capset(cap_user_header_t header, const cap_user_data_t data)
 {
-     kernel_cap_t inheritable, permitted, effective;
-     __u32 version;
-     struct task_struct *target;
-     int ret;
-     pid_t pid;
-
-     if (get_user(version, &header->version))
-            return -EFAULT; 
-
-     if (version != _LINUX_CAPABILITY_VERSION) {
-            if (put_user(_LINUX_CAPABILITY_VERSION, &header->version))
-                    return -EFAULT; 
-             return -EINVAL;
-     }
-
-     if (get_user(pid, &header->pid))
-            return -EFAULT; 
-
-     if (pid && pid != current->pid && !capable(CAP_SETPCAP))
-             return -EPERM;
-
-     if (copy_from_user(&effective, &data->effective, sizeof(effective)) ||
-        copy_from_user(&inheritable, &data->inheritable, sizeof(inheritable)) ||
-        copy_from_user(&permitted, &data->permitted, sizeof(permitted)))
-            return -EFAULT; 
-
-     spin_lock(&task_capability_lock);
-     read_lock(&tasklist_lock);
-
-     if (pid > 0 && pid != current->pid) {
-          target = find_task_by_pid(pid);
-          if (!target) {
-               ret = -ESRCH;
-               goto out;
-          }
-     } else
-               target = current;
-
-     ret = 0;
-
-     /* having verified that the proposed changes are legal,
-           we now put them into effect. */
-     if (pid < 0) {
-             if (pid == -1)  /* all procs other than current and init */
-                     ret = cap_set_all(&effective, &inheritable, &permitted);
-
-             else            /* all procs in process group */
-                     ret = cap_set_pg(-pid, &effective, &inheritable,
-                                                       &permitted);
-     } else {
-            ret = security_capset_check(target, &effective, &inheritable,
-                                                       &permitted);
-            if (!ret)
-                    security_capset_set(target, &effective, &inheritable,
-                                                       &permitted);
-     }
+       kernel_cap_t inheritable, permitted, effective;
+       __u32 version;
+       struct task_struct *target;
+       int ret;
+       pid_t pid;
+
+       if (get_user(version, &header->version))
+               return -EFAULT;
+
+       if (version != _LINUX_CAPABILITY_VERSION) {
+               if (put_user(_LINUX_CAPABILITY_VERSION, &header->version))
+                       return -EFAULT;
+               return -EINVAL;
+       }
+
+       if (get_user(pid, &header->pid))
+               return -EFAULT;
+
+       if (pid && pid != task_pid_vnr(current) && !capable(CAP_SETPCAP))
+               return -EPERM;
+
+       if (copy_from_user(&effective, &data->effective, sizeof(effective)) ||
+           copy_from_user(&inheritable, &data->inheritable, sizeof(inheritable)) ||
+           copy_from_user(&permitted, &data->permitted, sizeof(permitted)))
+               return -EFAULT;
+
+       spin_lock(&task_capability_lock);
+       read_lock(&tasklist_lock);
+
+       if (pid > 0 && pid != task_pid_vnr(current)) {
+               target = find_task_by_vpid(pid);
+               if (!target) {
+                       ret = -ESRCH;
+                       goto out;
+               }
+       } else
+               target = current;
+
+       ret = 0;
+
+       /* having verified that the proposed changes are legal,
+          we now put them into effect. */
+       if (pid < 0) {
+               if (pid == -1)  /* all procs other than current and init */
+                       ret = cap_set_all(&effective, &inheritable, &permitted);
+
+               else            /* all procs in process group */
+                       ret = cap_set_pg(-pid, &effective, &inheritable,
+                                        &permitted);
+       } else {
+               ret = security_capset_check(target, &effective, &inheritable,
+                                           &permitted);
+               if (!ret)
+                       security_capset_set(target, &effective, &inheritable,
+                                           &permitted);
+       }
 
 out:
-     read_unlock(&tasklist_lock);
-     spin_unlock(&task_capability_lock);
+       read_unlock(&tasklist_lock);
+       spin_unlock(&task_capability_lock);
 
-     return ret;
+       return ret;
 }
 
 int __capable(struct task_struct *t, int cap)
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
new file mode 100644 (file)
index 0000000..5987dcc
--- /dev/null
@@ -0,0 +1,2805 @@
+/*
+ *  kernel/cgroup.c
+ *
+ *  Generic process-grouping system.
+ *
+ *  Based originally on the cpuset system, extracted by Paul Menage
+ *  Copyright (C) 2006 Google, Inc
+ *
+ *  Copyright notices from the original cpuset code:
+ *  --------------------------------------------------
+ *  Copyright (C) 2003 BULL SA.
+ *  Copyright (C) 2004-2006 Silicon Graphics, Inc.
+ *
+ *  Portions derived from Patrick Mochel's sysfs code.
+ *  sysfs is Copyright (c) 2001-3 Patrick Mochel
+ *
+ *  2003-10-10 Written by Simon Derr.
+ *  2003-10-22 Updates by Stephen Hemminger.
+ *  2004 May-July Rework by Paul Jackson.
+ *  ---------------------------------------------------
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of the Linux
+ *  distribution for more details.
+ */
+
+#include <linux/cgroup.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/mutex.h>
+#include <linux/mount.h>
+#include <linux/pagemap.h>
+#include <linux/proc_fs.h>
+#include <linux/rcupdate.h>
+#include <linux/sched.h>
+#include <linux/backing-dev.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+#include <linux/magic.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/sort.h>
+#include <linux/kmod.h>
+#include <linux/delayacct.h>
+#include <linux/cgroupstats.h>
+
+#include <asm/atomic.h>
+
+static DEFINE_MUTEX(cgroup_mutex);
+
+/* Generate an array of cgroup subsystem pointers */
+#define SUBSYS(_x) &_x ## _subsys,
+
+static struct cgroup_subsys *subsys[] = {
+#include <linux/cgroup_subsys.h>
+};
+
+/*
+ * A cgroupfs_root represents the root of a cgroup hierarchy,
+ * and may be associated with a superblock to form an active
+ * hierarchy
+ */
+struct cgroupfs_root {
+       struct super_block *sb;
+
+       /*
+        * The bitmask of subsystems intended to be attached to this
+        * hierarchy
+        */
+       unsigned long subsys_bits;
+
+       /* The bitmask of subsystems currently attached to this hierarchy */
+       unsigned long actual_subsys_bits;
+
+       /* A list running through the attached subsystems */
+       struct list_head subsys_list;
+
+       /* The root cgroup for this hierarchy */
+       struct cgroup top_cgroup;
+
+       /* Tracks how many cgroups are currently defined in hierarchy.*/
+       int number_of_cgroups;
+
+       /* A list running through the mounted hierarchies */
+       struct list_head root_list;
+
+       /* Hierarchy-specific flags */
+       unsigned long flags;
+
+       /* The path to use for release notifications. No locking
+        * between setting and use - so if userspace updates this
+        * while child cgroups exist, you could miss a
+        * notification. We ensure that it's always a valid
+        * NUL-terminated string */
+       char release_agent_path[PATH_MAX];
+};
+
+
+/*
+ * The "rootnode" hierarchy is the "dummy hierarchy", reserved for the
+ * subsystems that are otherwise unattached - it never has more than a
+ * single cgroup, and all tasks are part of that cgroup.
+ */
+static struct cgroupfs_root rootnode;
+
+/* The list of hierarchy roots */
+
+static LIST_HEAD(roots);
+static int root_count;
+
+/* dummytop is a shorthand for the dummy hierarchy's top cgroup */
+#define dummytop (&rootnode.top_cgroup)
+
+/* This flag indicates whether tasks in the fork and exit paths should
+ * take callback_mutex and check for fork/exit handlers to call. This
+ * avoids us having to do extra work in the fork/exit path if none of the
+ * subsystems need to be called.
+ */
+static int need_forkexit_callback;
+
+/* bits in struct cgroup flags field */
+enum {
+       /* Control Group is dead */
+       CGRP_REMOVED,
+       /* Control Group has previously had a child cgroup or a task,
+        * but no longer (only if CGRP_NOTIFY_ON_RELEASE is set) */
+       CGRP_RELEASABLE,
+       /* Control Group requires release notifications to userspace */
+       CGRP_NOTIFY_ON_RELEASE,
+};
+
+/* convenient tests for these bits */
+inline int cgroup_is_removed(const struct cgroup *cgrp)
+{
+       return test_bit(CGRP_REMOVED, &cgrp->flags);
+}
+
+/* bits in struct cgroupfs_root flags field */
+enum {
+       ROOT_NOPREFIX, /* mounted subsystems have no named prefix */
+};
+
+inline int cgroup_is_releasable(const struct cgroup *cgrp)
+{
+       const int bits =
+               (1 << CGRP_RELEASABLE) |
+               (1 << CGRP_NOTIFY_ON_RELEASE);
+       return (cgrp->flags & bits) == bits;
+}
+
+inline int notify_on_release(const struct cgroup *cgrp)
+{
+       return test_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags);
+}
+
+/*
+ * for_each_subsys() allows you to iterate on each subsystem attached to
+ * an active hierarchy
+ */
+#define for_each_subsys(_root, _ss) \
+list_for_each_entry(_ss, &_root->subsys_list, sibling)
+
+/* for_each_root() allows you to iterate across the active hierarchies */
+#define for_each_root(_root) \
+list_for_each_entry(_root, &roots, root_list)
+
+/* the list of cgroups eligible for automatic release. Protected by
+ * release_list_lock */
+static LIST_HEAD(release_list);
+static DEFINE_SPINLOCK(release_list_lock);
+static void cgroup_release_agent(struct work_struct *work);
+static DECLARE_WORK(release_agent_work, cgroup_release_agent);
+static void check_for_release(struct cgroup *cgrp);
+
+/* Link structure for associating css_set objects with cgroups */
+struct cg_cgroup_link {
+       /*
+        * List running through cg_cgroup_links associated with a
+        * cgroup, anchored on cgroup->css_sets
+        */
+       struct list_head cgrp_link_list;
+       /*
+        * List running through cg_cgroup_links pointing at a
+        * single css_set object, anchored on css_set->cg_links
+        */
+       struct list_head cg_link_list;
+       struct css_set *cg;
+};
+
+/* The default css_set - used by init and its children prior to any
+ * hierarchies being mounted. It contains a pointer to the root state
+ * for each subsystem. Also used to anchor the list of css_sets. Not
+ * reference-counted, to improve performance when child cgroups
+ * haven't been created.
+ */
+
+static struct css_set init_css_set;
+static struct cg_cgroup_link init_css_set_link;
+
+/* css_set_lock protects the list of css_set objects, and the
+ * chain of tasks off each css_set.  Nests outside task->alloc_lock
+ * due to cgroup_iter_start() */
+static DEFINE_RWLOCK(css_set_lock);
+static int css_set_count;
+
+/* We don't maintain the lists running through each css_set to its
+ * task until after the first call to cgroup_iter_start(). This
+ * reduces the fork()/exit() overhead for people who have cgroups
+ * compiled into their kernel but not actually in use */
+static int use_task_css_set_links;
+
+/* When we create or destroy a css_set, the operation simply
+ * takes/releases a reference count on all the cgroups referenced
+ * by subsystems in this css_set. This can end up multiple-counting
+ * some cgroups, but that's OK - the ref-count is just a
+ * busy/not-busy indicator; ensuring that we only count each cgroup
+ * once would require taking a global lock to ensure that no
+ * subsystems moved between hierarchies while we were doing so.
+ *
+ * Possible TODO: decide at boot time based on the number of
+ * registered subsystems and the number of CPUs or NUMA nodes whether
+ * it's better for performance to ref-count every subsystem, or to
+ * take a global lock and only add one ref count to each hierarchy.
+ */
+
+/*
+ * unlink a css_set from the list and free it
+ */
+static void unlink_css_set(struct css_set *cg)
+{
+       write_lock(&css_set_lock);
+       list_del(&cg->list);
+       css_set_count--;
+       while (!list_empty(&cg->cg_links)) {
+               struct cg_cgroup_link *link;
+               link = list_entry(cg->cg_links.next,
+                                 struct cg_cgroup_link, cg_link_list);
+               list_del(&link->cg_link_list);
+               list_del(&link->cgrp_link_list);
+               kfree(link);
+       }
+       write_unlock(&css_set_lock);
+}
+
+static void __release_css_set(struct kref *k, int taskexit)
+{
+       int i;
+       struct css_set *cg = container_of(k, struct css_set, ref);
+
+       unlink_css_set(cg);
+
+       rcu_read_lock();
+       for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+               struct cgroup *cgrp = cg->subsys[i]->cgroup;
+               if (atomic_dec_and_test(&cgrp->count) &&
+                   notify_on_release(cgrp)) {
+                       if (taskexit)
+                               set_bit(CGRP_RELEASABLE, &cgrp->flags);
+                       check_for_release(cgrp);
+               }
+       }
+       rcu_read_unlock();
+       kfree(cg);
+}
+
+static void release_css_set(struct kref *k)
+{
+       __release_css_set(k, 0);
+}
+
+static void release_css_set_taskexit(struct kref *k)
+{
+       __release_css_set(k, 1);
+}
+
+/*
+ * refcounted get/put for css_set objects
+ */
+static inline void get_css_set(struct css_set *cg)
+{
+       kref_get(&cg->ref);
+}
+
+static inline void put_css_set(struct css_set *cg)
+{
+       kref_put(&cg->ref, release_css_set);
+}
+
+static inline void put_css_set_taskexit(struct css_set *cg)
+{
+       kref_put(&cg->ref, release_css_set_taskexit);
+}
+
+/*
+ * find_existing_css_set() is a helper for
+ * find_css_set(), and checks to see whether an existing
+ * css_set is suitable. This currently walks a linked-list for
+ * simplicity; a later patch will use a hash table for better
+ * performance
+ *
+ * oldcg: the cgroup group that we're using before the cgroup
+ * transition
+ *
+ * cgrp: the cgroup that we're moving into
+ *
+ * template: location in which to build the desired set of subsystem
+ * state objects for the new cgroup group
+ */
+
+static struct css_set *find_existing_css_set(
+       struct css_set *oldcg,
+       struct cgroup *cgrp,
+       struct cgroup_subsys_state *template[])
+{
+       int i;
+       struct cgroupfs_root *root = cgrp->root;
+       struct list_head *l = &init_css_set.list;
+
+       /* Built the set of subsystem state objects that we want to
+        * see in the new css_set */
+       for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+               if (root->subsys_bits & (1ull << i)) {
+                       /* Subsystem is in this hierarchy. So we want
+                        * the subsystem state from the new
+                        * cgroup */
+                       template[i] = cgrp->subsys[i];
+               } else {
+                       /* Subsystem is not in this hierarchy, so we
+                        * don't want to change the subsystem state */
+                       template[i] = oldcg->subsys[i];
+               }
+       }
+
+       /* Look through existing cgroup groups to find one to reuse */
+       do {
+               struct css_set *cg =
+                       list_entry(l, struct css_set, list);
+
+               if (!memcmp(template, cg->subsys, sizeof(cg->subsys))) {
+                       /* All subsystems matched */
+                       return cg;
+               }
+               /* Try the next cgroup group */
+               l = l->next;
+       } while (l != &init_css_set.list);
+
+       /* No existing cgroup group matched */
+       return NULL;
+}
+
+/*
+ * allocate_cg_links() allocates "count" cg_cgroup_link structures
+ * and chains them on tmp through their cgrp_link_list fields. Returns 0 on
+ * success or a negative error
+ */
+
+static int allocate_cg_links(int count, struct list_head *tmp)
+{
+       struct cg_cgroup_link *link;
+       int i;
+       INIT_LIST_HEAD(tmp);
+       for (i = 0; i < count; i++) {
+               link = kmalloc(sizeof(*link), GFP_KERNEL);
+               if (!link) {
+                       while (!list_empty(tmp)) {
+                               link = list_entry(tmp->next,
+                                                 struct cg_cgroup_link,
+                                                 cgrp_link_list);
+                               list_del(&link->cgrp_link_list);
+                               kfree(link);
+                       }
+                       return -ENOMEM;
+               }
+               list_add(&link->cgrp_link_list, tmp);
+       }
+       return 0;
+}
+
+static void free_cg_links(struct list_head *tmp)
+{
+       while (!list_empty(tmp)) {
+               struct cg_cgroup_link *link;
+               link = list_entry(tmp->next,
+                                 struct cg_cgroup_link,
+                                 cgrp_link_list);
+               list_del(&link->cgrp_link_list);
+               kfree(link);
+       }
+}
+
+/*
+ * find_css_set() takes an existing cgroup group and a
+ * cgroup object, and returns a css_set object that's
+ * equivalent to the old group, but with the given cgroup
+ * substituted into the appropriate hierarchy. Must be called with
+ * cgroup_mutex held
+ */
+
+static struct css_set *find_css_set(
+       struct css_set *oldcg, struct cgroup *cgrp)
+{
+       struct css_set *res;
+       struct cgroup_subsys_state *template[CGROUP_SUBSYS_COUNT];
+       int i;
+
+       struct list_head tmp_cg_links;
+       struct cg_cgroup_link *link;
+
+       /* First see if we already have a cgroup group that matches
+        * the desired set */
+       write_lock(&css_set_lock);
+       res = find_existing_css_set(oldcg, cgrp, template);
+       if (res)
+               get_css_set(res);
+       write_unlock(&css_set_lock);
+
+       if (res)
+               return res;
+
+       res = kmalloc(sizeof(*res), GFP_KERNEL);
+       if (!res)
+               return NULL;
+
+       /* Allocate all the cg_cgroup_link objects that we'll need */
+       if (allocate_cg_links(root_count, &tmp_cg_links) < 0) {
+               kfree(res);
+               return NULL;
+       }
+
+       kref_init(&res->ref);
+       INIT_LIST_HEAD(&res->cg_links);
+       INIT_LIST_HEAD(&res->tasks);
+
+       /* Copy the set of subsystem state objects generated in
+        * find_existing_css_set() */
+       memcpy(res->subsys, template, sizeof(res->subsys));
+
+       write_lock(&css_set_lock);
+       /* Add reference counts and links from the new css_set. */
+       for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+               struct cgroup *cgrp = res->subsys[i]->cgroup;
+               struct cgroup_subsys *ss = subsys[i];
+               atomic_inc(&cgrp->count);
+               /*
+                * We want to add a link once per cgroup, so we
+                * only do it for the first subsystem in each
+                * hierarchy
+                */
+               if (ss->root->subsys_list.next == &ss->sibling) {
+                       BUG_ON(list_empty(&tmp_cg_links));
+                       link = list_entry(tmp_cg_links.next,
+                                         struct cg_cgroup_link,
+                                         cgrp_link_list);
+                       list_del(&link->cgrp_link_list);
+                       list_add(&link->cgrp_link_list, &cgrp->css_sets);
+                       link->cg = res;
+                       list_add(&link->cg_link_list, &res->cg_links);
+               }
+       }
+       if (list_empty(&rootnode.subsys_list)) {
+               link = list_entry(tmp_cg_links.next,
+                                 struct cg_cgroup_link,
+                                 cgrp_link_list);
+               list_del(&link->cgrp_link_list);
+               list_add(&link->cgrp_link_list, &dummytop->css_sets);
+               link->cg = res;
+               list_add(&link->cg_link_list, &res->cg_links);
+       }
+
+       BUG_ON(!list_empty(&tmp_cg_links));
+
+       /* Link this cgroup group into the list */
+       list_add(&res->list, &init_css_set.list);
+       css_set_count++;
+       INIT_LIST_HEAD(&res->tasks);
+       write_unlock(&css_set_lock);
+
+       return res;
+}
+
+/*
+ * There is one global cgroup mutex. We also require taking
+ * task_lock() when dereferencing a task's cgroup subsys pointers.
+ * See "The task_lock() exception", at the end of this comment.
+ *
+ * A task must hold cgroup_mutex to modify cgroups.
+ *
+ * Any task can increment and decrement the count field without lock.
+ * So in general, code holding cgroup_mutex can't rely on the count
+ * field not changing.  However, if the count goes to zero, then only
+ * attach_task() can increment it again.  Because a count of zero
+ * means that no tasks are currently attached, therefore there is no
+ * way a task attached to that cgroup can fork (the other way to
+ * increment the count).  So code holding cgroup_mutex can safely
+ * assume that if the count is zero, it will stay zero. Similarly, if
+ * a task holds cgroup_mutex on a cgroup with zero count, it
+ * knows that the cgroup won't be removed, as cgroup_rmdir()
+ * needs that mutex.
+ *
+ * The cgroup_common_file_write handler for operations that modify
+ * the cgroup hierarchy holds cgroup_mutex across the entire operation,
+ * single threading all such cgroup modifications across the system.
+ *
+ * The fork and exit callbacks cgroup_fork() and cgroup_exit(), don't
+ * (usually) take cgroup_mutex.  These are the two most performance
+ * critical pieces of code here.  The exception occurs on cgroup_exit(),
+ * when a task in a notify_on_release cgroup exits.  Then cgroup_mutex
+ * is taken, and if the cgroup count is zero, a usermode call made
+ * to /sbin/cgroup_release_agent with the name of the cgroup (path
+ * relative to the root of cgroup file system) as the argument.
+ *
+ * A cgroup can only be deleted if both its 'count' of using tasks
+ * is zero, and its list of 'children' cgroups is empty.  Since all
+ * tasks in the system use _some_ cgroup, and since there is always at
+ * least one task in the system (init, pid == 1), therefore, top_cgroup
+ * always has either children cgroups and/or using tasks.  So we don't
+ * need a special hack to ensure that top_cgroup cannot be deleted.
+ *
+ *     The task_lock() exception
+ *
+ * The need for this exception arises from the action of
+ * attach_task(), which overwrites one tasks cgroup pointer with
+ * another.  It does so using cgroup_mutexe, however there are
+ * several performance critical places that need to reference
+ * task->cgroup without the expense of grabbing a system global
+ * mutex.  Therefore except as noted below, when dereferencing or, as
+ * in attach_task(), modifying a task'ss cgroup pointer we use
+ * task_lock(), which acts on a spinlock (task->alloc_lock) already in
+ * the task_struct routinely used for such matters.
+ *
+ * P.S.  One more locking exception.  RCU is used to guard the
+ * update of a tasks cgroup pointer by attach_task()
+ */
+
+/**
+ * cgroup_lock - lock out any changes to cgroup structures
+ *
+ */
+
+void cgroup_lock(void)
+{
+       mutex_lock(&cgroup_mutex);
+}
+
+/**
+ * cgroup_unlock - release lock on cgroup changes
+ *
+ * Undo the lock taken in a previous cgroup_lock() call.
+ */
+
+void cgroup_unlock(void)
+{
+       mutex_unlock(&cgroup_mutex);
+}
+
+/*
+ * A couple of forward declarations required, due to cyclic reference loop:
+ * cgroup_mkdir -> cgroup_create -> cgroup_populate_dir ->
+ * cgroup_add_file -> cgroup_create_file -> cgroup_dir_inode_operations
+ * -> cgroup_mkdir.
+ */
+
+static int cgroup_mkdir(struct inode *dir, struct dentry *dentry, int mode);
+static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry);
+static int cgroup_populate_dir(struct cgroup *cgrp);
+static struct inode_operations cgroup_dir_inode_operations;
+static struct file_operations proc_cgroupstats_operations;
+
+static struct backing_dev_info cgroup_backing_dev_info = {
+       .capabilities   = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
+};
+
+static struct inode *cgroup_new_inode(mode_t mode, struct super_block *sb)
+{
+       struct inode *inode = new_inode(sb);
+
+       if (inode) {
+               inode->i_mode = mode;
+               inode->i_uid = current->fsuid;
+               inode->i_gid = current->fsgid;
+               inode->i_blocks = 0;
+               inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+               inode->i_mapping->backing_dev_info = &cgroup_backing_dev_info;
+       }
+       return inode;
+}
+
+static void cgroup_diput(struct dentry *dentry, struct inode *inode)
+{
+       /* is dentry a directory ? if so, kfree() associated cgroup */
+       if (S_ISDIR(inode->i_mode)) {
+               struct cgroup *cgrp = dentry->d_fsdata;
+               BUG_ON(!(cgroup_is_removed(cgrp)));
+               /* It's possible for external users to be holding css
+                * reference counts on a cgroup; css_put() needs to
+                * be able to access the cgroup after decrementing
+                * the reference count in order to know if it needs to
+                * queue the cgroup to be handled by the release
+                * agent */
+               synchronize_rcu();
+               kfree(cgrp);
+       }
+       iput(inode);
+}
+
+static void remove_dir(struct dentry *d)
+{
+       struct dentry *parent = dget(d->d_parent);
+
+       d_delete(d);
+       simple_rmdir(parent->d_inode, d);
+       dput(parent);
+}
+
+static void cgroup_clear_directory(struct dentry *dentry)
+{
+       struct list_head *node;
+
+       BUG_ON(!mutex_is_locked(&dentry->d_inode->i_mutex));
+       spin_lock(&dcache_lock);
+       node = dentry->d_subdirs.next;
+       while (node != &dentry->d_subdirs) {
+               struct dentry *d = list_entry(node, struct dentry, d_u.d_child);
+               list_del_init(node);
+               if (d->d_inode) {
+                       /* This should never be called on a cgroup
+                        * directory with child cgroups */
+                       BUG_ON(d->d_inode->i_mode & S_IFDIR);
+                       d = dget_locked(d);
+                       spin_unlock(&dcache_lock);
+                       d_delete(d);
+                       simple_unlink(dentry->d_inode, d);
+                       dput(d);
+                       spin_lock(&dcache_lock);
+               }
+               node = dentry->d_subdirs.next;
+       }
+       spin_unlock(&dcache_lock);
+}
+
+/*
+ * NOTE : the dentry must have been dget()'ed
+ */
+static void cgroup_d_remove_dir(struct dentry *dentry)
+{
+       cgroup_clear_directory(dentry);
+
+       spin_lock(&dcache_lock);
+       list_del_init(&dentry->d_u.d_child);
+       spin_unlock(&dcache_lock);
+       remove_dir(dentry);
+}
+
+static int rebind_subsystems(struct cgroupfs_root *root,
+                             unsigned long final_bits)
+{
+       unsigned long added_bits, removed_bits;
+       struct cgroup *cgrp = &root->top_cgroup;
+       int i;
+
+       removed_bits = root->actual_subsys_bits & ~final_bits;
+       added_bits = final_bits & ~root->actual_subsys_bits;
+       /* Check that any added subsystems are currently free */
+       for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+               unsigned long long bit = 1ull << i;
+               struct cgroup_subsys *ss = subsys[i];
+               if (!(bit & added_bits))
+                       continue;
+               if (ss->root != &rootnode) {
+                       /* Subsystem isn't free */
+                       return -EBUSY;
+               }
+       }
+
+       /* Currently we don't handle adding/removing subsystems when
+        * any child cgroups exist. This is theoretically supportable
+        * but involves complex error handling, so it's being left until
+        * later */
+       if (!list_empty(&cgrp->children))
+               return -EBUSY;
+
+       /* Process each subsystem */
+       for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+               struct cgroup_subsys *ss = subsys[i];
+               unsigned long bit = 1UL << i;
+               if (bit & added_bits) {
+                       /* We're binding this subsystem to this hierarchy */
+                       BUG_ON(cgrp->subsys[i]);
+                       BUG_ON(!dummytop->subsys[i]);
+                       BUG_ON(dummytop->subsys[i]->cgroup != dummytop);
+                       cgrp->subsys[i] = dummytop->subsys[i];
+                       cgrp->subsys[i]->cgroup = cgrp;
+                       list_add(&ss->sibling, &root->subsys_list);
+                       rcu_assign_pointer(ss->root, root);
+                       if (ss->bind)
+                               ss->bind(ss, cgrp);
+
+               } else if (bit & removed_bits) {
+                       /* We're removing this subsystem */
+                       BUG_ON(cgrp->subsys[i] != dummytop->subsys[i]);
+                       BUG_ON(cgrp->subsys[i]->cgroup != cgrp);
+                       if (ss->bind)
+                               ss->bind(ss, dummytop);
+                       dummytop->subsys[i]->cgroup = dummytop;
+                       cgrp->subsys[i] = NULL;
+                       rcu_assign_pointer(subsys[i]->root, &rootnode);
+                       list_del(&ss->sibling);
+               } else if (bit & final_bits) {
+                       /* Subsystem state should already exist */
+                       BUG_ON(!cgrp->subsys[i]);
+               } else {
+                       /* Subsystem state shouldn't exist */
+                       BUG_ON(cgrp->subsys[i]);
+               }
+       }
+       root->subsys_bits = root->actual_subsys_bits = final_bits;
+       synchronize_rcu();
+
+       return 0;
+}
+
+static int cgroup_show_options(struct seq_file *seq, struct vfsmount *vfs)
+{
+       struct cgroupfs_root *root = vfs->mnt_sb->s_fs_info;
+       struct cgroup_subsys *ss;
+
+       mutex_lock(&cgroup_mutex);
+       for_each_subsys(root, ss)
+               seq_printf(seq, ",%s", ss->name);
+       if (test_bit(ROOT_NOPREFIX, &root->flags))
+               seq_puts(seq, ",noprefix");
+       if (strlen(root->release_agent_path))
+               seq_printf(seq, ",release_agent=%s", root->release_agent_path);
+       mutex_unlock(&cgroup_mutex);
+       return 0;
+}
+
+struct cgroup_sb_opts {
+       unsigned long subsys_bits;
+       unsigned long flags;
+       char *release_agent;
+};
+
+/* Convert a hierarchy specifier into a bitmask of subsystems and
+ * flags. */
+static int parse_cgroupfs_options(char *data,
+                                    struct cgroup_sb_opts *opts)
+{
+       char *token, *o = data ?: "all";
+
+       opts->subsys_bits = 0;
+       opts->flags = 0;
+       opts->release_agent = NULL;
+
+       while ((token = strsep(&o, ",")) != NULL) {
+               if (!*token)
+                       return -EINVAL;
+               if (!strcmp(token, "all")) {
+                       opts->subsys_bits = (1 << CGROUP_SUBSYS_COUNT) - 1;
+               } else if (!strcmp(token, "noprefix")) {
+                       set_bit(ROOT_NOPREFIX, &opts->flags);
+               } else if (!strncmp(token, "release_agent=", 14)) {
+                       /* Specifying two release agents is forbidden */
+                       if (opts->release_agent)
+                               return -EINVAL;
+                       opts->release_agent = kzalloc(PATH_MAX, GFP_KERNEL);
+                       if (!opts->release_agent)
+                               return -ENOMEM;
+                       strncpy(opts->release_agent, token + 14, PATH_MAX - 1);
+                       opts->release_agent[PATH_MAX - 1] = 0;
+               } else {
+                       struct cgroup_subsys *ss;
+                       int i;
+                       for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+                               ss = subsys[i];
+                               if (!strcmp(token, ss->name)) {
+                                       set_bit(i, &opts->subsys_bits);
+                                       break;
+                               }
+                       }
+                       if (i == CGROUP_SUBSYS_COUNT)
+                               return -ENOENT;
+               }
+       }
+
+       /* We can't have an empty hierarchy */
+       if (!opts->subsys_bits)
+               return -EINVAL;
+
+       return 0;
+}
+
+static int cgroup_remount(struct super_block *sb, int *flags, char *data)
+{
+       int ret = 0;
+       struct cgroupfs_root *root = sb->s_fs_info;
+       struct cgroup *cgrp = &root->top_cgroup;
+       struct cgroup_sb_opts opts;
+
+       mutex_lock(&cgrp->dentry->d_inode->i_mutex);
+       mutex_lock(&cgroup_mutex);
+
+       /* See what subsystems are wanted */
+       ret = parse_cgroupfs_options(data, &opts);
+       if (ret)
+               goto out_unlock;
+
+       /* Don't allow flags to change at remount */
+       if (opts.flags != root->flags) {
+               ret = -EINVAL;
+               goto out_unlock;
+       }
+
+       ret = rebind_subsystems(root, opts.subsys_bits);
+
+       /* (re)populate subsystem files */
+       if (!ret)
+               cgroup_populate_dir(cgrp);
+
+       if (opts.release_agent)
+               strcpy(root->release_agent_path, opts.release_agent);
+ out_unlock:
+       if (opts.release_agent)
+               kfree(opts.release_agent);
+       mutex_unlock(&cgroup_mutex);
+       mutex_unlock(&cgrp->dentry->d_inode->i_mutex);
+       return ret;
+}
+
+static struct super_operations cgroup_ops = {
+       .statfs = simple_statfs,
+       .drop_inode = generic_delete_inode,
+       .show_options = cgroup_show_options,
+       .remount_fs = cgroup_remount,
+};
+
+static void init_cgroup_root(struct cgroupfs_root *root)
+{
+       struct cgroup *cgrp = &root->top_cgroup;
+       INIT_LIST_HEAD(&root->subsys_list);
+       INIT_LIST_HEAD(&root->root_list);
+       root->number_of_cgroups = 1;
+       cgrp->root = root;
+       cgrp->top_cgroup = cgrp;
+       INIT_LIST_HEAD(&cgrp->sibling);
+       INIT_LIST_HEAD(&cgrp->children);
+       INIT_LIST_HEAD(&cgrp->css_sets);
+       INIT_LIST_HEAD(&cgrp->release_list);
+}
+
+static int cgroup_test_super(struct super_block *sb, void *data)
+{
+       struct cgroupfs_root *new = data;
+       struct cgroupfs_root *root = sb->s_fs_info;
+
+       /* First check subsystems */
+       if (new->subsys_bits != root->subsys_bits)
+           return 0;
+
+       /* Next check flags */
+       if (new->flags != root->flags)
+               return 0;
+
+       return 1;
+}
+
+static int cgroup_set_super(struct super_block *sb, void *data)
+{
+       int ret;
+       struct cgroupfs_root *root = data;
+
+       ret = set_anon_super(sb, NULL);
+       if (ret)
+               return ret;
+
+       sb->s_fs_info = root;
+       root->sb = sb;
+
+       sb->s_blocksize = PAGE_CACHE_SIZE;
+       sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
+       sb->s_magic = CGROUP_SUPER_MAGIC;
+       sb->s_op = &cgroup_ops;
+
+       return 0;
+}
+
+static int cgroup_get_rootdir(struct super_block *sb)
+{
+       struct inode *inode =
+               cgroup_new_inode(S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR, sb);
+       struct dentry *dentry;
+
+       if (!inode)
+               return -ENOMEM;
+
+       inode->i_op = &simple_dir_inode_operations;
+       inode->i_fop = &simple_dir_operations;
+       inode->i_op = &cgroup_dir_inode_operations;
+       /* directories start off with i_nlink == 2 (for "." entry) */
+       inc_nlink(inode);
+       dentry = d_alloc_root(inode);
+       if (!dentry) {
+               iput(inode);
+               return -ENOMEM;
+       }
+       sb->s_root = dentry;
+       return 0;
+}
+
+static int cgroup_get_sb(struct file_system_type *fs_type,
+                        int flags, const char *unused_dev_name,
+                        void *data, struct vfsmount *mnt)
+{
+       struct cgroup_sb_opts opts;
+       int ret = 0;
+       struct super_block *sb;
+       struct cgroupfs_root *root;
+       struct list_head tmp_cg_links, *l;
+       INIT_LIST_HEAD(&tmp_cg_links);
+
+       /* First find the desired set of subsystems */
+       ret = parse_cgroupfs_options(data, &opts);
+       if (ret) {
+               if (opts.release_agent)
+                       kfree(opts.release_agent);
+               return ret;
+       }
+
+       root = kzalloc(sizeof(*root), GFP_KERNEL);
+       if (!root)
+               return -ENOMEM;
+
+       init_cgroup_root(root);
+       root->subsys_bits = opts.subsys_bits;
+       root->flags = opts.flags;
+       if (opts.release_agent) {
+               strcpy(root->release_agent_path, opts.release_agent);
+               kfree(opts.release_agent);
+       }
+
+       sb = sget(fs_type, cgroup_test_super, cgroup_set_super, root);
+
+       if (IS_ERR(sb)) {
+               kfree(root);
+               return PTR_ERR(sb);
+       }
+
+       if (sb->s_fs_info != root) {
+               /* Reusing an existing superblock */
+               BUG_ON(sb->s_root == NULL);
+               kfree(root);
+               root = NULL;
+       } else {
+               /* New superblock */
+               struct cgroup *cgrp = &root->top_cgroup;
+               struct inode *inode;
+
+               BUG_ON(sb->s_root != NULL);
+
+               ret = cgroup_get_rootdir(sb);
+               if (ret)
+                       goto drop_new_super;
+               inode = sb->s_root->d_inode;
+
+               mutex_lock(&inode->i_mutex);
+               mutex_lock(&cgroup_mutex);
+
+               /*
+                * We're accessing css_set_count without locking
+                * css_set_lock here, but that's OK - it can only be
+                * increased by someone holding cgroup_lock, and
+                * that's us. The worst that can happen is that we
+                * have some link structures left over
+                */
+               ret = allocate_cg_links(css_set_count, &tmp_cg_links);
+               if (ret) {
+                       mutex_unlock(&cgroup_mutex);
+                       mutex_unlock(&inode->i_mutex);
+                       goto drop_new_super;
+               }
+
+               ret = rebind_subsystems(root, root->subsys_bits);
+               if (ret == -EBUSY) {
+                       mutex_unlock(&cgroup_mutex);
+                       mutex_unlock(&inode->i_mutex);
+                       goto drop_new_super;
+               }
+
+               /* EBUSY should be the only error here */
+               BUG_ON(ret);
+
+               list_add(&root->root_list, &roots);
+               root_count++;
+
+               sb->s_root->d_fsdata = &root->top_cgroup;
+               root->top_cgroup.dentry = sb->s_root;
+
+               /* Link the top cgroup in this hierarchy into all
+                * the css_set objects */
+               write_lock(&css_set_lock);
+               l = &init_css_set.list;
+               do {
+                       struct css_set *cg;
+                       struct cg_cgroup_link *link;
+                       cg = list_entry(l, struct css_set, list);
+                       BUG_ON(list_empty(&tmp_cg_links));
+                       link = list_entry(tmp_cg_links.next,
+                                         struct cg_cgroup_link,
+                                         cgrp_link_list);
+                       list_del(&link->cgrp_link_list);
+                       link->cg = cg;
+                       list_add(&link->cgrp_link_list,
+                                &root->top_cgroup.css_sets);
+                       list_add(&link->cg_link_list, &cg->cg_links);
+                       l = l->next;
+               } while (l != &init_css_set.list);
+               write_unlock(&css_set_lock);
+
+               free_cg_links(&tmp_cg_links);
+
+               BUG_ON(!list_empty(&cgrp->sibling));
+               BUG_ON(!list_empty(&cgrp->children));
+               BUG_ON(root->number_of_cgroups != 1);
+
+               cgroup_populate_dir(cgrp);
+               mutex_unlock(&inode->i_mutex);
+               mutex_unlock(&cgroup_mutex);
+       }
+
+       return simple_set_mnt(mnt, sb);
+
+ drop_new_super:
+       up_write(&sb->s_umount);
+       deactivate_super(sb);
+       free_cg_links(&tmp_cg_links);
+       return ret;
+}
+
+static void cgroup_kill_sb(struct super_block *sb) {
+       struct cgroupfs_root *root = sb->s_fs_info;
+       struct cgroup *cgrp = &root->top_cgroup;
+       int ret;
+
+       BUG_ON(!root);
+
+       BUG_ON(root->number_of_cgroups != 1);
+       BUG_ON(!list_empty(&cgrp->children));
+       BUG_ON(!list_empty(&cgrp->sibling));
+
+       mutex_lock(&cgroup_mutex);
+
+       /* Rebind all subsystems back to the default hierarchy */
+       ret = rebind_subsystems(root, 0);
+       /* Shouldn't be able to fail ... */
+       BUG_ON(ret);
+
+       /*
+        * Release all the links from css_sets to this hierarchy's
+        * root cgroup
+        */
+       write_lock(&css_set_lock);
+       while (!list_empty(&cgrp->css_sets)) {
+               struct cg_cgroup_link *link;
+               link = list_entry(cgrp->css_sets.next,
+                                 struct cg_cgroup_link, cgrp_link_list);
+               list_del(&link->cg_link_list);
+               list_del(&link->cgrp_link_list);
+               kfree(link);
+       }
+       write_unlock(&css_set_lock);
+
+       if (!list_empty(&root->root_list)) {
+               list_del(&root->root_list);
+               root_count--;
+       }
+       mutex_unlock(&cgroup_mutex);
+
+       kfree(root);
+       kill_litter_super(sb);
+}
+
+static struct file_system_type cgroup_fs_type = {
+       .name = "cgroup",
+       .get_sb = cgroup_get_sb,
+       .kill_sb = cgroup_kill_sb,
+};
+
+static inline struct cgroup *__d_cgrp(struct dentry *dentry)
+{
+       return dentry->d_fsdata;
+}
+
+static inline struct cftype *__d_cft(struct dentry *dentry)
+{
+       return dentry->d_fsdata;
+}
+
+/*
+ * Called with cgroup_mutex held.  Writes path of cgroup into buf.
+ * Returns 0 on success, -errno on error.
+ */
+int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen)
+{
+       char *start;
+
+       if (cgrp == dummytop) {
+               /*
+                * Inactive subsystems have no dentry for their root
+                * cgroup
+                */
+               strcpy(buf, "/");
+               return 0;
+       }
+
+       start = buf + buflen;
+
+       *--start = '\0';
+       for (;;) {
+               int len = cgrp->dentry->d_name.len;
+               if ((start -= len) < buf)
+                       return -ENAMETOOLONG;
+               memcpy(start, cgrp->dentry->d_name.name, len);
+               cgrp = cgrp->parent;
+               if (!cgrp)
+                       break;
+               if (!cgrp->parent)
+                       continue;
+               if (--start < buf)
+                       return -ENAMETOOLONG;
+               *start = '/';
+       }
+       memmove(buf, start, buf + buflen - start);
+       return 0;
+}
+
+/*
+ * Return the first subsystem attached to a cgroup's hierarchy, and
+ * its subsystem id.
+ */
+
+static void get_first_subsys(const struct cgroup *cgrp,
+                       struct cgroup_subsys_state **css, int *subsys_id)
+{
+       const struct cgroupfs_root *root = cgrp->root;
+       const struct cgroup_subsys *test_ss;
+       BUG_ON(list_empty(&root->subsys_list));
+       test_ss = list_entry(root->subsys_list.next,
+                            struct cgroup_subsys, sibling);
+       if (css) {
+               *css = cgrp->subsys[test_ss->subsys_id];
+               BUG_ON(!*css);
+       }
+       if (subsys_id)
+               *subsys_id = test_ss->subsys_id;
+}
+
+/*
+ * Attach task 'tsk' to cgroup 'cgrp'
+ *
+ * Call holding cgroup_mutex.  May take task_lock of
+ * the task 'pid' during call.
+ */
+static int attach_task(struct cgroup *cgrp, struct task_struct *tsk)
+{
+       int retval = 0;
+       struct cgroup_subsys *ss;
+       struct cgroup *oldcgrp;
+       struct css_set *cg = tsk->cgroups;
+       struct css_set *newcg;
+       struct cgroupfs_root *root = cgrp->root;
+       int subsys_id;
+
+       get_first_subsys(cgrp, NULL, &subsys_id);
+
+       /* Nothing to do if the task is already in that cgroup */
+       oldcgrp = task_cgroup(tsk, subsys_id);
+       if (cgrp == oldcgrp)
+               return 0;
+
+       for_each_subsys(root, ss) {
+               if (ss->can_attach) {
+                       retval = ss->can_attach(ss, cgrp, tsk);
+                       if (retval) {
+                               return retval;
+                       }
+               }
+       }
+
+       /*
+        * Locate or allocate a new css_set for this task,
+        * based on its final set of cgroups
+        */
+       newcg = find_css_set(cg, cgrp);
+       if (!newcg) {
+               return -ENOMEM;
+       }
+
+       task_lock(tsk);
+       if (tsk->flags & PF_EXITING) {
+               task_unlock(tsk);
+               put_css_set(newcg);
+               return -ESRCH;
+       }
+       rcu_assign_pointer(tsk->cgroups, newcg);
+       task_unlock(tsk);
+
+       /* Update the css_set linked lists if we're using them */
+       write_lock(&css_set_lock);
+       if (!list_empty(&tsk->cg_list)) {
+               list_del(&tsk->cg_list);
+               list_add(&tsk->cg_list, &newcg->tasks);
+       }
+       write_unlock(&css_set_lock);
+
+       for_each_subsys(root, ss) {
+               if (ss->attach) {
+                       ss->attach(ss, cgrp, oldcgrp, tsk);
+               }
+       }
+       set_bit(CGRP_RELEASABLE, &oldcgrp->flags);
+       synchronize_rcu();
+       put_css_set(cg);
+       return 0;
+}
+
+/*
+ * Attach task with pid 'pid' to cgroup 'cgrp'. Call with
+ * cgroup_mutex, may take task_lock of task
+ */
+static int attach_task_by_pid(struct cgroup *cgrp, char *pidbuf)
+{
+       pid_t pid;
+       struct task_struct *tsk;
+       int ret;
+
+       if (sscanf(pidbuf, "%d", &pid) != 1)
+               return -EIO;
+
+       if (pid) {
+               rcu_read_lock();
+               tsk = find_task_by_pid(pid);
+               if (!tsk || tsk->flags & PF_EXITING) {
+                       rcu_read_unlock();
+                       return -ESRCH;
+               }
+               get_task_struct(tsk);
+               rcu_read_unlock();
+
+               if ((current->euid) && (current->euid != tsk->uid)
+                   && (current->euid != tsk->suid)) {
+                       put_task_struct(tsk);
+                       return -EACCES;
+               }
+       } else {
+               tsk = current;
+               get_task_struct(tsk);
+       }
+
+       ret = attach_task(cgrp, tsk);
+       put_task_struct(tsk);
+       return ret;
+}
+
+/* The various types of files and directories in a cgroup file system */
+
+enum cgroup_filetype {
+       FILE_ROOT,
+       FILE_DIR,
+       FILE_TASKLIST,
+       FILE_NOTIFY_ON_RELEASE,
+       FILE_RELEASABLE,
+       FILE_RELEASE_AGENT,
+};
+
+static ssize_t cgroup_write_uint(struct cgroup *cgrp, struct cftype *cft,
+                                struct file *file,
+                                const char __user *userbuf,
+                                size_t nbytes, loff_t *unused_ppos)
+{
+       char buffer[64];
+       int retval = 0;
+       u64 val;
+       char *end;
+
+       if (!nbytes)
+               return -EINVAL;
+       if (nbytes >= sizeof(buffer))
+               return -E2BIG;
+       if (copy_from_user(buffer, userbuf, nbytes))
+               return -EFAULT;
+
+       buffer[nbytes] = 0;     /* nul-terminate */
+
+       /* strip newline if necessary */
+       if (nbytes && (buffer[nbytes-1] == '\n'))
+               buffer[nbytes-1] = 0;
+       val = simple_strtoull(buffer, &end, 0);
+       if (*end)
+               return -EINVAL;
+
+       /* Pass to subsystem */
+       retval = cft->write_uint(cgrp, cft, val);
+       if (!retval)
+               retval = nbytes;
+       return retval;
+}
+
+static ssize_t cgroup_common_file_write(struct cgroup *cgrp,
+                                          struct cftype *cft,
+                                          struct file *file,
+                                          const char __user *userbuf,
+                                          size_t nbytes, loff_t *unused_ppos)
+{
+       enum cgroup_filetype type = cft->private;
+       char *buffer;
+       int retval = 0;
+
+       if (nbytes >= PATH_MAX)
+               return -E2BIG;
+
+       /* +1 for nul-terminator */
+       buffer = kmalloc(nbytes + 1, GFP_KERNEL);
+       if (buffer == NULL)
+               return -ENOMEM;
+
+       if (copy_from_user(buffer, userbuf, nbytes)) {
+               retval = -EFAULT;
+               goto out1;
+       }
+       buffer[nbytes] = 0;     /* nul-terminate */
+
+       mutex_lock(&cgroup_mutex);
+
+       if (cgroup_is_removed(cgrp)) {
+               retval = -ENODEV;
+               goto out2;
+       }
+
+       switch (type) {
+       case FILE_TASKLIST:
+               retval = attach_task_by_pid(cgrp, buffer);
+               break;
+       case FILE_NOTIFY_ON_RELEASE:
+               clear_bit(CGRP_RELEASABLE, &cgrp->flags);
+               if (simple_strtoul(buffer, NULL, 10) != 0)
+                       set_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags);
+               else
+                       clear_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags);
+               break;
+       case FILE_RELEASE_AGENT:
+       {
+               struct cgroupfs_root *root = cgrp->root;
+               /* Strip trailing newline */
+               if (nbytes && (buffer[nbytes-1] == '\n')) {
+                       buffer[nbytes-1] = 0;
+               }
+               if (nbytes < sizeof(root->release_agent_path)) {
+                       /* We never write anything other than '\0'
+                        * into the last char of release_agent_path,
+                        * so it always remains a NUL-terminated
+                        * string */
+                       strncpy(root->release_agent_path, buffer, nbytes);
+                       root->release_agent_path[nbytes] = 0;
+               } else {
+                       retval = -ENOSPC;
+               }
+               break;
+       }
+       default:
+               retval = -EINVAL;
+               goto out2;
+       }
+
+       if (retval == 0)
+               retval = nbytes;
+out2:
+       mutex_unlock(&cgroup_mutex);
+out1:
+       kfree(buffer);
+       return retval;
+}
+
+static ssize_t cgroup_file_write(struct file *file, const char __user *buf,
+                                               size_t nbytes, loff_t *ppos)
+{
+       struct cftype *cft = __d_cft(file->f_dentry);
+       struct cgroup *cgrp = __d_cgrp(file->f_dentry->d_parent);
+
+       if (!cft)
+               return -ENODEV;
+       if (cft->write)
+               return cft->write(cgrp, cft, file, buf, nbytes, ppos);
+       if (cft->write_uint)
+               return cgroup_write_uint(cgrp, cft, file, buf, nbytes, ppos);
+       return -EINVAL;
+}
+
+static ssize_t cgroup_read_uint(struct cgroup *cgrp, struct cftype *cft,
+                                  struct file *file,
+                                  char __user *buf, size_t nbytes,
+                                  loff_t *ppos)
+{
+       char tmp[64];
+       u64 val = cft->read_uint(cgrp, cft);
+       int len = sprintf(tmp, "%llu\n", (unsigned long long) val);
+
+       return simple_read_from_buffer(buf, nbytes, ppos, tmp, len);
+}
+
+static ssize_t cgroup_common_file_read(struct cgroup *cgrp,
+                                         struct cftype *cft,
+                                         struct file *file,
+                                         char __user *buf,
+                                         size_t nbytes, loff_t *ppos)
+{
+       enum cgroup_filetype type = cft->private;
+       char *page;
+       ssize_t retval = 0;
+       char *s;
+
+       if (!(page = (char *)__get_free_page(GFP_KERNEL)))
+               return -ENOMEM;
+
+       s = page;
+
+       switch (type) {
+       case FILE_RELEASE_AGENT:
+       {
+               struct cgroupfs_root *root;
+               size_t n;
+               mutex_lock(&cgroup_mutex);
+               root = cgrp->root;
+               n = strnlen(root->release_agent_path,
+                           sizeof(root->release_agent_path));
+               n = min(n, (size_t) PAGE_SIZE);
+               strncpy(s, root->release_agent_path, n);
+               mutex_unlock(&cgroup_mutex);
+               s += n;
+               break;
+       }
+       default:
+               retval = -EINVAL;
+               goto out;
+       }
+       *s++ = '\n';
+
+       retval = simple_read_from_buffer(buf, nbytes, ppos, page, s - page);
+out:
+       free_page((unsigned long)page);
+       return retval;
+}
+
+static ssize_t cgroup_file_read(struct file *file, char __user *buf,
+                                  size_t nbytes, loff_t *ppos)
+{
+       struct cftype *cft = __d_cft(file->f_dentry);
+       struct cgroup *cgrp = __d_cgrp(file->f_dentry->d_parent);
+
+       if (!cft)
+               return -ENODEV;
+
+       if (cft->read)
+               return cft->read(cgrp, cft, file, buf, nbytes, ppos);
+       if (cft->read_uint)
+               return cgroup_read_uint(cgrp, cft, file, buf, nbytes, ppos);
+       return -EINVAL;
+}
+
+static int cgroup_file_open(struct inode *inode, struct file *file)
+{
+       int err;
+       struct cftype *cft;
+
+       err = generic_file_open(inode, file);
+       if (err)
+               return err;
+
+       cft = __d_cft(file->f_dentry);
+       if (!cft)
+               return -ENODEV;
+       if (cft->open)
+               err = cft->open(inode, file);
+       else
+               err = 0;
+
+       return err;
+}
+
+static int cgroup_file_release(struct inode *inode, struct file *file)
+{
+       struct cftype *cft = __d_cft(file->f_dentry);
+       if (cft->release)
+               return cft->release(inode, file);
+       return 0;
+}
+
+/*
+ * cgroup_rename - Only allow simple rename of directories in place.
+ */
+static int cgroup_rename(struct inode *old_dir, struct dentry *old_dentry,
+                           struct inode *new_dir, struct dentry *new_dentry)
+{
+       if (!S_ISDIR(old_dentry->d_inode->i_mode))
+               return -ENOTDIR;
+       if (new_dentry->d_inode)
+               return -EEXIST;
+       if (old_dir != new_dir)
+               return -EIO;
+       return simple_rename(old_dir, old_dentry, new_dir, new_dentry);
+}
+
+static struct file_operations cgroup_file_operations = {
+       .read = cgroup_file_read,
+       .write = cgroup_file_write,
+       .llseek = generic_file_llseek,
+       .open = cgroup_file_open,
+       .release = cgroup_file_release,
+};
+
+static struct inode_operations cgroup_dir_inode_operations = {
+       .lookup = simple_lookup,
+       .mkdir = cgroup_mkdir,
+       .rmdir = cgroup_rmdir,
+       .rename = cgroup_rename,
+};
+
+static int cgroup_create_file(struct dentry *dentry, int mode,
+                               struct super_block *sb)
+{
+       static struct dentry_operations cgroup_dops = {
+               .d_iput = cgroup_diput,
+       };
+
+       struct inode *inode;
+
+       if (!dentry)
+               return -ENOENT;
+       if (dentry->d_inode)
+               return -EEXIST;
+
+       inode = cgroup_new_inode(mode, sb);
+       if (!inode)
+               return -ENOMEM;
+
+       if (S_ISDIR(mode)) {
+               inode->i_op = &cgroup_dir_inode_operations;
+               inode->i_fop = &simple_dir_operations;
+
+               /* start off with i_nlink == 2 (for "." entry) */
+               inc_nlink(inode);
+
+               /* start with the directory inode held, so that we can
+                * populate it without racing with another mkdir */
+               mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD);
+       } else if (S_ISREG(mode)) {
+               inode->i_size = 0;
+               inode->i_fop = &cgroup_file_operations;
+       }
+       dentry->d_op = &cgroup_dops;
+       d_instantiate(dentry, inode);
+       dget(dentry);   /* Extra count - pin the dentry in core */
+       return 0;
+}
+
+/*
+ *     cgroup_create_dir - create a directory for an object.
+ *     cgrp:   the cgroup we create the directory for.
+ *             It must have a valid ->parent field
+ *             And we are going to fill its ->dentry field.
+ *     dentry: dentry of the new cgroup
+ *     mode:   mode to set on new directory.
+ */
+static int cgroup_create_dir(struct cgroup *cgrp, struct dentry *dentry,
+                               int mode)
+{
+       struct dentry *parent;
+       int error = 0;
+
+       parent = cgrp->parent->dentry;
+       error = cgroup_create_file(dentry, S_IFDIR | mode, cgrp->root->sb);
+       if (!error) {
+               dentry->d_fsdata = cgrp;
+               inc_nlink(parent->d_inode);
+               cgrp->dentry = dentry;
+               dget(dentry);
+       }
+       dput(dentry);
+
+       return error;
+}
+
+int cgroup_add_file(struct cgroup *cgrp,
+                      struct cgroup_subsys *subsys,
+                      const struct cftype *cft)
+{
+       struct dentry *dir = cgrp->dentry;
+       struct dentry *dentry;
+       int error;
+
+       char name[MAX_CGROUP_TYPE_NAMELEN + MAX_CFTYPE_NAME + 2] = { 0 };
+       if (subsys && !test_bit(ROOT_NOPREFIX, &cgrp->root->flags)) {
+               strcpy(name, subsys->name);
+               strcat(name, ".");
+       }
+       strcat(name, cft->name);
+       BUG_ON(!mutex_is_locked(&dir->d_inode->i_mutex));
+       dentry = lookup_one_len(name, dir, strlen(name));
+       if (!IS_ERR(dentry)) {
+               error = cgroup_create_file(dentry, 0644 | S_IFREG,
+                                               cgrp->root->sb);
+               if (!error)
+                       dentry->d_fsdata = (void *)cft;
+               dput(dentry);
+       } else
+               error = PTR_ERR(dentry);
+       return error;
+}
+
+int cgroup_add_files(struct cgroup *cgrp,
+                       struct cgroup_subsys *subsys,
+                       const struct cftype cft[],
+                       int count)
+{
+       int i, err;
+       for (i = 0; i < count; i++) {
+               err = cgroup_add_file(cgrp, subsys, &cft[i]);
+               if (err)
+                       return err;
+       }
+       return 0;
+}
+
+/* Count the number of tasks in a cgroup. */
+
+int cgroup_task_count(const struct cgroup *cgrp)
+{
+       int count = 0;
+       struct list_head *l;
+
+       read_lock(&css_set_lock);
+       l = cgrp->css_sets.next;
+       while (l != &cgrp->css_sets) {
+               struct cg_cgroup_link *link =
+                       list_entry(l, struct cg_cgroup_link, cgrp_link_list);
+               count += atomic_read(&link->cg->ref.refcount);
+               l = l->next;
+       }
+       read_unlock(&css_set_lock);
+       return count;
+}
+
+/*
+ * Advance a list_head iterator.  The iterator should be positioned at
+ * the start of a css_set
+ */
+static void cgroup_advance_iter(struct cgroup *cgrp,
+                                         struct cgroup_iter *it)
+{
+       struct list_head *l = it->cg_link;
+       struct cg_cgroup_link *link;
+       struct css_set *cg;
+
+       /* Advance to the next non-empty css_set */
+       do {
+               l = l->next;
+               if (l == &cgrp->css_sets) {
+                       it->cg_link = NULL;
+                       return;
+               }
+               link = list_entry(l, struct cg_cgroup_link, cgrp_link_list);
+               cg = link->cg;
+       } while (list_empty(&cg->tasks));
+       it->cg_link = l;
+       it->task = cg->tasks.next;
+}
+
+void cgroup_iter_start(struct cgroup *cgrp, struct cgroup_iter *it)
+{
+       /*
+        * The first time anyone tries to iterate across a cgroup,
+        * we need to enable the list linking each css_set to its
+        * tasks, and fix up all existing tasks.
+        */
+       if (!use_task_css_set_links) {
+               struct task_struct *p, *g;
+               write_lock(&css_set_lock);
+               use_task_css_set_links = 1;
+               do_each_thread(g, p) {
+                       task_lock(p);
+                       if (list_empty(&p->cg_list))
+                               list_add(&p->cg_list, &p->cgroups->tasks);
+                       task_unlock(p);
+               } while_each_thread(g, p);
+               write_unlock(&css_set_lock);
+       }
+       read_lock(&css_set_lock);
+       it->cg_link = &cgrp->css_sets;
+       cgroup_advance_iter(cgrp, it);
+}
+
+struct task_struct *cgroup_iter_next(struct cgroup *cgrp,
+                                       struct cgroup_iter *it)
+{
+       struct task_struct *res;
+       struct list_head *l = it->task;
+
+       /* If the iterator cg is NULL, we have no tasks */
+       if (!it->cg_link)
+               return NULL;
+       res = list_entry(l, struct task_struct, cg_list);
+       /* Advance iterator to find next entry */
+       l = l->next;
+       if (l == &res->cgroups->tasks) {
+               /* We reached the end of this task list - move on to
+                * the next cg_cgroup_link */
+               cgroup_advance_iter(cgrp, it);
+       } else {
+               it->task = l;
+       }
+       return res;
+}
+
+void cgroup_iter_end(struct cgroup *cgrp, struct cgroup_iter *it)
+{
+       read_unlock(&css_set_lock);
+}
+
+/*
+ * Stuff for reading the 'tasks' file.
+ *
+ * Reading this file can return large amounts of data if a cgroup has
+ * *lots* of attached tasks. So it may need several calls to read(),
+ * but we cannot guarantee that the information we produce is correct
+ * unless we produce it entirely atomically.
+ *
+ * Upon tasks file open(), a struct ctr_struct is allocated, that
+ * will have a pointer to an array (also allocated here).  The struct
+ * ctr_struct * is stored in file->private_data.  Its resources will
+ * be freed by release() when the file is closed.  The array is used
+ * to sprintf the PIDs and then used by read().
+ */
+struct ctr_struct {
+       char *buf;
+       int bufsz;
+};
+
+/*
+ * Load into 'pidarray' up to 'npids' of the tasks using cgroup
+ * 'cgrp'.  Return actual number of pids loaded.  No need to
+ * task_lock(p) when reading out p->cgroup, since we're in an RCU
+ * read section, so the css_set can't go away, and is
+ * immutable after creation.
+ */
+static int pid_array_load(pid_t *pidarray, int npids, struct cgroup *cgrp)
+{
+       int n = 0;
+       struct cgroup_iter it;
+       struct task_struct *tsk;
+       cgroup_iter_start(cgrp, &it);
+       while ((tsk = cgroup_iter_next(cgrp, &it))) {
+               if (unlikely(n == npids))
+                       break;
+               pidarray[n++] = task_pid_nr(tsk);
+       }
+       cgroup_iter_end(cgrp, &it);
+       return n;
+}
+
+/**
+ * Build and fill cgroupstats so that taskstats can export it to user
+ * space.
+ *
+ * @stats: cgroupstats to fill information into
+ * @dentry: A dentry entry belonging to the cgroup for which stats have
+ * been requested.
+ */
+int cgroupstats_build(struct cgroupstats *stats, struct dentry *dentry)
+{
+       int ret = -EINVAL;
+       struct cgroup *cgrp;
+       struct cgroup_iter it;
+       struct task_struct *tsk;
+       /*
+        * Validate dentry by checking the superblock operations
+        */
+       if (dentry->d_sb->s_op != &cgroup_ops)
+                goto err;
+
+       ret = 0;
+       cgrp = dentry->d_fsdata;
+       rcu_read_lock();
+
+       cgroup_iter_start(cgrp, &it);
+       while ((tsk = cgroup_iter_next(cgrp, &it))) {
+               switch (tsk->state) {
+               case TASK_RUNNING:
+                       stats->nr_running++;
+                       break;
+               case TASK_INTERRUPTIBLE:
+                       stats->nr_sleeping++;
+                       break;
+               case TASK_UNINTERRUPTIBLE:
+                       stats->nr_uninterruptible++;
+                       break;
+               case TASK_STOPPED:
+                       stats->nr_stopped++;
+                       break;
+               default:
+                       if (delayacct_is_task_waiting_on_io(tsk))
+                               stats->nr_io_wait++;
+                       break;
+               }
+       }
+       cgroup_iter_end(cgrp, &it);
+
+       rcu_read_unlock();
+err:
+       return ret;
+}
+
+static int cmppid(const void *a, const void *b)
+{
+       return *(pid_t *)a - *(pid_t *)b;
+}
+
+/*
+ * Convert array 'a' of 'npids' pid_t's to a string of newline separated
+ * decimal pids in 'buf'.  Don't write more than 'sz' chars, but return
+ * count 'cnt' of how many chars would be written if buf were large enough.
+ */
+static int pid_array_to_buf(char *buf, int sz, pid_t *a, int npids)
+{
+       int cnt = 0;
+       int i;
+
+       for (i = 0; i < npids; i++)
+               cnt += snprintf(buf + cnt, max(sz - cnt, 0), "%d\n", a[i]);
+       return cnt;
+}
+
+/*
+ * Handle an open on 'tasks' file.  Prepare a buffer listing the
+ * process id's of tasks currently attached to the cgroup being opened.
+ *
+ * Does not require any specific cgroup mutexes, and does not take any.
+ */
+static int cgroup_tasks_open(struct inode *unused, struct file *file)
+{
+       struct cgroup *cgrp = __d_cgrp(file->f_dentry->d_parent);
+       struct ctr_struct *ctr;
+       pid_t *pidarray;
+       int npids;
+       char c;
+
+       if (!(file->f_mode & FMODE_READ))
+               return 0;
+
+       ctr = kmalloc(sizeof(*ctr), GFP_KERNEL);
+       if (!ctr)
+               goto err0;
+
+       /*
+        * If cgroup gets more users after we read count, we won't have
+        * enough space - tough.  This race is indistinguishable to the
+        * caller from the case that the additional cgroup users didn't
+        * show up until sometime later on.
+        */
+       npids = cgroup_task_count(cgrp);
+       if (npids) {
+               pidarray = kmalloc(npids * sizeof(pid_t), GFP_KERNEL);
+               if (!pidarray)
+                       goto err1;
+
+               npids = pid_array_load(pidarray, npids, cgrp);
+               sort(pidarray, npids, sizeof(pid_t), cmppid, NULL);
+
+               /* Call pid_array_to_buf() twice, first just to get bufsz */
+               ctr->bufsz = pid_array_to_buf(&c, sizeof(c), pidarray, npids) + 1;
+               ctr->buf = kmalloc(ctr->bufsz, GFP_KERNEL);
+               if (!ctr->buf)
+                       goto err2;
+               ctr->bufsz = pid_array_to_buf(ctr->buf, ctr->bufsz, pidarray, npids);
+
+               kfree(pidarray);
+       } else {
+               ctr->buf = 0;
+               ctr->bufsz = 0;
+       }
+       file->private_data = ctr;
+       return 0;
+
+err2:
+       kfree(pidarray);
+err1:
+       kfree(ctr);
+err0:
+       return -ENOMEM;
+}
+
+static ssize_t cgroup_tasks_read(struct cgroup *cgrp,
+                                   struct cftype *cft,
+                                   struct file *file, char __user *buf,
+                                   size_t nbytes, loff_t *ppos)
+{
+       struct ctr_struct *ctr = file->private_data;
+
+       return simple_read_from_buffer(buf, nbytes, ppos, ctr->buf, ctr->bufsz);
+}
+
+static int cgroup_tasks_release(struct inode *unused_inode,
+                                       struct file *file)
+{
+       struct ctr_struct *ctr;
+
+       if (file->f_mode & FMODE_READ) {
+               ctr = file->private_data;
+               kfree(ctr->buf);
+               kfree(ctr);
+       }
+       return 0;
+}
+
+static u64 cgroup_read_notify_on_release(struct cgroup *cgrp,
+                                           struct cftype *cft)
+{
+       return notify_on_release(cgrp);
+}
+
+static u64 cgroup_read_releasable(struct cgroup *cgrp, struct cftype *cft)
+{
+       return test_bit(CGRP_RELEASABLE, &cgrp->flags);
+}
+
+/*
+ * for the common functions, 'private' gives the type of file
+ */
+static struct cftype files[] = {
+       {
+               .name = "tasks",
+               .open = cgroup_tasks_open,
+               .read = cgroup_tasks_read,
+               .write = cgroup_common_file_write,
+               .release = cgroup_tasks_release,
+               .private = FILE_TASKLIST,
+       },
+
+       {
+               .name = "notify_on_release",
+               .read_uint = cgroup_read_notify_on_release,
+               .write = cgroup_common_file_write,
+               .private = FILE_NOTIFY_ON_RELEASE,
+       },
+
+       {
+               .name = "releasable",
+               .read_uint = cgroup_read_releasable,
+               .private = FILE_RELEASABLE,
+       }
+};
+
+static struct cftype cft_release_agent = {
+       .name = "release_agent",
+       .read = cgroup_common_file_read,
+       .write = cgroup_common_file_write,
+       .private = FILE_RELEASE_AGENT,
+};
+
+static int cgroup_populate_dir(struct cgroup *cgrp)
+{
+       int err;
+       struct cgroup_subsys *ss;
+
+       /* First clear out any existing files */
+       cgroup_clear_directory(cgrp->dentry);
+
+       err = cgroup_add_files(cgrp, NULL, files, ARRAY_SIZE(files));
+       if (err < 0)
+               return err;
+
+       if (cgrp == cgrp->top_cgroup) {
+               if ((err = cgroup_add_file(cgrp, NULL, &cft_release_agent)) < 0)
+                       return err;
+       }
+
+       for_each_subsys(cgrp->root, ss) {
+               if (ss->populate && (err = ss->populate(ss, cgrp)) < 0)
+                       return err;
+       }
+
+       return 0;
+}
+
+static void init_cgroup_css(struct cgroup_subsys_state *css,
+                              struct cgroup_subsys *ss,
+                              struct cgroup *cgrp)
+{
+       css->cgroup = cgrp;
+       atomic_set(&css->refcnt, 0);
+       css->flags = 0;
+       if (cgrp == dummytop)
+               set_bit(CSS_ROOT, &css->flags);
+       BUG_ON(cgrp->subsys[ss->subsys_id]);
+       cgrp->subsys[ss->subsys_id] = css;
+}
+
+/*
+ *     cgroup_create - create a cgroup
+ *     parent: cgroup that will be parent of the new cgroup.
+ *     name:           name of the new cgroup. Will be strcpy'ed.
+ *     mode:           mode to set on new inode
+ *
+ *     Must be called with the mutex on the parent inode held
+ */
+
+static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
+                            int mode)
+{
+       struct cgroup *cgrp;
+       struct cgroupfs_root *root = parent->root;
+       int err = 0;
+       struct cgroup_subsys *ss;
+       struct super_block *sb = root->sb;
+
+       cgrp = kzalloc(sizeof(*cgrp), GFP_KERNEL);
+       if (!cgrp)
+               return -ENOMEM;
+
+       /* Grab a reference on the superblock so the hierarchy doesn't
+        * get deleted on unmount if there are child cgroups.  This
+        * can be done outside cgroup_mutex, since the sb can't
+        * disappear while someone has an open control file on the
+        * fs */
+       atomic_inc(&sb->s_active);
+
+       mutex_lock(&cgroup_mutex);
+
+       cgrp->flags = 0;
+       INIT_LIST_HEAD(&cgrp->sibling);
+       INIT_LIST_HEAD(&cgrp->children);
+       INIT_LIST_HEAD(&cgrp->css_sets);
+       INIT_LIST_HEAD(&cgrp->release_list);
+
+       cgrp->parent = parent;
+       cgrp->root = parent->root;
+       cgrp->top_cgroup = parent->top_cgroup;
+
+       for_each_subsys(root, ss) {
+               struct cgroup_subsys_state *css = ss->create(ss, cgrp);
+               if (IS_ERR(css)) {
+                       err = PTR_ERR(css);
+                       goto err_destroy;
+               }
+               init_cgroup_css(css, ss, cgrp);
+       }
+
+       list_add(&cgrp->sibling, &cgrp->parent->children);
+       root->number_of_cgroups++;
+
+       err = cgroup_create_dir(cgrp, dentry, mode);
+       if (err < 0)
+               goto err_remove;
+
+       /* The cgroup directory was pre-locked for us */
+       BUG_ON(!mutex_is_locked(&cgrp->dentry->d_inode->i_mutex));
+
+       err = cgroup_populate_dir(cgrp);
+       /* If err < 0, we have a half-filled directory - oh well ;) */
+
+       mutex_unlock(&cgroup_mutex);
+       mutex_unlock(&cgrp->dentry->d_inode->i_mutex);
+
+       return 0;
+
+ err_remove:
+
+       list_del(&cgrp->sibling);
+       root->number_of_cgroups--;
+
+ err_destroy:
+
+       for_each_subsys(root, ss) {
+               if (cgrp->subsys[ss->subsys_id])
+                       ss->destroy(ss, cgrp);
+       }
+
+       mutex_unlock(&cgroup_mutex);
+
+       /* Release the reference count that we took on the superblock */
+       deactivate_super(sb);
+
+       kfree(cgrp);
+       return err;
+}
+
+static int cgroup_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+       struct cgroup *c_parent = dentry->d_parent->d_fsdata;
+
+       /* the vfs holds inode->i_mutex already */
+       return cgroup_create(c_parent, dentry, mode | S_IFDIR);
+}
+
+static inline int cgroup_has_css_refs(struct cgroup *cgrp)
+{
+       /* Check the reference count on each subsystem. Since we
+        * already established that there are no tasks in the
+        * cgroup, if the css refcount is also 0, then there should
+        * be no outstanding references, so the subsystem is safe to
+        * destroy. We scan across all subsystems rather than using
+        * the per-hierarchy linked list of mounted subsystems since
+        * we can be called via check_for_release() with no
+        * synchronization other than RCU, and the subsystem linked
+        * list isn't RCU-safe */
+       int i;
+       for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+               struct cgroup_subsys *ss = subsys[i];
+               struct cgroup_subsys_state *css;
+               /* Skip subsystems not in this hierarchy */
+               if (ss->root != cgrp->root)
+                       continue;
+               css = cgrp->subsys[ss->subsys_id];
+               /* When called from check_for_release() it's possible
+                * that by this point the cgroup has been removed
+                * and the css deleted. But a false-positive doesn't
+                * matter, since it can only happen if the cgroup
+                * has been deleted and hence no longer needs the
+                * release agent to be called anyway. */
+               if (css && atomic_read(&css->refcnt)) {
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry)
+{
+       struct cgroup *cgrp = dentry->d_fsdata;
+       struct dentry *d;
+       struct cgroup *parent;
+       struct cgroup_subsys *ss;
+       struct super_block *sb;
+       struct cgroupfs_root *root;
+
+       /* the vfs holds both inode->i_mutex already */
+
+       mutex_lock(&cgroup_mutex);
+       if (atomic_read(&cgrp->count) != 0) {
+               mutex_unlock(&cgroup_mutex);
+               return -EBUSY;
+       }
+       if (!list_empty(&cgrp->children)) {
+               mutex_unlock(&cgroup_mutex);
+               return -EBUSY;
+       }
+
+       parent = cgrp->parent;
+       root = cgrp->root;
+       sb = root->sb;
+
+       if (cgroup_has_css_refs(cgrp)) {
+               mutex_unlock(&cgroup_mutex);
+               return -EBUSY;
+       }
+
+       for_each_subsys(root, ss) {
+               if (cgrp->subsys[ss->subsys_id])
+                       ss->destroy(ss, cgrp);
+       }
+
+       spin_lock(&release_list_lock);
+       set_bit(CGRP_REMOVED, &cgrp->flags);
+       if (!list_empty(&cgrp->release_list))
+               list_del(&cgrp->release_list);
+       spin_unlock(&release_list_lock);
+       /* delete my sibling from parent->children */
+       list_del(&cgrp->sibling);
+       spin_lock(&cgrp->dentry->d_lock);
+       d = dget(cgrp->dentry);
+       cgrp->dentry = NULL;
+       spin_unlock(&d->d_lock);
+
+       cgroup_d_remove_dir(d);
+       dput(d);
+       root->number_of_cgroups--;
+
+       set_bit(CGRP_RELEASABLE, &parent->flags);
+       check_for_release(parent);
+
+       mutex_unlock(&cgroup_mutex);
+       /* Drop the active superblock reference that we took when we
+        * created the cgroup */
+       deactivate_super(sb);
+       return 0;
+}
+
+static void cgroup_init_subsys(struct cgroup_subsys *ss)
+{
+       struct cgroup_subsys_state *css;
+       struct list_head *l;
+       printk(KERN_ERR "Initializing cgroup subsys %s\n", ss->name);
+
+       /* Create the top cgroup state for this subsystem */
+       ss->root = &rootnode;
+       css = ss->create(ss, dummytop);
+       /* We don't handle early failures gracefully */
+       BUG_ON(IS_ERR(css));
+       init_cgroup_css(css, ss, dummytop);
+
+       /* Update all cgroup groups to contain a subsys
+        * pointer to this state - since the subsystem is
+        * newly registered, all tasks and hence all cgroup
+        * groups are in the subsystem's top cgroup. */
+       write_lock(&css_set_lock);
+       l = &init_css_set.list;
+       do {
+               struct css_set *cg =
+                       list_entry(l, struct css_set, list);
+               cg->subsys[ss->subsys_id] = dummytop->subsys[ss->subsys_id];
+               l = l->next;
+       } while (l != &init_css_set.list);
+       write_unlock(&css_set_lock);
+
+       /* If this subsystem requested that it be notified with fork
+        * events, we should send it one now for every process in the
+        * system */
+       if (ss->fork) {
+               struct task_struct *g, *p;
+
+               read_lock(&tasklist_lock);
+               do_each_thread(g, p) {
+                       ss->fork(ss, p);
+               } while_each_thread(g, p);
+               read_unlock(&tasklist_lock);
+       }
+
+       need_forkexit_callback |= ss->fork || ss->exit;
+
+       ss->active = 1;
+}
+
+/**
+ * cgroup_init_early - initialize cgroups at system boot, and
+ * initialize any subsystems that request early init.
+ */
+int __init cgroup_init_early(void)
+{
+       int i;
+       kref_init(&init_css_set.ref);
+       kref_get(&init_css_set.ref);
+       INIT_LIST_HEAD(&init_css_set.list);
+       INIT_LIST_HEAD(&init_css_set.cg_links);
+       INIT_LIST_HEAD(&init_css_set.tasks);
+       css_set_count = 1;
+       init_cgroup_root(&rootnode);
+       list_add(&rootnode.root_list, &roots);
+       root_count = 1;
+       init_task.cgroups = &init_css_set;
+
+       init_css_set_link.cg = &init_css_set;
+       list_add(&init_css_set_link.cgrp_link_list,
+                &rootnode.top_cgroup.css_sets);
+       list_add(&init_css_set_link.cg_link_list,
+                &init_css_set.cg_links);
+
+       for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+               struct cgroup_subsys *ss = subsys[i];
+
+               BUG_ON(!ss->name);
+               BUG_ON(strlen(ss->name) > MAX_CGROUP_TYPE_NAMELEN);
+               BUG_ON(!ss->create);
+               BUG_ON(!ss->destroy);
+               if (ss->subsys_id != i) {
+                       printk(KERN_ERR "Subsys %s id == %d\n",
+                              ss->name, ss->subsys_id);
+                       BUG();
+               }
+
+               if (ss->early_init)
+                       cgroup_init_subsys(ss);
+       }
+       return 0;
+}
+
+/**
+ * cgroup_init - register cgroup filesystem and /proc file, and
+ * initialize any subsystems that didn't request early init.
+ */
+int __init cgroup_init(void)
+{
+       int err;
+       int i;
+       struct proc_dir_entry *entry;
+
+       err = bdi_init(&cgroup_backing_dev_info);
+       if (err)
+               return err;
+
+       for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+               struct cgroup_subsys *ss = subsys[i];
+               if (!ss->early_init)
+                       cgroup_init_subsys(ss);
+       }
+
+       err = register_filesystem(&cgroup_fs_type);
+       if (err < 0)
+               goto out;
+
+       entry = create_proc_entry("cgroups", 0, NULL);
+       if (entry)
+               entry->proc_fops = &proc_cgroupstats_operations;
+
+out:
+       if (err)
+               bdi_destroy(&cgroup_backing_dev_info);
+
+       return err;
+}
+
+/*
+ * proc_cgroup_show()
+ *  - Print task's cgroup paths into seq_file, one line for each hierarchy
+ *  - Used for /proc/<pid>/cgroup.
+ *  - No need to task_lock(tsk) on this tsk->cgroup reference, as it
+ *    doesn't really matter if tsk->cgroup changes after we read it,
+ *    and we take cgroup_mutex, keeping attach_task() from changing it
+ *    anyway.  No need to check that tsk->cgroup != NULL, thanks to
+ *    the_top_cgroup_hack in cgroup_exit(), which sets an exiting tasks
+ *    cgroup to top_cgroup.
+ */
+
+/* TODO: Use a proper seq_file iterator */
+static int proc_cgroup_show(struct seq_file *m, void *v)
+{
+       struct pid *pid;
+       struct task_struct *tsk;
+       char *buf;
+       int retval;
+       struct cgroupfs_root *root;
+
+       retval = -ENOMEM;
+       buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+       if (!buf)
+               goto out;
+
+       retval = -ESRCH;
+       pid = m->private;
+       tsk = get_pid_task(pid, PIDTYPE_PID);
+       if (!tsk)
+               goto out_free;
+
+       retval = 0;
+
+       mutex_lock(&cgroup_mutex);
+
+       for_each_root(root) {
+               struct cgroup_subsys *ss;
+               struct cgroup *cgrp;
+               int subsys_id;
+               int count = 0;
+
+               /* Skip this hierarchy if it has no active subsystems */
+               if (!root->actual_subsys_bits)
+                       continue;
+               for_each_subsys(root, ss)
+                       seq_printf(m, "%s%s", count++ ? "," : "", ss->name);
+               seq_putc(m, ':');
+               get_first_subsys(&root->top_cgroup, NULL, &subsys_id);
+               cgrp = task_cgroup(tsk, subsys_id);
+               retval = cgroup_path(cgrp, buf, PAGE_SIZE);
+               if (retval < 0)
+                       goto out_unlock;
+               seq_puts(m, buf);
+               seq_putc(m, '\n');
+       }
+
+out_unlock:
+       mutex_unlock(&cgroup_mutex);
+       put_task_struct(tsk);
+out_free:
+       kfree(buf);
+out:
+       return retval;
+}
+
+static int cgroup_open(struct inode *inode, struct file *file)
+{
+       struct pid *pid = PROC_I(inode)->pid;
+       return single_open(file, proc_cgroup_show, pid);
+}
+
+struct file_operations proc_cgroup_operations = {
+       .open           = cgroup_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+/* Display information about each subsystem and each hierarchy */
+static int proc_cgroupstats_show(struct seq_file *m, void *v)
+{
+       int i;
+       struct cgroupfs_root *root;
+
+       seq_puts(m, "#subsys_name\thierarchy\tnum_cgroups\n");
+       mutex_lock(&cgroup_mutex);
+       for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+               struct cgroup_subsys *ss = subsys[i];
+               seq_printf(m, "%s\t%lu\t%d\n",
+                          ss->name, ss->root->subsys_bits,
+                          ss->root->number_of_cgroups);
+       }
+       mutex_unlock(&cgroup_mutex);
+       return 0;
+}
+
+static int cgroupstats_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, proc_cgroupstats_show, 0);
+}
+
+static struct file_operations proc_cgroupstats_operations = {
+       .open = cgroupstats_open,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = single_release,
+};
+
+/**
+ * cgroup_fork - attach newly forked task to its parents cgroup.
+ * @tsk: pointer to task_struct of forking parent process.
+ *
+ * Description: A task inherits its parent's cgroup at fork().
+ *
+ * A pointer to the shared css_set was automatically copied in
+ * fork.c by dup_task_struct().  However, we ignore that copy, since
+ * it was not made under the protection of RCU or cgroup_mutex, so
+ * might no longer be a valid cgroup pointer.  attach_task() might
+ * have already changed current->cgroups, allowing the previously
+ * referenced cgroup group to be removed and freed.
+ *
+ * At the point that cgroup_fork() is called, 'current' is the parent
+ * task, and the passed argument 'child' points to the child task.
+ */
+void cgroup_fork(struct task_struct *child)
+{
+       task_lock(current);
+       child->cgroups = current->cgroups;
+       get_css_set(child->cgroups);
+       task_unlock(current);
+       INIT_LIST_HEAD(&child->cg_list);
+}
+
+/**
+ * cgroup_fork_callbacks - called on a new task very soon before
+ * adding it to the tasklist. No need to take any locks since no-one
+ * can be operating on this task
+ */
+void cgroup_fork_callbacks(struct task_struct *child)
+{
+       if (need_forkexit_callback) {
+               int i;
+               for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+                       struct cgroup_subsys *ss = subsys[i];
+                       if (ss->fork)
+                               ss->fork(ss, child);
+               }
+       }
+}
+
+/**
+ * cgroup_post_fork - called on a new task after adding it to the
+ * task list. Adds the task to the list running through its css_set
+ * if necessary. Has to be after the task is visible on the task list
+ * in case we race with the first call to cgroup_iter_start() - to
+ * guarantee that the new task ends up on its list. */
+void cgroup_post_fork(struct task_struct *child)
+{
+       if (use_task_css_set_links) {
+               write_lock(&css_set_lock);
+               if (list_empty(&child->cg_list))
+                       list_add(&child->cg_list, &child->cgroups->tasks);
+               write_unlock(&css_set_lock);
+       }
+}
+/**
+ * cgroup_exit - detach cgroup from exiting task
+ * @tsk: pointer to task_struct of exiting process
+ *
+ * Description: Detach cgroup from @tsk and release it.
+ *
+ * Note that cgroups marked notify_on_release force every task in
+ * them to take the global cgroup_mutex mutex when exiting.
+ * This could impact scaling on very large systems.  Be reluctant to
+ * use notify_on_release cgroups where very high task exit scaling
+ * is required on large systems.
+ *
+ * the_top_cgroup_hack:
+ *
+ *    Set the exiting tasks cgroup to the root cgroup (top_cgroup).
+ *
+ *    We call cgroup_exit() while the task is still competent to
+ *    handle notify_on_release(), then leave the task attached to the
+ *    root cgroup in each hierarchy for the remainder of its exit.
+ *
+ *    To do this properly, we would increment the reference count on
+ *    top_cgroup, and near the very end of the kernel/exit.c do_exit()
+ *    code we would add a second cgroup function call, to drop that
+ *    reference.  This would just create an unnecessary hot spot on
+ *    the top_cgroup reference count, to no avail.
+ *
+ *    Normally, holding a reference to a cgroup without bumping its
+ *    count is unsafe.   The cgroup could go away, or someone could
+ *    attach us to a different cgroup, decrementing the count on
+ *    the first cgroup that we never incremented.  But in this case,
+ *    top_cgroup isn't going away, and either task has PF_EXITING set,
+ *    which wards off any attach_task() attempts, or task is a failed
+ *    fork, never visible to attach_task.
+ *
+ */
+void cgroup_exit(struct task_struct *tsk, int run_callbacks)
+{
+       int i;
+       struct css_set *cg;
+
+       if (run_callbacks && need_forkexit_callback) {
+               for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+                       struct cgroup_subsys *ss = subsys[i];
+                       if (ss->exit)
+                               ss->exit(ss, tsk);
+               }
+       }
+
+       /*
+        * Unlink from the css_set task list if necessary.
+        * Optimistically check cg_list before taking
+        * css_set_lock
+        */
+       if (!list_empty(&tsk->cg_list)) {
+               write_lock(&css_set_lock);
+               if (!list_empty(&tsk->cg_list))
+                       list_del(&tsk->cg_list);
+               write_unlock(&css_set_lock);
+       }
+
+       /* Reassign the task to the init_css_set. */
+       task_lock(tsk);
+       cg = tsk->cgroups;
+       tsk->cgroups = &init_css_set;
+       task_unlock(tsk);
+       if (cg)
+               put_css_set_taskexit(cg);
+}
+
+/**
+ * cgroup_clone - duplicate the current cgroup in the hierarchy
+ * that the given subsystem is attached to, and move this task into
+ * the new child
+ */
+int cgroup_clone(struct task_struct *tsk, struct cgroup_subsys *subsys)
+{
+       struct dentry *dentry;
+       int ret = 0;
+       char nodename[MAX_CGROUP_TYPE_NAMELEN];
+       struct cgroup *parent, *child;
+       struct inode *inode;
+       struct css_set *cg;
+       struct cgroupfs_root *root;
+       struct cgroup_subsys *ss;
+
+       /* We shouldn't be called by an unregistered subsystem */
+       BUG_ON(!subsys->active);
+
+       /* First figure out what hierarchy and cgroup we're dealing
+        * with, and pin them so we can drop cgroup_mutex */
+       mutex_lock(&cgroup_mutex);
+ again:
+       root = subsys->root;
+       if (root == &rootnode) {
+               printk(KERN_INFO
+                      "Not cloning cgroup for unused subsystem %s\n",
+                      subsys->name);
+               mutex_unlock(&cgroup_mutex);
+               return 0;
+       }
+       cg = tsk->cgroups;
+       parent = task_cgroup(tsk, subsys->subsys_id);
+
+       snprintf(nodename, MAX_CGROUP_TYPE_NAMELEN, "node_%d", tsk->pid);
+
+       /* Pin the hierarchy */
+       atomic_inc(&parent->root->sb->s_active);
+
+       /* Keep the cgroup alive */
+       get_css_set(cg);
+       mutex_unlock(&cgroup_mutex);
+
+       /* Now do the VFS work to create a cgroup */
+       inode = parent->dentry->d_inode;
+
+       /* Hold the parent directory mutex across this operation to
+        * stop anyone else deleting the new cgroup */
+       mutex_lock(&inode->i_mutex);
+       dentry = lookup_one_len(nodename, parent->dentry, strlen(nodename));
+       if (IS_ERR(dentry)) {
+               printk(KERN_INFO
+                      "Couldn't allocate dentry for %s: %ld\n", nodename,
+                      PTR_ERR(dentry));
+               ret = PTR_ERR(dentry);
+               goto out_release;
+       }
+
+       /* Create the cgroup directory, which also creates the cgroup */
+       ret = vfs_mkdir(inode, dentry, S_IFDIR | 0755);
+       child = __d_cgrp(dentry);
+       dput(dentry);
+       if (ret) {
+               printk(KERN_INFO
+                      "Failed to create cgroup %s: %d\n", nodename,
+                      ret);
+               goto out_release;
+       }
+
+       if (!child) {
+               printk(KERN_INFO
+                      "Couldn't find new cgroup %s\n", nodename);
+               ret = -ENOMEM;
+               goto out_release;
+       }
+
+       /* The cgroup now exists. Retake cgroup_mutex and check
+        * that we're still in the same state that we thought we
+        * were. */
+       mutex_lock(&cgroup_mutex);
+       if ((root != subsys->root) ||
+           (parent != task_cgroup(tsk, subsys->subsys_id))) {
+               /* Aargh, we raced ... */
+               mutex_unlock(&inode->i_mutex);
+               put_css_set(cg);
+
+               deactivate_super(parent->root->sb);
+               /* The cgroup is still accessible in the VFS, but
+                * we're not going to try to rmdir() it at this
+                * point. */
+               printk(KERN_INFO
+                      "Race in cgroup_clone() - leaking cgroup %s\n",
+                      nodename);
+               goto again;
+       }
+
+       /* do any required auto-setup */
+       for_each_subsys(root, ss) {
+               if (ss->post_clone)
+                       ss->post_clone(ss, child);
+       }
+
+       /* All seems fine. Finish by moving the task into the new cgroup */
+       ret = attach_task(child, tsk);
+       mutex_unlock(&cgroup_mutex);
+
+ out_release:
+       mutex_unlock(&inode->i_mutex);
+
+       mutex_lock(&cgroup_mutex);
+       put_css_set(cg);
+       mutex_unlock(&cgroup_mutex);
+       deactivate_super(parent->root->sb);
+       return ret;
+}
+
+/*
+ * See if "cgrp" is a descendant of the current task's cgroup in
+ * the appropriate hierarchy
+ *
+ * If we are sending in dummytop, then presumably we are creating
+ * the top cgroup in the subsystem.
+ *
+ * Called only by the ns (nsproxy) cgroup.
+ */
+int cgroup_is_descendant(const struct cgroup *cgrp)
+{
+       int ret;
+       struct cgroup *target;
+       int subsys_id;
+
+       if (cgrp == dummytop)
+               return 1;
+
+       get_first_subsys(cgrp, NULL, &subsys_id);
+       target = task_cgroup(current, subsys_id);
+       while (cgrp != target && cgrp!= cgrp->top_cgroup)
+               cgrp = cgrp->parent;
+       ret = (cgrp == target);
+       return ret;
+}
+
+static void check_for_release(struct cgroup *cgrp)
+{
+       /* All of these checks rely on RCU to keep the cgroup
+        * structure alive */
+       if (cgroup_is_releasable(cgrp) && !atomic_read(&cgrp->count)
+           && list_empty(&cgrp->children) && !cgroup_has_css_refs(cgrp)) {
+               /* Control Group is currently removeable. If it's not
+                * already queued for a userspace notification, queue
+                * it now */
+               int need_schedule_work = 0;
+               spin_lock(&release_list_lock);
+               if (!cgroup_is_removed(cgrp) &&
+                   list_empty(&cgrp->release_list)) {
+                       list_add(&cgrp->release_list, &release_list);
+                       need_schedule_work = 1;
+               }
+               spin_unlock(&release_list_lock);
+               if (need_schedule_work)
+                       schedule_work(&release_agent_work);
+       }
+}
+
+void __css_put(struct cgroup_subsys_state *css)
+{
+       struct cgroup *cgrp = css->cgroup;
+       rcu_read_lock();
+       if (atomic_dec_and_test(&css->refcnt) && notify_on_release(cgrp)) {
+               set_bit(CGRP_RELEASABLE, &cgrp->flags);
+               check_for_release(cgrp);
+       }
+       rcu_read_unlock();
+}
+
+/*
+ * Notify userspace when a cgroup is released, by running the
+ * configured release agent with the name of the cgroup (path
+ * relative to the root of cgroup file system) as the argument.
+ *
+ * Most likely, this user command will try to rmdir this cgroup.
+ *
+ * This races with the possibility that some other task will be
+ * attached to this cgroup before it is removed, or that some other
+ * user task will 'mkdir' a child cgroup of this cgroup.  That's ok.
+ * The presumed 'rmdir' will fail quietly if this cgroup is no longer
+ * unused, and this cgroup will be reprieved from its death sentence,
+ * to continue to serve a useful existence.  Next time it's released,
+ * we will get notified again, if it still has 'notify_on_release' set.
+ *
+ * The final arg to call_usermodehelper() is UMH_WAIT_EXEC, which
+ * means only wait until the task is successfully execve()'d.  The
+ * separate release agent task is forked by call_usermodehelper(),
+ * then control in this thread returns here, without waiting for the
+ * release agent task.  We don't bother to wait because the caller of
+ * this routine has no use for the exit status of the release agent
+ * task, so no sense holding our caller up for that.
+ *
+ */
+
+static void cgroup_release_agent(struct work_struct *work)
+{
+       BUG_ON(work != &release_agent_work);
+       mutex_lock(&cgroup_mutex);
+       spin_lock(&release_list_lock);
+       while (!list_empty(&release_list)) {
+               char *argv[3], *envp[3];
+               int i;
+               char *pathbuf;
+               struct cgroup *cgrp = list_entry(release_list.next,
+                                                   struct cgroup,
+                                                   release_list);
+               list_del_init(&cgrp->release_list);
+               spin_unlock(&release_list_lock);
+               pathbuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+               if (!pathbuf) {
+                       spin_lock(&release_list_lock);
+                       continue;
+               }
+
+               if (cgroup_path(cgrp, pathbuf, PAGE_SIZE) < 0) {
+                       kfree(pathbuf);
+                       spin_lock(&release_list_lock);
+                       continue;
+               }
+
+               i = 0;
+               argv[i++] = cgrp->root->release_agent_path;
+               argv[i++] = (char *)pathbuf;
+               argv[i] = NULL;
+
+               i = 0;
+               /* minimal command environment */
+               envp[i++] = "HOME=/";
+               envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
+               envp[i] = NULL;
+
+               /* Drop the lock while we invoke the usermode helper,
+                * since the exec could involve hitting disk and hence
+                * be a slow process */
+               mutex_unlock(&cgroup_mutex);
+               call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
+               kfree(pathbuf);
+               mutex_lock(&cgroup_mutex);
+               spin_lock(&release_list_lock);
+       }
+       spin_unlock(&release_list_lock);
+       mutex_unlock(&cgroup_mutex);
+}
diff --git a/kernel/cgroup_debug.c b/kernel/cgroup_debug.c
new file mode 100644 (file)
index 0000000..37301e8
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * kernel/ccontainer_debug.c - Example cgroup subsystem that
+ * exposes debug info
+ *
+ * Copyright (C) Google Inc, 2007
+ *
+ * Developed by Paul Menage (menage@google.com)
+ *
+ */
+
+#include <linux/cgroup.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/rcupdate.h>
+
+#include <asm/atomic.h>
+
+static struct cgroup_subsys_state *debug_create(struct cgroup_subsys *ss,
+                                                  struct cgroup *cont)
+{
+       struct cgroup_subsys_state *css = kzalloc(sizeof(*css), GFP_KERNEL);
+
+       if (!css)
+               return ERR_PTR(-ENOMEM);
+
+       return css;
+}
+
+static void debug_destroy(struct cgroup_subsys *ss, struct cgroup *cont)
+{
+       kfree(cont->subsys[debug_subsys_id]);
+}
+
+static u64 cgroup_refcount_read(struct cgroup *cont, struct cftype *cft)
+{
+       return atomic_read(&cont->count);
+}
+
+static u64 taskcount_read(struct cgroup *cont, struct cftype *cft)
+{
+       u64 count;
+
+       cgroup_lock();
+       count = cgroup_task_count(cont);
+       cgroup_unlock();
+       return count;
+}
+
+static u64 current_css_set_read(struct cgroup *cont, struct cftype *cft)
+{
+       return (u64)(long)current->cgroups;
+}
+
+static u64 current_css_set_refcount_read(struct cgroup *cont,
+                                          struct cftype *cft)
+{
+       u64 count;
+
+       rcu_read_lock();
+       count = atomic_read(&current->cgroups->ref.refcount);
+       rcu_read_unlock();
+       return count;
+}
+
+static struct cftype files[] =  {
+       {
+               .name = "cgroup_refcount",
+               .read_uint = cgroup_refcount_read,
+       },
+       {
+               .name = "taskcount",
+               .read_uint = taskcount_read,
+       },
+
+       {
+               .name = "current_css_set",
+               .read_uint = current_css_set_read,
+       },
+
+       {
+               .name = "current_css_set_refcount",
+               .read_uint = current_css_set_refcount_read,
+       },
+};
+
+static int debug_populate(struct cgroup_subsys *ss, struct cgroup *cont)
+{
+       return cgroup_add_files(cont, ss, files, ARRAY_SIZE(files));
+}
+
+struct cgroup_subsys debug_subsys = {
+       .name = "debug",
+       .create = debug_create,
+       .destroy = debug_destroy,
+       .populate = debug_populate,
+       .subsys_id = debug_subsys_id,
+};
index 3bae3742c2aa567e18f7b1558f7fa72b1c9155a0..42a1ed4b61b172afe1693234a4c68e5cfb695610 100644 (file)
@@ -40,62 +40,27 @@ int put_compat_timespec(const struct timespec *ts, struct compat_timespec __user
                        __put_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
 }
 
-static long compat_nanosleep_restart(struct restart_block *restart)
-{
-       unsigned long expire = restart->arg0, now = jiffies;
-       struct compat_timespec __user *rmtp;
-
-       /* Did it expire while we handled signals? */
-       if (!time_after(expire, now))
-               return 0;
-
-       expire = schedule_timeout_interruptible(expire - now);
-       if (expire == 0)
-               return 0;
-
-       rmtp = (struct compat_timespec __user *)restart->arg1;
-       if (rmtp) {
-               struct compat_timespec ct;
-               struct timespec t;
-
-               jiffies_to_timespec(expire, &t);
-               ct.tv_sec = t.tv_sec;
-               ct.tv_nsec = t.tv_nsec;
-               if (copy_to_user(rmtp, &ct, sizeof(ct)))
-                       return -EFAULT;
-       }
-       /* The 'restart' block is already filled in */
-       return -ERESTART_RESTARTBLOCK;
-}
-
 asmlinkage long compat_sys_nanosleep(struct compat_timespec __user *rqtp,
-               struct compat_timespec __user *rmtp)
+                                    struct compat_timespec __user *rmtp)
 {
-       struct timespec t;
-       struct restart_block *restart;
-       unsigned long expire;
+       struct timespec tu, rmt;
+       long ret;
 
-       if (get_compat_timespec(&t, rqtp))
+       if (get_compat_timespec(&tu, rqtp))
                return -EFAULT;
 
-       if ((t.tv_nsec >= 1000000000L) || (t.tv_nsec < 0) || (t.tv_sec < 0))
+       if (!timespec_valid(&tu))
                return -EINVAL;
 
-       expire = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec);
-       expire = schedule_timeout_interruptible(expire);
-       if (expire == 0)
-               return 0;
+       ret = hrtimer_nanosleep(&tu, rmtp ? &rmt : NULL, HRTIMER_MODE_REL,
+                               CLOCK_MONOTONIC);
 
-       if (rmtp) {
-               jiffies_to_timespec(expire, &t);
-               if (put_compat_timespec(&t, rmtp))
+       if (ret && rmtp) {
+               if (put_compat_timespec(&rmt, rmtp))
                        return -EFAULT;
        }
-       restart = &current_thread_info()->restart_block;
-       restart->fn = compat_nanosleep_restart;
-       restart->arg0 = jiffies + expire;
-       restart->arg1 = (unsigned long) rmtp;
-       return -ERESTART_RESTARTBLOCK;
+
+       return ret;
 }
 
 static inline long get_compat_itimerval(struct itimerval *o,
@@ -247,8 +212,8 @@ asmlinkage long compat_sys_setrlimit(unsigned int resource,
        int ret;
        mm_segment_t old_fs = get_fs ();
 
-       if (resource >= RLIM_NLIMITS) 
-               return -EINVAL; 
+       if (resource >= RLIM_NLIMITS)
+               return -EINVAL;
 
        if (!access_ok(VERIFY_READ, rlim, sizeof(*rlim)) ||
            __get_user(r.rlim_cur, &rlim->rlim_cur) ||
@@ -477,21 +442,21 @@ asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, unsigned int len,
 
 int get_compat_itimerspec(struct itimerspec *dst,
                          const struct compat_itimerspec __user *src)
-{ 
+{
        if (get_compat_timespec(&dst->it_interval, &src->it_interval) ||
            get_compat_timespec(&dst->it_value, &src->it_value))
                return -EFAULT;
        return 0;
-} 
+}
 
 int put_compat_itimerspec(struct compat_itimerspec __user *dst,
                          const struct itimerspec *src)
-{ 
+{
        if (put_compat_timespec(&src->it_interval, &dst->it_interval) ||
            put_compat_timespec(&src->it_value, &dst->it_value))
                return -EFAULT;
        return 0;
-} 
+}
 
 long compat_sys_timer_create(clockid_t which_clock,
                        struct compat_sigevent __user *timer_event_spec,
@@ -512,9 +477,9 @@ long compat_sys_timer_create(clockid_t which_clock,
 }
 
 long compat_sys_timer_settime(timer_t timer_id, int flags,
-                         struct compat_itimerspec __user *new, 
+                         struct compat_itimerspec __user *new,
                          struct compat_itimerspec __user *old)
-{ 
+{
        long err;
        mm_segment_t oldfs;
        struct itimerspec newts, oldts;
@@ -522,58 +487,58 @@ long compat_sys_timer_settime(timer_t timer_id, int flags,
        if (!new)
                return -EINVAL;
        if (get_compat_itimerspec(&newts, new))
-               return -EFAULT; 
+               return -EFAULT;
        oldfs = get_fs();
        set_fs(KERNEL_DS);
        err = sys_timer_settime(timer_id, flags,
                                (struct itimerspec __user *) &newts,
                                (struct itimerspec __user *) &oldts);
-       set_fs(oldfs); 
+       set_fs(oldfs);
        if (!err && old && put_compat_itimerspec(old, &oldts))
                return -EFAULT;
        return err;
-} 
+}
 
 long compat_sys_timer_gettime(timer_t timer_id,
                struct compat_itimerspec __user *setting)
-{ 
+{
        long err;
        mm_segment_t oldfs;
-       struct itimerspec ts; 
+       struct itimerspec ts;
 
        oldfs = get_fs();
        set_fs(KERNEL_DS);
        err = sys_timer_gettime(timer_id,
-                               (struct itimerspec __user *) &ts); 
-       set_fs(oldfs); 
+                               (struct itimerspec __user *) &ts);
+       set_fs(oldfs);
        if (!err && put_compat_itimerspec(setting, &ts))
                return -EFAULT;
        return err;
-} 
+}
 
 long compat_sys_clock_settime(clockid_t which_clock,
                struct compat_timespec __user *tp)
 {
        long err;
        mm_segment_t oldfs;
-       struct timespec ts; 
+       struct timespec ts;
 
        if (get_compat_timespec(&ts, tp))
-               return -EFAULT; 
+               return -EFAULT;
        oldfs = get_fs();
-       set_fs(KERNEL_DS);      
+       set_fs(KERNEL_DS);
        err = sys_clock_settime(which_clock,
                                (struct timespec __user *) &ts);
        set_fs(oldfs);
        return err;
-} 
+}
 
 long compat_sys_clock_gettime(clockid_t which_clock,
                struct compat_timespec __user *tp)
 {
        long err;
        mm_segment_t oldfs;
-       struct timespec ts; 
+       struct timespec ts;
 
        oldfs = get_fs();
        set_fs(KERNEL_DS);
@@ -581,16 +546,16 @@ long compat_sys_clock_gettime(clockid_t which_clock,
                                (struct timespec __user *) &ts);
        set_fs(oldfs);
        if (!err && put_compat_timespec(&ts, tp))
-               return -EFAULT; 
+               return -EFAULT;
        return err;
-} 
+}
 
 long compat_sys_clock_getres(clockid_t which_clock,
                struct compat_timespec __user *tp)
 {
        long err;
        mm_segment_t oldfs;
-       struct timespec ts; 
+       struct timespec ts;
 
        oldfs = get_fs();
        set_fs(KERNEL_DS);
@@ -598,9 +563,9 @@ long compat_sys_clock_getres(clockid_t which_clock,
                               (struct timespec __user *) &ts);
        set_fs(oldfs);
        if (!err && tp && put_compat_timespec(&ts, tp))
-               return -EFAULT; 
+               return -EFAULT;
        return err;
-} 
+}
 
 static long compat_clock_nanosleep_restart(struct restart_block *restart)
 {
@@ -632,10 +597,10 @@ long compat_sys_clock_nanosleep(clockid_t which_clock, int flags,
 {
        long err;
        mm_segment_t oldfs;
-       struct timespec in, out; 
+       struct timespec in, out;
        struct restart_block *restart;
 
-       if (get_compat_timespec(&in, rqtp)) 
+       if (get_compat_timespec(&in, rqtp))
                return -EFAULT;
 
        oldfs = get_fs();
@@ -654,8 +619,8 @@ long compat_sys_clock_nanosleep(clockid_t which_clock, int flags,
                restart->fn = compat_clock_nanosleep_restart;
                restart->arg1 = (unsigned long) rmtp;
        }
-       return err;     
-} 
+       return err;
+}
 
 /*
  * We currently only need the following fields from the sigevent
index 38033db8d8ec3d8f23af3973560dc995782efbda..6b3a0c15144f3404294dde422348e17242990e2b 100644 (file)
@@ -98,7 +98,8 @@ static inline void check_for_tasks(int cpu)
                     !cputime_eq(p->stime, cputime_zero)))
                        printk(KERN_WARNING "Task %s (pid = %d) is on cpu %d\
                                (state = %ld, flags = %x) \n",
-                                p->comm, p->pid, cpu, p->state, p->flags);
+                                p->comm, task_pid_nr(p), cpu,
+                                p->state, p->flags);
        }
        write_unlock_irq(&tasklist_lock);
 }
@@ -150,6 +151,7 @@ static int _cpu_down(unsigned int cpu, int tasks_frozen)
        err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE | mod,
                                        hcpu, -1, &nr_calls);
        if (err == NOTIFY_BAD) {
+               nr_calls--;
                __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED | mod,
                                          hcpu, nr_calls, NULL);
                printk("%s: attempt to take down CPU %u failed\n",
@@ -233,6 +235,7 @@ static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen)
        ret = __raw_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE | mod, hcpu,
                                                        -1, &nr_calls);
        if (ret == NOTIFY_BAD) {
+               nr_calls--;
                printk("%s: attempt to bring up CPU %u failed\n",
                                __FUNCTION__, cpu);
                ret = -EINVAL;
@@ -262,6 +265,15 @@ out_notify:
 int __cpuinit cpu_up(unsigned int cpu)
 {
        int err = 0;
+       if (!cpu_isset(cpu, cpu_possible_map)) {
+               printk(KERN_ERR "can't online cpu %d because it is not "
+                       "configured as may-hotadd at boot time\n", cpu);
+#if defined(CONFIG_IA64) || defined(CONFIG_X86_64) || defined(CONFIG_S390)
+               printk(KERN_ERR "please check additional_cpus= boot "
+                               "parameter\n");
+#endif
+               return -EINVAL;
+       }
 
        mutex_lock(&cpu_add_remove_lock);
        if (cpu_hotplug_disabled)
diff --git a/kernel/cpu_acct.c b/kernel/cpu_acct.c
new file mode 100644 (file)
index 0000000..731e47e
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * kernel/cpu_acct.c - CPU accounting cgroup subsystem
+ *
+ * Copyright (C) Google Inc, 2006
+ *
+ * Developed by Paul Menage (menage@google.com) and Balbir Singh
+ * (balbir@in.ibm.com)
+ *
+ */
+
+/*
+ * Example cgroup subsystem for reporting total CPU usage of tasks in a
+ * cgroup, along with percentage load over a time interval
+ */
+
+#include <linux/module.h>
+#include <linux/cgroup.h>
+#include <linux/fs.h>
+#include <linux/rcupdate.h>
+
+#include <asm/div64.h>
+
+struct cpuacct {
+       struct cgroup_subsys_state css;
+       spinlock_t lock;
+       /* total time used by this class */
+       cputime64_t time;
+
+       /* time when next load calculation occurs */
+       u64 next_interval_check;
+
+       /* time used in current period */
+       cputime64_t current_interval_time;
+
+       /* time used in last period */
+       cputime64_t last_interval_time;
+};
+
+struct cgroup_subsys cpuacct_subsys;
+
+static inline struct cpuacct *cgroup_ca(struct cgroup *cont)
+{
+       return container_of(cgroup_subsys_state(cont, cpuacct_subsys_id),
+                           struct cpuacct, css);
+}
+
+static inline struct cpuacct *task_ca(struct task_struct *task)
+{
+       return container_of(task_subsys_state(task, cpuacct_subsys_id),
+                           struct cpuacct, css);
+}
+
+#define INTERVAL (HZ * 10)
+
+static inline u64 next_interval_boundary(u64 now)
+{
+       /* calculate the next interval boundary beyond the
+        * current time */
+       do_div(now, INTERVAL);
+       return (now + 1) * INTERVAL;
+}
+
+static struct cgroup_subsys_state *cpuacct_create(
+       struct cgroup_subsys *ss, struct cgroup *cont)
+{
+       struct cpuacct *ca = kzalloc(sizeof(*ca), GFP_KERNEL);
+
+       if (!ca)
+               return ERR_PTR(-ENOMEM);
+       spin_lock_init(&ca->lock);
+       ca->next_interval_check = next_interval_boundary(get_jiffies_64());
+       return &ca->css;
+}
+
+static void cpuacct_destroy(struct cgroup_subsys *ss,
+                           struct cgroup *cont)
+{
+       kfree(cgroup_ca(cont));
+}
+
+/* Lazily update the load calculation if necessary. Called with ca locked */
+static void cpuusage_update(struct cpuacct *ca)
+{
+       u64 now = get_jiffies_64();
+
+       /* If we're not due for an update, return */
+       if (ca->next_interval_check > now)
+               return;
+
+       if (ca->next_interval_check <= (now - INTERVAL)) {
+               /* If it's been more than an interval since the last
+                * check, then catch up - the last interval must have
+                * been zero load */
+               ca->last_interval_time = 0;
+               ca->next_interval_check = next_interval_boundary(now);
+       } else {
+               /* If a steal takes the last interval time negative,
+                * then we just ignore it */
+               if ((s64)ca->current_interval_time > 0)
+                       ca->last_interval_time = ca->current_interval_time;
+               else
+                       ca->last_interval_time = 0;
+               ca->next_interval_check += INTERVAL;
+       }
+       ca->current_interval_time = 0;
+}
+
+static u64 cpuusage_read(struct cgroup *cont, struct cftype *cft)
+{
+       struct cpuacct *ca = cgroup_ca(cont);
+       u64 time;
+
+       spin_lock_irq(&ca->lock);
+       cpuusage_update(ca);
+       time = cputime64_to_jiffies64(ca->time);
+       spin_unlock_irq(&ca->lock);
+
+       /* Convert 64-bit jiffies to seconds */
+       time *= 1000;
+       do_div(time, HZ);
+       return time;
+}
+
+static u64 load_read(struct cgroup *cont, struct cftype *cft)
+{
+       struct cpuacct *ca = cgroup_ca(cont);
+       u64 time;
+
+       /* Find the time used in the previous interval */
+       spin_lock_irq(&ca->lock);
+       cpuusage_update(ca);
+       time = cputime64_to_jiffies64(ca->last_interval_time);
+       spin_unlock_irq(&ca->lock);
+
+       /* Convert time to a percentage, to give the load in the
+        * previous period */
+       time *= 100;
+       do_div(time, INTERVAL);
+
+       return time;
+}
+
+static struct cftype files[] = {
+       {
+               .name = "usage",
+               .read_uint = cpuusage_read,
+       },
+       {
+               .name = "load",
+               .read_uint = load_read,
+       }
+};
+
+static int cpuacct_populate(struct cgroup_subsys *ss, struct cgroup *cont)
+{
+       return cgroup_add_files(cont, ss, files, ARRAY_SIZE(files));
+}
+
+void cpuacct_charge(struct task_struct *task, cputime_t cputime)
+{
+
+       struct cpuacct *ca;
+       unsigned long flags;
+
+       if (!cpuacct_subsys.active)
+               return;
+       rcu_read_lock();
+       ca = task_ca(task);
+       if (ca) {
+               spin_lock_irqsave(&ca->lock, flags);
+               cpuusage_update(ca);
+               ca->time = cputime64_add(ca->time, cputime);
+               ca->current_interval_time =
+                       cputime64_add(ca->current_interval_time, cputime);
+               spin_unlock_irqrestore(&ca->lock, flags);
+       }
+       rcu_read_unlock();
+}
+
+struct cgroup_subsys cpuacct_subsys = {
+       .name = "cpuacct",
+       .create = cpuacct_create,
+       .destroy = cpuacct_destroy,
+       .populate = cpuacct_populate,
+       .subsys_id = cpuacct_subsys_id,
+};
index 2eb2e50db0d6a7c1c93915116ee9d8e125ad2981..50f5dc46368841de3497fe96534df12b871e530b 100644 (file)
@@ -4,7 +4,8 @@
  *  Processor and Memory placement constraints for sets of tasks.
  *
  *  Copyright (C) 2003 BULL SA.
- *  Copyright (C) 2004-2006 Silicon Graphics, Inc.
+ *  Copyright (C) 2004-2007 Silicon Graphics, Inc.
+ *  Copyright (C) 2006 Google, Inc
  *
  *  Portions derived from Patrick Mochel's sysfs code.
  *  sysfs is Copyright (c) 2001-3 Patrick Mochel
@@ -12,6 +13,7 @@
  *  2003-10-10 Written by Simon Derr.
  *  2003-10-22 Updates by Stephen Hemminger.
  *  2004 May-July Rework by Paul Jackson.
+ *  2006 Rework by Paul Menage to use generic cgroups
  *
  *  This file is subject to the terms and conditions of the GNU General Public
  *  License.  See the file COPYING in the main directory of the Linux
@@ -36,6 +38,7 @@
 #include <linux/mount.h>
 #include <linux/namei.h>
 #include <linux/pagemap.h>
+#include <linux/prio_heap.h>
 #include <linux/proc_fs.h>
 #include <linux/rcupdate.h>
 #include <linux/sched.h>
@@ -52,8 +55,7 @@
 #include <asm/uaccess.h>
 #include <asm/atomic.h>
 #include <linux/mutex.h>
-
-#define CPUSET_SUPER_MAGIC             0x27e0eb
+#include <linux/kfifo.h>
 
 /*
  * Tracks how many cpusets are currently defined in system.
  */
 int number_of_cpusets __read_mostly;
 
+/* Retrieve the cpuset from a cgroup */
+struct cgroup_subsys cpuset_subsys;
+struct cpuset;
+
 /* See "Frequency meter" comments, below. */
 
 struct fmeter {
@@ -72,24 +78,13 @@ struct fmeter {
 };
 
 struct cpuset {
+       struct cgroup_subsys_state css;
+
        unsigned long flags;            /* "unsigned long" so bitops work */
        cpumask_t cpus_allowed;         /* CPUs allowed to tasks in cpuset */
        nodemask_t mems_allowed;        /* Memory Nodes allowed to tasks */
 
-       /*
-        * Count is atomic so can incr (fork) or decr (exit) without a lock.
-        */
-       atomic_t count;                 /* count tasks using this cpuset */
-
-       /*
-        * We link our 'sibling' struct into our parents 'children'.
-        * Our children link their 'sibling' into our 'children'.
-        */
-       struct list_head sibling;       /* my parents children */
-       struct list_head children;      /* my children */
-
        struct cpuset *parent;          /* my parent */
-       struct dentry *dentry;          /* cpuset fs entry */
 
        /*
         * Copy of global cpuset_mems_generation as of the most
@@ -98,15 +93,32 @@ struct cpuset {
        int mems_generation;
 
        struct fmeter fmeter;           /* memory_pressure filter */
+
+       /* partition number for rebuild_sched_domains() */
+       int pn;
 };
 
+/* Retrieve the cpuset for a cgroup */
+static inline struct cpuset *cgroup_cs(struct cgroup *cont)
+{
+       return container_of(cgroup_subsys_state(cont, cpuset_subsys_id),
+                           struct cpuset, css);
+}
+
+/* Retrieve the cpuset for a task */
+static inline struct cpuset *task_cs(struct task_struct *task)
+{
+       return container_of(task_subsys_state(task, cpuset_subsys_id),
+                           struct cpuset, css);
+}
+
+
 /* bits in struct cpuset flags field */
 typedef enum {
        CS_CPU_EXCLUSIVE,
        CS_MEM_EXCLUSIVE,
        CS_MEMORY_MIGRATE,
-       CS_REMOVED,
-       CS_NOTIFY_ON_RELEASE,
+       CS_SCHED_LOAD_BALANCE,
        CS_SPREAD_PAGE,
        CS_SPREAD_SLAB,
 } cpuset_flagbits_t;
@@ -122,14 +134,9 @@ static inline int is_mem_exclusive(const struct cpuset *cs)
        return test_bit(CS_MEM_EXCLUSIVE, &cs->flags);
 }
 
-static inline int is_removed(const struct cpuset *cs)
+static inline int is_sched_load_balance(const struct cpuset *cs)
 {
-       return test_bit(CS_REMOVED, &cs->flags);
-}
-
-static inline int notify_on_release(const struct cpuset *cs)
-{
-       return test_bit(CS_NOTIFY_ON_RELEASE, &cs->flags);
+       return test_bit(CS_SCHED_LOAD_BALANCE, &cs->flags);
 }
 
 static inline int is_memory_migrate(const struct cpuset *cs)
@@ -172,14 +179,8 @@ static struct cpuset top_cpuset = {
        .flags = ((1 << CS_CPU_EXCLUSIVE) | (1 << CS_MEM_EXCLUSIVE)),
        .cpus_allowed = CPU_MASK_ALL,
        .mems_allowed = NODE_MASK_ALL,
-       .count = ATOMIC_INIT(0),
-       .sibling = LIST_HEAD_INIT(top_cpuset.sibling),
-       .children = LIST_HEAD_INIT(top_cpuset.children),
 };
 
-static struct vfsmount *cpuset_mount;
-static struct super_block *cpuset_sb;
-
 /*
  * We have two global cpuset mutexes below.  They can nest.
  * It is ok to first take manage_mutex, then nest callback_mutex.  We also
@@ -263,297 +264,33 @@ static struct super_block *cpuset_sb;
  * the routine cpuset_update_task_memory_state().
  */
 
-static DEFINE_MUTEX(manage_mutex);
 static DEFINE_MUTEX(callback_mutex);
 
-/*
- * A couple of forward declarations required, due to cyclic reference loop:
- *  cpuset_mkdir -> cpuset_create -> cpuset_populate_dir -> cpuset_add_file
- *  -> cpuset_create_file -> cpuset_dir_inode_operations -> cpuset_mkdir.
- */
-
-static int cpuset_mkdir(struct inode *dir, struct dentry *dentry, int mode);
-static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry);
-
-static struct backing_dev_info cpuset_backing_dev_info = {
-       .ra_pages = 0,          /* No readahead */
-       .capabilities   = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
-};
-
-static struct inode *cpuset_new_inode(mode_t mode)
-{
-       struct inode *inode = new_inode(cpuset_sb);
-
-       if (inode) {
-               inode->i_mode = mode;
-               inode->i_uid = current->fsuid;
-               inode->i_gid = current->fsgid;
-               inode->i_blocks = 0;
-               inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-               inode->i_mapping->backing_dev_info = &cpuset_backing_dev_info;
-       }
-       return inode;
-}
-
-static void cpuset_diput(struct dentry *dentry, struct inode *inode)
-{
-       /* is dentry a directory ? if so, kfree() associated cpuset */
-       if (S_ISDIR(inode->i_mode)) {
-               struct cpuset *cs = dentry->d_fsdata;
-               BUG_ON(!(is_removed(cs)));
-               kfree(cs);
-       }
-       iput(inode);
-}
-
-static struct dentry_operations cpuset_dops = {
-       .d_iput = cpuset_diput,
-};
-
-static struct dentry *cpuset_get_dentry(struct dentry *parent, const char *name)
-{
-       struct dentry *d = lookup_one_len(name, parent, strlen(name));
-       if (!IS_ERR(d))
-               d->d_op = &cpuset_dops;
-       return d;
-}
-
-static void remove_dir(struct dentry *d)
-{
-       struct dentry *parent = dget(d->d_parent);
-
-       d_delete(d);
-       simple_rmdir(parent->d_inode, d);
-       dput(parent);
-}
-
-/*
- * NOTE : the dentry must have been dget()'ed
- */
-static void cpuset_d_remove_dir(struct dentry *dentry)
-{
-       struct list_head *node;
-
-       spin_lock(&dcache_lock);
-       node = dentry->d_subdirs.next;
-       while (node != &dentry->d_subdirs) {
-               struct dentry *d = list_entry(node, struct dentry, d_u.d_child);
-               list_del_init(node);
-               if (d->d_inode) {
-                       d = dget_locked(d);
-                       spin_unlock(&dcache_lock);
-                       d_delete(d);
-                       simple_unlink(dentry->d_inode, d);
-                       dput(d);
-                       spin_lock(&dcache_lock);
-               }
-               node = dentry->d_subdirs.next;
-       }
-       list_del_init(&dentry->d_u.d_child);
-       spin_unlock(&dcache_lock);
-       remove_dir(dentry);
-}
-
-static struct super_operations cpuset_ops = {
-       .statfs = simple_statfs,
-       .drop_inode = generic_delete_inode,
-};
-
-static int cpuset_fill_super(struct super_block *sb, void *unused_data,
-                                                       int unused_silent)
-{
-       struct inode *inode;
-       struct dentry *root;
-
-       sb->s_blocksize = PAGE_CACHE_SIZE;
-       sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
-       sb->s_magic = CPUSET_SUPER_MAGIC;
-       sb->s_op = &cpuset_ops;
-       cpuset_sb = sb;
-
-       inode = cpuset_new_inode(S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR);
-       if (inode) {
-               inode->i_op = &simple_dir_inode_operations;
-               inode->i_fop = &simple_dir_operations;
-               /* directories start off with i_nlink == 2 (for "." entry) */
-               inc_nlink(inode);
-       } else {
-               return -ENOMEM;
-       }
-
-       root = d_alloc_root(inode);
-       if (!root) {
-               iput(inode);
-               return -ENOMEM;
-       }
-       sb->s_root = root;
-       return 0;
-}
-
+/* This is ugly, but preserves the userspace API for existing cpuset
+ * users. If someone tries to mount the "cpuset" filesystem, we
+ * silently switch it to mount "cgroup" instead */
 static int cpuset_get_sb(struct file_system_type *fs_type,
                         int flags, const char *unused_dev_name,
                         void *data, struct vfsmount *mnt)
 {
-       return get_sb_single(fs_type, flags, data, cpuset_fill_super, mnt);
+       struct file_system_type *cgroup_fs = get_fs_type("cgroup");
+       int ret = -ENODEV;
+       if (cgroup_fs) {
+               char mountopts[] =
+                       "cpuset,noprefix,"
+                       "release_agent=/sbin/cpuset_release_agent";
+               ret = cgroup_fs->get_sb(cgroup_fs, flags,
+                                          unused_dev_name, mountopts, mnt);
+               put_filesystem(cgroup_fs);
+       }
+       return ret;
 }
 
 static struct file_system_type cpuset_fs_type = {
        .name = "cpuset",
        .get_sb = cpuset_get_sb,
-       .kill_sb = kill_litter_super,
 };
 
-/* struct cftype:
- *
- * The files in the cpuset filesystem mostly have a very simple read/write
- * handling, some common function will take care of it. Nevertheless some cases
- * (read tasks) are special and therefore I define this structure for every
- * kind of file.
- *
- *
- * When reading/writing to a file:
- *     - the cpuset to use in file->f_path.dentry->d_parent->d_fsdata
- *     - the 'cftype' of the file is file->f_path.dentry->d_fsdata
- */
-
-struct cftype {
-       char *name;
-       int private;
-       int (*open) (struct inode *inode, struct file *file);
-       ssize_t (*read) (struct file *file, char __user *buf, size_t nbytes,
-                                                       loff_t *ppos);
-       int (*write) (struct file *file, const char __user *buf, size_t nbytes,
-                                                       loff_t *ppos);
-       int (*release) (struct inode *inode, struct file *file);
-};
-
-static inline struct cpuset *__d_cs(struct dentry *dentry)
-{
-       return dentry->d_fsdata;
-}
-
-static inline struct cftype *__d_cft(struct dentry *dentry)
-{
-       return dentry->d_fsdata;
-}
-
-/*
- * Call with manage_mutex held.  Writes path of cpuset into buf.
- * Returns 0 on success, -errno on error.
- */
-
-static int cpuset_path(const struct cpuset *cs, char *buf, int buflen)
-{
-       char *start;
-
-       start = buf + buflen;
-
-       *--start = '\0';
-       for (;;) {
-               int len = cs->dentry->d_name.len;
-               if ((start -= len) < buf)
-                       return -ENAMETOOLONG;
-               memcpy(start, cs->dentry->d_name.name, len);
-               cs = cs->parent;
-               if (!cs)
-                       break;
-               if (!cs->parent)
-                       continue;
-               if (--start < buf)
-                       return -ENAMETOOLONG;
-               *start = '/';
-       }
-       memmove(buf, start, buf + buflen - start);
-       return 0;
-}
-
-/*
- * Notify userspace when a cpuset is released, by running
- * /sbin/cpuset_release_agent with the name of the cpuset (path
- * relative to the root of cpuset file system) as the argument.
- *
- * Most likely, this user command will try to rmdir this cpuset.
- *
- * This races with the possibility that some other task will be
- * attached to this cpuset before it is removed, or that some other
- * user task will 'mkdir' a child cpuset of this cpuset.  That's ok.
- * The presumed 'rmdir' will fail quietly if this cpuset is no longer
- * unused, and this cpuset will be reprieved from its death sentence,
- * to continue to serve a useful existence.  Next time it's released,
- * we will get notified again, if it still has 'notify_on_release' set.
- *
- * The final arg to call_usermodehelper() is 0, which means don't
- * wait.  The separate /sbin/cpuset_release_agent task is forked by
- * call_usermodehelper(), then control in this thread returns here,
- * without waiting for the release agent task.  We don't bother to
- * wait because the caller of this routine has no use for the exit
- * status of the /sbin/cpuset_release_agent task, so no sense holding
- * our caller up for that.
- *
- * When we had only one cpuset mutex, we had to call this
- * without holding it, to avoid deadlock when call_usermodehelper()
- * allocated memory.  With two locks, we could now call this while
- * holding manage_mutex, but we still don't, so as to minimize
- * the time manage_mutex is held.
- */
-
-static void cpuset_release_agent(const char *pathbuf)
-{
-       char *argv[3], *envp[3];
-       int i;
-
-       if (!pathbuf)
-               return;
-
-       i = 0;
-       argv[i++] = "/sbin/cpuset_release_agent";
-       argv[i++] = (char *)pathbuf;
-       argv[i] = NULL;
-
-       i = 0;
-       /* minimal command environment */
-       envp[i++] = "HOME=/";
-       envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
-       envp[i] = NULL;
-
-       call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
-       kfree(pathbuf);
-}
-
-/*
- * Either cs->count of using tasks transitioned to zero, or the
- * cs->children list of child cpusets just became empty.  If this
- * cs is notify_on_release() and now both the user count is zero and
- * the list of children is empty, prepare cpuset path in a kmalloc'd
- * buffer, to be returned via ppathbuf, so that the caller can invoke
- * cpuset_release_agent() with it later on, once manage_mutex is dropped.
- * Call here with manage_mutex held.
- *
- * This check_for_release() routine is responsible for kmalloc'ing
- * pathbuf.  The above cpuset_release_agent() is responsible for
- * kfree'ing pathbuf.  The caller of these routines is responsible
- * for providing a pathbuf pointer, initialized to NULL, then
- * calling check_for_release() with manage_mutex held and the address
- * of the pathbuf pointer, then dropping manage_mutex, then calling
- * cpuset_release_agent() with pathbuf, as set by check_for_release().
- */
-
-static void check_for_release(struct cpuset *cs, char **ppathbuf)
-{
-       if (notify_on_release(cs) && atomic_read(&cs->count) == 0 &&
-           list_empty(&cs->children)) {
-               char *buf;
-
-               buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
-               if (!buf)
-                       return;
-               if (cpuset_path(cs, buf, PAGE_SIZE) < 0)
-                       kfree(buf);
-               else
-                       *ppathbuf = buf;
-       }
-}
-
 /*
  * Return in *pmask the portion of a cpusets's cpus_allowed that
  * are online.  If none are online, walk up the cpuset hierarchy
@@ -653,20 +390,19 @@ void cpuset_update_task_memory_state(void)
        struct task_struct *tsk = current;
        struct cpuset *cs;
 
-       if (tsk->cpuset == &top_cpuset) {
+       if (task_cs(tsk) == &top_cpuset) {
                /* Don't need rcu for top_cpuset.  It's never freed. */
                my_cpusets_mem_gen = top_cpuset.mems_generation;
        } else {
                rcu_read_lock();
-               cs = rcu_dereference(tsk->cpuset);
-               my_cpusets_mem_gen = cs->mems_generation;
+               my_cpusets_mem_gen = task_cs(current)->mems_generation;
                rcu_read_unlock();
        }
 
        if (my_cpusets_mem_gen != tsk->cpuset_mems_generation) {
                mutex_lock(&callback_mutex);
                task_lock(tsk);
-               cs = tsk->cpuset;       /* Maybe changed when task not locked */
+               cs = task_cs(tsk); /* Maybe changed when task not locked */
                guarantee_online_mems(cs, &tsk->mems_allowed);
                tsk->cpuset_mems_generation = cs->mems_generation;
                if (is_spread_page(cs))
@@ -721,11 +457,12 @@ static int is_cpuset_subset(const struct cpuset *p, const struct cpuset *q)
 
 static int validate_change(const struct cpuset *cur, const struct cpuset *trial)
 {
+       struct cgroup *cont;
        struct cpuset *c, *par;
 
        /* Each of our child cpusets must be a subset of us */
-       list_for_each_entry(c, &cur->children, sibling) {
-               if (!is_cpuset_subset(c, trial))
+       list_for_each_entry(cont, &cur->css.cgroup->children, sibling) {
+               if (!is_cpuset_subset(cgroup_cs(cont), trial))
                        return -EBUSY;
        }
 
@@ -740,7 +477,8 @@ static int validate_change(const struct cpuset *cur, const struct cpuset *trial)
                return -EACCES;
 
        /* If either I or some sibling (!= me) is exclusive, we can't overlap */
-       list_for_each_entry(c, &par->children, sibling) {
+       list_for_each_entry(cont, &par->css.cgroup->children, sibling) {
+               c = cgroup_cs(cont);
                if ((is_cpu_exclusive(trial) || is_cpu_exclusive(c)) &&
                    c != cur &&
                    cpus_intersects(trial->cpus_allowed, c->cpus_allowed))
@@ -751,9 +489,249 @@ static int validate_change(const struct cpuset *cur, const struct cpuset *trial)
                        return -EINVAL;
        }
 
+       /* Cpusets with tasks can't have empty cpus_allowed or mems_allowed */
+       if (cgroup_task_count(cur->css.cgroup)) {
+               if (cpus_empty(trial->cpus_allowed) ||
+                   nodes_empty(trial->mems_allowed)) {
+                       return -ENOSPC;
+               }
+       }
+
        return 0;
 }
 
+/*
+ * Helper routine for rebuild_sched_domains().
+ * Do cpusets a, b have overlapping cpus_allowed masks?
+ */
+
+static int cpusets_overlap(struct cpuset *a, struct cpuset *b)
+{
+       return cpus_intersects(a->cpus_allowed, b->cpus_allowed);
+}
+
+/*
+ * rebuild_sched_domains()
+ *
+ * If the flag 'sched_load_balance' of any cpuset with non-empty
+ * 'cpus' changes, or if the 'cpus' allowed changes in any cpuset
+ * which has that flag enabled, or if any cpuset with a non-empty
+ * 'cpus' is removed, then call this routine to rebuild the
+ * scheduler's dynamic sched domains.
+ *
+ * This routine builds a partial partition of the systems CPUs
+ * (the set of non-overlappping cpumask_t's in the array 'part'
+ * below), and passes that partial partition to the kernel/sched.c
+ * partition_sched_domains() routine, which will rebuild the
+ * schedulers load balancing domains (sched domains) as specified
+ * by that partial partition.  A 'partial partition' is a set of
+ * non-overlapping subsets whose union is a subset of that set.
+ *
+ * See "What is sched_load_balance" in Documentation/cpusets.txt
+ * for a background explanation of this.
+ *
+ * Does not return errors, on the theory that the callers of this
+ * routine would rather not worry about failures to rebuild sched
+ * domains when operating in the severe memory shortage situations
+ * that could cause allocation failures below.
+ *
+ * Call with cgroup_mutex held.  May take callback_mutex during
+ * call due to the kfifo_alloc() and kmalloc() calls.  May nest
+ * a call to the lock_cpu_hotplug()/unlock_cpu_hotplug() pair.
+ * Must not be called holding callback_mutex, because we must not
+ * call lock_cpu_hotplug() while holding callback_mutex.  Elsewhere
+ * the kernel nests callback_mutex inside lock_cpu_hotplug() calls.
+ * So the reverse nesting would risk an ABBA deadlock.
+ *
+ * The three key local variables below are:
+ *    q  - a kfifo queue of cpuset pointers, used to implement a
+ *        top-down scan of all cpusets.  This scan loads a pointer
+ *        to each cpuset marked is_sched_load_balance into the
+ *        array 'csa'.  For our purposes, rebuilding the schedulers
+ *        sched domains, we can ignore !is_sched_load_balance cpusets.
+ *  csa  - (for CpuSet Array) Array of pointers to all the cpusets
+ *        that need to be load balanced, for convenient iterative
+ *        access by the subsequent code that finds the best partition,
+ *        i.e the set of domains (subsets) of CPUs such that the
+ *        cpus_allowed of every cpuset marked is_sched_load_balance
+ *        is a subset of one of these domains, while there are as
+ *        many such domains as possible, each as small as possible.
+ * doms  - Conversion of 'csa' to an array of cpumasks, for passing to
+ *        the kernel/sched.c routine partition_sched_domains() in a
+ *        convenient format, that can be easily compared to the prior
+ *        value to determine what partition elements (sched domains)
+ *        were changed (added or removed.)
+ *
+ * Finding the best partition (set of domains):
+ *     The triple nested loops below over i, j, k scan over the
+ *     load balanced cpusets (using the array of cpuset pointers in
+ *     csa[]) looking for pairs of cpusets that have overlapping
+ *     cpus_allowed, but which don't have the same 'pn' partition
+ *     number and gives them in the same partition number.  It keeps
+ *     looping on the 'restart' label until it can no longer find
+ *     any such pairs.
+ *
+ *     The union of the cpus_allowed masks from the set of
+ *     all cpusets having the same 'pn' value then form the one
+ *     element of the partition (one sched domain) to be passed to
+ *     partition_sched_domains().
+ */
+
+static void rebuild_sched_domains(void)
+{
+       struct kfifo *q;        /* queue of cpusets to be scanned */
+       struct cpuset *cp;      /* scans q */
+       struct cpuset **csa;    /* array of all cpuset ptrs */
+       int csn;                /* how many cpuset ptrs in csa so far */
+       int i, j, k;            /* indices for partition finding loops */
+       cpumask_t *doms;        /* resulting partition; i.e. sched domains */
+       int ndoms;              /* number of sched domains in result */
+       int nslot;              /* next empty doms[] cpumask_t slot */
+
+       q = NULL;
+       csa = NULL;
+       doms = NULL;
+
+       /* Special case for the 99% of systems with one, full, sched domain */
+       if (is_sched_load_balance(&top_cpuset)) {
+               ndoms = 1;
+               doms = kmalloc(sizeof(cpumask_t), GFP_KERNEL);
+               if (!doms)
+                       goto rebuild;
+               *doms = top_cpuset.cpus_allowed;
+               goto rebuild;
+       }
+
+       q = kfifo_alloc(number_of_cpusets * sizeof(cp), GFP_KERNEL, NULL);
+       if (IS_ERR(q))
+               goto done;
+       csa = kmalloc(number_of_cpusets * sizeof(cp), GFP_KERNEL);
+       if (!csa)
+               goto done;
+       csn = 0;
+
+       cp = &top_cpuset;
+       __kfifo_put(q, (void *)&cp, sizeof(cp));
+       while (__kfifo_get(q, (void *)&cp, sizeof(cp))) {
+               struct cgroup *cont;
+               struct cpuset *child;   /* scans child cpusets of cp */
+               if (is_sched_load_balance(cp))
+                       csa[csn++] = cp;
+               list_for_each_entry(cont, &cp->css.cgroup->children, sibling) {
+                       child = cgroup_cs(cont);
+                       __kfifo_put(q, (void *)&child, sizeof(cp));
+               }
+       }
+
+       for (i = 0; i < csn; i++)
+               csa[i]->pn = i;
+       ndoms = csn;
+
+restart:
+       /* Find the best partition (set of sched domains) */
+       for (i = 0; i < csn; i++) {
+               struct cpuset *a = csa[i];
+               int apn = a->pn;
+
+               for (j = 0; j < csn; j++) {
+                       struct cpuset *b = csa[j];
+                       int bpn = b->pn;
+
+                       if (apn != bpn && cpusets_overlap(a, b)) {
+                               for (k = 0; k < csn; k++) {
+                                       struct cpuset *c = csa[k];
+
+                                       if (c->pn == bpn)
+                                               c->pn = apn;
+                               }
+                               ndoms--;        /* one less element */
+                               goto restart;
+                       }
+               }
+       }
+
+       /* Convert <csn, csa> to <ndoms, doms> */
+       doms = kmalloc(ndoms * sizeof(cpumask_t), GFP_KERNEL);
+       if (!doms)
+               goto rebuild;
+
+       for (nslot = 0, i = 0; i < csn; i++) {
+               struct cpuset *a = csa[i];
+               int apn = a->pn;
+
+               if (apn >= 0) {
+                       cpumask_t *dp = doms + nslot;
+
+                       if (nslot == ndoms) {
+                               static int warnings = 10;
+                               if (warnings) {
+                                       printk(KERN_WARNING
+                                        "rebuild_sched_domains confused:"
+                                         " nslot %d, ndoms %d, csn %d, i %d,"
+                                         " apn %d\n",
+                                         nslot, ndoms, csn, i, apn);
+                                       warnings--;
+                               }
+                               continue;
+                       }
+
+                       cpus_clear(*dp);
+                       for (j = i; j < csn; j++) {
+                               struct cpuset *b = csa[j];
+
+                               if (apn == b->pn) {
+                                       cpus_or(*dp, *dp, b->cpus_allowed);
+                                       b->pn = -1;
+                               }
+                       }
+                       nslot++;
+               }
+       }
+       BUG_ON(nslot != ndoms);
+
+rebuild:
+       /* Have scheduler rebuild sched domains */
+       lock_cpu_hotplug();
+       partition_sched_domains(ndoms, doms);
+       unlock_cpu_hotplug();
+
+done:
+       if (q && !IS_ERR(q))
+               kfifo_free(q);
+       kfree(csa);
+       /* Don't kfree(doms) -- partition_sched_domains() does that. */
+}
+
+static inline int started_after_time(struct task_struct *t1,
+                                    struct timespec *time,
+                                    struct task_struct *t2)
+{
+       int start_diff = timespec_compare(&t1->start_time, time);
+       if (start_diff > 0) {
+               return 1;
+       } else if (start_diff < 0) {
+               return 0;
+       } else {
+               /*
+                * Arbitrarily, if two processes started at the same
+                * time, we'll say that the lower pointer value
+                * started first. Note that t2 may have exited by now
+                * so this may not be a valid pointer any longer, but
+                * that's fine - it still serves to distinguish
+                * between two tasks started (effectively)
+                * simultaneously.
+                */
+               return t1 > t2;
+       }
+}
+
+static inline int started_after(void *p1, void *p2)
+{
+       struct task_struct *t1 = p1;
+       struct task_struct *t2 = p2;
+       return started_after_time(t1, &t2->start_time, t2);
+}
+
 /*
  * Call with manage_mutex held.  May take callback_mutex during call.
  */
@@ -761,7 +739,15 @@ static int validate_change(const struct cpuset *cur, const struct cpuset *trial)
 static int update_cpumask(struct cpuset *cs, char *buf)
 {
        struct cpuset trialcs;
-       int retval;
+       int retval, i;
+       int is_load_balanced;
+       struct cgroup_iter it;
+       struct cgroup *cgrp = cs->css.cgroup;
+       struct task_struct *p, *dropped;
+       /* Never dereference latest_task, since it's not refcounted */
+       struct task_struct *latest_task = NULL;
+       struct ptr_heap heap;
+       struct timespec latest_time = { 0, 0 };
 
        /* top_cpuset.cpus_allowed tracks cpu_online_map; it's read-only */
        if (cs == &top_cpuset)
@@ -770,11 +756,13 @@ static int update_cpumask(struct cpuset *cs, char *buf)
        trialcs = *cs;
 
        /*
-        * We allow a cpuset's cpus_allowed to be empty; if it has attached
-        * tasks, we'll catch it later when we validate the change and return
-        * -ENOSPC.
+        * An empty cpus_allowed is ok iff there are no tasks in the cpuset.
+        * Since cpulist_parse() fails on an empty mask, we special case
+        * that parsing.  The validate_change() call ensures that cpusets
+        * with tasks have cpus.
         */
-       if (!buf[0] || (buf[0] == '\n' && !buf[1])) {
+       buf = strstrip(buf);
+       if (!*buf) {
                cpus_clear(trialcs.cpus_allowed);
        } else {
                retval = cpulist_parse(buf, trialcs.cpus_allowed);
@@ -782,15 +770,79 @@ static int update_cpumask(struct cpuset *cs, char *buf)
                        return retval;
        }
        cpus_and(trialcs.cpus_allowed, trialcs.cpus_allowed, cpu_online_map);
-       /* cpus_allowed cannot be empty for a cpuset with attached tasks. */
-       if (atomic_read(&cs->count) && cpus_empty(trialcs.cpus_allowed))
-               return -ENOSPC;
        retval = validate_change(cs, &trialcs);
        if (retval < 0)
                return retval;
+
+       /* Nothing to do if the cpus didn't change */
+       if (cpus_equal(cs->cpus_allowed, trialcs.cpus_allowed))
+               return 0;
+       retval = heap_init(&heap, PAGE_SIZE, GFP_KERNEL, &started_after);
+       if (retval)
+               return retval;
+
+       is_load_balanced = is_sched_load_balance(&trialcs);
+
        mutex_lock(&callback_mutex);
        cs->cpus_allowed = trialcs.cpus_allowed;
        mutex_unlock(&callback_mutex);
+
+ again:
+       /*
+        * Scan tasks in the cpuset, and update the cpumasks of any
+        * that need an update. Since we can't call set_cpus_allowed()
+        * while holding tasklist_lock, gather tasks to be processed
+        * in a heap structure. If the statically-sized heap fills up,
+        * overflow tasks that started later, and in future iterations
+        * only consider tasks that started after the latest task in
+        * the previous pass. This guarantees forward progress and
+        * that we don't miss any tasks
+        */
+       heap.size = 0;
+       cgroup_iter_start(cgrp, &it);
+       while ((p = cgroup_iter_next(cgrp, &it))) {
+               /* Only affect tasks that don't have the right cpus_allowed */
+               if (cpus_equal(p->cpus_allowed, cs->cpus_allowed))
+                       continue;
+               /*
+                * Only process tasks that started after the last task
+                * we processed
+                */
+               if (!started_after_time(p, &latest_time, latest_task))
+                       continue;
+               dropped = heap_insert(&heap, p);
+               if (dropped == NULL) {
+                       get_task_struct(p);
+               } else if (dropped != p) {
+                       get_task_struct(p);
+                       put_task_struct(dropped);
+               }
+       }
+       cgroup_iter_end(cgrp, &it);
+       if (heap.size) {
+               for (i = 0; i < heap.size; i++) {
+                       struct task_struct *p = heap.ptrs[i];
+                       if (i == 0) {
+                               latest_time = p->start_time;
+                               latest_task = p;
+                       }
+                       set_cpus_allowed(p, cs->cpus_allowed);
+                       put_task_struct(p);
+               }
+               /*
+                * If we had to process any tasks at all, scan again
+                * in case some of them were in the middle of forking
+                * children that didn't notice the new cpumask
+                * restriction.  Not the most efficient way to do it,
+                * but it avoids having to take callback_mutex in the
+                * fork path
+                */
+               goto again;
+       }
+       heap_free(&heap);
+       if (is_load_balanced)
+               rebuild_sched_domains();
+
        return 0;
 }
 
@@ -839,7 +891,7 @@ static void cpuset_migrate_mm(struct mm_struct *mm, const nodemask_t *from,
        do_migrate_pages(mm, from, to, MPOL_MF_MOVE_ALL);
 
        mutex_lock(&callback_mutex);
-       guarantee_online_mems(tsk->cpuset, &tsk->mems_allowed);
+       guarantee_online_mems(task_cs(tsk),&tsk->mems_allowed);
        mutex_unlock(&callback_mutex);
 }
 
@@ -857,16 +909,19 @@ static void cpuset_migrate_mm(struct mm_struct *mm, const nodemask_t *from,
  * their mempolicies to the cpusets new mems_allowed.
  */
 
+static void *cpuset_being_rebound;
+
 static int update_nodemask(struct cpuset *cs, char *buf)
 {
        struct cpuset trialcs;
        nodemask_t oldmem;
-       struct task_struct *g, *p;
+       struct task_struct *p;
        struct mm_struct **mmarray;
        int i, n, ntasks;
        int migrate;
        int fudge;
        int retval;
+       struct cgroup_iter it;
 
        /*
         * top_cpuset.mems_allowed tracks node_stats[N_HIGH_MEMORY];
@@ -878,29 +933,19 @@ static int update_nodemask(struct cpuset *cs, char *buf)
        trialcs = *cs;
 
        /*
-        * We allow a cpuset's mems_allowed to be empty; if it has attached
-        * tasks, we'll catch it later when we validate the change and return
-        * -ENOSPC.
+        * An empty mems_allowed is ok iff there are no tasks in the cpuset.
+        * Since nodelist_parse() fails on an empty mask, we special case
+        * that parsing.  The validate_change() call ensures that cpusets
+        * with tasks have memory.
         */
-       if (!buf[0] || (buf[0] == '\n' && !buf[1])) {
+       buf = strstrip(buf);
+       if (!*buf) {
                nodes_clear(trialcs.mems_allowed);
        } else {
                retval = nodelist_parse(buf, trialcs.mems_allowed);
                if (retval < 0)
                        goto done;
-               if (!nodes_intersects(trialcs.mems_allowed,
-                                               node_states[N_HIGH_MEMORY])) {
-                       /*
-                        * error if only memoryless nodes specified.
-                        */
-                       retval = -ENOSPC;
-                       goto done;
-               }
        }
-       /*
-        * Exclude memoryless nodes.  We know that trialcs.mems_allowed
-        * contains at least one node with memory.
-        */
        nodes_and(trialcs.mems_allowed, trialcs.mems_allowed,
                                                node_states[N_HIGH_MEMORY]);
        oldmem = cs->mems_allowed;
@@ -908,11 +953,6 @@ static int update_nodemask(struct cpuset *cs, char *buf)
                retval = 0;             /* Too easy - nothing to do */
                goto done;
        }
-       /* mems_allowed cannot be empty for a cpuset with attached tasks. */
-       if (atomic_read(&cs->count) && nodes_empty(trialcs.mems_allowed)) {
-               retval = -ENOSPC;
-               goto done;
-       }
        retval = validate_change(cs, &trialcs);
        if (retval < 0)
                goto done;
@@ -922,7 +962,7 @@ static int update_nodemask(struct cpuset *cs, char *buf)
        cs->mems_generation = cpuset_mems_generation++;
        mutex_unlock(&callback_mutex);
 
-       set_cpuset_being_rebound(cs);           /* causes mpol_copy() rebind */
+       cpuset_being_rebound = cs;              /* causes mpol_copy() rebind */
 
        fudge = 10;                             /* spare mmarray[] slots */
        fudge += cpus_weight(cs->cpus_allowed); /* imagine one fork-bomb/cpu */
@@ -936,13 +976,13 @@ static int update_nodemask(struct cpuset *cs, char *buf)
         * enough mmarray[] w/o using GFP_ATOMIC.
         */
        while (1) {
-               ntasks = atomic_read(&cs->count);       /* guess */
+               ntasks = cgroup_task_count(cs->css.cgroup);  /* guess */
                ntasks += fudge;
                mmarray = kmalloc(ntasks * sizeof(*mmarray), GFP_KERNEL);
                if (!mmarray)
                        goto done;
                read_lock(&tasklist_lock);              /* block fork */
-               if (atomic_read(&cs->count) <= ntasks)
+               if (cgroup_task_count(cs->css.cgroup) <= ntasks)
                        break;                          /* got enough */
                read_unlock(&tasklist_lock);            /* try again */
                kfree(mmarray);
@@ -951,21 +991,21 @@ static int update_nodemask(struct cpuset *cs, char *buf)
        n = 0;
 
        /* Load up mmarray[] with mm reference for each task in cpuset. */
-       do_each_thread(g, p) {
+       cgroup_iter_start(cs->css.cgroup, &it);
+       while ((p = cgroup_iter_next(cs->css.cgroup, &it))) {
                struct mm_struct *mm;
 
                if (n >= ntasks) {
                        printk(KERN_WARNING
                                "Cpuset mempolicy rebind incomplete.\n");
-                       continue;
+                       break;
                }
-               if (p->cpuset != cs)
-                       continue;
                mm = get_task_mm(p);
                if (!mm)
                        continue;
                mmarray[n++] = mm;
-       } while_each_thread(g, p);
+       }
+       cgroup_iter_end(cs->css.cgroup, &it);
        read_unlock(&tasklist_lock);
 
        /*
@@ -993,12 +1033,17 @@ static int update_nodemask(struct cpuset *cs, char *buf)
 
        /* We're done rebinding vma's to this cpusets new mems_allowed. */
        kfree(mmarray);
-       set_cpuset_being_rebound(NULL);
+       cpuset_being_rebound = NULL;
        retval = 0;
 done:
        return retval;
 }
 
+int current_cpuset_is_being_rebound(void)
+{
+       return task_cs(current) == cpuset_being_rebound;
+}
+
 /*
  * Call with manage_mutex held.
  */
@@ -1015,6 +1060,7 @@ static int update_memory_pressure_enabled(struct cpuset *cs, char *buf)
 /*
  * update_flag - read a 0 or a 1 in a file and update associated flag
  * bit:        the bit to update (CS_CPU_EXCLUSIVE, CS_MEM_EXCLUSIVE,
+ *                             CS_SCHED_LOAD_BALANCE,
  *                             CS_NOTIFY_ON_RELEASE, CS_MEMORY_MIGRATE,
  *                             CS_SPREAD_PAGE, CS_SPREAD_SLAB)
  * cs: the cpuset to update
@@ -1028,6 +1074,7 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, char *buf)
        int turning_on;
        struct cpuset trialcs;
        int err;
+       int cpus_nonempty, balance_flag_changed;
 
        turning_on = (simple_strtoul(buf, NULL, 10) != 0);
 
@@ -1040,10 +1087,18 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, char *buf)
        err = validate_change(cs, &trialcs);
        if (err < 0)
                return err;
+
+       cpus_nonempty = !cpus_empty(trialcs.cpus_allowed);
+       balance_flag_changed = (is_sched_load_balance(cs) !=
+                                       is_sched_load_balance(&trialcs));
+
        mutex_lock(&callback_mutex);
        cs->flags = trialcs.flags;
        mutex_unlock(&callback_mutex);
 
+       if (cpus_nonempty && balance_flag_changed)
+               rebuild_sched_domains();
+
        return 0;
 }
 
@@ -1145,85 +1200,34 @@ static int fmeter_getrate(struct fmeter *fmp)
        return val;
 }
 
-/*
- * Attack task specified by pid in 'pidbuf' to cpuset 'cs', possibly
- * writing the path of the old cpuset in 'ppathbuf' if it needs to be
- * notified on release.
- *
- * Call holding manage_mutex.  May take callback_mutex and task_lock of
- * the task 'pid' during call.
- */
-
-static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
+static int cpuset_can_attach(struct cgroup_subsys *ss,
+                            struct cgroup *cont, struct task_struct *tsk)
 {
-       pid_t pid;
-       struct task_struct *tsk;
-       struct cpuset *oldcs;
-       cpumask_t cpus;
-       nodemask_t from, to;
-       struct mm_struct *mm;
-       int retval;
+       struct cpuset *cs = cgroup_cs(cont);
 
-       if (sscanf(pidbuf, "%d", &pid) != 1)
-               return -EIO;
        if (cpus_empty(cs->cpus_allowed) || nodes_empty(cs->mems_allowed))
                return -ENOSPC;
 
-       if (pid) {
-               read_lock(&tasklist_lock);
-
-               tsk = find_task_by_pid(pid);
-               if (!tsk || tsk->flags & PF_EXITING) {
-                       read_unlock(&tasklist_lock);
-                       return -ESRCH;
-               }
-
-               get_task_struct(tsk);
-               read_unlock(&tasklist_lock);
-
-               if ((current->euid) && (current->euid != tsk->uid)
-                   && (current->euid != tsk->suid)) {
-                       put_task_struct(tsk);
-                       return -EACCES;
-               }
-       } else {
-               tsk = current;
-               get_task_struct(tsk);
-       }
+       return security_task_setscheduler(tsk, 0, NULL);
+}
 
-       retval = security_task_setscheduler(tsk, 0, NULL);
-       if (retval) {
-               put_task_struct(tsk);
-               return retval;
-       }
+static void cpuset_attach(struct cgroup_subsys *ss,
+                         struct cgroup *cont, struct cgroup *oldcont,
+                         struct task_struct *tsk)
+{
+       cpumask_t cpus;
+       nodemask_t from, to;
+       struct mm_struct *mm;
+       struct cpuset *cs = cgroup_cs(cont);
+       struct cpuset *oldcs = cgroup_cs(oldcont);
 
        mutex_lock(&callback_mutex);
-
-       task_lock(tsk);
-       oldcs = tsk->cpuset;
-       /*
-        * After getting 'oldcs' cpuset ptr, be sure still not exiting.
-        * If 'oldcs' might be the top_cpuset due to the_top_cpuset_hack
-        * then fail this attach_task(), to avoid breaking top_cpuset.count.
-        */
-       if (tsk->flags & PF_EXITING) {
-               task_unlock(tsk);
-               mutex_unlock(&callback_mutex);
-               put_task_struct(tsk);
-               return -ESRCH;
-       }
-       atomic_inc(&cs->count);
-       rcu_assign_pointer(tsk->cpuset, cs);
-       task_unlock(tsk);
-
        guarantee_online_cpus(cs, &cpus);
        set_cpus_allowed(tsk, cpus);
+       mutex_unlock(&callback_mutex);
 
        from = oldcs->mems_allowed;
        to = cs->mems_allowed;
-
-       mutex_unlock(&callback_mutex);
-
        mm = get_task_mm(tsk);
        if (mm) {
                mpol_rebind_mm(mm, &to);
@@ -1232,44 +1236,36 @@ static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
                mmput(mm);
        }
 
-       put_task_struct(tsk);
-       synchronize_rcu();
-       if (atomic_dec_and_test(&oldcs->count))
-               check_for_release(oldcs, ppathbuf);
-       return 0;
 }
 
 /* The various types of files and directories in a cpuset file system */
 
 typedef enum {
-       FILE_ROOT,
-       FILE_DIR,
        FILE_MEMORY_MIGRATE,
        FILE_CPULIST,
        FILE_MEMLIST,
        FILE_CPU_EXCLUSIVE,
        FILE_MEM_EXCLUSIVE,
-       FILE_NOTIFY_ON_RELEASE,
+       FILE_SCHED_LOAD_BALANCE,
        FILE_MEMORY_PRESSURE_ENABLED,
        FILE_MEMORY_PRESSURE,
        FILE_SPREAD_PAGE,
        FILE_SPREAD_SLAB,
-       FILE_TASKLIST,
 } cpuset_filetype_t;
 
-static ssize_t cpuset_common_file_write(struct file *file,
+static ssize_t cpuset_common_file_write(struct cgroup *cont,
+                                       struct cftype *cft,
+                                       struct file *file,
                                        const char __user *userbuf,
                                        size_t nbytes, loff_t *unused_ppos)
 {
-       struct cpuset *cs = __d_cs(file->f_path.dentry->d_parent);
-       struct cftype *cft = __d_cft(file->f_path.dentry);
+       struct cpuset *cs = cgroup_cs(cont);
        cpuset_filetype_t type = cft->private;
        char *buffer;
-       char *pathbuf = NULL;
        int retval = 0;
 
        /* Crude upper limit on largest legitimate cpulist user might write. */
-       if (nbytes > 100 + 6 * max(NR_CPUS, MAX_NUMNODES))
+       if (nbytes > 100U + 6 * max(NR_CPUS, MAX_NUMNODES))
                return -E2BIG;
 
        /* +1 for nul-terminator */
@@ -1282,9 +1278,9 @@ static ssize_t cpuset_common_file_write(struct file *file,
        }
        buffer[nbytes] = 0;     /* nul-terminate */
 
-       mutex_lock(&manage_mutex);
+       cgroup_lock();
 
-       if (is_removed(cs)) {
+       if (cgroup_is_removed(cont)) {
                retval = -ENODEV;
                goto out2;
        }
@@ -1302,8 +1298,8 @@ static ssize_t cpuset_common_file_write(struct file *file,
        case FILE_MEM_EXCLUSIVE:
                retval = update_flag(CS_MEM_EXCLUSIVE, cs, buffer);
                break;
-       case FILE_NOTIFY_ON_RELEASE:
-               retval = update_flag(CS_NOTIFY_ON_RELEASE, cs, buffer);
+       case FILE_SCHED_LOAD_BALANCE:
+               retval = update_flag(CS_SCHED_LOAD_BALANCE, cs, buffer);
                break;
        case FILE_MEMORY_MIGRATE:
                retval = update_flag(CS_MEMORY_MIGRATE, cs, buffer);
@@ -1322,9 +1318,6 @@ static ssize_t cpuset_common_file_write(struct file *file,
                retval = update_flag(CS_SPREAD_SLAB, cs, buffer);
                cs->mems_generation = cpuset_mems_generation++;
                break;
-       case FILE_TASKLIST:
-               retval = attach_task(cs, buffer, &pathbuf);
-               break;
        default:
                retval = -EINVAL;
                goto out2;
@@ -1333,30 +1326,12 @@ static ssize_t cpuset_common_file_write(struct file *file,
        if (retval == 0)
                retval = nbytes;
 out2:
-       mutex_unlock(&manage_mutex);
-       cpuset_release_agent(pathbuf);
+       cgroup_unlock();
 out1:
        kfree(buffer);
        return retval;
 }
 
-static ssize_t cpuset_file_write(struct file *file, const char __user *buf,
-                                               size_t nbytes, loff_t *ppos)
-{
-       ssize_t retval = 0;
-       struct cftype *cft = __d_cft(file->f_path.dentry);
-       if (!cft)
-               return -ENODEV;
-
-       /* special function ? */
-       if (cft->write)
-               retval = cft->write(file, buf, nbytes, ppos);
-       else
-               retval = cpuset_common_file_write(file, buf, nbytes, ppos);
-
-       return retval;
-}
-
 /*
  * These ascii lists should be read in a single call, by using a user
  * buffer large enough to hold the entire map.  If read in smaller
@@ -1391,11 +1366,13 @@ static int cpuset_sprintf_memlist(char *page, struct cpuset *cs)
        return nodelist_scnprintf(page, PAGE_SIZE, mask);
 }
 
-static ssize_t cpuset_common_file_read(struct file *file, char __user *buf,
-                               size_t nbytes, loff_t *ppos)
+static ssize_t cpuset_common_file_read(struct cgroup *cont,
+                                      struct cftype *cft,
+                                      struct file *file,
+                                      char __user *buf,
+                                      size_t nbytes, loff_t *ppos)
 {
-       struct cftype *cft = __d_cft(file->f_path.dentry);
-       struct cpuset *cs = __d_cs(file->f_path.dentry->d_parent);
+       struct cpuset *cs = cgroup_cs(cont);
        cpuset_filetype_t type = cft->private;
        char *page;
        ssize_t retval = 0;
@@ -1419,8 +1396,8 @@ static ssize_t cpuset_common_file_read(struct file *file, char __user *buf,
        case FILE_MEM_EXCLUSIVE:
                *s++ = is_mem_exclusive(cs) ? '1' : '0';
                break;
-       case FILE_NOTIFY_ON_RELEASE:
-               *s++ = notify_on_release(cs) ? '1' : '0';
+       case FILE_SCHED_LOAD_BALANCE:
+               *s++ = is_sched_load_balance(cs) ? '1' : '0';
                break;
        case FILE_MEMORY_MIGRATE:
                *s++ = is_memory_migrate(cs) ? '1' : '0';
@@ -1449,389 +1426,149 @@ out:
        return retval;
 }
 
-static ssize_t cpuset_file_read(struct file *file, char __user *buf, size_t nbytes,
-                                                               loff_t *ppos)
-{
-       ssize_t retval = 0;
-       struct cftype *cft = __d_cft(file->f_path.dentry);
-       if (!cft)
-               return -ENODEV;
-
-       /* special function ? */
-       if (cft->read)
-               retval = cft->read(file, buf, nbytes, ppos);
-       else
-               retval = cpuset_common_file_read(file, buf, nbytes, ppos);
-
-       return retval;
-}
 
-static int cpuset_file_open(struct inode *inode, struct file *file)
-{
-       int err;
-       struct cftype *cft;
 
-       err = generic_file_open(inode, file);
-       if (err)
-               return err;
 
-       cft = __d_cft(file->f_path.dentry);
-       if (!cft)
-               return -ENODEV;
-       if (cft->open)
-               err = cft->open(inode, file);
-       else
-               err = 0;
-
-       return err;
-}
-
-static int cpuset_file_release(struct inode *inode, struct file *file)
-{
-       struct cftype *cft = __d_cft(file->f_path.dentry);
-       if (cft->release)
-               return cft->release(inode, file);
-       return 0;
-}
-
-/*
- * cpuset_rename - Only allow simple rename of directories in place.
- */
-static int cpuset_rename(struct inode *old_dir, struct dentry *old_dentry,
-                  struct inode *new_dir, struct dentry *new_dentry)
-{
-       if (!S_ISDIR(old_dentry->d_inode->i_mode))
-               return -ENOTDIR;
-       if (new_dentry->d_inode)
-               return -EEXIST;
-       if (old_dir != new_dir)
-               return -EIO;
-       return simple_rename(old_dir, old_dentry, new_dir, new_dentry);
-}
-
-static const struct file_operations cpuset_file_operations = {
-       .read = cpuset_file_read,
-       .write = cpuset_file_write,
-       .llseek = generic_file_llseek,
-       .open = cpuset_file_open,
-       .release = cpuset_file_release,
-};
-
-static const struct inode_operations cpuset_dir_inode_operations = {
-       .lookup = simple_lookup,
-       .mkdir = cpuset_mkdir,
-       .rmdir = cpuset_rmdir,
-       .rename = cpuset_rename,
-};
-
-static int cpuset_create_file(struct dentry *dentry, int mode)
-{
-       struct inode *inode;
-
-       if (!dentry)
-               return -ENOENT;
-       if (dentry->d_inode)
-               return -EEXIST;
-
-       inode = cpuset_new_inode(mode);
-       if (!inode)
-               return -ENOMEM;
-
-       if (S_ISDIR(mode)) {
-               inode->i_op = &cpuset_dir_inode_operations;
-               inode->i_fop = &simple_dir_operations;
-
-               /* start off with i_nlink == 2 (for "." entry) */
-               inc_nlink(inode);
-       } else if (S_ISREG(mode)) {
-               inode->i_size = 0;
-               inode->i_fop = &cpuset_file_operations;
-       }
-
-       d_instantiate(dentry, inode);
-       dget(dentry);   /* Extra count - pin the dentry in core */
-       return 0;
-}
-
-/*
- *     cpuset_create_dir - create a directory for an object.
- *     cs:     the cpuset we create the directory for.
- *             It must have a valid ->parent field
- *             And we are going to fill its ->dentry field.
- *     name:   The name to give to the cpuset directory. Will be copied.
- *     mode:   mode to set on new directory.
- */
-
-static int cpuset_create_dir(struct cpuset *cs, const char *name, int mode)
-{
-       struct dentry *dentry = NULL;
-       struct dentry *parent;
-       int error = 0;
-
-       parent = cs->parent->dentry;
-       dentry = cpuset_get_dentry(parent, name);
-       if (IS_ERR(dentry))
-               return PTR_ERR(dentry);
-       error = cpuset_create_file(dentry, S_IFDIR | mode);
-       if (!error) {
-               dentry->d_fsdata = cs;
-               inc_nlink(parent->d_inode);
-               cs->dentry = dentry;
-       }
-       dput(dentry);
-
-       return error;
-}
-
-static int cpuset_add_file(struct dentry *dir, const struct cftype *cft)
-{
-       struct dentry *dentry;
-       int error;
-
-       mutex_lock(&dir->d_inode->i_mutex);
-       dentry = cpuset_get_dentry(dir, cft->name);
-       if (!IS_ERR(dentry)) {
-               error = cpuset_create_file(dentry, 0644 | S_IFREG);
-               if (!error)
-                       dentry->d_fsdata = (void *)cft;
-               dput(dentry);
-       } else
-               error = PTR_ERR(dentry);
-       mutex_unlock(&dir->d_inode->i_mutex);
-       return error;
-}
-
-/*
- * Stuff for reading the 'tasks' file.
- *
- * Reading this file can return large amounts of data if a cpuset has
- * *lots* of attached tasks. So it may need several calls to read(),
- * but we cannot guarantee that the information we produce is correct
- * unless we produce it entirely atomically.
- *
- * Upon tasks file open(), a struct ctr_struct is allocated, that
- * will have a pointer to an array (also allocated here).  The struct
- * ctr_struct * is stored in file->private_data.  Its resources will
- * be freed by release() when the file is closed.  The array is used
- * to sprintf the PIDs and then used by read().
- */
-
-/* cpusets_tasks_read array */
-
-struct ctr_struct {
-       char *buf;
-       int bufsz;
-};
-
-/*
- * Load into 'pidarray' up to 'npids' of the tasks using cpuset 'cs'.
- * Return actual number of pids loaded.  No need to task_lock(p)
- * when reading out p->cpuset, as we don't really care if it changes
- * on the next cycle, and we are not going to try to dereference it.
- */
-static int pid_array_load(pid_t *pidarray, int npids, struct cpuset *cs)
-{
-       int n = 0;
-       struct task_struct *g, *p;
-
-       read_lock(&tasklist_lock);
-
-       do_each_thread(g, p) {
-               if (p->cpuset == cs) {
-                       if (unlikely(n == npids))
-                               goto array_full;
-                       pidarray[n++] = p->pid;
-               }
-       } while_each_thread(g, p);
-
-array_full:
-       read_unlock(&tasklist_lock);
-       return n;
-}
-
-static int cmppid(const void *a, const void *b)
-{
-       return *(pid_t *)a - *(pid_t *)b;
-}
-
-/*
- * Convert array 'a' of 'npids' pid_t's to a string of newline separated
- * decimal pids in 'buf'.  Don't write more than 'sz' chars, but return
- * count 'cnt' of how many chars would be written if buf were large enough.
- */
-static int pid_array_to_buf(char *buf, int sz, pid_t *a, int npids)
-{
-       int cnt = 0;
-       int i;
-
-       for (i = 0; i < npids; i++)
-               cnt += snprintf(buf + cnt, max(sz - cnt, 0), "%d\n", a[i]);
-       return cnt;
-}
-
-/*
- * Handle an open on 'tasks' file.  Prepare a buffer listing the
- * process id's of tasks currently attached to the cpuset being opened.
- *
- * Does not require any specific cpuset mutexes, and does not take any.
- */
-static int cpuset_tasks_open(struct inode *unused, struct file *file)
-{
-       struct cpuset *cs = __d_cs(file->f_path.dentry->d_parent);
-       struct ctr_struct *ctr;
-       pid_t *pidarray;
-       int npids;
-       char c;
-
-       if (!(file->f_mode & FMODE_READ))
-               return 0;
-
-       ctr = kmalloc(sizeof(*ctr), GFP_KERNEL);
-       if (!ctr)
-               goto err0;
-
-       /*
-        * If cpuset gets more users after we read count, we won't have
-        * enough space - tough.  This race is indistinguishable to the
-        * caller from the case that the additional cpuset users didn't
-        * show up until sometime later on.
-        */
-       npids = atomic_read(&cs->count);
-       pidarray = kmalloc(npids * sizeof(pid_t), GFP_KERNEL);
-       if (!pidarray)
-               goto err1;
-
-       npids = pid_array_load(pidarray, npids, cs);
-       sort(pidarray, npids, sizeof(pid_t), cmppid, NULL);
-
-       /* Call pid_array_to_buf() twice, first just to get bufsz */
-       ctr->bufsz = pid_array_to_buf(&c, sizeof(c), pidarray, npids) + 1;
-       ctr->buf = kmalloc(ctr->bufsz, GFP_KERNEL);
-       if (!ctr->buf)
-               goto err2;
-       ctr->bufsz = pid_array_to_buf(ctr->buf, ctr->bufsz, pidarray, npids);
-
-       kfree(pidarray);
-       file->private_data = ctr;
-       return 0;
-
-err2:
-       kfree(pidarray);
-err1:
-       kfree(ctr);
-err0:
-       return -ENOMEM;
-}
-
-static ssize_t cpuset_tasks_read(struct file *file, char __user *buf,
-                                               size_t nbytes, loff_t *ppos)
-{
-       struct ctr_struct *ctr = file->private_data;
-
-       return simple_read_from_buffer(buf, nbytes, ppos, ctr->buf, ctr->bufsz);
-}
-
-static int cpuset_tasks_release(struct inode *unused_inode, struct file *file)
-{
-       struct ctr_struct *ctr;
-
-       if (file->f_mode & FMODE_READ) {
-               ctr = file->private_data;
-               kfree(ctr->buf);
-               kfree(ctr);
-       }
-       return 0;
-}
 
 /*
  * for the common functions, 'private' gives the type of file
  */
 
-static struct cftype cft_tasks = {
-       .name = "tasks",
-       .open = cpuset_tasks_open,
-       .read = cpuset_tasks_read,
-       .release = cpuset_tasks_release,
-       .private = FILE_TASKLIST,
-};
-
 static struct cftype cft_cpus = {
        .name = "cpus",
+       .read = cpuset_common_file_read,
+       .write = cpuset_common_file_write,
        .private = FILE_CPULIST,
 };
 
 static struct cftype cft_mems = {
        .name = "mems",
+       .read = cpuset_common_file_read,
+       .write = cpuset_common_file_write,
        .private = FILE_MEMLIST,
 };
 
 static struct cftype cft_cpu_exclusive = {
        .name = "cpu_exclusive",
+       .read = cpuset_common_file_read,
+       .write = cpuset_common_file_write,
        .private = FILE_CPU_EXCLUSIVE,
 };
 
 static struct cftype cft_mem_exclusive = {
        .name = "mem_exclusive",
+       .read = cpuset_common_file_read,
+       .write = cpuset_common_file_write,
        .private = FILE_MEM_EXCLUSIVE,
 };
 
-static struct cftype cft_notify_on_release = {
-       .name = "notify_on_release",
-       .private = FILE_NOTIFY_ON_RELEASE,
+static struct cftype cft_sched_load_balance = {
+       .name = "sched_load_balance",
+       .read = cpuset_common_file_read,
+       .write = cpuset_common_file_write,
+       .private = FILE_SCHED_LOAD_BALANCE,
 };
 
 static struct cftype cft_memory_migrate = {
        .name = "memory_migrate",
+       .read = cpuset_common_file_read,
+       .write = cpuset_common_file_write,
        .private = FILE_MEMORY_MIGRATE,
 };
 
 static struct cftype cft_memory_pressure_enabled = {
        .name = "memory_pressure_enabled",
+       .read = cpuset_common_file_read,
+       .write = cpuset_common_file_write,
        .private = FILE_MEMORY_PRESSURE_ENABLED,
 };
 
 static struct cftype cft_memory_pressure = {
        .name = "memory_pressure",
+       .read = cpuset_common_file_read,
+       .write = cpuset_common_file_write,
        .private = FILE_MEMORY_PRESSURE,
 };
 
 static struct cftype cft_spread_page = {
        .name = "memory_spread_page",
+       .read = cpuset_common_file_read,
+       .write = cpuset_common_file_write,
        .private = FILE_SPREAD_PAGE,
 };
 
 static struct cftype cft_spread_slab = {
        .name = "memory_spread_slab",
+       .read = cpuset_common_file_read,
+       .write = cpuset_common_file_write,
        .private = FILE_SPREAD_SLAB,
 };
 
-static int cpuset_populate_dir(struct dentry *cs_dentry)
+static int cpuset_populate(struct cgroup_subsys *ss, struct cgroup *cont)
 {
        int err;
 
-       if ((err = cpuset_add_file(cs_dentry, &cft_cpus)) < 0)
-               return err;
-       if ((err = cpuset_add_file(cs_dentry, &cft_mems)) < 0)
+       if ((err = cgroup_add_file(cont, ss, &cft_cpus)) < 0)
                return err;
-       if ((err = cpuset_add_file(cs_dentry, &cft_cpu_exclusive)) < 0)
+       if ((err = cgroup_add_file(cont, ss, &cft_mems)) < 0)
                return err;
-       if ((err = cpuset_add_file(cs_dentry, &cft_mem_exclusive)) < 0)
+       if ((err = cgroup_add_file(cont, ss, &cft_cpu_exclusive)) < 0)
                return err;
-       if ((err = cpuset_add_file(cs_dentry, &cft_notify_on_release)) < 0)
+       if ((err = cgroup_add_file(cont, ss, &cft_mem_exclusive)) < 0)
                return err;
-       if ((err = cpuset_add_file(cs_dentry, &cft_memory_migrate)) < 0)
+       if ((err = cgroup_add_file(cont, ss, &cft_memory_migrate)) < 0)
                return err;
-       if ((err = cpuset_add_file(cs_dentry, &cft_memory_pressure)) < 0)
+       if ((err = cgroup_add_file(cont, ss, &cft_sched_load_balance)) < 0)
                return err;
-       if ((err = cpuset_add_file(cs_dentry, &cft_spread_page)) < 0)
+       if ((err = cgroup_add_file(cont, ss, &cft_memory_pressure)) < 0)
                return err;
-       if ((err = cpuset_add_file(cs_dentry, &cft_spread_slab)) < 0)
+       if ((err = cgroup_add_file(cont, ss, &cft_spread_page)) < 0)
                return err;
-       if ((err = cpuset_add_file(cs_dentry, &cft_tasks)) < 0)
+       if ((err = cgroup_add_file(cont, ss, &cft_spread_slab)) < 0)
                return err;
+       /* memory_pressure_enabled is in root cpuset only */
+       if (err == 0 && !cont->parent)
+               err = cgroup_add_file(cont, ss,
+                                        &cft_memory_pressure_enabled);
        return 0;
 }
 
+/*
+ * post_clone() is called at the end of cgroup_clone().
+ * 'cgroup' was just created automatically as a result of
+ * a cgroup_clone(), and the current task is about to
+ * be moved into 'cgroup'.
+ *
+ * Currently we refuse to set up the cgroup - thereby
+ * refusing the task to be entered, and as a result refusing
+ * the sys_unshare() or clone() which initiated it - if any
+ * sibling cpusets have exclusive cpus or mem.
+ *
+ * If this becomes a problem for some users who wish to
+ * allow that scenario, then cpuset_post_clone() could be
+ * changed to grant parent->cpus_allowed-sibling_cpus_exclusive
+ * (and likewise for mems) to the new cgroup.
+ */
+static void cpuset_post_clone(struct cgroup_subsys *ss,
+                             struct cgroup *cgroup)
+{
+       struct cgroup *parent, *child;
+       struct cpuset *cs, *parent_cs;
+
+       parent = cgroup->parent;
+       list_for_each_entry(child, &parent->children, sibling) {
+               cs = cgroup_cs(child);
+               if (is_mem_exclusive(cs) || is_cpu_exclusive(cs))
+                       return;
+       }
+       cs = cgroup_cs(cgroup);
+       parent_cs = cgroup_cs(parent);
+
+       cs->mems_allowed = parent_cs->mems_allowed;
+       cs->cpus_allowed = parent_cs->cpus_allowed;
+       return;
+}
+
 /*
  *     cpuset_create - create a cpuset
  *     parent: cpuset that will be parent of the new cpuset.
@@ -1841,106 +1578,77 @@ static int cpuset_populate_dir(struct dentry *cs_dentry)
  *     Must be called with the mutex on the parent inode held
  */
 
-static long cpuset_create(struct cpuset *parent, const char *name, int mode)
+static struct cgroup_subsys_state *cpuset_create(
+       struct cgroup_subsys *ss,
+       struct cgroup *cont)
 {
        struct cpuset *cs;
-       int err;
+       struct cpuset *parent;
 
+       if (!cont->parent) {
+               /* This is early initialization for the top cgroup */
+               top_cpuset.mems_generation = cpuset_mems_generation++;
+               return &top_cpuset.css;
+       }
+       parent = cgroup_cs(cont->parent);
        cs = kmalloc(sizeof(*cs), GFP_KERNEL);
        if (!cs)
-               return -ENOMEM;
+               return ERR_PTR(-ENOMEM);
 
-       mutex_lock(&manage_mutex);
        cpuset_update_task_memory_state();
        cs->flags = 0;
-       if (notify_on_release(parent))
-               set_bit(CS_NOTIFY_ON_RELEASE, &cs->flags);
        if (is_spread_page(parent))
                set_bit(CS_SPREAD_PAGE, &cs->flags);
        if (is_spread_slab(parent))
                set_bit(CS_SPREAD_SLAB, &cs->flags);
+       set_bit(CS_SCHED_LOAD_BALANCE, &cs->flags);
        cs->cpus_allowed = CPU_MASK_NONE;
        cs->mems_allowed = NODE_MASK_NONE;
-       atomic_set(&cs->count, 0);
-       INIT_LIST_HEAD(&cs->sibling);
-       INIT_LIST_HEAD(&cs->children);
        cs->mems_generation = cpuset_mems_generation++;
        fmeter_init(&cs->fmeter);
 
        cs->parent = parent;
-
-       mutex_lock(&callback_mutex);
-       list_add(&cs->sibling, &cs->parent->children);
        number_of_cpusets++;
-       mutex_unlock(&callback_mutex);
-
-       err = cpuset_create_dir(cs, name, mode);
-       if (err < 0)
-               goto err;
-
-       /*
-        * Release manage_mutex before cpuset_populate_dir() because it
-        * will down() this new directory's i_mutex and if we race with
-        * another mkdir, we might deadlock.
-        */
-       mutex_unlock(&manage_mutex);
-
-       err = cpuset_populate_dir(cs->dentry);
-       /* If err < 0, we have a half-filled directory - oh well ;) */
-       return 0;
-err:
-       list_del(&cs->sibling);
-       mutex_unlock(&manage_mutex);
-       kfree(cs);
-       return err;
+       return &cs->css ;
 }
 
-static int cpuset_mkdir(struct inode *dir, struct dentry *dentry, int mode)
-{
-       struct cpuset *c_parent = dentry->d_parent->d_fsdata;
-
-       /* the vfs holds inode->i_mutex already */
-       return cpuset_create(c_parent, dentry->d_name.name, mode | S_IFDIR);
-}
+/*
+ * Locking note on the strange update_flag() call below:
+ *
+ * If the cpuset being removed has its flag 'sched_load_balance'
+ * enabled, then simulate turning sched_load_balance off, which
+ * will call rebuild_sched_domains().  The lock_cpu_hotplug()
+ * call in rebuild_sched_domains() must not be made while holding
+ * callback_mutex.  Elsewhere the kernel nests callback_mutex inside
+ * lock_cpu_hotplug() calls.  So the reverse nesting would risk an
+ * ABBA deadlock.
+ */
 
-static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry)
+static void cpuset_destroy(struct cgroup_subsys *ss, struct cgroup *cont)
 {
-       struct cpuset *cs = dentry->d_fsdata;
-       struct dentry *d;
-       struct cpuset *parent;
-       char *pathbuf = NULL;
+       struct cpuset *cs = cgroup_cs(cont);
 
-       /* the vfs holds both inode->i_mutex already */
-
-       mutex_lock(&manage_mutex);
        cpuset_update_task_memory_state();
-       if (atomic_read(&cs->count) > 0) {
-               mutex_unlock(&manage_mutex);
-               return -EBUSY;
-       }
-       if (!list_empty(&cs->children)) {
-               mutex_unlock(&manage_mutex);
-               return -EBUSY;
-       }
-       parent = cs->parent;
-       mutex_lock(&callback_mutex);
-       set_bit(CS_REMOVED, &cs->flags);
-       list_del(&cs->sibling); /* delete my sibling from parent->children */
-       spin_lock(&cs->dentry->d_lock);
-       d = dget(cs->dentry);
-       cs->dentry = NULL;
-       spin_unlock(&d->d_lock);
-       cpuset_d_remove_dir(d);
-       dput(d);
+
+       if (is_sched_load_balance(cs))
+               update_flag(CS_SCHED_LOAD_BALANCE, cs, "0");
+
        number_of_cpusets--;
-       mutex_unlock(&callback_mutex);
-       if (list_empty(&parent->children))
-               check_for_release(parent, &pathbuf);
-       mutex_unlock(&manage_mutex);
-       cpuset_release_agent(pathbuf);
-       return 0;
+       kfree(cs);
 }
 
+struct cgroup_subsys cpuset_subsys = {
+       .name = "cpuset",
+       .create = cpuset_create,
+       .destroy  = cpuset_destroy,
+       .can_attach = cpuset_can_attach,
+       .attach = cpuset_attach,
+       .populate = cpuset_populate,
+       .post_clone = cpuset_post_clone,
+       .subsys_id = cpuset_subsys_id,
+       .early_init = 1,
+};
+
 /*
  * cpuset_init_early - just enough so that the calls to
  * cpuset_update_task_memory_state() in early init code
@@ -1949,13 +1657,11 @@ static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry)
 
 int __init cpuset_init_early(void)
 {
-       struct task_struct *tsk = current;
-
-       tsk->cpuset = &top_cpuset;
-       tsk->cpuset->mems_generation = cpuset_mems_generation++;
+       top_cpuset.mems_generation = cpuset_mems_generation++;
        return 0;
 }
 
+
 /**
  * cpuset_init - initialize cpusets at system boot
  *
@@ -1964,39 +1670,21 @@ int __init cpuset_init_early(void)
 
 int __init cpuset_init(void)
 {
-       struct dentry *root;
-       int err;
+       int err = 0;
 
        top_cpuset.cpus_allowed = CPU_MASK_ALL;
        top_cpuset.mems_allowed = NODE_MASK_ALL;
 
        fmeter_init(&top_cpuset.fmeter);
        top_cpuset.mems_generation = cpuset_mems_generation++;
-
-       init_task.cpuset = &top_cpuset;
+       set_bit(CS_SCHED_LOAD_BALANCE, &top_cpuset.flags);
 
        err = register_filesystem(&cpuset_fs_type);
        if (err < 0)
-               goto out;
-       cpuset_mount = kern_mount(&cpuset_fs_type);
-       if (IS_ERR(cpuset_mount)) {
-               printk(KERN_ERR "cpuset: could not mount!\n");
-               err = PTR_ERR(cpuset_mount);
-               cpuset_mount = NULL;
-               goto out;
-       }
-       root = cpuset_mount->mnt_sb->s_root;
-       root->d_fsdata = &top_cpuset;
-       inc_nlink(root->d_inode);
-       top_cpuset.dentry = root;
-       root->d_inode->i_op = &cpuset_dir_inode_operations;
+               return err;
+
        number_of_cpusets = 1;
-       err = cpuset_populate_dir(root);
-       /* memory_pressure_enabled is in root cpuset only */
-       if (err == 0)
-               err = cpuset_add_file(root, &cft_memory_pressure_enabled);
-out:
-       return err;
+       return 0;
 }
 
 /*
@@ -2022,10 +1710,12 @@ out:
 
 static void guarantee_online_cpus_mems_in_subtree(const struct cpuset *cur)
 {
+       struct cgroup *cont;
        struct cpuset *c;
 
        /* Each of our child cpusets mems must be online */
-       list_for_each_entry(c, &cur->children, sibling) {
+       list_for_each_entry(cont, &cur->css.cgroup->children, sibling) {
+               c = cgroup_cs(cont);
                guarantee_online_cpus_mems_in_subtree(c);
                if (!cpus_empty(c->cpus_allowed))
                        guarantee_online_cpus(c, &c->cpus_allowed);
@@ -2053,7 +1743,7 @@ static void guarantee_online_cpus_mems_in_subtree(const struct cpuset *cur)
 
 static void common_cpu_mem_hotplug_unplug(void)
 {
-       mutex_lock(&manage_mutex);
+       cgroup_lock();
        mutex_lock(&callback_mutex);
 
        guarantee_online_cpus_mems_in_subtree(&top_cpuset);
@@ -2061,7 +1751,7 @@ static void common_cpu_mem_hotplug_unplug(void)
        top_cpuset.mems_allowed = node_states[N_HIGH_MEMORY];
 
        mutex_unlock(&callback_mutex);
-       mutex_unlock(&manage_mutex);
+       cgroup_unlock();
 }
 
 /*
@@ -2074,8 +1764,8 @@ static void common_cpu_mem_hotplug_unplug(void)
  * cpu_online_map on each CPU hotplug (cpuhp) event.
  */
 
-static int cpuset_handle_cpuhp(struct notifier_block *nb,
-                               unsigned long phase, void *cpu)
+static int cpuset_handle_cpuhp(struct notifier_block *unused_nb,
+                               unsigned long phase, void *unused_cpu)
 {
        if (phase == CPU_DYING || phase == CPU_DYING_FROZEN)
                return NOTIFY_DONE;
@@ -2113,109 +1803,7 @@ void __init cpuset_init_smp(void)
 }
 
 /**
- * cpuset_fork - attach newly forked task to its parents cpuset.
- * @tsk: pointer to task_struct of forking parent process.
- *
- * Description: A task inherits its parent's cpuset at fork().
- *
- * A pointer to the shared cpuset was automatically copied in fork.c
- * by dup_task_struct().  However, we ignore that copy, since it was
- * not made under the protection of task_lock(), so might no longer be
- * a valid cpuset pointer.  attach_task() might have already changed
- * current->cpuset, allowing the previously referenced cpuset to
- * be removed and freed.  Instead, we task_lock(current) and copy
- * its present value of current->cpuset for our freshly forked child.
- *
- * At the point that cpuset_fork() is called, 'current' is the parent
- * task, and the passed argument 'child' points to the child task.
- **/
-
-void cpuset_fork(struct task_struct *child)
-{
-       task_lock(current);
-       child->cpuset = current->cpuset;
-       atomic_inc(&child->cpuset->count);
-       task_unlock(current);
-}
-
-/**
- * cpuset_exit - detach cpuset from exiting task
- * @tsk: pointer to task_struct of exiting process
- *
- * Description: Detach cpuset from @tsk and release it.
- *
- * Note that cpusets marked notify_on_release force every task in
- * them to take the global manage_mutex mutex when exiting.
- * This could impact scaling on very large systems.  Be reluctant to
- * use notify_on_release cpusets where very high task exit scaling
- * is required on large systems.
- *
- * Don't even think about derefencing 'cs' after the cpuset use count
- * goes to zero, except inside a critical section guarded by manage_mutex
- * or callback_mutex.   Otherwise a zero cpuset use count is a license to
- * any other task to nuke the cpuset immediately, via cpuset_rmdir().
- *
- * This routine has to take manage_mutex, not callback_mutex, because
- * it is holding that mutex while calling check_for_release(),
- * which calls kmalloc(), so can't be called holding callback_mutex().
- *
- * the_top_cpuset_hack:
- *
- *    Set the exiting tasks cpuset to the root cpuset (top_cpuset).
- *
- *    Don't leave a task unable to allocate memory, as that is an
- *    accident waiting to happen should someone add a callout in
- *    do_exit() after the cpuset_exit() call that might allocate.
- *    If a task tries to allocate memory with an invalid cpuset,
- *    it will oops in cpuset_update_task_memory_state().
- *
- *    We call cpuset_exit() while the task is still competent to
- *    handle notify_on_release(), then leave the task attached to
- *    the root cpuset (top_cpuset) for the remainder of its exit.
- *
- *    To do this properly, we would increment the reference count on
- *    top_cpuset, and near the very end of the kernel/exit.c do_exit()
- *    code we would add a second cpuset function call, to drop that
- *    reference.  This would just create an unnecessary hot spot on
- *    the top_cpuset reference count, to no avail.
- *
- *    Normally, holding a reference to a cpuset without bumping its
- *    count is unsafe.   The cpuset could go away, or someone could
- *    attach us to a different cpuset, decrementing the count on
- *    the first cpuset that we never incremented.  But in this case,
- *    top_cpuset isn't going away, and either task has PF_EXITING set,
- *    which wards off any attach_task() attempts, or task is a failed
- *    fork, never visible to attach_task.
- *
- *    Another way to do this would be to set the cpuset pointer
- *    to NULL here, and check in cpuset_update_task_memory_state()
- *    for a NULL pointer.  This hack avoids that NULL check, for no
- *    cost (other than this way too long comment ;).
- **/
-
-void cpuset_exit(struct task_struct *tsk)
-{
-       struct cpuset *cs;
-
-       task_lock(current);
-       cs = tsk->cpuset;
-       tsk->cpuset = &top_cpuset;      /* the_top_cpuset_hack - see above */
-       task_unlock(current);
-
-       if (notify_on_release(cs)) {
-               char *pathbuf = NULL;
 
-               mutex_lock(&manage_mutex);
-               if (atomic_dec_and_test(&cs->count))
-                       check_for_release(cs, &pathbuf);
-               mutex_unlock(&manage_mutex);
-               cpuset_release_agent(pathbuf);
-       } else {
-               atomic_dec(&cs->count);
-       }
-}
-
-/**
  * cpuset_cpus_allowed - return cpus_allowed mask from a tasks cpuset.
  * @tsk: pointer to task_struct from which to obtain cpuset->cpus_allowed.
  *
@@ -2230,10 +1818,23 @@ cpumask_t cpuset_cpus_allowed(struct task_struct *tsk)
        cpumask_t mask;
 
        mutex_lock(&callback_mutex);
+       mask = cpuset_cpus_allowed_locked(tsk);
+       mutex_unlock(&callback_mutex);
+
+       return mask;
+}
+
+/**
+ * cpuset_cpus_allowed_locked - return cpus_allowed mask from a tasks cpuset.
+ * Must be  called with callback_mutex held.
+ **/
+cpumask_t cpuset_cpus_allowed_locked(struct task_struct *tsk)
+{
+       cpumask_t mask;
+
        task_lock(tsk);
-       guarantee_online_cpus(tsk->cpuset, &mask);
+       guarantee_online_cpus(task_cs(tsk), &mask);
        task_unlock(tsk);
-       mutex_unlock(&callback_mutex);
 
        return mask;
 }
@@ -2259,7 +1860,7 @@ nodemask_t cpuset_mems_allowed(struct task_struct *tsk)
 
        mutex_lock(&callback_mutex);
        task_lock(tsk);
-       guarantee_online_mems(tsk->cpuset, &mask);
+       guarantee_online_mems(task_cs(tsk), &mask);
        task_unlock(tsk);
        mutex_unlock(&callback_mutex);
 
@@ -2390,7 +1991,7 @@ int __cpuset_zone_allowed_softwall(struct zone *z, gfp_t gfp_mask)
        mutex_lock(&callback_mutex);
 
        task_lock(current);
-       cs = nearest_exclusive_ancestor(current->cpuset);
+       cs = nearest_exclusive_ancestor(task_cs(current));
        task_unlock(current);
 
        allowed = node_isset(node, cs->mems_allowed);
@@ -2431,12 +2032,12 @@ int __cpuset_zone_allowed_hardwall(struct zone *z, gfp_t gfp_mask)
        node = zone_to_nid(z);
        if (node_isset(node, current->mems_allowed))
                return 1;
-        /*
-         * Allow tasks that have access to memory reserves because they have
-         * been OOM killed to get memory anywhere.
-         */
-        if (unlikely(test_thread_flag(TIF_MEMDIE)))
-                return 1;
+       /*
+        * Allow tasks that have access to memory reserves because they have
+        * been OOM killed to get memory anywhere.
+        */
+       if (unlikely(test_thread_flag(TIF_MEMDIE)))
+               return 1;
        return 0;
 }
 
@@ -2550,14 +2151,12 @@ int cpuset_memory_pressure_enabled __read_mostly;
 
 void __cpuset_memory_pressure_bump(void)
 {
-       struct cpuset *cs;
-
        task_lock(current);
-       cs = current->cpuset;
-       fmeter_markevent(&cs->fmeter);
+       fmeter_markevent(&task_cs(current)->fmeter);
        task_unlock(current);
 }
 
+#ifdef CONFIG_PROC_PID_CPUSET
 /*
  * proc_cpuset_show()
  *  - Print tasks cpuset path into seq_file.
@@ -2569,11 +2168,12 @@ void __cpuset_memory_pressure_bump(void)
  *    the_top_cpuset_hack in cpuset_exit(), which sets an exiting tasks
  *    cpuset to top_cpuset.
  */
-static int proc_cpuset_show(struct seq_file *m, void *v)
+static int proc_cpuset_show(struct seq_file *m, void *unused_v)
 {
        struct pid *pid;
        struct task_struct *tsk;
        char *buf;
+       struct cgroup_subsys_state *css;
        int retval;
 
        retval = -ENOMEM;
@@ -2588,15 +2188,15 @@ static int proc_cpuset_show(struct seq_file *m, void *v)
                goto out_free;
 
        retval = -EINVAL;
-       mutex_lock(&manage_mutex);
-
-       retval = cpuset_path(tsk->cpuset, buf, PAGE_SIZE);
+       cgroup_lock();
+       css = task_subsys_state(tsk, cpuset_subsys_id);
+       retval = cgroup_path(css->cgroup, buf, PAGE_SIZE);
        if (retval < 0)
                goto out_unlock;
        seq_puts(m, buf);
        seq_putc(m, '\n');
 out_unlock:
-       mutex_unlock(&manage_mutex);
+       cgroup_unlock();
        put_task_struct(tsk);
 out_free:
        kfree(buf);
@@ -2616,6 +2216,7 @@ const struct file_operations proc_cpuset_operations = {
        .llseek         = seq_lseek,
        .release        = single_release,
 };
+#endif /* CONFIG_PROC_PID_CPUSET */
 
 /* Display task cpus_allowed, mems_allowed in /proc/<pid>/status file. */
 char *cpuset_task_status_allowed(struct task_struct *task, char *buffer)
index 09e9574eeb26f0273054e1111224521e0a072c67..10e43fd8b721a7c28f44dbb60515efa9d0d4042d 100644 (file)
@@ -115,6 +115,12 @@ int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk)
        tmp += timespec_to_ns(&ts);
        d->cpu_run_real_total = (tmp < (s64)d->cpu_run_real_total) ? 0 : tmp;
 
+       tmp = (s64)d->cpu_scaled_run_real_total;
+       cputime_to_timespec(tsk->utimescaled + tsk->stimescaled, &ts);
+       tmp += timespec_to_ns(&ts);
+       d->cpu_scaled_run_real_total =
+               (tmp < (s64)d->cpu_scaled_run_real_total) ? 0 : tmp;
+
        /*
         * No locking available for sched_info (and too expensive to add one)
         * Mitigate by taking snapshot of values
diff --git a/kernel/die_notifier.c b/kernel/die_notifier.c
deleted file mode 100644 (file)
index 0d98827..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-
-#include <linux/module.h>
-#include <linux/notifier.h>
-#include <linux/vmalloc.h>
-#include <linux/kdebug.h>
-
-
-static ATOMIC_NOTIFIER_HEAD(die_chain);
-
-int notify_die(enum die_val val, const char *str,
-              struct pt_regs *regs, long err, int trap, int sig)
-{
-       struct die_args args = {
-               .regs           = regs,
-               .str            = str,
-               .err            = err,
-               .trapnr         = trap,
-               .signr          = sig,
-
-       };
-
-       return atomic_notifier_call_chain(&die_chain, val, &args);
-}
-
-int register_die_notifier(struct notifier_block *nb)
-{
-       vmalloc_sync_all();
-       return atomic_notifier_chain_register(&die_chain, nb);
-}
-EXPORT_SYMBOL_GPL(register_die_notifier);
-
-int unregister_die_notifier(struct notifier_block *nb)
-{
-       return atomic_notifier_chain_unregister(&die_chain, nb);
-}
-EXPORT_SYMBOL_GPL(unregister_die_notifier);
-
-
index 937b13ca33baaac6a3ab01437b4016f9995a11f9..6a82bb716dace9bbcf0b469e3119fd10a95b9b1a 100644 (file)
@@ -20,7 +20,7 @@
 #include <asm/dma.h>
 #include <asm/system.h>
 
+
 
 /* A note on resource allocation:
  *
@@ -95,7 +95,7 @@ void free_dma(unsigned int dmanr)
        if (xchg(&dma_chan_busy[dmanr].lock, 0) == 0) {
                printk(KERN_WARNING "Trying to free free DMA%d\n", dmanr);
                return;
-       }       
+       }
 
 } /* free_dma */
 
@@ -121,8 +121,8 @@ static int proc_dma_show(struct seq_file *m, void *v)
 
        for (i = 0 ; i < MAX_DMA_CHANNELS ; i++) {
                if (dma_chan_busy[i].lock) {
-                   seq_printf(m, "%2d: %s\n", i,
-                              dma_chan_busy[i].device_id);
+                       seq_printf(m, "%2d: %s\n", i,
+                                  dma_chan_busy[i].device_id);
                }
        }
        return 0;
index 3c2eaea66b1e16347bcd564b0c492b8f026dcf21..a9e6bad9f706b05f96b2e7c4e16e6cb75acd6f4e 100644 (file)
@@ -57,7 +57,7 @@ lookup_exec_domain(u_long personality)
 {
        struct exec_domain *    ep;
        u_long                  pers = personality(personality);
-               
+
        read_lock(&exec_domains_lock);
        for (ep = exec_domains; ep; ep = ep->next) {
                if (pers >= ep->pers_low && pers <= ep->pers_high)
index 2c704c86edb3200864d4ec950c4e2bd89cbf3443..f1aec27f1df00eaae4cbb9c3f99dde1b4e1c8520 100644 (file)
@@ -31,7 +31,7 @@
 #include <linux/taskstats_kern.h>
 #include <linux/delayacct.h>
 #include <linux/freezer.h>
-#include <linux/cpuset.h>
+#include <linux/cgroup.h>
 #include <linux/syscalls.h>
 #include <linux/signal.h>
 #include <linux/posix-timers.h>
@@ -148,6 +148,7 @@ void release_task(struct task_struct * p)
        int zap_leader;
 repeat:
        atomic_dec(&p->user->processes);
+       proc_flush_task(p);
        write_lock_irq(&tasklist_lock);
        ptrace_unlink(p);
        BUG_ON(!list_empty(&p->ptrace_list) || !list_empty(&p->ptrace_children));
@@ -175,7 +176,6 @@ repeat:
        }
 
        write_unlock_irq(&tasklist_lock);
-       proc_flush_task(p);
        release_thread(p);
        call_rcu(&p->rcu, delayed_put_task_struct);
 
@@ -221,7 +221,7 @@ static int will_become_orphaned_pgrp(struct pid *pgrp, struct task_struct *ignor
        do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
                if (p == ignored_task
                                || p->exit_state
-                               || is_init(p->real_parent))
+                               || is_global_init(p->real_parent))
                        continue;
                if (task_pgrp(p->real_parent) != pgrp &&
                    task_session(p->real_parent) == task_session(p)) {
@@ -299,14 +299,14 @@ void __set_special_pids(pid_t session, pid_t pgrp)
 {
        struct task_struct *curr = current->group_leader;
 
-       if (process_session(curr) != session) {
+       if (task_session_nr(curr) != session) {
                detach_pid(curr, PIDTYPE_SID);
-               set_signal_session(curr->signal, session);
+               set_task_session(curr, session);
                attach_pid(curr, PIDTYPE_SID, find_pid(session));
        }
-       if (process_group(curr) != pgrp) {
+       if (task_pgrp_nr(curr) != pgrp) {
                detach_pid(curr, PIDTYPE_PGID);
-               curr->signal->pgrp = pgrp;
+               set_task_pgrp(curr, pgrp);
                attach_pid(curr, PIDTYPE_PGID, find_pid(pgrp));
        }
 }
@@ -400,11 +400,12 @@ void daemonize(const char *name, ...)
        current->fs = fs;
        atomic_inc(&fs->count);
 
-       exit_task_namespaces(current);
-       current->nsproxy = init_task.nsproxy;
-       get_task_namespaces(current);
+       if (current->nsproxy != init_task.nsproxy) {
+               get_nsproxy(init_task.nsproxy);
+               switch_task_namespaces(current, init_task.nsproxy);
+       }
 
-       exit_files(current);
+       exit_files(current);
        current->files = init_task.files;
        atomic_inc(&current->files->count);
 
@@ -492,7 +493,7 @@ void reset_files_struct(struct task_struct *tsk, struct files_struct *files)
 }
 EXPORT_SYMBOL(reset_files_struct);
 
-static inline void __exit_files(struct task_struct *tsk)
+static void __exit_files(struct task_struct *tsk)
 {
        struct files_struct * files = tsk->files;
 
@@ -509,7 +510,7 @@ void exit_files(struct task_struct *tsk)
        __exit_files(tsk);
 }
 
-static inline void __put_fs_struct(struct fs_struct *fs)
+static void __put_fs_struct(struct fs_struct *fs)
 {
        /* No need to hold fs->lock if we are killing it */
        if (atomic_dec_and_test(&fs->count)) {
@@ -530,7 +531,7 @@ void put_fs_struct(struct fs_struct *fs)
        __put_fs_struct(fs);
 }
 
-static inline void __exit_fs(struct task_struct *tsk)
+static void __exit_fs(struct task_struct *tsk)
 {
        struct fs_struct * fs = tsk->fs;
 
@@ -665,19 +666,22 @@ reparent_thread(struct task_struct *p, struct task_struct *father, int traced)
  * the child reaper process (ie "init") in our pid
  * space.
  */
-static void
-forget_original_parent(struct task_struct *father, struct list_head *to_release)
+static void forget_original_parent(struct task_struct *father)
 {
-       struct task_struct *p, *reaper = father;
-       struct list_head *_p, *_n;
+       struct task_struct *p, *n, *reaper = father;
+       struct list_head ptrace_dead;
+
+       INIT_LIST_HEAD(&ptrace_dead);
+
+       write_lock_irq(&tasklist_lock);
 
        do {
                reaper = next_thread(reaper);
                if (reaper == father) {
-                       reaper = child_reaper(father);
+                       reaper = task_child_reaper(father);
                        break;
                }
-       } while (reaper->exit_state);
+       } while (reaper->flags & PF_EXITING);
 
        /*
         * There are only two places where our children can be:
@@ -687,9 +691,8 @@ forget_original_parent(struct task_struct *father, struct list_head *to_release)
         *
         * Search them and reparent children.
         */
-       list_for_each_safe(_p, _n, &father->children) {
+       list_for_each_entry_safe(p, n, &father->children, sibling) {
                int ptrace;
-               p = list_entry(_p, struct task_struct, sibling);
 
                ptrace = p->ptrace;
 
@@ -715,13 +718,23 @@ forget_original_parent(struct task_struct *father, struct list_head *to_release)
                 * while it was being traced by us, to be able to see it in wait4.
                 */
                if (unlikely(ptrace && p->exit_state == EXIT_ZOMBIE && p->exit_signal == -1))
-                       list_add(&p->ptrace_list, to_release);
+                       list_add(&p->ptrace_list, &ptrace_dead);
        }
-       list_for_each_safe(_p, _n, &father->ptrace_children) {
-               p = list_entry(_p, struct task_struct, ptrace_list);
+
+       list_for_each_entry_safe(p, n, &father->ptrace_children, ptrace_list) {
                p->real_parent = reaper;
                reparent_thread(p, father, 1);
        }
+
+       write_unlock_irq(&tasklist_lock);
+       BUG_ON(!list_empty(&father->children));
+       BUG_ON(!list_empty(&father->ptrace_children));
+
+       list_for_each_entry_safe(p, n, &ptrace_dead, ptrace_list) {
+               list_del_init(&p->ptrace_list);
+               release_task(p);
+       }
+
 }
 
 /*
@@ -732,7 +745,6 @@ static void exit_notify(struct task_struct *tsk)
 {
        int state;
        struct task_struct *t;
-       struct list_head ptrace_dead, *_p, *_n;
        struct pid *pgrp;
 
        if (signal_pending(tsk) && !(tsk->signal->flags & SIGNAL_GROUP_EXIT)
@@ -753,8 +765,6 @@ static void exit_notify(struct task_struct *tsk)
                spin_unlock_irq(&tsk->sighand->siglock);
        }
 
-       write_lock_irq(&tasklist_lock);
-
        /*
         * This does two things:
         *
@@ -763,12 +773,10 @@ static void exit_notify(struct task_struct *tsk)
         *      as a result of our exiting, and if they have any stopped
         *      jobs, send them a SIGHUP and then a SIGCONT.  (POSIX 3.2.2.2)
         */
+       forget_original_parent(tsk);
+       exit_task_namespaces(tsk);
 
-       INIT_LIST_HEAD(&ptrace_dead);
-       forget_original_parent(tsk, &ptrace_dead);
-       BUG_ON(!list_empty(&tsk->children));
-       BUG_ON(!list_empty(&tsk->ptrace_children));
-
+       write_lock_irq(&tasklist_lock);
        /*
         * Check to see if any process groups have become orphaned
         * as a result of our exiting, and if they have any stopped
@@ -792,7 +800,7 @@ static void exit_notify(struct task_struct *tsk)
        /* Let father know we died
         *
         * Thread signals are configurable, but you aren't going to use
-        * that to send signals to arbitary processes. 
+        * that to send signals to arbitary processes.
         * That stops right now.
         *
         * If the parent exec id doesn't match the exec id we saved
@@ -833,12 +841,6 @@ static void exit_notify(struct task_struct *tsk)
 
        write_unlock_irq(&tasklist_lock);
 
-       list_for_each_safe(_p, _n, &ptrace_dead) {
-               list_del_init(_p);
-               t = list_entry(_p, struct task_struct, ptrace_list);
-               release_task(t);
-       }
-
        /* If the process is dead, release it - nobody will wait for it */
        if (state == EXIT_DEAD)
                release_task(tsk);
@@ -874,10 +876,35 @@ static inline void check_stack_usage(void) {}
 
 static inline void exit_child_reaper(struct task_struct *tsk)
 {
-       if (likely(tsk->group_leader != child_reaper(tsk)))
+       if (likely(tsk->group_leader != task_child_reaper(tsk)))
                return;
 
-       panic("Attempted to kill init!");
+       if (tsk->nsproxy->pid_ns == &init_pid_ns)
+               panic("Attempted to kill init!");
+
+       /*
+        * @tsk is the last thread in the 'cgroup-init' and is exiting.
+        * Terminate all remaining processes in the namespace and reap them
+        * before exiting @tsk.
+        *
+        * Note that @tsk (last thread of cgroup-init) may not necessarily
+        * be the child-reaper (i.e main thread of cgroup-init) of the
+        * namespace i.e the child_reaper may have already exited.
+        *
+        * Even after a child_reaper exits, we let it inherit orphaned children,
+        * because, pid_ns->child_reaper remains valid as long as there is
+        * at least one living sub-thread in the cgroup init.
+
+        * This living sub-thread of the cgroup-init will be notified when
+        * a child inherited by the 'child-reaper' exits (do_notify_parent()
+        * uses __group_send_sig_info()). Further, when reaping child processes,
+        * do_wait() iterates over children of all living sub threads.
+
+        * i.e even though 'child_reaper' thread is listed as the parent of the
+        * orphaned children, any living sub-thread in the cgroup-init can
+        * perform the role of the child_reaper.
+        */
+       zap_pid_ns_processes(tsk->nsproxy->pid_ns);
 }
 
 fastcall NORET_TYPE void do_exit(long code)
@@ -932,7 +959,7 @@ fastcall NORET_TYPE void do_exit(long code)
 
        if (unlikely(in_atomic()))
                printk(KERN_INFO "note: %s[%d] exited with preempt_count %d\n",
-                               current->comm, current->pid,
+                               current->comm, task_pid_nr(current),
                                preempt_count());
 
        acct_update_integrals(tsk);
@@ -972,7 +999,7 @@ fastcall NORET_TYPE void do_exit(long code)
        __exit_fs(tsk);
        check_stack_usage();
        exit_thread();
-       cpuset_exit(tsk);
+       cgroup_exit(tsk, 1);
        exit_keys(tsk);
 
        if (group_dead && tsk->signal->leader)
@@ -983,7 +1010,6 @@ fastcall NORET_TYPE void do_exit(long code)
                module_put(tsk->binfmt->module);
 
        proc_exit_connector(tsk);
-       exit_task_namespaces(tsk);
        exit_notify(tsk);
 #ifdef CONFIG_NUMA
        mpol_free(tsk->mempolicy);
@@ -1086,15 +1112,17 @@ asmlinkage void sys_exit_group(int error_code)
 static int eligible_child(pid_t pid, int options, struct task_struct *p)
 {
        int err;
+       struct pid_namespace *ns;
 
+       ns = current->nsproxy->pid_ns;
        if (pid > 0) {
-               if (p->pid != pid)
+               if (task_pid_nr_ns(p, ns) != pid)
                        return 0;
        } else if (!pid) {
-               if (process_group(p) != process_group(current))
+               if (task_pgrp_nr_ns(p, ns) != task_pgrp_vnr(current))
                        return 0;
        } else if (pid != -1) {
-               if (process_group(p) != -pid)
+               if (task_pgrp_nr_ns(p, ns) != -pid)
                        return 0;
        }
 
@@ -1164,9 +1192,12 @@ static int wait_task_zombie(struct task_struct *p, int noreap,
 {
        unsigned long state;
        int retval, status, traced;
+       struct pid_namespace *ns;
+
+       ns = current->nsproxy->pid_ns;
 
        if (unlikely(noreap)) {
-               pid_t pid = p->pid;
+               pid_t pid = task_pid_nr_ns(p, ns);
                uid_t uid = p->uid;
                int exit_code = p->exit_code;
                int why, status;
@@ -1285,11 +1316,11 @@ static int wait_task_zombie(struct task_struct *p, int noreap,
                        retval = put_user(status, &infop->si_status);
        }
        if (!retval && infop)
-               retval = put_user(p->pid, &infop->si_pid);
+               retval = put_user(task_pid_nr_ns(p, ns), &infop->si_pid);
        if (!retval && infop)
                retval = put_user(p->uid, &infop->si_uid);
        if (!retval)
-               retval = p->pid;
+               retval = task_pid_nr_ns(p, ns);
 
        if (traced) {
                write_lock_irq(&tasklist_lock);
@@ -1326,6 +1357,7 @@ static int wait_task_stopped(struct task_struct *p, int delayed_group_leader,
                             int __user *stat_addr, struct rusage __user *ru)
 {
        int retval, exit_code;
+       struct pid_namespace *ns;
 
        if (!p->exit_code)
                return 0;
@@ -1344,11 +1376,12 @@ static int wait_task_stopped(struct task_struct *p, int delayed_group_leader,
         * keep holding onto the tasklist_lock while we call getrusage and
         * possibly take page faults for user memory.
         */
+       ns = current->nsproxy->pid_ns;
        get_task_struct(p);
        read_unlock(&tasklist_lock);
 
        if (unlikely(noreap)) {
-               pid_t pid = p->pid;
+               pid_t pid = task_pid_nr_ns(p, ns);
                uid_t uid = p->uid;
                int why = (p->ptrace & PT_PTRACED) ? CLD_TRAPPED : CLD_STOPPED;
 
@@ -1419,11 +1452,11 @@ bail_ref:
        if (!retval && infop)
                retval = put_user(exit_code, &infop->si_status);
        if (!retval && infop)
-               retval = put_user(p->pid, &infop->si_pid);
+               retval = put_user(task_pid_nr_ns(p, ns), &infop->si_pid);
        if (!retval && infop)
                retval = put_user(p->uid, &infop->si_uid);
        if (!retval)
-               retval = p->pid;
+               retval = task_pid_nr_ns(p, ns);
        put_task_struct(p);
 
        BUG_ON(!retval);
@@ -1443,6 +1476,7 @@ static int wait_task_continued(struct task_struct *p, int noreap,
        int retval;
        pid_t pid;
        uid_t uid;
+       struct pid_namespace *ns;
 
        if (!(p->signal->flags & SIGNAL_STOP_CONTINUED))
                return 0;
@@ -1457,7 +1491,8 @@ static int wait_task_continued(struct task_struct *p, int noreap,
                p->signal->flags &= ~SIGNAL_STOP_CONTINUED;
        spin_unlock_irq(&p->sighand->siglock);
 
-       pid = p->pid;
+       ns = current->nsproxy->pid_ns;
+       pid = task_pid_nr_ns(p, ns);
        uid = p->uid;
        get_task_struct(p);
        read_unlock(&tasklist_lock);
@@ -1468,7 +1503,7 @@ static int wait_task_continued(struct task_struct *p, int noreap,
                if (!retval && stat_addr)
                        retval = put_user(0xffff, stat_addr);
                if (!retval)
-                       retval = p->pid;
+                       retval = task_pid_nr_ns(p, ns);
        } else {
                retval = wait_noreap_copyout(p, pid, uid,
                                             CLD_CONTINUED, SIGCONT,
@@ -1517,12 +1552,9 @@ repeat:
        tsk = current;
        do {
                struct task_struct *p;
-               struct list_head *_p;
                int ret;
 
-               list_for_each(_p,&tsk->children) {
-                       p = list_entry(_p, struct task_struct, sibling);
-
+               list_for_each_entry(p, &tsk->children, sibling) {
                        ret = eligible_child(pid, options, p);
                        if (!ret)
                                continue;
@@ -1604,9 +1636,8 @@ check_continued:
                        }
                }
                if (!flag) {
-                       list_for_each(_p, &tsk->ptrace_children) {
-                               p = list_entry(_p, struct task_struct,
-                                               ptrace_list);
+                       list_for_each_entry(p, &tsk->ptrace_children,
+                                           ptrace_list) {
                                if (!eligible_child(pid, options, p))
                                        continue;
                                flag = 1;
index 490495a39c7e65cb0eb239b2b6474ce5d58b718b..ddafdfac9456e151b2d8731b52475a5af4ca68e1 100644 (file)
@@ -29,7 +29,7 @@
 #include <linux/nsproxy.h>
 #include <linux/capability.h>
 #include <linux/cpu.h>
-#include <linux/cpuset.h>
+#include <linux/cgroup.h>
 #include <linux/security.h>
 #include <linux/swap.h>
 #include <linux/syscalls.h>
@@ -50,6 +50,7 @@
 #include <linux/taskstats_kern.h>
 #include <linux/random.h>
 #include <linux/tty.h>
+#include <linux/proc_fs.h>
 
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
@@ -116,7 +117,7 @@ EXPORT_SYMBOL(free_task);
 
 void __put_task_struct(struct task_struct *tsk)
 {
-       WARN_ON(!(tsk->exit_state & (EXIT_DEAD | EXIT_ZOMBIE)));
+       WARN_ON(!tsk->exit_state);
        WARN_ON(atomic_read(&tsk->usage));
        WARN_ON(tsk == current);
 
@@ -205,7 +206,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
 }
 
 #ifdef CONFIG_MMU
-static inline int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
+static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
 {
        struct vm_area_struct *mpnt, *tmp, **pprev;
        struct rb_node **rb_link, *rb_parent;
@@ -268,7 +269,7 @@ static inline int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
                        get_file(file);
                        if (tmp->vm_flags & VM_DENYWRITE)
                                atomic_dec(&inode->i_writecount);
-      
+
                        /* insert tmp into the share list, just after mpnt */
                        spin_lock(&file->f_mapping->i_mmap_lock);
                        tmp->vm_truncate_count = mpnt->vm_truncate_count;
@@ -331,7 +332,7 @@ static inline void mm_free_pgd(struct mm_struct * mm)
 #define mm_free_pgd(mm)
 #endif /* CONFIG_MMU */
 
- __cacheline_aligned_in_smp DEFINE_SPINLOCK(mmlist_lock);
+__cacheline_aligned_in_smp DEFINE_SPINLOCK(mmlist_lock);
 
 #define allocate_mm()  (kmem_cache_alloc(mm_cachep, GFP_KERNEL))
 #define free_mm(mm)    (kmem_cache_free(mm_cachep, (mm)))
@@ -583,7 +584,7 @@ fail_nomem:
        return retval;
 }
 
-static inline struct fs_struct *__copy_fs_struct(struct fs_struct *old)
+static struct fs_struct *__copy_fs_struct(struct fs_struct *old)
 {
        struct fs_struct *fs = kmem_cache_alloc(fs_cachep, GFP_KERNEL);
        /* We don't need to lock fs - think why ;-) */
@@ -615,7 +616,7 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old)
 
 EXPORT_SYMBOL_GPL(copy_fs_struct);
 
-static inline int copy_fs(unsigned long clone_flags, struct task_struct * tsk)
+static int copy_fs(unsigned long clone_flags, struct task_struct *tsk)
 {
        if (clone_flags & CLONE_FS) {
                atomic_inc(&current->fs->count);
@@ -738,8 +739,8 @@ static struct files_struct *dup_fd(struct files_struct *oldf, int *errorp)
        /* compute the remainder to be cleared */
        size = (new_fdt->max_fds - open_files) * sizeof(struct file *);
 
-       /* This is long word aligned thus could use a optimized version */ 
-       memset(new_fds, 0, size); 
+       /* This is long word aligned thus could use a optimized version */
+       memset(new_fds, 0, size);
 
        if (new_fdt->max_fds > open_files) {
                int left = (new_fdt->max_fds-open_files)/8;
@@ -818,7 +819,7 @@ int unshare_files(void)
 
 EXPORT_SYMBOL(unshare_files);
 
-static inline int copy_sighand(unsigned long clone_flags, struct task_struct * tsk)
+static int copy_sighand(unsigned long clone_flags, struct task_struct *tsk)
 {
        struct sighand_struct *sig;
 
@@ -841,7 +842,7 @@ void __cleanup_sighand(struct sighand_struct *sighand)
                kmem_cache_free(sighand_cachep, sighand);
 }
 
-static inline int copy_signal(unsigned long clone_flags, struct task_struct * tsk)
+static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
 {
        struct signal_struct *sig;
        int ret;
@@ -923,7 +924,7 @@ void __cleanup_signal(struct signal_struct *sig)
        kmem_cache_free(signal_cachep, sig);
 }
 
-static inline void cleanup_signal(struct task_struct *tsk)
+static void cleanup_signal(struct task_struct *tsk)
 {
        struct signal_struct *sig = tsk->signal;
 
@@ -933,7 +934,7 @@ static inline void cleanup_signal(struct task_struct *tsk)
                __cleanup_signal(sig);
 }
 
-static inline void copy_flags(unsigned long clone_flags, struct task_struct *p)
+static void copy_flags(unsigned long clone_flags, struct task_struct *p)
 {
        unsigned long new_flags = p->flags;
 
@@ -942,16 +943,17 @@ static inline void copy_flags(unsigned long clone_flags, struct task_struct *p)
        if (!(clone_flags & CLONE_PTRACE))
                p->ptrace = 0;
        p->flags = new_flags;
+       clear_freeze_flag(p);
 }
 
 asmlinkage long sys_set_tid_address(int __user *tidptr)
 {
        current->clear_child_tid = tidptr;
 
-       return current->pid;
+       return task_pid_vnr(current);
 }
 
-static inline void rt_mutex_init_task(struct task_struct *p)
+static void rt_mutex_init_task(struct task_struct *p)
 {
        spin_lock_init(&p->pi_lock);
 #ifdef CONFIG_RT_MUTEXES
@@ -972,12 +974,12 @@ static struct task_struct *copy_process(unsigned long clone_flags,
                                        unsigned long stack_start,
                                        struct pt_regs *regs,
                                        unsigned long stack_size,
-                                       int __user *parent_tidptr,
                                        int __user *child_tidptr,
                                        struct pid *pid)
 {
        int retval;
-       struct task_struct *p = NULL;
+       struct task_struct *p;
+       int cgroup_callbacks_done = 0;
 
        if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
                return ERR_PTR(-EINVAL);
@@ -1041,12 +1043,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        p->did_exec = 0;
        delayacct_tsk_init(p);  /* Must remain after dup_task_struct() */
        copy_flags(clone_flags, p);
-       p->pid = pid_nr(pid);
-       retval = -EFAULT;
-       if (clone_flags & CLONE_PARENT_SETTID)
-               if (put_user(p->pid, parent_tidptr))
-                       goto bad_fork_cleanup_delays_binfmt;
-
        INIT_LIST_HEAD(&p->children);
        INIT_LIST_HEAD(&p->sibling);
        p->vfork_done = NULL;
@@ -1058,6 +1054,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        p->utime = cputime_zero;
        p->stime = cputime_zero;
        p->gtime = cputime_zero;
+       p->utimescaled = cputime_zero;
+       p->stimescaled = cputime_zero;
 
 #ifdef CONFIG_TASK_XACCT
        p->rchar = 0;           /* I/O counter: bytes read */
@@ -1068,12 +1066,12 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        task_io_accounting_init(p);
        acct_clear_integrals(p);
 
-       p->it_virt_expires = cputime_zero;
+       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]);
+       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]);
 
        p->lock_depth = -1;             /* -1 = no lock */
        do_posix_clock_monotonic_gettime(&p->start_time);
@@ -1083,15 +1081,14 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        p->security = NULL;
 #endif
        p->io_context = NULL;
-       p->io_wait = NULL;
        p->audit_context = NULL;
-       cpuset_fork(p);
+       cgroup_fork(p);
 #ifdef CONFIG_NUMA
        p->mempolicy = mpol_copy(p->mempolicy);
        if (IS_ERR(p->mempolicy)) {
                retval = PTR_ERR(p->mempolicy);
                p->mempolicy = NULL;
-               goto bad_fork_cleanup_cpuset;
+               goto bad_fork_cleanup_cgroup;
        }
        mpol_fix_fork_child_flag(p);
 #endif
@@ -1124,10 +1121,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        p->blocked_on = NULL; /* not blocked yet */
 #endif
 
-       p->tgid = p->pid;
-       if (clone_flags & CLONE_THREAD)
-               p->tgid = current->tgid;
-
        if ((retval = security_task_alloc(p)))
                goto bad_fork_cleanup_policy;
        if ((retval = audit_alloc(p)))
@@ -1153,6 +1146,24 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        if (retval)
                goto bad_fork_cleanup_namespaces;
 
+       if (pid != &init_struct_pid) {
+               retval = -ENOMEM;
+               pid = alloc_pid(task_active_pid_ns(p));
+               if (!pid)
+                       goto bad_fork_cleanup_namespaces;
+
+               if (clone_flags & CLONE_NEWPID) {
+                       retval = pid_ns_prepare_proc(task_active_pid_ns(p));
+                       if (retval < 0)
+                               goto bad_fork_free_pid;
+               }
+       }
+
+       p->pid = pid_nr(pid);
+       p->tgid = p->pid;
+       if (clone_flags & CLONE_THREAD)
+               p->tgid = current->tgid;
+
        p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
        /*
         * Clear TID on mm_release()?
@@ -1202,6 +1213,12 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        /* Perform scheduler related setup. Assign this task to a CPU. */
        sched_fork(p, clone_flags);
 
+       /* Now that the task is set up, run cgroup callbacks if
+        * necessary. We need to run them before the task is visible
+        * on the tasklist. */
+       cgroup_fork_callbacks(p);
+       cgroup_callbacks_done = 1;
+
        /* Need tasklist lock for parent etc handling! */
        write_lock_irq(&tasklist_lock);
 
@@ -1239,12 +1256,12 @@ static struct task_struct *copy_process(unsigned long clone_flags,
         * A fatal signal pending means that current will exit, so the new
         * thread can't slip out of an OOM kill (or normal SIGKILL).
         */
-       recalc_sigpending();
+       recalc_sigpending();
        if (signal_pending(current)) {
                spin_unlock(&current->sighand->siglock);
                write_unlock_irq(&tasklist_lock);
                retval = -ERESTARTNOINTR;
-               goto bad_fork_cleanup_namespaces;
+               goto bad_fork_free_pid;
        }
 
        if (clone_flags & CLONE_THREAD) {
@@ -1273,11 +1290,22 @@ static struct task_struct *copy_process(unsigned long clone_flags,
                        __ptrace_link(p, current->parent);
 
                if (thread_group_leader(p)) {
-                       p->signal->tty = current->signal->tty;
-                       p->signal->pgrp = process_group(current);
-                       set_signal_session(p->signal, process_session(current));
-                       attach_pid(p, PIDTYPE_PGID, task_pgrp(current));
-                       attach_pid(p, PIDTYPE_SID, task_session(current));
+                       if (clone_flags & CLONE_NEWPID) {
+                               p->nsproxy->pid_ns->child_reaper = p;
+                               p->signal->tty = NULL;
+                               set_task_pgrp(p, p->pid);
+                               set_task_session(p, p->pid);
+                               attach_pid(p, PIDTYPE_PGID, pid);
+                               attach_pid(p, PIDTYPE_SID, pid);
+                       } else {
+                               p->signal->tty = current->signal->tty;
+                               set_task_pgrp(p, task_pgrp_nr(current));
+                               set_task_session(p, task_session_nr(current));
+                               attach_pid(p, PIDTYPE_PGID,
+                                               task_pgrp(current));
+                               attach_pid(p, PIDTYPE_SID,
+                                               task_session(current));
+                       }
 
                        list_add_tail_rcu(&p->tasks, &init_task.tasks);
                        __get_cpu_var(process_counts)++;
@@ -1290,8 +1318,12 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        spin_unlock(&current->sighand->siglock);
        write_unlock_irq(&tasklist_lock);
        proc_fork_connector(p);
+       cgroup_post_fork(p);
        return p;
 
+bad_fork_free_pid:
+       if (pid != &init_struct_pid)
+               free_pid(pid);
 bad_fork_cleanup_namespaces:
        exit_task_namespaces(p);
 bad_fork_cleanup_keys:
@@ -1316,10 +1348,9 @@ bad_fork_cleanup_security:
 bad_fork_cleanup_policy:
 #ifdef CONFIG_NUMA
        mpol_free(p->mempolicy);
-bad_fork_cleanup_cpuset:
+bad_fork_cleanup_cgroup:
 #endif
-       cpuset_exit(p);
-bad_fork_cleanup_delays_binfmt:
+       cgroup_exit(p, cgroup_callbacks_done);
        delayacct_tsk_free(p);
        if (p->binfmt)
                module_put(p->binfmt->module);
@@ -1346,7 +1377,7 @@ struct task_struct * __cpuinit fork_idle(int cpu)
        struct task_struct *task;
        struct pt_regs regs;
 
-       task = copy_process(CLONE_VM, 0, idle_regs(&regs), 0, NULL, NULL,
+       task = copy_process(CLONE_VM, 0, idle_regs(&regs), 0, NULL,
                                &init_struct_pid);
        if (!IS_ERR(task))
                init_idle(task, cpu);
@@ -1354,7 +1385,7 @@ struct task_struct * __cpuinit fork_idle(int cpu)
        return task;
 }
 
-static inline int fork_traceflag (unsigned clone_flags)
+static int fork_traceflag(unsigned clone_flags)
 {
        if (clone_flags & CLONE_UNTRACED)
                return 0;
@@ -1385,19 +1416,16 @@ long do_fork(unsigned long clone_flags,
 {
        struct task_struct *p;
        int trace = 0;
-       struct pid *pid = alloc_pid();
        long nr;
 
-       if (!pid)
-               return -EAGAIN;
-       nr = pid->nr;
        if (unlikely(current->ptrace)) {
                trace = fork_traceflag (clone_flags);
                if (trace)
                        clone_flags |= CLONE_PTRACE;
        }
 
-       p = copy_process(clone_flags, stack_start, regs, stack_size, parent_tidptr, child_tidptr, pid);
+       p = copy_process(clone_flags, stack_start, regs, stack_size,
+                       child_tidptr, NULL);
        /*
         * Do this prior waking up the new thread - the thread pointer
         * might get invalid after that point, if the thread exits quickly.
@@ -1405,6 +1433,17 @@ long do_fork(unsigned long clone_flags,
        if (!IS_ERR(p)) {
                struct completion vfork;
 
+               /*
+                * this is enough to call pid_nr_ns here, but this if
+                * improves optimisation of regular fork()
+                */
+               nr = (clone_flags & CLONE_NEWPID) ?
+                       task_pid_nr_ns(p, current->nsproxy->pid_ns) :
+                               task_pid_vnr(p);
+
+               if (clone_flags & CLONE_PARENT_SETTID)
+                       put_user(nr, parent_tidptr);
+
                if (clone_flags & CLONE_VFORK) {
                        p->vfork_done = &vfork;
                        init_completion(&vfork);
@@ -1438,7 +1477,6 @@ long do_fork(unsigned long clone_flags,
                        }
                }
        } else {
-               free_pid(pid);
                nr = PTR_ERR(p);
        }
        return nr;
@@ -1483,7 +1521,7 @@ void __init proc_caches_init(void)
  * Check constraints on flags passed to the unshare system call and
  * force unsharing of additional process context as appropriate.
  */
-static inline void check_unshare_flags(unsigned long *flags_ptr)
+static void check_unshare_flags(unsigned long *flags_ptr)
 {
        /*
         * If unsharing a thread from a thread group, must also
@@ -1615,7 +1653,7 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
        struct mm_struct *mm, *new_mm = NULL, *active_mm = NULL;
        struct files_struct *fd, *new_fd = NULL;
        struct sem_undo_list *new_ulist = NULL;
-       struct nsproxy *new_nsproxy = NULL, *old_nsproxy = NULL;
+       struct nsproxy *new_nsproxy = NULL;
 
        check_unshare_flags(&unshare_flags);
 
@@ -1645,14 +1683,13 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
 
        if (new_fs ||  new_mm || new_fd || new_ulist || new_nsproxy) {
 
-               task_lock(current);
-
                if (new_nsproxy) {
-                       old_nsproxy = current->nsproxy;
-                       current->nsproxy = new_nsproxy;
-                       new_nsproxy = old_nsproxy;
+                       switch_task_namespaces(current, new_nsproxy);
+                       new_nsproxy = NULL;
                }
 
+               task_lock(current);
+
                if (new_fs) {
                        fs = current->fs;
                        current->fs = new_fs;
index d725676d84f3580813161678394bc9220630af82..32710451dc20ea7763cc22d02f0363c9155a772f 100644 (file)
@@ -53,6 +53,9 @@
 #include <linux/signal.h>
 #include <linux/module.h>
 #include <linux/magic.h>
+#include <linux/pid.h>
+#include <linux/nsproxy.h>
+
 #include <asm/futex.h>
 
 #include "rtmutex_common.h"
@@ -293,7 +296,7 @@ EXPORT_SYMBOL_GPL(get_futex_key_refs);
  */
 void drop_futex_key_refs(union futex_key *key)
 {
-       if (key->both.ptr == 0)
+       if (!key->both.ptr)
                return;
        switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) {
                case FUT_OFF_INODE:
@@ -443,8 +446,7 @@ static struct task_struct * futex_find_get_task(pid_t pid)
        struct task_struct *p;
 
        rcu_read_lock();
-       p = find_task_by_pid(pid);
-
+       p = find_task_by_vpid(pid);
        if (!p || ((current->euid != p->euid) && (current->euid != p->uid)))
                p = ERR_PTR(-ESRCH);
        else
@@ -653,7 +655,7 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this)
        if (!(uval & FUTEX_OWNER_DIED)) {
                int ret = 0;
 
-               newval = FUTEX_WAITERS | new_owner->pid;
+               newval = FUTEX_WAITERS | task_pid_vnr(new_owner);
 
                curval = cmpxchg_futex_value_locked(uaddr, uval, newval);
 
@@ -1046,7 +1048,7 @@ static int unqueue_me(struct futex_q *q)
  retry:
        lock_ptr = q->lock_ptr;
        barrier();
-       if (lock_ptr != 0) {
+       if (lock_ptr != NULL) {
                spin_lock(lock_ptr);
                /*
                 * q->lock_ptr can change between reading it and
@@ -1106,7 +1108,7 @@ static void unqueue_me_pi(struct futex_q *q)
 static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q,
                                struct task_struct *curr)
 {
-       u32 newtid = curr->pid | FUTEX_WAITERS;
+       u32 newtid = task_pid_vnr(curr) | FUTEX_WAITERS;
        struct futex_pi_state *pi_state = q->pi_state;
        u32 uval, curval, newval;
        int ret;
@@ -1368,7 +1370,7 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared,
         * (by doing a 0 -> TID atomic cmpxchg), while holding all
         * the locks. It will most likely not succeed.
         */
-       newval = current->pid;
+       newval = task_pid_vnr(current);
 
        curval = cmpxchg_futex_value_locked(uaddr, 0, newval);
 
@@ -1379,7 +1381,7 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared,
         * Detect deadlocks. In case of REQUEUE_PI this is a valid
         * situation and we return success to user space.
         */
-       if (unlikely((curval & FUTEX_TID_MASK) == current->pid)) {
+       if (unlikely((curval & FUTEX_TID_MASK) == task_pid_vnr(current))) {
                ret = -EDEADLK;
                goto out_unlock_release_sem;
        }
@@ -1408,7 +1410,7 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared,
         */
        if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) {
                /* Keep the OWNER_DIED bit */
-               newval = (curval & ~FUTEX_TID_MASK) | current->pid;
+               newval = (curval & ~FUTEX_TID_MASK) | task_pid_vnr(current);
                ownerdied = 0;
                lock_taken = 1;
        }
@@ -1587,7 +1589,7 @@ retry:
        /*
         * We release only a lock we actually own:
         */
-       if ((uval & FUTEX_TID_MASK) != current->pid)
+       if ((uval & FUTEX_TID_MASK) != task_pid_vnr(current))
                return -EPERM;
        /*
         * First take all the futex related locks:
@@ -1608,7 +1610,7 @@ retry_unlocked:
         * anyone else up:
         */
        if (!(uval & FUTEX_OWNER_DIED))
-               uval = cmpxchg_futex_value_locked(uaddr, current->pid, 0);
+               uval = cmpxchg_futex_value_locked(uaddr, task_pid_vnr(current), 0);
 
 
        if (unlikely(uval == -EFAULT))
@@ -1617,7 +1619,7 @@ retry_unlocked:
         * Rare case: we managed to release the lock atomically,
         * no need to wake anyone else up:
         */
-       if (unlikely(uval == current->pid))
+       if (unlikely(uval == task_pid_vnr(current)))
                goto out_unlock;
 
        /*
@@ -1854,7 +1856,7 @@ sys_get_robust_list(int pid, struct robust_list_head __user * __user *head_ptr,
 
                ret = -ESRCH;
                rcu_read_lock();
-               p = find_task_by_pid(pid);
+               p = find_task_by_vpid(pid);
                if (!p)
                        goto err_unlock;
                ret = -EPERM;
@@ -1887,7 +1889,7 @@ retry:
        if (get_user(uval, uaddr))
                return -1;
 
-       if ((uval & FUTEX_TID_MASK) == curr->pid) {
+       if ((uval & FUTEX_TID_MASK) == task_pid_vnr(curr)) {
                /*
                 * Ok, this dying thread is truly holding a futex
                 * of interest. Set the OWNER_DIED bit atomically
index 2c2e2954b713b2681a5bf120c0097cb2c2affc8c..00b572666cc76178d81979f512dc9e3078b08fda 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/linkage.h>
 #include <linux/compat.h>
+#include <linux/nsproxy.h>
 #include <linux/futex.h>
 
 #include <asm/uaccess.h>
@@ -124,7 +125,7 @@ compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr,
 
                ret = -ESRCH;
                read_lock(&tasklist_lock);
-               p = find_task_by_pid(pid);
+               p = find_task_by_vpid(pid);
                if (!p)
                        goto err_unlock;
                ret = -EPERM;
index dc8a4451d79b15d64a37caf55c9dc4595c6ec5d2..b6d2ff7e37ee280d266ecc98ed63cb2d8f48d0f9 100644 (file)
@@ -412,7 +412,7 @@ static int hrtimer_reprogram(struct hrtimer *timer,
        /*
         * When the callback is running, we do not reprogram the clock event
         * device. The timer callback is either running on a different CPU or
-        * the callback is executed in the hrtimer_interupt context. The
+        * the callback is executed in the hrtimer_interrupt context. The
         * reprogramming is handled either by the softirq, which called the
         * callback or at the end of the hrtimer_interrupt.
         */
@@ -638,7 +638,7 @@ void __timer_stats_hrtimer_set_start_info(struct hrtimer *timer, void *addr)
 #endif
 
 /*
- * Counterpart to lock_timer_base above:
+ * Counterpart to lock_hrtimer_base above:
  */
 static inline
 void unlock_hrtimer_base(const struct hrtimer *timer, unsigned long *flags)
@@ -1286,8 +1286,7 @@ static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mod
 long __sched hrtimer_nanosleep_restart(struct restart_block *restart)
 {
        struct hrtimer_sleeper t;
-       struct timespec __user *rmtp;
-       struct timespec tu;
+       struct timespec *rmtp;
        ktime_t time;
 
        restart->fn = do_no_restart_syscall;
@@ -1298,14 +1297,12 @@ long __sched hrtimer_nanosleep_restart(struct restart_block *restart)
        if (do_nanosleep(&t, HRTIMER_MODE_ABS))
                return 0;
 
-       rmtp = (struct timespec __user *) restart->arg1;
+       rmtp = (struct timespec *)restart->arg1;
        if (rmtp) {
                time = ktime_sub(t.timer.expires, t.timer.base->get_time());
                if (time.tv64 <= 0)
                        return 0;
-               tu = ktime_to_timespec(time);
-               if (copy_to_user(rmtp, &tu, sizeof(tu)))
-                       return -EFAULT;
+               *rmtp = ktime_to_timespec(time);
        }
 
        restart->fn = hrtimer_nanosleep_restart;
@@ -1314,12 +1311,11 @@ long __sched hrtimer_nanosleep_restart(struct restart_block *restart)
        return -ERESTART_RESTARTBLOCK;
 }
 
-long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
+long hrtimer_nanosleep(struct timespec *rqtp, struct timespec *rmtp,
                       const enum hrtimer_mode mode, const clockid_t clockid)
 {
        struct restart_block *restart;
        struct hrtimer_sleeper t;
-       struct timespec tu;
        ktime_t rem;
 
        hrtimer_init(&t.timer, clockid, mode);
@@ -1335,9 +1331,7 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
                rem = ktime_sub(t.timer.expires, t.timer.base->get_time());
                if (rem.tv64 <= 0)
                        return 0;
-               tu = ktime_to_timespec(rem);
-               if (copy_to_user(rmtp, &tu, sizeof(tu)))
-                       return -EFAULT;
+               *rmtp = ktime_to_timespec(rem);
        }
 
        restart = &current_thread_info()->restart_block;
@@ -1353,7 +1347,8 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
 asmlinkage long
 sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp)
 {
-       struct timespec tu;
+       struct timespec tu, rmt;
+       int ret;
 
        if (copy_from_user(&tu, rqtp, sizeof(tu)))
                return -EFAULT;
@@ -1361,7 +1356,15 @@ sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp)
        if (!timespec_valid(&tu))
                return -EINVAL;
 
-       return hrtimer_nanosleep(&tu, rmtp, HRTIMER_MODE_REL, CLOCK_MONOTONIC);
+       ret = hrtimer_nanosleep(&tu, rmtp ? &rmt : NULL, HRTIMER_MODE_REL,
+                               CLOCK_MONOTONIC);
+
+       if (ret && rmtp) {
+               if (copy_to_user(rmtp, &rmt, sizeof(*rmtp)))
+                       return -EFAULT;
+       }
+
+       return ret;
 }
 
 /*
index 80eab7a0420597ec0c27fe7eaefe12a5868674b9..1f314221d534be091d809628b39f12ccba4e997e 100644 (file)
 void synchronize_irq(unsigned int irq)
 {
        struct irq_desc *desc = irq_desc + irq;
+       unsigned int status;
 
        if (irq >= NR_IRQS)
                return;
 
-       while (desc->status & IRQ_INPROGRESS)
-               cpu_relax();
+       do {
+               unsigned long flags;
+
+               /*
+                * Wait until we're out of the critical section.  This might
+                * give the wrong answer due to the lack of memory barriers.
+                */
+               while (desc->status & IRQ_INPROGRESS)
+                       cpu_relax();
+
+               /* Ok, that indicated we're done: double-check carefully. */
+               spin_lock_irqsave(&desc->lock, flags);
+               status = desc->status;
+               spin_unlock_irqrestore(&desc->lock, flags);
+
+               /* Oops, that failed? */
+       } while (status & IRQ_INPROGRESS);
 }
 EXPORT_SYMBOL(synchronize_irq);
 
index 3205e8e114fa361eff4a1698c9a3ec2bbf4e730f..2fab344dbf56c737b39feb3951e822e5911a775b 100644 (file)
@@ -130,7 +130,7 @@ asmlinkage long sys_getitimer(int which, struct itimerval __user *value)
 enum hrtimer_restart it_real_fn(struct hrtimer *timer)
 {
        struct signal_struct *sig =
-           container_of(timer, struct signal_struct, real_timer);
+               container_of(timer, struct signal_struct, real_timer);
 
        send_group_sig_info(SIGALRM, SEND_SIG_PRIV, sig->tsk);
 
@@ -291,6 +291,6 @@ asmlinkage long sys_setitimer(int which,
                return error;
 
        if (copy_to_user(ovalue, &get_buffer, sizeof(get_buffer)))
-               return -EFAULT; 
+               return -EFAULT;
        return 0;
 }
index 7885269b0da2589f08fcf655cc0ecfa9c28c9a37..aa74a1ef2da8003768519e4283d2b392be0a4171 100644 (file)
@@ -51,7 +51,7 @@ struct resource crashk_res = {
 
 int kexec_should_crash(struct task_struct *p)
 {
-       if (in_interrupt() || !p->pid || is_init(p) || panic_on_oops)
+       if (in_interrupt() || !p->pid || is_global_init(p) || panic_on_oops)
                return 1;
        return 0;
 }
@@ -785,7 +785,7 @@ static int kimage_load_normal_segment(struct kimage *image,
                size_t uchunk, mchunk;
 
                page = kimage_alloc_page(image, GFP_HIGHUSER, maddr);
-               if (page == 0) {
+               if (!page) {
                        result  = -ENOMEM;
                        goto out;
                }
@@ -844,7 +844,7 @@ static int kimage_load_crash_segment(struct kimage *image,
                size_t uchunk, mchunk;
 
                page = pfn_to_page(maddr >> PAGE_SHIFT);
-               if (page == 0) {
+               if (!page) {
                        result  = -ENOMEM;
                        goto out;
                }
@@ -1146,6 +1146,172 @@ static int __init crash_notes_memory_init(void)
 }
 module_init(crash_notes_memory_init)
 
+
+/*
+ * parsing the "crashkernel" commandline
+ *
+ * this code is intended to be called from architecture specific code
+ */
+
+
+/*
+ * This function parses command lines in the format
+ *
+ *   crashkernel=ramsize-range:size[,...][@offset]
+ *
+ * The function returns 0 on success and -EINVAL on failure.
+ */
+static int __init parse_crashkernel_mem(char                   *cmdline,
+                                       unsigned long long      system_ram,
+                                       unsigned long long      *crash_size,
+                                       unsigned long long      *crash_base)
+{
+       char *cur = cmdline, *tmp;
+
+       /* for each entry of the comma-separated list */
+       do {
+               unsigned long long start, end = ULLONG_MAX, size;
+
+               /* get the start of the range */
+               start = memparse(cur, &tmp);
+               if (cur == tmp) {
+                       pr_warning("crashkernel: Memory value expected\n");
+                       return -EINVAL;
+               }
+               cur = tmp;
+               if (*cur != '-') {
+                       pr_warning("crashkernel: '-' expected\n");
+                       return -EINVAL;
+               }
+               cur++;
+
+               /* if no ':' is here, than we read the end */
+               if (*cur != ':') {
+                       end = memparse(cur, &tmp);
+                       if (cur == tmp) {
+                               pr_warning("crashkernel: Memory "
+                                               "value expected\n");
+                               return -EINVAL;
+                       }
+                       cur = tmp;
+                       if (end <= start) {
+                               pr_warning("crashkernel: end <= start\n");
+                               return -EINVAL;
+                       }
+               }
+
+               if (*cur != ':') {
+                       pr_warning("crashkernel: ':' expected\n");
+                       return -EINVAL;
+               }
+               cur++;
+
+               size = memparse(cur, &tmp);
+               if (cur == tmp) {
+                       pr_warning("Memory value expected\n");
+                       return -EINVAL;
+               }
+               cur = tmp;
+               if (size >= system_ram) {
+                       pr_warning("crashkernel: invalid size\n");
+                       return -EINVAL;
+               }
+
+               /* match ? */
+               if (system_ram >= start && system_ram <= end) {
+                       *crash_size = size;
+                       break;
+               }
+       } while (*cur++ == ',');
+
+       if (*crash_size > 0) {
+               while (*cur != ' ' && *cur != '@')
+                       cur++;
+               if (*cur == '@') {
+                       cur++;
+                       *crash_base = memparse(cur, &tmp);
+                       if (cur == tmp) {
+                               pr_warning("Memory value expected "
+                                               "after '@'\n");
+                               return -EINVAL;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * That function parses "simple" (old) crashkernel command lines like
+ *
+ *     crashkernel=size[@offset]
+ *
+ * It returns 0 on success and -EINVAL on failure.
+ */
+static int __init parse_crashkernel_simple(char                *cmdline,
+                                          unsigned long long   *crash_size,
+                                          unsigned long long   *crash_base)
+{
+       char *cur = cmdline;
+
+       *crash_size = memparse(cmdline, &cur);
+       if (cmdline == cur) {
+               pr_warning("crashkernel: memory value expected\n");
+               return -EINVAL;
+       }
+
+       if (*cur == '@')
+               *crash_base = memparse(cur+1, &cur);
+
+       return 0;
+}
+
+/*
+ * That function is the entry point for command line parsing and should be
+ * called from the arch-specific code.
+ */
+int __init parse_crashkernel(char               *cmdline,
+                            unsigned long long system_ram,
+                            unsigned long long *crash_size,
+                            unsigned long long *crash_base)
+{
+       char    *p = cmdline, *ck_cmdline = NULL;
+       char    *first_colon, *first_space;
+
+       BUG_ON(!crash_size || !crash_base);
+       *crash_size = 0;
+       *crash_base = 0;
+
+       /* find crashkernel and use the last one if there are more */
+       p = strstr(p, "crashkernel=");
+       while (p) {
+               ck_cmdline = p;
+               p = strstr(p+1, "crashkernel=");
+       }
+
+       if (!ck_cmdline)
+               return -EINVAL;
+
+       ck_cmdline += 12; /* strlen("crashkernel=") */
+
+       /*
+        * if the commandline contains a ':', then that's the extended
+        * syntax -- if not, it must be the classic syntax
+        */
+       first_colon = strchr(ck_cmdline, ':');
+       first_space = strchr(ck_cmdline, ' ');
+       if (first_colon && (!first_space || first_colon < first_space))
+               return parse_crashkernel_mem(ck_cmdline, system_ram,
+                               crash_size, crash_base);
+       else
+               return parse_crashkernel_simple(ck_cmdline, crash_size,
+                               crash_base);
+
+       return 0;
+}
+
+
+
 void crash_save_vmcoreinfo(void)
 {
        u32 *buf;
index a6f1ee9c92d9fb7900ae02e44debe938a293aedb..55fe0c7cd95fc6776dda4f93d85fa1541200ebb1 100644 (file)
@@ -511,11 +511,11 @@ static void lockdep_print_held_locks(struct task_struct *curr)
        int i, depth = curr->lockdep_depth;
 
        if (!depth) {
-               printk("no locks held by %s/%d.\n", curr->comm, curr->pid);
+               printk("no locks held by %s/%d.\n", curr->comm, task_pid_nr(curr));
                return;
        }
        printk("%d lock%s held by %s/%d:\n",
-               depth, depth > 1 ? "s" : "", curr->comm, curr->pid);
+               depth, depth > 1 ? "s" : "", curr->comm, task_pid_nr(curr));
 
        for (i = 0; i < depth; i++) {
                printk(" #%d: ", i);
@@ -904,7 +904,7 @@ print_circular_bug_header(struct lock_list *entry, unsigned int depth)
        print_kernel_version();
        printk(  "-------------------------------------------------------\n");
        printk("%s/%d is trying to acquire lock:\n",
-               curr->comm, curr->pid);
+               curr->comm, task_pid_nr(curr));
        print_lock(check_source);
        printk("\nbut task is already holding lock:\n");
        print_lock(check_target);
@@ -1085,7 +1085,7 @@ print_bad_irq_dependency(struct task_struct *curr,
        print_kernel_version();
        printk(  "------------------------------------------------------\n");
        printk("%s/%d [HC%u[%lu]:SC%u[%lu]:HE%u:SE%u] is trying to acquire:\n",
-               curr->comm, curr->pid,
+               curr->comm, task_pid_nr(curr),
                curr->hardirq_context, hardirq_count() >> HARDIRQ_SHIFT,
                curr->softirq_context, softirq_count() >> SOFTIRQ_SHIFT,
                curr->hardirqs_enabled,
@@ -1237,7 +1237,7 @@ print_deadlock_bug(struct task_struct *curr, struct held_lock *prev,
        print_kernel_version();
        printk(  "---------------------------------------------\n");
        printk("%s/%d is trying to acquire lock:\n",
-               curr->comm, curr->pid);
+               curr->comm, task_pid_nr(curr));
        print_lock(next);
        printk("\nbut task is already holding lock:\n");
        print_lock(prev);
@@ -1521,7 +1521,7 @@ cache_hit:
 }
 
 static int validate_chain(struct task_struct *curr, struct lockdep_map *lock,
-               struct held_lock *hlock, int chain_head, u64 chain_key)
+               struct held_lock *hlock, int chain_head, u64 chain_key)
 {
        /*
         * Trylock needs to maintain the stack of held locks, but it
@@ -1641,7 +1641,7 @@ print_usage_bug(struct task_struct *curr, struct held_lock *this,
                usage_str[prev_bit], usage_str[new_bit]);
 
        printk("%s/%d [HC%u[%lu]:SC%u[%lu]:HE%u:SE%u] takes:\n",
-               curr->comm, curr->pid,
+               curr->comm, task_pid_nr(curr),
                trace_hardirq_context(curr), hardirq_count() >> HARDIRQ_SHIFT,
                trace_softirq_context(curr), softirq_count() >> SOFTIRQ_SHIFT,
                trace_hardirqs_enabled(curr),
@@ -1694,7 +1694,7 @@ print_irq_inversion_bug(struct task_struct *curr, struct lock_class *other,
        print_kernel_version();
        printk(  "---------------------------------------------------------\n");
        printk("%s/%d just changed the state of lock:\n",
-               curr->comm, curr->pid);
+               curr->comm, task_pid_nr(curr));
        print_lock(this);
        if (forwards)
                printk("but this lock took another, %s-irq-unsafe lock in the past:\n", irqclass);
@@ -2487,7 +2487,7 @@ print_unlock_inbalance_bug(struct task_struct *curr, struct lockdep_map *lock,
        printk(  "[ BUG: bad unlock balance detected! ]\n");
        printk(  "-------------------------------------\n");
        printk("%s/%d is trying to release lock (",
-               curr->comm, curr->pid);
+               curr->comm, task_pid_nr(curr));
        print_lockdep_cache(lock);
        printk(") at:\n");
        print_ip_sym(ip);
@@ -2737,7 +2737,7 @@ print_lock_contention_bug(struct task_struct *curr, struct lockdep_map *lock,
        printk(  "[ BUG: bad contention detected! ]\n");
        printk(  "---------------------------------\n");
        printk("%s/%d is trying to contend lock (",
-               curr->comm, curr->pid);
+               curr->comm, task_pid_nr(curr));
        print_lockdep_cache(lock);
        printk(") at:\n");
        print_ip_sym(ip);
@@ -3072,7 +3072,7 @@ print_freed_lock_bug(struct task_struct *curr, const void *mem_from,
        printk(  "[ BUG: held lock freed! ]\n");
        printk(  "-------------------------\n");
        printk("%s/%d is freeing memory %p-%p, with a lock still held there!\n",
-               curr->comm, curr->pid, mem_from, mem_to-1);
+               curr->comm, task_pid_nr(curr), mem_from, mem_to-1);
        print_lock(hlock);
        lockdep_print_held_locks(curr);
 
@@ -3125,7 +3125,7 @@ static void print_held_locks_bug(struct task_struct *curr)
        printk(  "[ BUG: lock held at task exit time! ]\n");
        printk(  "-------------------------------------\n");
        printk("%s/%d is exiting with locks still held!\n",
-               curr->comm, curr->pid);
+               curr->comm, task_pid_nr(curr));
        lockdep_print_held_locks(curr);
 
        printk("\nstack backtrace:\n");
diff --git a/kernel/marker.c b/kernel/marker.c
new file mode 100644 (file)
index 0000000..ccb48d9
--- /dev/null
@@ -0,0 +1,525 @@
+/*
+ * Copyright (C) 2007 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/marker.h>
+#include <linux/err.h>
+
+extern struct marker __start___markers[];
+extern struct marker __stop___markers[];
+
+/*
+ * module_mutex nests inside markers_mutex. Markers mutex protects the builtin
+ * and module markers, the hash table and deferred_sync.
+ */
+static DEFINE_MUTEX(markers_mutex);
+
+/*
+ * Marker deferred synchronization.
+ * Upon marker probe_unregister, we delay call to synchronize_sched() to
+ * accelerate mass unregistration (only when there is no more reference to a
+ * given module do we call synchronize_sched()). However, we need to make sure
+ * every critical region has ended before we re-arm a marker that has been
+ * unregistered and then registered back with a different probe data.
+ */
+static int deferred_sync;
+
+/*
+ * Marker hash table, containing the active markers.
+ * Protected by module_mutex.
+ */
+#define MARKER_HASH_BITS 6
+#define MARKER_TABLE_SIZE (1 << MARKER_HASH_BITS)
+
+struct marker_entry {
+       struct hlist_node hlist;
+       char *format;
+       marker_probe_func *probe;
+       void *private;
+       int refcount;   /* Number of times armed. 0 if disarmed. */
+       char name[0];   /* Contains name'\0'format'\0' */
+};
+
+static struct hlist_head marker_table[MARKER_TABLE_SIZE];
+
+/**
+ * __mark_empty_function - Empty probe callback
+ * @mdata: pointer of type const struct marker
+ * @fmt: format string
+ * @...: variable argument list
+ *
+ * Empty callback provided as a probe to the markers. By providing this to a
+ * disabled marker, we make sure the  execution flow is always valid even
+ * though the function pointer change and the marker enabling are two distinct
+ * operations that modifies the execution flow of preemptible code.
+ */
+void __mark_empty_function(const struct marker *mdata, void *private,
+       const char *fmt, ...)
+{
+}
+EXPORT_SYMBOL_GPL(__mark_empty_function);
+
+/*
+ * Get marker if the marker is present in the marker hash table.
+ * Must be called with markers_mutex held.
+ * Returns NULL if not present.
+ */
+static struct marker_entry *get_marker(const char *name)
+{
+       struct hlist_head *head;
+       struct hlist_node *node;
+       struct marker_entry *e;
+       u32 hash = jhash(name, strlen(name), 0);
+
+       head = &marker_table[hash & ((1 << MARKER_HASH_BITS)-1)];
+       hlist_for_each_entry(e, node, head, hlist) {
+               if (!strcmp(name, e->name))
+                       return e;
+       }
+       return NULL;
+}
+
+/*
+ * Add the marker to the marker hash table. Must be called with markers_mutex
+ * held.
+ */
+static int add_marker(const char *name, const char *format,
+       marker_probe_func *probe, void *private)
+{
+       struct hlist_head *head;
+       struct hlist_node *node;
+       struct marker_entry *e;
+       size_t name_len = strlen(name) + 1;
+       size_t format_len = 0;
+       u32 hash = jhash(name, name_len-1, 0);
+
+       if (format)
+               format_len = strlen(format) + 1;
+       head = &marker_table[hash & ((1 << MARKER_HASH_BITS)-1)];
+       hlist_for_each_entry(e, node, head, hlist) {
+               if (!strcmp(name, e->name)) {
+                       printk(KERN_NOTICE
+                               "Marker %s busy, probe %p already installed\n",
+                               name, e->probe);
+                       return -EBUSY;  /* Already there */
+               }
+       }
+       /*
+        * Using kmalloc here to allocate a variable length element. Could
+        * cause some memory fragmentation if overused.
+        */
+       e = kmalloc(sizeof(struct marker_entry) + name_len + format_len,
+                       GFP_KERNEL);
+       if (!e)
+               return -ENOMEM;
+       memcpy(&e->name[0], name, name_len);
+       if (format) {
+               e->format = &e->name[name_len];
+               memcpy(e->format, format, format_len);
+               trace_mark(core_marker_format, "name %s format %s",
+                               e->name, e->format);
+       } else
+               e->format = NULL;
+       e->probe = probe;
+       e->private = private;
+       e->refcount = 0;
+       hlist_add_head(&e->hlist, head);
+       return 0;
+}
+
+/*
+ * Remove the marker from the marker hash table. Must be called with mutex_lock
+ * held.
+ */
+static void *remove_marker(const char *name)
+{
+       struct hlist_head *head;
+       struct hlist_node *node;
+       struct marker_entry *e;
+       int found = 0;
+       size_t len = strlen(name) + 1;
+       void *private = NULL;
+       u32 hash = jhash(name, len-1, 0);
+
+       head = &marker_table[hash & ((1 << MARKER_HASH_BITS)-1)];
+       hlist_for_each_entry(e, node, head, hlist) {
+               if (!strcmp(name, e->name)) {
+                       found = 1;
+                       break;
+               }
+       }
+       if (found) {
+               private = e->private;
+               hlist_del(&e->hlist);
+               kfree(e);
+       }
+       return private;
+}
+
+/*
+ * Set the mark_entry format to the format found in the element.
+ */
+static int marker_set_format(struct marker_entry **entry, const char *format)
+{
+       struct marker_entry *e;
+       size_t name_len = strlen((*entry)->name) + 1;
+       size_t format_len = strlen(format) + 1;
+
+       e = kmalloc(sizeof(struct marker_entry) + name_len + format_len,
+                       GFP_KERNEL);
+       if (!e)
+               return -ENOMEM;
+       memcpy(&e->name[0], (*entry)->name, name_len);
+       e->format = &e->name[name_len];
+       memcpy(e->format, format, format_len);
+       e->probe = (*entry)->probe;
+       e->private = (*entry)->private;
+       e->refcount = (*entry)->refcount;
+       hlist_add_before(&e->hlist, &(*entry)->hlist);
+       hlist_del(&(*entry)->hlist);
+       kfree(*entry);
+       *entry = e;
+       trace_mark(core_marker_format, "name %s format %s",
+                       e->name, e->format);
+       return 0;
+}
+
+/*
+ * Sets the probe callback corresponding to one marker.
+ */
+static int set_marker(struct marker_entry **entry, struct marker *elem)
+{
+       int ret;
+       WARN_ON(strcmp((*entry)->name, elem->name) != 0);
+
+       if ((*entry)->format) {
+               if (strcmp((*entry)->format, elem->format) != 0) {
+                       printk(KERN_NOTICE
+                               "Format mismatch for probe %s "
+                               "(%s), marker (%s)\n",
+                               (*entry)->name,
+                               (*entry)->format,
+                               elem->format);
+                       return -EPERM;
+               }
+       } else {
+               ret = marker_set_format(entry, elem->format);
+               if (ret)
+                       return ret;
+       }
+       elem->call = (*entry)->probe;
+       elem->private = (*entry)->private;
+       elem->state = 1;
+       return 0;
+}
+
+/*
+ * Disable a marker and its probe callback.
+ * Note: only after a synchronize_sched() issued after setting elem->call to the
+ * empty function insures that the original callback is not used anymore. This
+ * insured by preemption disabling around the call site.
+ */
+static void disable_marker(struct marker *elem)
+{
+       elem->state = 0;
+       elem->call = __mark_empty_function;
+       /*
+        * Leave the private data and id there, because removal is racy and
+        * should be done only after a synchronize_sched(). These are never used
+        * until the next initialization anyway.
+        */
+}
+
+/**
+ * marker_update_probe_range - Update a probe range
+ * @begin: beginning of the range
+ * @end: end of the range
+ * @probe_module: module address of the probe being updated
+ * @refcount: number of references left to the given probe_module (out)
+ *
+ * Updates the probe callback corresponding to a range of markers.
+ * Must be called with markers_mutex held.
+ */
+void marker_update_probe_range(struct marker *begin,
+       struct marker *end, struct module *probe_module,
+       int *refcount)
+{
+       struct marker *iter;
+       struct marker_entry *mark_entry;
+
+       for (iter = begin; iter < end; iter++) {
+               mark_entry = get_marker(iter->name);
+               if (mark_entry && mark_entry->refcount) {
+                       set_marker(&mark_entry, iter);
+                       /*
+                        * ignore error, continue
+                        */
+                       if (probe_module)
+                               if (probe_module ==
+                       __module_text_address((unsigned long)mark_entry->probe))
+                                       (*refcount)++;
+               } else {
+                       disable_marker(iter);
+               }
+       }
+}
+
+/*
+ * Update probes, removing the faulty probes.
+ * Issues a synchronize_sched() when no reference to the module passed
+ * as parameter is found in the probes so the probe module can be
+ * safely unloaded from now on.
+ */
+static void marker_update_probes(struct module *probe_module)
+{
+       int refcount = 0;
+
+       mutex_lock(&markers_mutex);
+       /* Core kernel markers */
+       marker_update_probe_range(__start___markers,
+                       __stop___markers, probe_module, &refcount);
+       /* Markers in modules. */
+       module_update_markers(probe_module, &refcount);
+       if (probe_module && refcount == 0) {
+               synchronize_sched();
+               deferred_sync = 0;
+       }
+       mutex_unlock(&markers_mutex);
+}
+
+/**
+ * marker_probe_register -  Connect a probe to a marker
+ * @name: marker name
+ * @format: format string
+ * @probe: probe handler
+ * @private: probe private data
+ *
+ * private data must be a valid allocated memory address, or NULL.
+ * Returns 0 if ok, error value on error.
+ */
+int marker_probe_register(const char *name, const char *format,
+                       marker_probe_func *probe, void *private)
+{
+       struct marker_entry *entry;
+       int ret = 0, need_update = 0;
+
+       mutex_lock(&markers_mutex);
+       entry = get_marker(name);
+       if (entry && entry->refcount) {
+               ret = -EBUSY;
+               goto end;
+       }
+       if (deferred_sync) {
+               synchronize_sched();
+               deferred_sync = 0;
+       }
+       ret = add_marker(name, format, probe, private);
+       if (ret)
+               goto end;
+       need_update = 1;
+end:
+       mutex_unlock(&markers_mutex);
+       if (need_update)
+               marker_update_probes(NULL);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(marker_probe_register);
+
+/**
+ * marker_probe_unregister -  Disconnect a probe from a marker
+ * @name: marker name
+ *
+ * Returns the private data given to marker_probe_register, or an ERR_PTR().
+ */
+void *marker_probe_unregister(const char *name)
+{
+       struct module *probe_module;
+       struct marker_entry *entry;
+       void *private;
+       int need_update = 0;
+
+       mutex_lock(&markers_mutex);
+       entry = get_marker(name);
+       if (!entry) {
+               private = ERR_PTR(-ENOENT);
+               goto end;
+       }
+       entry->refcount = 0;
+       /* In what module is the probe handler ? */
+       probe_module = __module_text_address((unsigned long)entry->probe);
+       private = remove_marker(name);
+       deferred_sync = 1;
+       need_update = 1;
+end:
+       mutex_unlock(&markers_mutex);
+       if (need_update)
+               marker_update_probes(probe_module);
+       return private;
+}
+EXPORT_SYMBOL_GPL(marker_probe_unregister);
+
+/**
+ * marker_probe_unregister_private_data -  Disconnect a probe from a marker
+ * @private: probe private data
+ *
+ * Unregister a marker by providing the registered private data.
+ * Returns the private data given to marker_probe_register, or an ERR_PTR().
+ */
+void *marker_probe_unregister_private_data(void *private)
+{
+       struct module *probe_module;
+       struct hlist_head *head;
+       struct hlist_node *node;
+       struct marker_entry *entry;
+       int found = 0;
+       unsigned int i;
+       int need_update = 0;
+
+       mutex_lock(&markers_mutex);
+       for (i = 0; i < MARKER_TABLE_SIZE; i++) {
+               head = &marker_table[i];
+               hlist_for_each_entry(entry, node, head, hlist) {
+                       if (entry->private == private) {
+                               found = 1;
+                               goto iter_end;
+                       }
+               }
+       }
+iter_end:
+       if (!found) {
+               private = ERR_PTR(-ENOENT);
+               goto end;
+       }
+       entry->refcount = 0;
+       /* In what module is the probe handler ? */
+       probe_module = __module_text_address((unsigned long)entry->probe);
+       private = remove_marker(entry->name);
+       deferred_sync = 1;
+       need_update = 1;
+end:
+       mutex_unlock(&markers_mutex);
+       if (need_update)
+               marker_update_probes(probe_module);
+       return private;
+}
+EXPORT_SYMBOL_GPL(marker_probe_unregister_private_data);
+
+/**
+ * marker_arm - Arm a marker
+ * @name: marker name
+ *
+ * Activate a marker. It keeps a reference count of the number of
+ * arming/disarming done.
+ * Returns 0 if ok, error value on error.
+ */
+int marker_arm(const char *name)
+{
+       struct marker_entry *entry;
+       int ret = 0, need_update = 0;
+
+       mutex_lock(&markers_mutex);
+       entry = get_marker(name);
+       if (!entry) {
+               ret = -ENOENT;
+               goto end;
+       }
+       /*
+        * Only need to update probes when refcount passes from 0 to 1.
+        */
+       if (entry->refcount++)
+               goto end;
+       need_update = 1;
+end:
+       mutex_unlock(&markers_mutex);
+       if (need_update)
+               marker_update_probes(NULL);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(marker_arm);
+
+/**
+ * marker_disarm - Disarm a marker
+ * @name: marker name
+ *
+ * Disarm a marker. It keeps a reference count of the number of arming/disarming
+ * done.
+ * Returns 0 if ok, error value on error.
+ */
+int marker_disarm(const char *name)
+{
+       struct marker_entry *entry;
+       int ret = 0, need_update = 0;
+
+       mutex_lock(&markers_mutex);
+       entry = get_marker(name);
+       if (!entry) {
+               ret = -ENOENT;
+               goto end;
+       }
+       /*
+        * Only permit decrement refcount if higher than 0.
+        * Do probe update only on 1 -> 0 transition.
+        */
+       if (entry->refcount) {
+               if (--entry->refcount)
+                       goto end;
+       } else {
+               ret = -EPERM;
+               goto end;
+       }
+       need_update = 1;
+end:
+       mutex_unlock(&markers_mutex);
+       if (need_update)
+               marker_update_probes(NULL);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(marker_disarm);
+
+/**
+ * marker_get_private_data - Get a marker's probe private data
+ * @name: marker name
+ *
+ * Returns the private data pointer, or an ERR_PTR.
+ * The private data pointer should _only_ be dereferenced if the caller is the
+ * owner of the data, or its content could vanish. This is mostly used to
+ * confirm that a caller is the owner of a registered probe.
+ */
+void *marker_get_private_data(const char *name)
+{
+       struct hlist_head *head;
+       struct hlist_node *node;
+       struct marker_entry *e;
+       size_t name_len = strlen(name) + 1;
+       u32 hash = jhash(name, name_len-1, 0);
+       int found = 0;
+
+       head = &marker_table[hash & ((1 << MARKER_HASH_BITS)-1)];
+       hlist_for_each_entry(e, node, head, hlist) {
+               if (!strcmp(name, e->name)) {
+                       found = 1;
+                       return e->private;
+               }
+       }
+       return ERR_PTR(-ENOENT);
+}
+EXPORT_SYMBOL_GPL(marker_get_private_data);
index a389b423c279dcb6e5f2b94ffcf56e534b06875e..3202c9950073ebc05fb232a625da27d2ec35eee8 100644 (file)
@@ -105,7 +105,7 @@ void __module_put_and_exit(struct module *mod, long code)
        do_exit(code);
 }
 EXPORT_SYMBOL(__module_put_and_exit);
-       
+
 /* Find a module section: 0 means not found. */
 static unsigned int find_sec(Elf_Ehdr *hdr,
                             Elf_Shdr *sechdrs,
@@ -179,7 +179,7 @@ static unsigned long __find_symbol(const char *name,
        struct module *mod;
        const struct kernel_symbol *ks;
 
-       /* Core kernel first. */ 
+       /* Core kernel first. */
        *owner = NULL;
        ks = lookup_symbol(name, __start___ksymtab, __stop___ksymtab);
        if (ks) {
@@ -231,7 +231,7 @@ static unsigned long __find_symbol(const char *name,
                return ks->value;
        }
 
-       /* Now try modules. */ 
+       /* Now try modules. */
        list_for_each_entry(mod, &modules, list) {
                *owner = mod;
                ks = lookup_symbol(name, mod->syms, mod->syms + mod->num_syms);
@@ -285,7 +285,7 @@ static unsigned long __find_symbol(const char *name,
                }
        }
        DEBUGP("Failed to find symbol %s\n", name);
-       return 0;
+       return 0;
 }
 
 /* Search for module by name: must hold module_mutex. */
@@ -441,7 +441,7 @@ static int percpu_modinit(void)
        }
 
        return 0;
-}      
+}
 __initcall(percpu_modinit);
 #else /* ... !CONFIG_SMP */
 static inline void *percpu_modalloc(unsigned long size, unsigned long align,
@@ -483,8 +483,8 @@ static int modinfo_##field##_exists(struct module *mod)               \
 }                                                                     \
 static void free_modinfo_##field(struct module *mod)                  \
 {                                                                     \
-        kfree(mod->field);                                            \
-        mod->field = NULL;                                            \
+       kfree(mod->field);                                            \
+       mod->field = NULL;                                            \
 }                                                                     \
 static struct module_attribute modinfo_##field = {                    \
        .attr = { .name = __stringify(field), .mode = 0444 },         \
@@ -990,7 +990,7 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect,
        struct module_sect_attrs *sect_attrs;
        struct module_sect_attr *sattr;
        struct attribute **gattr;
-       
+
        /* Count loaded sections and allocate structures */
        for (i = 0; i < nsect; i++)
                if (sechdrs[i].sh_flags & SHF_ALLOC)
@@ -1348,14 +1348,14 @@ static int verify_export_symbols(struct module *mod)
        const unsigned long *crc;
 
        for (i = 0; i < mod->num_syms; i++)
-               if (__find_symbol(mod->syms[i].name, &owner, &crc, 1)) {
+               if (__find_symbol(mod->syms[i].name, &owner, &crc, 1)) {
                        name = mod->syms[i].name;
                        ret = -ENOEXEC;
                        goto dup;
                }
 
        for (i = 0; i < mod->num_gpl_syms; i++)
-               if (__find_symbol(mod->gpl_syms[i].name, &owner, &crc, 1)) {
+               if (__find_symbol(mod->gpl_syms[i].name, &owner, &crc, 1)) {
                        name = mod->gpl_syms[i].name;
                        ret = -ENOEXEC;
                        goto dup;
@@ -1673,6 +1673,8 @@ static struct module *load_module(void __user *umod,
        unsigned int unusedcrcindex;
        unsigned int unusedgplindex;
        unsigned int unusedgplcrcindex;
+       unsigned int markersindex;
+       unsigned int markersstringsindex;
        struct module *mod;
        long err = 0;
        void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
@@ -1929,7 +1931,7 @@ static struct module *load_module(void __user *umod,
                mod->unused_crcs = (void *)sechdrs[unusedgplcrcindex].sh_addr;
 
 #ifdef CONFIG_MODVERSIONS
-       if ((mod->num_syms && !crcindex) || 
+       if ((mod->num_syms && !crcindex) ||
            (mod->num_gpl_syms && !gplcrcindex) ||
            (mod->num_gpl_future_syms && !gplfuturecrcindex) ||
            (mod->num_unused_syms && !unusedcrcindex) ||
@@ -1939,6 +1941,9 @@ static struct module *load_module(void __user *umod,
                add_taint_module(mod, TAINT_FORCED_MODULE);
        }
 #endif
+       markersindex = find_sec(hdr, sechdrs, secstrings, "__markers");
+       markersstringsindex = find_sec(hdr, sechdrs, secstrings,
+                                       "__markers_strings");
 
        /* Now do relocations. */
        for (i = 1; i < hdr->e_shnum; i++) {
@@ -1961,6 +1966,11 @@ static 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);
@@ -1979,6 +1989,11 @@ static struct module *load_module(void __user *umod,
 
        add_kallsyms(mod, sechdrs, symindex, strindex, secstrings);
 
+#ifdef CONFIG_MARKERS
+       if (!mod->taints)
+               marker_update_probe_range(mod->markers,
+                       mod->markers + mod->num_markers, NULL, NULL);
+#endif
        err = module_finalize(hdr, sechdrs, mod);
        if (err < 0)
                goto cleanup;
@@ -2016,7 +2031,7 @@ static struct module *load_module(void __user *umod,
        if (err < 0)
                goto arch_cleanup;
 
-       err = mod_sysfs_setup(mod, 
+       err = mod_sysfs_setup(mod,
                              (struct kernel_param *)
                              sechdrs[setupindex].sh_addr,
                              sechdrs[setupindex].sh_size
@@ -2028,8 +2043,8 @@ static struct module *load_module(void __user *umod,
 
        /* Size of section 0 is 0, so this works well if no unwind info. */
        mod->unwind_info = unwind_add_table(mod,
-                                           (void *)sechdrs[unwindex].sh_addr,
-                                           sechdrs[unwindex].sh_size);
+                                           (void *)sechdrs[unwindex].sh_addr,
+                                           sechdrs[unwindex].sh_size);
 
        /* Get rid of temporary copy */
        vfree(hdr);
@@ -2146,7 +2161,7 @@ static inline int within(unsigned long addr, void *start, unsigned long size)
  */
 static inline int is_arm_mapping_symbol(const char *str)
 {
-       return str[0] == '$' && strchr("atd", str[1]) 
+       return str[0] == '$' && strchr("atd", str[1])
               && (str[2] == '\0' || str[2] == '.');
 }
 
@@ -2161,11 +2176,11 @@ static const char *get_ksymbol(struct module *mod,
        /* At worse, next value is at end of module */
        if (within(addr, mod->module_init, mod->init_size))
                nextval = (unsigned long)mod->module_init+mod->init_text_size;
-       else 
+       else
                nextval = (unsigned long)mod->module_core+mod->core_text_size;
 
        /* Scan for closest preceeding symbol, and next symbol. (ELF
-           starts real symbols at 1). */
+          starts real symbols at 1). */
        for (i = 1; i < mod->num_symtab; i++) {
                if (mod->symtab[i].st_shndx == SHN_UNDEF)
                        continue;
@@ -2407,7 +2422,7 @@ const struct exception_table_entry *search_module_extables(unsigned long addr)
        list_for_each_entry(mod, &modules, list) {
                if (mod->num_exentries == 0)
                        continue;
-                               
+
                e = search_extable(mod->extable,
                                   mod->extable + mod->num_exentries - 1,
                                   addr);
@@ -2417,7 +2432,7 @@ const struct exception_table_entry *search_module_extables(unsigned long addr)
        preempt_enable();
 
        /* Now, if we found one, we are running inside it now, hence
-           we cannot unload the module, hence no refcnt needed. */
+          we cannot unload the module, hence no refcnt needed. */
        return e;
 }
 
@@ -2570,3 +2585,18 @@ EXPORT_SYMBOL(module_remove_driver);
 void struct_module(struct module *mod) { return; }
 EXPORT_SYMBOL(struct_module);
 #endif
+
+#ifdef CONFIG_MARKERS
+void module_update_markers(struct module *probe_module, int *refcount)
+{
+       struct module *mod;
+
+       mutex_lock(&module_mutex);
+       list_for_each_entry(mod, &modules, list)
+               if (!mod->taints)
+                       marker_update_probe_range(mod->markers,
+                               mod->markers + mod->num_markers,
+                               probe_module, refcount);
+       mutex_unlock(&module_mutex);
+}
+#endif
diff --git a/kernel/notifier.c b/kernel/notifier.c
new file mode 100644 (file)
index 0000000..4253f47
--- /dev/null
@@ -0,0 +1,539 @@
+#include <linux/kdebug.h>
+#include <linux/kprobes.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
+#include <linux/rcupdate.h>
+#include <linux/vmalloc.h>
+
+/*
+ *     Notifier list for kernel code which wants to be called
+ *     at shutdown. This is used to stop any idling DMA operations
+ *     and the like.
+ */
+BLOCKING_NOTIFIER_HEAD(reboot_notifier_list);
+
+/*
+ *     Notifier chain core routines.  The exported routines below
+ *     are layered on top of these, with appropriate locking added.
+ */
+
+static int notifier_chain_register(struct notifier_block **nl,
+               struct notifier_block *n)
+{
+       while ((*nl) != NULL) {
+               if (n->priority > (*nl)->priority)
+                       break;
+               nl = &((*nl)->next);
+       }
+       n->next = *nl;
+       rcu_assign_pointer(*nl, n);
+       return 0;
+}
+
+static int notifier_chain_unregister(struct notifier_block **nl,
+               struct notifier_block *n)
+{
+       while ((*nl) != NULL) {
+               if ((*nl) == n) {
+                       rcu_assign_pointer(*nl, n->next);
+                       return 0;
+               }
+               nl = &((*nl)->next);
+       }
+       return -ENOENT;
+}
+
+/**
+ * notifier_call_chain - Informs the registered notifiers about an event.
+ *     @nl:            Pointer to head of the blocking notifier chain
+ *     @val:           Value passed unmodified to notifier function
+ *     @v:             Pointer passed unmodified to notifier function
+ *     @nr_to_call:    Number of notifier functions to be called. Don't care
+ *                     value of this parameter is -1.
+ *     @nr_calls:      Records the number of notifications sent. Don't care
+ *                     value of this field is NULL.
+ *     @returns:       notifier_call_chain returns the value returned by the
+ *                     last notifier function called.
+ */
+static int __kprobes notifier_call_chain(struct notifier_block **nl,
+                                       unsigned long val, void *v,
+                                       int nr_to_call, int *nr_calls)
+{
+       int ret = NOTIFY_DONE;
+       struct notifier_block *nb, *next_nb;
+
+       nb = rcu_dereference(*nl);
+
+       while (nb && nr_to_call) {
+               next_nb = rcu_dereference(nb->next);
+               ret = nb->notifier_call(nb, val, v);
+
+               if (nr_calls)
+                       (*nr_calls)++;
+
+               if ((ret & NOTIFY_STOP_MASK) == NOTIFY_STOP_MASK)
+                       break;
+               nb = next_nb;
+               nr_to_call--;
+       }
+       return ret;
+}
+
+/*
+ *     Atomic notifier chain routines.  Registration and unregistration
+ *     use a spinlock, and call_chain is synchronized by RCU (no locks).
+ */
+
+/**
+ *     atomic_notifier_chain_register - Add notifier to an atomic notifier chain
+ *     @nh: Pointer to head of the atomic notifier chain
+ *     @n: New entry in notifier chain
+ *
+ *     Adds a notifier to an atomic notifier chain.
+ *
+ *     Currently always returns zero.
+ */
+int atomic_notifier_chain_register(struct atomic_notifier_head *nh,
+               struct notifier_block *n)
+{
+       unsigned long flags;
+       int ret;
+
+       spin_lock_irqsave(&nh->lock, flags);
+       ret = notifier_chain_register(&nh->head, n);
+       spin_unlock_irqrestore(&nh->lock, flags);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(atomic_notifier_chain_register);
+
+/**
+ *     atomic_notifier_chain_unregister - Remove notifier from an atomic notifier chain
+ *     @nh: Pointer to head of the atomic notifier chain
+ *     @n: Entry to remove from notifier chain
+ *
+ *     Removes a notifier from an atomic notifier chain.
+ *
+ *     Returns zero on success or %-ENOENT on failure.
+ */
+int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh,
+               struct notifier_block *n)
+{
+       unsigned long flags;
+       int ret;
+
+       spin_lock_irqsave(&nh->lock, flags);
+       ret = notifier_chain_unregister(&nh->head, n);
+       spin_unlock_irqrestore(&nh->lock, flags);
+       synchronize_rcu();
+       return ret;
+}
+EXPORT_SYMBOL_GPL(atomic_notifier_chain_unregister);
+
+/**
+ *     __atomic_notifier_call_chain - Call functions in an atomic notifier chain
+ *     @nh: Pointer to head of the atomic notifier chain
+ *     @val: Value passed unmodified to notifier function
+ *     @v: Pointer passed unmodified to notifier function
+ *     @nr_to_call: See the comment for notifier_call_chain.
+ *     @nr_calls: See the comment for notifier_call_chain.
+ *
+ *     Calls each function in a notifier chain in turn.  The functions
+ *     run in an atomic context, so they must not block.
+ *     This routine uses RCU to synchronize with changes to the chain.
+ *
+ *     If the return value of the notifier can be and'ed
+ *     with %NOTIFY_STOP_MASK then atomic_notifier_call_chain()
+ *     will return immediately, with the return value of
+ *     the notifier function which halted execution.
+ *     Otherwise the return value is the return value
+ *     of the last notifier function called.
+ */
+int __kprobes __atomic_notifier_call_chain(struct atomic_notifier_head *nh,
+                                       unsigned long val, void *v,
+                                       int nr_to_call, int *nr_calls)
+{
+       int ret;
+
+       rcu_read_lock();
+       ret = notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls);
+       rcu_read_unlock();
+       return ret;
+}
+EXPORT_SYMBOL_GPL(__atomic_notifier_call_chain);
+
+int __kprobes atomic_notifier_call_chain(struct atomic_notifier_head *nh,
+               unsigned long val, void *v)
+{
+       return __atomic_notifier_call_chain(nh, val, v, -1, NULL);
+}
+EXPORT_SYMBOL_GPL(atomic_notifier_call_chain);
+
+/*
+ *     Blocking notifier chain routines.  All access to the chain is
+ *     synchronized by an rwsem.
+ */
+
+/**
+ *     blocking_notifier_chain_register - Add notifier to a blocking notifier chain
+ *     @nh: Pointer to head of the blocking notifier chain
+ *     @n: New entry in notifier chain
+ *
+ *     Adds a notifier to a blocking notifier chain.
+ *     Must be called in process context.
+ *
+ *     Currently always returns zero.
+ */
+int blocking_notifier_chain_register(struct blocking_notifier_head *nh,
+               struct notifier_block *n)
+{
+       int ret;
+
+       /*
+        * This code gets used during boot-up, when task switching is
+        * not yet working and interrupts must remain disabled.  At
+        * such times we must not call down_write().
+        */
+       if (unlikely(system_state == SYSTEM_BOOTING))
+               return notifier_chain_register(&nh->head, n);
+
+       down_write(&nh->rwsem);
+       ret = notifier_chain_register(&nh->head, n);
+       up_write(&nh->rwsem);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(blocking_notifier_chain_register);
+
+/**
+ *     blocking_notifier_chain_unregister - Remove notifier from a blocking notifier chain
+ *     @nh: Pointer to head of the blocking notifier chain
+ *     @n: Entry to remove from notifier chain
+ *
+ *     Removes a notifier from a blocking notifier chain.
+ *     Must be called from process context.
+ *
+ *     Returns zero on success or %-ENOENT on failure.
+ */
+int blocking_notifier_chain_unregister(struct blocking_notifier_head *nh,
+               struct notifier_block *n)
+{
+       int ret;
+
+       /*
+        * This code gets used during boot-up, when task switching is
+        * not yet working and interrupts must remain disabled.  At
+        * such times we must not call down_write().
+        */
+       if (unlikely(system_state == SYSTEM_BOOTING))
+               return notifier_chain_unregister(&nh->head, n);
+
+       down_write(&nh->rwsem);
+       ret = notifier_chain_unregister(&nh->head, n);
+       up_write(&nh->rwsem);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(blocking_notifier_chain_unregister);
+
+/**
+ *     __blocking_notifier_call_chain - Call functions in a blocking notifier chain
+ *     @nh: Pointer to head of the blocking notifier chain
+ *     @val: Value passed unmodified to notifier function
+ *     @v: Pointer passed unmodified to notifier function
+ *     @nr_to_call: See comment for notifier_call_chain.
+ *     @nr_calls: See comment for notifier_call_chain.
+ *
+ *     Calls each function in a notifier chain in turn.  The functions
+ *     run in a process context, so they are allowed to block.
+ *
+ *     If the return value of the notifier can be and'ed
+ *     with %NOTIFY_STOP_MASK then blocking_notifier_call_chain()
+ *     will return immediately, with the return value of
+ *     the notifier function which halted execution.
+ *     Otherwise the return value is the return value
+ *     of the last notifier function called.
+ */
+int __blocking_notifier_call_chain(struct blocking_notifier_head *nh,
+                                  unsigned long val, void *v,
+                                  int nr_to_call, int *nr_calls)
+{
+       int ret = NOTIFY_DONE;
+
+       /*
+        * We check the head outside the lock, but if this access is
+        * racy then it does not matter what the result of the test
+        * is, we re-check the list after having taken the lock anyway:
+        */
+       if (rcu_dereference(nh->head)) {
+               down_read(&nh->rwsem);
+               ret = notifier_call_chain(&nh->head, val, v, nr_to_call,
+                                       nr_calls);
+               up_read(&nh->rwsem);
+       }
+       return ret;
+}
+EXPORT_SYMBOL_GPL(__blocking_notifier_call_chain);
+
+int blocking_notifier_call_chain(struct blocking_notifier_head *nh,
+               unsigned long val, void *v)
+{
+       return __blocking_notifier_call_chain(nh, val, v, -1, NULL);
+}
+EXPORT_SYMBOL_GPL(blocking_notifier_call_chain);
+
+/*
+ *     Raw notifier chain routines.  There is no protection;
+ *     the caller must provide it.  Use at your own risk!
+ */
+
+/**
+ *     raw_notifier_chain_register - Add notifier to a raw notifier chain
+ *     @nh: Pointer to head of the raw notifier chain
+ *     @n: New entry in notifier chain
+ *
+ *     Adds a notifier to a raw notifier chain.
+ *     All locking must be provided by the caller.
+ *
+ *     Currently always returns zero.
+ */
+int raw_notifier_chain_register(struct raw_notifier_head *nh,
+               struct notifier_block *n)
+{
+       return notifier_chain_register(&nh->head, n);
+}
+EXPORT_SYMBOL_GPL(raw_notifier_chain_register);
+
+/**
+ *     raw_notifier_chain_unregister - Remove notifier from a raw notifier chain
+ *     @nh: Pointer to head of the raw notifier chain
+ *     @n: Entry to remove from notifier chain
+ *
+ *     Removes a notifier from a raw notifier chain.
+ *     All locking must be provided by the caller.
+ *
+ *     Returns zero on success or %-ENOENT on failure.
+ */
+int raw_notifier_chain_unregister(struct raw_notifier_head *nh,
+               struct notifier_block *n)
+{
+       return notifier_chain_unregister(&nh->head, n);
+}
+EXPORT_SYMBOL_GPL(raw_notifier_chain_unregister);
+
+/**
+ *     __raw_notifier_call_chain - Call functions in a raw notifier chain
+ *     @nh: Pointer to head of the raw notifier chain
+ *     @val: Value passed unmodified to notifier function
+ *     @v: Pointer passed unmodified to notifier function
+ *     @nr_to_call: See comment for notifier_call_chain.
+ *     @nr_calls: See comment for notifier_call_chain
+ *
+ *     Calls each function in a notifier chain in turn.  The functions
+ *     run in an undefined context.
+ *     All locking must be provided by the caller.
+ *
+ *     If the return value of the notifier can be and'ed
+ *     with %NOTIFY_STOP_MASK then raw_notifier_call_chain()
+ *     will return immediately, with the return value of
+ *     the notifier function which halted execution.
+ *     Otherwise the return value is the return value
+ *     of the last notifier function called.
+ */
+int __raw_notifier_call_chain(struct raw_notifier_head *nh,
+                             unsigned long val, void *v,
+                             int nr_to_call, int *nr_calls)
+{
+       return notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls);
+}
+EXPORT_SYMBOL_GPL(__raw_notifier_call_chain);
+
+int raw_notifier_call_chain(struct raw_notifier_head *nh,
+               unsigned long val, void *v)
+{
+       return __raw_notifier_call_chain(nh, val, v, -1, NULL);
+}
+EXPORT_SYMBOL_GPL(raw_notifier_call_chain);
+
+/*
+ *     SRCU notifier chain routines.    Registration and unregistration
+ *     use a mutex, and call_chain is synchronized by SRCU (no locks).
+ */
+
+/**
+ *     srcu_notifier_chain_register - Add notifier to an SRCU notifier chain
+ *     @nh: Pointer to head of the SRCU notifier chain
+ *     @n: New entry in notifier chain
+ *
+ *     Adds a notifier to an SRCU notifier chain.
+ *     Must be called in process context.
+ *
+ *     Currently always returns zero.
+ */
+int srcu_notifier_chain_register(struct srcu_notifier_head *nh,
+               struct notifier_block *n)
+{
+       int ret;
+
+       /*
+        * This code gets used during boot-up, when task switching is
+        * not yet working and interrupts must remain disabled.  At
+        * such times we must not call mutex_lock().
+        */
+       if (unlikely(system_state == SYSTEM_BOOTING))
+               return notifier_chain_register(&nh->head, n);
+
+       mutex_lock(&nh->mutex);
+       ret = notifier_chain_register(&nh->head, n);
+       mutex_unlock(&nh->mutex);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(srcu_notifier_chain_register);
+
+/**
+ *     srcu_notifier_chain_unregister - Remove notifier from an SRCU notifier chain
+ *     @nh: Pointer to head of the SRCU notifier chain
+ *     @n: Entry to remove from notifier chain
+ *
+ *     Removes a notifier from an SRCU notifier chain.
+ *     Must be called from process context.
+ *
+ *     Returns zero on success or %-ENOENT on failure.
+ */
+int srcu_notifier_chain_unregister(struct srcu_notifier_head *nh,
+               struct notifier_block *n)
+{
+       int ret;
+
+       /*
+        * This code gets used during boot-up, when task switching is
+        * not yet working and interrupts must remain disabled.  At
+        * such times we must not call mutex_lock().
+        */
+       if (unlikely(system_state == SYSTEM_BOOTING))
+               return notifier_chain_unregister(&nh->head, n);
+
+       mutex_lock(&nh->mutex);
+       ret = notifier_chain_unregister(&nh->head, n);
+       mutex_unlock(&nh->mutex);
+       synchronize_srcu(&nh->srcu);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(srcu_notifier_chain_unregister);
+
+/**
+ *     __srcu_notifier_call_chain - Call functions in an SRCU notifier chain
+ *     @nh: Pointer to head of the SRCU notifier chain
+ *     @val: Value passed unmodified to notifier function
+ *     @v: Pointer passed unmodified to notifier function
+ *     @nr_to_call: See comment for notifier_call_chain.
+ *     @nr_calls: See comment for notifier_call_chain
+ *
+ *     Calls each function in a notifier chain in turn.  The functions
+ *     run in a process context, so they are allowed to block.
+ *
+ *     If the return value of the notifier can be and'ed
+ *     with %NOTIFY_STOP_MASK then srcu_notifier_call_chain()
+ *     will return immediately, with the return value of
+ *     the notifier function which halted execution.
+ *     Otherwise the return value is the return value
+ *     of the last notifier function called.
+ */
+int __srcu_notifier_call_chain(struct srcu_notifier_head *nh,
+                              unsigned long val, void *v,
+                              int nr_to_call, int *nr_calls)
+{
+       int ret;
+       int idx;
+
+       idx = srcu_read_lock(&nh->srcu);
+       ret = notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls);
+       srcu_read_unlock(&nh->srcu, idx);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(__srcu_notifier_call_chain);
+
+int srcu_notifier_call_chain(struct srcu_notifier_head *nh,
+               unsigned long val, void *v)
+{
+       return __srcu_notifier_call_chain(nh, val, v, -1, NULL);
+}
+EXPORT_SYMBOL_GPL(srcu_notifier_call_chain);
+
+/**
+ *     srcu_init_notifier_head - Initialize an SRCU notifier head
+ *     @nh: Pointer to head of the srcu notifier chain
+ *
+ *     Unlike other sorts of notifier heads, SRCU notifier heads require
+ *     dynamic initialization.  Be sure to call this routine before
+ *     calling any of the other SRCU notifier routines for this head.
+ *
+ *     If an SRCU notifier head is deallocated, it must first be cleaned
+ *     up by calling srcu_cleanup_notifier_head().  Otherwise the head's
+ *     per-cpu data (used by the SRCU mechanism) will leak.
+ */
+void srcu_init_notifier_head(struct srcu_notifier_head *nh)
+{
+       mutex_init(&nh->mutex);
+       if (init_srcu_struct(&nh->srcu) < 0)
+               BUG();
+       nh->head = NULL;
+}
+EXPORT_SYMBOL_GPL(srcu_init_notifier_head);
+
+/**
+ *     register_reboot_notifier - Register function to be called at reboot time
+ *     @nb: Info about notifier function to be called
+ *
+ *     Registers a function with the list of functions
+ *     to be called at reboot time.
+ *
+ *     Currently always returns zero, as blocking_notifier_chain_register()
+ *     always returns zero.
+ */
+int register_reboot_notifier(struct notifier_block *nb)
+{
+       return blocking_notifier_chain_register(&reboot_notifier_list, nb);
+}
+EXPORT_SYMBOL(register_reboot_notifier);
+
+/**
+ *     unregister_reboot_notifier - Unregister previously registered reboot notifier
+ *     @nb: Hook to be unregistered
+ *
+ *     Unregisters a previously registered reboot
+ *     notifier function.
+ *
+ *     Returns zero on success, or %-ENOENT on failure.
+ */
+int unregister_reboot_notifier(struct notifier_block *nb)
+{
+       return blocking_notifier_chain_unregister(&reboot_notifier_list, nb);
+}
+EXPORT_SYMBOL(unregister_reboot_notifier);
+
+static ATOMIC_NOTIFIER_HEAD(die_chain);
+
+int notify_die(enum die_val val, const char *str,
+              struct pt_regs *regs, long err, int trap, int sig)
+{
+       struct die_args args = {
+               .regs   = regs,
+               .str    = str,
+               .err    = err,
+               .trapnr = trap,
+               .signr  = sig,
+
+       };
+       return atomic_notifier_call_chain(&die_chain, val, &args);
+}
+
+int register_die_notifier(struct notifier_block *nb)
+{
+       vmalloc_sync_all();
+       return atomic_notifier_chain_register(&die_chain, nb);
+}
+EXPORT_SYMBOL_GPL(register_die_notifier);
+
+int unregister_die_notifier(struct notifier_block *nb)
+{
+       return atomic_notifier_chain_unregister(&die_chain, nb);
+}
+EXPORT_SYMBOL_GPL(unregister_die_notifier);
diff --git a/kernel/ns_cgroup.c b/kernel/ns_cgroup.c
new file mode 100644 (file)
index 0000000..aead4d6
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * ns_cgroup.c - namespace cgroup subsystem
+ *
+ * Copyright 2006, 2007 IBM Corp
+ */
+
+#include <linux/module.h>
+#include <linux/cgroup.h>
+#include <linux/fs.h>
+
+struct ns_cgroup {
+       struct cgroup_subsys_state css;
+       spinlock_t lock;
+};
+
+struct cgroup_subsys ns_subsys;
+
+static inline struct ns_cgroup *cgroup_to_ns(
+               struct cgroup *cgroup)
+{
+       return container_of(cgroup_subsys_state(cgroup, ns_subsys_id),
+                           struct ns_cgroup, css);
+}
+
+int ns_cgroup_clone(struct task_struct *task)
+{
+       return cgroup_clone(task, &ns_subsys);
+}
+
+/*
+ * Rules:
+ *   1. you can only enter a cgroup which is a child of your current
+ *     cgroup
+ *   2. you can only place another process into a cgroup if
+ *     a. you have CAP_SYS_ADMIN
+ *     b. your cgroup is an ancestor of task's destination cgroup
+ *       (hence either you are in the same cgroup as task, or in an
+ *        ancestor cgroup thereof)
+ */
+static int ns_can_attach(struct cgroup_subsys *ss,
+               struct cgroup *new_cgroup, struct task_struct *task)
+{
+       struct cgroup *orig;
+
+       if (current != task) {
+               if (!capable(CAP_SYS_ADMIN))
+                       return -EPERM;
+
+               if (!cgroup_is_descendant(new_cgroup))
+                       return -EPERM;
+       }
+
+       if (atomic_read(&new_cgroup->count) != 0)
+               return -EPERM;
+
+       orig = task_cgroup(task, ns_subsys_id);
+       if (orig && orig != new_cgroup->parent)
+               return -EPERM;
+
+       return 0;
+}
+
+/*
+ * Rules: you can only create a cgroup if
+ *     1. you are capable(CAP_SYS_ADMIN)
+ *     2. the target cgroup is a descendant of your own cgroup
+ */
+static struct cgroup_subsys_state *ns_create(struct cgroup_subsys *ss,
+                                               struct cgroup *cgroup)
+{
+       struct ns_cgroup *ns_cgroup;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return ERR_PTR(-EPERM);
+       if (!cgroup_is_descendant(cgroup))
+               return ERR_PTR(-EPERM);
+
+       ns_cgroup = kzalloc(sizeof(*ns_cgroup), GFP_KERNEL);
+       if (!ns_cgroup)
+               return ERR_PTR(-ENOMEM);
+       spin_lock_init(&ns_cgroup->lock);
+       return &ns_cgroup->css;
+}
+
+static void ns_destroy(struct cgroup_subsys *ss,
+                       struct cgroup *cgroup)
+{
+       struct ns_cgroup *ns_cgroup;
+
+       ns_cgroup = cgroup_to_ns(cgroup);
+       kfree(ns_cgroup);
+}
+
+struct cgroup_subsys ns_subsys = {
+       .name = "ns",
+       .can_attach = ns_can_attach,
+       .create = ns_create,
+       .destroy  = ns_destroy,
+       .subsys_id = ns_subsys_id,
+};
index 049e7c0ac5668964cb08554aee935ee687642852..79f871bc0ef40026e111df575622cbc6b11031c3 100644 (file)
@@ -26,19 +26,6 @@ static struct kmem_cache *nsproxy_cachep;
 
 struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy);
 
-static inline void get_nsproxy(struct nsproxy *ns)
-{
-       atomic_inc(&ns->count);
-}
-
-void get_task_namespaces(struct task_struct *tsk)
-{
-       struct nsproxy *ns = tsk->nsproxy;
-       if (ns) {
-               get_nsproxy(ns);
-       }
-}
-
 /*
  * creates a copy of "orig" with refcount 1.
  */
@@ -87,7 +74,7 @@ static struct nsproxy *create_new_namespaces(unsigned long flags,
                goto out_ipc;
        }
 
-       new_nsp->pid_ns = copy_pid_ns(flags, tsk->nsproxy->pid_ns);
+       new_nsp->pid_ns = copy_pid_ns(flags, task_active_pid_ns(tsk));
        if (IS_ERR(new_nsp->pid_ns)) {
                err = PTR_ERR(new_nsp->pid_ns);
                goto out_pid;
@@ -142,7 +129,8 @@ int copy_namespaces(unsigned long flags, struct task_struct *tsk)
 
        get_nsproxy(old_ns);
 
-       if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWUSER | CLONE_NEWNET)))
+       if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
+                               CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWNET)))
                return 0;
 
        if (!capable(CAP_SYS_ADMIN)) {
@@ -156,7 +144,14 @@ int copy_namespaces(unsigned long flags, struct task_struct *tsk)
                goto out;
        }
 
+       err = ns_cgroup_clone(tsk);
+       if (err) {
+               put_nsproxy(new_ns);
+               goto out;
+       }
+
        tsk->nsproxy = new_ns;
+
 out:
        put_nsproxy(old_ns);
        return err;
@@ -196,11 +191,46 @@ int unshare_nsproxy_namespaces(unsigned long unshare_flags,
 
        *new_nsp = create_new_namespaces(unshare_flags, current,
                                new_fs ? new_fs : current->fs);
-       if (IS_ERR(*new_nsp))
+       if (IS_ERR(*new_nsp)) {
                err = PTR_ERR(*new_nsp);
+               goto out;
+       }
+
+       err = ns_cgroup_clone(current);
+       if (err)
+               put_nsproxy(*new_nsp);
+
+out:
        return err;
 }
 
+void switch_task_namespaces(struct task_struct *p, struct nsproxy *new)
+{
+       struct nsproxy *ns;
+
+       might_sleep();
+
+       ns = p->nsproxy;
+
+       rcu_assign_pointer(p->nsproxy, new);
+
+       if (ns && atomic_dec_and_test(&ns->count)) {
+               /*
+                * wait for others to get what they want from this nsproxy.
+                *
+                * cannot release this nsproxy via the call_rcu() since
+                * put_mnt_ns() will want to sleep
+                */
+               synchronize_rcu();
+               free_nsproxy(ns);
+       }
+}
+
+void exit_task_namespaces(struct task_struct *p)
+{
+       switch_task_namespaces(p, NULL);
+}
+
 static int __init nsproxy_cache_init(void)
 {
        nsproxy_cachep = KMEM_CACHE(nsproxy, SLAB_PANIC);
index f64f4c1ac11fc78c6c13d28968383e77c724e35c..6f6e03e91595f7f1959a282c5a35697efb02c79d 100644 (file)
@@ -56,14 +56,14 @@ EXPORT_SYMBOL(panic_blink);
  *
  *     This function never returns.
  */
+
 NORET_TYPE void panic(const char * fmt, ...)
 {
        long i;
        static char buf[1024];
        va_list args;
 #if defined(CONFIG_S390)
-        unsigned long caller = (unsigned long) __builtin_return_address(0);
+       unsigned long caller = (unsigned long) __builtin_return_address(0);
 #endif
 
        /*
@@ -128,7 +128,7 @@ NORET_TYPE void panic(const char * fmt, ...)
        }
 #endif
 #if defined(CONFIG_S390)
-        disabled_wait(caller);
+       disabled_wait(caller);
 #endif
        local_irq_enable();
        for (i = 0;;) {
@@ -148,13 +148,13 @@ EXPORT_SYMBOL(panic);
  *  'F' - Module has been forcibly loaded.
  *  'S' - SMP with CPUs not designed for SMP.
  *  'R' - User forced a module unload.
- *  'M' - Machine had a machine check experience.
+ *  'M' - System experienced a machine check exception.
  *  'B' - System has hit bad_page.
  *  'U' - Userspace-defined naughtiness.
  *
  *     The string is overwritten by the next call to print_taint().
  */
+
 const char *print_tainted(void)
 {
        static char buf[20];
@@ -164,7 +164,7 @@ const char *print_tainted(void)
                        tainted & TAINT_FORCED_MODULE ? 'F' : ' ',
                        tainted & TAINT_UNSAFE_SMP ? 'S' : ' ',
                        tainted & TAINT_FORCED_RMMOD ? 'R' : ' ',
-                       tainted & TAINT_MACHINE_CHECK ? 'M' : ' ',
+                       tainted & TAINT_MACHINE_CHECK ? 'M' : ' ',
                        tainted & TAINT_BAD_PAGE ? 'B' : ' ',
                        tainted & TAINT_USER ? 'U' : ' ',
                        tainted & TAINT_DIE ? 'D' : ' ');
index 1d6aca288cdcb078ed5a3a6790d9f532f98d8f88..16f269e9ddc9b7d4ed129f98f0deac4965b87507 100644 (file)
@@ -592,11 +592,17 @@ static void __init param_sysfs_builtin(void)
 
        for (i=0; i < __stop___param - __start___param; i++) {
                char *dot;
+               size_t kplen;
 
                kp = &__start___param[i];
+               kplen = strlen(kp->name);
 
                /* We do not handle args without periods. */
-               dot = memchr(kp->name, '.', MAX_KBUILD_MODNAME);
+               if (kplen > MAX_KBUILD_MODNAME) {
+                       DEBUGP("kernel parameter name is too long: %s\n", kp->name);
+                       continue;
+               }
+               dot = memchr(kp->name, '.', kplen);
                if (!dot) {
                        DEBUGP("couldn't find period in %s\n", kp->name);
                        continue;
index c6e3f9ffff87e62afa5aa93233833b8642144dd9..d1db36b94674dbdc318845233b1804c659515740 100644 (file)
  * allocation scenario when all but one out of 1 million PIDs possible are
  * allocated already: the scanning of 32 list entries and at most PAGE_SIZE
  * bytes. The typical fastpath is a single successful setbit. Freeing is O(1).
+ *
+ * Pid namespaces:
+ *    (C) 2007 Pavel Emelyanov <xemul@openvz.org>, OpenVZ, SWsoft Inc.
+ *    (C) 2007 Sukadev Bhattiprolu <sukadev@us.ibm.com>, IBM
+ *     Many thanks to Oleg Nesterov for comments and help
+ *
  */
 
 #include <linux/mm.h>
 #include <linux/hash.h>
 #include <linux/pid_namespace.h>
 #include <linux/init_task.h>
+#include <linux/syscalls.h>
 
-#define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
+#define pid_hashfn(nr, ns)     \
+       hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift)
 static struct hlist_head *pid_hash;
 static int pidhash_shift;
-static struct kmem_cache *pid_cachep;
 struct pid init_struct_pid = INIT_STRUCT_PID;
+static struct kmem_cache *pid_ns_cachep;
 
 int pid_max = PID_MAX_DEFAULT;
 
@@ -68,8 +76,25 @@ struct pid_namespace init_pid_ns = {
                [ 0 ... PIDMAP_ENTRIES-1] = { ATOMIC_INIT(BITS_PER_PAGE), NULL }
        },
        .last_pid = 0,
-       .child_reaper = &init_task
+       .level = 0,
+       .child_reaper = &init_task,
 };
+EXPORT_SYMBOL_GPL(init_pid_ns);
+
+int is_container_init(struct task_struct *tsk)
+{
+       int ret = 0;
+       struct pid *pid;
+
+       rcu_read_lock();
+       pid = task_pid(tsk);
+       if (pid != NULL && pid->numbers[pid->level].nr == 1)
+               ret = 1;
+       rcu_read_unlock();
+
+       return ret;
+}
+EXPORT_SYMBOL(is_container_init);
 
 /*
  * Note: disable interrupts while the pidmap_lock is held as an
@@ -176,11 +201,17 @@ static int next_pidmap(struct pid_namespace *pid_ns, int last)
 
 fastcall void put_pid(struct pid *pid)
 {
+       struct pid_namespace *ns;
+
        if (!pid)
                return;
+
+       ns = pid->numbers[pid->level].ns;
        if ((atomic_read(&pid->count) == 1) ||
-            atomic_dec_and_test(&pid->count))
-               kmem_cache_free(pid_cachep, pid);
+            atomic_dec_and_test(&pid->count)) {
+               kmem_cache_free(ns->pid_cachep, pid);
+               put_pid_ns(ns);
+       }
 }
 EXPORT_SYMBOL_GPL(put_pid);
 
@@ -193,60 +224,94 @@ static void delayed_put_pid(struct rcu_head *rhp)
 fastcall void free_pid(struct pid *pid)
 {
        /* We can be called with write_lock_irq(&tasklist_lock) held */
+       int i;
        unsigned long flags;
 
        spin_lock_irqsave(&pidmap_lock, flags);
-       hlist_del_rcu(&pid->pid_chain);
+       for (i = 0; i <= pid->level; i++)
+               hlist_del_rcu(&pid->numbers[i].pid_chain);
        spin_unlock_irqrestore(&pidmap_lock, flags);
 
-       free_pidmap(&init_pid_ns, pid->nr);
+       for (i = 0; i <= pid->level; i++)
+               free_pidmap(pid->numbers[i].ns, pid->numbers[i].nr);
+
        call_rcu(&pid->rcu, delayed_put_pid);
 }
 
-struct pid *alloc_pid(void)
+struct pid *alloc_pid(struct pid_namespace *ns)
 {
        struct pid *pid;
        enum pid_type type;
-       int nr = -1;
+       int i, nr;
+       struct pid_namespace *tmp;
+       struct upid *upid;
 
-       pid = kmem_cache_alloc(pid_cachep, GFP_KERNEL);
+       pid = kmem_cache_alloc(ns->pid_cachep, GFP_KERNEL);
        if (!pid)
                goto out;
 
-       nr = alloc_pidmap(current->nsproxy->pid_ns);
-       if (nr < 0)
-               goto out_free;
+       tmp = ns;
+       for (i = ns->level; i >= 0; i--) {
+               nr = alloc_pidmap(tmp);
+               if (nr < 0)
+                       goto out_free;
+
+               pid->numbers[i].nr = nr;
+               pid->numbers[i].ns = tmp;
+               tmp = tmp->parent;
+       }
 
+       get_pid_ns(ns);
+       pid->level = ns->level;
        atomic_set(&pid->count, 1);
-       pid->nr = nr;
        for (type = 0; type < PIDTYPE_MAX; ++type)
                INIT_HLIST_HEAD(&pid->tasks[type]);
 
        spin_lock_irq(&pidmap_lock);
-       hlist_add_head_rcu(&pid->pid_chain, &pid_hash[pid_hashfn(pid->nr)]);
+       for (i = ns->level; i >= 0; i--) {
+               upid = &pid->numbers[i];
+               hlist_add_head_rcu(&upid->pid_chain,
+                               &pid_hash[pid_hashfn(upid->nr, upid->ns)]);
+       }
        spin_unlock_irq(&pidmap_lock);
 
 out:
        return pid;
 
 out_free:
-       kmem_cache_free(pid_cachep, pid);
+       for (i++; i <= ns->level; i++)
+               free_pidmap(pid->numbers[i].ns, pid->numbers[i].nr);
+
+       kmem_cache_free(ns->pid_cachep, pid);
        pid = NULL;
        goto out;
 }
 
-struct pid * fastcall find_pid(int nr)
+struct pid * fastcall find_pid_ns(int nr, struct pid_namespace *ns)
 {
        struct hlist_node *elem;
-       struct pid *pid;
+       struct upid *pnr;
+
+       hlist_for_each_entry_rcu(pnr, elem,
+                       &pid_hash[pid_hashfn(nr, ns)], pid_chain)
+               if (pnr->nr == nr && pnr->ns == ns)
+                       return container_of(pnr, struct pid,
+                                       numbers[ns->level]);
 
-       hlist_for_each_entry_rcu(pid, elem,
-                       &pid_hash[pid_hashfn(nr)], pid_chain) {
-               if (pid->nr == nr)
-                       return pid;
-       }
        return NULL;
 }
+EXPORT_SYMBOL_GPL(find_pid_ns);
+
+struct pid *find_vpid(int nr)
+{
+       return find_pid_ns(nr, current->nsproxy->pid_ns);
+}
+EXPORT_SYMBOL_GPL(find_vpid);
+
+struct pid *find_pid(int nr)
+{
+       return find_pid_ns(nr, &init_pid_ns);
+}
 EXPORT_SYMBOL_GPL(find_pid);
 
 /*
@@ -307,12 +372,32 @@ struct task_struct * fastcall pid_task(struct pid *pid, enum pid_type type)
 /*
  * Must be called under rcu_read_lock() or with tasklist_lock read-held.
  */
-struct task_struct *find_task_by_pid_type(int type, int nr)
+struct task_struct *find_task_by_pid_type_ns(int type, int nr,
+               struct pid_namespace *ns)
 {
-       return pid_task(find_pid(nr), type);
+       return pid_task(find_pid_ns(nr, ns), type);
 }
 
-EXPORT_SYMBOL(find_task_by_pid_type);
+EXPORT_SYMBOL(find_task_by_pid_type_ns);
+
+struct task_struct *find_task_by_pid(pid_t nr)
+{
+       return find_task_by_pid_type_ns(PIDTYPE_PID, nr, &init_pid_ns);
+}
+EXPORT_SYMBOL(find_task_by_pid);
+
+struct task_struct *find_task_by_vpid(pid_t vnr)
+{
+       return find_task_by_pid_type_ns(PIDTYPE_PID, vnr,
+                       current->nsproxy->pid_ns);
+}
+EXPORT_SYMBOL(find_task_by_vpid);
+
+struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns)
+{
+       return find_task_by_pid_type_ns(PIDTYPE_PID, nr, ns);
+}
+EXPORT_SYMBOL(find_task_by_pid_ns);
 
 struct pid *get_task_pid(struct task_struct *task, enum pid_type type)
 {
@@ -339,45 +424,239 @@ struct pid *find_get_pid(pid_t nr)
        struct pid *pid;
 
        rcu_read_lock();
-       pid = get_pid(find_pid(nr));
+       pid = get_pid(find_vpid(nr));
        rcu_read_unlock();
 
        return pid;
 }
 
+pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns)
+{
+       struct upid *upid;
+       pid_t nr = 0;
+
+       if (pid && ns->level <= pid->level) {
+               upid = &pid->numbers[ns->level];
+               if (upid->ns == ns)
+                       nr = upid->nr;
+       }
+       return nr;
+}
+
+pid_t task_pid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
+{
+       return pid_nr_ns(task_pid(tsk), ns);
+}
+EXPORT_SYMBOL(task_pid_nr_ns);
+
+pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
+{
+       return pid_nr_ns(task_tgid(tsk), ns);
+}
+EXPORT_SYMBOL(task_tgid_nr_ns);
+
+pid_t task_pgrp_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
+{
+       return pid_nr_ns(task_pgrp(tsk), ns);
+}
+EXPORT_SYMBOL(task_pgrp_nr_ns);
+
+pid_t task_session_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
+{
+       return pid_nr_ns(task_session(tsk), ns);
+}
+EXPORT_SYMBOL(task_session_nr_ns);
+
 /*
  * Used by proc to find the first pid that is greater then or equal to nr.
  *
  * If there is a pid at nr this function is exactly the same as find_pid.
  */
-struct pid *find_ge_pid(int nr)
+struct pid *find_ge_pid(int nr, struct pid_namespace *ns)
 {
        struct pid *pid;
 
        do {
-               pid = find_pid(nr);
+               pid = find_pid_ns(nr, ns);
                if (pid)
                        break;
-               nr = next_pidmap(current->nsproxy->pid_ns, nr);
+               nr = next_pidmap(ns, nr);
        } while (nr > 0);
 
        return pid;
 }
 EXPORT_SYMBOL_GPL(find_get_pid);
 
+struct pid_cache {
+       int nr_ids;
+       char name[16];
+       struct kmem_cache *cachep;
+       struct list_head list;
+};
+
+static LIST_HEAD(pid_caches_lh);
+static DEFINE_MUTEX(pid_caches_mutex);
+
+/*
+ * creates the kmem cache to allocate pids from.
+ * @nr_ids: the number of numerical ids this pid will have to carry
+ */
+
+static struct kmem_cache *create_pid_cachep(int nr_ids)
+{
+       struct pid_cache *pcache;
+       struct kmem_cache *cachep;
+
+       mutex_lock(&pid_caches_mutex);
+       list_for_each_entry (pcache, &pid_caches_lh, list)
+               if (pcache->nr_ids == nr_ids)
+                       goto out;
+
+       pcache = kmalloc(sizeof(struct pid_cache), GFP_KERNEL);
+       if (pcache == NULL)
+               goto err_alloc;
+
+       snprintf(pcache->name, sizeof(pcache->name), "pid_%d", nr_ids);
+       cachep = kmem_cache_create(pcache->name,
+                       sizeof(struct pid) + (nr_ids - 1) * sizeof(struct upid),
+                       0, SLAB_HWCACHE_ALIGN, NULL);
+       if (cachep == NULL)
+               goto err_cachep;
+
+       pcache->nr_ids = nr_ids;
+       pcache->cachep = cachep;
+       list_add(&pcache->list, &pid_caches_lh);
+out:
+       mutex_unlock(&pid_caches_mutex);
+       return pcache->cachep;
+
+err_cachep:
+       kfree(pcache);
+err_alloc:
+       mutex_unlock(&pid_caches_mutex);
+       return NULL;
+}
+
+static struct pid_namespace *create_pid_namespace(int level)
+{
+       struct pid_namespace *ns;
+       int i;
+
+       ns = kmem_cache_alloc(pid_ns_cachep, GFP_KERNEL);
+       if (ns == NULL)
+               goto out;
+
+       ns->pidmap[0].page = kzalloc(PAGE_SIZE, GFP_KERNEL);
+       if (!ns->pidmap[0].page)
+               goto out_free;
+
+       ns->pid_cachep = create_pid_cachep(level + 1);
+       if (ns->pid_cachep == NULL)
+               goto out_free_map;
+
+       kref_init(&ns->kref);
+       ns->last_pid = 0;
+       ns->child_reaper = NULL;
+       ns->level = level;
+
+       set_bit(0, ns->pidmap[0].page);
+       atomic_set(&ns->pidmap[0].nr_free, BITS_PER_PAGE - 1);
+
+       for (i = 1; i < PIDMAP_ENTRIES; i++) {
+               ns->pidmap[i].page = 0;
+               atomic_set(&ns->pidmap[i].nr_free, BITS_PER_PAGE);
+       }
+
+       return ns;
+
+out_free_map:
+       kfree(ns->pidmap[0].page);
+out_free:
+       kmem_cache_free(pid_ns_cachep, ns);
+out:
+       return ERR_PTR(-ENOMEM);
+}
+
+static void destroy_pid_namespace(struct pid_namespace *ns)
+{
+       int i;
+
+       for (i = 0; i < PIDMAP_ENTRIES; i++)
+               kfree(ns->pidmap[i].page);
+       kmem_cache_free(pid_ns_cachep, ns);
+}
+
 struct pid_namespace *copy_pid_ns(unsigned long flags, struct pid_namespace *old_ns)
 {
+       struct pid_namespace *new_ns;
+
        BUG_ON(!old_ns);
-       get_pid_ns(old_ns);
-       return old_ns;
+       new_ns = get_pid_ns(old_ns);
+       if (!(flags & CLONE_NEWPID))
+               goto out;
+
+       new_ns = ERR_PTR(-EINVAL);
+       if (flags & CLONE_THREAD)
+               goto out_put;
+
+       new_ns = create_pid_namespace(old_ns->level + 1);
+       if (!IS_ERR(new_ns))
+               new_ns->parent = get_pid_ns(old_ns);
+
+out_put:
+       put_pid_ns(old_ns);
+out:
+       return new_ns;
 }
 
 void free_pid_ns(struct kref *kref)
 {
-       struct pid_namespace *ns;
+       struct pid_namespace *ns, *parent;
 
        ns = container_of(kref, struct pid_namespace, kref);
-       kfree(ns);
+
+       parent = ns->parent;
+       destroy_pid_namespace(ns);
+
+       if (parent != NULL)
+               put_pid_ns(parent);
+}
+
+void zap_pid_ns_processes(struct pid_namespace *pid_ns)
+{
+       int nr;
+       int rc;
+
+       /*
+        * The last thread in the cgroup-init thread group is terminating.
+        * Find remaining pid_ts in the namespace, signal and wait for them
+        * to exit.
+        *
+        * Note:  This signals each threads in the namespace - even those that
+        *        belong to the same thread group, To avoid this, we would have
+        *        to walk the entire tasklist looking a processes in this
+        *        namespace, but that could be unnecessarily expensive if the
+        *        pid namespace has just a few processes. Or we need to
+        *        maintain a tasklist for each pid namespace.
+        *
+        */
+       read_lock(&tasklist_lock);
+       nr = next_pidmap(pid_ns, 1);
+       while (nr > 0) {
+               kill_proc_info(SIGKILL, SEND_SIG_PRIV, nr);
+               nr = next_pidmap(pid_ns, nr);
+       }
+       read_unlock(&tasklist_lock);
+
+       do {
+               clear_thread_flag(TIF_SIGPENDING);
+               rc = sys_wait4(-1, NULL, __WALL, NULL);
+       } while (rc != -ECHILD);
+
+
+       /* Child reaper for the pid namespace is going away */
+       pid_ns->child_reaper = NULL;
+       return;
 }
 
 /*
@@ -412,5 +691,9 @@ void __init pidmap_init(void)
        set_bit(0, init_pid_ns.pidmap[0].page);
        atomic_dec(&init_pid_ns.pidmap[0].nr_free);
 
-       pid_cachep = KMEM_CACHE(pid, SLAB_PANIC);
+       init_pid_ns.pid_cachep = create_pid_cachep(1);
+       if (init_pid_ns.pid_cachep == NULL)
+               panic("Can't create pid_1 cachep\n");
+
+       pid_ns_cachep = KMEM_CACHE(pid_namespace, SLAB_PANIC);
 }
index b53c8fcd9d82d25044867c9529a17f9b1fdb00f8..68c96376e84a6078da9c07d6ebfc2b1c64a3e2a7 100644 (file)
@@ -21,8 +21,8 @@ static int check_clock(const clockid_t which_clock)
 
        read_lock(&tasklist_lock);
        p = find_task_by_pid(pid);
-       if (!p || (CPUCLOCK_PERTHREAD(which_clock) ?
-                  p->tgid != current->tgid : p->tgid != pid)) {
+       if (!p || !(CPUCLOCK_PERTHREAD(which_clock) ?
+                  same_thread_group(p, current) : thread_group_leader(p))) {
                error = -EINVAL;
        }
        read_unlock(&tasklist_lock);
@@ -308,13 +308,13 @@ int posix_cpu_clock_get(const clockid_t which_clock, struct timespec *tp)
                p = find_task_by_pid(pid);
                if (p) {
                        if (CPUCLOCK_PERTHREAD(which_clock)) {
-                               if (p->tgid == current->tgid) {
+                               if (same_thread_group(p, current)) {
                                        error = cpu_clock_sample(which_clock,
                                                                 p, &rtn);
                                }
                        } else {
                                read_lock(&tasklist_lock);
-                               if (p->tgid == pid && p->signal) {
+                               if (thread_group_leader(p) && p->signal) {
                                        error =
                                            cpu_clock_sample_group(which_clock,
                                                                   p, &rtn);
@@ -355,7 +355,7 @@ int posix_cpu_timer_create(struct k_itimer *new_timer)
                        p = current;
                } else {
                        p = find_task_by_pid(pid);
-                       if (p && p->tgid != current->tgid)
+                       if (p && !same_thread_group(p, current))
                                p = NULL;
                }
        } else {
@@ -363,7 +363,7 @@ int posix_cpu_timer_create(struct k_itimer *new_timer)
                        p = current->group_leader;
                } else {
                        p = find_task_by_pid(pid);
-                       if (p && p->tgid != pid)
+                       if (p && !thread_group_leader(p))
                                p = NULL;
                }
        }
index d71ed09fe1dddd985e79f882ff30dd26bf1d28a2..35b4bbfc78ff6ee7d3f389baf0430231ed09af7b 100644 (file)
@@ -404,7 +404,7 @@ static struct task_struct * good_sigevent(sigevent_t * event)
 
        if ((event->sigev_notify & SIGEV_THREAD_ID ) &&
                (!(rtn = find_task_by_pid(event->sigev_notify_thread_id)) ||
-                rtn->tgid != current->tgid ||
+                !same_thread_group(rtn, current) ||
                 (event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_SIGNAL))
                return NULL;
 
@@ -608,7 +608,7 @@ static struct k_itimer * lock_timer(timer_t timer_id, unsigned long *flags)
                spin_lock(&timr->it_lock);
 
                if ((timr->it_id != timer_id) || !(timr->it_process) ||
-                               timr->it_process->tgid != current->tgid) {
+                               !same_thread_group(timr->it_process, current)) {
                        spin_unlock(&timr->it_lock);
                        spin_unlock_irqrestore(&idr_lock, *flags);
                        timr = NULL;
@@ -981,9 +981,20 @@ sys_clock_getres(const clockid_t which_clock, struct timespec __user *tp)
 static int common_nsleep(const clockid_t which_clock, int flags,
                         struct timespec *tsave, struct timespec __user *rmtp)
 {
-       return hrtimer_nanosleep(tsave, rmtp, flags & TIMER_ABSTIME ?
-                                HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
-                                which_clock);
+       struct timespec rmt;
+       int ret;
+
+       ret = hrtimer_nanosleep(tsave, rmtp ? &rmt : NULL,
+                               flags & TIMER_ABSTIME ?
+                               HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
+                               which_clock);
+
+       if (ret && rmtp) {
+               if (copy_to_user(rmtp, &rmt, sizeof(*rmtp)))
+                       return -EFAULT;
+       }
+
+       return ret;
 }
 
 asmlinkage long
index 14b0e10dc95c6a8a1b305f212e2300574120f16f..8e186c678149e23581969a7acfca814a00295b95 100644 (file)
@@ -44,17 +44,6 @@ config PM_VERBOSE
        ---help---
        This option enables verbose messages from the Power Management code.
 
-config DISABLE_CONSOLE_SUSPEND
-       bool "Keep console(s) enabled during suspend/resume (DANGEROUS)"
-       depends on PM_DEBUG && PM_SLEEP
-       default n
-       ---help---
-       This option turns off the console suspend mechanism that prevents
-       debug messages from reaching the console during the suspend/resume
-       operations.  This may be helpful when debugging device drivers'
-       suspend/resume routines, but may itself lead to problems, for example
-       if netconsole is used.
-
 config PM_TRACE
        bool "Suspend/resume event tracing"
        depends on PM_DEBUG && X86 && PM_SLEEP && EXPERIMENTAL
index eb72255b5c86049d1c31f0c9d6ca09b5b653fdca..8b15f777010a9daefe2361adfbf5c1c0851dfb75 100644 (file)
@@ -45,17 +45,18 @@ enum {
 
 static int hibernation_mode = HIBERNATION_SHUTDOWN;
 
-static struct hibernation_ops *hibernation_ops;
+static struct platform_hibernation_ops *hibernation_ops;
 
 /**
  * hibernation_set_ops - set the global hibernate operations
  * @ops: the hibernation operations to use in subsequent hibernation transitions
  */
 
-void hibernation_set_ops(struct hibernation_ops *ops)
+void hibernation_set_ops(struct platform_hibernation_ops *ops)
 {
-       if (ops && !(ops->prepare && ops->enter && ops->finish
-           && ops->pre_restore && ops->restore_cleanup)) {
+       if (ops && !(ops->start && ops->pre_snapshot && ops->finish
+           && ops->prepare && ops->enter && ops->pre_restore
+           && ops->restore_cleanup)) {
                WARN_ON(1);
                return;
        }
@@ -69,16 +70,37 @@ void hibernation_set_ops(struct hibernation_ops *ops)
        mutex_unlock(&pm_mutex);
 }
 
+/**
+ *     platform_start - tell the platform driver that we're starting
+ *     hibernation
+ */
+
+static int platform_start(int platform_mode)
+{
+       return (platform_mode && hibernation_ops) ?
+               hibernation_ops->start() : 0;
+}
 
 /**
- *     platform_prepare - prepare the machine for hibernation using the
+ *     platform_pre_snapshot - prepare the machine for hibernation using the
  *     platform driver if so configured and return an error code if it fails
  */
 
-static int platform_prepare(int platform_mode)
+static int platform_pre_snapshot(int platform_mode)
 {
        return (platform_mode && hibernation_ops) ?
-               hibernation_ops->prepare() : 0;
+               hibernation_ops->pre_snapshot() : 0;
+}
+
+/**
+ *     platform_leave - prepare the machine for switching to the normal mode
+ *     of operation using the platform driver (called with interrupts disabled)
+ */
+
+static void platform_leave(int platform_mode)
+{
+       if (platform_mode && hibernation_ops)
+               hibernation_ops->leave();
 }
 
 /**
@@ -117,6 +139,51 @@ static void platform_restore_cleanup(int platform_mode)
                hibernation_ops->restore_cleanup();
 }
 
+/**
+ *     create_image - freeze devices that need to be frozen with interrupts
+ *     off, create the hibernation image and thaw those devices.  Control
+ *     reappears in this routine after a restore.
+ */
+
+int create_image(int platform_mode)
+{
+       int error;
+
+       error = arch_prepare_suspend();
+       if (error)
+               return error;
+
+       local_irq_disable();
+       /* At this point, device_suspend() has been called, but *not*
+        * device_power_down(). We *must* call device_power_down() now.
+        * Otherwise, drivers for some devices (e.g. interrupt controllers)
+        * become desynchronized with the actual state of the hardware
+        * at resume time, and evil weirdness ensues.
+        */
+       error = device_power_down(PMSG_FREEZE);
+       if (error) {
+               printk(KERN_ERR "Some devices failed to power down, "
+                       KERN_ERR "aborting suspend\n");
+               goto Enable_irqs;
+       }
+
+       save_processor_state();
+       error = swsusp_arch_suspend();
+       if (error)
+               printk(KERN_ERR "Error %d while creating the image\n", error);
+       /* Restore control flow magically appears here */
+       restore_processor_state();
+       if (!in_suspend)
+               platform_leave(platform_mode);
+       /* NOTE:  device_power_up() is just a resume() for devices
+        * that suspended with irqs off ... no overall powerup.
+        */
+       device_power_up();
+ Enable_irqs:
+       local_irq_enable();
+       return error;
+}
+
 /**
  *     hibernation_snapshot - quiesce devices and create the hibernation
  *     snapshot image.
@@ -135,12 +202,16 @@ int hibernation_snapshot(int platform_mode)
        if (error)
                return error;
 
+       error = platform_start(platform_mode);
+       if (error)
+               return error;
+
        suspend_console();
        error = device_suspend(PMSG_FREEZE);
        if (error)
                goto Resume_console;
 
-       error = platform_prepare(platform_mode);
+       error = platform_pre_snapshot(platform_mode);
        if (error)
                goto Resume_devices;
 
@@ -148,7 +219,7 @@ int hibernation_snapshot(int platform_mode)
        if (!error) {
                if (hibernation_mode != HIBERNATION_TEST) {
                        in_suspend = 1;
-                       error = swsusp_suspend();
+                       error = create_image(platform_mode);
                        /* Control returns here after successful restore */
                } else {
                        printk("swsusp debug: Waiting for 5 seconds.\n");
@@ -207,21 +278,50 @@ int hibernation_platform_enter(void)
 {
        int error;
 
-       if (hibernation_ops) {
-               kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK);
-               /*
-                * We have cancelled the power transition by running
-                * hibernation_ops->finish() before saving the image, so we
-                * should let the firmware know that we're going to enter the
-                * sleep state after all
-                */
-               error = hibernation_ops->prepare();
-               sysdev_shutdown();
-               if (!error)
-                       error = hibernation_ops->enter();
-       } else {
-               error = -ENOSYS;
+       if (!hibernation_ops)
+               return -ENOSYS;
+
+       /*
+        * We have cancelled the power transition by running
+        * hibernation_ops->finish() before saving the image, so we should let
+        * the firmware know that we're going to enter the sleep state after all
+        */
+       error = hibernation_ops->start();
+       if (error)
+               return error;
+
+       suspend_console();
+       error = device_suspend(PMSG_SUSPEND);
+       if (error)
+               goto Resume_console;
+
+       error = hibernation_ops->prepare();
+       if (error)
+               goto Resume_devices;
+
+       error = disable_nonboot_cpus();
+       if (error)
+               goto Finish;
+
+       local_irq_disable();
+       error = device_power_down(PMSG_SUSPEND);
+       if (!error) {
+               hibernation_ops->enter();
+               /* We should never get here */
+               while (1);
        }
+       local_irq_enable();
+
+       /*
+        * We don't need to reenable the nonboot CPUs or resume consoles, since
+        * the system is going to be halted anyway.
+        */
+ Finish:
+       hibernation_ops->finish();
+ Resume_devices:
+       device_resume();
+ Resume_console:
+       resume_console();
        return error;
 }
 
@@ -238,14 +338,14 @@ static void power_down(void)
        case HIBERNATION_TEST:
        case HIBERNATION_TESTPROC:
                break;
-       case HIBERNATION_SHUTDOWN:
-               kernel_power_off();
-               break;
        case HIBERNATION_REBOOT:
                kernel_restart(NULL);
                break;
        case HIBERNATION_PLATFORM:
                hibernation_platform_enter();
+       case HIBERNATION_SHUTDOWN:
+               kernel_power_off();
+               break;
        }
        kernel_halt();
        /*
@@ -298,6 +398,10 @@ int hibernate(void)
        if (error)
                goto Exit;
 
+       printk("Syncing filesystems ... ");
+       sys_sync();
+       printk("done.\n");
+
        error = prepare_processes();
        if (error)
                goto Finish;
index 350b485b3b60bdc7679cbd9963ef4ba4b64ed4f3..3cdf95b1dc92af97e13e8a6c68c4e0a6f8d42153 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/resume-trace.h>
 #include <linux/freezer.h>
 #include <linux/vmstat.h>
+#include <linux/syscalls.h>
 
 #include "power.h"
 
@@ -32,39 +33,32 @@ DEFINE_MUTEX(pm_mutex);
 /* This is just an arbitrary number */
 #define FREE_PAGE_NUMBER (100)
 
-struct pm_ops *pm_ops;
+static struct platform_suspend_ops *suspend_ops;
 
 /**
- *     pm_set_ops - Set the global power method table. 
+ *     suspend_set_ops - Set the global suspend method table.
  *     @ops:   Pointer to ops structure.
  */
 
-void pm_set_ops(struct pm_ops * ops)
+void suspend_set_ops(struct platform_suspend_ops *ops)
 {
        mutex_lock(&pm_mutex);
-       pm_ops = ops;
+       suspend_ops = ops;
        mutex_unlock(&pm_mutex);
 }
 
 /**
- * pm_valid_only_mem - generic memory-only valid callback
+ * suspend_valid_only_mem - generic memory-only valid callback
  *
- * pm_ops drivers that implement mem suspend only and only need
+ * Platform drivers that implement mem suspend only and only need
  * to check for that in their .valid callback can use this instead
  * of rolling their own .valid callback.
  */
-int pm_valid_only_mem(suspend_state_t state)
+int suspend_valid_only_mem(suspend_state_t state)
 {
        return state == PM_SUSPEND_MEM;
 }
 
-
-static inline void pm_finish(suspend_state_t state)
-{
-       if (pm_ops->finish)
-               pm_ops->finish(state);
-}
-
 /**
  *     suspend_prepare - Do prep work before entering low-power state.
  *
@@ -76,7 +70,7 @@ static int suspend_prepare(void)
        int error;
        unsigned int free_pages;
 
-       if (!pm_ops || !pm_ops->enter)
+       if (!suspend_ops || !suspend_ops->enter)
                return -EPERM;
 
        error = pm_notifier_call_chain(PM_SUSPEND_PREPARE);
@@ -128,7 +122,7 @@ void __attribute__ ((weak)) arch_suspend_enable_irqs(void)
  *
  *     This function should be called after devices have been suspended.
  */
-int suspend_enter(suspend_state_t state)
+static int suspend_enter(suspend_state_t state)
 {
        int error = 0;
 
@@ -139,7 +133,7 @@ int suspend_enter(suspend_state_t state)
                printk(KERN_ERR "Some devices failed to power down\n");
                goto Done;
        }
-       error = pm_ops->enter(state);
+       error = suspend_ops->enter(state);
        device_power_up();
  Done:
        arch_suspend_enable_irqs();
@@ -156,11 +150,11 @@ int suspend_devices_and_enter(suspend_state_t state)
 {
        int error;
 
-       if (!pm_ops)
+       if (!suspend_ops)
                return -ENOSYS;
 
-       if (pm_ops->set_target) {
-               error = pm_ops->set_target(state);
+       if (suspend_ops->set_target) {
+               error = suspend_ops->set_target(state);
                if (error)
                        return error;
        }
@@ -170,8 +164,8 @@ int suspend_devices_and_enter(suspend_state_t state)
                printk(KERN_ERR "Some devices failed to suspend\n");
                goto Resume_console;
        }
-       if (pm_ops->prepare) {
-               error = pm_ops->prepare(state);
+       if (suspend_ops->prepare) {
+               error = suspend_ops->prepare();
                if (error)
                        goto Resume_devices;
        }
@@ -180,7 +174,8 @@ int suspend_devices_and_enter(suspend_state_t state)
                suspend_enter(state);
 
        enable_nonboot_cpus();
-       pm_finish(state);
+       if (suspend_ops->finish)
+               suspend_ops->finish();
  Resume_devices:
        device_resume();
  Resume_console:
@@ -214,7 +209,7 @@ static inline int valid_state(suspend_state_t state)
        /* All states need lowlevel support and need to be valid
         * to the lowlevel implementation, no valid callback
         * implies that none are valid. */
-       if (!pm_ops || !pm_ops->valid || !pm_ops->valid(state))
+       if (!suspend_ops || !suspend_ops->valid || !suspend_ops->valid(state))
                return 0;
        return 1;
 }
@@ -236,9 +231,14 @@ static int enter_state(suspend_state_t state)
 
        if (!valid_state(state))
                return -ENODEV;
+
        if (!mutex_trylock(&pm_mutex))
                return -EBUSY;
 
+       printk("Syncing filesystems ... ");
+       sys_sync();
+       printk("done.\n");
+
        pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]);
        if ((error = suspend_prepare()))
                goto Unlock;
index 95fbf2dd3fe33901be99ef8ce60a3bf2ca9fb833..195dc4611764b08a65780976a6231aaf004889fe 100644 (file)
@@ -11,14 +11,32 @@ struct swsusp_info {
        unsigned long           size;
 } __attribute__((aligned(PAGE_SIZE)));
 
+#ifdef CONFIG_HIBERNATION
+#ifdef CONFIG_ARCH_HIBERNATION_HEADER
+/* Maximum size of architecture specific data in a hibernation header */
+#define MAX_ARCH_HEADER_SIZE   (sizeof(struct new_utsname) + 4)
 
+extern int arch_hibernation_header_save(void *addr, unsigned int max_size);
+extern int arch_hibernation_header_restore(void *addr);
+
+static inline int init_header_complete(struct swsusp_info *info)
+{
+       return arch_hibernation_header_save(info, MAX_ARCH_HEADER_SIZE);
+}
+
+static inline char *check_image_kernel(struct swsusp_info *info)
+{
+       return arch_hibernation_header_restore(info) ?
+                       "architecture specific data" : NULL;
+}
+#endif /* CONFIG_ARCH_HIBERNATION_HEADER */
 
-#ifdef CONFIG_HIBERNATION
 /*
  * Keep some memory free so that I/O operations can succeed without paging
  * [Might this be more than 4 MB?]
  */
 #define PAGES_FOR_IO   ((4096 * 1024) >> PAGE_SHIFT)
+
 /*
  * Keep 1 MB of memory free so that device drivers can allocate some pages in
  * their .suspend() routines without breaking the suspend to disk.
@@ -165,7 +183,6 @@ extern int swsusp_swap_in_use(void);
 extern int swsusp_check(void);
 extern int swsusp_shrink_memory(void);
 extern void swsusp_free(void);
-extern int swsusp_suspend(void);
 extern int swsusp_resume(void);
 extern int swsusp_read(unsigned int *flags_p);
 extern int swsusp_write(unsigned int flags);
index 3434940a3df175679e4391f94755f09431c864c1..6533923e711b5dd8be01efd5f1e9576250ebf42f 100644 (file)
@@ -75,21 +75,79 @@ void refrigerator(void)
        __set_current_state(save);
 }
 
-static void freeze_task(struct task_struct *p)
+static void fake_signal_wake_up(struct task_struct *p, int resume)
 {
        unsigned long flags;
 
-       if (!freezing(p)) {
+       spin_lock_irqsave(&p->sighand->siglock, flags);
+       signal_wake_up(p, resume);
+       spin_unlock_irqrestore(&p->sighand->siglock, flags);
+}
+
+static void send_fake_signal(struct task_struct *p)
+{
+       if (p->state == TASK_STOPPED)
+               force_sig_specific(SIGSTOP, p);
+       fake_signal_wake_up(p, p->state == TASK_STOPPED);
+}
+
+static int has_mm(struct task_struct *p)
+{
+       return (p->mm && !(p->flags & PF_BORROWED_MM));
+}
+
+/**
+ *     freeze_task - send a freeze request to given task
+ *     @p: task to send the request to
+ *     @with_mm_only: if set, the request will only be sent if the task has its
+ *             own mm
+ *     Return value: 0, if @with_mm_only is set and the task has no mm of its
+ *             own or the task is frozen, 1, otherwise
+ *
+ *     The freeze request is sent by seting the tasks's TIF_FREEZE flag and
+ *     either sending a fake signal to it or waking it up, depending on whether
+ *     or not it has its own mm (ie. it is a user land task).  If @with_mm_only
+ *     is set and the task has no mm of its own (ie. it is a kernel thread),
+ *     its TIF_FREEZE flag should not be set.
+ *
+ *     The task_lock() is necessary to prevent races with exit_mm() or
+ *     use_mm()/unuse_mm() from occuring.
+ */
+static int freeze_task(struct task_struct *p, int with_mm_only)
+{
+       int ret = 1;
+
+       task_lock(p);
+       if (freezing(p)) {
+               if (has_mm(p)) {
+                       if (!signal_pending(p))
+                               fake_signal_wake_up(p, 0);
+               } else {
+                       if (with_mm_only)
+                               ret = 0;
+                       else
+                               wake_up_state(p, TASK_INTERRUPTIBLE);
+               }
+       } else {
                rmb();
-               if (!frozen(p)) {
-                       set_freeze_flag(p);
-                       if (p->state == TASK_STOPPED)
-                               force_sig_specific(SIGSTOP, p);
-                       spin_lock_irqsave(&p->sighand->siglock, flags);
-                       signal_wake_up(p, p->state == TASK_STOPPED);
-                       spin_unlock_irqrestore(&p->sighand->siglock, flags);
+               if (frozen(p)) {
+                       ret = 0;
+               } else {
+                       if (has_mm(p)) {
+                               set_freeze_flag(p);
+                               send_fake_signal(p);
+                       } else {
+                               if (with_mm_only) {
+                                       ret = 0;
+                               } else {
+                                       set_freeze_flag(p);
+                                       wake_up_state(p, TASK_INTERRUPTIBLE);
+                               }
+                       }
                }
        }
+       task_unlock(p);
+       return ret;
 }
 
 static void cancel_freezing(struct task_struct *p)
@@ -110,6 +168,11 @@ static int try_to_freeze_tasks(int freeze_user_space)
        struct task_struct *g, *p;
        unsigned long end_time;
        unsigned int todo;
+       struct timeval start, end;
+       s64 elapsed_csecs64;
+       unsigned int elapsed_csecs;
+
+       do_gettimeofday(&start);
 
        end_time = jiffies + TIMEOUT;
        do {
@@ -119,31 +182,14 @@ static int try_to_freeze_tasks(int freeze_user_space)
                        if (frozen(p) || !freezeable(p))
                                continue;
 
-                       if (freeze_user_space) {
-                               if (p->state == TASK_TRACED &&
-                                   frozen(p->parent)) {
-                                       cancel_freezing(p);
-                                       continue;
-                               }
-                               /*
-                                * Kernel threads should not have TIF_FREEZE set
-                                * at this point, so we must ensure that either
-                                * p->mm is not NULL *and* PF_BORROWED_MM is
-                                * unset, or TIF_FRREZE is left unset.
-                                * The task_lock() is necessary to prevent races
-                                * with exit_mm() or use_mm()/unuse_mm() from
-                                * occuring.
-                                */
-                               task_lock(p);
-                               if (!p->mm || (p->flags & PF_BORROWED_MM)) {
-                                       task_unlock(p);
-                                       continue;
-                               }
-                               freeze_task(p);
-                               task_unlock(p);
-                       } else {
-                               freeze_task(p);
+                       if (p->state == TASK_TRACED && frozen(p->parent)) {
+                               cancel_freezing(p);
+                               continue;
                        }
+
+                       if (!freeze_task(p, freeze_user_space))
+                               continue;
+
                        if (!freezer_should_skip(p))
                                todo++;
                } while_each_thread(g, p);
@@ -153,6 +199,11 @@ static int try_to_freeze_tasks(int freeze_user_space)
                        break;
        } while (todo);
 
+       do_gettimeofday(&end);
+       elapsed_csecs64 = timeval_to_ns(&end) - timeval_to_ns(&start);
+       do_div(elapsed_csecs64, NSEC_PER_SEC / 100);
+       elapsed_csecs = elapsed_csecs64;
+
        if (todo) {
                /* This does not unfreeze processes that are already frozen
                 * (we have slightly ugly calling convention in that respect,
@@ -160,10 +211,9 @@ static int try_to_freeze_tasks(int freeze_user_space)
                 * but it cleans up leftover PF_FREEZE requests.
                 */
                printk("\n");
-               printk(KERN_ERR "Freezing of %s timed out after %d seconds "
+               printk(KERN_ERR "Freezing of tasks failed after %d.%02d seconds "
                                "(%d tasks refusing to freeze):\n",
-                               freeze_user_space ? "user space " : "tasks ",
-                               TIMEOUT / HZ, todo);
+                               elapsed_csecs / 100, elapsed_csecs % 100, todo);
                show_state();
                read_lock(&tasklist_lock);
                do_each_thread(g, p) {
@@ -174,6 +224,9 @@ static int try_to_freeze_tasks(int freeze_user_space)
                        task_unlock(p);
                } while_each_thread(g, p);
                read_unlock(&tasklist_lock);
+       } else {
+               printk("(elapsed %d.%02d seconds) ", elapsed_csecs / 100,
+                       elapsed_csecs % 100);
        }
 
        return todo ? -EBUSY : 0;
@@ -186,19 +239,21 @@ int freeze_processes(void)
 {
        int error;
 
-       printk("Stopping tasks ... ");
+       printk("Freezing user space processes ... ");
        error = try_to_freeze_tasks(FREEZER_USER_SPACE);
        if (error)
-               return error;
+               goto Exit;
+       printk("done.\n");
 
-       sys_sync();
+       printk("Freezing remaining freezable tasks ... ");
        error = try_to_freeze_tasks(FREEZER_KERNEL_THREADS);
        if (error)
-               return error;
-
-       printk("done.\n");
+               goto Exit;
+       printk("done.");
+ Exit:
        BUG_ON(in_atomic());
-       return 0;
+       printk("\n");
+       return error;
 }
 
 static void thaw_tasks(int thaw_user_space)
index a686590d88c1b5def265e84aa9ab9091c4b07290..78039b477d2bd7bbae3ab893763111475ea932a6 100644 (file)
@@ -1005,11 +1005,12 @@ copy_data_pages(struct memory_bitmap *copy_bm, struct memory_bitmap *orig_bm)
        }
        memory_bm_position_reset(orig_bm);
        memory_bm_position_reset(copy_bm);
-       do {
+       for(;;) {
                pfn = memory_bm_next_pfn(orig_bm);
-               if (likely(pfn != BM_END_OF_MAP))
-                       copy_data_page(memory_bm_next_pfn(copy_bm), pfn);
-       } while (pfn != BM_END_OF_MAP);
+               if (unlikely(pfn == BM_END_OF_MAP))
+                       break;
+               copy_data_page(memory_bm_next_pfn(copy_bm), pfn);
+       }
 }
 
 /* Total number of image pages */
@@ -1239,17 +1240,39 @@ asmlinkage int swsusp_save(void)
        return 0;
 }
 
-static void init_header(struct swsusp_info *info)
+#ifndef CONFIG_ARCH_HIBERNATION_HEADER
+static int init_header_complete(struct swsusp_info *info)
 {
-       memset(info, 0, sizeof(struct swsusp_info));
+       memcpy(&info->uts, init_utsname(), sizeof(struct new_utsname));
        info->version_code = LINUX_VERSION_CODE;
+       return 0;
+}
+
+static char *check_image_kernel(struct swsusp_info *info)
+{
+       if (info->version_code != LINUX_VERSION_CODE)
+               return "kernel version";
+       if (strcmp(info->uts.sysname,init_utsname()->sysname))
+               return "system type";
+       if (strcmp(info->uts.release,init_utsname()->release))
+               return "kernel release";
+       if (strcmp(info->uts.version,init_utsname()->version))
+               return "version";
+       if (strcmp(info->uts.machine,init_utsname()->machine))
+               return "machine";
+       return NULL;
+}
+#endif /* CONFIG_ARCH_HIBERNATION_HEADER */
+
+static int init_header(struct swsusp_info *info)
+{
+       memset(info, 0, sizeof(struct swsusp_info));
        info->num_physpages = num_physpages;
-       memcpy(&info->uts, init_utsname(), sizeof(struct new_utsname));
-       info->cpus = num_online_cpus();
        info->image_pages = nr_copy_pages;
        info->pages = nr_copy_pages + nr_meta_pages + 1;
        info->size = info->pages;
        info->size <<= PAGE_SHIFT;
+       return init_header_complete(info);
 }
 
 /**
@@ -1303,7 +1326,11 @@ int snapshot_read_next(struct snapshot_handle *handle, size_t count)
                        return -ENOMEM;
        }
        if (!handle->offset) {
-               init_header((struct swsusp_info *)buffer);
+               int error;
+
+               error = init_header((struct swsusp_info *)buffer);
+               if (error)
+                       return error;
                handle->buffer = buffer;
                memory_bm_position_reset(&orig_bm);
                memory_bm_position_reset(&copy_bm);
@@ -1394,22 +1421,13 @@ duplicate_memory_bitmap(struct memory_bitmap *dst, struct memory_bitmap *src)
        }
 }
 
-static inline int check_header(struct swsusp_info *info)
+static int check_header(struct swsusp_info *info)
 {
-       char *reason = NULL;
+       char *reason;
 
-       if (info->version_code != LINUX_VERSION_CODE)
-               reason = "kernel version";
-       if (info->num_physpages != num_physpages)
+       reason = check_image_kernel(info);
+       if (!reason && info->num_physpages != num_physpages)
                reason = "memory size";
-       if (strcmp(info->uts.sysname,init_utsname()->sysname))
-               reason = "system type";
-       if (strcmp(info->uts.release,init_utsname()->release))
-               reason = "kernel release";
-       if (strcmp(info->uts.version,init_utsname()->version))
-               reason = "version";
-       if (strcmp(info->uts.machine,init_utsname()->machine))
-               reason = "machine";
        if (reason) {
                printk(KERN_ERR "swsusp: Resume mismatch: %s\n", reason);
                return -EPERM;
index 5da304c8f1f66473233d68d713a66e2a17c59d54..e1722d3155f17057284ab6374b3a00b9a31ed1d2 100644 (file)
@@ -270,39 +270,6 @@ int swsusp_shrink_memory(void)
        return 0;
 }
 
-int swsusp_suspend(void)
-{
-       int error;
-
-       if ((error = arch_prepare_suspend()))
-               return error;
-
-       local_irq_disable();
-       /* At this point, device_suspend() has been called, but *not*
-        * device_power_down(). We *must* device_power_down() now.
-        * Otherwise, drivers for some devices (e.g. interrupt controllers)
-        * become desynchronized with the actual state of the hardware
-        * at resume time, and evil weirdness ensues.
-        */
-       if ((error = device_power_down(PMSG_FREEZE))) {
-               printk(KERN_ERR "Some devices failed to power down, aborting suspend\n");
-               goto Enable_irqs;
-       }
-
-       save_processor_state();
-       if ((error = swsusp_arch_suspend()))
-               printk(KERN_ERR "Error %d suspending\n", error);
-       /* Restore control flow magically appears here */
-       restore_processor_state();
-       /* NOTE:  device_power_up() is just a resume() for devices
-        * that suspended with irqs off ... no overall powerup.
-        */
-       device_power_up();
- Enable_irqs:
-       local_irq_enable();
-       return error;
-}
-
 int swsusp_resume(void)
 {
        int error;
index bd0723a7df3f99cf811834f9cc1d107202d46947..5bd321bcbb75f06031d6ede749cad599c251373c 100644 (file)
@@ -153,6 +153,10 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
                mutex_lock(&pm_mutex);
                error = pm_notifier_call_chain(PM_HIBERNATION_PREPARE);
                if (!error) {
+                       printk("Syncing filesystems ... ");
+                       sys_sync();
+                       printk("done.\n");
+
                        error = freeze_processes();
                        if (error)
                                thaw_processes();
index 52493474f0abafdfd7939ab57f3f2d6ad2006695..a30fe33de395a7964f68e237c73de7344190b18a 100644 (file)
@@ -862,7 +862,16 @@ int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, cha
        return -1;
 }
 
-#ifndef CONFIG_DISABLE_CONSOLE_SUSPEND
+int console_suspend_enabled = 1;
+EXPORT_SYMBOL(console_suspend_enabled);
+
+static int __init console_suspend_disable(char *str)
+{
+       console_suspend_enabled = 0;
+       return 1;
+}
+__setup("no_console_suspend", console_suspend_disable);
+
 /**
  * suspend_console - suspend the console subsystem
  *
@@ -870,6 +879,8 @@ int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, cha
  */
 void suspend_console(void)
 {
+       if (!console_suspend_enabled)
+               return;
        printk("Suspending console(s)\n");
        acquire_console_sem();
        console_suspended = 1;
@@ -877,10 +888,11 @@ void suspend_console(void)
 
 void resume_console(void)
 {
+       if (!console_suspend_enabled)
+               return;
        console_suspended = 0;
        release_console_sem();
 }
-#endif /* CONFIG_DISABLE_CONSOLE_SUSPEND */
 
 /**
  * acquire_console_sem - lock the console system for exclusive use.
index a73ebd3b9d4ca5019522fcf80c47eac8d5d7fa0c..7c76f2ffaeaad78060cfb3223857a89c7a4ccb8f 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/security.h>
 #include <linux/signal.h>
 #include <linux/audit.h>
+#include <linux/pid_namespace.h>
 
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
@@ -168,7 +169,7 @@ int ptrace_attach(struct task_struct *task)
        retval = -EPERM;
        if (task->pid <= 1)
                goto out;
-       if (task->tgid == current->tgid)
+       if (same_thread_group(task, current))
                goto out;
 
 repeat:
@@ -443,7 +444,7 @@ struct task_struct *ptrace_get_task_struct(pid_t pid)
                return ERR_PTR(-EPERM);
 
        read_lock(&tasklist_lock);
-       child = find_task_by_pid(pid);
+       child = find_task_by_vpid(pid);
        if (child)
                get_task_struct(child);
 
index ad855017bc59de72ebf592fda7576edf6e245bb4..61134eb7a0c8a9b2d2e0557b33ff4fbd7ff96f31 100644 (file)
@@ -370,7 +370,7 @@ void relay_reset(struct rchan *chan)
        if (!chan)
                return;
 
-       if (chan->is_global && chan->buf[0]) {
+       if (chan->is_global && chan->buf[0]) {
                __relay_reset(chan->buf[0], 0);
                return;
        }
@@ -850,13 +850,13 @@ static int relay_file_read_avail(struct rchan_buf *buf, size_t read_pos)
                buf->subbufs_consumed = consumed;
                buf->bytes_consumed = 0;
        }
-       
+
        produced = (produced % n_subbufs) * subbuf_size + buf->offset;
        consumed = (consumed % n_subbufs) * subbuf_size + buf->bytes_consumed;
 
        if (consumed > produced)
                produced += n_subbufs * subbuf_size;
-       
+
        if (consumed == produced)
                return 0;
 
index 6b0703db152d2a61411595380ce4b608e98f6890..56d73cb8826d86ff75ce0dea818ce658be11cf49 100644 (file)
@@ -87,7 +87,7 @@ static int rt_trace_on = 1;
 static void printk_task(struct task_struct *p)
 {
        if (p)
-               printk("%16s:%5d [%p, %3d]", p->comm, p->pid, p, p->prio);
+               printk("%16s:%5d [%p, %3d]", p->comm, task_pid_nr(p), p, p->prio);
        else
                printk("<none>");
 }
@@ -152,22 +152,25 @@ void debug_rt_mutex_print_deadlock(struct rt_mutex_waiter *waiter)
        printk(  "[ BUG: circular locking deadlock detected! ]\n");
        printk(  "--------------------------------------------\n");
        printk("%s/%d is deadlocking current task %s/%d\n\n",
-              task->comm, task->pid, current->comm, current->pid);
+              task->comm, task_pid_nr(task),
+              current->comm, task_pid_nr(current));
 
        printk("\n1) %s/%d is trying to acquire this lock:\n",
-              current->comm, current->pid);
+              current->comm, task_pid_nr(current));
        printk_lock(waiter->lock, 1);
 
-       printk("\n2) %s/%d is blocked on this lock:\n", task->comm, task->pid);
+       printk("\n2) %s/%d is blocked on this lock:\n",
+               task->comm, task_pid_nr(task));
        printk_lock(waiter->deadlock_lock, 1);
 
        debug_show_held_locks(current);
        debug_show_held_locks(task);
 
-       printk("\n%s/%d's [blocked] stackdump:\n\n", task->comm, task->pid);
+       printk("\n%s/%d's [blocked] stackdump:\n\n",
+               task->comm, task_pid_nr(task));
        show_stack(task, NULL);
        printk("\n%s/%d's [current] stackdump:\n\n",
-              current->comm, current->pid);
+               current->comm, task_pid_nr(current));
        dump_stack();
        debug_show_all_locks();
 
index 8cd9bd2cdb34243a89c45102708abdcc2c7cbdbd..0deef71ff8d2a7444f74af1904b11b93e2a86766 100644 (file)
@@ -185,7 +185,7 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task,
                        prev_max = max_lock_depth;
                        printk(KERN_WARNING "Maximum lock depth %d reached "
                               "task: %s (%d)\n", max_lock_depth,
-                              top_task->comm, top_task->pid);
+                              top_task->comm, task_pid_nr(top_task));
                }
                put_task_struct(task);
 
index 92721d1534b85f1e2f3b192b041677b50b79b9e9..2810e562a9913d79aa510f31aa5db46a1b7fbf01 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/vmalloc.h>
 #include <linux/blkdev.h>
 #include <linux/delay.h>
+#include <linux/pid_namespace.h>
 #include <linux/smp.h>
 #include <linux/threads.h>
 #include <linux/timer.h>
@@ -51,6 +52,7 @@
 #include <linux/cpu.h>
 #include <linux/cpuset.h>
 #include <linux/percpu.h>
+#include <linux/cpu_acct.h>
 #include <linux/kthread.h>
 #include <linux/seq_file.h>
 #include <linux/sysctl.h>
@@ -153,10 +155,15 @@ struct rt_prio_array {
 
 #ifdef CONFIG_FAIR_GROUP_SCHED
 
+#include <linux/cgroup.h>
+
 struct cfs_rq;
 
 /* task group related information */
 struct task_group {
+#ifdef CONFIG_FAIR_CGROUP_SCHED
+       struct cgroup_subsys_state css;
+#endif
        /* schedulable entities of this group on each cpu */
        struct sched_entity **se;
        /* runqueue "owned" by this group on each cpu */
@@ -197,6 +204,9 @@ static inline struct task_group *task_group(struct task_struct *p)
 
 #ifdef CONFIG_FAIR_USER_SCHED
        tg = p->user->tg;
+#elif defined(CONFIG_FAIR_CGROUP_SCHED)
+       tg = container_of(task_subsys_state(p, cpu_cgroup_subsys_id),
+                               struct task_group, css);
 #else
        tg  = &init_task_group;
 #endif
@@ -266,7 +276,8 @@ struct rt_rq {
  * acquire operations must be ordered by ascending &runqueue.
  */
 struct rq {
-       spinlock_t lock;        /* runqueue lock */
+       /* runqueue lock: */
+       spinlock_t lock;
 
        /*
         * nr_running and cpu_load should be in the same cacheline because
@@ -279,13 +290,15 @@ struct rq {
 #ifdef CONFIG_NO_HZ
        unsigned char in_nohz_recently;
 #endif
-       struct load_weight load;        /* capture load from *all* tasks on this cpu */
+       /* capture load from *all* tasks on this cpu: */
+       struct load_weight load;
        unsigned long nr_load_updates;
        u64 nr_switches;
 
        struct cfs_rq cfs;
 #ifdef CONFIG_FAIR_GROUP_SCHED
-       struct list_head leaf_cfs_rq_list; /* list of leaf cfs_rq on this cpu */
+       /* list of leaf cfs_rq on this cpu: */
+       struct list_head leaf_cfs_rq_list;
 #endif
        struct rt_rq  rt;
 
@@ -317,7 +330,8 @@ struct rq {
        /* For active balancing */
        int active_balance;
        int push_cpu;
-       int cpu;                /* cpu of this runqueue */
+       /* cpu of this runqueue: */
+       int cpu;
 
        struct task_struct *migration_thread;
        struct list_head migration_queue;
@@ -328,22 +342,22 @@ struct rq {
        struct sched_info rq_sched_info;
 
        /* sys_sched_yield() stats */
-       unsigned long yld_exp_empty;
-       unsigned long yld_act_empty;
-       unsigned long yld_both_empty;
-       unsigned long yld_count;
+       unsigned int yld_exp_empty;
+       unsigned int yld_act_empty;
+       unsigned int yld_both_empty;
+       unsigned int yld_count;
 
        /* schedule() stats */
-       unsigned long sched_switch;
-       unsigned long sched_count;
-       unsigned long sched_goidle;
+       unsigned int sched_switch;
+       unsigned int sched_count;
+       unsigned int sched_goidle;
 
        /* try_to_wake_up() stats */
-       unsigned long ttwu_count;
-       unsigned long ttwu_local;
+       unsigned int ttwu_count;
+       unsigned int ttwu_local;
 
        /* BKL stats */
-       unsigned long bkl_count;
+       unsigned int bkl_count;
 #endif
        struct lock_class_key rq_lock_key;
 };
@@ -449,12 +463,12 @@ enum {
 };
 
 const_debug unsigned int sysctl_sched_features =
-               SCHED_FEAT_NEW_FAIR_SLEEPERS    *1 |
-               SCHED_FEAT_START_DEBIT          *1 |
-               SCHED_FEAT_TREE_AVG             *0 |
-               SCHED_FEAT_APPROX_AVG           *0 |
-               SCHED_FEAT_WAKEUP_PREEMPT       *1 |
-               SCHED_FEAT_PREEMPT_RESTRICT     *1;
+               SCHED_FEAT_NEW_FAIR_SLEEPERS    * 1 |
+               SCHED_FEAT_START_DEBIT          * 1 |
+               SCHED_FEAT_TREE_AVG             * 0 |
+               SCHED_FEAT_APPROX_AVG           * 0 |
+               SCHED_FEAT_WAKEUP_PREEMPT       * 1 |
+               SCHED_FEAT_PREEMPT_RESTRICT     * 1;
 
 #define sched_feat(x) (sysctl_sched_features & SCHED_FEAT_##x)
 
@@ -1871,7 +1885,7 @@ asmlinkage void schedule_tail(struct task_struct *prev)
        preempt_enable();
 #endif
        if (current->set_child_tid)
-               put_user(current->pid, current->set_child_tid);
+               put_user(task_pid_vnr(current), current->set_child_tid);
 }
 
 /*
@@ -3296,16 +3310,19 @@ unsigned long long task_sched_runtime(struct task_struct *p)
 /*
  * Account user cpu time to a process.
  * @p: the process that the cpu time gets accounted to
- * @hardirq_offset: the offset to subtract from hardirq_count()
  * @cputime: the cpu time spent in user space since the last update
  */
 void account_user_time(struct task_struct *p, cputime_t cputime)
 {
        struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
        cputime64_t tmp;
+       struct rq *rq = this_rq();
 
        p->utime = cputime_add(p->utime, cputime);
 
+       if (p != rq->idle)
+               cpuacct_charge(p, cputime);
+
        /* Add user time to cpustat. */
        tmp = cputime_to_cputime64(cputime);
        if (TASK_NICE(p) > 0)
@@ -3333,6 +3350,16 @@ void account_guest_time(struct task_struct *p, cputime_t cputime)
        cpustat->guest = cputime64_add(cpustat->guest, tmp);
 }
 
+/*
+ * Account scaled user cpu time to a process.
+ * @p: the process that the cpu time gets accounted to
+ * @cputime: the cpu time spent in user space since the last update
+ */
+void account_user_time_scaled(struct task_struct *p, cputime_t cputime)
+{
+       p->utimescaled = cputime_add(p->utimescaled, cputime);
+}
+
 /*
  * Account system cpu time to a process.
  * @p: the process that the cpu time gets accounted to
@@ -3348,7 +3375,6 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
 
        if (p->flags & PF_VCPU) {
                account_guest_time(p, cputime);
-               p->flags &= ~PF_VCPU;
                return;
        }
 
@@ -3360,9 +3386,10 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
                cpustat->irq = cputime64_add(cpustat->irq, tmp);
        else if (softirq_count())
                cpustat->softirq = cputime64_add(cpustat->softirq, tmp);
-       else if (p != rq->idle)
+       else if (p != rq->idle) {
                cpustat->system = cputime64_add(cpustat->system, tmp);
-       else if (atomic_read(&rq->nr_iowait) > 0)
+               cpuacct_charge(p, cputime);
+       } else if (atomic_read(&rq->nr_iowait) > 0)
                cpustat->iowait = cputime64_add(cpustat->iowait, tmp);
        else
                cpustat->idle = cputime64_add(cpustat->idle, tmp);
@@ -3370,6 +3397,17 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
        acct_update_integrals(p);
 }
 
+/*
+ * Account scaled system cpu time to a process.
+ * @p: the process that the cpu time gets accounted to
+ * @hardirq_offset: the offset to subtract from hardirq_count()
+ * @cputime: the cpu time spent in kernel space since the last update
+ */
+void account_system_time_scaled(struct task_struct *p, cputime_t cputime)
+{
+       p->stimescaled = cputime_add(p->stimescaled, cputime);
+}
+
 /*
  * Account for involuntary wait time.
  * @p: the process from which the cpu time has been stolen
@@ -3387,8 +3425,10 @@ void account_steal_time(struct task_struct *p, cputime_t steal)
                        cpustat->iowait = cputime64_add(cpustat->iowait, tmp);
                else
                        cpustat->idle = cputime64_add(cpustat->idle, tmp);
-       } else
+       } else {
                cpustat->steal = cputime64_add(cpustat->steal, tmp);
+               cpuacct_charge(p, -tmp);
+       }
 }
 
 /*
@@ -3468,7 +3508,7 @@ EXPORT_SYMBOL(sub_preempt_count);
 static noinline void __schedule_bug(struct task_struct *prev)
 {
        printk(KERN_ERR "BUG: scheduling while atomic: %s/0x%08x/%d\n",
-               prev->comm, preempt_count(), prev->pid);
+               prev->comm, preempt_count(), task_pid_nr(prev));
        debug_show_held_locks(prev);
        if (irqs_disabled())
                print_irqtrace_events(prev);
@@ -3859,7 +3899,10 @@ EXPORT_SYMBOL(wait_for_completion_timeout);
 
 int __sched wait_for_completion_interruptible(struct completion *x)
 {
-       return wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_INTERRUPTIBLE);
+       long t = wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_INTERRUPTIBLE);
+       if (t == -ERESTARTSYS)
+               return t;
+       return 0;
 }
 EXPORT_SYMBOL(wait_for_completion_interruptible);
 
@@ -4131,7 +4174,7 @@ struct task_struct *idle_task(int cpu)
  */
 static struct task_struct *find_process_by_pid(pid_t pid)
 {
-       return pid ? find_task_by_pid(pid) : current;
+       return pid ? find_task_by_vpid(pid) : current;
 }
 
 /* Actually do priority change: must hold rq lock. */
@@ -4434,8 +4477,21 @@ long sched_setaffinity(pid_t pid, cpumask_t new_mask)
 
        cpus_allowed = cpuset_cpus_allowed(p);
        cpus_and(new_mask, new_mask, cpus_allowed);
+ again:
        retval = set_cpus_allowed(p, new_mask);
 
+       if (!retval) {
+               cpus_allowed = cpuset_cpus_allowed(p);
+               if (!cpus_subset(new_mask, cpus_allowed)) {
+                       /*
+                        * We must have raced with a concurrent cpuset
+                        * update. Just reset the cpus_allowed to the
+                        * cpuset's cpus_allowed
+                        */
+                       new_mask = cpus_allowed;
+                       goto again;
+               }
+       }
 out_unlock:
        put_task_struct(p);
        mutex_unlock(&sched_hotcpu_mutex);
@@ -4794,18 +4850,18 @@ static void show_task(struct task_struct *p)
        unsigned state;
 
        state = p->state ? __ffs(p->state) + 1 : 0;
-       printk("%-13.13s %c", p->comm,
+       printk(KERN_INFO "%-13.13s %c", p->comm,
                state < sizeof(stat_nam) - 1 ? stat_nam[state] : '?');
 #if BITS_PER_LONG == 32
        if (state == TASK_RUNNING)
-               printk(" running  ");
+               printk(KERN_CONT " running  ");
        else
-               printk(" %08lx ", thread_saved_pc(p));
+               printk(KERN_CONT " %08lx ", thread_saved_pc(p));
 #else
        if (state == TASK_RUNNING)
-               printk("  running task    ");
+               printk(KERN_CONT "  running task    ");
        else
-               printk(" %016lx ", thread_saved_pc(p));
+               printk(KERN_CONT " %016lx ", thread_saved_pc(p));
 #endif
 #ifdef CONFIG_DEBUG_STACK_USAGE
        {
@@ -4815,7 +4871,8 @@ static void show_task(struct task_struct *p)
                free = (unsigned long)n - (unsigned long)end_of_stack(p);
        }
 #endif
-       printk("%5lu %5d %6d\n", free, p->pid, p->parent->pid);
+       printk(KERN_CONT "%5lu %5d %6d\n", free,
+               task_pid_nr(p), task_pid_nr(p->parent));
 
        if (state != TASK_RUNNING)
                show_stack(p, NULL);
@@ -5087,7 +5144,7 @@ static int __migrate_task_irq(struct task_struct *p, int src_cpu, int dest_cpu)
 }
 
 /*
- * Figure out where task on dead CPU should go, use force if neccessary.
+ * Figure out where task on dead CPU should go, use force if necessary.
  * NOTE: interrupts should be disabled by the caller
  */
 static void move_task_off_dead_cpu(int dead_cpu, struct task_struct *p)
@@ -5109,8 +5166,16 @@ static void move_task_off_dead_cpu(int dead_cpu, struct task_struct *p)
 
                /* No more Mr. Nice Guy. */
                if (dest_cpu == NR_CPUS) {
+                       cpumask_t cpus_allowed = cpuset_cpus_allowed_locked(p);
+                       /*
+                        * Try to stay on the same cpuset, where the
+                        * current cpuset may be a subset of all cpus.
+                        * The cpuset_cpus_allowed_locked() variant of
+                        * cpuset_cpus_allowed() will not block.  It must be
+                        * called within calls to cpuset_lock/cpuset_unlock.
+                        */
                        rq = task_rq_lock(p, &flags);
-                       cpus_setall(p->cpus_allowed);
+                       p->cpus_allowed = cpus_allowed;
                        dest_cpu = any_online_cpu(p->cpus_allowed);
                        task_rq_unlock(rq, &flags);
 
@@ -5122,7 +5187,7 @@ static void move_task_off_dead_cpu(int dead_cpu, struct task_struct *p)
                        if (p->mm && printk_ratelimit())
                                printk(KERN_INFO "process %d (%s) no "
                                       "longer affine to cpu%d\n",
-                                      p->pid, p->comm, dead_cpu);
+                              task_pid_nr(p), p->comm, dead_cpu);
                }
        } while (!__migrate_task_irq(p, dead_cpu, dest_cpu));
 }
@@ -5229,7 +5294,7 @@ static void migrate_dead(unsigned int dead_cpu, struct task_struct *p)
        struct rq *rq = cpu_rq(dead_cpu);
 
        /* Must be exiting, otherwise would be on tasklist. */
-       BUG_ON(p->exit_state != EXIT_ZOMBIE && p->exit_state != EXIT_DEAD);
+       BUG_ON(!p->exit_state);
 
        /* Cannot have done final schedule yet: would have vanished. */
        BUG_ON(p->state == TASK_DEAD);
@@ -5364,7 +5429,7 @@ sd_alloc_ctl_domain_table(struct sched_domain *sd)
        return table;
 }
 
-static ctl_table *sd_alloc_ctl_cpu_table(int cpu)
+static ctl_table * sd_alloc_ctl_cpu_table(int cpu)
 {
        struct ctl_table *entry, *table;
        struct sched_domain *sd;
@@ -5458,7 +5523,7 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
 
        case CPU_ONLINE:
        case CPU_ONLINE_FROZEN:
-               /* Strictly unneccessary, as first user will wake it. */
+               /* Strictly unnecessary, as first user will wake it. */
                wake_up_process(cpu_rq(cpu)->migration_thread);
                break;
 
@@ -5476,6 +5541,7 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
 
        case CPU_DEAD:
        case CPU_DEAD_FROZEN:
+               cpuset_lock(); /* around calls to cpuset_cpus_allowed_lock() */
                migrate_live_tasks(cpu);
                rq = cpu_rq(cpu);
                kthread_stop(rq->migration_thread);
@@ -5489,6 +5555,7 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
                rq->idle->sched_class = &idle_sched_class;
                migrate_dead_tasks(cpu);
                spin_unlock_irq(&rq->lock);
+               cpuset_unlock();
                migrate_nr_uninterruptible(rq);
                BUG_ON(rq->nr_running != 0);
 
@@ -5598,20 +5665,20 @@ static void sched_domain_debug(struct sched_domain *sd, int cpu)
                        }
 
                        if (!group->__cpu_power) {
-                               printk("\n");
+                               printk(KERN_CONT "\n");
                                printk(KERN_ERR "ERROR: domain->cpu_power not "
                                                "set\n");
                                break;
                        }
 
                        if (!cpus_weight(group->cpumask)) {
-                               printk("\n");
+                               printk(KERN_CONT "\n");
                                printk(KERN_ERR "ERROR: empty group\n");
                                break;
                        }
 
                        if (cpus_intersects(groupmask, group->cpumask)) {
-                               printk("\n");
+                               printk(KERN_CONT "\n");
                                printk(KERN_ERR "ERROR: repeated CPUs\n");
                                break;
                        }
@@ -5619,11 +5686,11 @@ static void sched_domain_debug(struct sched_domain *sd, int cpu)
                        cpus_or(groupmask, groupmask, group->cpumask);
 
                        cpumask_scnprintf(str, NR_CPUS, group->cpumask);
-                       printk(" %s", str);
+                       printk(KERN_CONT " %s", str);
 
                        group = group->next;
                } while (group != sd->groups);
-               printk("\n");
+               printk(KERN_CONT "\n");
 
                if (!cpus_equal(sd->span, groupmask))
                        printk(KERN_ERR "ERROR: groups don't span "
@@ -6339,26 +6406,31 @@ error:
        return -ENOMEM;
 #endif
 }
+
+static cpumask_t *doms_cur;    /* current sched domains */
+static int ndoms_cur;          /* number of sched domains in 'doms_cur' */
+
+/*
+ * Special case: If a kmalloc of a doms_cur partition (array of
+ * cpumask_t) fails, then fallback to a single sched domain,
+ * as determined by the single cpumask_t fallback_doms.
+ */
+static cpumask_t fallback_doms;
+
 /*
  * Set up scheduler domains and groups.  Callers must hold the hotplug lock.
+ * For now this just excludes isolated cpus, but could be used to
+ * exclude other special cases in the future.
  */
 static int arch_init_sched_domains(const cpumask_t *cpu_map)
 {
-       cpumask_t cpu_default_map;
-       int err;
-
-       /*
-        * Setup mask for cpus without special case scheduling requirements.
-        * For now this just excludes isolated cpus, but could be used to
-        * exclude other special cases in the future.
-        */
-       cpus_andnot(cpu_default_map, *cpu_map, cpu_isolated_map);
-
-       err = build_sched_domains(&cpu_default_map);
-
+       ndoms_cur = 1;
+       doms_cur = kmalloc(sizeof(cpumask_t), GFP_KERNEL);
+       if (!doms_cur)
+               doms_cur = &fallback_doms;
+       cpus_andnot(*doms_cur, *cpu_map, cpu_isolated_map);
        register_sched_domain_sysctl();
-
-       return err;
+       return build_sched_domains(doms_cur);
 }
 
 static void arch_destroy_sched_domains(const cpumask_t *cpu_map)
@@ -6382,6 +6454,68 @@ static void detach_destroy_domains(const cpumask_t *cpu_map)
        arch_destroy_sched_domains(cpu_map);
 }
 
+/*
+ * Partition sched domains as specified by the 'ndoms_new'
+ * cpumasks in the array doms_new[] of cpumasks.  This compares
+ * doms_new[] to the current sched domain partitioning, doms_cur[].
+ * It destroys each deleted domain and builds each new domain.
+ *
+ * 'doms_new' is an array of cpumask_t's of length 'ndoms_new'.
+ * The masks don't intersect (don't overlap.)  We should setup one
+ * sched domain for each mask.  CPUs not in any of the cpumasks will
+ * not be load balanced.  If the same cpumask appears both in the
+ * current 'doms_cur' domains and in the new 'doms_new', we can leave
+ * it as it is.
+ *
+ * The passed in 'doms_new' should be kmalloc'd.  This routine takes
+ * ownership of it and will kfree it when done with it.  If the caller
+ * failed the kmalloc call, then it can pass in doms_new == NULL,
+ * and partition_sched_domains() will fallback to the single partition
+ * 'fallback_doms'.
+ *
+ * Call with hotplug lock held
+ */
+void partition_sched_domains(int ndoms_new, cpumask_t *doms_new)
+{
+       int i, j;
+
+       if (doms_new == NULL) {
+               ndoms_new = 1;
+               doms_new = &fallback_doms;
+               cpus_andnot(doms_new[0], cpu_online_map, cpu_isolated_map);
+       }
+
+       /* Destroy deleted domains */
+       for (i = 0; i < ndoms_cur; i++) {
+               for (j = 0; j < ndoms_new; j++) {
+                       if (cpus_equal(doms_cur[i], doms_new[j]))
+                               goto match1;
+               }
+               /* no match - a current sched domain not in new doms_new[] */
+               detach_destroy_domains(doms_cur + i);
+match1:
+               ;
+       }
+
+       /* Build new domains */
+       for (i = 0; i < ndoms_new; i++) {
+               for (j = 0; j < ndoms_cur; j++) {
+                       if (cpus_equal(doms_new[i], doms_cur[j]))
+                               goto match2;
+               }
+               /* no match - add a new doms_new */
+               build_sched_domains(doms_new + i);
+match2:
+               ;
+       }
+
+       /* Remember the new sched domains */
+       if (doms_cur != &fallback_doms)
+               kfree(doms_cur);
+       doms_cur = doms_new;
+       ndoms_cur = ndoms_new;
+}
+
 #if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
 static int arch_reinit_sched_domains(void)
 {
@@ -6963,3 +7097,116 @@ unsigned long sched_group_shares(struct task_group *tg)
 }
 
 #endif /* CONFIG_FAIR_GROUP_SCHED */
+
+#ifdef CONFIG_FAIR_CGROUP_SCHED
+
+/* return corresponding task_group object of a cgroup */
+static inline struct task_group *cgroup_tg(struct cgroup *cont)
+{
+       return container_of(cgroup_subsys_state(cont, cpu_cgroup_subsys_id),
+                                        struct task_group, css);
+}
+
+static struct cgroup_subsys_state *
+cpu_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont)
+{
+       struct task_group *tg;
+
+       if (!cont->parent) {
+               /* This is early initialization for the top cgroup */
+               init_task_group.css.cgroup = cont;
+               return &init_task_group.css;
+       }
+
+       /* we support only 1-level deep hierarchical scheduler atm */
+       if (cont->parent->parent)
+               return ERR_PTR(-EINVAL);
+
+       tg = sched_create_group();
+       if (IS_ERR(tg))
+               return ERR_PTR(-ENOMEM);
+
+       /* Bind the cgroup to task_group object we just created */
+       tg->css.cgroup = cont;
+
+       return &tg->css;
+}
+
+static void cpu_cgroup_destroy(struct cgroup_subsys *ss,
+                                       struct cgroup *cont)
+{
+       struct task_group *tg = cgroup_tg(cont);
+
+       sched_destroy_group(tg);
+}
+
+static int cpu_cgroup_can_attach(struct cgroup_subsys *ss,
+                            struct cgroup *cont, struct task_struct *tsk)
+{
+       /* We don't support RT-tasks being in separate groups */
+       if (tsk->sched_class != &fair_sched_class)
+               return -EINVAL;
+
+       return 0;
+}
+
+static void
+cpu_cgroup_attach(struct cgroup_subsys *ss, struct cgroup *cont,
+                       struct cgroup *old_cont, struct task_struct *tsk)
+{
+       sched_move_task(tsk);
+}
+
+static ssize_t cpu_shares_write(struct cgroup *cont, struct cftype *cftype,
+                               struct file *file, const char __user *userbuf,
+                               size_t nbytes, loff_t *ppos)
+{
+       unsigned long shareval;
+       struct task_group *tg = cgroup_tg(cont);
+       char buffer[2*sizeof(unsigned long) + 1];
+       int rc;
+
+       if (nbytes > 2*sizeof(unsigned long))   /* safety check */
+               return -E2BIG;
+
+       if (copy_from_user(buffer, userbuf, nbytes))
+               return -EFAULT;
+
+       buffer[nbytes] = 0;     /* nul-terminate */
+       shareval = simple_strtoul(buffer, NULL, 10);
+
+       rc = sched_group_set_shares(tg, shareval);
+
+       return (rc < 0 ? rc : nbytes);
+}
+
+static u64 cpu_shares_read_uint(struct cgroup *cont, struct cftype *cft)
+{
+       struct task_group *tg = cgroup_tg(cont);
+
+       return (u64) tg->shares;
+}
+
+static struct cftype cpu_shares = {
+       .name = "shares",
+       .read_uint = cpu_shares_read_uint,
+       .write = cpu_shares_write,
+};
+
+static int cpu_cgroup_populate(struct cgroup_subsys *ss, struct cgroup *cont)
+{
+       return cgroup_add_file(cont, ss, &cpu_shares);
+}
+
+struct cgroup_subsys cpu_cgroup_subsys = {
+       .name           = "cpu",
+       .create         = cpu_cgroup_create,
+       .destroy        = cpu_cgroup_destroy,
+       .can_attach     = cpu_cgroup_can_attach,
+       .attach         = cpu_cgroup_attach,
+       .populate       = cpu_cgroup_populate,
+       .subsys_id      = cpu_cgroup_subsys_id,
+       .early_init     = 1,
+};
+
+#endif /* CONFIG_FAIR_CGROUP_SCHED */
index a5e517ec07c3dfa5e7b688b40355a9e4a67f13bc..e6fb392e51644b24ec063681a99fed402c65a3e5 100644 (file)
@@ -137,7 +137,7 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)
        SEQ_printf(m, "  .%-30s: %ld\n", "nr_running", cfs_rq->nr_running);
        SEQ_printf(m, "  .%-30s: %ld\n", "load", cfs_rq->load.weight);
 #ifdef CONFIG_SCHEDSTATS
-       SEQ_printf(m, "  .%-30s: %ld\n", "bkl_count",
+       SEQ_printf(m, "  .%-30s: %d\n", "bkl_count",
                        rq->bkl_count);
 #endif
        SEQ_printf(m, "  .%-30s: %ld\n", "nr_spread_over",
index 1c084842c3e75517b7cbbdcb2f665b0dfe8f56dd..ef1a7df80ea21257ab141a3ef57142bad9ab47ae 100644 (file)
@@ -21,7 +21,7 @@ static int show_schedstat(struct seq_file *seq, void *v)
 
                /* runqueue-specific stats */
                seq_printf(seq,
-                   "cpu%d %lu %lu %lu %lu %lu %lu %lu %lu %lu %llu %llu %lu",
+                   "cpu%d %u %u %u %u %u %u %u %u %u %llu %llu %lu",
                    cpu, rq->yld_both_empty,
                    rq->yld_act_empty, rq->yld_exp_empty, rq->yld_count,
                    rq->sched_switch, rq->sched_count, rq->sched_goidle,
@@ -42,8 +42,7 @@ static int show_schedstat(struct seq_file *seq, void *v)
                        seq_printf(seq, "domain%d %s", dcount++, mask_str);
                        for (itype = CPU_IDLE; itype < CPU_MAX_IDLE_TYPES;
                                        itype++) {
-                               seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu "
-                                               "%lu",
+                               seq_printf(seq, " %u %u %u %u %u %u %u %u",
                                    sd->lb_count[itype],
                                    sd->lb_balanced[itype],
                                    sd->lb_failed[itype],
@@ -53,8 +52,7 @@ static int show_schedstat(struct seq_file *seq, void *v)
                                    sd->lb_nobusyq[itype],
                                    sd->lb_nobusyg[itype]);
                        }
-                       seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu %lu %lu"
-                           " %lu %lu %lu\n",
+                       seq_printf(seq, " %u %u %u %u %u %u %u %u %u %u %u %u\n",
                            sd->alb_count, sd->alb_failed, sd->alb_pushed,
                            sd->sbe_count, sd->sbe_balanced, sd->sbe_pushed,
                            sd->sbf_count, sd->sbf_balanced, sd->sbf_pushed,
index 2124ffadcfdefff5a6cf0fbc2da37c3ac19d8a44..12006308c7eba5f920ba417bcff27a42312399af 100644 (file)
@@ -99,7 +99,6 @@ static inline int has_pending_signals(sigset_t *signal, sigset_t *blocked)
 static int recalc_sigpending_tsk(struct task_struct *t)
 {
        if (t->signal->group_stop_count > 0 ||
-           (freezing(t)) ||
            PENDING(&t->pending, &t->blocked) ||
            PENDING(&t->signal->shared_pending, &t->blocked)) {
                set_tsk_thread_flag(t, TIF_SIGPENDING);
@@ -257,7 +256,7 @@ flush_signal_handlers(struct task_struct *t, int force_default)
 
 int unhandled_signal(struct task_struct *tsk, int sig)
 {
-       if (is_init(tsk))
+       if (is_global_init(tsk))
                return 1;
        if (tsk->ptrace & PT_PTRACED)
                return 0;
@@ -537,7 +536,7 @@ static int check_kill_permission(int sig, struct siginfo *info,
                        return error;
                error = -EPERM;
                if (((sig != SIGCONT) ||
-                       (process_session(current) != process_session(t)))
+                       (task_session_nr(current) != task_session_nr(t)))
                    && (current->euid ^ t->suid) && (current->euid ^ t->uid)
                    && (current->uid ^ t->suid) && (current->uid ^ t->uid)
                    && !capable(CAP_KILL))
@@ -695,7 +694,7 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
                        q->info.si_signo = sig;
                        q->info.si_errno = 0;
                        q->info.si_code = SI_USER;
-                       q->info.si_pid = current->pid;
+                       q->info.si_pid = task_pid_vnr(current);
                        q->info.si_uid = current->uid;
                        break;
                case (unsigned long) SEND_SIG_PRIV:
@@ -731,7 +730,7 @@ int print_fatal_signals;
 static void print_fatal_signal(struct pt_regs *regs, int signr)
 {
        printk("%s/%d: potentially unexpected fatal signal %d.\n",
-               current->comm, current->pid, signr);
+               current->comm, task_pid_nr(current), signr);
 
 #ifdef __i386__
        printk("code at %08lx: ", regs->eip);
@@ -1090,7 +1089,7 @@ kill_proc_info(int sig, struct siginfo *info, pid_t pid)
 {
        int error;
        rcu_read_lock();
-       error = kill_pid_info(sig, info, find_pid(pid));
+       error = kill_pid_info(sig, info, find_vpid(pid));
        rcu_read_unlock();
        return error;
 }
@@ -1151,7 +1150,7 @@ static int kill_something_info(int sig, struct siginfo *info, int pid)
 
                read_lock(&tasklist_lock);
                for_each_process(p) {
-                       if (p->pid > 1 && p->tgid != current->tgid) {
+                       if (p->pid > 1 && !same_thread_group(p, current)) {
                                int err = group_send_sig_info(sig, info, p);
                                ++count;
                                if (err != -EPERM)
@@ -1161,9 +1160,9 @@ static int kill_something_info(int sig, struct siginfo *info, int pid)
                read_unlock(&tasklist_lock);
                ret = count ? retval : -ESRCH;
        } else if (pid < 0) {
-               ret = kill_pgrp_info(sig, info, find_pid(-pid));
+               ret = kill_pgrp_info(sig, info, find_vpid(-pid));
        } else {
-               ret = kill_pid_info(sig, info, find_pid(pid));
+               ret = kill_pid_info(sig, info, find_vpid(pid));
        }
        rcu_read_unlock();
        return ret;
@@ -1267,7 +1266,12 @@ EXPORT_SYMBOL(kill_pid);
 int
 kill_proc(pid_t pid, int sig, int priv)
 {
-       return kill_proc_info(sig, __si_special(priv), pid);
+       int ret;
+
+       rcu_read_lock();
+       ret = kill_pid_info(sig, __si_special(priv), find_pid(pid));
+       rcu_read_unlock();
+       return ret;
 }
 
 /*
@@ -1444,7 +1448,22 @@ void do_notify_parent(struct task_struct *tsk, int sig)
 
        info.si_signo = sig;
        info.si_errno = 0;
-       info.si_pid = tsk->pid;
+       /*
+        * we are under tasklist_lock here so our parent is tied to
+        * us and cannot exit and release its namespace.
+        *
+        * the only it can is to switch its nsproxy with sys_unshare,
+        * bu uncharing pid namespaces is not allowed, so we'll always
+        * see relevant namespace
+        *
+        * write_lock() currently calls preempt_disable() which is the
+        * same as rcu_read_lock(), but according to Oleg, this is not
+        * correct to rely on this
+        */
+       rcu_read_lock();
+       info.si_pid = task_pid_nr_ns(tsk, tsk->parent->nsproxy->pid_ns);
+       rcu_read_unlock();
+
        info.si_uid = tsk->uid;
 
        /* FIXME: find out whether or not this is supposed to be c*time. */
@@ -1509,7 +1528,13 @@ static void do_notify_parent_cldstop(struct task_struct *tsk, int why)
 
        info.si_signo = SIGCHLD;
        info.si_errno = 0;
-       info.si_pid = tsk->pid;
+       /*
+        * see comment in do_notify_parent() abot the following 3 lines
+        */
+       rcu_read_lock();
+       info.si_pid = task_pid_nr_ns(tsk, tsk->parent->nsproxy->pid_ns);
+       rcu_read_unlock();
+
        info.si_uid = tsk->uid;
 
        /* FIXME: find out whether or not this is supposed to be c*time. */
@@ -1635,7 +1660,7 @@ void ptrace_notify(int exit_code)
        memset(&info, 0, sizeof info);
        info.si_signo = SIGTRAP;
        info.si_code = exit_code;
-       info.si_pid = current->pid;
+       info.si_pid = task_pid_vnr(current);
        info.si_uid = current->uid;
 
        /* Let the debugger run.  */
@@ -1805,7 +1830,7 @@ relock:
                                info->si_signo = signr;
                                info->si_errno = 0;
                                info->si_code = SI_USER;
-                               info->si_pid = current->parent->pid;
+                               info->si_pid = task_pid_vnr(current->parent);
                                info->si_uid = current->parent->uid;
                        }
 
@@ -1836,11 +1861,9 @@ relock:
                        continue;
 
                /*
-                * Init of a pid space gets no signals it doesn't want from
-                * within that pid space. It can of course get signals from
-                * its parent pid space.
+                * Global init gets no signals it doesn't want.
                 */
-               if (current == child_reaper(current))
+               if (is_global_init(current))
                        continue;
 
                if (sig_kernel_stop(signr)) {
@@ -2194,7 +2217,7 @@ sys_kill(int pid, int sig)
        info.si_signo = sig;
        info.si_errno = 0;
        info.si_code = SI_USER;
-       info.si_pid = current->tgid;
+       info.si_pid = task_tgid_vnr(current);
        info.si_uid = current->uid;
 
        return kill_something_info(sig, &info, pid);
@@ -2210,12 +2233,12 @@ static int do_tkill(int tgid, int pid, int sig)
        info.si_signo = sig;
        info.si_errno = 0;
        info.si_code = SI_TKILL;
-       info.si_pid = current->tgid;
+       info.si_pid = task_tgid_vnr(current);
        info.si_uid = current->uid;
 
        read_lock(&tasklist_lock);
-       p = find_task_by_pid(pid);
-       if (p && (tgid <= 0 || p->tgid == tgid)) {
+       p = find_task_by_vpid(pid);
+       if (p && (tgid <= 0 || task_tgid_vnr(p) == tgid)) {
                error = check_kill_permission(sig, &info, p);
                /*
                 * The null signal is a permissions and process existence
index edeeef3a6a322917b5b2befb95238df5557a9af5..11df812263c8fd3eed16f4f1a57d36a68f6eaedc 100644 (file)
@@ -113,7 +113,7 @@ void softlockup_tick(void)
        spin_lock(&print_lock);
        printk(KERN_ERR "BUG: soft lockup - CPU#%d stuck for %lus! [%s:%d]\n",
                        this_cpu, now - touch_timestamp,
-                               current->comm, current->pid);
+                       current->comm, task_pid_nr(current));
        if (regs)
                show_regs(regs);
        else
index 8ae2e636eb1ba690f9fd9cf0f363d5f677db80ac..304b5410d746ec724afcb4e3ce50bfe65f1bf2ff 100644 (file)
@@ -105,538 +105,6 @@ EXPORT_SYMBOL(cad_pid);
  */
 
 void (*pm_power_off_prepare)(void);
-EXPORT_SYMBOL(pm_power_off_prepare);
-
-/*
- *     Notifier list for kernel code which wants to be called
- *     at shutdown. This is used to stop any idling DMA operations
- *     and the like. 
- */
-
-static BLOCKING_NOTIFIER_HEAD(reboot_notifier_list);
-
-/*
- *     Notifier chain core routines.  The exported routines below
- *     are layered on top of these, with appropriate locking added.
- */
-
-static int notifier_chain_register(struct notifier_block **nl,
-               struct notifier_block *n)
-{
-       while ((*nl) != NULL) {
-               if (n->priority > (*nl)->priority)
-                       break;
-               nl = &((*nl)->next);
-       }
-       n->next = *nl;
-       rcu_assign_pointer(*nl, n);
-       return 0;
-}
-
-static int notifier_chain_unregister(struct notifier_block **nl,
-               struct notifier_block *n)
-{
-       while ((*nl) != NULL) {
-               if ((*nl) == n) {
-                       rcu_assign_pointer(*nl, n->next);
-                       return 0;
-               }
-               nl = &((*nl)->next);
-       }
-       return -ENOENT;
-}
-
-/**
- * notifier_call_chain - Informs the registered notifiers about an event.
- *     @nl:            Pointer to head of the blocking notifier chain
- *     @val:           Value passed unmodified to notifier function
- *     @v:             Pointer passed unmodified to notifier function
- *     @nr_to_call:    Number of notifier functions to be called. Don't care
- *                     value of this parameter is -1.
- *     @nr_calls:      Records the number of notifications sent. Don't care
- *                     value of this field is NULL.
- *     @returns:       notifier_call_chain returns the value returned by the
- *                     last notifier function called.
- */
-
-static int __kprobes notifier_call_chain(struct notifier_block **nl,
-                                       unsigned long val, void *v,
-                                       int nr_to_call, int *nr_calls)
-{
-       int ret = NOTIFY_DONE;
-       struct notifier_block *nb, *next_nb;
-
-       nb = rcu_dereference(*nl);
-
-       while (nb && nr_to_call) {
-               next_nb = rcu_dereference(nb->next);
-               ret = nb->notifier_call(nb, val, v);
-
-               if (nr_calls)
-                       (*nr_calls)++;
-
-               if ((ret & NOTIFY_STOP_MASK) == NOTIFY_STOP_MASK)
-                       break;
-               nb = next_nb;
-               nr_to_call--;
-       }
-       return ret;
-}
-
-/*
- *     Atomic notifier chain routines.  Registration and unregistration
- *     use a spinlock, and call_chain is synchronized by RCU (no locks).
- */
-
-/**
- *     atomic_notifier_chain_register - Add notifier to an atomic notifier chain
- *     @nh: Pointer to head of the atomic notifier chain
- *     @n: New entry in notifier chain
- *
- *     Adds a notifier to an atomic notifier chain.
- *
- *     Currently always returns zero.
- */
-
-int atomic_notifier_chain_register(struct atomic_notifier_head *nh,
-               struct notifier_block *n)
-{
-       unsigned long flags;
-       int ret;
-
-       spin_lock_irqsave(&nh->lock, flags);
-       ret = notifier_chain_register(&nh->head, n);
-       spin_unlock_irqrestore(&nh->lock, flags);
-       return ret;
-}
-
-EXPORT_SYMBOL_GPL(atomic_notifier_chain_register);
-
-/**
- *     atomic_notifier_chain_unregister - Remove notifier from an atomic notifier chain
- *     @nh: Pointer to head of the atomic notifier chain
- *     @n: Entry to remove from notifier chain
- *
- *     Removes a notifier from an atomic notifier chain.
- *
- *     Returns zero on success or %-ENOENT on failure.
- */
-int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh,
-               struct notifier_block *n)
-{
-       unsigned long flags;
-       int ret;
-
-       spin_lock_irqsave(&nh->lock, flags);
-       ret = notifier_chain_unregister(&nh->head, n);
-       spin_unlock_irqrestore(&nh->lock, flags);
-       synchronize_rcu();
-       return ret;
-}
-
-EXPORT_SYMBOL_GPL(atomic_notifier_chain_unregister);
-
-/**
- *     __atomic_notifier_call_chain - Call functions in an atomic notifier chain
- *     @nh: Pointer to head of the atomic notifier chain
- *     @val: Value passed unmodified to notifier function
- *     @v: Pointer passed unmodified to notifier function
- *     @nr_to_call: See the comment for notifier_call_chain.
- *     @nr_calls: See the comment for notifier_call_chain.
- *
- *     Calls each function in a notifier chain in turn.  The functions
- *     run in an atomic context, so they must not block.
- *     This routine uses RCU to synchronize with changes to the chain.
- *
- *     If the return value of the notifier can be and'ed
- *     with %NOTIFY_STOP_MASK then atomic_notifier_call_chain()
- *     will return immediately, with the return value of
- *     the notifier function which halted execution.
- *     Otherwise the return value is the return value
- *     of the last notifier function called.
- */
-int __kprobes __atomic_notifier_call_chain(struct atomic_notifier_head *nh,
-                                       unsigned long val, void *v,
-                                       int nr_to_call, int *nr_calls)
-{
-       int ret;
-
-       rcu_read_lock();
-       ret = notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls);
-       rcu_read_unlock();
-       return ret;
-}
-
-EXPORT_SYMBOL_GPL(__atomic_notifier_call_chain);
-
-int __kprobes atomic_notifier_call_chain(struct atomic_notifier_head *nh,
-               unsigned long val, void *v)
-{
-       return __atomic_notifier_call_chain(nh, val, v, -1, NULL);
-}
-
-EXPORT_SYMBOL_GPL(atomic_notifier_call_chain);
-/*
- *     Blocking notifier chain routines.  All access to the chain is
- *     synchronized by an rwsem.
- */
-
-/**
- *     blocking_notifier_chain_register - Add notifier to a blocking notifier chain
- *     @nh: Pointer to head of the blocking notifier chain
- *     @n: New entry in notifier chain
- *
- *     Adds a notifier to a blocking notifier chain.
- *     Must be called in process context.
- *
- *     Currently always returns zero.
- */
-int blocking_notifier_chain_register(struct blocking_notifier_head *nh,
-               struct notifier_block *n)
-{
-       int ret;
-
-       /*
-        * This code gets used during boot-up, when task switching is
-        * not yet working and interrupts must remain disabled.  At
-        * such times we must not call down_write().
-        */
-       if (unlikely(system_state == SYSTEM_BOOTING))
-               return notifier_chain_register(&nh->head, n);
-
-       down_write(&nh->rwsem);
-       ret = notifier_chain_register(&nh->head, n);
-       up_write(&nh->rwsem);
-       return ret;
-}
-
-EXPORT_SYMBOL_GPL(blocking_notifier_chain_register);
-
-/**
- *     blocking_notifier_chain_unregister - Remove notifier from a blocking notifier chain
- *     @nh: Pointer to head of the blocking notifier chain
- *     @n: Entry to remove from notifier chain
- *
- *     Removes a notifier from a blocking notifier chain.
- *     Must be called from process context.
- *
- *     Returns zero on success or %-ENOENT on failure.
- */
-int blocking_notifier_chain_unregister(struct blocking_notifier_head *nh,
-               struct notifier_block *n)
-{
-       int ret;
-
-       /*
-        * This code gets used during boot-up, when task switching is
-        * not yet working and interrupts must remain disabled.  At
-        * such times we must not call down_write().
-        */
-       if (unlikely(system_state == SYSTEM_BOOTING))
-               return notifier_chain_unregister(&nh->head, n);
-
-       down_write(&nh->rwsem);
-       ret = notifier_chain_unregister(&nh->head, n);
-       up_write(&nh->rwsem);
-       return ret;
-}
-
-EXPORT_SYMBOL_GPL(blocking_notifier_chain_unregister);
-
-/**
- *     __blocking_notifier_call_chain - Call functions in a blocking notifier chain
- *     @nh: Pointer to head of the blocking notifier chain
- *     @val: Value passed unmodified to notifier function
- *     @v: Pointer passed unmodified to notifier function
- *     @nr_to_call: See comment for notifier_call_chain.
- *     @nr_calls: See comment for notifier_call_chain.
- *
- *     Calls each function in a notifier chain in turn.  The functions
- *     run in a process context, so they are allowed to block.
- *
- *     If the return value of the notifier can be and'ed
- *     with %NOTIFY_STOP_MASK then blocking_notifier_call_chain()
- *     will return immediately, with the return value of
- *     the notifier function which halted execution.
- *     Otherwise the return value is the return value
- *     of the last notifier function called.
- */
-int __blocking_notifier_call_chain(struct blocking_notifier_head *nh,
-                                  unsigned long val, void *v,
-                                  int nr_to_call, int *nr_calls)
-{
-       int ret = NOTIFY_DONE;
-
-       /*
-        * We check the head outside the lock, but if this access is
-        * racy then it does not matter what the result of the test
-        * is, we re-check the list after having taken the lock anyway:
-        */
-       if (rcu_dereference(nh->head)) {
-               down_read(&nh->rwsem);
-               ret = notifier_call_chain(&nh->head, val, v, nr_to_call,
-                                       nr_calls);
-               up_read(&nh->rwsem);
-       }
-       return ret;
-}
-EXPORT_SYMBOL_GPL(__blocking_notifier_call_chain);
-
-int blocking_notifier_call_chain(struct blocking_notifier_head *nh,
-               unsigned long val, void *v)
-{
-       return __blocking_notifier_call_chain(nh, val, v, -1, NULL);
-}
-EXPORT_SYMBOL_GPL(blocking_notifier_call_chain);
-
-/*
- *     Raw notifier chain routines.  There is no protection;
- *     the caller must provide it.  Use at your own risk!
- */
-
-/**
- *     raw_notifier_chain_register - Add notifier to a raw notifier chain
- *     @nh: Pointer to head of the raw notifier chain
- *     @n: New entry in notifier chain
- *
- *     Adds a notifier to a raw notifier chain.
- *     All locking must be provided by the caller.
- *
- *     Currently always returns zero.
- */
-
-int raw_notifier_chain_register(struct raw_notifier_head *nh,
-               struct notifier_block *n)
-{
-       return notifier_chain_register(&nh->head, n);
-}
-
-EXPORT_SYMBOL_GPL(raw_notifier_chain_register);
-
-/**
- *     raw_notifier_chain_unregister - Remove notifier from a raw notifier chain
- *     @nh: Pointer to head of the raw notifier chain
- *     @n: Entry to remove from notifier chain
- *
- *     Removes a notifier from a raw notifier chain.
- *     All locking must be provided by the caller.
- *
- *     Returns zero on success or %-ENOENT on failure.
- */
-int raw_notifier_chain_unregister(struct raw_notifier_head *nh,
-               struct notifier_block *n)
-{
-       return notifier_chain_unregister(&nh->head, n);
-}
-
-EXPORT_SYMBOL_GPL(raw_notifier_chain_unregister);
-
-/**
- *     __raw_notifier_call_chain - Call functions in a raw notifier chain
- *     @nh: Pointer to head of the raw notifier chain
- *     @val: Value passed unmodified to notifier function
- *     @v: Pointer passed unmodified to notifier function
- *     @nr_to_call: See comment for notifier_call_chain.
- *     @nr_calls: See comment for notifier_call_chain
- *
- *     Calls each function in a notifier chain in turn.  The functions
- *     run in an undefined context.
- *     All locking must be provided by the caller.
- *
- *     If the return value of the notifier can be and'ed
- *     with %NOTIFY_STOP_MASK then raw_notifier_call_chain()
- *     will return immediately, with the return value of
- *     the notifier function which halted execution.
- *     Otherwise the return value is the return value
- *     of the last notifier function called.
- */
-
-int __raw_notifier_call_chain(struct raw_notifier_head *nh,
-                             unsigned long val, void *v,
-                             int nr_to_call, int *nr_calls)
-{
-       return notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls);
-}
-
-EXPORT_SYMBOL_GPL(__raw_notifier_call_chain);
-
-int raw_notifier_call_chain(struct raw_notifier_head *nh,
-               unsigned long val, void *v)
-{
-       return __raw_notifier_call_chain(nh, val, v, -1, NULL);
-}
-
-EXPORT_SYMBOL_GPL(raw_notifier_call_chain);
-
-/*
- *     SRCU notifier chain routines.    Registration and unregistration
- *     use a mutex, and call_chain is synchronized by SRCU (no locks).
- */
-
-/**
- *     srcu_notifier_chain_register - Add notifier to an SRCU notifier chain
- *     @nh: Pointer to head of the SRCU notifier chain
- *     @n: New entry in notifier chain
- *
- *     Adds a notifier to an SRCU notifier chain.
- *     Must be called in process context.
- *
- *     Currently always returns zero.
- */
-
-int srcu_notifier_chain_register(struct srcu_notifier_head *nh,
-               struct notifier_block *n)
-{
-       int ret;
-
-       /*
-        * This code gets used during boot-up, when task switching is
-        * not yet working and interrupts must remain disabled.  At
-        * such times we must not call mutex_lock().
-        */
-       if (unlikely(system_state == SYSTEM_BOOTING))
-               return notifier_chain_register(&nh->head, n);
-
-       mutex_lock(&nh->mutex);
-       ret = notifier_chain_register(&nh->head, n);
-       mutex_unlock(&nh->mutex);
-       return ret;
-}
-
-EXPORT_SYMBOL_GPL(srcu_notifier_chain_register);
-
-/**
- *     srcu_notifier_chain_unregister - Remove notifier from an SRCU notifier chain
- *     @nh: Pointer to head of the SRCU notifier chain
- *     @n: Entry to remove from notifier chain
- *
- *     Removes a notifier from an SRCU notifier chain.
- *     Must be called from process context.
- *
- *     Returns zero on success or %-ENOENT on failure.
- */
-int srcu_notifier_chain_unregister(struct srcu_notifier_head *nh,
-               struct notifier_block *n)
-{
-       int ret;
-
-       /*
-        * This code gets used during boot-up, when task switching is
-        * not yet working and interrupts must remain disabled.  At
-        * such times we must not call mutex_lock().
-        */
-       if (unlikely(system_state == SYSTEM_BOOTING))
-               return notifier_chain_unregister(&nh->head, n);
-
-       mutex_lock(&nh->mutex);
-       ret = notifier_chain_unregister(&nh->head, n);
-       mutex_unlock(&nh->mutex);
-       synchronize_srcu(&nh->srcu);
-       return ret;
-}
-
-EXPORT_SYMBOL_GPL(srcu_notifier_chain_unregister);
-
-/**
- *     __srcu_notifier_call_chain - Call functions in an SRCU notifier chain
- *     @nh: Pointer to head of the SRCU notifier chain
- *     @val: Value passed unmodified to notifier function
- *     @v: Pointer passed unmodified to notifier function
- *     @nr_to_call: See comment for notifier_call_chain.
- *     @nr_calls: See comment for notifier_call_chain
- *
- *     Calls each function in a notifier chain in turn.  The functions
- *     run in a process context, so they are allowed to block.
- *
- *     If the return value of the notifier can be and'ed
- *     with %NOTIFY_STOP_MASK then srcu_notifier_call_chain()
- *     will return immediately, with the return value of
- *     the notifier function which halted execution.
- *     Otherwise the return value is the return value
- *     of the last notifier function called.
- */
-
-int __srcu_notifier_call_chain(struct srcu_notifier_head *nh,
-                              unsigned long val, void *v,
-                              int nr_to_call, int *nr_calls)
-{
-       int ret;
-       int idx;
-
-       idx = srcu_read_lock(&nh->srcu);
-       ret = notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls);
-       srcu_read_unlock(&nh->srcu, idx);
-       return ret;
-}
-EXPORT_SYMBOL_GPL(__srcu_notifier_call_chain);
-
-int srcu_notifier_call_chain(struct srcu_notifier_head *nh,
-               unsigned long val, void *v)
-{
-       return __srcu_notifier_call_chain(nh, val, v, -1, NULL);
-}
-EXPORT_SYMBOL_GPL(srcu_notifier_call_chain);
-
-/**
- *     srcu_init_notifier_head - Initialize an SRCU notifier head
- *     @nh: Pointer to head of the srcu notifier chain
- *
- *     Unlike other sorts of notifier heads, SRCU notifier heads require
- *     dynamic initialization.  Be sure to call this routine before
- *     calling any of the other SRCU notifier routines for this head.
- *
- *     If an SRCU notifier head is deallocated, it must first be cleaned
- *     up by calling srcu_cleanup_notifier_head().  Otherwise the head's
- *     per-cpu data (used by the SRCU mechanism) will leak.
- */
-
-void srcu_init_notifier_head(struct srcu_notifier_head *nh)
-{
-       mutex_init(&nh->mutex);
-       if (init_srcu_struct(&nh->srcu) < 0)
-               BUG();
-       nh->head = NULL;
-}
-
-EXPORT_SYMBOL_GPL(srcu_init_notifier_head);
-
-/**
- *     register_reboot_notifier - Register function to be called at reboot time
- *     @nb: Info about notifier function to be called
- *
- *     Registers a function with the list of functions
- *     to be called at reboot time.
- *
- *     Currently always returns zero, as blocking_notifier_chain_register()
- *     always returns zero.
- */
-int register_reboot_notifier(struct notifier_block * nb)
-{
-       return blocking_notifier_chain_register(&reboot_notifier_list, nb);
-}
-
-EXPORT_SYMBOL(register_reboot_notifier);
-
-/**
- *     unregister_reboot_notifier - Unregister previously registered reboot notifier
- *     @nb: Hook to be unregistered
- *
- *     Unregisters a previously registered reboot
- *     notifier function.
- *
- *     Returns zero on success, or %-ENOENT on failure.
- */
-int unregister_reboot_notifier(struct notifier_block * nb)
-{
-       return blocking_notifier_chain_unregister(&reboot_notifier_list, nb);
-}
-
-EXPORT_SYMBOL(unregister_reboot_notifier);
 
 static int set_one_prio(struct task_struct *p, int niceval, int error)
 {
@@ -684,7 +152,7 @@ asmlinkage long sys_setpriority(int which, int who, int niceval)
        switch (which) {
                case PRIO_PROCESS:
                        if (who)
-                               p = find_task_by_pid(who);
+                               p = find_task_by_vpid(who);
                        else
                                p = current;
                        if (p)
@@ -692,7 +160,7 @@ asmlinkage long sys_setpriority(int which, int who, int niceval)
                        break;
                case PRIO_PGRP:
                        if (who)
-                               pgrp = find_pid(who);
+                               pgrp = find_vpid(who);
                        else
                                pgrp = task_pgrp(current);
                        do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
@@ -741,7 +209,7 @@ asmlinkage long sys_getpriority(int which, int who)
        switch (which) {
                case PRIO_PROCESS:
                        if (who)
-                               p = find_task_by_pid(who);
+                               p = find_task_by_vpid(who);
                        else
                                p = current;
                        if (p) {
@@ -752,7 +220,7 @@ asmlinkage long sys_getpriority(int which, int who)
                        break;
                case PRIO_PGRP:
                        if (who)
-                               pgrp = find_pid(who);
+                               pgrp = find_vpid(who);
                        else
                                pgrp = task_pgrp(current);
                        do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
@@ -1449,9 +917,10 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
        struct task_struct *p;
        struct task_struct *group_leader = current->group_leader;
        int err = -EINVAL;
+       struct pid_namespace *ns;
 
        if (!pid)
-               pid = group_leader->pid;
+               pid = task_pid_vnr(group_leader);
        if (!pgid)
                pgid = pid;
        if (pgid < 0)
@@ -1460,10 +929,12 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
        /* From this point forward we keep holding onto the tasklist lock
         * so that our parent does not change from under us. -DaveM
         */
+       ns = current->nsproxy->pid_ns;
+
        write_lock_irq(&tasklist_lock);
 
        err = -ESRCH;
-       p = find_task_by_pid(pid);
+       p = find_task_by_pid_ns(pid, ns);
        if (!p)
                goto out;
 
@@ -1489,9 +960,9 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
                goto out;
 
        if (pgid != pid) {
-               struct task_struct *g =
-                       find_task_by_pid_type(PIDTYPE_PGID, pgid);
+               struct task_struct *g;
 
+               g = find_task_by_pid_type_ns(PIDTYPE_PGID, pgid, ns);
                if (!g || task_session(g) != task_session(group_leader))
                        goto out;
        }
@@ -1500,10 +971,13 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
        if (err)
                goto out;
 
-       if (process_group(p) != pgid) {
+       if (task_pgrp_nr_ns(p, ns) != pgid) {
+               struct pid *pid;
+
                detach_pid(p, PIDTYPE_PGID);
-               p->signal->pgrp = pgid;
-               attach_pid(p, PIDTYPE_PGID, find_pid(pgid));
+               pid = find_vpid(pgid);
+               attach_pid(p, PIDTYPE_PGID, pid);
+               set_task_pgrp(p, pid_nr(pid));
        }
 
        err = 0;
@@ -1516,19 +990,21 @@ out:
 asmlinkage long sys_getpgid(pid_t pid)
 {
        if (!pid)
-               return process_group(current);
+               return task_pgrp_vnr(current);
        else {
                int retval;
                struct task_struct *p;
+               struct pid_namespace *ns;
 
-               read_lock(&tasklist_lock);
-               p = find_task_by_pid(pid);
+               ns = current->nsproxy->pid_ns;
 
+               read_lock(&tasklist_lock);
+               p = find_task_by_pid_ns(pid, ns);
                retval = -ESRCH;
                if (p) {
                        retval = security_task_getpgid(p);
                        if (!retval)
-                               retval = process_group(p);
+                               retval = task_pgrp_nr_ns(p, ns);
                }
                read_unlock(&tasklist_lock);
                return retval;
@@ -1540,7 +1016,7 @@ asmlinkage long sys_getpgid(pid_t pid)
 asmlinkage long sys_getpgrp(void)
 {
        /* SMP - assuming writes are word atomic this is fine */
-       return process_group(current);
+       return task_pgrp_vnr(current);
 }
 
 #endif
@@ -1548,19 +1024,21 @@ asmlinkage long sys_getpgrp(void)
 asmlinkage long sys_getsid(pid_t pid)
 {
        if (!pid)
-               return process_session(current);
+               return task_session_vnr(current);
        else {
                int retval;
                struct task_struct *p;
+               struct pid_namespace *ns;
 
-               read_lock(&tasklist_lock);
-               p = find_task_by_pid(pid);
+               ns = current->nsproxy->pid_ns;
 
+               read_lock(&tasklist_lock);
+               p = find_task_by_pid_ns(pid, ns);
                retval = -ESRCH;
                if (p) {
                        retval = security_task_getsid(p);
                        if (!retval)
-                               retval = process_session(p);
+                               retval = task_session_nr_ns(p, ns);
                }
                read_unlock(&tasklist_lock);
                return retval;
@@ -1587,7 +1065,8 @@ asmlinkage long sys_setsid(void)
         * session id and so the check will always fail and make it so
         * init cannot successfully call setsid.
         */
-       if (session > 1 && find_task_by_pid_type(PIDTYPE_PGID, session))
+       if (session > 1 && find_task_by_pid_type_ns(PIDTYPE_PGID,
+                               session, &init_pid_ns))
                goto out;
 
        group_leader->signal->leader = 1;
@@ -1597,7 +1076,7 @@ asmlinkage long sys_setsid(void)
        group_leader->signal->tty = NULL;
        spin_unlock(&group_leader->sighand->siglock);
 
-       err = process_group(group_leader);
+       err = task_pgrp_vnr(group_leader);
 out:
        write_unlock_irq(&tasklist_lock);
        return err;
index dde3d53e8adc0fd8aabbf871d0b5c6751dfb9907..3b4efbe2644572a32576b1a591f003e9869699f0 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/slab.h>
 #include <linux/sysctl.h>
 #include <linux/proc_fs.h>
-#include <linux/capability.h>
+#include <linux/security.h>
 #include <linux/ctype.h>
 #include <linux/utsname.h>
 #include <linux/smp_lock.h>
@@ -55,6 +55,8 @@
 #include <asm/stacktrace.h>
 #endif
 
+static int deprecated_sysctl_warning(struct __sysctl_args *args);
+
 #if defined(CONFIG_SYSCTL)
 
 /* External variables not in a header file. */
@@ -142,32 +144,29 @@ extern int max_lock_depth;
 
 #ifdef CONFIG_SYSCTL_SYSCALL
 static int parse_table(int __user *, int, void __user *, size_t __user *,
-               void __user *, size_t, ctl_table *);
+               void __user *, size_t, struct ctl_table *);
 #endif
 
 
 #ifdef CONFIG_PROC_SYSCTL
-static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
+static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp,
                  void __user *buffer, size_t *lenp, loff_t *ppos);
-static int proc_dointvec_taint(ctl_table *table, int write, struct file *filp,
+static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp,
                               void __user *buffer, size_t *lenp, loff_t *ppos);
 #endif
 
-static ctl_table root_table[];
+static struct ctl_table root_table[];
 static struct ctl_table_header root_table_header =
        { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) };
 
-static ctl_table kern_table[];
-static ctl_table vm_table[];
-static ctl_table fs_table[];
-static ctl_table debug_table[];
-static ctl_table dev_table[];
-extern ctl_table random_table[];
-#ifdef CONFIG_UNIX98_PTYS
-extern ctl_table pty_table[];
-#endif
+static struct ctl_table kern_table[];
+static struct ctl_table vm_table[];
+static struct ctl_table fs_table[];
+static struct ctl_table debug_table[];
+static struct ctl_table dev_table[];
+extern struct ctl_table random_table[];
 #ifdef CONFIG_INOTIFY_USER
-extern ctl_table inotify_table[];
+extern struct ctl_table inotify_table[];
 #endif
 
 #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
@@ -179,7 +178,7 @@ extern int lock_stat;
 
 /* The default sysctl tables: */
 
-static ctl_table root_table[] = {
+static struct ctl_table root_table[] = {
        {
                .ctl_name       = CTL_KERN,
                .procname       = "kernel",
@@ -232,7 +231,7 @@ static unsigned long min_wakeup_granularity_ns;                     /* 0 usecs */
 static unsigned long max_wakeup_granularity_ns = 1000000000;   /* 1 second */
 #endif
 
-static ctl_table kern_table[] = {
+static struct ctl_table kern_table[] = {
 #ifdef CONFIG_SCHED_DEBUG
        {
                .ctl_name       = CTL_UNNUMBERED,
@@ -365,7 +364,6 @@ static ctl_table kern_table[] = {
        },
 #ifdef CONFIG_PROC_SYSCTL
        {
-               .ctl_name       = KERN_TAINTED,
                .procname       = "tainted",
                .data           = &tainted,
                .maxlen         = sizeof(int),
@@ -373,14 +371,15 @@ static ctl_table kern_table[] = {
                .proc_handler   = &proc_dointvec_taint,
        },
 #endif
+#ifdef CONFIG_SECURITY_CAPABILITIES
        {
-               .ctl_name       = KERN_CAP_BSET,
                .procname       = "cap-bound",
                .data           = &cap_bset,
                .maxlen         = sizeof(kernel_cap_t),
                .mode           = 0600,
                .proc_handler   = &proc_dointvec_bset,
        },
+#endif /* def CONFIG_SECURITY_CAPABILITIES */
 #ifdef CONFIG_BLK_DEV_INITRD
        {
                .ctl_name       = KERN_REALROOTDEV,
@@ -514,7 +513,6 @@ static ctl_table kern_table[] = {
 #endif
 #ifdef CONFIG_PROC_SYSCTL
        {
-               .ctl_name       = KERN_CADPID,
                .procname       = "cad_pid",
                .data           = NULL,
                .maxlen         = sizeof (int),
@@ -536,14 +534,6 @@ static ctl_table kern_table[] = {
                .mode           = 0555,
                .child          = random_table,
        },
-#ifdef CONFIG_UNIX98_PTYS
-       {
-               .ctl_name       = KERN_PTY,
-               .procname       = "pty",
-               .mode           = 0555,
-               .child          = pty_table,
-       },
-#endif
        {
                .ctl_name       = KERN_OVERFLOWUID,
                .procname       = "overflowuid",
@@ -650,7 +640,6 @@ static ctl_table kern_table[] = {
                .proc_handler   = &proc_dointvec,
        },
        {
-               .ctl_name       = KERN_NMI_WATCHDOG,
                .procname       = "nmi_watchdog",
                .data           = &nmi_watchdog_enabled,
                .maxlen         = sizeof (int),
@@ -706,7 +695,6 @@ static ctl_table kern_table[] = {
 #endif
 #if    defined(CONFIG_ACPI_SLEEP) && defined(CONFIG_X86)
        {
-               .ctl_name       = KERN_ACPI_VIDEO_FLAGS,
                .procname       = "acpi_video_flags",
                .data           = &acpi_realmode_flags,
                .maxlen         = sizeof (unsigned long),
@@ -783,7 +771,7 @@ static ctl_table kern_table[] = {
        { .ctl_name = 0 }
 };
 
-static ctl_table vm_table[] = {
+static struct ctl_table vm_table[] = {
        {
                .ctl_name       = VM_OVERCOMMIT_MEMORY,
                .procname       = "overcommit_memory",
@@ -847,7 +835,6 @@ static ctl_table vm_table[] = {
                .extra2         = &one_hundred,
        },
        {
-               .ctl_name       = VM_DIRTY_WB_CS,
                .procname       = "dirty_writeback_centisecs",
                .data           = &dirty_writeback_interval,
                .maxlen         = sizeof(dirty_writeback_interval),
@@ -855,7 +842,6 @@ static ctl_table vm_table[] = {
                .proc_handler   = &dirty_writeback_centisecs_handler,
        },
        {
-               .ctl_name       = VM_DIRTY_EXPIRE_CS,
                .procname       = "dirty_expire_centisecs",
                .data           = &dirty_expire_interval,
                .maxlen         = sizeof(dirty_expire_interval),
@@ -883,7 +869,6 @@ static ctl_table vm_table[] = {
        },
 #ifdef CONFIG_HUGETLB_PAGE
         {
-               .ctl_name       = VM_HUGETLB_PAGES,
                .procname       = "nr_hugepages",
                .data           = &max_huge_pages,
                .maxlen         = sizeof(unsigned long),
@@ -1093,12 +1078,12 @@ static ctl_table vm_table[] = {
 };
 
 #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
-static ctl_table binfmt_misc_table[] = {
+static struct ctl_table binfmt_misc_table[] = {
        { .ctl_name = 0 }
 };
 #endif
 
-static ctl_table fs_table[] = {
+static struct ctl_table fs_table[] = {
        {
                .ctl_name       = FS_NRINODE,
                .procname       = "inode-nr",
@@ -1116,7 +1101,6 @@ static ctl_table fs_table[] = {
                .proc_handler   = &proc_dointvec,
        },
        {
-               .ctl_name       = FS_NRFILE,
                .procname       = "file-nr",
                .data           = &files_stat,
                .maxlen         = 3*sizeof(int),
@@ -1192,7 +1176,6 @@ static ctl_table fs_table[] = {
                .extra2         = &two,
        },
        {
-               .ctl_name       = FS_AIO_NR,
                .procname       = "aio-nr",
                .data           = &aio_nr,
                .maxlen         = sizeof(aio_nr),
@@ -1200,7 +1183,6 @@ static ctl_table fs_table[] = {
                .proc_handler   = &proc_doulongvec_minmax,
        },
        {
-               .ctl_name       = FS_AIO_MAX_NR,
                .procname       = "aio-max-nr",
                .data           = &aio_max_nr,
                .maxlen         = sizeof(aio_max_nr),
@@ -1239,7 +1221,7 @@ static ctl_table fs_table[] = {
        { .ctl_name = 0 }
 };
 
-static ctl_table debug_table[] = {
+static struct ctl_table debug_table[] = {
 #if defined(CONFIG_X86) || defined(CONFIG_PPC)
        {
                .ctl_name       = CTL_UNNUMBERED,
@@ -1253,7 +1235,7 @@ static ctl_table debug_table[] = {
        { .ctl_name = 0 }
 };
 
-static ctl_table dev_table[] = {
+static struct ctl_table dev_table[] = {
        { .ctl_name = 0 }
 };
 
@@ -1369,10 +1351,15 @@ asmlinkage long sys_sysctl(struct __sysctl_args __user *args)
        if (copy_from_user(&tmp, args, sizeof(tmp)))
                return -EFAULT;
 
+       error = deprecated_sysctl_warning(&tmp);
+       if (error)
+               goto out;
+
        lock_kernel();
        error = do_sysctl(tmp.name, tmp.nlen, tmp.oldval, tmp.oldlenp,
                          tmp.newval, tmp.newlen);
        unlock_kernel();
+out:
        return error;
 }
 #endif /* CONFIG_SYSCTL_SYSCALL */
@@ -1393,7 +1380,7 @@ static int test_perm(int mode, int op)
        return -EACCES;
 }
 
-int sysctl_perm(ctl_table *table, int op)
+int sysctl_perm(struct ctl_table *table, int op)
 {
        int error;
        error = security_sysctl(table, op);
@@ -1406,7 +1393,7 @@ int sysctl_perm(ctl_table *table, int op)
 static int parse_table(int __user *name, int nlen,
                       void __user *oldval, size_t __user *oldlenp,
                       void __user *newval, size_t newlen,
-                      ctl_table *table)
+                      struct ctl_table *table)
 {
        int n;
 repeat:
@@ -1437,13 +1424,12 @@ repeat:
 }
 
 /* Perform the actual read/write of a sysctl table entry. */
-int do_sysctl_strategy (ctl_table *table, 
+int do_sysctl_strategy (struct ctl_table *table,
                        int __user *name, int nlen,
                        void __user *oldval, size_t __user *oldlenp,
                        void __user *newval, size_t newlen)
 {
        int op = 0, rc;
-       size_t len;
 
        if (oldval)
                op |= 004;
@@ -1464,25 +1450,10 @@ int do_sysctl_strategy (ctl_table *table,
        /* If there is no strategy routine, or if the strategy returns
         * zero, proceed with automatic r/w */
        if (table->data && table->maxlen) {
-               if (oldval && oldlenp) {
-                       if (get_user(len, oldlenp))
-                               return -EFAULT;
-                       if (len) {
-                               if (len > table->maxlen)
-                                       len = table->maxlen;
-                               if(copy_to_user(oldval, table->data, len))
-                                       return -EFAULT;
-                               if(put_user(len, oldlenp))
-                                       return -EFAULT;
-                       }
-               }
-               if (newval && newlen) {
-                       len = newlen;
-                       if (len > table->maxlen)
-                               len = table->maxlen;
-                       if(copy_from_user(table->data, newval, len))
-                               return -EFAULT;
-               }
+               rc = sysctl_data(table, name, nlen, oldval, oldlenp,
+                                newval, newlen);
+               if (rc < 0)
+                       return rc;
        }
        return 0;
 }
@@ -1499,7 +1470,9 @@ static void sysctl_set_parent(struct ctl_table *parent, struct ctl_table *table)
 
 static __init int sysctl_init(void)
 {
+       int err;
        sysctl_set_parent(NULL, root_table);
+       err = sysctl_check_table(root_table);
        return 0;
 }
 
@@ -1512,7 +1485,7 @@ core_initcall(sysctl_init);
  * Register a sysctl table hierarchy. @table should be a filled in ctl_table
  * array. An entry with a ctl_name of 0 terminates the table. 
  *
- * The members of the &ctl_table structure are used as follows:
+ * The members of the &struct ctl_table structure are used as follows:
  *
  * ctl_name - This is the numeric sysctl value used by sysctl(2). The number
  *            must be unique within that level of sysctl
@@ -1573,7 +1546,7 @@ core_initcall(sysctl_init);
  * This routine returns %NULL on a failure to register, and a pointer
  * to the table header on success.
  */
-struct ctl_table_header *register_sysctl_table(ctl_table * table)
+struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
 {
        struct ctl_table_header *tmp;
        tmp = kmalloc(sizeof(struct ctl_table_header), GFP_KERNEL);
@@ -1584,6 +1557,10 @@ struct ctl_table_header *register_sysctl_table(ctl_table * table)
        tmp->used = 0;
        tmp->unregistering = NULL;
        sysctl_set_parent(NULL, table);
+       if (sysctl_check_table(tmp->ctl_table)) {
+               kfree(tmp);
+               return NULL;
+       }
        spin_lock(&sysctl_lock);
        list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry);
        spin_unlock(&sysctl_lock);
@@ -1607,7 +1584,7 @@ void unregister_sysctl_table(struct ctl_table_header * header)
 }
 
 #else /* !CONFIG_SYSCTL */
-struct ctl_table_header *register_sysctl_table(ctl_table * table)
+struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
 {
        return NULL;
 }
@@ -1700,7 +1677,7 @@ static int _proc_do_string(void* data, int maxlen, int write,
  *
  * Returns 0 on success.
  */
-int proc_dostring(ctl_table *table, int write, struct file *filp,
+int proc_dostring(struct ctl_table *table, int write, struct file *filp,
                  void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        return _proc_do_string(table->data, table->maxlen, write, filp,
@@ -1727,7 +1704,7 @@ static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp,
        return 0;
 }
 
-static int __do_proc_dointvec(void *tbl_data, ctl_table *table,
+static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
                  int write, struct file *filp, void __user *buffer,
                  size_t *lenp, loff_t *ppos,
                  int (*conv)(int *negp, unsigned long *lvalp, int *valp,
@@ -1837,7 +1814,7 @@ static int __do_proc_dointvec(void *tbl_data, ctl_table *table,
 #undef TMPBUFLEN
 }
 
-static int do_proc_dointvec(ctl_table *table, int write, struct file *filp,
+static int do_proc_dointvec(struct ctl_table *table, int write, struct file *filp,
                  void __user *buffer, size_t *lenp, loff_t *ppos,
                  int (*conv)(int *negp, unsigned long *lvalp, int *valp,
                              int write, void *data),
@@ -1861,7 +1838,7 @@ static int do_proc_dointvec(ctl_table *table, int write, struct file *filp,
  *
  * Returns 0 on success.
  */
-int proc_dointvec(ctl_table *table, int write, struct file *filp,
+int proc_dointvec(struct ctl_table *table, int write, struct file *filp,
                     void __user *buffer, size_t *lenp, loff_t *ppos)
 {
     return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
@@ -1897,11 +1874,12 @@ static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp,
        return 0;
 }
 
+#ifdef CONFIG_SECURITY_CAPABILITIES
 /*
  *     init may raise the set.
  */
-int proc_dointvec_bset(ctl_table *table, int write, struct file *filp,
+
+int proc_dointvec_bset(struct ctl_table *table, int write, struct file *filp,
                        void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        int op;
@@ -1910,15 +1888,16 @@ int proc_dointvec_bset(ctl_table *table, int write, struct file *filp,
                return -EPERM;
        }
 
-       op = is_init(current) ? OP_SET : OP_AND;
+       op = is_global_init(current) ? OP_SET : OP_AND;
        return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
                                do_proc_dointvec_bset_conv,&op);
 }
+#endif /* def CONFIG_SECURITY_CAPABILITIES */
 
 /*
  *     Taint values can only be increased
  */
-static int proc_dointvec_taint(ctl_table *table, int write, struct file *filp,
+static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp,
                               void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        int op;
@@ -1977,7 +1956,7 @@ static int do_proc_dointvec_minmax_conv(int *negp, unsigned long *lvalp,
  *
  * Returns 0 on success.
  */
-int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp,
                  void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        struct do_proc_dointvec_minmax_conv_param param = {
@@ -1988,7 +1967,7 @@ int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp,
                                do_proc_dointvec_minmax_conv, &param);
 }
 
-static int __do_proc_doulongvec_minmax(void *data, ctl_table *table, int write,
+static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int write,
                                     struct file *filp,
                                     void __user *buffer,
                                     size_t *lenp, loff_t *ppos,
@@ -2093,7 +2072,7 @@ static int __do_proc_doulongvec_minmax(void *data, ctl_table *table, int write,
 #undef TMPBUFLEN
 }
 
-static int do_proc_doulongvec_minmax(ctl_table *table, int write,
+static int do_proc_doulongvec_minmax(struct ctl_table *table, int write,
                                     struct file *filp,
                                     void __user *buffer,
                                     size_t *lenp, loff_t *ppos,
@@ -2121,7 +2100,7 @@ static int do_proc_doulongvec_minmax(ctl_table *table, int write,
  *
  * Returns 0 on success.
  */
-int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp,
+int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp,
                           void __user *buffer, size_t *lenp, loff_t *ppos)
 {
     return do_proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos, 1l, 1l);
@@ -2145,7 +2124,7 @@ int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp,
  *
  * Returns 0 on success.
  */
-int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write,
+int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write,
                                      struct file *filp,
                                      void __user *buffer,
                                      size_t *lenp, loff_t *ppos)
@@ -2238,7 +2217,7 @@ static int do_proc_dointvec_ms_jiffies_conv(int *negp, unsigned long *lvalp,
  *
  * Returns 0 on success.
  */
-int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp,
                          void __user *buffer, size_t *lenp, loff_t *ppos)
 {
     return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
@@ -2261,7 +2240,7 @@ int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp,
  *
  * Returns 0 on success.
  */
-int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file *filp,
                                 void __user *buffer, size_t *lenp, loff_t *ppos)
 {
     return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
@@ -2285,21 +2264,21 @@ int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp,
  *
  * Returns 0 on success.
  */
-int proc_dointvec_ms_jiffies(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, struct file *filp,
                             void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        return do_proc_dointvec(table, write, filp, buffer, lenp, ppos,
                                do_proc_dointvec_ms_jiffies_conv, NULL);
 }
 
-static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
+static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp,
                           void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        struct pid *new_pid;
        pid_t tmp;
        int r;
 
-       tmp = pid_nr(cad_pid);
+       tmp = pid_nr_ns(cad_pid, current->nsproxy->pid_ns);
 
        r = __do_proc_dointvec(&tmp, table, write, filp, buffer,
                               lenp, ppos, NULL, NULL);
@@ -2316,55 +2295,55 @@ static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
 
 #else /* CONFIG_PROC_FS */
 
-int proc_dostring(ctl_table *table, int write, struct file *filp,
+int proc_dostring(struct ctl_table *table, int write, struct file *filp,
                  void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        return -ENOSYS;
 }
 
-int proc_dointvec(ctl_table *table, int write, struct file *filp,
+int proc_dointvec(struct ctl_table *table, int write, struct file *filp,
                  void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        return -ENOSYS;
 }
 
-int proc_dointvec_bset(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_bset(struct ctl_table *table, int write, struct file *filp,
                        void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        return -ENOSYS;
 }
 
-int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp,
                    void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        return -ENOSYS;
 }
 
-int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp,
                    void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        return -ENOSYS;
 }
 
-int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file *filp,
                    void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        return -ENOSYS;
 }
 
-int proc_dointvec_ms_jiffies(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, struct file *filp,
                             void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        return -ENOSYS;
 }
 
-int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp,
+int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp,
                    void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        return -ENOSYS;
 }
 
-int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write,
+int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write,
                                      struct file *filp,
                                      void __user *buffer,
                                      size_t *lenp, loff_t *ppos)
@@ -2381,8 +2360,42 @@ int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write,
  * General sysctl support routines 
  */
 
+/* The generic sysctl data routine (used if no strategy routine supplied) */
+int sysctl_data(struct ctl_table *table, int __user *name, int nlen,
+               void __user *oldval, size_t __user *oldlenp,
+               void __user *newval, size_t newlen)
+{
+       size_t len;
+
+       /* Get out of I don't have a variable */
+       if (!table->data || !table->maxlen)
+               return -ENOTDIR;
+
+       if (oldval && oldlenp) {
+               if (get_user(len, oldlenp))
+                       return -EFAULT;
+               if (len) {
+                       if (len > table->maxlen)
+                               len = table->maxlen;
+                       if (copy_to_user(oldval, table->data, len))
+                               return -EFAULT;
+                       if (put_user(len, oldlenp))
+                               return -EFAULT;
+               }
+       }
+
+       if (newval && newlen) {
+               if (newlen > table->maxlen)
+                       newlen = table->maxlen;
+
+               if (copy_from_user(table->data, newval, newlen))
+                       return -EFAULT;
+       }
+       return 1;
+}
+
 /* The generic string strategy routine: */
-int sysctl_string(ctl_table *table, int __user *name, int nlen,
+int sysctl_string(struct ctl_table *table, int __user *name, int nlen,
                  void __user *oldval, size_t __user *oldlenp,
                  void __user *newval, size_t newlen)
 {
@@ -2428,7 +2441,7 @@ int sysctl_string(ctl_table *table, int __user *name, int nlen,
  * are between the minimum and maximum values given in the arrays
  * table->extra1 and table->extra2, respectively.
  */
-int sysctl_intvec(ctl_table *table, int __user *name, int nlen,
+int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen,
                void __user *oldval, size_t __user *oldlenp,
                void __user *newval, size_t newlen)
 {
@@ -2464,7 +2477,7 @@ int sysctl_intvec(ctl_table *table, int __user *name, int nlen,
 }
 
 /* Strategy function to convert jiffies to seconds */ 
-int sysctl_jiffies(ctl_table *table, int __user *name, int nlen,
+int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen,
                void __user *oldval, size_t __user *oldlenp,
                void __user *newval, size_t newlen)
 {
@@ -2498,7 +2511,7 @@ int sysctl_jiffies(ctl_table *table, int __user *name, int nlen,
 }
 
 /* Strategy function to convert jiffies to seconds */ 
-int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen,
+int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen,
                void __user *oldval, size_t __user *oldlenp,
                void __user *newval, size_t newlen)
 {
@@ -2538,59 +2551,50 @@ int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen,
 
 asmlinkage long sys_sysctl(struct __sysctl_args __user *args)
 {
-       static int msg_count;
        struct __sysctl_args tmp;
-       int name[CTL_MAXNAME];
-       int i;
+       int error;
 
-       /* Read in the sysctl name for better debug message logging */
        if (copy_from_user(&tmp, args, sizeof(tmp)))
                return -EFAULT;
-       if (tmp.nlen <= 0 || tmp.nlen >= CTL_MAXNAME)
-               return -ENOTDIR;
-       for (i = 0; i < tmp.nlen; i++)
-               if (get_user(name[i], tmp.name + i))
-                       return -EFAULT;
 
-       /* Ignore accesses to kernel.version */
-       if ((tmp.nlen == 2) && (name[0] == CTL_KERN) && (name[1] == KERN_VERSION))
-               goto out;
+       error = deprecated_sysctl_warning(&tmp);
 
-       if (msg_count < 5) {
-               msg_count++;
-               printk(KERN_INFO
-                       "warning: process `%s' used the removed sysctl "
-                       "system call with ", current->comm);
-               for (i = 0; i < tmp.nlen; i++)
-                       printk("%d.", name[i]);
-               printk("\n");
-       }
-out:
+       /* If no error reading the parameters then just -ENOSYS ... */
+       if (!error)
+               error = -ENOSYS;
+
+       return error;
+}
+
+int sysctl_data(struct ctl_table *table, int __user *name, int nlen,
+                 void __user *oldval, size_t __user *oldlenp,
+                 void __user *newval, size_t newlen)
+{
        return -ENOSYS;
 }
 
-int sysctl_string(ctl_table *table, int __user *name, int nlen,
+int sysctl_string(struct ctl_table *table, int __user *name, int nlen,
                  void __user *oldval, size_t __user *oldlenp,
                  void __user *newval, size_t newlen)
 {
        return -ENOSYS;
 }
 
-int sysctl_intvec(ctl_table *table, int __user *name, int nlen,
+int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen,
                void __user *oldval, size_t __user *oldlenp,
                void __user *newval, size_t newlen)
 {
        return -ENOSYS;
 }
 
-int sysctl_jiffies(ctl_table *table, int __user *name, int nlen,
+int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen,
                void __user *oldval, size_t __user *oldlenp,
                void __user *newval, size_t newlen)
 {
        return -ENOSYS;
 }
 
-int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen,
+int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen,
                void __user *oldval, size_t __user *oldlenp,
                void __user *newval, size_t newlen)
 {
@@ -2599,6 +2603,33 @@ int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen,
 
 #endif /* CONFIG_SYSCTL_SYSCALL */
 
+static int deprecated_sysctl_warning(struct __sysctl_args *args)
+{
+       static int msg_count;
+       int name[CTL_MAXNAME];
+       int i;
+
+       /* Read in the sysctl name for better debug message logging */
+       for (i = 0; i < args->nlen; i++)
+               if (get_user(name[i], args->name + i))
+                       return -EFAULT;
+
+       /* Ignore accesses to kernel.version */
+       if ((args->nlen == 2) && (name[0] == CTL_KERN) && (name[1] == KERN_VERSION))
+               return 0;
+
+       if (msg_count < 5) {
+               msg_count++;
+               printk(KERN_INFO
+                       "warning: process `%s' used the deprecated sysctl "
+                       "system call with ", current->comm);
+               for (i = 0; i < args->nlen; i++)
+                       printk("%d.", name[i]);
+               printk("\n");
+       }
+       return 0;
+}
+
 /*
  * No sense putting this after each symbol definition, twice,
  * exception granted :-)
@@ -2616,4 +2647,5 @@ EXPORT_SYMBOL(sysctl_intvec);
 EXPORT_SYMBOL(sysctl_jiffies);
 EXPORT_SYMBOL(sysctl_ms_jiffies);
 EXPORT_SYMBOL(sysctl_string);
+EXPORT_SYMBOL(sysctl_data);
 EXPORT_SYMBOL(unregister_sysctl_table);
diff --git a/kernel/sysctl_check.c b/kernel/sysctl_check.c
new file mode 100644 (file)
index 0000000..ed6fe51
--- /dev/null
@@ -0,0 +1,1588 @@
+#include <linux/stat.h>
+#include <linux/sysctl.h>
+#include "../arch/s390/appldata/appldata.h"
+#include "../fs/xfs/linux-2.6/xfs_sysctl.h"
+#include <linux/sunrpc/debug.h>
+#include <linux/string.h>
+#include <net/ip_vs.h>
+
+struct trans_ctl_table {
+       int                     ctl_name;
+       const char              *procname;
+       struct trans_ctl_table  *child;
+};
+
+static struct trans_ctl_table trans_random_table[] = {
+       { RANDOM_POOLSIZE,      "poolsize" },
+       { RANDOM_ENTROPY_COUNT, "entropy_avail" },
+       { RANDOM_READ_THRESH,   "read_wakeup_threshold" },
+       { RANDOM_WRITE_THRESH,  "write_wakeup_threshold" },
+       { RANDOM_BOOT_ID,       "boot_id" },
+       { RANDOM_UUID,          "uuid" },
+       {}
+};
+
+static struct trans_ctl_table trans_pty_table[] = {
+       { PTY_MAX,              "max" },
+       { PTY_NR,               "nr" },
+       {}
+};
+
+static struct trans_ctl_table trans_kern_table[] = {
+       { KERN_OSTYPE,                  "ostype" },
+       { KERN_OSRELEASE,               "osrelease" },
+       /* KERN_OSREV not used */
+       { KERN_VERSION,                 "version" },
+       /* KERN_SECUREMASK not used */
+       /* KERN_PROF not used */
+       { KERN_NODENAME,                "hostname" },
+       { KERN_DOMAINNAME,              "domainname" },
+
+#ifdef CONFIG_SECURITY_CAPABILITIES
+       { KERN_CAP_BSET,                "cap-bound" },
+#endif /* def CONFIG_SECURITY_CAPABILITIES */
+
+       { KERN_PANIC,                   "panic" },
+       { KERN_REALROOTDEV,             "real-root-dev" },
+
+       { KERN_SPARC_REBOOT,            "reboot-cmd" },
+       { KERN_CTLALTDEL,               "ctrl-alt-del" },
+       { KERN_PRINTK,                  "printk" },
+
+       /* KERN_NAMETRANS not used */
+       /* KERN_PPC_HTABRECLAIM not used */
+       /* KERN_PPC_ZEROPAGED not used */
+       { KERN_PPC_POWERSAVE_NAP,       "powersave-nap" },
+
+       { KERN_MODPROBE,                "modprobe" },
+       { KERN_SG_BIG_BUFF,             "sg-big-buff" },
+       { KERN_ACCT,                    "acct" },
+       { KERN_PPC_L2CR,                "l2cr" },
+
+       /* KERN_RTSIGNR not used */
+       /* KERN_RTSIGMAX not used */
+
+       { KERN_SHMMAX,                  "shmmax" },
+       { KERN_MSGMAX,                  "msgmax" },
+       { KERN_MSGMNB,                  "msgmnb" },
+       /* KERN_MSGPOOL not used*/
+       { KERN_SYSRQ,                   "sysrq" },
+       { KERN_MAX_THREADS,             "threads-max" },
+       { KERN_RANDOM,                  "random",       trans_random_table },
+       { KERN_SHMALL,                  "shmall" },
+       { KERN_MSGMNI,                  "msgmni" },
+       { KERN_SEM,                     "sem" },
+       { KERN_SPARC_STOP_A,            "stop-a" },
+       { KERN_SHMMNI,                  "shmmni" },
+
+       { KERN_OVERFLOWUID,             "overflowuid" },
+       { KERN_OVERFLOWGID,             "overflowgid" },
+
+       { KERN_HOTPLUG,                 "hotplug", },
+       { KERN_IEEE_EMULATION_WARNINGS, "ieee_emulation_warnings" },
+
+       { KERN_S390_USER_DEBUG_LOGGING, "userprocess_debug" },
+       { KERN_CORE_USES_PID,           "core_uses_pid" },
+       { KERN_TAINTED,                 "tainted" },
+       { KERN_CADPID,                  "cad_pid" },
+       { KERN_PIDMAX,                  "pid_max" },
+       { KERN_CORE_PATTERN,            "core_pattern" },
+       { KERN_PANIC_ON_OOPS,           "panic_on_oops" },
+       { KERN_HPPA_PWRSW,              "soft-power" },
+       { KERN_HPPA_UNALIGNED,          "unaligned-trap" },
+
+       { KERN_PRINTK_RATELIMIT,        "printk_ratelimit" },
+       { KERN_PRINTK_RATELIMIT_BURST,  "printk_ratelimit_burst" },
+
+       { KERN_PTY,                     "pty",          trans_pty_table },
+       { KERN_NGROUPS_MAX,             "ngroups_max" },
+       { KERN_SPARC_SCONS_PWROFF,      "scons_poweroff" },
+       { KERN_HZ_TIMER,                "hz_timer" },
+       { KERN_UNKNOWN_NMI_PANIC,       "unknown_nmi_panic" },
+       { KERN_BOOTLOADER_TYPE,         "bootloader_type" },
+       { KERN_RANDOMIZE,               "randomize_va_space" },
+
+       { KERN_SPIN_RETRY,              "spin_retry" },
+       { KERN_ACPI_VIDEO_FLAGS,        "acpi_video_flags" },
+       { KERN_IA64_UNALIGNED,          "ignore-unaligned-usertrap" },
+       { KERN_COMPAT_LOG,              "compat-log" },
+       { KERN_MAX_LOCK_DEPTH,          "max_lock_depth" },
+       { KERN_NMI_WATCHDOG,            "nmi_watchdog" },
+       { KERN_PANIC_ON_NMI,            "panic_on_unrecovered_nmi" },
+       {}
+};
+
+static struct trans_ctl_table trans_vm_table[] = {
+       { VM_OVERCOMMIT_MEMORY,         "overcommit_memory" },
+       { VM_PAGE_CLUSTER,              "page-cluster" },
+       { VM_DIRTY_BACKGROUND,          "dirty_background_ratio" },
+       { VM_DIRTY_RATIO,               "dirty_ratio" },
+       { VM_DIRTY_WB_CS,               "dirty_writeback_centisecs" },
+       { VM_DIRTY_EXPIRE_CS,           "dirty_expire_centisecs" },
+       { VM_NR_PDFLUSH_THREADS,        "nr_pdflush_threads" },
+       { VM_OVERCOMMIT_RATIO,          "overcommit_ratio" },
+       /* VM_PAGEBUF unused */
+       { VM_HUGETLB_PAGES,             "nr_hugepages" },
+       { VM_SWAPPINESS,                "swappiness" },
+       { VM_LOWMEM_RESERVE_RATIO,      "lowmem_reserve_ratio" },
+       { VM_MIN_FREE_KBYTES,           "min_free_kbytes" },
+       { VM_MAX_MAP_COUNT,             "max_map_count" },
+       { VM_LAPTOP_MODE,               "laptop_mode" },
+       { VM_BLOCK_DUMP,                "block_dump" },
+       { VM_HUGETLB_GROUP,             "hugetlb_shm_group" },
+       { VM_VFS_CACHE_PRESSURE,        "vfs_cache_pressure" },
+       { VM_LEGACY_VA_LAYOUT,          "legacy_va_layout" },
+       /* VM_SWAP_TOKEN_TIMEOUT unused */
+       { VM_DROP_PAGECACHE,            "drop_caches" },
+       { VM_PERCPU_PAGELIST_FRACTION,  "percpu_pagelist_fraction" },
+       { VM_ZONE_RECLAIM_MODE,         "zone_reclaim_mode" },
+       { VM_MIN_UNMAPPED,              "min_unmapped_ratio" },
+       { VM_PANIC_ON_OOM,              "panic_on_oom" },
+       { VM_VDSO_ENABLED,              "vdso_enabled" },
+       { VM_MIN_SLAB,                  "min_slab_ratio" },
+       { VM_CMM_PAGES,                 "cmm_pages" },
+       { VM_CMM_TIMED_PAGES,           "cmm_timed_pages" },
+       { VM_CMM_TIMEOUT,               "cmm_timeout" },
+
+       {}
+};
+
+static struct trans_ctl_table trans_net_core_table[] = {
+       { NET_CORE_WMEM_MAX,            "wmem_max" },
+       { NET_CORE_RMEM_MAX,            "rmem_max" },
+       { NET_CORE_WMEM_DEFAULT,        "wmem_default" },
+       { NET_CORE_RMEM_DEFAULT,        "rmem_default" },
+       /* NET_CORE_DESTROY_DELAY unused */
+       { NET_CORE_MAX_BACKLOG,         "netdev_max_backlog" },
+       /* NET_CORE_FASTROUTE unused */
+       { NET_CORE_MSG_COST,            "message_cost" },
+       { NET_CORE_MSG_BURST,           "message_burst" },
+       { NET_CORE_OPTMEM_MAX,          "optmem_max" },
+       /* NET_CORE_HOT_LIST_LENGTH unused */
+       /* NET_CORE_DIVERT_VERSION unused */
+       /* NET_CORE_NO_CONG_THRESH unused */
+       /* NET_CORE_NO_CONG unused */
+       /* NET_CORE_LO_CONG unused */
+       /* NET_CORE_MOD_CONG unused */
+       { NET_CORE_DEV_WEIGHT,          "dev_weight" },
+       { NET_CORE_SOMAXCONN,           "somaxconn" },
+       { NET_CORE_BUDGET,              "netdev_budget" },
+       { NET_CORE_AEVENT_ETIME,        "xfrm_aevent_etime" },
+       { NET_CORE_AEVENT_RSEQTH,       "xfrm_aevent_rseqth" },
+       { NET_CORE_WARNINGS,            "warnings" },
+       {},
+};
+
+static struct trans_ctl_table trans_net_unix_table[] = {
+       /* NET_UNIX_DESTROY_DELAY unused */
+       /* NET_UNIX_DELETE_DELAY unused */
+       { NET_UNIX_MAX_DGRAM_QLEN,      "max_dgram_qlen" },
+       {}
+};
+
+static struct trans_ctl_table trans_net_ipv4_route_table[] = {
+       { NET_IPV4_ROUTE_FLUSH,                 "flush" },
+       { NET_IPV4_ROUTE_MIN_DELAY,             "min_delay" },
+       { NET_IPV4_ROUTE_MAX_DELAY,             "max_delay" },
+       { NET_IPV4_ROUTE_GC_THRESH,             "gc_thresh" },
+       { NET_IPV4_ROUTE_MAX_SIZE,              "max_size" },
+       { NET_IPV4_ROUTE_GC_MIN_INTERVAL,       "gc_min_interval" },
+       { NET_IPV4_ROUTE_GC_TIMEOUT,            "gc_timeout" },
+       { NET_IPV4_ROUTE_GC_INTERVAL,           "gc_interval" },
+       { NET_IPV4_ROUTE_REDIRECT_LOAD,         "redirect_load" },
+       { NET_IPV4_ROUTE_REDIRECT_NUMBER,       "redirect_number" },
+       { NET_IPV4_ROUTE_REDIRECT_SILENCE,      "redirect_silence" },
+       { NET_IPV4_ROUTE_ERROR_COST,            "error_cost" },
+       { NET_IPV4_ROUTE_ERROR_BURST,           "error_burst" },
+       { NET_IPV4_ROUTE_GC_ELASTICITY,         "gc_elasticity" },
+       { NET_IPV4_ROUTE_MTU_EXPIRES,           "mtu_expires" },
+       { NET_IPV4_ROUTE_MIN_PMTU,              "min_pmtu" },
+       { NET_IPV4_ROUTE_MIN_ADVMSS,            "min_adv_mss" },
+       { NET_IPV4_ROUTE_SECRET_INTERVAL,       "secret_interval" },
+       { NET_IPV4_ROUTE_GC_MIN_INTERVAL_MS,    "gc_min_interval_ms" },
+       {}
+};
+
+static struct trans_ctl_table trans_net_ipv4_conf_vars_table[] = {
+       { NET_IPV4_CONF_FORWARDING,             "forwarding" },
+       { NET_IPV4_CONF_MC_FORWARDING,          "mc_forwarding" },
+
+       { NET_IPV4_CONF_PROXY_ARP,              "proxy_arp" },
+       { NET_IPV4_CONF_ACCEPT_REDIRECTS,       "accept_redirects" },
+       { NET_IPV4_CONF_SECURE_REDIRECTS,       "secure_redirects" },
+       { NET_IPV4_CONF_SEND_REDIRECTS,         "send_redirects" },
+       { NET_IPV4_CONF_SHARED_MEDIA,           "shared_media" },
+       { NET_IPV4_CONF_RP_FILTER,              "rp_filter" },
+       { NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE,    "accept_source_route" },
+       { NET_IPV4_CONF_BOOTP_RELAY,            "bootp_relay" },
+       { NET_IPV4_CONF_LOG_MARTIANS,           "log_martians" },
+       { NET_IPV4_CONF_TAG,                    "tag" },
+       { NET_IPV4_CONF_ARPFILTER,              "arp_filter" },
+       { NET_IPV4_CONF_MEDIUM_ID,              "medium_id" },
+       { NET_IPV4_CONF_NOXFRM,                 "disable_xfrm" },
+       { NET_IPV4_CONF_NOPOLICY,               "disable_policy" },
+       { NET_IPV4_CONF_FORCE_IGMP_VERSION,     "force_igmp_version" },
+
+       { NET_IPV4_CONF_ARP_ANNOUNCE,           "arp_announce" },
+       { NET_IPV4_CONF_ARP_IGNORE,             "arp_ignore" },
+       { NET_IPV4_CONF_PROMOTE_SECONDARIES,    "promote_secondaries" },
+       { NET_IPV4_CONF_ARP_ACCEPT,             "arp_accept" },
+       {}
+};
+
+static struct trans_ctl_table trans_net_ipv4_conf_table[] = {
+       { NET_PROTO_CONF_ALL,           "all",          trans_net_ipv4_conf_vars_table },
+       { NET_PROTO_CONF_DEFAULT,       "default",      trans_net_ipv4_conf_vars_table },
+       { 0, NULL, trans_net_ipv4_conf_vars_table },
+       {}
+};
+
+
+static struct trans_ctl_table trans_net_ipv4_vs_table[] = {
+       { NET_IPV4_VS_AMEMTHRESH,       "amemthresh" },
+       { NET_IPV4_VS_DEBUG_LEVEL,      "debug_level" },
+       { NET_IPV4_VS_AMDROPRATE,       "am_droprate" },
+       { NET_IPV4_VS_DROP_ENTRY,       "drop_entry" },
+       { NET_IPV4_VS_DROP_PACKET,      "drop_packet" },
+       { NET_IPV4_VS_SECURE_TCP,       "secure_tcp" },
+       { NET_IPV4_VS_TO_ES,            "timeout_established" },
+       { NET_IPV4_VS_TO_SS,            "timeout_synsent" },
+       { NET_IPV4_VS_TO_SR,            "timeout_synrecv" },
+       { NET_IPV4_VS_TO_FW,            "timeout_finwait" },
+       { NET_IPV4_VS_TO_TW,            "timeout_timewait" },
+       { NET_IPV4_VS_TO_CL,            "timeout_close" },
+       { NET_IPV4_VS_TO_CW,            "timeout_closewait" },
+       { NET_IPV4_VS_TO_LA,            "timeout_lastack" },
+       { NET_IPV4_VS_TO_LI,            "timeout_listen" },
+       { NET_IPV4_VS_TO_SA,            "timeout_synack" },
+       { NET_IPV4_VS_TO_UDP,           "timeout_udp" },
+       { NET_IPV4_VS_TO_ICMP,          "timeout_icmp" },
+       { NET_IPV4_VS_CACHE_BYPASS,     "cache_bypass" },
+       { NET_IPV4_VS_EXPIRE_NODEST_CONN,       "expire_nodest_conn" },
+       { NET_IPV4_VS_EXPIRE_QUIESCENT_TEMPLATE,        "expire_quiescent_template" },
+       { NET_IPV4_VS_SYNC_THRESHOLD,           "sync_threshold" },
+       { NET_IPV4_VS_NAT_ICMP_SEND,    "nat_icmp_send" },
+       { NET_IPV4_VS_LBLC_EXPIRE,              "lblc_expiration" },
+       { NET_IPV4_VS_LBLCR_EXPIRE,             "lblcr_expiration" },
+       {}
+};
+
+static struct trans_ctl_table trans_net_neigh_vars_table[] = {
+       { NET_NEIGH_MCAST_SOLICIT,      "mcast_solicit" },
+       { NET_NEIGH_UCAST_SOLICIT,      "ucast_solicit" },
+       { NET_NEIGH_APP_SOLICIT,        "app_solicit" },
+       { NET_NEIGH_RETRANS_TIME,       "retrans_time" },
+       { NET_NEIGH_REACHABLE_TIME,     "base_reachable_time" },
+       { NET_NEIGH_DELAY_PROBE_TIME,   "delay_first_probe_time" },
+       { NET_NEIGH_GC_STALE_TIME,      "gc_stale_time" },
+       { NET_NEIGH_UNRES_QLEN,         "unres_qlen" },
+       { NET_NEIGH_PROXY_QLEN,         "proxy_qlen" },
+       { NET_NEIGH_ANYCAST_DELAY,      "anycast_delay" },
+       { NET_NEIGH_PROXY_DELAY,        "proxy_delay" },
+       { NET_NEIGH_LOCKTIME,           "locktime" },
+       { NET_NEIGH_GC_INTERVAL,        "gc_interval" },
+       { NET_NEIGH_GC_THRESH1,         "gc_thresh1" },
+       { NET_NEIGH_GC_THRESH2,         "gc_thresh2" },
+       { NET_NEIGH_GC_THRESH3,         "gc_thresh3" },
+       { NET_NEIGH_RETRANS_TIME_MS,    "retrans_time_ms" },
+       { NET_NEIGH_REACHABLE_TIME_MS,  "base_reachable_time_ms" },
+       {}
+};
+
+static struct trans_ctl_table trans_net_neigh_table[] = {
+       { NET_PROTO_CONF_DEFAULT, "default", trans_net_neigh_vars_table },
+       { 0, NULL, trans_net_neigh_vars_table },
+       {}
+};
+
+static struct trans_ctl_table trans_net_ipv4_netfilter_table[] = {
+       { NET_IPV4_NF_CONNTRACK_MAX,                            "ip_conntrack_max" },
+
+       { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT,           "ip_conntrack_tcp_timeout_syn_sent" },
+       { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV,           "ip_conntrack_tcp_timeout_syn_recv" },
+       { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED,        "ip_conntrack_tcp_timeout_established" },
+       { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT,           "ip_conntrack_tcp_timeout_fin_wait" },
+       { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT,         "ip_conntrack_tcp_timeout_close_wait" },
+       { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK,           "ip_conntrack_tcp_timeout_last_ack" },
+       { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT,          "ip_conntrack_tcp_timeout_time_wait" },
+       { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE,              "ip_conntrack_tcp_timeout_close" },
+
+       { NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT,                    "ip_conntrack_udp_timeout" },
+       { NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT_STREAM,             "ip_conntrack_udp_timeout_stream" },
+       { NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT,                   "ip_conntrack_icmp_timeout" },
+       { NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT,                "ip_conntrack_generic_timeout" },
+
+       { NET_IPV4_NF_CONNTRACK_BUCKETS,                        "ip_conntrack_buckets" },
+       { NET_IPV4_NF_CONNTRACK_LOG_INVALID,                    "ip_conntrack_log_invalid" },
+       { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS,        "ip_conntrack_tcp_timeout_max_retrans" },
+       { NET_IPV4_NF_CONNTRACK_TCP_LOOSE,                      "ip_conntrack_tcp_loose" },
+       { NET_IPV4_NF_CONNTRACK_TCP_BE_LIBERAL,                 "ip_conntrack_tcp_be_liberal" },
+       { NET_IPV4_NF_CONNTRACK_TCP_MAX_RETRANS,                "ip_conntrack_tcp_max_retrans" },
+
+       { NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED,            "ip_conntrack_sctp_timeout_closed" },
+       { NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT,       "ip_conntrack_sctp_timeout_cookie_wait" },
+       { NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED,     "ip_conntrack_sctp_timeout_cookie_echoed" },
+       { NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED,       "ip_conntrack_sctp_timeout_established" },
+       { NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT,     "ip_conntrack_sctp_timeout_shutdown_sent" },
+       { NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD,     "ip_conntrack_sctp_timeout_shutdown_recd" },
+       { NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT, "ip_conntrack_sctp_timeout_shutdown_ack_sent" },
+
+       { NET_IPV4_NF_CONNTRACK_COUNT,          "ip_conntrack_count" },
+       { NET_IPV4_NF_CONNTRACK_CHECKSUM,       "ip_conntrack_checksum" },
+       {}
+};
+
+static struct trans_ctl_table trans_net_ipv4_table[] = {
+       { NET_IPV4_FORWARD,                     "ip_forward" },
+       { NET_IPV4_DYNADDR,                     "ip_dynaddr" },
+
+       { NET_IPV4_CONF,                "conf",         trans_net_ipv4_conf_table },
+       { NET_IPV4_NEIGH,               "neigh",        trans_net_neigh_table },
+       { NET_IPV4_ROUTE,               "route",        trans_net_ipv4_route_table },
+       /* NET_IPV4_FIB_HASH unused */
+       { NET_IPV4_NETFILTER,           "netfilter",    trans_net_ipv4_netfilter_table },
+       { NET_IPV4_VS,                  "vs",           trans_net_ipv4_vs_table },
+
+       { NET_IPV4_TCP_TIMESTAMPS,              "tcp_timestamps" },
+       { NET_IPV4_TCP_WINDOW_SCALING,          "tcp_window_scaling" },
+       { NET_IPV4_TCP_SACK,                    "tcp_sack" },
+       { NET_IPV4_TCP_RETRANS_COLLAPSE,        "tcp_retrans_collapse" },
+       { NET_IPV4_DEFAULT_TTL,                 "ip_default_ttl" },
+       /* NET_IPV4_AUTOCONFIG unused */
+       { NET_IPV4_NO_PMTU_DISC,                "ip_no_pmtu_disc" },
+       { NET_IPV4_TCP_SYN_RETRIES,             "tcp_syn_retries" },
+       { NET_IPV4_IPFRAG_HIGH_THRESH,          "ipfrag_high_thresh" },
+       { NET_IPV4_IPFRAG_LOW_THRESH,           "ipfrag_low_thresh" },
+       { NET_IPV4_IPFRAG_TIME,                 "ipfrag_time" },
+       /* NET_IPV4_TCP_MAX_KA_PROBES unused */
+       { NET_IPV4_TCP_KEEPALIVE_TIME,          "tcp_keepalive_time" },
+       { NET_IPV4_TCP_KEEPALIVE_PROBES,        "tcp_keepalive_probes" },
+       { NET_IPV4_TCP_RETRIES1,                "tcp_retries1" },
+       { NET_IPV4_TCP_RETRIES2,                "tcp_retries2" },
+       { NET_IPV4_TCP_FIN_TIMEOUT,             "tcp_fin_timeout" },
+       /* NET_IPV4_IP_MASQ_DEBUG unused */
+       { NET_TCP_SYNCOOKIES,                   "tcp_syncookies" },
+       { NET_TCP_STDURG,                       "tcp_stdurg" },
+       { NET_TCP_RFC1337,                      "tcp_rfc1337" },
+       /* NET_TCP_SYN_TAILDROP unused */
+       { NET_TCP_MAX_SYN_BACKLOG,              "tcp_max_syn_backlog" },
+       { NET_IPV4_LOCAL_PORT_RANGE,            "ip_local_port_range" },
+       { NET_IPV4_ICMP_ECHO_IGNORE_ALL,        "icmp_echo_ignore_all" },
+       { NET_IPV4_ICMP_ECHO_IGNORE_BROADCASTS, "icmp_echo_ignore_broadcasts" },
+       /* NET_IPV4_ICMP_SOURCEQUENCH_RATE unused */
+       /* NET_IPV4_ICMP_DESTUNREACH_RATE unused */
+       /* NET_IPV4_ICMP_TIMEEXCEED_RATE unused */
+       /* NET_IPV4_ICMP_PARAMPROB_RATE unused */
+       /* NET_IPV4_ICMP_ECHOREPLY_RATE unused */
+       { NET_IPV4_ICMP_IGNORE_BOGUS_ERROR_RESPONSES,   "icmp_ignore_bogus_error_responses" },
+       { NET_IPV4_IGMP_MAX_MEMBERSHIPS,        "igmp_max_memberships" },
+       { NET_TCP_TW_RECYCLE,                   "tcp_tw_recycle" },
+       /* NET_IPV4_ALWAYS_DEFRAG unused */
+       { NET_IPV4_TCP_KEEPALIVE_INTVL,         "tcp_keepalive_intvl" },
+       { NET_IPV4_INET_PEER_THRESHOLD,         "inet_peer_threshold" },
+       { NET_IPV4_INET_PEER_MINTTL,            "inet_peer_minttl" },
+       { NET_IPV4_INET_PEER_MAXTTL,            "inet_peer_maxttl" },
+       { NET_IPV4_INET_PEER_GC_MINTIME,        "inet_peer_gc_mintime" },
+       { NET_IPV4_INET_PEER_GC_MAXTIME,        "inet_peer_gc_maxtime" },
+       { NET_TCP_ORPHAN_RETRIES,               "tcp_orphan_retries" },
+       { NET_TCP_ABORT_ON_OVERFLOW,            "tcp_abort_on_overflow" },
+       { NET_TCP_SYNACK_RETRIES,               "tcp_synack_retries" },
+       { NET_TCP_MAX_ORPHANS,                  "tcp_max_orphans" },
+       { NET_TCP_MAX_TW_BUCKETS,               "tcp_max_tw_buckets" },
+       { NET_TCP_FACK,                         "tcp_fack" },
+       { NET_TCP_REORDERING,                   "tcp_reordering" },
+       { NET_TCP_ECN,                          "tcp_ecn" },
+       { NET_TCP_DSACK,                        "tcp_dsack" },
+       { NET_TCP_MEM,                          "tcp_mem" },
+       { NET_TCP_WMEM,                         "tcp_wmem" },
+       { NET_TCP_RMEM,                         "tcp_rmem" },
+       { NET_TCP_APP_WIN,                      "tcp_app_win" },
+       { NET_TCP_ADV_WIN_SCALE,                "tcp_adv_win_scale" },
+       { NET_IPV4_NONLOCAL_BIND,               "ip_nonlocal_bind" },
+       { NET_IPV4_ICMP_RATELIMIT,              "icmp_ratelimit" },
+       { NET_IPV4_ICMP_RATEMASK,               "icmp_ratemask" },
+       { NET_TCP_TW_REUSE,                     "tcp_tw_reuse" },
+       { NET_TCP_FRTO,                         "tcp_frto" },
+       { NET_TCP_LOW_LATENCY,                  "tcp_low_latency" },
+       { NET_IPV4_IPFRAG_SECRET_INTERVAL,      "ipfrag_secret_interval" },
+       { NET_IPV4_IGMP_MAX_MSF,                "igmp_max_msf" },
+       { NET_TCP_NO_METRICS_SAVE,              "tcp_no_metrics_save" },
+       /* NET_TCP_DEFAULT_WIN_SCALE unused */
+       { NET_TCP_MODERATE_RCVBUF,              "tcp_moderate_rcvbuf" },
+       { NET_TCP_TSO_WIN_DIVISOR,              "tcp_tso_win_divisor" },
+       /* NET_TCP_BIC_BETA unused */
+       { NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR,      "icmp_errors_use_inbound_ifaddr" },
+       { NET_TCP_CONG_CONTROL,                 "tcp_congestion_control" },
+       { NET_TCP_ABC,                          "tcp_abc" },
+       { NET_IPV4_IPFRAG_MAX_DIST,             "ipfrag_max_dist" },
+       { NET_TCP_MTU_PROBING,                  "tcp_mtu_probing" },
+       { NET_TCP_BASE_MSS,                     "tcp_base_mss" },
+       { NET_IPV4_TCP_WORKAROUND_SIGNED_WINDOWS,       "tcp_workaround_signed_windows" },
+       { NET_TCP_DMA_COPYBREAK,                "tcp_dma_copybreak" },
+       { NET_TCP_SLOW_START_AFTER_IDLE,        "tcp_slow_start_after_idle" },
+       { NET_CIPSOV4_CACHE_ENABLE,             "cipso_cache_enable" },
+       { NET_CIPSOV4_CACHE_BUCKET_SIZE,        "cipso_cache_bucket_size" },
+       { NET_CIPSOV4_RBM_OPTFMT,               "cipso_rbm_optfmt" },
+       { NET_CIPSOV4_RBM_STRICTVALID,          "cipso_rbm_strictvalid" },
+       { NET_TCP_AVAIL_CONG_CONTROL,           "tcp_available_congestion_control" },
+       { NET_TCP_ALLOWED_CONG_CONTROL,         "tcp_allowed_congestion_control" },
+       { NET_TCP_MAX_SSTHRESH,                 "tcp_max_ssthresh" },
+       { NET_TCP_FRTO_RESPONSE,                "tcp_frto_response" },
+       { 2088 /* NET_IPQ_QMAX */,              "ip_queue_maxlen" },
+       {}
+};
+
+static struct trans_ctl_table trans_net_ipx_table[] = {
+       { NET_IPX_PPROP_BROADCASTING,   "ipx_pprop_broadcasting" },
+       /* NET_IPX_FORWARDING unused */
+       {}
+};
+
+static struct trans_ctl_table trans_net_atalk_table[] = {
+       { NET_ATALK_AARP_EXPIRY_TIME,           "aarp-expiry-time" },
+       { NET_ATALK_AARP_TICK_TIME,             "aarp-tick-time" },
+       { NET_ATALK_AARP_RETRANSMIT_LIMIT,      "aarp-retransmit-limit" },
+       { NET_ATALK_AARP_RESOLVE_TIME,          "aarp-resolve-time" },
+       {},
+};
+
+static struct trans_ctl_table trans_net_netrom_table[] = {
+       { NET_NETROM_DEFAULT_PATH_QUALITY,              "default_path_quality" },
+       { NET_NETROM_OBSOLESCENCE_COUNT_INITIALISER,    "obsolescence_count_initialiser" },
+       { NET_NETROM_NETWORK_TTL_INITIALISER,           "network_ttl_initialiser" },
+       { NET_NETROM_TRANSPORT_TIMEOUT,                 "transport_timeout" },
+       { NET_NETROM_TRANSPORT_MAXIMUM_TRIES,           "transport_maximum_tries" },
+       { NET_NETROM_TRANSPORT_ACKNOWLEDGE_DELAY,       "transport_acknowledge_delay" },
+       { NET_NETROM_TRANSPORT_BUSY_DELAY,              "transport_busy_delay" },
+       { NET_NETROM_TRANSPORT_REQUESTED_WINDOW_SIZE,   "transport_requested_window_size" },
+       { NET_NETROM_TRANSPORT_NO_ACTIVITY_TIMEOUT,     "transport_no_activity_timeout" },
+       { NET_NETROM_ROUTING_CONTROL,                   "routing_control" },
+       { NET_NETROM_LINK_FAILS_COUNT,                  "link_fails_count" },
+       { NET_NETROM_RESET,                             "reset" },
+       {}
+};
+
+static struct trans_ctl_table trans_net_ax25_table[] = {
+       { NET_AX25_IP_DEFAULT_MODE,     "ip_default_mode" },
+       { NET_AX25_DEFAULT_MODE,        "ax25_default_mode" },
+       { NET_AX25_BACKOFF_TYPE,        "backoff_type" },
+       { NET_AX25_CONNECT_MODE,        "connect_mode" },
+       { NET_AX25_STANDARD_WINDOW,     "standard_window_size" },
+       { NET_AX25_EXTENDED_WINDOW,     "extended_window_size" },
+       { NET_AX25_T1_TIMEOUT,          "t1_timeout" },
+       { NET_AX25_T2_TIMEOUT,          "t2_timeout" },
+       { NET_AX25_T3_TIMEOUT,          "t3_timeout" },
+       { NET_AX25_IDLE_TIMEOUT,        "idle_timeout" },
+       { NET_AX25_N2,                  "maximum_retry_count" },
+       { NET_AX25_PACLEN,              "maximum_packet_length" },
+       { NET_AX25_PROTOCOL,            "protocol" },
+       { NET_AX25_DAMA_SLAVE_TIMEOUT,  "dama_slave_timeout" },
+       {}
+};
+
+static struct trans_ctl_table trans_net_bridge_table[] = {
+       { NET_BRIDGE_NF_CALL_ARPTABLES,         "bridge-nf-call-arptables" },
+       { NET_BRIDGE_NF_CALL_IPTABLES,          "bridge-nf-call-iptables" },
+       { NET_BRIDGE_NF_CALL_IP6TABLES,         "bridge-nf-call-ip6tables" },
+       { NET_BRIDGE_NF_FILTER_VLAN_TAGGED,     "bridge-nf-filter-vlan-tagged" },
+       { NET_BRIDGE_NF_FILTER_PPPOE_TAGGED,    "bridge-nf-filter-pppoe-tagged" },
+       {}
+};
+
+static struct trans_ctl_table trans_net_rose_table[] = {
+       { NET_ROSE_RESTART_REQUEST_TIMEOUT,     "restart_request_timeout" },
+       { NET_ROSE_CALL_REQUEST_TIMEOUT,        "call_request_timeout" },
+       { NET_ROSE_RESET_REQUEST_TIMEOUT,       "reset_request_timeout" },
+       { NET_ROSE_CLEAR_REQUEST_TIMEOUT,       "clear_request_timeout" },
+       { NET_ROSE_ACK_HOLD_BACK_TIMEOUT,       "acknowledge_hold_back_timeout" },
+       { NET_ROSE_ROUTING_CONTROL,             "routing_control" },
+       { NET_ROSE_LINK_FAIL_TIMEOUT,           "link_fail_timeout" },
+       { NET_ROSE_MAX_VCS,                     "maximum_virtual_circuits" },
+       { NET_ROSE_WINDOW_SIZE,                 "window_size" },
+       { NET_ROSE_NO_ACTIVITY_TIMEOUT,         "no_activity_timeout" },
+       {}
+};
+
+static struct trans_ctl_table trans_net_ipv6_conf_var_table[] = {
+       { NET_IPV6_FORWARDING,                  "forwarding" },
+       { NET_IPV6_HOP_LIMIT,                   "hop_limit" },
+       { NET_IPV6_MTU,                         "mtu" },
+       { NET_IPV6_ACCEPT_RA,                   "accept_ra" },
+       { NET_IPV6_ACCEPT_REDIRECTS,            "accept_redirects" },
+       { NET_IPV6_AUTOCONF,                    "autoconf" },
+       { NET_IPV6_DAD_TRANSMITS,               "dad_transmits" },
+       { NET_IPV6_RTR_SOLICITS,                "router_solicitations" },
+       { NET_IPV6_RTR_SOLICIT_INTERVAL,        "router_solicitation_interval" },
+       { NET_IPV6_RTR_SOLICIT_DELAY,           "router_solicitation_delay" },
+       { NET_IPV6_USE_TEMPADDR,                "use_tempaddr" },
+       { NET_IPV6_TEMP_VALID_LFT,              "temp_valid_lft" },
+       { NET_IPV6_TEMP_PREFERED_LFT,           "temp_prefered_lft" },
+       { NET_IPV6_REGEN_MAX_RETRY,             "regen_max_retry" },
+       { NET_IPV6_MAX_DESYNC_FACTOR,           "max_desync_factor" },
+       { NET_IPV6_MAX_ADDRESSES,               "max_addresses" },
+       { NET_IPV6_FORCE_MLD_VERSION,           "force_mld_version" },
+       { NET_IPV6_ACCEPT_RA_DEFRTR,            "accept_ra_defrtr" },
+       { NET_IPV6_ACCEPT_RA_PINFO,             "accept_ra_pinfo" },
+       { NET_IPV6_ACCEPT_RA_RTR_PREF,          "accept_ra_rtr_pref" },
+       { NET_IPV6_RTR_PROBE_INTERVAL,          "router_probe_interval" },
+       { NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN,  "accept_ra_rt_info_max_plen" },
+       { NET_IPV6_PROXY_NDP,                   "proxy_ndp" },
+       { NET_IPV6_ACCEPT_SOURCE_ROUTE,         "accept_source_route" },
+       {}
+};
+
+static struct trans_ctl_table trans_net_ipv6_conf_table[] = {
+       { NET_PROTO_CONF_ALL,           "all",  trans_net_ipv6_conf_var_table },
+       { NET_PROTO_CONF_DEFAULT,       "default", trans_net_ipv6_conf_var_table },
+       { 0, NULL, trans_net_ipv6_conf_var_table },
+       {}
+};
+
+static struct trans_ctl_table trans_net_ipv6_route_table[] = {
+       { NET_IPV6_ROUTE_FLUSH,                 "flush" },
+       { NET_IPV6_ROUTE_GC_THRESH,             "gc_thresh" },
+       { NET_IPV6_ROUTE_MAX_SIZE,              "max_size" },
+       { NET_IPV6_ROUTE_GC_MIN_INTERVAL,       "gc_min_interval" },
+       { NET_IPV6_ROUTE_GC_TIMEOUT,            "gc_timeout" },
+       { NET_IPV6_ROUTE_GC_INTERVAL,           "gc_interval" },
+       { NET_IPV6_ROUTE_GC_ELASTICITY,         "gc_elasticity" },
+       { NET_IPV6_ROUTE_MTU_EXPIRES,           "mtu_expires" },
+       { NET_IPV6_ROUTE_MIN_ADVMSS,            "min_adv_mss" },
+       { NET_IPV6_ROUTE_GC_MIN_INTERVAL_MS,    "gc_min_interval_ms" },
+       {}
+};
+
+static struct trans_ctl_table trans_net_ipv6_icmp_table[] = {
+       { NET_IPV6_ICMP_RATELIMIT,      "ratelimit" },
+       {}
+};
+
+static struct trans_ctl_table trans_net_ipv6_table[] = {
+       { NET_IPV6_CONF,                "conf",         trans_net_ipv6_conf_table },
+       { NET_IPV6_NEIGH,               "neigh",        trans_net_neigh_table },
+       { NET_IPV6_ROUTE,               "route",        trans_net_ipv6_route_table },
+       { NET_IPV6_ICMP,                "icmp",         trans_net_ipv6_icmp_table },
+       { NET_IPV6_BINDV6ONLY,          "bindv6only" },
+       { NET_IPV6_IP6FRAG_HIGH_THRESH, "ip6frag_high_thresh" },
+       { NET_IPV6_IP6FRAG_LOW_THRESH,  "ip6frag_low_thresh" },
+       { NET_IPV6_IP6FRAG_TIME,        "ip6frag_time" },
+       { NET_IPV6_IP6FRAG_SECRET_INTERVAL,     "ip6frag_secret_interval" },
+       { NET_IPV6_MLD_MAX_MSF,         "mld_max_msf" },
+       { 2088 /* IPQ_QMAX */,          "ip6_queue_maxlen" },
+       {}
+};
+
+static struct trans_ctl_table trans_net_x25_table[] = {
+       { NET_X25_RESTART_REQUEST_TIMEOUT,      "restart_request_timeout" },
+       { NET_X25_CALL_REQUEST_TIMEOUT,         "call_request_timeout" },
+       { NET_X25_RESET_REQUEST_TIMEOUT,        "reset_request_timeout" },
+       { NET_X25_CLEAR_REQUEST_TIMEOUT,        "clear_request_timeout" },
+       { NET_X25_ACK_HOLD_BACK_TIMEOUT,        "acknowledgement_hold_back_timeout" },
+       { NET_X25_FORWARD,                      "x25_forward" },
+       {}
+};
+
+static struct trans_ctl_table trans_net_tr_table[] = {
+       { NET_TR_RIF_TIMEOUT,   "rif_timeout" },
+       {}
+};
+
+
+static struct trans_ctl_table trans_net_decnet_conf_vars[] = {
+       { NET_DECNET_CONF_DEV_FORWARDING,       "forwarding" },
+       { NET_DECNET_CONF_DEV_PRIORITY,         "priority" },
+       { NET_DECNET_CONF_DEV_T2,               "t2" },
+       { NET_DECNET_CONF_DEV_T3,               "t3" },
+       {}
+};
+
+static struct trans_ctl_table trans_net_decnet_conf[] = {
+       { 0, NULL, trans_net_decnet_conf_vars },
+       {}
+};
+
+static struct trans_ctl_table trans_net_decnet_table[] = {
+       { NET_DECNET_CONF,              "conf", trans_net_decnet_conf },
+       { NET_DECNET_NODE_ADDRESS,      "node_address" },
+       { NET_DECNET_NODE_NAME,         "node_name" },
+       { NET_DECNET_DEFAULT_DEVICE,    "default_device" },
+       { NET_DECNET_TIME_WAIT,         "time_wait" },
+       { NET_DECNET_DN_COUNT,          "dn_count" },
+       { NET_DECNET_DI_COUNT,          "di_count" },
+       { NET_DECNET_DR_COUNT,          "dr_count" },
+       { NET_DECNET_DST_GC_INTERVAL,   "dst_gc_interval" },
+       { NET_DECNET_NO_FC_MAX_CWND,    "no_fc_max_cwnd" },
+       { NET_DECNET_MEM,               "decnet_mem" },
+       { NET_DECNET_RMEM,              "decnet_rmem" },
+       { NET_DECNET_WMEM,              "decnet_wmem" },
+       { NET_DECNET_DEBUG_LEVEL,       "debug" },
+       {}
+};
+
+static struct trans_ctl_table trans_net_sctp_table[] = {
+       { NET_SCTP_RTO_INITIAL,         "rto_initial" },
+       { NET_SCTP_RTO_MIN,             "rto_min" },
+       { NET_SCTP_RTO_MAX,             "rto_max" },
+       { NET_SCTP_RTO_ALPHA,           "rto_alpha_exp_divisor" },
+       { NET_SCTP_RTO_BETA,            "rto_beta_exp_divisor" },
+       { NET_SCTP_VALID_COOKIE_LIFE,   "valid_cookie_life" },
+       { NET_SCTP_ASSOCIATION_MAX_RETRANS,     "association_max_retrans" },
+       { NET_SCTP_PATH_MAX_RETRANS,    "path_max_retrans" },
+       { NET_SCTP_MAX_INIT_RETRANSMITS,        "max_init_retransmits" },
+       { NET_SCTP_HB_INTERVAL,         "hb_interval" },
+       { NET_SCTP_PRESERVE_ENABLE,     "cookie_preserve_enable" },
+       { NET_SCTP_MAX_BURST,           "max_burst" },
+       { NET_SCTP_ADDIP_ENABLE,        "addip_enable" },
+       { NET_SCTP_PRSCTP_ENABLE,       "prsctp_enable" },
+       { NET_SCTP_SNDBUF_POLICY,       "sndbuf_policy" },
+       { NET_SCTP_SACK_TIMEOUT,        "sack_timeout" },
+       { NET_SCTP_RCVBUF_POLICY,       "rcvbuf_policy" },
+       {}
+};
+
+static struct trans_ctl_table trans_net_llc_llc2_timeout_table[] = {
+       { NET_LLC2_ACK_TIMEOUT,         "ack" },
+       { NET_LLC2_P_TIMEOUT,           "p" },
+       { NET_LLC2_REJ_TIMEOUT,         "rej" },
+       { NET_LLC2_BUSY_TIMEOUT,        "busy" },
+       {}
+};
+
+static struct trans_ctl_table trans_net_llc_station_table[] = {
+       { NET_LLC_STATION_ACK_TIMEOUT,  "ack_timeout" },
+       {}
+};
+
+static struct trans_ctl_table trans_net_llc_llc2_table[] = {
+       { NET_LLC2,             "timeout",      trans_net_llc_llc2_timeout_table },
+       {}
+};
+
+static struct trans_ctl_table trans_net_llc_table[] = {
+       { NET_LLC2,             "llc2",         trans_net_llc_llc2_table },
+       { NET_LLC_STATION,      "station",      trans_net_llc_station_table },
+       {}
+};
+
+static struct trans_ctl_table trans_net_netfilter_table[] = {
+       { NET_NF_CONNTRACK_MAX,                         "nf_conntrack_max" },
+       { NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT,        "nf_conntrack_tcp_timeout_syn_sent" },
+       { NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV,        "nf_conntrack_tcp_timeout_syn_recv" },
+       { NET_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED,     "nf_conntrack_tcp_timeout_established" },
+       { NET_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT,        "nf_conntrack_tcp_timeout_fin_wait" },
+       { NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT,      "nf_conntrack_tcp_timeout_close_wait" },
+       { NET_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK,        "nf_conntrack_tcp_timeout_last_ack" },
+       { NET_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT,       "nf_conntrack_tcp_timeout_time_wait" },
+       { NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE,           "nf_conntrack_tcp_timeout_close" },
+       { NET_NF_CONNTRACK_UDP_TIMEOUT,                 "nf_conntrack_udp_timeout" },
+       { NET_NF_CONNTRACK_UDP_TIMEOUT_STREAM,          "nf_conntrack_udp_timeout_stream" },
+       { NET_NF_CONNTRACK_ICMP_TIMEOUT,        "nf_conntrack_icmp_timeout" },
+       { NET_NF_CONNTRACK_GENERIC_TIMEOUT,             "nf_conntrack_generic_timeout" },
+       { NET_NF_CONNTRACK_BUCKETS,                     "nf_conntrack_buckets" },
+       { NET_NF_CONNTRACK_LOG_INVALID,                 "nf_conntrack_log_invalid" },
+       { NET_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS,     "nf_conntrack_tcp_timeout_max_retrans" },
+       { NET_NF_CONNTRACK_TCP_LOOSE,                   "nf_conntrack_tcp_loose" },
+       { NET_NF_CONNTRACK_TCP_BE_LIBERAL,              "nf_conntrack_tcp_be_liberal" },
+       { NET_NF_CONNTRACK_TCP_MAX_RETRANS,             "nf_conntrack_tcp_max_retrans" },
+       { NET_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED,         "nf_conntrack_sctp_timeout_closed" },
+       { NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT,    "nf_conntrack_sctp_timeout_cookie_wait" },
+       { NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED,  "nf_conntrack_sctp_timeout_cookie_echoed" },
+       { NET_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED,    "nf_conntrack_sctp_timeout_established" },
+       { NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT,  "nf_conntrack_sctp_timeout_shutdown_sent" },
+       { NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD,  "nf_conntrack_sctp_timeout_shutdown_recd" },
+       { NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT,      "nf_conntrack_sctp_timeout_shutdown_ack_sent" },
+       { NET_NF_CONNTRACK_COUNT,                       "nf_conntrack_count" },
+       { NET_NF_CONNTRACK_ICMPV6_TIMEOUT,      "nf_conntrack_icmpv6_timeout" },
+       { NET_NF_CONNTRACK_FRAG6_TIMEOUT,               "nf_conntrack_frag6_timeout" },
+       { NET_NF_CONNTRACK_FRAG6_LOW_THRESH,            "nf_conntrack_frag6_low_thresh" },
+       { NET_NF_CONNTRACK_FRAG6_HIGH_THRESH,           "nf_conntrack_frag6_high_thresh" },
+       { NET_NF_CONNTRACK_CHECKSUM,                    "nf_conntrack_checksum" },
+
+       {}
+};
+
+static struct trans_ctl_table trans_net_dccp_table[] = {
+       { NET_DCCP_DEFAULT,     "default" },
+       {}
+};
+
+static struct trans_ctl_table trans_net_irda_table[] = {
+       { NET_IRDA_DISCOVERY,           "discovery" },
+       { NET_IRDA_DEVNAME,             "devname" },
+       { NET_IRDA_DEBUG,               "debug" },
+       { NET_IRDA_FAST_POLL,           "fast_poll_increase" },
+       { NET_IRDA_DISCOVERY_SLOTS,     "discovery_slots" },
+       { NET_IRDA_DISCOVERY_TIMEOUT,   "discovery_timeout" },
+       { NET_IRDA_SLOT_TIMEOUT,        "slot_timeout" },
+       { NET_IRDA_MAX_BAUD_RATE,       "max_baud_rate" },
+       { NET_IRDA_MIN_TX_TURN_TIME,    "min_tx_turn_time" },
+       { NET_IRDA_MAX_TX_DATA_SIZE,    "max_tx_data_size" },
+       { NET_IRDA_MAX_TX_WINDOW,       "max_tx_window" },
+       { NET_IRDA_MAX_NOREPLY_TIME,    "max_noreply_time" },
+       { NET_IRDA_WARN_NOREPLY_TIME,   "warn_noreply_time" },
+       { NET_IRDA_LAP_KEEPALIVE_TIME,  "lap_keepalive_time" },
+       {}
+};
+
+static struct trans_ctl_table trans_net_table[] = {
+       { NET_CORE,             "core",         trans_net_core_table },
+       /* NET_ETHER not used */
+       /* NET_802 not used */
+       { NET_UNIX,             "unix",         trans_net_unix_table },
+       { NET_IPV4,             "ipv4",         trans_net_ipv4_table },
+       { NET_IPX,              "ipx",          trans_net_ipx_table },
+       { NET_ATALK,            "appletalk",    trans_net_atalk_table },
+       { NET_NETROM,           "netrom",       trans_net_netrom_table },
+       { NET_AX25,             "ax25",         trans_net_ax25_table },
+       { NET_BRIDGE,           "bridge",       trans_net_bridge_table },
+       { NET_ROSE,             "rose",         trans_net_rose_table },
+       { NET_IPV6,             "ipv6",         trans_net_ipv6_table },
+       { NET_X25,              "x25",          trans_net_x25_table },
+       { NET_TR,               "tr",           trans_net_tr_table },
+       { NET_DECNET,           "decnet",       trans_net_decnet_table },
+       /*  NET_ECONET not used */
+       { NET_SCTP,             "sctp",         trans_net_sctp_table },
+       { NET_LLC,              "llc",          trans_net_llc_table },
+       { NET_NETFILTER,        "netfilter",    trans_net_netfilter_table },
+       { NET_DCCP,             "dccp",         trans_net_dccp_table },
+       { NET_IRDA,             "irda",         trans_net_irda_table },
+       { 2089,                 "nf_conntrack_max" },
+       {}
+};
+
+static struct trans_ctl_table trans_fs_quota_table[] = {
+       { FS_DQ_LOOKUPS,        "lookups" },
+       { FS_DQ_DROPS,          "drops" },
+       { FS_DQ_READS,          "reads" },
+       { FS_DQ_WRITES,         "writes" },
+       { FS_DQ_CACHE_HITS,     "cache_hits" },
+       { FS_DQ_ALLOCATED,      "allocated_dquots" },
+       { FS_DQ_FREE,           "free_dquots" },
+       { FS_DQ_SYNCS,          "syncs" },
+       { FS_DQ_WARNINGS,       "warnings" },
+       {}
+};
+
+static struct trans_ctl_table trans_fs_xfs_table[] = {
+       { XFS_RESTRICT_CHOWN,   "restrict_chown" },
+       { XFS_SGID_INHERIT,     "irix_sgid_inherit" },
+       { XFS_SYMLINK_MODE,     "irix_symlink_mode" },
+       { XFS_PANIC_MASK,       "panic_mask" },
+
+       { XFS_ERRLEVEL,         "error_level" },
+       { XFS_SYNCD_TIMER,      "xfssyncd_centisecs" },
+       { XFS_INHERIT_SYNC,     "inherit_sync" },
+       { XFS_INHERIT_NODUMP,   "inherit_nodump" },
+       { XFS_INHERIT_NOATIME,  "inherit_noatime" },
+       { XFS_BUF_TIMER,        "xfsbufd_centisecs" },
+       { XFS_BUF_AGE,          "age_buffer_centisecs" },
+       { XFS_INHERIT_NOSYM,    "inherit_nosymlinks" },
+       { XFS_ROTORSTEP,        "rotorstep" },
+       { XFS_INHERIT_NODFRG,   "inherit_nodefrag" },
+       { XFS_FILESTREAM_TIMER, "filestream_centisecs" },
+       { XFS_STATS_CLEAR,      "stats_clear" },
+       {}
+};
+
+static struct trans_ctl_table trans_fs_ocfs2_nm_table[] = {
+       { 1, "hb_ctl_path" },
+       {}
+};
+
+static struct trans_ctl_table trans_fs_ocfs2_table[] = {
+       { 1,    "nm",   trans_fs_ocfs2_nm_table },
+       {}
+};
+
+static struct trans_ctl_table trans_inotify_table[] = {
+       { INOTIFY_MAX_USER_INSTANCES,   "max_user_instances" },
+       { INOTIFY_MAX_USER_WATCHES,     "max_user_watches" },
+       { INOTIFY_MAX_QUEUED_EVENTS,    "max_queued_events" },
+       {}
+};
+
+static struct trans_ctl_table trans_fs_table[] = {
+       { FS_NRINODE,           "inode-nr" },
+       { FS_STATINODE,         "inode-state" },
+       /* FS_MAXINODE unused */
+       /* FS_NRDQUOT unused */
+       /* FS_MAXDQUOT unused */
+       { FS_NRFILE,            "file-nr" },
+       { FS_MAXFILE,           "file-max" },
+       { FS_DENTRY,            "dentry-state" },
+       /* FS_NRSUPER unused */
+       /* FS_MAXUPSER unused */
+       { FS_OVERFLOWUID,       "overflowuid" },
+       { FS_OVERFLOWGID,       "overflowgid" },
+       { FS_LEASES,            "leases-enable" },
+       { FS_DIR_NOTIFY,        "dir-notify-enable" },
+       { FS_LEASE_TIME,        "lease-break-time" },
+       { FS_DQSTATS,           "quota",                trans_fs_quota_table },
+       { FS_XFS,               "xfs",                  trans_fs_xfs_table },
+       { FS_AIO_NR,            "aio-nr" },
+       { FS_AIO_MAX_NR,        "aio-max-nr" },
+       { FS_INOTIFY,           "inotify",              trans_inotify_table },
+       { FS_OCFS2,             "ocfs2",                trans_fs_ocfs2_table },
+       { KERN_SETUID_DUMPABLE, "suid_dumpable" },
+       {}
+};
+
+static struct trans_ctl_table trans_debug_table[] = {
+       {}
+};
+
+static struct trans_ctl_table trans_cdrom_table[] = {
+       { DEV_CDROM_INFO,               "info" },
+       { DEV_CDROM_AUTOCLOSE,          "autoclose" },
+       { DEV_CDROM_AUTOEJECT,          "autoeject" },
+       { DEV_CDROM_DEBUG,              "debug" },
+       { DEV_CDROM_LOCK,               "lock" },
+       { DEV_CDROM_CHECK_MEDIA,        "check_media" },
+       {}
+};
+
+static struct trans_ctl_table trans_ipmi_table[] = {
+       { DEV_IPMI_POWEROFF_POWERCYCLE, "poweroff_powercycle" },
+       {}
+};
+
+static struct trans_ctl_table trans_mac_hid_files[] = {
+       /* DEV_MAC_HID_KEYBOARD_SENDS_LINUX_KEYCODES unused */
+       /* DEV_MAC_HID_KEYBOARD_LOCK_KEYCODES unused */
+       { DEV_MAC_HID_MOUSE_BUTTON_EMULATION,   "mouse_button_emulation" },
+       { DEV_MAC_HID_MOUSE_BUTTON2_KEYCODE,    "mouse_button2_keycode" },
+       { DEV_MAC_HID_MOUSE_BUTTON3_KEYCODE,    "mouse_button3_keycode" },
+       /* DEV_MAC_HID_ADB_MOUSE_SENDS_KEYCODES unused */
+       {}
+};
+
+static struct trans_ctl_table trans_raid_table[] = {
+       { DEV_RAID_SPEED_LIMIT_MIN,     "speed_limit_min" },
+       { DEV_RAID_SPEED_LIMIT_MAX,     "speed_limit_max" },
+       {}
+};
+
+static struct trans_ctl_table trans_scsi_table[] = {
+       { DEV_SCSI_LOGGING_LEVEL, "logging_level" },
+       {}
+};
+
+static struct trans_ctl_table trans_parport_default_table[] = {
+       { DEV_PARPORT_DEFAULT_TIMESLICE,        "timeslice" },
+       { DEV_PARPORT_DEFAULT_SPINTIME,         "spintime" },
+       {}
+};
+
+static struct trans_ctl_table trans_parport_device_table[] = {
+       { DEV_PARPORT_DEVICE_TIMESLICE,         "timeslice" },
+       {}
+};
+
+static struct trans_ctl_table trans_parport_devices_table[] = {
+       { DEV_PARPORT_DEVICES_ACTIVE,           "active" },
+       { 0, NULL, trans_parport_device_table },
+       {}
+};
+
+static struct trans_ctl_table trans_parport_parport_table[] = {
+       { DEV_PARPORT_SPINTIME,         "spintime" },
+       { DEV_PARPORT_BASE_ADDR,        "base-addr" },
+       { DEV_PARPORT_IRQ,              "irq" },
+       { DEV_PARPORT_DMA,              "dma" },
+       { DEV_PARPORT_MODES,            "modes" },
+       { DEV_PARPORT_DEVICES,          "devices",      trans_parport_devices_table },
+       { DEV_PARPORT_AUTOPROBE,        "autoprobe" },
+       { DEV_PARPORT_AUTOPROBE + 1,    "autoprobe0" },
+       { DEV_PARPORT_AUTOPROBE + 2,    "autoprobe1" },
+       { DEV_PARPORT_AUTOPROBE + 3,    "autoprobe2" },
+       { DEV_PARPORT_AUTOPROBE + 4,    "autoprobe3" },
+       {}
+};
+static struct trans_ctl_table trans_parport_table[] = {
+       { DEV_PARPORT_DEFAULT,  "default",      trans_parport_default_table },
+       { 0, NULL, trans_parport_parport_table },
+       {}
+};
+
+static struct trans_ctl_table trans_dev_table[] = {
+       { DEV_CDROM,    "cdrom",        trans_cdrom_table },
+       /* DEV_HWMON unused */
+       { DEV_PARPORT,  "parport",      trans_parport_table },
+       { DEV_RAID,     "raid",         trans_raid_table },
+       { DEV_MAC_HID,  "mac_hid",      trans_mac_hid_files },
+       { DEV_SCSI,     "scsi",         trans_scsi_table },
+       { DEV_IPMI,     "ipmi",         trans_ipmi_table },
+       {}
+};
+
+static struct trans_ctl_table trans_bus_isa_table[] = {
+       { BUS_ISA_MEM_BASE,     "membase" },
+       { BUS_ISA_PORT_BASE,    "portbase" },
+       { BUS_ISA_PORT_SHIFT,   "portshift" },
+       {}
+};
+
+static struct trans_ctl_table trans_bus_table[] = {
+       { CTL_BUS_ISA,  "isa",  trans_bus_isa_table },
+       {}
+};
+
+static struct trans_ctl_table trans_arlan_conf_table0[] = {
+       { 1,    "spreadingCode" },
+       { 2,    "channelNumber" },
+       { 3,    "scramblingDisable" },
+       { 4,    "txAttenuation" },
+       { 5,    "systemId" },
+       { 6,    "maxDatagramSize" },
+       { 7,    "maxFrameSize" },
+       { 8,    "maxRetries" },
+       { 9,    "receiveMode" },
+       { 10,   "priority" },
+       { 11,   "rootOrRepeater" },
+       { 12,   "SID" },
+       { 13,   "registrationMode" },
+       { 14,   "registrationFill" },
+       { 15,   "localTalkAddress" },
+       { 16,   "codeFormat" },
+       { 17,   "numChannels" },
+       { 18,   "channel1" },
+       { 19,   "channel2" },
+       { 20,   "channel3" },
+       { 21,   "channel4" },
+       { 22,   "txClear" },
+       { 23,   "txRetries" },
+       { 24,   "txRouting" },
+       { 25,   "txScrambled" },
+       { 26,   "rxParameter" },
+       { 27,   "txTimeoutMs" },
+       { 28,   "waitCardTimeout" },
+       { 29,   "channelSet" },
+       { 30,   "name" },
+       { 31,   "waitTime" },
+       { 32,   "lParameter" },
+       { 33,   "_15" },
+       { 34,   "headerSize" },
+       { 36,   "tx_delay_ms" },
+       { 37,   "retries" },
+       { 38,   "ReTransmitPacketMaxSize" },
+       { 39,   "waitReTransmitPacketMaxSize" },
+       { 40,   "fastReTransCount" },
+       { 41,   "driverRetransmissions" },
+       { 42,   "txAckTimeoutMs" },
+       { 43,   "registrationInterrupts" },
+       { 44,   "hardwareType" },
+       { 45,   "radioType" },
+       { 46,   "writeEEPROM" },
+       { 47,   "writeRadioType" },
+       { 48,   "entry_exit_debug" },
+       { 49,   "debug" },
+       { 50,   "in_speed" },
+       { 51,   "out_speed" },
+       { 52,   "in_speed10" },
+       { 53,   "out_speed10" },
+       { 54,   "in_speed_max" },
+       { 55,   "out_speed_max" },
+       { 56,   "measure_rate" },
+       { 57,   "pre_Command_Wait" },
+       { 58,   "rx_tweak1" },
+       { 59,   "rx_tweak2" },
+       { 60,   "tx_queue_len" },
+
+       { 150,  "arlan0-txRing" },
+       { 151,  "arlan0-rxRing" },
+       { 152,  "arlan0-18" },
+       { 153,  "arlan0-ring" },
+       { 154,  "arlan0-shm-cpy" },
+       { 155,  "config0" },
+       { 156,  "reset0" },
+       {}
+};
+
+static struct trans_ctl_table trans_arlan_conf_table1[] = {
+       { 1,    "spreadingCode" },
+       { 2,    "channelNumber" },
+       { 3,    "scramblingDisable" },
+       { 4,    "txAttenuation" },
+       { 5,    "systemId" },
+       { 6,    "maxDatagramSize" },
+       { 7,    "maxFrameSize" },
+       { 8,    "maxRetries" },
+       { 9,    "receiveMode" },
+       { 10,   "priority" },
+       { 11,   "rootOrRepeater" },
+       { 12,   "SID" },
+       { 13,   "registrationMode" },
+       { 14,   "registrationFill" },
+       { 15,   "localTalkAddress" },
+       { 16,   "codeFormat" },
+       { 17,   "numChannels" },
+       { 18,   "channel1" },
+       { 19,   "channel2" },
+       { 20,   "channel3" },
+       { 21,   "channel4" },
+       { 22,   "txClear" },
+       { 23,   "txRetries" },
+       { 24,   "txRouting" },
+       { 25,   "txScrambled" },
+       { 26,   "rxParameter" },
+       { 27,   "txTimeoutMs" },
+       { 28,   "waitCardTimeout" },
+       { 29,   "channelSet" },
+       { 30,   "name" },
+       { 31,   "waitTime" },
+       { 32,   "lParameter" },
+       { 33,   "_15" },
+       { 34,   "headerSize" },
+       { 36,   "tx_delay_ms" },
+       { 37,   "retries" },
+       { 38,   "ReTransmitPacketMaxSize" },
+       { 39,   "waitReTransmitPacketMaxSize" },
+       { 40,   "fastReTransCount" },
+       { 41,   "driverRetransmissions" },
+       { 42,   "txAckTimeoutMs" },
+       { 43,   "registrationInterrupts" },
+       { 44,   "hardwareType" },
+       { 45,   "radioType" },
+       { 46,   "writeEEPROM" },
+       { 47,   "writeRadioType" },
+       { 48,   "entry_exit_debug" },
+       { 49,   "debug" },
+       { 50,   "in_speed" },
+       { 51,   "out_speed" },
+       { 52,   "in_speed10" },
+       { 53,   "out_speed10" },
+       { 54,   "in_speed_max" },
+       { 55,   "out_speed_max" },
+       { 56,   "measure_rate" },
+       { 57,   "pre_Command_Wait" },
+       { 58,   "rx_tweak1" },
+       { 59,   "rx_tweak2" },
+       { 60,   "tx_queue_len" },
+
+       { 150,  "arlan1-txRing" },
+       { 151,  "arlan1-rxRing" },
+       { 152,  "arlan1-18" },
+       { 153,  "arlan1-ring" },
+       { 154,  "arlan1-shm-cpy" },
+       { 155,  "config1" },
+       { 156,  "reset1" },
+       {}
+};
+
+static struct trans_ctl_table trans_arlan_conf_table2[] = {
+       { 1,    "spreadingCode" },
+       { 2,    "channelNumber" },
+       { 3,    "scramblingDisable" },
+       { 4,    "txAttenuation" },
+       { 5,    "systemId" },
+       { 6,    "maxDatagramSize" },
+       { 7,    "maxFrameSize" },
+       { 8,    "maxRetries" },
+       { 9,    "receiveMode" },
+       { 10,   "priority" },
+       { 11,   "rootOrRepeater" },
+       { 12,   "SID" },
+       { 13,   "registrationMode" },
+       { 14,   "registrationFill" },
+       { 15,   "localTalkAddress" },
+       { 16,   "codeFormat" },
+       { 17,   "numChannels" },
+       { 18,   "channel1" },
+       { 19,   "channel2" },
+       { 20,   "channel3" },
+       { 21,   "channel4" },
+       { 22,   "txClear" },
+       { 23,   "txRetries" },
+       { 24,   "txRouting" },
+       { 25,   "txScrambled" },
+       { 26,   "rxParameter" },
+       { 27,   "txTimeoutMs" },
+       { 28,   "waitCardTimeout" },
+       { 29,   "channelSet" },
+       { 30,   "name" },
+       { 31,   "waitTime" },
+       { 32,   "lParameter" },
+       { 33,   "_15" },
+       { 34,   "headerSize" },
+       { 36,   "tx_delay_ms" },
+       { 37,   "retries" },
+       { 38,   "ReTransmitPacketMaxSize" },
+       { 39,   "waitReTransmitPacketMaxSize" },
+       { 40,   "fastReTransCount" },
+       { 41,   "driverRetransmissions" },
+       { 42,   "txAckTimeoutMs" },
+       { 43,   "registrationInterrupts" },
+       { 44,   "hardwareType" },
+       { 45,   "radioType" },
+       { 46,   "writeEEPROM" },
+       { 47,   "writeRadioType" },
+       { 48,   "entry_exit_debug" },
+       { 49,   "debug" },
+       { 50,   "in_speed" },
+       { 51,   "out_speed" },
+       { 52,   "in_speed10" },
+       { 53,   "out_speed10" },
+       { 54,   "in_speed_max" },
+       { 55,   "out_speed_max" },
+       { 56,   "measure_rate" },
+       { 57,   "pre_Command_Wait" },
+       { 58,   "rx_tweak1" },
+       { 59,   "rx_tweak2" },
+       { 60,   "tx_queue_len" },
+
+       { 150,  "arlan2-txRing" },
+       { 151,  "arlan2-rxRing" },
+       { 152,  "arlan2-18" },
+       { 153,  "arlan2-ring" },
+       { 154,  "arlan2-shm-cpy" },
+       { 155,  "config2" },
+       { 156,  "reset2" },
+       {}
+};
+
+static struct trans_ctl_table trans_arlan_conf_table3[] = {
+       { 1,    "spreadingCode" },
+       { 2,    "channelNumber" },
+       { 3,    "scramblingDisable" },
+       { 4,    "txAttenuation" },
+       { 5,    "systemId" },
+       { 6,    "maxDatagramSize" },
+       { 7,    "maxFrameSize" },
+       { 8,    "maxRetries" },
+       { 9,    "receiveMode" },
+       { 10,   "priority" },
+       { 11,   "rootOrRepeater" },
+       { 12,   "SID" },
+       { 13,   "registrationMode" },
+       { 14,   "registrationFill" },
+       { 15,   "localTalkAddress" },
+       { 16,   "codeFormat" },
+       { 17,   "numChannels" },
+       { 18,   "channel1" },
+       { 19,   "channel2" },
+       { 20,   "channel3" },
+       { 21,   "channel4" },
+       { 22,   "txClear" },
+       { 23,   "txRetries" },
+       { 24,   "txRouting" },
+       { 25,   "txScrambled" },
+       { 26,   "rxParameter" },
+       { 27,   "txTimeoutMs" },
+       { 28,   "waitCardTimeout" },
+       { 29,   "channelSet" },
+       { 30,   "name" },
+       { 31,   "waitTime" },
+       { 32,   "lParameter" },
+       { 33,   "_15" },
+       { 34,   "headerSize" },
+       { 36,   "tx_delay_ms" },
+       { 37,   "retries" },
+       { 38,   "ReTransmitPacketMaxSize" },
+       { 39,   "waitReTransmitPacketMaxSize" },
+       { 40,   "fastReTransCount" },
+       { 41,   "driverRetransmissions" },
+       { 42,   "txAckTimeoutMs" },
+       { 43,   "registrationInterrupts" },
+       { 44,   "hardwareType" },
+       { 45,   "radioType" },
+       { 46,   "writeEEPROM" },
+       { 47,   "writeRadioType" },
+       { 48,   "entry_exit_debug" },
+       { 49,   "debug" },
+       { 50,   "in_speed" },
+       { 51,   "out_speed" },
+       { 52,   "in_speed10" },
+       { 53,   "out_speed10" },
+       { 54,   "in_speed_max" },
+       { 55,   "out_speed_max" },
+       { 56,   "measure_rate" },
+       { 57,   "pre_Command_Wait" },
+       { 58,   "rx_tweak1" },
+       { 59,   "rx_tweak2" },
+       { 60,   "tx_queue_len" },
+
+       { 150,  "arlan3-txRing" },
+       { 151,  "arlan3-rxRing" },
+       { 152,  "arlan3-18" },
+       { 153,  "arlan3-ring" },
+       { 154,  "arlan3-shm-cpy" },
+       { 155,  "config3" },
+       { 156,  "reset3" },
+       {}
+};
+
+static struct trans_ctl_table trans_arlan_table[] = {
+       { 1,            "arlan0",       trans_arlan_conf_table0 },
+       { 2,            "arlan1",       trans_arlan_conf_table1 },
+       { 3,            "arlan2",       trans_arlan_conf_table2 },
+       { 4,            "arlan3",       trans_arlan_conf_table3 },
+       {}
+};
+
+static struct trans_ctl_table trans_appldata_table[] = {
+       { CTL_APPLDATA_TIMER,           "timer" },
+       { CTL_APPLDATA_INTERVAL,        "interval" },
+       { CTL_APPLDATA_OS,              "os" },
+       { CTL_APPLDATA_NET_SUM,         "net_sum" },
+       { CTL_APPLDATA_MEM,             "mem" },
+       {}
+
+};
+
+static struct trans_ctl_table trans_s390dbf_table[] = {
+       { 5678 /* CTL_S390DBF_STOPPABLE */,     "debug_stoppable" },
+       { 5679 /* CTL_S390DBF_ACTIVE */,        "debug_active" },
+       {}
+};
+
+static struct trans_ctl_table trans_sunrpc_table[] = {
+       { CTL_RPCDEBUG,         "rpc_debug" },
+       { CTL_NFSDEBUG,         "nfs_debug" },
+       { CTL_NFSDDEBUG,        "nfsd_debug" },
+       { CTL_NLMDEBUG,         "nlm_debug" },
+       { CTL_SLOTTABLE_UDP,    "udp_slot_table_entries" },
+       { CTL_SLOTTABLE_TCP,    "tcp_slot_table_entries" },
+       { CTL_MIN_RESVPORT,     "min_resvport" },
+       { CTL_MAX_RESVPORT,     "max_resvport" },
+       {}
+};
+
+static struct trans_ctl_table trans_pm_table[] = {
+       { 1 /* CTL_PM_SUSPEND */,       "suspend" },
+       { 2 /* CTL_PM_CMODE */,         "cmode" },
+       { 3 /* CTL_PM_P0 */,            "p0" },
+       { 4 /* CTL_PM_CM */,            "cm" },
+       {}
+};
+
+static struct trans_ctl_table trans_frv_table[] = {
+       { 1,    "cache-mode" },
+       { 2,    "pin-cxnr" },
+       {}
+};
+
+static struct trans_ctl_table trans_root_table[] = {
+       { CTL_KERN,     "kernel",       trans_kern_table },
+       { CTL_VM,       "vm",           trans_vm_table },
+       { CTL_NET,      "net",          trans_net_table },
+       /* CTL_PROC not used */
+       { CTL_FS,       "fs",           trans_fs_table },
+       { CTL_DEBUG,    "debug",        trans_debug_table },
+       { CTL_DEV,      "dev",          trans_dev_table },
+       { CTL_BUS,      "bus",          trans_bus_table },
+       { CTL_ABI,      "abi" },
+       /* CTL_CPU not used */
+       { CTL_ARLAN,    "arlan",        trans_arlan_table },
+       { CTL_APPLDATA, "appldata",     trans_appldata_table },
+       { CTL_S390DBF,  "s390dbf",      trans_s390dbf_table },
+       { CTL_SUNRPC,   "sunrpc",       trans_sunrpc_table },
+       { CTL_PM,       "pm",           trans_pm_table },
+       { CTL_FRV,      "frv",          trans_frv_table },
+       {}
+};
+
+
+
+
+static int sysctl_depth(struct ctl_table *table)
+{
+       struct ctl_table *tmp;
+       int depth;
+
+       depth = 0;
+       for (tmp = table; tmp->parent; tmp = tmp->parent)
+               depth++;
+
+       return depth;
+}
+
+static struct ctl_table *sysctl_parent(struct ctl_table *table, int n)
+{
+       int i;
+
+       for (i = 0; table && i < n; i++)
+               table = table->parent;
+
+       return table;
+}
+
+static struct trans_ctl_table *sysctl_binary_lookup(struct ctl_table *table)
+{
+       struct ctl_table *test;
+       struct trans_ctl_table *ref;
+       int depth, cur_depth;
+
+       depth = sysctl_depth(table);
+
+       cur_depth = depth;
+       ref = trans_root_table;
+repeat:
+       test = sysctl_parent(table, cur_depth);
+       for (; ref->ctl_name || ref->procname || ref->child; ref++) {
+               int match = 0;
+
+               if (cur_depth && !ref->child)
+                       continue;
+
+               if (test->procname && ref->procname &&
+                       (strcmp(test->procname, ref->procname) == 0))
+                       match++;
+
+               if (test->ctl_name && ref->ctl_name &&
+                       (test->ctl_name == ref->ctl_name))
+                       match++;
+
+               if (!ref->ctl_name && !ref->procname)
+                       match++;
+
+               if (match) {
+                       if (cur_depth != 0) {
+                               cur_depth--;
+                               ref = ref->child;
+                               goto repeat;
+                       }
+                       goto out;
+               }
+       }
+       ref = NULL;
+out:
+       return ref;
+}
+
+static void sysctl_print_path(struct ctl_table *table)
+{
+       struct ctl_table *tmp;
+       int depth, i;
+       depth = sysctl_depth(table);
+       if (table->procname) {
+               for (i = depth; i >= 0; i--) {
+                       tmp = sysctl_parent(table, i);
+                       printk("/%s", tmp->procname?tmp->procname:"");
+               }
+       }
+       printk(" ");
+       if (table->ctl_name) {
+               for (i = depth; i >= 0; i--) {
+                       tmp = sysctl_parent(table, i);
+                       printk(".%d", tmp->ctl_name);
+               }
+       }
+}
+
+static void sysctl_repair_table(struct ctl_table *table)
+{
+       /* Don't complain about the classic default
+        * sysctl strategy routine.  Maybe later we
+        * can get the tables fixed and complain about
+        * this.
+        */
+       if (table->ctl_name && table->procname &&
+               (table->proc_handler == proc_dointvec) &&
+               (!table->strategy)) {
+               table->strategy = sysctl_data;
+       }
+}
+
+static struct ctl_table *sysctl_check_lookup(struct ctl_table *table)
+{
+       struct ctl_table_header *head;
+       struct ctl_table *ref, *test;
+       int depth, cur_depth;
+
+       depth = sysctl_depth(table);
+
+       for (head = sysctl_head_next(NULL); head;
+            head = sysctl_head_next(head)) {
+               cur_depth = depth;
+               ref = head->ctl_table;
+repeat:
+               test = sysctl_parent(table, cur_depth);
+               for (; ref->ctl_name || ref->procname; ref++) {
+                       int match = 0;
+                       if (cur_depth && !ref->child)
+                               continue;
+
+                       if (test->procname && ref->procname &&
+                           (strcmp(test->procname, ref->procname) == 0))
+                                       match++;
+
+                       if (test->ctl_name && ref->ctl_name &&
+                           (test->ctl_name == ref->ctl_name))
+                               match++;
+
+                       if (match) {
+                               if (cur_depth != 0) {
+                                       cur_depth--;
+                                       ref = ref->child;
+                                       goto repeat;
+                               }
+                               goto out;
+                       }
+               }
+       }
+       ref = NULL;
+out:
+       sysctl_head_finish(head);
+       return ref;
+}
+
+static void set_fail(const char **fail, struct ctl_table *table, const char *str)
+{
+       if (*fail) {
+               printk(KERN_ERR "sysctl table check failed: ");
+               sysctl_print_path(table);
+               printk(" %s\n", *fail);
+       }
+       *fail = str;
+}
+
+static int sysctl_check_dir(struct ctl_table *table)
+{
+       struct ctl_table *ref;
+       int error;
+
+       error = 0;
+       ref = sysctl_check_lookup(table);
+       if (ref) {
+               int match = 0;
+               if ((!table->procname && !ref->procname) ||
+                   (table->procname && ref->procname &&
+                    (strcmp(table->procname, ref->procname) == 0)))
+                       match++;
+
+               if ((!table->ctl_name && !ref->ctl_name) ||
+                   (table->ctl_name && ref->ctl_name &&
+                    (table->ctl_name == ref->ctl_name)))
+                       match++;
+
+               if (match != 2) {
+                       printk(KERN_ERR "%s: failed: ", __func__);
+                       sysctl_print_path(table);
+                       printk(" ref: ");
+                       sysctl_print_path(ref);
+                       printk("\n");
+                       error = -EINVAL;
+               }
+       }
+       return error;
+}
+
+static void sysctl_check_leaf(struct ctl_table *table, const char **fail)
+{
+       struct ctl_table *ref;
+
+       ref = sysctl_check_lookup(table);
+       if (ref && (ref != table))
+               set_fail(fail, table, "Sysctl already exists");
+}
+
+static void sysctl_check_bin_path(struct ctl_table *table, const char **fail)
+{
+       struct trans_ctl_table *ref;
+
+       ref = sysctl_binary_lookup(table);
+       if (table->ctl_name && !ref)
+               set_fail(fail, table, "Unknown sysctl binary path");
+       if (ref) {
+               if (ref->procname &&
+                   (!table->procname ||
+                    (strcmp(table->procname, ref->procname) != 0)))
+                       set_fail(fail, table, "procname does not match binary path procname");
+
+               if (ref->ctl_name && table->ctl_name &&
+                   (table->ctl_name != ref->ctl_name))
+                       set_fail(fail, table, "ctl_name does not match binary path ctl_name");
+       }
+}
+
+int sysctl_check_table(struct ctl_table *table)
+{
+       int error = 0;
+       for (; table->ctl_name || table->procname; table++) {
+               const char *fail = NULL;
+
+               sysctl_repair_table(table);
+               if (table->parent) {
+                       if (table->procname && !table->parent->procname)
+                               set_fail(&fail, table, "Parent without procname");
+                       if (table->ctl_name && !table->parent->ctl_name)
+                               set_fail(&fail, table, "Parent without ctl_name");
+               }
+               if (!table->procname)
+                       set_fail(&fail, table, "No procname");
+               if (table->child) {
+                       if (table->data)
+                               set_fail(&fail, table, "Directory with data?");
+                       if (table->maxlen)
+                               set_fail(&fail, table, "Directory with maxlen?");
+                       if ((table->mode & (S_IRUGO|S_IXUGO)) != table->mode)
+                               set_fail(&fail, table, "Writable sysctl directory");
+                       if (table->proc_handler)
+                               set_fail(&fail, table, "Directory with proc_handler");
+                       if (table->strategy)
+                               set_fail(&fail, table, "Directory with strategy");
+                       if (table->extra1)
+                               set_fail(&fail, table, "Directory with extra1");
+                       if (table->extra2)
+                               set_fail(&fail, table, "Directory with extra2");
+                       if (sysctl_check_dir(table))
+                               set_fail(&fail, table, "Inconsistent directory names");
+               } else {
+                       if ((table->strategy == sysctl_data) ||
+                           (table->strategy == sysctl_string) ||
+                           (table->strategy == sysctl_intvec) ||
+                           (table->strategy == sysctl_jiffies) ||
+                           (table->strategy == sysctl_ms_jiffies) ||
+                           (table->proc_handler == proc_dostring) ||
+                           (table->proc_handler == proc_dointvec) ||
+#ifdef CONFIG_SECURITY_CAPABILITIES
+                           (table->proc_handler == proc_dointvec_bset) ||
+#endif /* def CONFIG_SECURITY_CAPABILITIES */
+                           (table->proc_handler == proc_dointvec_minmax) ||
+                           (table->proc_handler == proc_dointvec_jiffies) ||
+                           (table->proc_handler == proc_dointvec_userhz_jiffies) ||
+                           (table->proc_handler == proc_dointvec_ms_jiffies) ||
+                           (table->proc_handler == proc_doulongvec_minmax) ||
+                           (table->proc_handler == proc_doulongvec_ms_jiffies_minmax)) {
+                               if (!table->data)
+                                       set_fail(&fail, table, "No data");
+                               if (!table->maxlen)
+                                       set_fail(&fail, table, "No maxlen");
+                       }
+                       if ((table->proc_handler == proc_doulongvec_minmax) ||
+                           (table->proc_handler == proc_doulongvec_ms_jiffies_minmax)) {
+                               if (table->maxlen > sizeof (unsigned long)) {
+                                       if (!table->extra1)
+                                               set_fail(&fail, table, "No min");
+                                       if (!table->extra2)
+                                               set_fail(&fail, table, "No max");
+                               }
+                       }
+#ifdef CONFIG_SYSCTL_SYSCALL
+                       if (table->ctl_name && !table->strategy)
+                               set_fail(&fail, table, "Missing strategy");
+#endif
+#if 0
+                       if (!table->ctl_name && table->strategy)
+                               set_fail(&fail, table, "Strategy without ctl_name");
+#endif
+#ifdef CONFIG_PROC_FS
+                       if (table->procname && !table->proc_handler)
+                               set_fail(&fail, table, "No proc_handler");
+#endif
+#if 0
+                       if (!table->procname && table->proc_handler)
+                               set_fail(&fail, table, "proc_handler without procname");
+#endif
+                       sysctl_check_leaf(table, &fail);
+               }
+               sysctl_check_bin_path(table, &fail);
+               if (fail) {
+                       set_fail(&fail, table, NULL);
+                       error = -EINVAL;
+               }
+               if (table->child)
+                       error |= sysctl_check_table(table->child);
+       }
+       return error;
+}
index 7d4d7f9c1bb2a0575cf15f9119c403e696657bb8..354e74bc17c186099b50edd9471b7f6163ce2c62 100644 (file)
 #include <linux/delayacct.h>
 #include <linux/cpumask.h>
 #include <linux/percpu.h>
+#include <linux/cgroupstats.h>
+#include <linux/cgroup.h>
+#include <linux/fs.h>
+#include <linux/file.h>
 #include <net/genetlink.h>
 #include <asm/atomic.h>
 
@@ -49,6 +53,11 @@ __read_mostly = {
        [TASKSTATS_CMD_ATTR_REGISTER_CPUMASK] = { .type = NLA_STRING },
        [TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK] = { .type = NLA_STRING },};
 
+static struct nla_policy
+cgroupstats_cmd_get_policy[CGROUPSTATS_CMD_ATTR_MAX+1] __read_mostly = {
+       [CGROUPSTATS_CMD_ATTR_FD] = { .type = NLA_U32 },
+};
+
 struct listener {
        struct list_head list;
        pid_t pid;
@@ -254,7 +263,7 @@ out:
 
        stats->version = TASKSTATS_VERSION;
        /*
-        * Accounting subsytems can also add calls here to modify
+        * Accounting subsystems can also add calls here to modify
         * fields of taskstats.
         */
        return rc;
@@ -372,6 +381,51 @@ err:
        return NULL;
 }
 
+static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info)
+{
+       int rc = 0;
+       struct sk_buff *rep_skb;
+       struct cgroupstats *stats;
+       struct nlattr *na;
+       size_t size;
+       u32 fd;
+       struct file *file;
+       int fput_needed;
+
+       na = info->attrs[CGROUPSTATS_CMD_ATTR_FD];
+       if (!na)
+               return -EINVAL;
+
+       fd = nla_get_u32(info->attrs[CGROUPSTATS_CMD_ATTR_FD]);
+       file = fget_light(fd, &fput_needed);
+       if (file) {
+               size = nla_total_size(sizeof(struct cgroupstats));
+
+               rc = prepare_reply(info, CGROUPSTATS_CMD_NEW, &rep_skb,
+                                       size);
+               if (rc < 0)
+                       goto err;
+
+               na = nla_reserve(rep_skb, CGROUPSTATS_TYPE_CGROUP_STATS,
+                                       sizeof(struct cgroupstats));
+               stats = nla_data(na);
+               memset(stats, 0, sizeof(*stats));
+
+               rc = cgroupstats_build(stats, file->f_dentry);
+               if (rc < 0)
+                       goto err;
+
+               fput_light(file, fput_needed);
+               return send_reply(rep_skb, info->snd_pid);
+       }
+
+err:
+       if (file)
+               fput_light(file, fput_needed);
+       nlmsg_free(rep_skb);
+       return rc;
+}
+
 static int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info)
 {
        int rc = 0;
@@ -522,6 +576,12 @@ static struct genl_ops taskstats_ops = {
        .policy         = taskstats_cmd_get_policy,
 };
 
+static struct genl_ops cgroupstats_ops = {
+       .cmd            = CGROUPSTATS_CMD_GET,
+       .doit           = cgroupstats_user_cmd,
+       .policy         = cgroupstats_cmd_get_policy,
+};
+
 /* Needed early in initialization */
 void __init taskstats_init_early(void)
 {
@@ -546,8 +606,15 @@ static int __init taskstats_init(void)
        if (rc < 0)
                goto err;
 
+       rc = genl_register_ops(&family, &cgroupstats_ops);
+       if (rc < 0)
+               goto err_cgroup_ops;
+
        family_registered = 1;
+       printk("registered taskstats version %d\n", TASKSTATS_GENL_VERSION);
        return 0;
+err_cgroup_ops:
+       genl_unregister_ops(&family, &taskstats_ops);
 err:
        genl_unregister_family(&family);
        return rc;
index 2d5b6a682138d12af18eb2b93caeca9c4443c56f..09d3c45c4da78d9af2bec9e10f89e37bfeec01d5 100644 (file)
@@ -9,9 +9,9 @@
  */
 /*
  * Modification history kernel/time.c
- * 
+ *
  * 1993-09-02    Philip Gladstone
- *      Created file with time related functions from sched.c and adjtimex() 
+ *      Created file with time related functions from sched.c and adjtimex()
  * 1993-10-08    Torsten Duwe
  *      adjtime interface update and CMOS clock write code
  * 1995-08-13    Torsten Duwe
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/timex.h>
 #include <linux/capability.h>
+#include <linux/clocksource.h>
 #include <linux/errno.h>
 #include <linux/syscalls.h>
 #include <linux/security.h>
@@ -38,7 +39,7 @@
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
 
-/* 
+/*
  * The timezone where the local system is located.  Used as a default by some
  * programs who obtain this value by using gettimeofday.
  */
@@ -71,7 +72,7 @@ asmlinkage long sys_time(time_t __user * tloc)
  * why not move it into the appropriate arch directory (for those
  * architectures that need it).
  */
+
 asmlinkage long sys_stime(time_t __user *tptr)
 {
        struct timespec tv;
@@ -110,10 +111,10 @@ asmlinkage long sys_gettimeofday(struct timeval __user *tv, struct timezone __us
 /*
  * Adjust the time obtained from the CMOS to be UTC time instead of
  * local time.
- * 
+ *
  * This is ugly, but preferable to the alternatives.  Otherwise we
  * would either need to write a program to do it in /etc/rc (and risk
- * confusion if the program gets run more than once; it would also be 
+ * confusion if the program gets run more than once; it would also be
  * hard to make the program warp the clock precisely n hours)  or
  * compile in the timezone information into the kernel.  Bad, bad....
  *
@@ -158,6 +159,7 @@ int do_sys_settimeofday(struct timespec *tv, struct timezone *tz)
        if (tz) {
                /* SMP safe, global irq locking makes it work. */
                sys_tz = *tz;
+               update_vsyscall_tz();
                if (firsttime) {
                        firsttime = 0;
                        if (!tv)
index 51b6a6a6158cab016aa11b09f0a65c1919c750ec..c8a9d13874dfdcf85c6b2ab9d7d03f92a8f39401 100644 (file)
@@ -207,15 +207,12 @@ static inline void clocksource_resume_watchdog(void) { }
  */
 void clocksource_resume(void)
 {
-       struct list_head *tmp;
+       struct clocksource *cs;
        unsigned long flags;
 
        spin_lock_irqsave(&clocksource_lock, flags);
 
-       list_for_each(tmp, &clocksource_list) {
-               struct clocksource *cs;
-
-               cs = list_entry(tmp, struct clocksource, list);
+       list_for_each_entry(cs, &clocksource_list, list) {
                if (cs->resume)
                        cs->resume();
        }
@@ -369,7 +366,6 @@ static ssize_t sysfs_override_clocksource(struct sys_device *dev,
                                          const char *buf, size_t count)
 {
        struct clocksource *ovr = NULL;
-       struct list_head *tmp;
        size_t ret = count;
        int len;
 
@@ -389,12 +385,11 @@ static ssize_t sysfs_override_clocksource(struct sys_device *dev,
 
        len = strlen(override_name);
        if (len) {
+               struct clocksource *cs;
+
                ovr = clocksource_override;
                /* try to select it: */
-               list_for_each(tmp, &clocksource_list) {
-                       struct clocksource *cs;
-
-                       cs = list_entry(tmp, struct clocksource, list);
+               list_for_each_entry(cs, &clocksource_list, list) {
                        if (strlen(cs->name) == len &&
                            !strcmp(cs->name, override_name))
                                ovr = cs;
@@ -422,14 +417,11 @@ static ssize_t sysfs_override_clocksource(struct sys_device *dev,
 static ssize_t
 sysfs_show_available_clocksources(struct sys_device *dev, char *buf)
 {
-       struct list_head *tmp;
+       struct clocksource *src;
        char *curr = buf;
 
        spin_lock_irq(&clocksource_lock);
-       list_for_each(tmp, &clocksource_list) {
-               struct clocksource *src;
-
-               src = list_entry(tmp, struct clocksource, list);
+       list_for_each_entry(src, &clocksource_list, list) {
                curr += sprintf(curr, "%s ", src->name);
        }
        spin_unlock_irq(&clocksource_lock);
index ce89ffb474d0cbeba8b2d84af5c3a6c9ae5f7389..10a1347597fd394fec309d1ae74663ae2d9ae05c 100644 (file)
@@ -153,6 +153,7 @@ void tick_nohz_stop_sched_tick(void)
        unsigned long seq, last_jiffies, next_jiffies, delta_jiffies, flags;
        struct tick_sched *ts;
        ktime_t last_update, expires, now, delta;
+       struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev;
        int cpu;
 
        local_irq_save(flags);
@@ -302,10 +303,25 @@ void tick_nohz_stop_sched_tick(void)
 out:
        ts->next_jiffies = next_jiffies;
        ts->last_jiffies = last_jiffies;
+       ts->sleep_length = ktime_sub(dev->next_event, now);
 end:
        local_irq_restore(flags);
 }
 
+/**
+ * tick_nohz_get_sleep_length - return the length of the current sleep
+ *
+ * Called from power state control code with interrupts disabled
+ */
+ktime_t tick_nohz_get_sleep_length(void)
+{
+       struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched);
+
+       return ts->sleep_length;
+}
+
+EXPORT_SYMBOL_GPL(tick_nohz_get_sleep_length);
+
 /**
  * nohz_restart_sched_tick - restart the idle tick from the idle task
  *
index 6ce1952eea7dbf84d4d9a4c3a5d03f8fd5bffbf3..fb4e67d5dd6032eab811202526a194aa004523ad 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/swap.h>
+#include <linux/pid_namespace.h>
 #include <linux/notifier.h>
 #include <linux/thread_info.h>
 #include <linux/time.h>
@@ -817,7 +818,7 @@ unsigned long next_timer_interrupt(void)
 #endif
 
 /*
- * Called from the timer interrupt handler to charge one tick to the current 
+ * Called from the timer interrupt handler to charge one tick to the current
  * process.  user_tick is 1 if the tick is user time, 0 for system.
  */
 void update_process_times(int user_tick)
@@ -826,10 +827,13 @@ void update_process_times(int user_tick)
        int cpu = smp_processor_id();
 
        /* Note: this timer irq context must be accounted for as well. */
-       if (user_tick)
+       if (user_tick) {
                account_user_time(p, jiffies_to_cputime(1));
-       else
+               account_user_time_scaled(p, jiffies_to_cputime(1));
+       } else {
                account_system_time(p, HARDIRQ_OFFSET, jiffies_to_cputime(1));
+               account_system_time_scaled(p, jiffies_to_cputime(1));
+       }
        run_local_timers();
        if (rcu_pending(cpu))
                rcu_check_callbacks(cpu, user_tick);
@@ -953,7 +957,7 @@ asmlinkage unsigned long sys_alarm(unsigned int seconds)
  */
 asmlinkage long sys_getpid(void)
 {
-       return current->tgid;
+       return task_tgid_vnr(current);
 }
 
 /*
@@ -967,7 +971,7 @@ asmlinkage long sys_getppid(void)
        int pid;
 
        rcu_read_lock();
-       pid = rcu_dereference(current->real_parent)->tgid;
+       pid = task_ppid_nr_ns(current, current->nsproxy->pid_ns);
        rcu_read_unlock();
 
        return pid;
@@ -1099,7 +1103,7 @@ EXPORT_SYMBOL(schedule_timeout_uninterruptible);
 /* Thread ID - the internal kernel "pid" */
 asmlinkage long sys_gettid(void)
 {
-       return current->pid;
+       return task_pid_vnr(current);
 }
 
 /**
index c122131a122f54121f239ece78f830efbaf90d69..4ab1b584961b922afacc61f80750d1f0396ac0ec 100644 (file)
@@ -62,6 +62,10 @@ void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk)
        rcu_read_unlock();
        stats->ac_utime  = cputime_to_msecs(tsk->utime) * USEC_PER_MSEC;
        stats->ac_stime  = cputime_to_msecs(tsk->stime) * USEC_PER_MSEC;
+       stats->ac_utimescaled =
+               cputime_to_msecs(tsk->utimescaled) * USEC_PER_MSEC;
+       stats->ac_stimescaled =
+               cputime_to_msecs(tsk->stimescaled) * USEC_PER_MSEC;
        stats->ac_minflt = tsk->min_flt;
        stats->ac_majflt = tsk->maj_flt;
 
index e080d1d744cce242b587664445888fa23eeb0b9a..52d5e7c9a8e6e82e68a0cb88ba0cdbad508eded5 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/freezer.h>
 #include <linux/kallsyms.h>
 #include <linux/debug_locks.h>
+#include <linux/lockdep.h>
 
 /*
  * The per-CPU workqueue (if single thread, we always use the first
@@ -61,6 +62,9 @@ struct workqueue_struct {
        const char *name;
        int singlethread;
        int freezeable;         /* Freeze threads during suspend */
+#ifdef CONFIG_LOCKDEP
+       struct lockdep_map lockdep_map;
+#endif
 };
 
 /* All the per-cpu workqueues on the system, for hotplug cpu to add/remove
@@ -250,6 +254,17 @@ static void run_workqueue(struct cpu_workqueue_struct *cwq)
                struct work_struct *work = list_entry(cwq->worklist.next,
                                                struct work_struct, entry);
                work_func_t f = work->func;
+#ifdef CONFIG_LOCKDEP
+               /*
+                * It is permissible to free the struct work_struct
+                * from inside the function that is called from it,
+                * this we need to take into account for lockdep too.
+                * To avoid bogus "held lock freed" warnings as well
+                * as problems when looking into work->lockdep_map,
+                * make a copy and use that here.
+                */
+               struct lockdep_map lockdep_map = work->lockdep_map;
+#endif
 
                cwq->current_work = work;
                list_del_init(cwq->worklist.next);
@@ -257,13 +272,17 @@ static void run_workqueue(struct cpu_workqueue_struct *cwq)
 
                BUG_ON(get_wq_data(work) != cwq);
                work_clear_pending(work);
+               lock_acquire(&cwq->wq->lockdep_map, 0, 0, 0, 2, _THIS_IP_);
+               lock_acquire(&lockdep_map, 0, 0, 0, 2, _THIS_IP_);
                f(work);
+               lock_release(&lockdep_map, 1, _THIS_IP_);
+               lock_release(&cwq->wq->lockdep_map, 1, _THIS_IP_);
 
                if (unlikely(in_atomic() || lockdep_depth(current) > 0)) {
                        printk(KERN_ERR "BUG: workqueue leaked lock or atomic: "
                                        "%s/0x%08x/%d\n",
                                        current->comm, preempt_count(),
-                                       current->pid);
+                                       task_pid_nr(current));
                        printk(KERN_ERR "    last function: ");
                        print_symbol("%s\n", (unsigned long)f);
                        debug_show_held_locks(current);
@@ -376,6 +395,8 @@ void fastcall flush_workqueue(struct workqueue_struct *wq)
        int cpu;
 
        might_sleep();
+       lock_acquire(&wq->lockdep_map, 0, 0, 0, 2, _THIS_IP_);
+       lock_release(&wq->lockdep_map, 1, _THIS_IP_);
        for_each_cpu_mask(cpu, *cpu_map)
                flush_cpu_workqueue(per_cpu_ptr(wq->cpu_wq, cpu));
 }
@@ -446,6 +467,9 @@ static void wait_on_work(struct work_struct *work)
 
        might_sleep();
 
+       lock_acquire(&work->lockdep_map, 0, 0, 0, 2, _THIS_IP_);
+       lock_release(&work->lockdep_map, 1, _THIS_IP_);
+
        cwq = get_wq_data(work);
        if (!cwq)
                return;
@@ -695,8 +719,10 @@ static void start_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu)
        }
 }
 
-struct workqueue_struct *__create_workqueue(const char *name,
-                                           int singlethread, int freezeable)
+struct workqueue_struct *__create_workqueue_key(const char *name,
+                                               int singlethread,
+                                               int freezeable,
+                                               struct lock_class_key *key)
 {
        struct workqueue_struct *wq;
        struct cpu_workqueue_struct *cwq;
@@ -713,6 +739,7 @@ struct workqueue_struct *__create_workqueue(const char *name,
        }
 
        wq->name = name;
+       lockdep_init_map(&wq->lockdep_map, name, key, 0);
        wq->singlethread = singlethread;
        wq->freezeable = freezeable;
        INIT_LIST_HEAD(&wq->list);
@@ -741,7 +768,7 @@ struct workqueue_struct *__create_workqueue(const char *name,
        }
        return wq;
 }
-EXPORT_SYMBOL_GPL(__create_workqueue);
+EXPORT_SYMBOL_GPL(__create_workqueue_key);
 
 static void cleanup_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu)
 {
@@ -752,6 +779,9 @@ static void cleanup_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu)
        if (cwq->thread == NULL)
                return;
 
+       lock_acquire(&cwq->wq->lockdep_map, 0, 0, 0, 2, _THIS_IP_);
+       lock_release(&cwq->wq->lockdep_map, 1, _THIS_IP_);
+
        flush_cpu_workqueue(cwq);
        /*
         * If the caller is CPU_DEAD and cwq->worklist was not empty,
index 7d16e64333025db69440fe96b46beb229749e746..1faa5087dc86d65685f97a0714bf70e7f586fd35 100644 (file)
@@ -389,6 +389,16 @@ config DEBUG_LIST
 
          If unsure, say N.
 
+config DEBUG_SG
+       bool "Debug SG table operations"
+       depends on DEBUG_KERNEL
+       help
+         Enable this to turn on checks on scatter-gather tables. This can
+         help find problems with drivers that do not properly initialize
+         their sg tables.
+
+         If unsure, say N.
+
 config FRAME_POINTER
        bool "Compile the kernel with frame pointers"
        depends on DEBUG_KERNEL && (X86 || CRIS || M68K || M68KNOMMU || FRV || UML || S390 || AVR32 || SUPERH || BFIN)
@@ -498,3 +508,5 @@ config FAULT_INJECTION_STACKTRACE_FILTER
        select FRAME_POINTER
        help
          Provide stacktrace filter for fault-injection capabilities
+
+source "samples/Kconfig"
index c5f215d509d3e36429f8f9a8eb1fd52fb9411dcc..3a0983b77412cdc6b0336bb0e3e1f539ddc2d0cd 100644 (file)
@@ -6,7 +6,7 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
         rbtree.o radix-tree.o dump_stack.o \
         idr.o int_sqrt.o bitmap.o extable.o prio_tree.o \
         sha1.o irq_regs.o reciprocal_div.o argv_split.o \
-        proportions.o
+        proportions.o prio_heap.o
 
 lib-$(CONFIG_MMU) += ioremap.o
 lib-$(CONFIG_SMP) += cpumask.o
index fad6ce4f7b57e353bf9b4a9d8c2dca502b4d5938..5205a8dae5bc08c51a4f0f283dd812e2fab25a04 100644 (file)
@@ -4,7 +4,8 @@
 
 #include <linux/kernel.h>
 #include <linux/ctype.h>
-#include <linux/bug.h>
+#include <linux/slab.h>
+#include <linux/module.h>
 
 static const char *skip_sep(const char *cp)
 {
index bfc33314c72088845f46e35465c31827e7170422..d2c2f257bedd348a0f81316fc02ef90226ecc0ac 100644 (file)
@@ -49,7 +49,7 @@ MODULE_LICENSE("GPL");
  * @p: pointer to buffer over which CRC is run
  * @len: length of buffer @p
  */
-u32 __attribute_pure__ crc32_le(u32 crc, unsigned char const *p, size_t len);
+u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len);
 
 #if CRC_LE_BITS == 1
 /*
@@ -57,7 +57,7 @@ u32 __attribute_pure__ crc32_le(u32 crc, unsigned char const *p, size_t len);
  * simplified by inlining the table in ?: form.
  */
 
-u32 __attribute_pure__ crc32_le(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
 {
        int i;
        while (len--) {
@@ -69,7 +69,7 @@ u32 __attribute_pure__ crc32_le(u32 crc, unsigned char const *p, size_t len)
 }
 #else                          /* Table-based approach */
 
-u32 __attribute_pure__ crc32_le(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
 {
 # if CRC_LE_BITS == 8
        const u32      *b =(u32 *)p;
@@ -145,7 +145,7 @@ u32 __attribute_pure__ crc32_le(u32 crc, unsigned char const *p, size_t len)
  * @p: pointer to buffer over which CRC is run
  * @len: length of buffer @p
  */
-u32 __attribute_pure__ crc32_be(u32 crc, unsigned char const *p, size_t len);
+u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len);
 
 #if CRC_BE_BITS == 1
 /*
@@ -153,7 +153,7 @@ u32 __attribute_pure__ crc32_be(u32 crc, unsigned char const *p, size_t len);
  * simplified by inlining the table in ?: form.
  */
 
-u32 __attribute_pure__ crc32_be(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
 {
        int i;
        while (len--) {
@@ -167,7 +167,7 @@ u32 __attribute_pure__ crc32_be(u32 crc, unsigned char const *p, size_t len)
 }
 
 #else                          /* Table-based approach */
-u32 __attribute_pure__ crc32_be(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
 {
 # if CRC_BE_BITS == 8
        const u32      *b =(u32 *)p;
index 360556a7803d4dae582b39edec3e91bb78ac7749..389424ecb129f13760de1677bd297b392264c953 100644 (file)
@@ -1,6 +1,6 @@
 #include <linux/module.h>
+#include <linux/bitops.h>
 #include <asm/types.h>
-#include <asm/bitops.h>
 
 /**
  * hweightN - returns the hamming weight of a N-bit word
index e0fdfddb406ec3975673f150f46bd3302bc08599..f73e2f8c308f2e3b17e0cd21b5f0ab7131872f08 100644 (file)
@@ -2,7 +2,7 @@
  * lib/kernel_lock.c
  *
  * This is the traditional BKL - big kernel lock. Largely
- * relegated to obsolescense, but used by various less
+ * relegated to obsolescence, but used by various less
  * important (or lazy) subsystems.
  */
 #include <linux/smp_lock.h>
index 2e4eae5b0824400de9f6eeafb5483c3fde8f5b0c..5886147252d0d643598e408b63bf193aa49b5f34 100644 (file)
@@ -126,7 +126,7 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
        else
                subsystem = kobject_name(&kset->kobj);
        if (!subsystem) {
-               pr_debug("unset subsytem caused the event to drop!\n");
+               pr_debug("unset subsystem caused the event to drop!\n");
                return 0;
        }
 
index 60f46803af3f1c82ea6650bf12a40e9f3ac5aefc..802f11f0bf5baebf99460c1e4d238921764fab93 100644 (file)
@@ -66,7 +66,7 @@ EXPORT_SYMBOL(crc32c_le);
  * loop below with crc32 and vary the POLY if we don't find value in terms
  * of space and maintainability in keeping the two modules separate.
  */
-u32 __attribute_pure__
+u32 __pure
 crc32c_le(u32 crc, unsigned char const *p, size_t len)
 {
        int i;
@@ -160,7 +160,7 @@ static const u32 crc32c_table[256] = {
  * crc using table.
  */
 
-u32 __attribute_pure__
+u32 __pure
 crc32c_le(u32 seed, unsigned char const *data, size_t length)
 {
        u32 crc = __cpu_to_le32(seed);
@@ -177,7 +177,7 @@ crc32c_le(u32 seed, unsigned char const *data, size_t length)
 EXPORT_SYMBOL(crc32c_be);
 
 #if CRC_BE_BITS == 1
-u32 __attribute_pure__
+u32 __pure
 crc32c_be(u32 crc, unsigned char const *p, size_t len)
 {
        int i;
index 9659eabffc319c5235669a87687949d270536b4e..393a0e915c23b252b747c62645beb463e25843ed 100644 (file)
@@ -124,12 +124,13 @@ static int __cpuinit percpu_counter_hotcpu_callback(struct notifier_block *nb,
        mutex_lock(&percpu_counters_lock);
        list_for_each_entry(fbc, &percpu_counters, list) {
                s32 *pcount;
+               unsigned long flags;
 
-               spin_lock(&fbc->lock);
+               spin_lock_irqsave(&fbc->lock, flags);
                pcount = per_cpu_ptr(fbc->counters, cpu);
                fbc->count += *pcount;
                *pcount = 0;
-               spin_unlock(&fbc->lock);
+               spin_unlock_irqrestore(&fbc->lock, flags);
        }
        mutex_unlock(&percpu_counters_lock);
        return NOTIFY_OK;
diff --git a/lib/prio_heap.c b/lib/prio_heap.c
new file mode 100644 (file)
index 0000000..471944a
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Simple insertion-only static-sized priority heap containing
+ * pointers, based on CLR, chapter 7
+ */
+
+#include <linux/slab.h>
+#include <linux/prio_heap.h>
+
+int heap_init(struct ptr_heap *heap, size_t size, gfp_t gfp_mask,
+             int (*gt)(void *, void *))
+{
+       heap->ptrs = kmalloc(size, gfp_mask);
+       if (!heap->ptrs)
+               return -ENOMEM;
+       heap->size = 0;
+       heap->max = size / sizeof(void *);
+       heap->gt = gt;
+       return 0;
+}
+
+void heap_free(struct ptr_heap *heap)
+{
+       kfree(heap->ptrs);
+}
+
+void *heap_insert(struct ptr_heap *heap, void *p)
+{
+       void *res;
+       void **ptrs = heap->ptrs;
+       int pos;
+
+       if (heap->size < heap->max) {
+               /* Heap insertion */
+               int pos = heap->size++;
+               while (pos > 0 && heap->gt(p, ptrs[(pos-1)/2])) {
+                       ptrs[pos] = ptrs[(pos-1)/2];
+                       pos = (pos-1)/2;
+               }
+               ptrs[pos] = p;
+               return NULL;
+       }
+
+       /* The heap is full, so something will have to be dropped */
+
+       /* If the new pointer is greater than the current max, drop it */
+       if (heap->gt(p, ptrs[0]))
+               return p;
+
+       /* Replace the current max and heapify */
+       res = ptrs[0];
+       ptrs[0] = p;
+       pos = 0;
+
+       while (1) {
+               int left = 2 * pos + 1;
+               int right = 2 * pos + 2;
+               int largest = pos;
+               if (left < heap->size && heap->gt(ptrs[left], p))
+                       largest = left;
+               if (right < heap->size && heap->gt(ptrs[right], ptrs[largest]))
+                       largest = right;
+               if (largest == pos)
+                       break;
+               /* Push p down the heap one level and bump one up */
+               ptrs[pos] = ptrs[largest];
+               ptrs[largest] = p;
+               pos = largest;
+       }
+       return res;
+}
index a58df56f09b6093f06a038f9a38675936ec3fa88..0ec3f257ffdf9d38b96dad16276e7b3164f13e63 100644 (file)
@@ -39,8 +39,7 @@
 
        /* Check length parameter for validity */
        pad = nn - nroots - len;
-       if (pad < 0 || pad >= nn)
-               return -ERANGE;
+       BUG_ON(pad < 0 || pad >= nn);
 
        /* Does the caller provide the syndrome ? */
        if (s != NULL)
                 * deg(lambda) unequal to number of roots => uncorrectable
                 * error detected
                 */
-               count = -1;
+               count = -EBADMSG;
                goto finish;
        }
        /*
index 5b0d8522b7ca16882b54cee337536a665cb825d0..3ea2db94d5b01bbe64501b2ac1bea68ec99ccf84 100644 (file)
@@ -320,6 +320,7 @@ EXPORT_SYMBOL_GPL(encode_rs8);
  *  The syndrome and parity uses a uint16_t data type to enable
  *  symbol size > 8. The calling code must take care of decoding of the
  *  syndrome result and the received parity before calling this code.
+ *  Returns the number of corrected bits or -EBADMSG for uncorrectable errors.
  */
 int decode_rs8(struct rs_control *rs, uint8_t *data, uint16_t *par, int len,
               uint16_t *s, int no_eras, int *eras_pos, uint16_t invmsk,
@@ -363,6 +364,7 @@ EXPORT_SYMBOL_GPL(encode_rs16);
  *  @corr:     buffer to store correction bitmask on eras_pos
  *
  *  Each field in the data array contains up to symbol size bits of valid data.
+ *  Returns the number of corrected bits or -EBADMSG for uncorrectable errors.
  */
 int decode_rs16(struct rs_control *rs, uint16_t *data, uint16_t *par, int len,
                uint16_t *s, int no_eras, int *eras_pos, uint16_t invmsk,
index 479fd462eaa9c7630df676bdddd91d4dd1212a2c..9c4b0256490bd240b37f8811915e873463c88537 100644 (file)
@@ -60,12 +60,12 @@ static void spin_bug(spinlock_t *lock, const char *msg)
                owner = lock->owner;
        printk(KERN_EMERG "BUG: spinlock %s on CPU#%d, %s/%d\n",
                msg, raw_smp_processor_id(),
-               current->comm, current->pid);
+               current->comm, task_pid_nr(current));
        printk(KERN_EMERG " lock: %p, .magic: %08x, .owner: %s/%d, "
                        ".owner_cpu: %d\n",
                lock, lock->magic,
                owner ? owner->comm : "<none>",
-               owner ? owner->pid : -1,
+               owner ? task_pid_nr(owner) : -1,
                lock->owner_cpu);
        dump_stack();
 }
@@ -116,7 +116,7 @@ static void __spin_lock_debug(spinlock_t *lock)
                        printk(KERN_EMERG "BUG: spinlock lockup on CPU#%d, "
                                        "%s/%d, %p\n",
                                raw_smp_processor_id(), current->comm,
-                               current->pid, lock);
+                               task_pid_nr(current), lock);
                        dump_stack();
 #ifdef CONFIG_SMP
                        trigger_all_cpu_backtrace();
@@ -161,7 +161,7 @@ static void rwlock_bug(rwlock_t *lock, const char *msg)
 
        printk(KERN_EMERG "BUG: rwlock %s on CPU#%d, %s/%d, %p\n",
                msg, raw_smp_processor_id(), current->comm,
-               current->pid, lock);
+               task_pid_nr(current), lock);
        dump_stack();
 }
 
index 752fd95323f3d777496f93c2144c7e158d936789..1a8050ade86159877fd6eb4486954c7719bfc28d 100644 (file)
@@ -35,7 +35,7 @@
 #define OFFSET(val,align) ((unsigned long)     \
                           ( (val) & ( (align) - 1)))
 
-#define SG_ENT_VIRT_ADDRESS(sg)        (page_address((sg)->page) + (sg)->offset)
+#define SG_ENT_VIRT_ADDRESS(sg)        (sg_virt((sg)))
 #define SG_ENT_PHYS_ADDRESS(sg)        virt_to_bus(SG_ENT_VIRT_ADDRESS(sg))
 
 /*
index b1f03b0eb7f13e5318535ef1ef799783803e3acd..c070ec0c15bfeee19c59659a668f7ab920ee77b3 100644 (file)
@@ -37,7 +37,7 @@ config DISCONTIGMEM_MANUAL
          in their physical address spaces, and this option provides
          more efficient handling of these holes.  However, the vast
          majority of hardware has quite flat address spaces, and
-         can have degraded performance from extra overhead that
+         can have degraded performance from the extra overhead that
          this option imposes.
 
          Many NUMA configurations will have this as the only option.
index 79f24a969cb4dfef1de95045bb5e9ced44e6243c..5209e47b7fe39dba855e84ee9ca4d89283fd3d80 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/uio.h>
 #include <linux/hash.h>
 #include <linux/writeback.h>
+#include <linux/backing-dev.h>
 #include <linux/pagevec.h>
 #include <linux/blkdev.h>
 #include <linux/security.h>
@@ -840,7 +841,7 @@ static void shrink_readahead_size_eio(struct file *filp,
 /**
  * do_generic_mapping_read - generic file read routine
  * @mapping:   address_space to be read
- * @_ra:       file's readahead state
+ * @ra:                file's readahead state
  * @filp:      the file to read
  * @ppos:      current file position
  * @desc:      read_descriptor
index ae2959bb59cbb785c70ffa99677c6194b1d4910d..8b809ecefa39e4b54f4bfbed8830009a9e260e96 100644 (file)
@@ -1017,10 +1017,10 @@ static long region_chg(struct list_head *head, long f, long t)
 
        /* If we are below the current region then a new region is required.
         * Subtle, allocate a new region at the position but make it zero
-        * size such that we can guarentee to record the reservation. */
+        * size such that we can guarantee to record the reservation. */
        if (&rg->link == head || t < rg->from) {
                nrg = kmalloc(sizeof(*nrg), GFP_KERNEL);
-               if (nrg == 0)
+               if (!nrg)
                        return -ENOMEM;
                nrg->from = f;
                nrg->to   = f;
index bd16dcaeefb8ce4e3b504916b81b67c536d0c4dc..eefd5b68bc42d76768e773a43ae310806c9fa17c 100644 (file)
@@ -259,9 +259,6 @@ void free_pgd_range(struct mmu_gather **tlb,
                        continue;
                free_pud_range(*tlb, pgd, addr, next, floor, ceiling);
        } while (pgd++, addr = next, addr != end);
-
-       if (!(*tlb)->fullmm)
-               flush_tlb_pgtables((*tlb)->mm, start, end);
 }
 
 void free_pgtables(struct mmu_gather **tlb, struct vm_area_struct *vma,
@@ -2716,7 +2713,7 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, in
                return 0;
 
        down_read(&mm->mmap_sem);
-       /* ignore errors, just check how much was sucessfully transfered */
+       /* ignore errors, just check how much was successfully transferred */
        while (len) {
                int bytes, ret, offset;
                void *maddr;
index 091b9c6c252973dd1cf5e89ffcf73de1afba173c..3a47871a29d909c561a4371f6afca71f59689126 100644 (file)
@@ -121,7 +121,7 @@ int __add_pages(struct zone *zone, unsigned long phys_start_pfn,
                err = __add_section(zone, i << PFN_SECTION_SHIFT);
 
                /*
-                * EEXIST is finally dealed with by ioresource collision
+                * EEXIST is finally dealt with by ioresource collision
                 * check. see add_memory() => register_memory_resource()
                 * Warning will be printed if there is collision.
                 */
@@ -187,7 +187,24 @@ int online_pages(unsigned long pfn, unsigned long nr_pages)
        unsigned long onlined_pages = 0;
        struct zone *zone;
        int need_zonelists_rebuild = 0;
+       int nid;
+       int ret;
+       struct memory_notify arg;
+
+       arg.start_pfn = pfn;
+       arg.nr_pages = nr_pages;
+       arg.status_change_nid = -1;
+
+       nid = page_to_nid(pfn_to_page(pfn));
+       if (node_present_pages(nid) == 0)
+               arg.status_change_nid = nid;
 
+       ret = memory_notify(MEM_GOING_ONLINE, &arg);
+       ret = notifier_to_errno(ret);
+       if (ret) {
+               memory_notify(MEM_CANCEL_ONLINE, &arg);
+               return ret;
+       }
        /*
         * This doesn't need a lock to do pfn_to_page().
         * The section can't be removed here because of the
@@ -222,6 +239,10 @@ int online_pages(unsigned long pfn, unsigned long nr_pages)
                build_all_zonelists();
        vm_total_pages = nr_free_pagecache_pages();
        writeback_set_ratelimit();
+
+       if (onlined_pages)
+               memory_notify(MEM_ONLINE, &arg);
+
        return 0;
 }
 #endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */
@@ -467,8 +488,9 @@ int offline_pages(unsigned long start_pfn,
 {
        unsigned long pfn, nr_pages, expire;
        long offlined_pages;
-       int ret, drain, retry_max;
+       int ret, drain, retry_max, node;
        struct zone *zone;
+       struct memory_notify arg;
 
        BUG_ON(start_pfn >= end_pfn);
        /* at least, alignment against pageblock is necessary */
@@ -480,11 +502,27 @@ int offline_pages(unsigned long start_pfn,
           we assume this for now. .*/
        if (!test_pages_in_a_zone(start_pfn, end_pfn))
                return -EINVAL;
+
+       zone = page_zone(pfn_to_page(start_pfn));
+       node = zone_to_nid(zone);
+       nr_pages = end_pfn - start_pfn;
+
        /* set above range as isolated */
        ret = start_isolate_page_range(start_pfn, end_pfn);
        if (ret)
                return ret;
-       nr_pages = end_pfn - start_pfn;
+
+       arg.start_pfn = start_pfn;
+       arg.nr_pages = nr_pages;
+       arg.status_change_nid = -1;
+       if (nr_pages >= node_present_pages(node))
+               arg.status_change_nid = node;
+
+       ret = memory_notify(MEM_GOING_OFFLINE, &arg);
+       ret = notifier_to_errno(ret);
+       if (ret)
+               goto failed_removal;
+
        pfn = start_pfn;
        expire = jiffies + timeout;
        drain = 0;
@@ -539,20 +577,24 @@ repeat:
        /* reset pagetype flags */
        start_isolate_page_range(start_pfn, end_pfn);
        /* removal success */
-       zone = page_zone(pfn_to_page(start_pfn));
        zone->present_pages -= offlined_pages;
        zone->zone_pgdat->node_present_pages -= offlined_pages;
        totalram_pages -= offlined_pages;
        num_physpages -= offlined_pages;
+
        vm_total_pages = nr_free_pagecache_pages();
        writeback_set_ratelimit();
+
+       memory_notify(MEM_OFFLINE, &arg);
        return 0;
 
 failed_removal:
        printk(KERN_INFO "memory offlining %lx to %lx failed\n",
                start_pfn, end_pfn);
+       memory_notify(MEM_CANCEL_OFFLINE, &arg);
        /* pushback to free area */
        undo_isolate_page_range(start_pfn, end_pfn);
+
        return ret;
 }
 #else
index 568152ae6cafe9c6f6052cf704c0e6dae0d198f7..c1592a94582f8c2950a6a4cf34711f02a35066c6 100644 (file)
@@ -78,6 +78,7 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/module.h>
+#include <linux/nsproxy.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/compat.h>
@@ -940,7 +941,7 @@ asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode,
 
        /* Find the mm_struct */
        read_lock(&tasklist_lock);
-       task = pid ? find_task_by_pid(pid) : current;
+       task = pid ? find_task_by_vpid(pid) : current;
        if (!task) {
                read_unlock(&tasklist_lock);
                return -ESRCH;
@@ -1388,7 +1389,6 @@ EXPORT_SYMBOL(alloc_pages_current);
  * keeps mempolicies cpuset relative after its cpuset moves.  See
  * further kernel/cpuset.c update_nodemask().
  */
-void *cpuset_being_rebound;
 
 /* Slow path of a mempolicy copy */
 struct mempolicy *__mpol_copy(struct mempolicy *old)
@@ -2019,4 +2019,3 @@ out:
                m->version = (vma != priv->tail_vma) ? vma->vm_start : 0;
        return 0;
 }
-
index 02d5ec3feabc9a6db30f0933c234038679cba837..a46eb1b4bb661e12a6f752964ad2df190bc763aa 100644 (file)
@@ -299,7 +299,7 @@ EXPORT_SYMBOL(mempool_free_slab);
 
 /*
  * A commonly used alloc and free fn that kmalloc/kfrees the amount of memory
- * specfied by pool_data
+ * specified by pool_data
  */
 void *mempool_kmalloc(gfp_t gfp_mask, void *pool_data)
 {
index 06d0877a66efa74a3d599b4ea50f0c5100dd7a1f..6a207e8d17ea3f74f0e20511fc726fe80ac47fb1 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/pagemap.h>
 #include <linux/buffer_head.h>
 #include <linux/mm_inline.h>
+#include <linux/nsproxy.h>
 #include <linux/pagevec.h>
 #include <linux/rmap.h>
 #include <linux/topology.h>
@@ -705,7 +706,7 @@ move_newpage:
  * The function returns after 10 attempts or if no pages
  * are movable anymore because to has become empty
  * or no retryable pages exist anymore. All pages will be
- * retruned to the LRU or freed.
+ * returned to the LRU or freed.
  *
  * Return: Number of pages not migrated or error code.
  */
@@ -924,7 +925,7 @@ asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages,
 
        /* Find the mm_struct */
        read_lock(&tasklist_lock);
-       task = pid ? find_task_by_pid(pid) : current;
+       task = pid ? find_task_by_vpid(pid) : current;
        if (!task) {
                read_unlock(&tasklist_lock);
                return -ESRCH;
index 4275e81e25ba69cf49b777ca2819fb6295d7b084..facc1a75bd4fdbc9f274dbc26a7e536f0eb8f561 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1048,8 +1048,7 @@ int vma_wants_writenotify(struct vm_area_struct *vma)
 
        /* The open routine did something to the protections already? */
        if (pgprot_val(vma->vm_page_prot) !=
-           pgprot_val(protection_map[vm_flags &
-                   (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]))
+           pgprot_val(vm_get_page_prot(vm_flags)))
                return 0;
 
        /* Specialty mapping? */
@@ -1130,8 +1129,7 @@ munmap_back:
        vma->vm_start = addr;
        vma->vm_end = addr + len;
        vma->vm_flags = vm_flags;
-       vma->vm_page_prot = protection_map[vm_flags &
-                               (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
+       vma->vm_page_prot = vm_get_page_prot(vm_flags);
        vma->vm_pgoff = pgoff;
 
        if (file) {
@@ -1173,8 +1171,7 @@ munmap_back:
        vm_flags = vma->vm_flags;
 
        if (vma_wants_writenotify(vma))
-               vma->vm_page_prot =
-                       protection_map[vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
+               vma->vm_page_prot = vm_get_page_prot(vm_flags & ~VM_SHARED);
 
        if (!file || !vma_merge(mm, prev, addr, vma->vm_end,
                        vma->vm_flags, NULL, file, pgoff, vma_policy(vma))) {
@@ -2002,8 +1999,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
        vma->vm_end = addr + len;
        vma->vm_pgoff = pgoff;
        vma->vm_flags = flags;
-       vma->vm_page_prot = protection_map[flags &
-                               (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
+       vma->vm_page_prot = vm_get_page_prot(flags);
        vma_link(mm, vma, prev, rb_link, rb_parent);
 out:
        mm->total_vm += len >> PAGE_SHIFT;
@@ -2209,7 +2205,7 @@ int install_special_mapping(struct mm_struct *mm,
        vma->vm_end = addr + len;
 
        vma->vm_flags = vm_flags | mm->def_flags;
-       vma->vm_page_prot = protection_map[vma->vm_flags & 7];
+       vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
 
        vma->vm_ops = &special_mapping_vmops;
        vma->vm_private_data = pages;
index 1d4d69790e59920e8876971dc0ed8adeb48175b8..4de546899dc140d139f218fc53ff0c358c6c5a42 100644 (file)
@@ -192,11 +192,9 @@ success:
         * held in write mode.
         */
        vma->vm_flags = newflags;
-       vma->vm_page_prot = protection_map[newflags &
-               (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
+       vma->vm_page_prot = vm_get_page_prot(newflags);
        if (vma_wants_writenotify(vma)) {
-               vma->vm_page_prot = protection_map[newflags &
-                       (VM_READ|VM_WRITE|VM_EXEC)];
+               vma->vm_page_prot = vm_get_page_prot(newflags & ~VM_SHARED);
                dirty_accountable = 1;
        }
 
index 8ea5c2412c6e155aef62dbaa1fb4c882b77c1acc..08e3c7f2bd15a1b2e502aeb3e9f509148cb5dfa8 100644 (file)
@@ -291,7 +291,7 @@ unsigned long do_mremap(unsigned long addr,
                if ((addr <= new_addr) && (addr+old_len) > new_addr)
                        goto out;
 
-               ret = security_file_mmap(0, 0, 0, 0, new_addr, 1);
+               ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
                if (ret)
                        goto out;
 
@@ -399,7 +399,7 @@ unsigned long do_mremap(unsigned long addr,
                                goto out;
                        }
 
-                       ret = security_file_mmap(0, 0, 0, 0, new_addr, 1);
+                       ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
                        if (ret)
                                goto out;
                }
index 42fb84e9e8152819701d3da1cd449c30a0466db0..8f09333f78e1d63dbe1a5d24c9ba240ce683dbc6 100644 (file)
@@ -175,7 +175,8 @@ EXPORT_SYMBOL(vfree);
 void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
 {
        /*
-        * kmalloc doesn't like __GFP_HIGHMEM for some reason
+        *  You can't specify __GFP_HIGHMEM with kmalloc() since kmalloc()
+        * returns only a logical address.
         */
        return kmalloc(size, (gfp_mask | __GFP_COMP) & ~__GFP_HIGHMEM);
 }
index a64decb5b13fb3922e05a70559855dde685b57b4..91a081a82f55a330706f92d92cd54186ea6339af 100644 (file)
@@ -212,7 +212,7 @@ static struct task_struct *select_bad_process(unsigned long *ppoints)
                if (!p->mm)
                        continue;
                /* skip the init task */
-               if (is_init(p))
+               if (is_global_init(p))
                        continue;
 
                /*
@@ -265,7 +265,7 @@ static struct task_struct *select_bad_process(unsigned long *ppoints)
  */
 static void __oom_kill_task(struct task_struct *p, int verbose)
 {
-       if (is_init(p)) {
+       if (is_global_init(p)) {
                WARN_ON(1);
                printk(KERN_WARNING "tried to kill init!\n");
                return;
@@ -278,7 +278,8 @@ static void __oom_kill_task(struct task_struct *p, int verbose)
        }
 
        if (verbose)
-               printk(KERN_ERR "Killed process %d (%s)\n", p->pid, p->comm);
+               printk(KERN_ERR "Killed process %d (%s)\n",
+                               task_pid_nr(p), p->comm);
 
        /*
         * We give our sacrificial lamb high priority and access to
@@ -326,7 +327,7 @@ static int oom_kill_task(struct task_struct *p)
         * to memory reserves though, otherwise we might deplete all memory.
         */
        do_each_thread(g, q) {
-               if (q->mm == mm && q->tgid != p->tgid)
+               if (q->mm == mm && !same_thread_group(q, p))
                        force_sig(SIGKILL, q);
        } while_each_thread(g, q);
 
@@ -337,7 +338,6 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,
                            unsigned long points, const char *message)
 {
        struct task_struct *c;
-       struct list_head *tsk;
 
        if (printk_ratelimit()) {
                printk(KERN_WARNING "%s invoked oom-killer: "
@@ -357,11 +357,10 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,
        }
 
        printk(KERN_ERR "%s: kill process %d (%s) score %li or a child\n",
-                                       message, p->pid, p->comm, points);
+                                       message, task_pid_nr(p), p->comm, points);
 
        /* Try to kill a child first */
-       list_for_each(tsk, &p->children) {
-               c = list_entry(tsk, struct task_struct, sibling);
+       list_for_each_entry(c, &p->children, sibling) {
                if (c->mm == p->mm)
                        continue;
                if (!oom_kill_task(c))
@@ -497,7 +496,7 @@ retry:
                        panic("Out of memory and no killable processes...\n");
                }
 
-               if (oom_kill_process(p, points, gfp_mask, order,
+               if (oom_kill_process(p, gfp_mask, order, points,
                                     "Out of memory"))
                        goto retry;
 
index 7845462064f4c13457528852c09e5db9e770596b..838a5e31394cbbbe0e9a34b66e1570cf03b5bb86 100644 (file)
@@ -989,7 +989,7 @@ int __set_page_dirty_no_writeback(struct page *page)
  * mapping is pinned by the vma's ->vm_file reference.
  *
  * We take care to handle the case where the page was truncated from the
- * mapping by re-checking page_mapping() insode tree_lock.
+ * mapping by re-checking page_mapping() inside tree_lock.
  */
 int __set_page_dirty_nobuffers(struct page *page)
 {
index 43f757fcf30f6b1dc61cffd2c824e791db28c418..da69d833e0671fe6b8a04b019e47b63c7dcf0f4c 100644 (file)
@@ -123,7 +123,7 @@ static unsigned long __meminitdata dma_reserve;
 
 #ifdef CONFIG_ARCH_POPULATES_NODE_MAP
   /*
-   * MAX_ACTIVE_REGIONS determines the maxmimum number of distinct
+   * MAX_ACTIVE_REGIONS determines the maximum number of distinct
    * ranges of memory (RAM) that may be registered with add_active_range().
    * Ranges passed to add_active_range() will be merged if possible
    * so the number of times add_active_range() can be called is
@@ -1260,7 +1260,7 @@ int zone_watermark_ok(struct zone *z, int order, unsigned long mark,
  * skip over zones that are not allowed by the cpuset, or that have
  * been recently (in last second) found to be nearly full.  See further
  * comments in mmzone.h.  Reduces cache footprint of zonelist scans
- * that have to skip over alot of full or unallowed zones.
+ * that have to skip over a lot of full or unallowed zones.
  *
  * If the zonelist cache is present in the passed in zonelist, then
  * returns a pointer to the allowed node mask (either the current
@@ -2358,7 +2358,7 @@ void build_all_zonelists(void)
                __build_all_zonelists(NULL);
                cpuset_init_current_mems_allowed();
        } else {
-               /* we have to stop all cpus to guaranntee there is no user
+               /* we have to stop all cpus to guarantee there is no user
                   of zonelist */
                stop_machine_run(__build_all_zonelists, NULL, NR_CPUS);
                /* cpuset refresh routine should be here */
@@ -2864,7 +2864,7 @@ static int __meminit first_active_region_index_in_nid(int nid)
 
 /*
  * Basic iterator support. Return the next active range of PFNs for a node
- * Note: nid == MAX_NUMNODES returns next region regardles of node
+ * Note: nid == MAX_NUMNODES returns next region regardless of node
  */
 static int __meminit next_active_region_index_in_nid(int index, int nid)
 {
index b4e76c25f953061a571d23d69353457728a4285a..603ae98d9694dfbf88561abb266021b1bf370fb1 100644 (file)
@@ -34,7 +34,7 @@
  * Radix priority search tree for address_space->i_mmap
  *
  * For each vma that map a unique set of file pages i.e., unique [radix_index,
- * heap_index] value, we have a corresponing priority search tree node. If
+ * heap_index] value, we have a corresponding priority search tree node. If
  * multiple vmas have identical [radix_index, heap_index] value, then one of
  * them is used as a tree node and others are stored in a vm_set list. The tree
  * node points to the first vma (head) of the list using vm_set.head.
index 289dbb0a6fd6dff9e983a42ac7d0f1fdd964e5a3..404e53bb212764f8a6ab7f5bf688c54d4d4c9d06 100644 (file)
@@ -2020,33 +2020,25 @@ static int shmem_match(struct inode *ino, void *vfh)
        return ino->i_ino == inum && fh[0] == ino->i_generation;
 }
 
-static struct dentry *shmem_get_dentry(struct super_block *sb, void *vfh)
+static struct dentry *shmem_fh_to_dentry(struct super_block *sb,
+               struct fid *fid, int fh_len, int fh_type)
 {
-       struct dentry *de = NULL;
        struct inode *inode;
-       __u32 *fh = vfh;
-       __u64 inum = fh[2];
-       inum = (inum << 32) | fh[1];
+       struct dentry *dentry = NULL;
+       u64 inum = fid->raw[2];
+       inum = (inum << 32) | fid->raw[1];
+
+       if (fh_len < 3)
+               return NULL;
 
-       inode = ilookup5(sb, (unsigned long)(inum+fh[0]), shmem_match, vfh);
+       inode = ilookup5(sb, (unsigned long)(inum + fid->raw[0]),
+                       shmem_match, fid->raw);
        if (inode) {
-               de = d_find_alias(inode);
+               dentry = d_find_alias(inode);
                iput(inode);
        }
 
-       return de? de: ERR_PTR(-ESTALE);
-}
-
-static struct dentry *shmem_decode_fh(struct super_block *sb, __u32 *fh,
-               int len, int type,
-               int (*acceptable)(void *context, struct dentry *de),
-               void *context)
-{
-       if (len < 3)
-               return ERR_PTR(-ESTALE);
-
-       return sb->s_export_op->find_exported_dentry(sb, fh, NULL, acceptable,
-                                                       context);
+       return dentry;
 }
 
 static int shmem_encode_fh(struct dentry *dentry, __u32 *fh, int *len,
@@ -2079,11 +2071,10 @@ static int shmem_encode_fh(struct dentry *dentry, __u32 *fh, int *len,
        return 1;
 }
 
-static struct export_operations shmem_export_ops = {
+static const struct export_operations shmem_export_ops = {
        .get_parent     = shmem_get_parent,
-       .get_dentry     = shmem_get_dentry,
        .encode_fh      = shmem_encode_fh,
-       .decode_fh      = shmem_decode_fh,
+       .fh_to_dentry   = shmem_fh_to_dentry,
 };
 
 static int shmem_parse_options(char *options, int *mode, uid_t *uid,
index 3ce9bc024d676c9db1f58a298d5aacc5f1d9c6fa..cfa6be4e378ea1c625081e3ace43c5b212f41968 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -26,7 +26,7 @@
  * initialized objects.
  *
  * This means, that your constructor is used only for newly allocated
- * slabs and you must pass objects with the same intializations to
+ * slabs and you must pass objects with the same initializations to
  * kmem_cache_free.
  *
  * Each cache can only support one memory type (GFP_DMA, GFP_HIGHMEM,
@@ -1156,105 +1156,187 @@ static inline int cache_free_alien(struct kmem_cache *cachep, void *objp)
 }
 #endif
 
-static int __cpuinit cpuup_callback(struct notifier_block *nfb,
-                                   unsigned long action, void *hcpu)
+static void __cpuinit cpuup_canceled(long cpu)
+{
+       struct kmem_cache *cachep;
+       struct kmem_list3 *l3 = NULL;
+       int node = cpu_to_node(cpu);
+
+       list_for_each_entry(cachep, &cache_chain, next) {
+               struct array_cache *nc;
+               struct array_cache *shared;
+               struct array_cache **alien;
+               cpumask_t mask;
+
+               mask = node_to_cpumask(node);
+               /* cpu is dead; no one can alloc from it. */
+               nc = cachep->array[cpu];
+               cachep->array[cpu] = NULL;
+               l3 = cachep->nodelists[node];
+
+               if (!l3)
+                       goto free_array_cache;
+
+               spin_lock_irq(&l3->list_lock);
+
+               /* Free limit for this kmem_list3 */
+               l3->free_limit -= cachep->batchcount;
+               if (nc)
+                       free_block(cachep, nc->entry, nc->avail, node);
+
+               if (!cpus_empty(mask)) {
+                       spin_unlock_irq(&l3->list_lock);
+                       goto free_array_cache;
+               }
+
+               shared = l3->shared;
+               if (shared) {
+                       free_block(cachep, shared->entry,
+                                  shared->avail, node);
+                       l3->shared = NULL;
+               }
+
+               alien = l3->alien;
+               l3->alien = NULL;
+
+               spin_unlock_irq(&l3->list_lock);
+
+               kfree(shared);
+               if (alien) {
+                       drain_alien_cache(cachep, alien);
+                       free_alien_cache(alien);
+               }
+free_array_cache:
+               kfree(nc);
+       }
+       /*
+        * In the previous loop, all the objects were freed to
+        * the respective cache's slabs,  now we can go ahead and
+        * shrink each nodelist to its limit.
+        */
+       list_for_each_entry(cachep, &cache_chain, next) {
+               l3 = cachep->nodelists[node];
+               if (!l3)
+                       continue;
+               drain_freelist(cachep, l3, l3->free_objects);
+       }
+}
+
+static int __cpuinit cpuup_prepare(long cpu)
 {
-       long cpu = (long)hcpu;
        struct kmem_cache *cachep;
        struct kmem_list3 *l3 = NULL;
        int node = cpu_to_node(cpu);
        const int memsize = sizeof(struct kmem_list3);
 
-       switch (action) {
-       case CPU_LOCK_ACQUIRE:
-               mutex_lock(&cache_chain_mutex);
-               break;
-       case CPU_UP_PREPARE:
-       case CPU_UP_PREPARE_FROZEN:
+       /*
+        * We need to do this right in the beginning since
+        * alloc_arraycache's are going to use this list.
+        * kmalloc_node allows us to add the slab to the right
+        * kmem_list3 and not this cpu's kmem_list3
+        */
+
+       list_for_each_entry(cachep, &cache_chain, next) {
                /*
-                * We need to do this right in the beginning since
-                * alloc_arraycache's are going to use this list.
-                * kmalloc_node allows us to add the slab to the right
-                * kmem_list3 and not this cpu's kmem_list3
+                * Set up the size64 kmemlist for cpu before we can
+                * begin anything. Make sure some other cpu on this
+                * node has not already allocated this
                 */
+               if (!cachep->nodelists[node]) {
+                       l3 = kmalloc_node(memsize, GFP_KERNEL, node);
+                       if (!l3)
+                               goto bad;
+                       kmem_list3_init(l3);
+                       l3->next_reap = jiffies + REAPTIMEOUT_LIST3 +
+                           ((unsigned long)cachep) % REAPTIMEOUT_LIST3;
 
-               list_for_each_entry(cachep, &cache_chain, next) {
                        /*
-                        * Set up the size64 kmemlist for cpu before we can
-                        * begin anything. Make sure some other cpu on this
-                        * node has not already allocated this
+                        * The l3s don't come and go as CPUs come and
+                        * go.  cache_chain_mutex is sufficient
+                        * protection here.
                         */
-                       if (!cachep->nodelists[node]) {
-                               l3 = kmalloc_node(memsize, GFP_KERNEL, node);
-                               if (!l3)
-                                       goto bad;
-                               kmem_list3_init(l3);
-                               l3->next_reap = jiffies + REAPTIMEOUT_LIST3 +
-                                   ((unsigned long)cachep) % REAPTIMEOUT_LIST3;
-
-                               /*
-                                * The l3s don't come and go as CPUs come and
-                                * go.  cache_chain_mutex is sufficient
-                                * protection here.
-                                */
-                               cachep->nodelists[node] = l3;
-                       }
-
-                       spin_lock_irq(&cachep->nodelists[node]->list_lock);
-                       cachep->nodelists[node]->free_limit =
-                               (1 + nr_cpus_node(node)) *
-                               cachep->batchcount + cachep->num;
-                       spin_unlock_irq(&cachep->nodelists[node]->list_lock);
+                       cachep->nodelists[node] = l3;
                }
 
-               /*
-                * Now we can go ahead with allocating the shared arrays and
-                * array caches
-                */
-               list_for_each_entry(cachep, &cache_chain, next) {
-                       struct array_cache *nc;
-                       struct array_cache *shared = NULL;
-                       struct array_cache **alien = NULL;
-
-                       nc = alloc_arraycache(node, cachep->limit,
-                                               cachep->batchcount);
-                       if (!nc)
+               spin_lock_irq(&cachep->nodelists[node]->list_lock);
+               cachep->nodelists[node]->free_limit =
+                       (1 + nr_cpus_node(node)) *
+                       cachep->batchcount + cachep->num;
+               spin_unlock_irq(&cachep->nodelists[node]->list_lock);
+       }
+
+       /*
+        * Now we can go ahead with allocating the shared arrays and
+        * array caches
+        */
+       list_for_each_entry(cachep, &cache_chain, next) {
+               struct array_cache *nc;
+               struct array_cache *shared = NULL;
+               struct array_cache **alien = NULL;
+
+               nc = alloc_arraycache(node, cachep->limit,
+                                       cachep->batchcount);
+               if (!nc)
+                       goto bad;
+               if (cachep->shared) {
+                       shared = alloc_arraycache(node,
+                               cachep->shared * cachep->batchcount,
+                               0xbaadf00d);
+                       if (!shared) {
+                               kfree(nc);
                                goto bad;
-                       if (cachep->shared) {
-                               shared = alloc_arraycache(node,
-                                       cachep->shared * cachep->batchcount,
-                                       0xbaadf00d);
-                               if (!shared)
-                                       goto bad;
                        }
-                       if (use_alien_caches) {
-                                alien = alloc_alien_cache(node, cachep->limit);
-                                if (!alien)
-                                        goto bad;
-                        }
-                       cachep->array[cpu] = nc;
-                       l3 = cachep->nodelists[node];
-                       BUG_ON(!l3);
-
-                       spin_lock_irq(&l3->list_lock);
-                       if (!l3->shared) {
-                               /*
-                                * We are serialised from CPU_DEAD or
-                                * CPU_UP_CANCELLED by the cpucontrol lock
-                                */
-                               l3->shared = shared;
-                               shared = NULL;
+               }
+               if (use_alien_caches) {
+                       alien = alloc_alien_cache(node, cachep->limit);
+                       if (!alien) {
+                               kfree(shared);
+                               kfree(nc);
+                               goto bad;
                        }
+               }
+               cachep->array[cpu] = nc;
+               l3 = cachep->nodelists[node];
+               BUG_ON(!l3);
+
+               spin_lock_irq(&l3->list_lock);
+               if (!l3->shared) {
+                       /*
+                        * We are serialised from CPU_DEAD or
+                        * CPU_UP_CANCELLED by the cpucontrol lock
+                        */
+                       l3->shared = shared;
+                       shared = NULL;
+               }
 #ifdef CONFIG_NUMA
-                       if (!l3->alien) {
-                               l3->alien = alien;
-                               alien = NULL;
-                       }
-#endif
-                       spin_unlock_irq(&l3->list_lock);
-                       kfree(shared);
-                       free_alien_cache(alien);
+               if (!l3->alien) {
+                       l3->alien = alien;
+                       alien = NULL;
                }
+#endif
+               spin_unlock_irq(&l3->list_lock);
+               kfree(shared);
+               free_alien_cache(alien);
+       }
+       return 0;
+bad:
+       cpuup_canceled(cpu);
+       return -ENOMEM;
+}
+
+static int __cpuinit cpuup_callback(struct notifier_block *nfb,
+                                   unsigned long action, void *hcpu)
+{
+       long cpu = (long)hcpu;
+       int err = 0;
+
+       switch (action) {
+       case CPU_LOCK_ACQUIRE:
+               mutex_lock(&cache_chain_mutex);
+               break;
+       case CPU_UP_PREPARE:
+       case CPU_UP_PREPARE_FROZEN:
+               err = cpuup_prepare(cpu);
                break;
        case CPU_ONLINE:
        case CPU_ONLINE_FROZEN:
@@ -1287,76 +1369,17 @@ static int __cpuinit cpuup_callback(struct notifier_block *nfb,
                 * structure is usually allocated from kmem_cache_create() and
                 * gets destroyed at kmem_cache_destroy().
                 */
-               /* fall thru */
+               /* fall through */
 #endif
        case CPU_UP_CANCELED:
        case CPU_UP_CANCELED_FROZEN:
-               list_for_each_entry(cachep, &cache_chain, next) {
-                       struct array_cache *nc;
-                       struct array_cache *shared;
-                       struct array_cache **alien;
-                       cpumask_t mask;
-
-                       mask = node_to_cpumask(node);
-                       /* cpu is dead; no one can alloc from it. */
-                       nc = cachep->array[cpu];
-                       cachep->array[cpu] = NULL;
-                       l3 = cachep->nodelists[node];
-
-                       if (!l3)
-                               goto free_array_cache;
-
-                       spin_lock_irq(&l3->list_lock);
-
-                       /* Free limit for this kmem_list3 */
-                       l3->free_limit -= cachep->batchcount;
-                       if (nc)
-                               free_block(cachep, nc->entry, nc->avail, node);
-
-                       if (!cpus_empty(mask)) {
-                               spin_unlock_irq(&l3->list_lock);
-                               goto free_array_cache;
-                       }
-
-                       shared = l3->shared;
-                       if (shared) {
-                               free_block(cachep, shared->entry,
-                                          shared->avail, node);
-                               l3->shared = NULL;
-                       }
-
-                       alien = l3->alien;
-                       l3->alien = NULL;
-
-                       spin_unlock_irq(&l3->list_lock);
-
-                       kfree(shared);
-                       if (alien) {
-                               drain_alien_cache(cachep, alien);
-                               free_alien_cache(alien);
-                       }
-free_array_cache:
-                       kfree(nc);
-               }
-               /*
-                * In the previous loop, all the objects were freed to
-                * the respective cache's slabs,  now we can go ahead and
-                * shrink each nodelist to its limit.
-                */
-               list_for_each_entry(cachep, &cache_chain, next) {
-                       l3 = cachep->nodelists[node];
-                       if (!l3)
-                               continue;
-                       drain_freelist(cachep, l3, l3->free_objects);
-               }
+               cpuup_canceled(cpu);
                break;
        case CPU_LOCK_RELEASE:
                mutex_unlock(&cache_chain_mutex);
                break;
        }
-       return NOTIFY_OK;
-bad:
-       return NOTIFY_BAD;
+       return err ? NOTIFY_BAD : NOTIFY_OK;
 }
 
 static struct notifier_block __cpuinitdata cpucache_notifier = {
@@ -3783,7 +3806,7 @@ const char *kmem_cache_name(struct kmem_cache *cachep)
 EXPORT_SYMBOL_GPL(kmem_cache_name);
 
 /*
- * This initializes kmem_list3 or resizes varioius caches for all nodes.
+ * This initializes kmem_list3 or resizes various caches for all nodes.
  */
 static int alloc_kmemlist(struct kmem_cache *cachep)
 {
index e29a42988c78ca17d9594c2cb9fdb3cb87c257d0..aac1dd3c657d1de350c5e7615a31d0c8021abb55 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -20,6 +20,7 @@
 #include <linux/mempolicy.h>
 #include <linux/ctype.h>
 #include <linux/kallsyms.h>
+#include <linux/memory.h>
 
 /*
  * Lock order:
@@ -2694,6 +2695,121 @@ int kmem_cache_shrink(struct kmem_cache *s)
 }
 EXPORT_SYMBOL(kmem_cache_shrink);
 
+#if defined(CONFIG_NUMA) && defined(CONFIG_MEMORY_HOTPLUG)
+static int slab_mem_going_offline_callback(void *arg)
+{
+       struct kmem_cache *s;
+
+       down_read(&slub_lock);
+       list_for_each_entry(s, &slab_caches, list)
+               kmem_cache_shrink(s);
+       up_read(&slub_lock);
+
+       return 0;
+}
+
+static void slab_mem_offline_callback(void *arg)
+{
+       struct kmem_cache_node *n;
+       struct kmem_cache *s;
+       struct memory_notify *marg = arg;
+       int offline_node;
+
+       offline_node = marg->status_change_nid;
+
+       /*
+        * If the node still has available memory. we need kmem_cache_node
+        * for it yet.
+        */
+       if (offline_node < 0)
+               return;
+
+       down_read(&slub_lock);
+       list_for_each_entry(s, &slab_caches, list) {
+               n = get_node(s, offline_node);
+               if (n) {
+                       /*
+                        * if n->nr_slabs > 0, slabs still exist on the node
+                        * that is going down. We were unable to free them,
+                        * and offline_pages() function shoudn't call this
+                        * callback. So, we must fail.
+                        */
+                       BUG_ON(atomic_read(&n->nr_slabs));
+
+                       s->node[offline_node] = NULL;
+                       kmem_cache_free(kmalloc_caches, n);
+               }
+       }
+       up_read(&slub_lock);
+}
+
+static int slab_mem_going_online_callback(void *arg)
+{
+       struct kmem_cache_node *n;
+       struct kmem_cache *s;
+       struct memory_notify *marg = arg;
+       int nid = marg->status_change_nid;
+       int ret = 0;
+
+       /*
+        * If the node's memory is already available, then kmem_cache_node is
+        * already created. Nothing to do.
+        */
+       if (nid < 0)
+               return 0;
+
+       /*
+        * We are bringing a node online. No memory is availabe yet. We must
+        * allocate a kmem_cache_node structure in order to bring the node
+        * online.
+        */
+       down_read(&slub_lock);
+       list_for_each_entry(s, &slab_caches, list) {
+               /*
+                * XXX: kmem_cache_alloc_node will fallback to other nodes
+                *      since memory is not yet available from the node that
+                *      is brought up.
+                */
+               n = kmem_cache_alloc(kmalloc_caches, GFP_KERNEL);
+               if (!n) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+               init_kmem_cache_node(n);
+               s->node[nid] = n;
+       }
+out:
+       up_read(&slub_lock);
+       return ret;
+}
+
+static int slab_memory_callback(struct notifier_block *self,
+                               unsigned long action, void *arg)
+{
+       int ret = 0;
+
+       switch (action) {
+       case MEM_GOING_ONLINE:
+               ret = slab_mem_going_online_callback(arg);
+               break;
+       case MEM_GOING_OFFLINE:
+               ret = slab_mem_going_offline_callback(arg);
+               break;
+       case MEM_OFFLINE:
+       case MEM_CANCEL_ONLINE:
+               slab_mem_offline_callback(arg);
+               break;
+       case MEM_ONLINE:
+       case MEM_CANCEL_OFFLINE:
+               break;
+       }
+
+       ret = notifier_from_errno(ret);
+       return ret;
+}
+
+#endif /* CONFIG_MEMORY_HOTPLUG */
+
 /********************************************************************
  *                     Basic setup of slabs
  *******************************************************************/
@@ -2715,6 +2831,8 @@ void __init kmem_cache_init(void)
                sizeof(struct kmem_cache_node), GFP_KERNEL);
        kmalloc_caches[0].refcount = -1;
        caches++;
+
+       hotplug_memory_notifier(slab_memory_callback, 1);
 #endif
 
        /* Able to allocate the per node structures */
index a65eff8a517af30716ffb863b9866098abeccc3d..9ac88323d237a82e9a6bf4a91fced71225a4e318 100644 (file)
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -5,7 +5,7 @@
  */
 
 /*
- * This file contains the default values for the opereation of the
+ * This file contains the default values for the operation of the
  * Linux VM subsystem. Fine-tuning documentation can be found in
  * Documentation/sysctl/vm.txt.
  * Started 18.12.91
index 2e01af365848eb3d8485369d2fc4d9c4dad2a05c..af77e171e339a357933d7eb6ba4b001efae5e390 100644 (file)
@@ -247,7 +247,7 @@ struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
 EXPORT_SYMBOL_GPL(__get_vm_area);
 
 /**
- *     get_vm_area  -  reserve a contingous kernel virtual area
+ *     get_vm_area  -  reserve a contiguous kernel virtual area
  *     @size:          size of the area
  *     @flags:         %VM_IOREMAP for I/O mappings or VM_ALLOC
  *
@@ -303,7 +303,7 @@ found:
 }
 
 /**
- *     remove_vm_area  -  find and remove a contingous kernel virtual area
+ *     remove_vm_area  -  find and remove a continuous kernel virtual area
  *     @addr:          base address
  *
  *     Search for the kernel VM area starting at @addr, and remove it.
@@ -364,7 +364,7 @@ static void __vunmap(void *addr, int deallocate_pages)
  *     vfree  -  release memory allocated by vmalloc()
  *     @addr:          memory base address
  *
- *     Free the virtually contiguous memory area starting at @addr, as
+ *     Free the virtually continuous memory area starting at @addr, as
  *     obtained from vmalloc(), vmalloc_32() or __vmalloc(). If @addr is
  *     NULL, no operation is performed.
  *
index e1471385d0014a79e4e7834b1c6e1f46c80cba1e..e5a9597e3bbc7aad2ed7af943528aa164eb4aa36 100644 (file)
@@ -141,7 +141,7 @@ EXPORT_SYMBOL(unregister_shrinker);
  * percentages of the lru and ageable caches.  This should balance the seeks
  * generated by these structures.
  *
- * If the vm encounted mapped pages on the LRU it increase the pressure on
+ * If the vm encountered mapped pages on the LRU it increase the pressure on
  * slab to avoid swapping.
  *
  * We do weird things to avoid (scanned*seeks*entries) overflowing 32 bits.
@@ -1282,7 +1282,7 @@ out:
         */
        if (priority < 0)
                priority = 0;
-       for (i = 0; zones[i] != 0; i++) {
+       for (i = 0; zones[i] != NULL; i++) {
                struct zone *zone = zones[i];
 
                if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL))
index eecbf12f6393eefebd8bb41b3419f9f94032682e..bafc50c9e6ff6891e4fb2b4fbab7f61ab9dc92ca 100644 (file)
@@ -23,9 +23,16 @@ config NET_9P_FD
          file descriptors.  TCP/IP is the default transport for 9p,
          so if you are going to use 9p, you'll likely want this.
 
+config NET_9P_VIRTIO
+       depends on NET_9P && EXPERIMENTAL && VIRTIO
+       tristate "9P Virtio Transport (Experimental)"
+       help
+         This builds support for a transports between
+         guest partitions and a host partition.
+
 config NET_9P_DEBUG
        bool "Debug information"
        depends on NET_9P
        help
-         Say Y if you want the 9P subsistem to log debug information.
+         Say Y if you want the 9P subsystem to log debug information.
 
index 5059bc06f8f3600ecdd620f7c01d412a2e9c3061..d3abb246ccab41af3b237945f0fd520e96e451fe 100644 (file)
@@ -1,5 +1,6 @@
 obj-$(CONFIG_NET_9P) := 9pnet.o
 obj-$(CONFIG_NET_9P_FD) += 9pnet_fd.o
+obj-$(CONFIG_NET_9P_VIRTIO) += 9pnet_virtio.o
 
 9pnet-objs := \
        mod.o \
@@ -12,3 +13,6 @@ obj-$(CONFIG_NET_9P_FD) += 9pnet_fd.o
 
 9pnet_fd-objs := \
        trans_fd.o \
+
+9pnet_virtio-objs := \
+       trans_virtio.o \
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
new file mode 100644 (file)
index 0000000..40b71a2
--- /dev/null
@@ -0,0 +1,353 @@
+/*
+ * The Guest 9p transport driver
+ *
+ * This is a trivial pipe-based transport driver based on the lguest console
+ * code: we use lguest's DMA mechanism to send bytes out, and register a
+ * DMA buffer to receive bytes in.  It is assumed to be present and available
+ * from the very beginning of boot.
+ *
+ * This may be have been done by just instaniating another HVC console,
+ * but HVC's blocksize of 16 bytes is annoying and painful to performance.
+ *
+ * A more efficient transport could be built based on the virtio block driver
+ * but it requires some changes in the 9p transport model (which are in
+ * progress)
+ *
+ */
+/*
+ *  Copyright (C) 2007 Eric Van Hensbergen, IBM Corporation
+ *
+ *  Based on virtio console driver
+ *  Copyright (C) 2006, 2007 Rusty Russell, 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.
+ *
+ *  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/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 <net/9p/9p.h>
+#include <linux/parser.h>
+#include <net/9p/transport.h>
+#include <linux/scatterlist.h>
+#include <linux/virtio.h>
+#include <linux/virtio_9p.h>
+
+/* a single mutex to manage channel initialization and attachment */
+static DECLARE_MUTEX(virtio_9p_lock);
+/* global which tracks highest initialized channel */
+static int chan_index;
+
+/* We keep all per-channel information in a structure.
+ * This structure is allocated within the devices dev->mem space.
+ * A pointer to the structure will get put in the transport private.
+ */
+static struct virtio_chan {
+       bool initialized;               /* channel is initialized */
+       bool inuse;                     /* channel is in use */
+
+       struct virtqueue *in_vq, *out_vq;
+       struct virtio_device *vdev;
+
+       /* This is our input buffer, and how much data is left in it. */
+       unsigned int in_len;
+       char *in, *inbuf;
+
+       wait_queue_head_t wq;           /* waitq for buffer */
+} channels[MAX_9P_CHAN];
+
+/* How many bytes left in this page. */
+static unsigned int rest_of_page(void *data)
+{
+       return PAGE_SIZE - ((unsigned long)data % PAGE_SIZE);
+}
+
+static int p9_virtio_write(struct p9_trans *trans, void *buf, int count)
+{
+       struct virtio_chan *chan = (struct virtio_chan *) trans->priv;
+       struct virtqueue *out_vq = chan->out_vq;
+       struct scatterlist sg[1];
+       unsigned int len;
+
+       P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio write (%d)\n", count);
+
+       /* keep it simple - make sure we don't overflow a page */
+       if (rest_of_page(buf) < count)
+               count = rest_of_page(buf);
+
+       sg_init_one(sg, buf, count);
+
+       /* add_buf wants a token to identify this buffer: we hand it any
+        * non-NULL pointer, since there's only ever one buffer. */
+       if (out_vq->vq_ops->add_buf(out_vq, sg, 1, 0, (void *)1) == 0) {
+               /* Tell Host to go! */
+               out_vq->vq_ops->kick(out_vq);
+               /* Chill out until it's done with the buffer. */
+               while (!out_vq->vq_ops->get_buf(out_vq, &len))
+                       cpu_relax();
+       }
+
+       P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio wrote (%d)\n", count);
+
+       /* We're expected to return the amount of data we wrote: all of it. */
+       return count;
+}
+
+/* Create a scatter-gather list representing our input buffer and put it in the
+ * queue. */
+static void add_inbuf(struct virtio_chan *chan)
+{
+       struct scatterlist sg[1];
+
+       sg_init_one(sg, chan->inbuf, PAGE_SIZE);
+
+       /* We should always be able to add one buffer to an empty queue. */
+       if (chan->in_vq->vq_ops->add_buf(chan->in_vq, sg, 0, 1, chan->inbuf))
+               BUG();
+       chan->in_vq->vq_ops->kick(chan->in_vq);
+}
+
+static int p9_virtio_read(struct p9_trans *trans, void *buf, int count)
+{
+       struct virtio_chan *chan = (struct virtio_chan *) trans->priv;
+       struct virtqueue *in_vq = chan->in_vq;
+
+       P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio read (%d)\n", count);
+
+       /* If we don't have an input queue yet, we can't get input. */
+       BUG_ON(!in_vq);
+
+       /* No buffer?  Try to get one. */
+       if (!chan->in_len) {
+               chan->in = in_vq->vq_ops->get_buf(in_vq, &chan->in_len);
+               if (!chan->in)
+                       return 0;
+       }
+
+       /* You want more than we have to give?  Well, try wanting less! */
+       if (chan->in_len < count)
+               count = chan->in_len;
+
+       /* Copy across to their buffer and increment offset. */
+       memcpy(buf, chan->in, count);
+       chan->in += count;
+       chan->in_len -= count;
+
+       /* Finished?  Re-register buffer so Host will use it again. */
+       if (chan->in_len == 0)
+               add_inbuf(chan);
+
+       P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio finished read (%d)\n",
+                                                                       count);
+
+       return count;
+}
+
+/* The poll function is used by 9p transports to determine if there
+ * is there is activity available on a particular channel.  In our case
+ * we use it to wait for a callback from the input routines.
+ */
+static unsigned int
+p9_virtio_poll(struct p9_trans *trans, struct poll_table_struct *pt)
+{
+       struct virtio_chan *chan = (struct virtio_chan *)trans->priv;
+       struct virtqueue *in_vq = chan->in_vq;
+       int ret = POLLOUT; /* we can always handle more output */
+
+       poll_wait(NULL, &chan->wq, pt);
+
+       /* No buffer?  Try to get one. */
+       if (!chan->in_len)
+               chan->in = in_vq->vq_ops->get_buf(in_vq, &chan->in_len);
+
+       if (chan->in_len)
+               ret |= POLLIN;
+
+       return ret;
+}
+
+static void p9_virtio_close(struct p9_trans *trans)
+{
+       struct virtio_chan *chan = trans->priv;
+
+       down(&virtio_9p_lock);
+       chan->inuse = false;
+       up(&virtio_9p_lock);
+
+       kfree(trans);
+}
+
+static bool p9_virtio_intr(struct virtqueue *q)
+{
+       struct virtio_chan *chan = q->vdev->priv;
+
+       P9_DPRINTK(P9_DEBUG_TRANS, "9p poll_wakeup: %p\n", &chan->wq);
+       wake_up_interruptible(&chan->wq);
+
+       return true;
+}
+
+static int p9_virtio_probe(struct virtio_device *dev)
+{
+       int err;
+       struct virtio_chan *chan;
+       int index;
+
+       down(&virtio_9p_lock);
+       index = chan_index++;
+       chan = &channels[index];
+       up(&virtio_9p_lock);
+
+       if (chan_index > MAX_9P_CHAN) {
+               printk(KERN_ERR "9p: virtio: Maximum channels exceeded\n");
+               BUG();
+       }
+
+       chan->vdev = dev;
+
+       /* This is the scratch page we use to receive console input */
+       chan->inbuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+       if (!chan->inbuf) {
+               err = -ENOMEM;
+               goto fail;
+       }
+
+       /* Find the input queue. */
+       dev->priv = chan;
+       chan->in_vq = dev->config->find_vq(dev, p9_virtio_intr);
+       if (IS_ERR(chan->in_vq)) {
+               err = PTR_ERR(chan->in_vq);
+               goto free;
+       }
+
+       chan->out_vq = dev->config->find_vq(dev, NULL);
+       if (IS_ERR(chan->out_vq)) {
+               err = PTR_ERR(chan->out_vq);
+               goto free_in_vq;
+       }
+
+       init_waitqueue_head(&chan->wq);
+
+       /* Register the input buffer the first time. */
+       add_inbuf(chan);
+       chan->inuse = false;
+       chan->initialized = true;
+
+       return 0;
+
+free_in_vq:
+       dev->config->del_vq(chan->in_vq);
+free:
+       kfree(chan->inbuf);
+fail:
+       down(&virtio_9p_lock);
+       chan_index--;
+       up(&virtio_9p_lock);
+       return err;
+}
+
+/* This sets up a transport channel for 9p communication.  Right now
+ * we only match the first available channel, but eventually we couldlook up
+ * alternate channels by matching devname versus a virtio_config entry.
+ * We use a simple reference count mechanism to ensure that only a single
+ * mount has a channel open at a time. */
+static struct p9_trans *p9_virtio_create(const char *devname, char *args)
+{
+       struct p9_trans *trans;
+       int index = 0;
+       struct virtio_chan *chan = channels;
+
+       down(&virtio_9p_lock);
+       while (index < MAX_9P_CHAN) {
+               if (chan->initialized && !chan->inuse) {
+                       chan->inuse = true;
+                       break;
+               } else {
+                       index++;
+                       chan = &channels[index];
+               }
+       }
+       up(&virtio_9p_lock);
+
+       if (index >= MAX_9P_CHAN) {
+               printk(KERN_ERR "9p: virtio: couldn't find a free channel\n");
+               return NULL;
+       }
+
+       trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL);
+       if (!trans) {
+               printk(KERN_ERR "9p: couldn't allocate transport\n");
+               return ERR_PTR(-ENOMEM);
+       }
+
+       trans->write = p9_virtio_write;
+       trans->read = p9_virtio_read;
+       trans->close = p9_virtio_close;
+       trans->poll = p9_virtio_poll;
+       trans->priv = chan;
+
+       return trans;
+}
+
+#define VIRTIO_ID_9P 9
+
+static struct virtio_device_id id_table[] = {
+       { VIRTIO_ID_9P, VIRTIO_DEV_ANY_ID },
+       { 0 },
+};
+
+/* The standard "struct lguest_driver": */
+static struct virtio_driver p9_virtio_drv = {
+       .driver.name =  KBUILD_MODNAME,
+       .driver.owner = THIS_MODULE,
+       .id_table =     id_table,
+       .probe =        p9_virtio_probe,
+};
+
+static struct p9_trans_module p9_virtio_trans = {
+       .name = "virtio",
+       .create = p9_virtio_create,
+       .maxsize = PAGE_SIZE,
+       .def = 0,
+};
+
+/* The standard init function */
+static int __init p9_virtio_init(void)
+{
+       int count;
+
+       for (count = 0; count < MAX_9P_CHAN; count++)
+               channels[count].initialized = false;
+
+       v9fs_register_trans(&p9_virtio_trans);
+       return register_virtio_driver(&p9_virtio_drv);
+}
+
+module_init(p9_virtio_init);
+
+MODULE_DEVICE_TABLE(virtio, id_table);
+MODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>");
+MODULE_DESCRIPTION("Virtio 9p Transport");
+MODULE_LICENSE("GPL");
index c742d37bfb972c631d45fda6bd1580d5216c5d3b..ba6428f204f9020209bc1dd693a5aa0e4727f4ac 100644 (file)
@@ -24,16 +24,6 @@ Author: Marcell GAL, 2000, XDSL Ltd, Hungary
 
 #include "common.h"
 
-/*
- * Define this to use a version of the code which interacts with the higher
- * layers in a more intellegent way, by always reserving enough space for
- * our header at the begining of the packet.  However, there may still be
- * some problems with programs like tcpdump.  In 2.5 we'll sort out what
- * we need to do to get this perfect.  For now we just will copy the packet
- * if we need space for the header
- */
-/* #define FASTER_VERSION */
-
 #ifdef SKB_DEBUG
 static void skb_debug(const struct sk_buff *skb)
 {
@@ -69,9 +59,7 @@ struct br2684_vcc {
 #ifdef CONFIG_ATM_BR2684_IPFILTER
        struct br2684_filter filter;
 #endif /* CONFIG_ATM_BR2684_IPFILTER */
-#ifndef FASTER_VERSION
        unsigned copies_needed, copies_failed;
-#endif /* FASTER_VERSION */
 };
 
 struct br2684_dev {
@@ -147,13 +135,6 @@ static int br2684_xmit_vcc(struct sk_buff *skb, struct br2684_dev *brdev,
        struct br2684_vcc *brvcc)
 {
        struct atm_vcc *atmvcc;
-#ifdef FASTER_VERSION
-       if (brvcc->encaps == e_llc)
-               memcpy(skb_push(skb, 8), llc_oui_pid_pad, 8);
-       /* last 2 bytes of llc_oui_pid_pad are managed by header routines;
-          yes, you got it: 8 + 2 = sizeof(llc_oui_pid_pad)
-        */
-#else
        int minheadroom = (brvcc->encaps == e_llc) ? 10 : 2;
        if (skb_headroom(skb) < minheadroom) {
                struct sk_buff *skb2 = skb_realloc_headroom(skb, minheadroom);
@@ -170,7 +151,6 @@ static int br2684_xmit_vcc(struct sk_buff *skb, struct br2684_dev *brdev,
                skb_copy_to_linear_data(skb, llc_oui_pid_pad, 10);
        else
                memset(skb->data, 0, 2);
-#endif /* FASTER_VERSION */
        skb_debug(skb);
 
        ATM_SKB(skb)->vcc = atmvcc = brvcc->atmvcc;
@@ -237,87 +217,6 @@ static struct net_device_stats *br2684_get_stats(struct net_device *dev)
        return &BRPRIV(dev)->stats;
 }
 
-#ifdef FASTER_VERSION
-/*
- * These mirror eth_header and eth_header_cache.  They are not usually
- * exported for use in modules, so we grab them from net_device
- * after ether_setup() is done with it.  Bit of a hack.
- */
-static int (*my_eth_header)(struct sk_buff *, struct net_device *,
-       unsigned short, void *, void *, unsigned);
-static int (*my_eth_header_cache)(struct neighbour *, struct hh_cache *);
-
-static int
-br2684_header(struct sk_buff *skb, struct net_device *dev,
-             unsigned short type, void *daddr, void *saddr, unsigned len)
-{
-       u16 *pad_before_eth;
-       int t = my_eth_header(skb, dev, type, daddr, saddr, len);
-       if (t > 0) {
-               pad_before_eth = (u16 *) skb_push(skb, 2);
-               *pad_before_eth = 0;
-               return dev->hard_header_len;    /* or return 16; ? */
-       } else
-               return t;
-}
-
-static int
-br2684_header_cache(struct neighbour *neigh, struct hh_cache *hh)
-{
-/* hh_data is 16 bytes long. if encaps is ether-llc we need 24, so
-xmit will add the additional header part in that case */
-       u16 *pad_before_eth = (u16 *)(hh->hh_data);
-       int t = my_eth_header_cache(neigh, hh);
-       DPRINTK("br2684_header_cache, neigh=%p, hh_cache=%p\n", neigh, hh);
-       if (t < 0)
-               return t;
-       else {
-               *pad_before_eth = 0;
-               hh->hh_len = PADLEN + ETH_HLEN;
-       }
-       return 0;
-}
-
-/*
- * This is similar to eth_type_trans, which cannot be used because of
- * our dev->hard_header_len
- */
-static inline __be16 br_type_trans(struct sk_buff *skb, struct net_device *dev)
-{
-       struct ethhdr *eth;
-       unsigned char *rawp;
-       eth = eth_hdr(skb);
-
-       if (is_multicast_ether_addr(eth->h_dest)) {
-               if (!compare_ether_addr(eth->h_dest, dev->broadcast))
-                       skb->pkt_type = PACKET_BROADCAST;
-               else
-                       skb->pkt_type = PACKET_MULTICAST;
-       }
-
-       else if (compare_ether_addr(eth->h_dest, dev->dev_addr))
-               skb->pkt_type = PACKET_OTHERHOST;
-
-       if (ntohs(eth->h_proto) >= 1536)
-               return eth->h_proto;
-
-       rawp = skb->data;
-
-       /*
-        * This is a magic hack to spot IPX packets. Older Novell breaks
-        * the protocol design and runs IPX over 802.3 without an 802.2 LLC
-        * layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
-        * won't work for fault tolerant netware but does for the rest.
-        */
-       if (*(unsigned short *) rawp == 0xFFFF)
-               return htons(ETH_P_802_3);
-
-       /*
-        * Real 802.2 LLC
-        */
-       return htons(ETH_P_802_2);
-}
-#endif /* FASTER_VERSION */
 
 /*
  * We remember when the MAC gets set, so we don't override it later with
@@ -448,17 +347,8 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
                return;
        }
 
-#ifdef FASTER_VERSION
-       /* FIXME: tcpdump shows that pointer to mac header is 2 bytes earlier,
-          than should be. What else should I set? */
-       skb_pull(skb, plen);
-       skb_set_mac_header(skb, -ETH_HLEN);
-       skb->pkt_type = PACKET_HOST;
-       skb->protocol = br_type_trans(skb, net_dev);
-#else
        skb_pull(skb, plen - ETH_HLEN);
        skb->protocol = eth_type_trans(skb, net_dev);
-#endif /* FASTER_VERSION */
 #ifdef CONFIG_ATM_BR2684_IPFILTER
        if (unlikely(packet_fails_filter(skb->protocol, brvcc, skb))) {
                brdev->stats.rx_dropped++;
@@ -584,13 +474,6 @@ static void br2684_setup(struct net_device *netdev)
        ether_setup(netdev);
        brdev->net_dev = netdev;
 
-#ifdef FASTER_VERSION
-       my_eth_header = netdev->hard_header;
-       netdev->hard_header = br2684_header;
-       my_eth_header_cache = netdev->hard_header_cache;
-       netdev->hard_header_cache = br2684_header_cache;
-       netdev->hard_header_len = sizeof(llc_oui_pid_pad) + ETH_HLEN;   /* 10 + 14 */
-#endif
        my_eth_mac_addr = netdev->set_mac_address;
        netdev->set_mac_address = br2684_mac_addr;
        netdev->hard_start_xmit = br2684_start_xmit;
@@ -719,16 +602,12 @@ static int br2684_seq_show(struct seq_file *seq, void *v)
 
        list_for_each_entry(brvcc, &brdev->brvccs, brvccs) {
                seq_printf(seq, "  vcc %d.%d.%d: encaps=%s"
-#ifndef FASTER_VERSION
                                    ", failed copies %u/%u"
-#endif /* FASTER_VERSION */
                                    "\n", brvcc->atmvcc->dev->number,
                                    brvcc->atmvcc->vpi, brvcc->atmvcc->vci,
                                    (brvcc->encaps == e_llc) ? "LLC" : "VC"
-#ifndef FASTER_VERSION
                                    , brvcc->copies_failed
                                    , brvcc->copies_needed
-#endif /* FASTER_VERSION */
                                    );
 #ifdef CONFIG_ATM_BR2684_IPFILTER
 #define b1(var, byte)  ((u8 *) &brvcc->filter.var)[byte]
index e37d217a986a6bc0de5ab3aa05f7d0c96014b96b..8273b1200eeefe701974106ed3ddbc39ed973621 100644 (file)
@@ -75,7 +75,7 @@ static int ax25_ds_state1_machine(ax25_cb *ax25, struct sk_buff *skb, int framet
                }
                ax25_dama_on(ax25);
 
-               /* according to DK4EG´s spec we are required to
+               /* according to DK4EG's spec we are required to
                 * send a RR RESPONSE FINAL NR=0.
                 */
 
index a49773ff2b92262ab7e75479d3ef4325014063e2..b5e59787be2f145084dfe15a6189e2f0923222b2 100644 (file)
@@ -41,7 +41,7 @@ void ax25_ds_enquiry_response(ax25_cb *ax25)
        ax25_cb *ax25o;
        struct hlist_node *node;
 
-       /* Please note that neither DK4EG´s nor DG2FEF´s
+       /* Please note that neither DK4EG's nor DG2FEF's
         * DAMA spec mention the following behaviour as seen
         * with TheFirmware:
         *
index 1f78c3e336d8cb460cfeb70ec5f7f053e20bddf7..347e935faaf0a175cfb23929b92dd9bbaf5682d1 100644 (file)
@@ -2,7 +2,7 @@
    BNEP implementation for Linux Bluetooth stack (BlueZ).
    Copyright (C) 2001-2002 Inventel Systemes
    Written 2001-2002 by
-       Clément Moreau <clement.moreau@inventel.fr>
+       Clément Moreau <clement.moreau@inventel.fr>
        David Libault  <david.libault@inventel.fr>
 
    Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
index 9092816f58de1e589d3afe951e2fa3b94b7404a0..95e3837e4312005916243e4285b21ed88dddfc1f 100644 (file)
@@ -2,7 +2,7 @@
    BNEP implementation for Linux Bluetooth stack (BlueZ).
    Copyright (C) 2001-2002 Inventel Systemes
    Written 2001-2002 by
-       Clément Moreau <clement.moreau@inventel.fr>
+       Clément Moreau <clement.moreau@inventel.fr>
        David Libault  <david.libault@inventel.fr>
 
    Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
index 5fdfc9a67d390fbf9cc00190f289f877cde88074..9483320f6dad01e967e219297ff798c5d1a29af0 100644 (file)
@@ -78,11 +78,11 @@ void hci_acl_connect(struct hci_conn *conn)
 
        cp.pkt_type = cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK);
        if (lmp_rswitch_capable(hdev) && !(hdev->link_mode & HCI_LM_MASTER))
-               cp.role_switch  = 0x01;
+               cp.role_switch = 0x01;
        else
-               cp.role_switch  = 0x00;
+               cp.role_switch = 0x00;
 
-       hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN, sizeof(cp), &cp);
+       hci_send_cmd(hdev, HCI_OP_CREATE_CONN, sizeof(cp), &cp);
 }
 
 static void hci_acl_connect_cancel(struct hci_conn *conn)
@@ -95,8 +95,7 @@ static void hci_acl_connect_cancel(struct hci_conn *conn)
                return;
 
        bacpy(&cp.bdaddr, &conn->dst);
-       hci_send_cmd(conn->hdev, OGF_LINK_CTL,
-                               OCF_CREATE_CONN_CANCEL, sizeof(cp), &cp);
+       hci_send_cmd(conn->hdev, HCI_OP_CREATE_CONN_CANCEL, sizeof(cp), &cp);
 }
 
 void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
@@ -109,8 +108,7 @@ void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
 
        cp.handle = cpu_to_le16(conn->handle);
        cp.reason = reason;
-       hci_send_cmd(conn->hdev, OGF_LINK_CTL,
-                               OCF_DISCONNECT, sizeof(cp), &cp);
+       hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT, sizeof(cp), &cp);
 }
 
 void hci_add_sco(struct hci_conn *conn, __u16 handle)
@@ -126,7 +124,29 @@ void hci_add_sco(struct hci_conn *conn, __u16 handle)
        cp.handle   = cpu_to_le16(handle);
        cp.pkt_type = cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
 
-       hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ADD_SCO, sizeof(cp), &cp);
+       hci_send_cmd(hdev, HCI_OP_ADD_SCO, sizeof(cp), &cp);
+}
+
+void hci_setup_sync(struct hci_conn *conn, __u16 handle)
+{
+       struct hci_dev *hdev = conn->hdev;
+       struct hci_cp_setup_sync_conn cp;
+
+       BT_DBG("%p", conn);
+
+       conn->state = BT_CONNECT;
+       conn->out = 1;
+
+       cp.handle   = cpu_to_le16(handle);
+       cp.pkt_type = cpu_to_le16(hdev->esco_type);
+
+       cp.tx_bandwidth   = cpu_to_le32(0x00001f40);
+       cp.rx_bandwidth   = cpu_to_le32(0x00001f40);
+       cp.max_latency    = cpu_to_le16(0xffff);
+       cp.voice_setting  = cpu_to_le16(hdev->voice_setting);
+       cp.retrans_effort = 0xff;
+
+       hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp);
 }
 
 static void hci_conn_timeout(unsigned long arg)
@@ -143,7 +163,10 @@ static void hci_conn_timeout(unsigned long arg)
 
        switch (conn->state) {
        case BT_CONNECT:
-               hci_acl_connect_cancel(conn);
+               if (conn->type == ACL_LINK)
+                       hci_acl_connect_cancel(conn);
+               else
+                       hci_acl_disconn(conn, 0x13);
                break;
        case BT_CONNECTED:
                hci_acl_disconn(conn, 0x13);
@@ -330,8 +353,12 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
        hci_conn_hold(sco);
 
        if (acl->state == BT_CONNECTED &&
-                       (sco->state == BT_OPEN || sco->state == BT_CLOSED))
-               hci_add_sco(sco, acl->handle);
+                       (sco->state == BT_OPEN || sco->state == BT_CLOSED)) {
+               if (lmp_esco_capable(hdev))
+                       hci_setup_sync(sco, acl->handle);
+               else
+                       hci_add_sco(sco, acl->handle);
+       }
 
        return sco;
 }
@@ -348,7 +375,7 @@ int hci_conn_auth(struct hci_conn *conn)
        if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
                struct hci_cp_auth_requested cp;
                cp.handle = cpu_to_le16(conn->handle);
-               hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_AUTH_REQUESTED, sizeof(cp), &cp);
+               hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
        }
        return 0;
 }
@@ -369,7 +396,7 @@ int hci_conn_encrypt(struct hci_conn *conn)
                struct hci_cp_set_conn_encrypt cp;
                cp.handle  = cpu_to_le16(conn->handle);
                cp.encrypt = 1;
-               hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_SET_CONN_ENCRYPT, sizeof(cp), &cp);
+               hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), &cp);
        }
        return 0;
 }
@@ -383,7 +410,7 @@ int hci_conn_change_link_key(struct hci_conn *conn)
        if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
                struct hci_cp_change_conn_link_key cp;
                cp.handle = cpu_to_le16(conn->handle);
-               hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_CHANGE_CONN_LINK_KEY, sizeof(cp), &cp);
+               hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY, sizeof(cp), &cp);
        }
        return 0;
 }
@@ -401,7 +428,7 @@ int hci_conn_switch_role(struct hci_conn *conn, uint8_t role)
                struct hci_cp_switch_role cp;
                bacpy(&cp.bdaddr, &conn->dst);
                cp.role = role;
-               hci_send_cmd(conn->hdev, OGF_LINK_POLICY, OCF_SWITCH_ROLE, sizeof(cp), &cp);
+               hci_send_cmd(conn->hdev, HCI_OP_SWITCH_ROLE, sizeof(cp), &cp);
        }
        return 0;
 }
@@ -423,8 +450,7 @@ void hci_conn_enter_active_mode(struct hci_conn *conn)
        if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
                struct hci_cp_exit_sniff_mode cp;
                cp.handle = cpu_to_le16(conn->handle);
-               hci_send_cmd(hdev, OGF_LINK_POLICY,
-                               OCF_EXIT_SNIFF_MODE, sizeof(cp), &cp);
+               hci_send_cmd(hdev, HCI_OP_EXIT_SNIFF_MODE, sizeof(cp), &cp);
        }
 
 timer:
@@ -455,8 +481,7 @@ void hci_conn_enter_sniff_mode(struct hci_conn *conn)
                cp.max_latency        = cpu_to_le16(0);
                cp.min_remote_timeout = cpu_to_le16(0);
                cp.min_local_timeout  = cpu_to_le16(0);
-               hci_send_cmd(hdev, OGF_LINK_POLICY,
-                               OCF_SNIFF_SUBRATE, sizeof(cp), &cp);
+               hci_send_cmd(hdev, HCI_OP_SNIFF_SUBRATE, sizeof(cp), &cp);
        }
 
        if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
@@ -466,8 +491,7 @@ void hci_conn_enter_sniff_mode(struct hci_conn *conn)
                cp.min_interval = cpu_to_le16(hdev->sniff_min_interval);
                cp.attempt      = cpu_to_le16(4);
                cp.timeout      = cpu_to_le16(1);
-               hci_send_cmd(hdev, OGF_LINK_POLICY,
-                               OCF_SNIFF_MODE, sizeof(cp), &cp);
+               hci_send_cmd(hdev, HCI_OP_SNIFF_MODE, sizeof(cp), &cp);
        }
 }
 
@@ -493,6 +517,22 @@ void hci_conn_hash_flush(struct hci_dev *hdev)
        }
 }
 
+/* Check pending connect attempts */
+void hci_conn_check_pending(struct hci_dev *hdev)
+{
+       struct hci_conn *conn;
+
+       BT_DBG("hdev %s", hdev->name);
+
+       hci_dev_lock(hdev);
+
+       conn = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2);
+       if (conn)
+               hci_acl_connect(conn);
+
+       hci_dev_unlock(hdev);
+}
+
 int hci_get_conn_list(void __user *arg)
 {
        struct hci_conn_list_req req, *cl;
index 18e3afc964df1b14c23cf149ad3c62078e463281..372b0d3b75a8f3ebf10e4701533e9fce6d488870 100644 (file)
@@ -176,7 +176,7 @@ static void hci_reset_req(struct hci_dev *hdev, unsigned long opt)
        BT_DBG("%s %ld", hdev->name, opt);
 
        /* Reset device */
-       hci_send_cmd(hdev, OGF_HOST_CTL, OCF_RESET, 0, NULL);
+       hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
 }
 
 static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
@@ -202,16 +202,16 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
 
        /* Reset */
        if (test_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks))
-                       hci_send_cmd(hdev, OGF_HOST_CTL, OCF_RESET, 0, NULL);
+                       hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
 
        /* Read Local Supported Features */
-       hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_LOCAL_FEATURES, 0, NULL);
+       hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
 
        /* Read Local Version */
-       hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_LOCAL_VERSION, 0, NULL);
+       hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
 
        /* Read Buffer Size (ACL mtu, max pkt, etc.) */
-       hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BUFFER_SIZE, 0, NULL);
+       hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
 
 #if 0
        /* Host buffer size */
@@ -221,29 +221,35 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
                cp.sco_mtu = HCI_MAX_SCO_SIZE;
                cp.acl_max_pkt = cpu_to_le16(0xffff);
                cp.sco_max_pkt = cpu_to_le16(0xffff);
-               hci_send_cmd(hdev, OGF_HOST_CTL, OCF_HOST_BUFFER_SIZE, sizeof(cp), &cp);
+               hci_send_cmd(hdev, HCI_OP_HOST_BUFFER_SIZE, sizeof(cp), &cp);
        }
 #endif
 
        /* Read BD Address */
-       hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BD_ADDR, 0, NULL);
+       hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL);
+
+       /* Read Class of Device */
+       hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
+
+       /* Read Local Name */
+       hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL);
 
        /* Read Voice Setting */
-       hci_send_cmd(hdev, OGF_HOST_CTL, OCF_READ_VOICE_SETTING, 0, NULL);
+       hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL);
 
        /* Optional initialization */
 
        /* Clear Event Filters */
        flt_type = HCI_FLT_CLEAR_ALL;
-       hci_send_cmd(hdev, OGF_HOST_CTL, OCF_SET_EVENT_FLT, 1, &flt_type);
+       hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
 
        /* Page timeout ~20 secs */
        param = cpu_to_le16(0x8000);
-       hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_PG_TIMEOUT, 2, &param);
+       hci_send_cmd(hdev, HCI_OP_WRITE_PG_TIMEOUT, 2, &param);
 
        /* Connection accept timeout ~20 secs */
        param = cpu_to_le16(0x7d00);
-       hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_CA_TIMEOUT, 2, &param);
+       hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
 }
 
 static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
@@ -253,7 +259,7 @@ static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
        BT_DBG("%s %x", hdev->name, scan);
 
        /* Inquiry and Page scans */
-       hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE, 1, &scan);
+       hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
 }
 
 static void hci_auth_req(struct hci_dev *hdev, unsigned long opt)
@@ -263,7 +269,7 @@ static void hci_auth_req(struct hci_dev *hdev, unsigned long opt)
        BT_DBG("%s %x", hdev->name, auth);
 
        /* Authentication */
-       hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE, 1, &auth);
+       hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
 }
 
 static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt)
@@ -273,7 +279,7 @@ static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt)
        BT_DBG("%s %x", hdev->name, encrypt);
 
        /* Authentication */
-       hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_ENCRYPT_MODE, 1, &encrypt);
+       hci_send_cmd(hdev, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
 }
 
 /* Get HCI device by index.
@@ -384,7 +390,7 @@ static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
        memcpy(&cp.lap, &ir->lap, 3);
        cp.length  = ir->length;
        cp.num_rsp = ir->num_rsp;
-       hci_send_cmd(hdev, OGF_LINK_CTL, OCF_INQUIRY, sizeof(cp), &cp);
+       hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
 }
 
 int hci_inquiry(void __user *arg)
@@ -1111,13 +1117,13 @@ static int hci_send_frame(struct sk_buff *skb)
 }
 
 /* Send HCI command */
-int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *param)
+int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)
 {
        int len = HCI_COMMAND_HDR_SIZE + plen;
        struct hci_command_hdr *hdr;
        struct sk_buff *skb;
 
-       BT_DBG("%s ogf 0x%x ocf 0x%x plen %d", hdev->name, ogf, ocf, plen);
+       BT_DBG("%s opcode 0x%x plen %d", hdev->name, opcode, plen);
 
        skb = bt_skb_alloc(len, GFP_ATOMIC);
        if (!skb) {
@@ -1126,7 +1132,7 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *p
        }
 
        hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
-       hdr->opcode = cpu_to_le16(hci_opcode_pack(ogf, ocf));
+       hdr->opcode = cpu_to_le16(opcode);
        hdr->plen   = plen;
 
        if (plen)
@@ -1143,7 +1149,7 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *p
 }
 
 /* Get data from the previously sent command */
-void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf)
+void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
 {
        struct hci_command_hdr *hdr;
 
@@ -1152,10 +1158,10 @@ void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf)
 
        hdr = (void *) hdev->sent_cmd->data;
 
-       if (hdr->opcode != cpu_to_le16(hci_opcode_pack(ogf, ocf)))
+       if (hdr->opcode != cpu_to_le16(opcode))
                return NULL;
 
-       BT_DBG("%s ogf 0x%x ocf 0x%x", hdev->name, ogf, ocf);
+       BT_DBG("%s opcode 0x%x", hdev->name, opcode);
 
        return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
 }
@@ -1355,6 +1361,26 @@ static inline void hci_sched_sco(struct hci_dev *hdev)
        }
 }
 
+static inline void hci_sched_esco(struct hci_dev *hdev)
+{
+       struct hci_conn *conn;
+       struct sk_buff *skb;
+       int quote;
+
+       BT_DBG("%s", hdev->name);
+
+       while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, &quote))) {
+               while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
+                       BT_DBG("skb %p len %d", skb, skb->len);
+                       hci_send_frame(skb);
+
+                       conn->sent++;
+                       if (conn->sent == ~0)
+                               conn->sent = 0;
+               }
+       }
+}
+
 static void hci_tx_task(unsigned long arg)
 {
        struct hci_dev *hdev = (struct hci_dev *) arg;
@@ -1370,6 +1396,8 @@ static void hci_tx_task(unsigned long arg)
 
        hci_sched_sco(hdev);
 
+       hci_sched_esco(hdev);
+
        /* Send next queued raw (unknown type) packet */
        while ((skb = skb_dequeue(&hdev->raw_q)))
                hci_send_frame(skb);
index 4baea1e3865222cff1bb8c2238eafd11712ba39a..46df2e403df871b131abfa10a8ec22faf8565256 100644 (file)
 
 /* Handle HCI Event packets */
 
-/* Command Complete OGF LINK_CTL  */
-static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
+static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
 {
-       __u8 status;
-       struct hci_conn *pend;
+       __u8 status = *((__u8 *) skb->data);
 
-       BT_DBG("%s ocf 0x%x", hdev->name, ocf);
+       BT_DBG("%s status 0x%x", hdev->name, status);
 
-       switch (ocf) {
-       case OCF_INQUIRY_CANCEL:
-       case OCF_EXIT_PERIODIC_INQ:
-               status = *((__u8 *) skb->data);
+       if (status)
+               return;
 
-               if (status) {
-                       BT_DBG("%s Inquiry cancel error: status 0x%x", hdev->name, status);
-               } else {
-                       clear_bit(HCI_INQUIRY, &hdev->flags);
-                       hci_req_complete(hdev, status);
-               }
+       clear_bit(HCI_INQUIRY, &hdev->flags);
 
-               hci_dev_lock(hdev);
+       hci_req_complete(hdev, status);
+
+       hci_conn_check_pending(hdev);
+}
 
-               pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2);
-               if (pend)
-                       hci_acl_connect(pend);
+static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       __u8 status = *((__u8 *) skb->data);
 
-               hci_dev_unlock(hdev);
+       BT_DBG("%s status 0x%x", hdev->name, status);
 
-               break;
+       if (status)
+               return;
 
-       default:
-               BT_DBG("%s Command complete: ogf LINK_CTL ocf %x", hdev->name, ocf);
-               break;
+       clear_bit(HCI_INQUIRY, &hdev->flags);
+
+       hci_conn_check_pending(hdev);
+}
+
+static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       BT_DBG("%s", hdev->name);
+}
+
+static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       struct hci_rp_role_discovery *rp = (void *) skb->data;
+       struct hci_conn *conn;
+
+       BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+       if (rp->status)
+               return;
+
+       hci_dev_lock(hdev);
+
+       conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
+       if (conn) {
+               if (rp->role)
+                       conn->link_mode &= ~HCI_LM_MASTER;
+               else
+                       conn->link_mode |= HCI_LM_MASTER;
        }
+
+       hci_dev_unlock(hdev);
 }
 
-/* Command Complete OGF LINK_POLICY  */
-static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
+static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
 {
+       struct hci_rp_write_link_policy *rp = (void *) skb->data;
        struct hci_conn *conn;
-       struct hci_rp_role_discovery *rd;
-       struct hci_rp_write_link_policy *lp;
        void *sent;
 
-       BT_DBG("%s ocf 0x%x", hdev->name, ocf);
+       BT_DBG("%s status 0x%x", hdev->name, rp->status);
 
-       switch (ocf) {
-       case OCF_ROLE_DISCOVERY:
-               rd = (void *) skb->data;
+       if (rp->status)
+               return;
 
-               if (rd->status)
-                       break;
+       sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
+       if (!sent)
+               return;
 
-               hci_dev_lock(hdev);
+       hci_dev_lock(hdev);
 
-               conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rd->handle));
-               if (conn) {
-                       if (rd->role)
-                               conn->link_mode &= ~HCI_LM_MASTER;
-                       else
-                               conn->link_mode |= HCI_LM_MASTER;
-               }
+       conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
+       if (conn) {
+               __le16 policy = get_unaligned((__le16 *) (sent + 2));
+               conn->link_policy = __le16_to_cpu(policy);
+       }
 
-               hci_dev_unlock(hdev);
-               break;
+       hci_dev_unlock(hdev);
+}
 
-       case OCF_WRITE_LINK_POLICY:
-               sent = hci_sent_cmd_data(hdev, OGF_LINK_POLICY, OCF_WRITE_LINK_POLICY);
-               if (!sent)
-                       break;
+static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       __u8 status = *((__u8 *) skb->data);
 
-               lp = (struct hci_rp_write_link_policy *) skb->data;
+       BT_DBG("%s status 0x%x", hdev->name, status);
 
-               if (lp->status)
-                       break;
+       hci_req_complete(hdev, status);
+}
 
-               hci_dev_lock(hdev);
+static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       __u8 status = *((__u8 *) skb->data);
+       void *sent;
 
-               conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(lp->handle));
-               if (conn) {
-                       __le16 policy = get_unaligned((__le16 *) (sent + 2));
-                       conn->link_policy = __le16_to_cpu(policy);
-               }
+       BT_DBG("%s status 0x%x", hdev->name, status);
 
-               hci_dev_unlock(hdev);
-               break;
+       sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
+       if (!sent)
+               return;
 
-       default:
-               BT_DBG("%s: Command complete: ogf LINK_POLICY ocf %x",
-                               hdev->name, ocf);
-               break;
+       if (!status)
+               memcpy(hdev->dev_name, sent, 248);
+}
+
+static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       struct hci_rp_read_local_name *rp = (void *) skb->data;
+
+       BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+       if (rp->status)
+               return;
+
+       memcpy(hdev->dev_name, rp->name, 248);
+}
+
+static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       __u8 status = *((__u8 *) skb->data);
+       void *sent;
+
+       BT_DBG("%s status 0x%x", hdev->name, status);
+
+       sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
+       if (!sent)
+               return;
+
+       if (!status) {
+               __u8 param = *((__u8 *) sent);
+
+               if (param == AUTH_ENABLED)
+                       set_bit(HCI_AUTH, &hdev->flags);
+               else
+                       clear_bit(HCI_AUTH, &hdev->flags);
        }
+
+       hci_req_complete(hdev, status);
 }
 
-/* Command Complete OGF HOST_CTL  */
-static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
+static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
 {
-       __u8 status, param;
-       __u16 setting;
-       struct hci_rp_read_voice_setting *vs;
+       __u8 status = *((__u8 *) skb->data);
        void *sent;
 
-       BT_DBG("%s ocf 0x%x", hdev->name, ocf);
+       BT_DBG("%s status 0x%x", hdev->name, status);
 
-       switch (ocf) {
-       case OCF_RESET:
-               status = *((__u8 *) skb->data);
-               hci_req_complete(hdev, status);
-               break;
+       sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
+       if (!sent)
+               return;
 
-       case OCF_SET_EVENT_FLT:
-               status = *((__u8 *) skb->data);
-               if (status) {
-                       BT_DBG("%s SET_EVENT_FLT failed %d", hdev->name, status);
-               } else {
-                       BT_DBG("%s SET_EVENT_FLT succeseful", hdev->name);
-               }
-               break;
+       if (!status) {
+               __u8 param = *((__u8 *) sent);
+
+               if (param)
+                       set_bit(HCI_ENCRYPT, &hdev->flags);
+               else
+                       clear_bit(HCI_ENCRYPT, &hdev->flags);
+       }
 
-       case OCF_WRITE_AUTH_ENABLE:
-               sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE);
-               if (!sent)
-                       break;
+       hci_req_complete(hdev, status);
+}
 
-               status = *((__u8 *) skb->data);
-               param  = *((__u8 *) sent);
+static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       __u8 status = *((__u8 *) skb->data);
+       void *sent;
 
-               if (!status) {
-                       if (param == AUTH_ENABLED)
-                               set_bit(HCI_AUTH, &hdev->flags);
-                       else
-                               clear_bit(HCI_AUTH, &hdev->flags);
-               }
-               hci_req_complete(hdev, status);
-               break;
+       BT_DBG("%s status 0x%x", hdev->name, status);
 
-       case OCF_WRITE_ENCRYPT_MODE:
-               sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_ENCRYPT_MODE);
-               if (!sent)
-                       break;
+       sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
+       if (!sent)
+               return;
 
-               status = *((__u8 *) skb->data);
-               param  = *((__u8 *) sent);
+       if (!status) {
+               __u8 param = *((__u8 *) sent);
 
-               if (!status) {
-                       if (param)
-                               set_bit(HCI_ENCRYPT, &hdev->flags);
-                       else
-                               clear_bit(HCI_ENCRYPT, &hdev->flags);
-               }
-               hci_req_complete(hdev, status);
-               break;
+               clear_bit(HCI_PSCAN, &hdev->flags);
+               clear_bit(HCI_ISCAN, &hdev->flags);
 
-       case OCF_WRITE_CA_TIMEOUT:
-               status = *((__u8 *) skb->data);
-               if (status) {
-                       BT_DBG("%s OCF_WRITE_CA_TIMEOUT failed %d", hdev->name, status);
-               } else {
-                       BT_DBG("%s OCF_WRITE_CA_TIMEOUT succeseful", hdev->name);
-               }
-               break;
+               if (param & SCAN_INQUIRY)
+                       set_bit(HCI_ISCAN, &hdev->flags);
 
-       case OCF_WRITE_PG_TIMEOUT:
-               status = *((__u8 *) skb->data);
-               if (status) {
-                       BT_DBG("%s OCF_WRITE_PG_TIMEOUT failed %d", hdev->name, status);
-               } else {
-                       BT_DBG("%s: OCF_WRITE_PG_TIMEOUT succeseful", hdev->name);
-               }
-               break;
+               if (param & SCAN_PAGE)
+                       set_bit(HCI_PSCAN, &hdev->flags);
+       }
 
-       case OCF_WRITE_SCAN_ENABLE:
-               sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE);
-               if (!sent)
-                       break;
+       hci_req_complete(hdev, status);
+}
 
-               status = *((__u8 *) skb->data);
-               param  = *((__u8 *) sent);
+static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
 
-               BT_DBG("param 0x%x", param);
+       BT_DBG("%s status 0x%x", hdev->name, rp->status);
 
-               if (!status) {
-                       clear_bit(HCI_PSCAN, &hdev->flags);
-                       clear_bit(HCI_ISCAN, &hdev->flags);
-                       if (param & SCAN_INQUIRY)
-                               set_bit(HCI_ISCAN, &hdev->flags);
+       if (rp->status)
+               return;
 
-                       if (param & SCAN_PAGE)
-                               set_bit(HCI_PSCAN, &hdev->flags);
-               }
-               hci_req_complete(hdev, status);
-               break;
+       memcpy(hdev->dev_class, rp->dev_class, 3);
 
-       case OCF_READ_VOICE_SETTING:
-               vs = (struct hci_rp_read_voice_setting *) skb->data;
+       BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
+               hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
+}
 
-               if (vs->status) {
-                       BT_DBG("%s READ_VOICE_SETTING failed %d", hdev->name, vs->status);
-                       break;
-               }
+static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       __u8 status = *((__u8 *) skb->data);
+       void *sent;
 
-               setting = __le16_to_cpu(vs->voice_setting);
+       BT_DBG("%s status 0x%x", hdev->name, status);
 
-               if (hdev->voice_setting != setting ) {
-                       hdev->voice_setting = setting;
+       sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
+       if (!sent)
+               return;
 
-                       BT_DBG("%s: voice setting 0x%04x", hdev->name, setting);
+       if (!status)
+               memcpy(hdev->dev_class, sent, 3);
+}
 
-                       if (hdev->notify) {
-                               tasklet_disable(&hdev->tx_task);
-                               hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
-                               tasklet_enable(&hdev->tx_task);
-                       }
-               }
-               break;
+static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       struct hci_rp_read_voice_setting *rp = (void *) skb->data;
+       __u16 setting;
+
+       BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+       if (rp->status)
+               return;
+
+       setting = __le16_to_cpu(rp->voice_setting);
+
+       if (hdev->voice_setting == setting )
+               return;
+
+       hdev->voice_setting = setting;
+
+       BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
+
+       if (hdev->notify) {
+               tasklet_disable(&hdev->tx_task);
+               hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
+               tasklet_enable(&hdev->tx_task);
+       }
+}
+
+static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       __u8 status = *((__u8 *) skb->data);
+       void *sent;
+
+       BT_DBG("%s status 0x%x", hdev->name, status);
 
-       case OCF_WRITE_VOICE_SETTING:
-               sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_VOICE_SETTING);
-               if (!sent)
-                       break;
+       sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
+       if (!sent)
+               return;
 
-               status = *((__u8 *) skb->data);
-               setting = __le16_to_cpu(get_unaligned((__le16 *) sent));
+       if (!status) {
+               __u16 setting = __le16_to_cpu(get_unaligned((__le16 *) sent));
 
-               if (!status && hdev->voice_setting != setting) {
+               if (hdev->voice_setting != setting) {
                        hdev->voice_setting = setting;
 
-                       BT_DBG("%s: voice setting 0x%04x", hdev->name, setting);
+                       BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
 
                        if (hdev->notify) {
                                tasklet_disable(&hdev->tx_task);
@@ -287,143 +326,153 @@ static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb
                                tasklet_enable(&hdev->tx_task);
                        }
                }
-               hci_req_complete(hdev, status);
-               break;
-
-       case OCF_HOST_BUFFER_SIZE:
-               status = *((__u8 *) skb->data);
-               if (status) {
-                       BT_DBG("%s OCF_BUFFER_SIZE failed %d", hdev->name, status);
-                       hci_req_complete(hdev, status);
-               }
-               break;
-
-       default:
-               BT_DBG("%s Command complete: ogf HOST_CTL ocf %x", hdev->name, ocf);
-               break;
        }
 }
 
-/* Command Complete OGF INFO_PARAM  */
-static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
+static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
 {
-       struct hci_rp_read_loc_version *lv;
-       struct hci_rp_read_local_features *lf;
-       struct hci_rp_read_buffer_size *bs;
-       struct hci_rp_read_bd_addr *ba;
+       __u8 status = *((__u8 *) skb->data);
 
-       BT_DBG("%s ocf 0x%x", hdev->name, ocf);
+       BT_DBG("%s status 0x%x", hdev->name, status);
 
-       switch (ocf) {
-       case OCF_READ_LOCAL_VERSION:
-               lv = (struct hci_rp_read_loc_version *) skb->data;
+       hci_req_complete(hdev, status);
+}
 
-               if (lv->status) {
-                       BT_DBG("%s READ_LOCAL_VERSION failed %d", hdev->name, lf->status);
-                       break;
-               }
+static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       struct hci_rp_read_local_version *rp = (void *) skb->data;
 
-               hdev->hci_ver = lv->hci_ver;
-               hdev->hci_rev = btohs(lv->hci_rev);
-               hdev->manufacturer = btohs(lv->manufacturer);
+       BT_DBG("%s status 0x%x", hdev->name, rp->status);
 
-               BT_DBG("%s: manufacturer %d hci_ver %d hci_rev %d", hdev->name,
-                               hdev->manufacturer, hdev->hci_ver, hdev->hci_rev);
+       if (rp->status)
+               return;
 
-               break;
+       hdev->hci_ver = rp->hci_ver;
+       hdev->hci_rev = btohs(rp->hci_rev);
+       hdev->manufacturer = btohs(rp->manufacturer);
 
-       case OCF_READ_LOCAL_FEATURES:
-               lf = (struct hci_rp_read_local_features *) skb->data;
+       BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
+                                       hdev->manufacturer,
+                                       hdev->hci_ver, hdev->hci_rev);
+}
 
-               if (lf->status) {
-                       BT_DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status);
-                       break;
-               }
+static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       struct hci_rp_read_local_commands *rp = (void *) skb->data;
 
-               memcpy(hdev->features, lf->features, sizeof(hdev->features));
+       BT_DBG("%s status 0x%x", hdev->name, rp->status);
 
-               /* Adjust default settings according to features
-                * supported by device. */
-               if (hdev->features[0] & LMP_3SLOT)
-                       hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
+       if (rp->status)
+               return;
 
-               if (hdev->features[0] & LMP_5SLOT)
-                       hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
+       memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
+}
 
-               if (hdev->features[1] & LMP_HV2) {
-                       hdev->pkt_type  |= (HCI_HV2);
-                       hdev->esco_type |= (ESCO_HV2);
-               }
+static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       struct hci_rp_read_local_features *rp = (void *) skb->data;
 
-               if (hdev->features[1] & LMP_HV3) {
-                       hdev->pkt_type  |= (HCI_HV3);
-                       hdev->esco_type |= (ESCO_HV3);
-               }
+       BT_DBG("%s status 0x%x", hdev->name, rp->status);
 
-               if (hdev->features[3] & LMP_ESCO)
-                       hdev->esco_type |= (ESCO_EV3);
+       if (rp->status)
+               return;
 
-               if (hdev->features[4] & LMP_EV4)
-                       hdev->esco_type |= (ESCO_EV4);
+       memcpy(hdev->features, rp->features, 8);
 
-               if (hdev->features[4] & LMP_EV5)
-                       hdev->esco_type |= (ESCO_EV5);
+       /* Adjust default settings according to features
+        * supported by device. */
 
-               BT_DBG("%s: features 0x%x 0x%x 0x%x", hdev->name,
-                               lf->features[0], lf->features[1], lf->features[2]);
+       if (hdev->features[0] & LMP_3SLOT)
+               hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
 
-               break;
+       if (hdev->features[0] & LMP_5SLOT)
+               hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
 
-       case OCF_READ_BUFFER_SIZE:
-               bs = (struct hci_rp_read_buffer_size *) skb->data;
+       if (hdev->features[1] & LMP_HV2) {
+               hdev->pkt_type  |= (HCI_HV2);
+               hdev->esco_type |= (ESCO_HV2);
+       }
 
-               if (bs->status) {
-                       BT_DBG("%s READ_BUFFER_SIZE failed %d", hdev->name, bs->status);
-                       hci_req_complete(hdev, bs->status);
-                       break;
-               }
+       if (hdev->features[1] & LMP_HV3) {
+               hdev->pkt_type  |= (HCI_HV3);
+               hdev->esco_type |= (ESCO_HV3);
+       }
 
-               hdev->acl_mtu  = __le16_to_cpu(bs->acl_mtu);
-               hdev->sco_mtu  = bs->sco_mtu;
-               hdev->acl_pkts = __le16_to_cpu(bs->acl_max_pkt);
-               hdev->sco_pkts = __le16_to_cpu(bs->sco_max_pkt);
+       if (hdev->features[3] & LMP_ESCO)
+               hdev->esco_type |= (ESCO_EV3);
 
-               if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
-                       hdev->sco_mtu  = 64;
-                       hdev->sco_pkts = 8;
-               }
+       if (hdev->features[4] & LMP_EV4)
+               hdev->esco_type |= (ESCO_EV4);
 
-               hdev->acl_cnt = hdev->acl_pkts;
-               hdev->sco_cnt = hdev->sco_pkts;
+       if (hdev->features[4] & LMP_EV5)
+               hdev->esco_type |= (ESCO_EV5);
 
-               BT_DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name,
-                       hdev->acl_mtu, hdev->sco_mtu, hdev->acl_pkts, hdev->sco_pkts);
-               break;
+       BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
+                                       hdev->features[0], hdev->features[1],
+                                       hdev->features[2], hdev->features[3],
+                                       hdev->features[4], hdev->features[5],
+                                       hdev->features[6], hdev->features[7]);
+}
 
-       case OCF_READ_BD_ADDR:
-               ba = (struct hci_rp_read_bd_addr *) skb->data;
+static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       struct hci_rp_read_buffer_size *rp = (void *) skb->data;
 
-               if (!ba->status) {
-                       bacpy(&hdev->bdaddr, &ba->bdaddr);
-               } else {
-                       BT_DBG("%s: READ_BD_ADDR failed %d", hdev->name, ba->status);
-               }
+       BT_DBG("%s status 0x%x", hdev->name, rp->status);
 
-               hci_req_complete(hdev, ba->status);
-               break;
+       if (rp->status)
+               return;
 
-       default:
-               BT_DBG("%s Command complete: ogf INFO_PARAM ocf %x", hdev->name, ocf);
-               break;
+       hdev->acl_mtu  = __le16_to_cpu(rp->acl_mtu);
+       hdev->sco_mtu  = rp->sco_mtu;
+       hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
+       hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
+
+       if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
+               hdev->sco_mtu  = 64;
+               hdev->sco_pkts = 8;
        }
+
+       hdev->acl_cnt = hdev->acl_pkts;
+       hdev->sco_cnt = hdev->sco_pkts;
+
+       BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
+                                       hdev->acl_mtu, hdev->acl_pkts,
+                                       hdev->sco_mtu, hdev->sco_pkts);
+}
+
+static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       struct hci_rp_read_bd_addr *rp = (void *) skb->data;
+
+       BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+       if (!rp->status)
+               bacpy(&hdev->bdaddr, &rp->bdaddr);
+
+       hci_req_complete(hdev, rp->status);
+}
+
+static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
+{
+       BT_DBG("%s status 0x%x", hdev->name, status);
+
+       if (status) {
+               hci_req_complete(hdev, status);
+
+               hci_conn_check_pending(hdev);
+       } else
+               set_bit(HCI_INQUIRY, &hdev->flags);
 }
 
-/* Command Status OGF LINK_CTL  */
 static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
 {
+       struct hci_cp_create_conn *cp;
        struct hci_conn *conn;
-       struct hci_cp_create_conn *cp = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_CREATE_CONN);
 
+       BT_DBG("%s status 0x%x", hdev->name, status);
+
+       cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
        if (!cp)
                return;
 
@@ -431,8 +480,7 @@ static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
 
        conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
 
-       BT_DBG("%s status 0x%x bdaddr %s conn %p", hdev->name,
-                       status, batostr(&cp->bdaddr), conn);
+       BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
 
        if (status) {
                if (conn && conn->state == BT_CONNECT) {
@@ -457,234 +505,138 @@ static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
        hci_dev_unlock(hdev);
 }
 
-static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
+static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
 {
-       BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-
-       switch (ocf) {
-       case OCF_CREATE_CONN:
-               hci_cs_create_conn(hdev, status);
-               break;
-
-       case OCF_ADD_SCO:
-               if (status) {
-                       struct hci_conn *acl, *sco;
-                       struct hci_cp_add_sco *cp = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_ADD_SCO);
-                       __u16 handle;
+       struct hci_cp_add_sco *cp;
+       struct hci_conn *acl, *sco;
+       __u16 handle;
 
-                       if (!cp)
-                               break;
+       BT_DBG("%s status 0x%x", hdev->name, status);
 
-                       handle = __le16_to_cpu(cp->handle);
-
-                       BT_DBG("%s Add SCO error: handle %d status 0x%x", hdev->name, handle, status);
+       if (!status)
+               return;
 
-                       hci_dev_lock(hdev);
+       cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
+       if (!cp)
+               return;
 
-                       acl = hci_conn_hash_lookup_handle(hdev, handle);
-                       if (acl && (sco = acl->link)) {
-                               sco->state = BT_CLOSED;
+       handle = __le16_to_cpu(cp->handle);
 
-                               hci_proto_connect_cfm(sco, status);
-                               hci_conn_del(sco);
-                       }
+       BT_DBG("%s handle %d", hdev->name, handle);
 
-                       hci_dev_unlock(hdev);
-               }
-               break;
+       hci_dev_lock(hdev);
 
-       case OCF_INQUIRY:
-               if (status) {
-                       BT_DBG("%s Inquiry error: status 0x%x", hdev->name, status);
-                       hci_req_complete(hdev, status);
-               } else {
-                       set_bit(HCI_INQUIRY, &hdev->flags);
-               }
-               break;
+       acl = hci_conn_hash_lookup_handle(hdev, handle);
+       if (acl && (sco = acl->link)) {
+               sco->state = BT_CLOSED;
 
-       default:
-               BT_DBG("%s Command status: ogf LINK_CTL ocf %x status %d",
-                       hdev->name, ocf, status);
-               break;
+               hci_proto_connect_cfm(sco, status);
+               hci_conn_del(sco);
        }
+
+       hci_dev_unlock(hdev);
 }
 
-/* Command Status OGF LINK_POLICY */
-static void hci_cs_link_policy(struct hci_dev *hdev, __u16 ocf, __u8 status)
+static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
 {
-       BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-
-       switch (ocf) {
-       case OCF_SNIFF_MODE:
-               if (status) {
-                       struct hci_conn *conn;
-                       struct hci_cp_sniff_mode *cp = hci_sent_cmd_data(hdev, OGF_LINK_POLICY, OCF_SNIFF_MODE);
-
-                       if (!cp)
-                               break;
+       BT_DBG("%s status 0x%x", hdev->name, status);
+}
 
-                       hci_dev_lock(hdev);
+static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
+{
+       struct hci_cp_setup_sync_conn *cp;
+       struct hci_conn *acl, *sco;
+       __u16 handle;
 
-                       conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
-                       if (conn) {
-                               clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
-                       }
+       BT_DBG("%s status 0x%x", hdev->name, status);
 
-                       hci_dev_unlock(hdev);
-               }
-               break;
+       if (!status)
+               return;
 
-       case OCF_EXIT_SNIFF_MODE:
-               if (status) {
-                       struct hci_conn *conn;
-                       struct hci_cp_exit_sniff_mode *cp = hci_sent_cmd_data(hdev, OGF_LINK_POLICY, OCF_EXIT_SNIFF_MODE);
+       cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
+       if (!cp)
+               return;
 
-                       if (!cp)
-                               break;
+       handle = __le16_to_cpu(cp->handle);
 
-                       hci_dev_lock(hdev);
+       BT_DBG("%s handle %d", hdev->name, handle);
 
-                       conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
-                       if (conn) {
-                               clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
-                       }
+       hci_dev_lock(hdev);
 
-                       hci_dev_unlock(hdev);
-               }
-               break;
+       acl = hci_conn_hash_lookup_handle(hdev, handle);
+       if (acl && (sco = acl->link)) {
+               sco->state = BT_CLOSED;
 
-       default:
-               BT_DBG("%s Command status: ogf LINK_POLICY ocf %x", hdev->name, ocf);
-               break;
+               hci_proto_connect_cfm(sco, status);
+               hci_conn_del(sco);
        }
+
+       hci_dev_unlock(hdev);
 }
 
-/* Command Status OGF HOST_CTL */
-static void hci_cs_host_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
+static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
 {
-       BT_DBG("%s ocf 0x%x", hdev->name, ocf);
+       struct hci_cp_sniff_mode *cp;
+       struct hci_conn *conn;
 
-       switch (ocf) {
-       default:
-               BT_DBG("%s Command status: ogf HOST_CTL ocf %x", hdev->name, ocf);
-               break;
-       }
-}
-
-/* Command Status OGF INFO_PARAM  */
-static void hci_cs_info_param(struct hci_dev *hdev, __u16 ocf, __u8 status)
-{
-       BT_DBG("%s: hci_cs_info_param: ocf 0x%x", hdev->name, ocf);
-
-       switch (ocf) {
-       default:
-               BT_DBG("%s Command status: ogf INFO_PARAM ocf %x", hdev->name, ocf);
-               break;
-       }
-}
-
-/* Inquiry Complete */
-static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-{
-       __u8 status = *((__u8 *) skb->data);
-       struct hci_conn *pend;
+       BT_DBG("%s status 0x%x", hdev->name, status);
 
-       BT_DBG("%s status %d", hdev->name, status);
+       if (!status)
+               return;
 
-       clear_bit(HCI_INQUIRY, &hdev->flags);
-       hci_req_complete(hdev, status);
+       cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
+       if (!cp)
+               return;
 
        hci_dev_lock(hdev);
 
-       pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2);
-       if (pend)
-               hci_acl_connect(pend);
+       conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
+       if (conn)
+               clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
 
        hci_dev_unlock(hdev);
 }
 
-/* Inquiry Result */
-static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
 {
-       struct inquiry_data data;
-       struct inquiry_info *info = (struct inquiry_info *) (skb->data + 1);
-       int num_rsp = *((__u8 *) skb->data);
+       struct hci_cp_exit_sniff_mode *cp;
+       struct hci_conn *conn;
 
-       BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
+       BT_DBG("%s status 0x%x", hdev->name, status);
 
-       if (!num_rsp)
+       if (!status)
+               return;
+
+       cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
+       if (!cp)
                return;
 
        hci_dev_lock(hdev);
 
-       for (; num_rsp; num_rsp--) {
-               bacpy(&data.bdaddr, &info->bdaddr);
-               data.pscan_rep_mode     = info->pscan_rep_mode;
-               data.pscan_period_mode  = info->pscan_period_mode;
-               data.pscan_mode         = info->pscan_mode;
-               memcpy(data.dev_class, info->dev_class, 3);
-               data.clock_offset       = info->clock_offset;
-               data.rssi               = 0x00;
-               info++;
-               hci_inquiry_cache_update(hdev, &data);
-       }
+       conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
+       if (conn)
+               clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
 
        hci_dev_unlock(hdev);
 }
 
-/* Inquiry Result With RSSI */
-static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
-       struct inquiry_data data;
-       int num_rsp = *((__u8 *) skb->data);
-
-       BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
-
-       if (!num_rsp)
-               return;
-
-       hci_dev_lock(hdev);
+       __u8 status = *((__u8 *) skb->data);
 
-       if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
-               struct inquiry_info_with_rssi_and_pscan_mode *info =
-                       (struct inquiry_info_with_rssi_and_pscan_mode *) (skb->data + 1);
+       BT_DBG("%s status %d", hdev->name, status);
 
-               for (; num_rsp; num_rsp--) {
-                       bacpy(&data.bdaddr, &info->bdaddr);
-                       data.pscan_rep_mode     = info->pscan_rep_mode;
-                       data.pscan_period_mode  = info->pscan_period_mode;
-                       data.pscan_mode         = info->pscan_mode;
-                       memcpy(data.dev_class, info->dev_class, 3);
-                       data.clock_offset       = info->clock_offset;
-                       data.rssi               = info->rssi;
-                       info++;
-                       hci_inquiry_cache_update(hdev, &data);
-               }
-       } else {
-               struct inquiry_info_with_rssi *info =
-                       (struct inquiry_info_with_rssi *) (skb->data + 1);
+       clear_bit(HCI_INQUIRY, &hdev->flags);
 
-               for (; num_rsp; num_rsp--) {
-                       bacpy(&data.bdaddr, &info->bdaddr);
-                       data.pscan_rep_mode     = info->pscan_rep_mode;
-                       data.pscan_period_mode  = info->pscan_period_mode;
-                       data.pscan_mode         = 0x00;
-                       memcpy(data.dev_class, info->dev_class, 3);
-                       data.clock_offset       = info->clock_offset;
-                       data.rssi               = info->rssi;
-                       info++;
-                       hci_inquiry_cache_update(hdev, &data);
-               }
-       }
+       hci_req_complete(hdev, status);
 
-       hci_dev_unlock(hdev);
+       hci_conn_check_pending(hdev);
 }
 
-/* Extended Inquiry Result */
-static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
        struct inquiry_data data;
-       struct extended_inquiry_info *info = (struct extended_inquiry_info *) (skb->data + 1);
+       struct inquiry_info *info = (void *) (skb->data + 1);
        int num_rsp = *((__u8 *) skb->data);
 
        BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
@@ -696,12 +648,12 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct
 
        for (; num_rsp; num_rsp--) {
                bacpy(&data.bdaddr, &info->bdaddr);
-               data.pscan_rep_mode     = info->pscan_rep_mode;
-               data.pscan_period_mode  = info->pscan_period_mode;
-               data.pscan_mode         = 0x00;
+               data.pscan_rep_mode     = info->pscan_rep_mode;
+               data.pscan_period_mode  = info->pscan_period_mode;
+               data.pscan_mode         = info->pscan_mode;
                memcpy(data.dev_class, info->dev_class, 3);
-               data.clock_offset       = info->clock_offset;
-               data.rssi               = info->rssi;
+               data.clock_offset       = info->clock_offset;
+               data.rssi               = 0x00;
                info++;
                hci_inquiry_cache_update(hdev, &data);
        }
@@ -709,70 +661,18 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct
        hci_dev_unlock(hdev);
 }
 
-/* Connect Request */
-static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
-{
-       struct hci_ev_conn_request *ev = (struct hci_ev_conn_request *) skb->data;
-       int mask = hdev->link_mode;
-
-       BT_DBG("%s Connection request: %s type 0x%x", hdev->name,
-                       batostr(&ev->bdaddr), ev->link_type);
-
-       mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
-
-       if (mask & HCI_LM_ACCEPT) {
-               /* Connection accepted */
-               struct hci_conn *conn;
-               struct hci_cp_accept_conn_req cp;
-
-               hci_dev_lock(hdev);
-               conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
-               if (!conn) {
-                       if (!(conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr))) {
-                               BT_ERR("No memmory for new connection");
-                               hci_dev_unlock(hdev);
-                               return;
-                       }
-               }
-               memcpy(conn->dev_class, ev->dev_class, 3);
-               conn->state = BT_CONNECT;
-               hci_dev_unlock(hdev);
-
-               bacpy(&cp.bdaddr, &ev->bdaddr);
-
-               if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
-                       cp.role = 0x00; /* Become master */
-               else
-                       cp.role = 0x01; /* Remain slave */
-
-               hci_send_cmd(hdev, OGF_LINK_CTL,
-                               OCF_ACCEPT_CONN_REQ, sizeof(cp), &cp);
-       } else {
-               /* Connection rejected */
-               struct hci_cp_reject_conn_req cp;
-
-               bacpy(&cp.bdaddr, &ev->bdaddr);
-               cp.reason = 0x0f;
-               hci_send_cmd(hdev, OGF_LINK_CTL,
-                               OCF_REJECT_CONN_REQ, sizeof(cp), &cp);
-       }
-}
-
-/* Connect Complete */
 static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
-       struct hci_ev_conn_complete *ev = (struct hci_ev_conn_complete *) skb->data;
-       struct hci_conn *conn, *pend;
+       struct hci_ev_conn_complete *ev = (void *) skb->data;
+       struct hci_conn *conn;
 
        BT_DBG("%s", hdev->name);
 
        hci_dev_lock(hdev);
 
        conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
-       if (!conn) {
-               hci_dev_unlock(hdev);
-               return;
-       }
+       if (!conn)
+               goto unlock;
 
        if (!ev->status) {
                conn->handle = __le16_to_cpu(ev->handle);
@@ -788,8 +688,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
                if (conn->type == ACL_LINK) {
                        struct hci_cp_read_remote_features cp;
                        cp.handle = ev->handle;
-                       hci_send_cmd(hdev, OGF_LINK_CTL,
-                               OCF_READ_REMOTE_FEATURES, sizeof(cp), &cp);
+                       hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES, sizeof(cp), &cp);
                }
 
                /* Set link policy */
@@ -797,8 +696,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
                        struct hci_cp_write_link_policy cp;
                        cp.handle = ev->handle;
                        cp.policy = cpu_to_le16(hdev->link_policy);
-                       hci_send_cmd(hdev, OGF_LINK_POLICY,
-                               OCF_WRITE_LINK_POLICY, sizeof(cp), &cp);
+                       hci_send_cmd(hdev, HCI_OP_WRITE_LINK_POLICY, sizeof(cp), &cp);
                }
 
                /* Set packet type for incoming connection */
@@ -809,8 +707,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
                                cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK):
                                cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
 
-                       hci_send_cmd(hdev, OGF_LINK_CTL,
-                               OCF_CHANGE_CONN_PTYPE, sizeof(cp), &cp);
+                       hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp), &cp);
                } else {
                        /* Update disconnect timer */
                        hci_conn_hold(conn);
@@ -822,9 +719,12 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
        if (conn->type == ACL_LINK) {
                struct hci_conn *sco = conn->link;
                if (sco) {
-                       if (!ev->status)
-                               hci_add_sco(sco, conn->handle);
-                       else {
+                       if (!ev->status) {
+                               if (lmp_esco_capable(hdev))
+                                       hci_setup_sync(sco, conn->handle);
+                               else
+                                       hci_add_sco(sco, conn->handle);
+                       } else {
                                hci_proto_connect_cfm(sco, ev->status);
                                hci_conn_del(sco);
                        }
@@ -835,136 +735,104 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
        if (ev->status)
                hci_conn_del(conn);
 
-       pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2);
-       if (pend)
-               hci_acl_connect(pend);
-
+unlock:
        hci_dev_unlock(hdev);
-}
-
-/* Disconnect Complete */
-static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-{
-       struct hci_ev_disconn_complete *ev = (struct hci_ev_disconn_complete *) skb->data;
-       struct hci_conn *conn;
-
-       BT_DBG("%s status %d", hdev->name, ev->status);
 
-       if (ev->status)
-               return;
-
-       hci_dev_lock(hdev);
-
-       conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
-       if (conn) {
-               conn->state = BT_CLOSED;
-               hci_proto_disconn_ind(conn, ev->reason);
-               hci_conn_del(conn);
-       }
-
-       hci_dev_unlock(hdev);
+       hci_conn_check_pending(hdev);
 }
 
-/* Number of completed packets */
-static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
-       struct hci_ev_num_comp_pkts *ev = (struct hci_ev_num_comp_pkts *) skb->data;
-       __le16 *ptr;
-       int i;
-
-       skb_pull(skb, sizeof(*ev));
-
-       BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
+       struct hci_ev_conn_request *ev = (void *) skb->data;
+       int mask = hdev->link_mode;
 
-       if (skb->len < ev->num_hndl * 4) {
-               BT_DBG("%s bad parameters", hdev->name);
-               return;
-       }
+       BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
+                                       batostr(&ev->bdaddr), ev->link_type);
 
-       tasklet_disable(&hdev->tx_task);
+       mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
 
-       for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
+       if (mask & HCI_LM_ACCEPT) {
+               /* Connection accepted */
                struct hci_conn *conn;
-               __u16  handle, count;
 
-               handle = __le16_to_cpu(get_unaligned(ptr++));
-               count  = __le16_to_cpu(get_unaligned(ptr++));
-
-               conn = hci_conn_hash_lookup_handle(hdev, handle);
-               if (conn) {
-                       conn->sent -= count;
+               hci_dev_lock(hdev);
 
-                       if (conn->type == ACL_LINK) {
-                               if ((hdev->acl_cnt += count) > hdev->acl_pkts)
-                                       hdev->acl_cnt = hdev->acl_pkts;
-                       } else {
-                               if ((hdev->sco_cnt += count) > hdev->sco_pkts)
-                                       hdev->sco_cnt = hdev->sco_pkts;
+               conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
+               if (!conn) {
+                       if (!(conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr))) {
+                               BT_ERR("No memmory for new connection");
+                               hci_dev_unlock(hdev);
+                               return;
                        }
                }
-       }
-       hci_sched_tx(hdev);
 
-       tasklet_enable(&hdev->tx_task);
-}
+               memcpy(conn->dev_class, ev->dev_class, 3);
+               conn->state = BT_CONNECT;
 
-/* Role Change */
-static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
-{
-       struct hci_ev_role_change *ev = (struct hci_ev_role_change *) skb->data;
-       struct hci_conn *conn;
+               hci_dev_unlock(hdev);
 
-       BT_DBG("%s status %d", hdev->name, ev->status);
+               if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
+                       struct hci_cp_accept_conn_req cp;
 
-       hci_dev_lock(hdev);
+                       bacpy(&cp.bdaddr, &ev->bdaddr);
 
-       conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
-       if (conn) {
-               if (!ev->status) {
-                       if (ev->role)
-                               conn->link_mode &= ~HCI_LM_MASTER;
+                       if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
+                               cp.role = 0x00; /* Become master */
                        else
-                               conn->link_mode |= HCI_LM_MASTER;
-               }
+                               cp.role = 0x01; /* Remain slave */
 
-               clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
+                       hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
+                                                       sizeof(cp), &cp);
+               } else {
+                       struct hci_cp_accept_sync_conn_req cp;
 
-               hci_role_switch_cfm(conn, ev->status, ev->role);
-       }
+                       bacpy(&cp.bdaddr, &ev->bdaddr);
+                       cp.pkt_type = cpu_to_le16(hdev->esco_type);
 
-       hci_dev_unlock(hdev);
+                       cp.tx_bandwidth   = cpu_to_le32(0x00001f40);
+                       cp.rx_bandwidth   = cpu_to_le32(0x00001f40);
+                       cp.max_latency    = cpu_to_le16(0xffff);
+                       cp.content_format = cpu_to_le16(hdev->voice_setting);
+                       cp.retrans_effort = 0xff;
+
+                       hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
+                                                       sizeof(cp), &cp);
+               }
+       } else {
+               /* Connection rejected */
+               struct hci_cp_reject_conn_req cp;
+
+               bacpy(&cp.bdaddr, &ev->bdaddr);
+               cp.reason = 0x0f;
+               hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
+       }
 }
 
-/* Mode Change */
-static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
-       struct hci_ev_mode_change *ev = (struct hci_ev_mode_change *) skb->data;
+       struct hci_ev_disconn_complete *ev = (void *) skb->data;
        struct hci_conn *conn;
 
        BT_DBG("%s status %d", hdev->name, ev->status);
 
+       if (ev->status)
+               return;
+
        hci_dev_lock(hdev);
 
        conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
        if (conn) {
-               conn->mode = ev->mode;
-               conn->interval = __le16_to_cpu(ev->interval);
-
-               if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
-                       if (conn->mode == HCI_CM_ACTIVE)
-                               conn->power_save = 1;
-                       else
-                               conn->power_save = 0;
-               }
+               conn->state = BT_CLOSED;
+               hci_proto_disconn_ind(conn, ev->reason);
+               hci_conn_del(conn);
        }
 
        hci_dev_unlock(hdev);
 }
 
-/* Authentication Complete */
 static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
-       struct hci_ev_auth_complete *ev = (struct hci_ev_auth_complete *) skb->data;
+       struct hci_ev_auth_complete *ev = (void *) skb->data;
        struct hci_conn *conn;
 
        BT_DBG("%s status %d", hdev->name, ev->status);
@@ -985,8 +853,8 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
                                struct hci_cp_set_conn_encrypt cp;
                                cp.handle  = cpu_to_le16(conn->handle);
                                cp.encrypt = 1;
-                               hci_send_cmd(conn->hdev, OGF_LINK_CTL,
-                                       OCF_SET_CONN_ENCRYPT, sizeof(cp), &cp);
+                               hci_send_cmd(conn->hdev,
+                                       HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), &cp);
                        } else {
                                clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
                                hci_encrypt_cfm(conn, ev->status, 0x00);
@@ -997,10 +865,16 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
        hci_dev_unlock(hdev);
 }
 
-/* Encryption Change */
+static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       BT_DBG("%s", hdev->name);
+
+       hci_conn_check_pending(hdev);
+}
+
 static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
-       struct hci_ev_encrypt_change *ev = (struct hci_ev_encrypt_change *) skb->data;
+       struct hci_ev_encrypt_change *ev = (void *) skb->data;
        struct hci_conn *conn;
 
        BT_DBG("%s status %d", hdev->name, ev->status);
@@ -1024,10 +898,9 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *
        hci_dev_unlock(hdev);
 }
 
-/* Change Connection Link Key Complete */
-static inline void hci_change_conn_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
-       struct hci_ev_change_conn_link_key_complete *ev = (struct hci_ev_change_conn_link_key_complete *) skb->data;
+       struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
        struct hci_conn *conn;
 
        BT_DBG("%s status %d", hdev->name, ev->status);
@@ -1047,25 +920,263 @@ static inline void hci_change_conn_link_key_complete_evt(struct hci_dev *hdev, s
        hci_dev_unlock(hdev);
 }
 
-/* Pin Code Request*/
-static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
-}
+       struct hci_ev_remote_features *ev = (void *) skb->data;
+       struct hci_conn *conn;
 
-/* Link Key Request */
-static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
-{
+       BT_DBG("%s status %d", hdev->name, ev->status);
+
+       if (ev->status)
+               return;
+
+       hci_dev_lock(hdev);
+
+       conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
+       if (conn)
+               memcpy(conn->features, ev->features, 8);
+
+       hci_dev_unlock(hdev);
 }
 
-/* Link Key Notification */
-static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       BT_DBG("%s", hdev->name);
+}
+
+static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
+       BT_DBG("%s", hdev->name);
 }
 
-/* Remote Features */
-static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
-       struct hci_ev_remote_features *ev = (struct hci_ev_remote_features *) skb->data;
+       struct hci_ev_cmd_complete *ev = (void *) skb->data;
+       __u16 opcode;
+
+       skb_pull(skb, sizeof(*ev));
+
+       opcode = __le16_to_cpu(ev->opcode);
+
+       switch (opcode) {
+       case HCI_OP_INQUIRY_CANCEL:
+               hci_cc_inquiry_cancel(hdev, skb);
+               break;
+
+       case HCI_OP_EXIT_PERIODIC_INQ:
+               hci_cc_exit_periodic_inq(hdev, skb);
+               break;
+
+       case HCI_OP_REMOTE_NAME_REQ_CANCEL:
+               hci_cc_remote_name_req_cancel(hdev, skb);
+               break;
+
+       case HCI_OP_ROLE_DISCOVERY:
+               hci_cc_role_discovery(hdev, skb);
+               break;
+
+       case HCI_OP_WRITE_LINK_POLICY:
+               hci_cc_write_link_policy(hdev, skb);
+               break;
+
+       case HCI_OP_RESET:
+               hci_cc_reset(hdev, skb);
+               break;
+
+       case HCI_OP_WRITE_LOCAL_NAME:
+               hci_cc_write_local_name(hdev, skb);
+               break;
+
+       case HCI_OP_READ_LOCAL_NAME:
+               hci_cc_read_local_name(hdev, skb);
+               break;
+
+       case HCI_OP_WRITE_AUTH_ENABLE:
+               hci_cc_write_auth_enable(hdev, skb);
+               break;
+
+       case HCI_OP_WRITE_ENCRYPT_MODE:
+               hci_cc_write_encrypt_mode(hdev, skb);
+               break;
+
+       case HCI_OP_WRITE_SCAN_ENABLE:
+               hci_cc_write_scan_enable(hdev, skb);
+               break;
+
+       case HCI_OP_READ_CLASS_OF_DEV:
+               hci_cc_read_class_of_dev(hdev, skb);
+               break;
+
+       case HCI_OP_WRITE_CLASS_OF_DEV:
+               hci_cc_write_class_of_dev(hdev, skb);
+               break;
+
+       case HCI_OP_READ_VOICE_SETTING:
+               hci_cc_read_voice_setting(hdev, skb);
+               break;
+
+       case HCI_OP_WRITE_VOICE_SETTING:
+               hci_cc_write_voice_setting(hdev, skb);
+               break;
+
+       case HCI_OP_HOST_BUFFER_SIZE:
+               hci_cc_host_buffer_size(hdev, skb);
+               break;
+
+       case HCI_OP_READ_LOCAL_VERSION:
+               hci_cc_read_local_version(hdev, skb);
+               break;
+
+       case HCI_OP_READ_LOCAL_COMMANDS:
+               hci_cc_read_local_commands(hdev, skb);
+               break;
+
+       case HCI_OP_READ_LOCAL_FEATURES:
+               hci_cc_read_local_features(hdev, skb);
+               break;
+
+       case HCI_OP_READ_BUFFER_SIZE:
+               hci_cc_read_buffer_size(hdev, skb);
+               break;
+
+       case HCI_OP_READ_BD_ADDR:
+               hci_cc_read_bd_addr(hdev, skb);
+               break;
+
+       default:
+               BT_DBG("%s opcode 0x%x", hdev->name, opcode);
+               break;
+       }
+
+       if (ev->ncmd) {
+               atomic_set(&hdev->cmd_cnt, 1);
+               if (!skb_queue_empty(&hdev->cmd_q))
+                       hci_sched_cmd(hdev);
+       }
+}
+
+static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       struct hci_ev_cmd_status *ev = (void *) skb->data;
+       __u16 opcode;
+
+       skb_pull(skb, sizeof(*ev));
+
+       opcode = __le16_to_cpu(ev->opcode);
+
+       switch (opcode) {
+       case HCI_OP_INQUIRY:
+               hci_cs_inquiry(hdev, ev->status);
+               break;
+
+       case HCI_OP_CREATE_CONN:
+               hci_cs_create_conn(hdev, ev->status);
+               break;
+
+       case HCI_OP_ADD_SCO:
+               hci_cs_add_sco(hdev, ev->status);
+               break;
+
+       case HCI_OP_REMOTE_NAME_REQ:
+               hci_cs_remote_name_req(hdev, ev->status);
+               break;
+
+       case HCI_OP_SETUP_SYNC_CONN:
+               hci_cs_setup_sync_conn(hdev, ev->status);
+               break;
+
+       case HCI_OP_SNIFF_MODE:
+               hci_cs_sniff_mode(hdev, ev->status);
+               break;
+
+       case HCI_OP_EXIT_SNIFF_MODE:
+               hci_cs_exit_sniff_mode(hdev, ev->status);
+               break;
+
+       default:
+               BT_DBG("%s opcode 0x%x", hdev->name, opcode);
+               break;
+       }
+
+       if (ev->ncmd) {
+               atomic_set(&hdev->cmd_cnt, 1);
+               if (!skb_queue_empty(&hdev->cmd_q))
+                       hci_sched_cmd(hdev);
+       }
+}
+
+static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       struct hci_ev_role_change *ev = (void *) skb->data;
+       struct hci_conn *conn;
+
+       BT_DBG("%s status %d", hdev->name, ev->status);
+
+       hci_dev_lock(hdev);
+
+       conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
+       if (conn) {
+               if (!ev->status) {
+                       if (ev->role)
+                               conn->link_mode &= ~HCI_LM_MASTER;
+                       else
+                               conn->link_mode |= HCI_LM_MASTER;
+               }
+
+               clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
+
+               hci_role_switch_cfm(conn, ev->status, ev->role);
+       }
+
+       hci_dev_unlock(hdev);
+}
+
+static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
+       __le16 *ptr;
+       int i;
+
+       skb_pull(skb, sizeof(*ev));
+
+       BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
+
+       if (skb->len < ev->num_hndl * 4) {
+               BT_DBG("%s bad parameters", hdev->name);
+               return;
+       }
+
+       tasklet_disable(&hdev->tx_task);
+
+       for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
+               struct hci_conn *conn;
+               __u16  handle, count;
+
+               handle = __le16_to_cpu(get_unaligned(ptr++));
+               count  = __le16_to_cpu(get_unaligned(ptr++));
+
+               conn = hci_conn_hash_lookup_handle(hdev, handle);
+               if (conn) {
+                       conn->sent -= count;
+
+                       if (conn->type == ACL_LINK) {
+                               if ((hdev->acl_cnt += count) > hdev->acl_pkts)
+                                       hdev->acl_cnt = hdev->acl_pkts;
+                       } else {
+                               if ((hdev->sco_cnt += count) > hdev->sco_pkts)
+                                       hdev->sco_cnt = hdev->sco_pkts;
+                       }
+               }
+       }
+
+       hci_sched_tx(hdev);
+
+       tasklet_enable(&hdev->tx_task);
+}
+
+static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       struct hci_ev_mode_change *ev = (void *) skb->data;
        struct hci_conn *conn;
 
        BT_DBG("%s status %d", hdev->name, ev->status);
@@ -1073,17 +1184,39 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff
        hci_dev_lock(hdev);
 
        conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
-       if (conn && !ev->status) {
-               memcpy(conn->features, ev->features, sizeof(conn->features));
+       if (conn) {
+               conn->mode = ev->mode;
+               conn->interval = __le16_to_cpu(ev->interval);
+
+               if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
+                       if (conn->mode == HCI_CM_ACTIVE)
+                               conn->power_save = 1;
+                       else
+                               conn->power_save = 0;
+               }
        }
 
        hci_dev_unlock(hdev);
 }
 
-/* Clock Offset */
+static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       BT_DBG("%s", hdev->name);
+}
+
+static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       BT_DBG("%s", hdev->name);
+}
+
+static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       BT_DBG("%s", hdev->name);
+}
+
 static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
-       struct hci_ev_clock_offset *ev = (struct hci_ev_clock_offset *) skb->data;
+       struct hci_ev_clock_offset *ev = (void *) skb->data;
        struct hci_conn *conn;
 
        BT_DBG("%s status %d", hdev->name, ev->status);
@@ -1103,10 +1236,9 @@ static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *sk
        hci_dev_unlock(hdev);
 }
 
-/* Page Scan Repetition Mode */
 static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
-       struct hci_ev_pscan_rep_mode *ev = (struct hci_ev_pscan_rep_mode *) skb->data;
+       struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
        struct inquiry_entry *ie;
 
        BT_DBG("%s", hdev->name);
@@ -1121,10 +1253,91 @@ static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *
        hci_dev_unlock(hdev);
 }
 
-/* Sniff Subrate */
+static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       struct inquiry_data data;
+       int num_rsp = *((__u8 *) skb->data);
+
+       BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
+
+       if (!num_rsp)
+               return;
+
+       hci_dev_lock(hdev);
+
+       if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
+               struct inquiry_info_with_rssi_and_pscan_mode *info = (void *) (skb->data + 1);
+
+               for (; num_rsp; num_rsp--) {
+                       bacpy(&data.bdaddr, &info->bdaddr);
+                       data.pscan_rep_mode     = info->pscan_rep_mode;
+                       data.pscan_period_mode  = info->pscan_period_mode;
+                       data.pscan_mode         = info->pscan_mode;
+                       memcpy(data.dev_class, info->dev_class, 3);
+                       data.clock_offset       = info->clock_offset;
+                       data.rssi               = info->rssi;
+                       info++;
+                       hci_inquiry_cache_update(hdev, &data);
+               }
+       } else {
+               struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
+
+               for (; num_rsp; num_rsp--) {
+                       bacpy(&data.bdaddr, &info->bdaddr);
+                       data.pscan_rep_mode     = info->pscan_rep_mode;
+                       data.pscan_period_mode  = info->pscan_period_mode;
+                       data.pscan_mode         = 0x00;
+                       memcpy(data.dev_class, info->dev_class, 3);
+                       data.clock_offset       = info->clock_offset;
+                       data.rssi               = info->rssi;
+                       info++;
+                       hci_inquiry_cache_update(hdev, &data);
+               }
+       }
+
+       hci_dev_unlock(hdev);
+}
+
+static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       BT_DBG("%s", hdev->name);
+}
+
+static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
+       struct hci_conn *conn;
+
+       BT_DBG("%s status %d", hdev->name, ev->status);
+
+       hci_dev_lock(hdev);
+
+       conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
+       if (!conn)
+               goto unlock;
+
+       if (!ev->status) {
+               conn->handle = __le16_to_cpu(ev->handle);
+               conn->state  = BT_CONNECTED;
+       } else
+               conn->state = BT_CLOSED;
+
+       hci_proto_connect_cfm(conn, ev->status);
+       if (ev->status)
+               hci_conn_del(conn);
+
+unlock:
+       hci_dev_unlock(hdev);
+}
+
+static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       BT_DBG("%s", hdev->name);
+}
+
 static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
-       struct hci_ev_sniff_subrate *ev = (struct hci_ev_sniff_subrate *) skb->data;
+       struct hci_ev_sniff_subrate *ev = (void *) skb->data;
        struct hci_conn *conn;
 
        BT_DBG("%s status %d", hdev->name, ev->status);
@@ -1138,22 +1351,42 @@ static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *s
        hci_dev_unlock(hdev);
 }
 
-void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
-       struct hci_event_hdr *hdr = (struct hci_event_hdr *) skb->data;
-       struct hci_ev_cmd_complete *ec;
-       struct hci_ev_cmd_status *cs;
-       u16 opcode, ocf, ogf;
+       struct inquiry_data data;
+       struct extended_inquiry_info *info = (void *) (skb->data + 1);
+       int num_rsp = *((__u8 *) skb->data);
 
-       skb_pull(skb, HCI_EVENT_HDR_SIZE);
+       BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
 
-       BT_DBG("%s evt 0x%x", hdev->name, hdr->evt);
+       if (!num_rsp)
+               return;
 
-       switch (hdr->evt) {
-       case HCI_EV_NUM_COMP_PKTS:
-               hci_num_comp_pkts_evt(hdev, skb);
-               break;
+       hci_dev_lock(hdev);
+
+       for (; num_rsp; num_rsp--) {
+               bacpy(&data.bdaddr, &info->bdaddr);
+               data.pscan_rep_mode     = info->pscan_rep_mode;
+               data.pscan_period_mode  = info->pscan_period_mode;
+               data.pscan_mode         = 0x00;
+               memcpy(data.dev_class, info->dev_class, 3);
+               data.clock_offset       = info->clock_offset;
+               data.rssi               = info->rssi;
+               info++;
+               hci_inquiry_cache_update(hdev, &data);
+       }
+
+       hci_dev_unlock(hdev);
+}
+
+void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       struct hci_event_hdr *hdr = (void *) skb->data;
+       __u8 event = hdr->evt;
+
+       skb_pull(skb, HCI_EVENT_HDR_SIZE);
 
+       switch (event) {
        case HCI_EV_INQUIRY_COMPLETE:
                hci_inquiry_complete_evt(hdev, skb);
                break;
@@ -1162,44 +1395,64 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
                hci_inquiry_result_evt(hdev, skb);
                break;
 
-       case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
-               hci_inquiry_result_with_rssi_evt(hdev, skb);
-               break;
-
-       case HCI_EV_EXTENDED_INQUIRY_RESULT:
-               hci_extended_inquiry_result_evt(hdev, skb);
+       case HCI_EV_CONN_COMPLETE:
+               hci_conn_complete_evt(hdev, skb);
                break;
 
        case HCI_EV_CONN_REQUEST:
                hci_conn_request_evt(hdev, skb);
                break;
 
-       case HCI_EV_CONN_COMPLETE:
-               hci_conn_complete_evt(hdev, skb);
-               break;
-
        case HCI_EV_DISCONN_COMPLETE:
                hci_disconn_complete_evt(hdev, skb);
                break;
 
-       case HCI_EV_ROLE_CHANGE:
-               hci_role_change_evt(hdev, skb);
-               break;
-
-       case HCI_EV_MODE_CHANGE:
-               hci_mode_change_evt(hdev, skb);
-               break;
-
        case HCI_EV_AUTH_COMPLETE:
                hci_auth_complete_evt(hdev, skb);
                break;
 
+       case HCI_EV_REMOTE_NAME:
+               hci_remote_name_evt(hdev, skb);
+               break;
+
        case HCI_EV_ENCRYPT_CHANGE:
                hci_encrypt_change_evt(hdev, skb);
                break;
 
-       case HCI_EV_CHANGE_CONN_LINK_KEY_COMPLETE:
-               hci_change_conn_link_key_complete_evt(hdev, skb);
+       case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
+               hci_change_link_key_complete_evt(hdev, skb);
+               break;
+
+       case HCI_EV_REMOTE_FEATURES:
+               hci_remote_features_evt(hdev, skb);
+               break;
+
+       case HCI_EV_REMOTE_VERSION:
+               hci_remote_version_evt(hdev, skb);
+               break;
+
+       case HCI_EV_QOS_SETUP_COMPLETE:
+               hci_qos_setup_complete_evt(hdev, skb);
+               break;
+
+       case HCI_EV_CMD_COMPLETE:
+               hci_cmd_complete_evt(hdev, skb);
+               break;
+
+       case HCI_EV_CMD_STATUS:
+               hci_cmd_status_evt(hdev, skb);
+               break;
+
+       case HCI_EV_ROLE_CHANGE:
+               hci_role_change_evt(hdev, skb);
+               break;
+
+       case HCI_EV_NUM_COMP_PKTS:
+               hci_num_comp_pkts_evt(hdev, skb);
+               break;
+
+       case HCI_EV_MODE_CHANGE:
+               hci_mode_change_evt(hdev, skb);
                break;
 
        case HCI_EV_PIN_CODE_REQ:
@@ -1214,10 +1467,6 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
                hci_link_key_notify_evt(hdev, skb);
                break;
 
-       case HCI_EV_REMOTE_FEATURES:
-               hci_remote_features_evt(hdev, skb);
-               break;
-
        case HCI_EV_CLOCK_OFFSET:
                hci_clock_offset_evt(hdev, skb);
                break;
@@ -1226,82 +1475,32 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
                hci_pscan_rep_mode_evt(hdev, skb);
                break;
 
-       case HCI_EV_SNIFF_SUBRATE:
-               hci_sniff_subrate_evt(hdev, skb);
+       case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
+               hci_inquiry_result_with_rssi_evt(hdev, skb);
                break;
 
-       case HCI_EV_CMD_STATUS:
-               cs = (struct hci_ev_cmd_status *) skb->data;
-               skb_pull(skb, sizeof(cs));
-
-               opcode = __le16_to_cpu(cs->opcode);
-               ogf = hci_opcode_ogf(opcode);
-               ocf = hci_opcode_ocf(opcode);
-
-               switch (ogf) {
-               case OGF_INFO_PARAM:
-                       hci_cs_info_param(hdev, ocf, cs->status);
-                       break;
-
-               case OGF_HOST_CTL:
-                       hci_cs_host_ctl(hdev, ocf, cs->status);
-                       break;
-
-               case OGF_LINK_CTL:
-                       hci_cs_link_ctl(hdev, ocf, cs->status);
-                       break;
-
-               case OGF_LINK_POLICY:
-                       hci_cs_link_policy(hdev, ocf, cs->status);
-                       break;
-
-               default:
-                       BT_DBG("%s Command Status OGF %x", hdev->name, ogf);
-                       break;
-               }
-
-               if (cs->ncmd) {
-                       atomic_set(&hdev->cmd_cnt, 1);
-                       if (!skb_queue_empty(&hdev->cmd_q))
-                               hci_sched_cmd(hdev);
-               }
+       case HCI_EV_REMOTE_EXT_FEATURES:
+               hci_remote_ext_features_evt(hdev, skb);
                break;
 
-       case HCI_EV_CMD_COMPLETE:
-               ec = (struct hci_ev_cmd_complete *) skb->data;
-               skb_pull(skb, sizeof(*ec));
-
-               opcode = __le16_to_cpu(ec->opcode);
-               ogf = hci_opcode_ogf(opcode);
-               ocf = hci_opcode_ocf(opcode);
-
-               switch (ogf) {
-               case OGF_INFO_PARAM:
-                       hci_cc_info_param(hdev, ocf, skb);
-                       break;
-
-               case OGF_HOST_CTL:
-                       hci_cc_host_ctl(hdev, ocf, skb);
-                       break;
+       case HCI_EV_SYNC_CONN_COMPLETE:
+               hci_sync_conn_complete_evt(hdev, skb);
+               break;
 
-               case OGF_LINK_CTL:
-                       hci_cc_link_ctl(hdev, ocf, skb);
-                       break;
+       case HCI_EV_SYNC_CONN_CHANGED:
+               hci_sync_conn_changed_evt(hdev, skb);
+               break;
 
-               case OGF_LINK_POLICY:
-                       hci_cc_link_policy(hdev, ocf, skb);
-                       break;
+       case HCI_EV_SNIFF_SUBRATE:
+               hci_sniff_subrate_evt(hdev, skb);
+               break;
 
-               default:
-                       BT_DBG("%s Command Completed OGF %x", hdev->name, ogf);
-                       break;
-               }
+       case HCI_EV_EXTENDED_INQUIRY_RESULT:
+               hci_extended_inquiry_result_evt(hdev, skb);
+               break;
 
-               if (ec->ncmd) {
-                       atomic_set(&hdev->cmd_cnt, 1);
-                       if (!skb_queue_empty(&hdev->cmd_q))
-                               hci_sched_cmd(hdev);
-               }
+       default:
+               BT_DBG("%s event 0x%x", hdev->name, event);
                break;
        }
 
index 43dd6373bff906e56859e36c5c572d772addad3b..8825102c517c48180960a5821c949f6463ce0480 100644 (file)
@@ -451,7 +451,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
                        goto drop;
                }
 
-               if (test_bit(HCI_RAW, &hdev->flags) || (ogf == OGF_VENDOR_CMD)) {
+               if (test_bit(HCI_RAW, &hdev->flags) || (ogf == 0x3f)) {
                        skb_queue_tail(&hdev->raw_q, skb);
                        hci_sched_tx(hdev);
                } else {
index 25835403d6591551c953f1aa1c1331fec92ca9db..cef1e3e1881ca70e1bf193b45f5874e2c1c44698 100644 (file)
@@ -41,6 +41,26 @@ static ssize_t show_type(struct device *dev, struct device_attribute *attr, char
        return sprintf(buf, "%s\n", typetostr(hdev->type));
 }
 
+static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct hci_dev *hdev = dev_get_drvdata(dev);
+       char name[249];
+       int i;
+
+       for (i = 0; i < 248; i++)
+               name[i] = hdev->dev_name[i];
+
+       name[248] = '\0';
+       return sprintf(buf, "%s\n", name);
+}
+
+static ssize_t show_class(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct hci_dev *hdev = dev_get_drvdata(dev);
+       return sprintf(buf, "0x%.2x%.2x%.2x\n",
+                       hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
+}
+
 static ssize_t show_address(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct hci_dev *hdev = dev_get_drvdata(dev);
@@ -49,6 +69,17 @@ static ssize_t show_address(struct device *dev, struct device_attribute *attr, c
        return sprintf(buf, "%s\n", batostr(&bdaddr));
 }
 
+static ssize_t show_features(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct hci_dev *hdev = dev_get_drvdata(dev);
+
+       return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
+                               hdev->features[0], hdev->features[1],
+                               hdev->features[2], hdev->features[3],
+                               hdev->features[4], hdev->features[5],
+                               hdev->features[6], hdev->features[7]);
+}
+
 static ssize_t show_manufacturer(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct hci_dev *hdev = dev_get_drvdata(dev);
@@ -170,7 +201,10 @@ static ssize_t store_sniff_min_interval(struct device *dev, struct device_attrib
 }
 
 static DEVICE_ATTR(type, S_IRUGO, show_type, NULL);
+static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+static DEVICE_ATTR(class, S_IRUGO, show_class, NULL);
 static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
+static DEVICE_ATTR(features, S_IRUGO, show_features, NULL);
 static DEVICE_ATTR(manufacturer, S_IRUGO, show_manufacturer, NULL);
 static DEVICE_ATTR(hci_version, S_IRUGO, show_hci_version, NULL);
 static DEVICE_ATTR(hci_revision, S_IRUGO, show_hci_revision, NULL);
@@ -185,7 +219,10 @@ static DEVICE_ATTR(sniff_min_interval, S_IRUGO | S_IWUSR,
 
 static struct device_attribute *bt_attrs[] = {
        &dev_attr_type,
+       &dev_attr_name,
+       &dev_attr_class,
        &dev_attr_address,
+       &dev_attr_features,
        &dev_attr_manufacturer,
        &dev_attr_hci_version,
        &dev_attr_hci_revision,
index ff5784b440d792b87bf2cd088801b1b6b5b5c0af..4bbacddeb49d4d4425177cf972b921bd195ec92f 100644 (file)
@@ -247,7 +247,7 @@ static inline int hidp_queue_report(struct hidp_session *session, unsigned char
 {
        struct sk_buff *skb;
 
-       BT_DBG("session %p hid %p data %p size %d", session, device, data, size);
+       BT_DBG("session %p hid %p data %p size %d", session, session->hid, data, size);
 
        if (!(skb = alloc_skb(size + 1, GFP_ATOMIC))) {
                BT_ERR("Can't allocate memory for new frame");
@@ -656,11 +656,13 @@ static inline int hidp_setup_input(struct hidp_session *session, struct hidp_con
        }
 
        if (req->subclass & 0x80) {
-               input->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-               input->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
-               input->relbit[0] = BIT(REL_X) | BIT(REL_Y);
-               input->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA);
-               input->relbit[0] |= BIT(REL_WHEEL);
+               input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+               input->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+                       BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
+               input->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
+               input->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_SIDE) |
+                       BIT_MASK(BTN_EXTRA);
+               input->relbit[0] |= BIT_MASK(REL_WHEEL);
        }
 
        input->dev.parent = hidp_get_device(session);
index 36ef27b625db23d19f67c81ae1e1849665d0bc10..6fbbae78b30452c8ee6e20742d011ebaba4acc11 100644 (file)
@@ -55,7 +55,9 @@
 #define BT_DBG(D...)
 #endif
 
-#define VERSION "2.8"
+#define VERSION "2.9"
+
+static u32 l2cap_feat_mask = 0x0000;
 
 static const struct proto_ops l2cap_sock_ops;
 
@@ -258,7 +260,119 @@ static void l2cap_chan_del(struct sock *sk, int err)
                sk->sk_state_change(sk);
 }
 
+static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
+{
+       u8 id;
+
+       /* Get next available identificator.
+        *    1 - 128 are used by kernel.
+        *  129 - 199 are reserved.
+        *  200 - 254 are used by utilities like l2ping, etc.
+        */
+
+       spin_lock_bh(&conn->lock);
+
+       if (++conn->tx_ident > 128)
+               conn->tx_ident = 1;
+
+       id = conn->tx_ident;
+
+       spin_unlock_bh(&conn->lock);
+
+       return id;
+}
+
+static inline int l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
+{
+       struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
+
+       BT_DBG("code 0x%2.2x", code);
+
+       if (!skb)
+               return -ENOMEM;
+
+       return hci_send_acl(conn->hcon, skb, 0);
+}
+
 /* ---- L2CAP connections ---- */
+static void l2cap_conn_start(struct l2cap_conn *conn)
+{
+       struct l2cap_chan_list *l = &conn->chan_list;
+       struct sock *sk;
+
+       BT_DBG("conn %p", conn);
+
+       read_lock(&l->lock);
+
+       for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
+               bh_lock_sock(sk);
+
+               if (sk->sk_type != SOCK_SEQPACKET) {
+                       l2cap_sock_clear_timer(sk);
+                       sk->sk_state = BT_CONNECTED;
+                       sk->sk_state_change(sk);
+               } else if (sk->sk_state == BT_CONNECT) {
+                       struct l2cap_conn_req req;
+                       l2cap_pi(sk)->ident = l2cap_get_ident(conn);
+                       req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
+                       req.psm  = l2cap_pi(sk)->psm;
+                       l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
+                                       L2CAP_CONN_REQ, sizeof(req), &req);
+               }
+
+               bh_unlock_sock(sk);
+       }
+
+       read_unlock(&l->lock);
+}
+
+static void l2cap_conn_ready(struct l2cap_conn *conn)
+{
+       BT_DBG("conn %p", conn);
+
+       if (conn->chan_list.head || !hlist_empty(&l2cap_sk_list.head)) {
+               struct l2cap_info_req req;
+
+               req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
+
+               conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
+               conn->info_ident = l2cap_get_ident(conn);
+
+               mod_timer(&conn->info_timer,
+                       jiffies + msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
+
+               l2cap_send_cmd(conn, conn->info_ident,
+                                       L2CAP_INFO_REQ, sizeof(req), &req);
+       }
+}
+
+/* Notify sockets that we cannot guaranty reliability anymore */
+static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
+{
+       struct l2cap_chan_list *l = &conn->chan_list;
+       struct sock *sk;
+
+       BT_DBG("conn %p", conn);
+
+       read_lock(&l->lock);
+
+       for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
+               if (l2cap_pi(sk)->link_mode & L2CAP_LM_RELIABLE)
+                       sk->sk_err = err;
+       }
+
+       read_unlock(&l->lock);
+}
+
+static void l2cap_info_timeout(unsigned long arg)
+{
+       struct l2cap_conn *conn = (void *) arg;
+
+       conn->info_ident = 0;
+
+       l2cap_conn_start(conn);
+}
+
 static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
 {
        struct l2cap_conn *conn = hcon->l2cap_data;
@@ -279,6 +393,12 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
        conn->src = &hcon->hdev->bdaddr;
        conn->dst = &hcon->dst;
 
+       conn->feat_mask = 0;
+
+       init_timer(&conn->info_timer);
+       conn->info_timer.function = l2cap_info_timeout;
+       conn->info_timer.data = (unsigned long) conn;
+
        spin_lock_init(&conn->lock);
        rwlock_init(&conn->chan_list.lock);
 
@@ -318,40 +438,6 @@ static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, stru
        write_unlock_bh(&l->lock);
 }
 
-static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
-{
-       u8 id;
-
-       /* Get next available identificator.
-        *    1 - 128 are used by kernel.
-        *  129 - 199 are reserved.
-        *  200 - 254 are used by utilities like l2ping, etc.
-        */
-
-       spin_lock_bh(&conn->lock);
-
-       if (++conn->tx_ident > 128)
-               conn->tx_ident = 1;
-
-       id = conn->tx_ident;
-
-       spin_unlock_bh(&conn->lock);
-
-       return id;
-}
-
-static inline int l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
-{
-       struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
-
-       BT_DBG("code 0x%2.2x", code);
-
-       if (!skb)
-               return -ENOMEM;
-
-       return hci_send_acl(conn->hcon, skb, 0);
-}
-
 /* ---- Socket interface ---- */
 static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
 {
@@ -508,7 +594,6 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
 
        /* Default config options */
        pi->conf_len = 0;
-       pi->conf_mtu = L2CAP_DEFAULT_MTU;
        pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
 }
 
@@ -530,7 +615,7 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p
        INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
 
        sk->sk_destruct = l2cap_sock_destruct;
-       sk->sk_sndtimeo = L2CAP_CONN_TIMEOUT;
+       sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
 
        sock_reset_flag(sk, SOCK_ZAPPED);
 
@@ -650,6 +735,11 @@ static int l2cap_do_connect(struct sock *sk)
        l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
 
        if (hcon->state == BT_CONNECTED) {
+               if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)) {
+                       l2cap_conn_ready(conn);
+                       goto done;
+               }
+
                if (sk->sk_type == SOCK_SEQPACKET) {
                        struct l2cap_conn_req req;
                        l2cap_pi(sk)->ident = l2cap_get_ident(conn);
@@ -958,7 +1048,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
                opts.imtu     = l2cap_pi(sk)->imtu;
                opts.omtu     = l2cap_pi(sk)->omtu;
                opts.flush_to = l2cap_pi(sk)->flush_to;
-               opts.mode     = 0x00;
+               opts.mode     = L2CAP_MODE_BASIC;
 
                len = min_t(unsigned int, sizeof(opts), optlen);
                if (copy_from_user((char *) &opts, optval, len)) {
@@ -1007,7 +1097,7 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch
                opts.imtu     = l2cap_pi(sk)->imtu;
                opts.omtu     = l2cap_pi(sk)->omtu;
                opts.flush_to = l2cap_pi(sk)->flush_to;
-               opts.mode     = 0x00;
+               opts.mode     = L2CAP_MODE_BASIC;
 
                len = min_t(unsigned int, len, sizeof(opts));
                if (copy_to_user(optval, (char *) &opts, len))
@@ -1084,52 +1174,6 @@ static int l2cap_sock_release(struct socket *sock)
        return err;
 }
 
-static void l2cap_conn_ready(struct l2cap_conn *conn)
-{
-       struct l2cap_chan_list *l = &conn->chan_list;
-       struct sock *sk;
-
-       BT_DBG("conn %p", conn);
-
-       read_lock(&l->lock);
-
-       for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-               bh_lock_sock(sk);
-
-               if (sk->sk_type != SOCK_SEQPACKET) {
-                       l2cap_sock_clear_timer(sk);
-                       sk->sk_state = BT_CONNECTED;
-                       sk->sk_state_change(sk);
-               } else if (sk->sk_state == BT_CONNECT) {
-                       struct l2cap_conn_req req;
-                       l2cap_pi(sk)->ident = l2cap_get_ident(conn);
-                       req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
-                       req.psm  = l2cap_pi(sk)->psm;
-                       l2cap_send_cmd(conn, l2cap_pi(sk)->ident, L2CAP_CONN_REQ, sizeof(req), &req);
-               }
-
-               bh_unlock_sock(sk);
-       }
-
-       read_unlock(&l->lock);
-}
-
-/* Notify sockets that we cannot guaranty reliability anymore */
-static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
-{
-       struct l2cap_chan_list *l = &conn->chan_list;
-       struct sock *sk;
-
-       BT_DBG("conn %p", conn);
-
-       read_lock(&l->lock);
-       for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-               if (l2cap_pi(sk)->link_mode & L2CAP_LM_RELIABLE)
-                       sk->sk_err = err;
-       }
-       read_unlock(&l->lock);
-}
-
 static void l2cap_chan_ready(struct sock *sk)
 {
        struct sock *parent = bt_sk(sk)->parent;
@@ -1256,11 +1300,11 @@ static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned
                break;
 
        case 2:
-               *val = __le16_to_cpu(*((__le16 *)opt->val));
+               *val = __le16_to_cpu(*((__le16 *) opt->val));
                break;
 
        case 4:
-               *val = __le32_to_cpu(*((__le32 *)opt->val));
+               *val = __le32_to_cpu(*((__le32 *) opt->val));
                break;
 
        default:
@@ -1332,6 +1376,8 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data)
        int len = pi->conf_len;
        int type, hint, olen;
        unsigned long val;
+       struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
+       u16 mtu = L2CAP_DEFAULT_MTU;
        u16 result = L2CAP_CONF_SUCCESS;
 
        BT_DBG("sk %p", sk);
@@ -1344,7 +1390,7 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data)
 
                switch (type) {
                case L2CAP_CONF_MTU:
-                       pi->conf_mtu = val;
+                       mtu = val;
                        break;
 
                case L2CAP_CONF_FLUSH_TO:
@@ -1354,6 +1400,11 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data)
                case L2CAP_CONF_QOS:
                        break;
 
+               case L2CAP_CONF_RFC:
+                       if (olen == sizeof(rfc))
+                               memcpy(&rfc, (void *) val, olen);
+                       break;
+
                default:
                        if (hint)
                                break;
@@ -1368,12 +1419,24 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data)
                /* Configure output options and let the other side know
                 * which ones we don't like. */
 
-               if (pi->conf_mtu < pi->omtu)
+               if (rfc.mode == L2CAP_MODE_BASIC) {
+                       if (mtu < pi->omtu)
+                               result = L2CAP_CONF_UNACCEPT;
+                       else {
+                               pi->omtu = mtu;
+                               pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
+                       }
+
+                       l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
+               } else {
                        result = L2CAP_CONF_UNACCEPT;
-               else
-                       pi->omtu = pi->conf_mtu;
 
-               l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
+                       memset(&rfc, 0, sizeof(rfc));
+                       rfc.mode = L2CAP_MODE_BASIC;
+
+                       l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
+                                               sizeof(rfc), (unsigned long) &rfc);
+               }
        }
 
        rsp->scid   = cpu_to_le16(pi->dcid);
@@ -1397,6 +1460,23 @@ static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 fla
        return ptr - data;
 }
 
+static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
+{
+       struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
+
+       if (rej->reason != 0x0000)
+               return 0;
+
+       if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
+                                       cmd->ident == conn->info_ident) {
+               conn->info_ident = 0;
+               del_timer(&conn->info_timer);
+               l2cap_conn_start(conn);
+       }
+
+       return 0;
+}
+
 static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
 {
        struct l2cap_chan_list *list = &conn->chan_list;
@@ -1577,16 +1657,19 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
 
        l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
 
-       /* Output config done. */
-       l2cap_pi(sk)->conf_state |= L2CAP_CONF_OUTPUT_DONE;
-
        /* Reset config buffer. */
        l2cap_pi(sk)->conf_len = 0;
 
+       if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
+               goto unlock;
+
        if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
                sk->sk_state = BT_CONNECTED;
                l2cap_chan_ready(sk);
-       } else if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
+               goto unlock;
+       }
+
+       if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
                u8 req[64];
                l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
                                        l2cap_build_conf_req(sk, req), req);
@@ -1646,7 +1729,6 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
        if (flags & 0x01)
                goto done;
 
-       /* Input config done */
        l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
 
        if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
@@ -1711,16 +1793,27 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
 static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
 {
        struct l2cap_info_req *req = (struct l2cap_info_req *) data;
-       struct l2cap_info_rsp rsp;
        u16 type;
 
        type = __le16_to_cpu(req->type);
 
        BT_DBG("type 0x%4.4x", type);
 
-       rsp.type   = cpu_to_le16(type);
-       rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
-       l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp), &rsp);
+       if (type == L2CAP_IT_FEAT_MASK) {
+               u8 buf[8];
+               struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
+               rsp->type   = cpu_to_le16(L2CAP_IT_FEAT_MASK);
+               rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
+               put_unaligned(cpu_to_le32(l2cap_feat_mask), (__le32 *) rsp->data);
+               l2cap_send_cmd(conn, cmd->ident,
+                                       L2CAP_INFO_RSP, sizeof(buf), buf);
+       } else {
+               struct l2cap_info_rsp rsp;
+               rsp.type   = cpu_to_le16(type);
+               rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
+               l2cap_send_cmd(conn, cmd->ident,
+                                       L2CAP_INFO_RSP, sizeof(rsp), &rsp);
+       }
 
        return 0;
 }
@@ -1735,6 +1828,15 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm
 
        BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
 
+       conn->info_ident = 0;
+
+       del_timer(&conn->info_timer);
+
+       if (type == L2CAP_IT_FEAT_MASK)
+               conn->feat_mask = __le32_to_cpu(get_unaligned((__le32 *) rsp->data));
+
+       l2cap_conn_start(conn);
+
        return 0;
 }
 
@@ -1764,7 +1866,7 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *sk
 
                switch (cmd.code) {
                case L2CAP_COMMAND_REJ:
-                       /* FIXME: We should process this */
+                       l2cap_command_rej(conn, &cmd, data);
                        break;
 
                case L2CAP_CONN_REQ:
index bb7220770f2c671c879cca9aecdb3404021323a4..e7ac6ba7ecab0391829956d3bc97ad756a2c3800 100644 (file)
 #include <linux/sched.h>
 #include <linux/signal.h>
 #include <linux/init.h>
-#include <linux/freezer.h>
 #include <linux/wait.h>
 #include <linux/device.h>
 #include <linux/net.h>
 #include <linux/mutex.h>
+#include <linux/kthread.h>
 
 #include <net/sock.h>
 #include <asm/uaccess.h>
@@ -68,7 +68,6 @@ static DEFINE_MUTEX(rfcomm_mutex);
 static unsigned long rfcomm_event;
 
 static LIST_HEAD(session_list);
-static atomic_t terminate, running;
 
 static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len);
 static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci);
@@ -1850,26 +1849,6 @@ static inline void rfcomm_process_sessions(void)
        rfcomm_unlock();
 }
 
-static void rfcomm_worker(void)
-{
-       BT_DBG("");
-
-       while (!atomic_read(&terminate)) {
-               set_current_state(TASK_INTERRUPTIBLE);
-               if (!test_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event)) {
-                       /* No pending events. Let's sleep.
-                        * Incoming connections and data will wake us up. */
-                       schedule();
-               }
-               set_current_state(TASK_RUNNING);
-
-               /* Process stuff */
-               clear_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
-               rfcomm_process_sessions();
-       }
-       return;
-}
-
 static int rfcomm_add_listener(bdaddr_t *ba)
 {
        struct sockaddr_l2 addr;
@@ -1935,22 +1914,28 @@ static void rfcomm_kill_listener(void)
 
 static int rfcomm_run(void *unused)
 {
-       rfcomm_thread = current;
-
-       atomic_inc(&running);
+       BT_DBG("");
 
-       daemonize("krfcommd");
        set_user_nice(current, -10);
 
-       BT_DBG("");
-
        rfcomm_add_listener(BDADDR_ANY);
 
-       rfcomm_worker();
+       while (!kthread_should_stop()) {
+               set_current_state(TASK_INTERRUPTIBLE);
+               if (!test_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event)) {
+                       /* No pending events. Let's sleep.
+                        * Incoming connections and data will wake us up. */
+                       schedule();
+               }
+               set_current_state(TASK_RUNNING);
+
+               /* Process stuff */
+               clear_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
+               rfcomm_process_sessions();
+       }
 
        rfcomm_kill_listener();
 
-       atomic_dec(&running);
        return 0;
 }
 
@@ -2059,7 +2044,11 @@ static int __init rfcomm_init(void)
 
        hci_register_cb(&rfcomm_cb);
 
-       kernel_thread(rfcomm_run, NULL, CLONE_KERNEL);
+       rfcomm_thread = kthread_run(rfcomm_run, NULL, "krfcommd");
+       if (IS_ERR(rfcomm_thread)) {
+               hci_unregister_cb(&rfcomm_cb);
+               return PTR_ERR(rfcomm_thread);
+       }
 
        if (class_create_file(bt_class, &class_attr_rfcomm_dlc) < 0)
                BT_ERR("Failed to create RFCOMM info file");
@@ -2081,14 +2070,7 @@ static void __exit rfcomm_exit(void)
 
        hci_unregister_cb(&rfcomm_cb);
 
-       /* Terminate working thread.
-        * ie. Set terminate flag and wake it up */
-       atomic_inc(&terminate);
-       rfcomm_schedule(RFCOMM_SCHED_STATE);
-
-       /* Wait until thread is running */
-       while (atomic_read(&running))
-               schedule();
+       kthread_stop(rfcomm_thread);
 
 #ifdef CONFIG_BT_RFCOMM_TTY
        rfcomm_cleanup_ttys();
index 22a832098d44057e120ae76cecda07ae2d48ca00..e447651a2dbe86705a0ad35706b73d06928d8b94 100644 (file)
@@ -189,6 +189,23 @@ static struct device *rfcomm_get_device(struct rfcomm_dev *dev)
        return conn ? &conn->dev : NULL;
 }
 
+static ssize_t show_address(struct device *tty_dev, struct device_attribute *attr, char *buf)
+{
+       struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
+       bdaddr_t bdaddr;
+       baswap(&bdaddr, &dev->dst);
+       return sprintf(buf, "%s\n", batostr(&bdaddr));
+}
+
+static ssize_t show_channel(struct device *tty_dev, struct device_attribute *attr, char *buf)
+{
+       struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
+       return sprintf(buf, "%d\n", dev->channel);
+}
+
+static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
+static DEVICE_ATTR(channel, S_IRUGO, show_channel, NULL);
+
 static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
 {
        struct rfcomm_dev *dev;
@@ -281,6 +298,14 @@ out:
                return err;
        }
 
+       dev_set_drvdata(dev->tty_dev, dev);
+
+       if (device_create_file(dev->tty_dev, &dev_attr_address) < 0)
+               BT_ERR("Failed to create address attribute");
+
+       if (device_create_file(dev->tty_dev, &dev_attr_channel) < 0)
+               BT_ERR("Failed to create channel attribute");
+
        return dev->id;
 }
 
index 65b6fb1c41548c5b508a6b93eb9fe3c0d181857b..82d0dfdfa7e268a3dc21d03fb6d3d822b6998c50 100644 (file)
@@ -189,7 +189,7 @@ static int sco_connect(struct sock *sk)
        struct sco_conn *conn;
        struct hci_conn *hcon;
        struct hci_dev  *hdev;
-       int err = 0;
+       int err, type;
 
        BT_DBG("%s -> %s", batostr(src), batostr(dst));
 
@@ -200,7 +200,9 @@ static int sco_connect(struct sock *sk)
 
        err = -ENOMEM;
 
-       hcon = hci_connect(hdev, SCO_LINK, dst);
+       type = lmp_esco_capable(hdev) ? ESCO_LINK : SCO_LINK;
+
+       hcon = hci_connect(hdev, type, dst);
        if (!hcon)
                goto done;
 
@@ -224,6 +226,7 @@ static int sco_connect(struct sock *sk)
                sk->sk_state = BT_CONNECT;
                sco_sock_set_timer(sk, sk->sk_sndtimeo);
        }
+
 done:
        hci_dev_unlock_bh(hdev);
        hci_dev_put(hdev);
@@ -846,7 +849,7 @@ static int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
 {
        BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
 
-       if (hcon->type != SCO_LINK)
+       if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
                return 0;
 
        if (!status) {
@@ -865,10 +868,11 @@ static int sco_disconn_ind(struct hci_conn *hcon, __u8 reason)
 {
        BT_DBG("hcon %p reason %d", hcon, reason);
 
-       if (hcon->type != SCO_LINK)
+       if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
                return 0;
 
        sco_conn_del(hcon, bt_err(reason));
+
        return 0;
 }
 
index d5a09eaef9153b6858fc3cecf44a777c002902bf..817169e718c1180ee8e9c3f5fab222727f4c4846 100644 (file)
@@ -871,7 +871,7 @@ static int translate_table(char *name, struct ebt_table_info *newinfo)
                                return -EINVAL;
                        }
 
-       /* we now know the following (along with E=mc²):
+       /* we now know the following (along with E=mc²):
           - the nr of entries in each chain is right
           - the size of the allocated space is right
           - all valid hooks have a corresponding chain
index 38b03da5c1ca93d061cfe250195bbfc8898b9da6..872658927e47cc619f7f82759e1487892fc20fa0 100644 (file)
@@ -1553,7 +1553,7 @@ gso:
                        return rc;
                }
                if (unlikely((netif_queue_stopped(dev) ||
-                            netif_subqueue_stopped(dev, skb->queue_mapping)) &&
+                            netif_subqueue_stopped(dev, skb)) &&
                             skb->next))
                        return NETDEV_TX_BUSY;
        } while (skb->next);
@@ -1661,7 +1661,7 @@ gso:
                q = dev->qdisc;
                if (q->enqueue) {
                        /* reset queue_mapping to zero */
-                       skb->queue_mapping = 0;
+                       skb_set_queue_mapping(skb, 0);
                        rc = q->enqueue(skb, q);
                        qdisc_run(dev);
                        spin_unlock(&dev->queue_lock);
@@ -1692,7 +1692,7 @@ gso:
                        HARD_TX_LOCK(dev, cpu);
 
                        if (!netif_queue_stopped(dev) &&
-                           !netif_subqueue_stopped(dev, skb->queue_mapping)) {
+                           !netif_subqueue_stopped(dev, skb)) {
                                rc = 0;
                                if (!dev_hard_start_xmit(skb, dev)) {
                                        HARD_TX_UNLOCK(dev);
index bd903aaf7aa74fb871f4f4cdda14c6cd55755ee5..e0a06942c025d24d3590658e997f420129858bc1 100644 (file)
@@ -386,6 +386,25 @@ int sk_chk_filter(struct sock_filter *filter, int flen)
        return (BPF_CLASS(filter[flen - 1].code) == BPF_RET) ? 0 : -EINVAL;
 }
 
+/**
+ *     sk_filter_rcu_release: Release a socket filter by rcu_head
+ *     @rcu: rcu_head that contains the sk_filter to free
+ */
+static void sk_filter_rcu_release(struct rcu_head *rcu)
+{
+       struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu);
+
+       sk_filter_release(fp);
+}
+
+static void sk_filter_delayed_uncharge(struct sock *sk, struct sk_filter *fp)
+{
+       unsigned int size = sk_filter_len(fp);
+
+       atomic_sub(size, &sk->sk_omem_alloc);
+       call_rcu_bh(&fp->rcu, sk_filter_rcu_release);
+}
+
 /**
  *     sk_attach_filter - attach a socket filter
  *     @fprog: the filter program
@@ -398,7 +417,7 @@ int sk_chk_filter(struct sock_filter *filter, int flen)
  */
 int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
 {
-       struct sk_filter *fp;
+       struct sk_filter *fp, *old_fp;
        unsigned int fsize = sizeof(struct sock_filter) * fprog->len;
        int err;
 
@@ -418,19 +437,35 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
        fp->len = fprog->len;
 
        err = sk_chk_filter(fp->insns, fp->len);
-       if (!err) {
-               struct sk_filter *old_fp;
-
-               rcu_read_lock_bh();
-               old_fp = rcu_dereference(sk->sk_filter);
-               rcu_assign_pointer(sk->sk_filter, fp);
-               rcu_read_unlock_bh();
-               fp = old_fp;
+       if (err) {
+               sk_filter_uncharge(sk, fp);
+               return err;
        }
 
-       if (fp)
-               sk_filter_release(sk, fp);
-       return err;
+       rcu_read_lock_bh();
+       old_fp = rcu_dereference(sk->sk_filter);
+       rcu_assign_pointer(sk->sk_filter, fp);
+       rcu_read_unlock_bh();
+
+       if (old_fp)
+               sk_filter_delayed_uncharge(sk, old_fp);
+       return 0;
+}
+
+int sk_detach_filter(struct sock *sk)
+{
+       int ret = -ENOENT;
+       struct sk_filter *filter;
+
+       rcu_read_lock_bh();
+       filter = rcu_dereference(sk->sk_filter);
+       if (filter) {
+               rcu_assign_pointer(sk->sk_filter, NULL);
+               sk_filter_delayed_uncharge(sk, filter);
+               ret = 0;
+       }
+       rcu_read_unlock_bh();
+       return ret;
 }
 
 EXPORT_SYMBOL(sk_chk_filter);
index 590a767b029c15e82886bfcb49574dcfdbc7ba1e..daadbcc4e8dd7e45d92205f6ef4810a315ce3a62 100644 (file)
@@ -15,7 +15,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
index cd3af59b38a10fbdb6163c2f705930f2002698df..05979e35696320eeee0bbd5ae36d06ec50e496cc 100644 (file)
@@ -1438,6 +1438,9 @@ int neigh_table_clear(struct neigh_table *tbl)
        free_percpu(tbl->stats);
        tbl->stats = NULL;
 
+       kmem_cache_destroy(tbl->kmem_cachep);
+       tbl->kmem_cachep = NULL;
+
        return 0;
 }
 
@@ -2496,7 +2499,6 @@ static struct neigh_sysctl_table {
                        .proc_handler   = &proc_dointvec,
                },
                {
-                       .ctl_name       = NET_NEIGH_RETRANS_TIME,
                        .procname       = "retrans_time",
                        .maxlen         = sizeof(int),
                        .mode           = 0644,
@@ -2541,26 +2543,39 @@ static struct neigh_sysctl_table {
                        .proc_handler   = &proc_dointvec,
                },
                {
-                       .ctl_name       = NET_NEIGH_ANYCAST_DELAY,
                        .procname       = "anycast_delay",
                        .maxlen         = sizeof(int),
                        .mode           = 0644,
                        .proc_handler   = &proc_dointvec_userhz_jiffies,
                },
                {
-                       .ctl_name       = NET_NEIGH_PROXY_DELAY,
                        .procname       = "proxy_delay",
                        .maxlen         = sizeof(int),
                        .mode           = 0644,
                        .proc_handler   = &proc_dointvec_userhz_jiffies,
                },
                {
-                       .ctl_name       = NET_NEIGH_LOCKTIME,
                        .procname       = "locktime",
                        .maxlen         = sizeof(int),
                        .mode           = 0644,
                        .proc_handler   = &proc_dointvec_userhz_jiffies,
                },
+               {
+                       .ctl_name       = NET_NEIGH_RETRANS_TIME_MS,
+                       .procname       = "retrans_time_ms",
+                       .maxlen         = sizeof(int),
+                       .mode           = 0644,
+                       .proc_handler   = &proc_dointvec_ms_jiffies,
+                       .strategy       = &sysctl_ms_jiffies,
+               },
+               {
+                       .ctl_name       = NET_NEIGH_REACHABLE_TIME_MS,
+                       .procname       = "base_reachable_time_ms",
+                       .maxlen         = sizeof(int),
+                       .mode           = 0644,
+                       .proc_handler   = &proc_dointvec_ms_jiffies,
+                       .strategy       = &sysctl_ms_jiffies,
+               },
                {
                        .ctl_name       = NET_NEIGH_GC_INTERVAL,
                        .procname       = "gc_interval",
@@ -2590,22 +2605,7 @@ static struct neigh_sysctl_table {
                        .mode           = 0644,
                        .proc_handler   = &proc_dointvec,
                },
-               {
-                       .ctl_name       = NET_NEIGH_RETRANS_TIME_MS,
-                       .procname       = "retrans_time_ms",
-                       .maxlen         = sizeof(int),
-                       .mode           = 0644,
-                       .proc_handler   = &proc_dointvec_ms_jiffies,
-                       .strategy       = &sysctl_ms_jiffies,
-               },
-               {
-                       .ctl_name       = NET_NEIGH_REACHABLE_TIME_MS,
-                       .procname       = "base_reachable_time_ms",
-                       .maxlen         = sizeof(int),
-                       .mode           = 0644,
-                       .proc_handler   = &proc_dointvec_ms_jiffies,
-                       .strategy       = &sysctl_ms_jiffies,
-               },
+               {}
        },
        .neigh_dev = {
                {
@@ -2658,42 +2658,48 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
        t->neigh_vars[9].data  = &p->anycast_delay;
        t->neigh_vars[10].data = &p->proxy_delay;
        t->neigh_vars[11].data = &p->locktime;
+       t->neigh_vars[12].data  = &p->retrans_time;
+       t->neigh_vars[13].data  = &p->base_reachable_time;
 
        if (dev) {
                dev_name_source = dev->name;
                t->neigh_dev[0].ctl_name = dev->ifindex;
-               t->neigh_vars[12].procname = NULL;
-               t->neigh_vars[13].procname = NULL;
-               t->neigh_vars[14].procname = NULL;
-               t->neigh_vars[15].procname = NULL;
+               /* Terminate the table early */
+               memset(&t->neigh_vars[14], 0, sizeof(t->neigh_vars[14]));
        } else {
                dev_name_source = t->neigh_dev[0].procname;
-               t->neigh_vars[12].data = (int *)(p + 1);
-               t->neigh_vars[13].data = (int *)(p + 1) + 1;
-               t->neigh_vars[14].data = (int *)(p + 1) + 2;
-               t->neigh_vars[15].data = (int *)(p + 1) + 3;
+               t->neigh_vars[14].data = (int *)(p + 1);
+               t->neigh_vars[15].data = (int *)(p + 1) + 1;
+               t->neigh_vars[16].data = (int *)(p + 1) + 2;
+               t->neigh_vars[17].data = (int *)(p + 1) + 3;
        }
 
-       t->neigh_vars[16].data  = &p->retrans_time;
-       t->neigh_vars[17].data  = &p->base_reachable_time;
 
        if (handler || strategy) {
                /* RetransTime */
                t->neigh_vars[3].proc_handler = handler;
                t->neigh_vars[3].strategy = strategy;
                t->neigh_vars[3].extra1 = dev;
+               if (!strategy)
+                       t->neigh_vars[3].ctl_name = CTL_UNNUMBERED;
                /* ReachableTime */
                t->neigh_vars[4].proc_handler = handler;
                t->neigh_vars[4].strategy = strategy;
                t->neigh_vars[4].extra1 = dev;
+               if (!strategy)
+                       t->neigh_vars[4].ctl_name = CTL_UNNUMBERED;
                /* RetransTime (in milliseconds)*/
-               t->neigh_vars[16].proc_handler = handler;
-               t->neigh_vars[16].strategy = strategy;
-               t->neigh_vars[16].extra1 = dev;
+               t->neigh_vars[12].proc_handler = handler;
+               t->neigh_vars[12].strategy = strategy;
+               t->neigh_vars[12].extra1 = dev;
+               if (!strategy)
+                       t->neigh_vars[12].ctl_name = CTL_UNNUMBERED;
                /* ReachableTime (in milliseconds) */
-               t->neigh_vars[17].proc_handler = handler;
-               t->neigh_vars[17].strategy = strategy;
-               t->neigh_vars[17].extra1 = dev;
+               t->neigh_vars[13].proc_handler = handler;
+               t->neigh_vars[13].strategy = strategy;
+               t->neigh_vars[13].extra1 = dev;
+               if (!strategy)
+                       t->neigh_vars[13].ctl_name = CTL_UNNUMBERED;
        }
 
        dev_name = kstrdup(dev_name_source, GFP_KERNEL);
index 95daba6249676dc8e466303279cadc1223e57d81..bf8d18f1b0130ffd258281eb264140ecbfe2b85d 100644 (file)
@@ -67,7 +67,7 @@ static void queue_process(struct work_struct *work)
                local_irq_save(flags);
                netif_tx_lock(dev);
                if ((netif_queue_stopped(dev) ||
-                    netif_subqueue_stopped(dev, skb->queue_mapping)) ||
+                    netif_subqueue_stopped(dev, skb)) ||
                     dev->hard_start_xmit(skb, dev) != NETDEV_TX_OK) {
                        skb_queue_head(&npinfo->txq, skb);
                        netif_tx_unlock(dev);
@@ -269,7 +269,7 @@ static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
                     tries > 0; --tries) {
                        if (netif_tx_trylock(dev)) {
                                if (!netif_queue_stopped(dev) &&
-                                   !netif_subqueue_stopped(dev, skb->queue_mapping))
+                                   !netif_subqueue_stopped(dev, skb))
                                        status = dev->hard_start_xmit(skb, dev);
                                netif_tx_unlock(dev);
 
index 2100c734b102c9bde14ef3e86a362621996f37b9..de33f36947e9064294085e6f775881b98a636a8a 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Alexey Kuznetsov  <kuznet@ms2.inr.ac.ru>
  * Ben Greear <greearb@candelatech.com>
- * Jens Låås <jens.laas@data.slu.se>
+ * Jens Låås <jens.laas@data.slu.se>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
 #endif
 #include <asm/byteorder.h>
 #include <linux/rcupdate.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <asm/uaccess.h>
@@ -2454,7 +2454,7 @@ static int pktgen_output_ipsec(struct sk_buff *skb, struct pktgen_dev *pkt_dev)
        spin_lock(&x->lock);
        iph = ip_hdr(skb);
 
-       err = x->mode->output(x, skb);
+       err = x->outer_mode->output(x, skb);
        if (err)
                goto error;
        err = x->type->output(x, skb);
@@ -2603,8 +2603,7 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
        skb->network_header = skb->tail;
        skb->transport_header = skb->network_header + sizeof(struct iphdr);
        skb_put(skb, sizeof(struct iphdr) + sizeof(struct udphdr));
-       skb->queue_mapping = pkt_dev->cur_queue_map;
-
+       skb_set_queue_mapping(skb, pkt_dev->cur_queue_map);
        iph = ip_hdr(skb);
        udph = udp_hdr(skb);
 
@@ -2941,8 +2940,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
        skb->network_header = skb->tail;
        skb->transport_header = skb->network_header + sizeof(struct ipv6hdr);
        skb_put(skb, sizeof(struct ipv6hdr) + sizeof(struct udphdr));
-       skb->queue_mapping = pkt_dev->cur_queue_map;
-
+       skb_set_queue_mapping(skb, pkt_dev->cur_queue_map);
        iph = ipv6_hdr(skb);
        udph = udp_hdr(skb);
 
@@ -3385,7 +3383,7 @@ static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
 
        if ((netif_queue_stopped(odev) ||
             (pkt_dev->skb &&
-             netif_subqueue_stopped(odev, pkt_dev->skb->queue_mapping))) ||
+             netif_subqueue_stopped(odev, pkt_dev->skb))) ||
            need_resched()) {
                idle_start = getCurUs();
 
@@ -3402,7 +3400,7 @@ static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
                pkt_dev->idle_acc += getCurUs() - idle_start;
 
                if (netif_queue_stopped(odev) ||
-                   netif_subqueue_stopped(odev, pkt_dev->skb->queue_mapping)) {
+                   netif_subqueue_stopped(odev, pkt_dev->skb)) {
                        pkt_dev->next_tx_us = getCurUs();       /* TODO */
                        pkt_dev->next_tx_ns = 0;
                        goto out;       /* Try the next interface */
@@ -3431,7 +3429,7 @@ static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
 
        netif_tx_lock_bh(odev);
        if (!netif_queue_stopped(odev) &&
-           !netif_subqueue_stopped(odev, pkt_dev->skb->queue_mapping)) {
+           !netif_subqueue_stopped(odev, pkt_dev->skb)) {
 
                atomic_inc(&(pkt_dev->skb->users));
              retry_now:
@@ -3514,7 +3512,7 @@ static int pktgen_thread_worker(void *arg)
 
        init_waitqueue_head(&t->queue);
 
-       pr_debug("pktgen: starting pktgen/%d:  pid=%d\n", cpu, current->pid);
+       pr_debug("pktgen: starting pktgen/%d:  pid=%d\n", cpu, task_pid_nr(current));
 
        set_current_state(TASK_INTERRUPTIBLE);
 
index 1072d16696c3b651993ef7130bd09a475c072b81..4a2640d3826166d98b066d626f9427e5daacc256 100644 (file)
@@ -744,10 +744,10 @@ static struct net *get_net_ns_by_pid(pid_t pid)
        rcu_read_lock();
        tsk = find_task_by_pid(pid);
        if (tsk) {
-               task_lock(tsk);
-               if (tsk->nsproxy)
-                       net = get_net(tsk->nsproxy->net_ns);
-               task_unlock(tsk);
+               struct nsproxy *nsproxy;
+               nsproxy = task_nsproxy(tsk);
+               if (nsproxy)
+                       net = get_net(nsproxy->net_ns);
        }
        rcu_read_unlock();
        return net;
index 530bee8d9ed90448ee2b406b897ada19ec11d28c..100ba6d9d478d7df1082a3790ddfac0e6c012d73 100644 (file)
@@ -24,6 +24,8 @@
 #include <linux/interrupt.h>
 #include <linux/netdevice.h>
 #include <linux/security.h>
+#include <linux/pid.h>
+#include <linux/nsproxy.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -42,7 +44,7 @@
 
 static __inline__ int scm_check_creds(struct ucred *creds)
 {
-       if ((creds->pid == current->tgid || capable(CAP_SYS_ADMIN)) &&
+       if ((creds->pid == task_tgid_vnr(current) || capable(CAP_SYS_ADMIN)) &&
            ((creds->uid == current->uid || creds->uid == current->euid ||
              creds->uid == current->suid) || capable(CAP_SETUID)) &&
            ((creds->gid == current->gid || creds->gid == current->egid ||
index 70d9b5da96aecca05bfd8461d30252f4f8e779df..4e2c84fcf2766fd542fb401b4e5847cd54603ce1 100644 (file)
@@ -2045,7 +2045,7 @@ skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
        if (copy > 0) {
                if (copy > len)
                        copy = len;
-               sg[elt].page = virt_to_page(skb->data + offset);
+               sg_set_page(&sg[elt], virt_to_page(skb->data + offset));
                sg[elt].offset = (unsigned long)(skb->data + offset) % PAGE_SIZE;
                sg[elt].length = copy;
                elt++;
@@ -2065,7 +2065,7 @@ skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
 
                        if (copy > len)
                                copy = len;
-                       sg[elt].page = frag->page;
+                       sg_set_page(&sg[elt], frag->page);
                        sg[elt].offset = frag->page_offset+offset-start;
                        sg[elt].length = copy;
                        elt++;
index d45ecdccc6a153ec1ffccb1430e6085a3dd42f7d..febbcbcf8022ac82f25d66de5dcd54177aeca250 100644 (file)
@@ -232,7 +232,7 @@ static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen)
                        warned++;
                        printk(KERN_INFO "sock_set_timeout: `%s' (pid %d) "
                               "tries to set negative timeout\n",
-                               current->comm, current->pid);
+                               current->comm, task_pid_nr(current));
                return 0;
        }
        *timeo_p = MAX_SCHEDULE_TIMEOUT;
@@ -428,7 +428,6 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
                    char __user *optval, int optlen)
 {
        struct sock *sk=sock->sk;
-       struct sk_filter *filter;
        int val;
        int valbool;
        struct linger ling;
@@ -652,16 +651,7 @@ set_rcvbuf:
                break;
 
        case SO_DETACH_FILTER:
-               rcu_read_lock_bh();
-               filter = rcu_dereference(sk->sk_filter);
-               if (filter) {
-                       rcu_assign_pointer(sk->sk_filter, NULL);
-                       sk_filter_release(sk, filter);
-                       rcu_read_unlock_bh();
-                       break;
-               }
-               rcu_read_unlock_bh();
-               ret = -ENONET;
+               ret = sk_detach_filter(sk);
                break;
 
        case SO_PASSSEC:
@@ -925,7 +915,7 @@ void sk_free(struct sock *sk)
 
        filter = rcu_dereference(sk->sk_filter);
        if (filter) {
-               sk_filter_release(sk, filter);
+               sk_filter_uncharge(sk, filter);
                rcu_assign_pointer(sk->sk_filter, NULL);
        }
 
index 0f3745585a9486e4e1aee74df934936949b5c040..d8a3509b26f68812c194f852eb5a0e017f0920e2 100644 (file)
@@ -68,3 +68,4 @@ module_exit(dccp_diag_fini);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Arnaldo Carvalho de Melo <acme@mandriva.com>");
 MODULE_DESCRIPTION("DCCP inet_diag handler");
+MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_NETLINK, NETLINK_INET_DIAG, DCCPDIAG_GETSOCK);
index 19d7e1dbd87e99a98f463e944a6f20f052fd9856..3560a2a875a05561f2d0b353cb62b6b58095e8b4 100644 (file)
@@ -19,6 +19,9 @@
 #include "ccid.h"
 #include "dccp.h"
 
+/* rate-limit for syncs in reply to sequence-invalid packets; RFC 4340, 7.5.4 */
+int sysctl_dccp_sync_ratelimit __read_mostly = HZ / 8;
+
 static void dccp_fin(struct sock *sk, struct sk_buff *skb)
 {
        sk->sk_shutdown |= RCV_SHUTDOWN;
index 44f6e17e105f3bc917bad9ffd6cf83fb3d6eb7ce..222549ab274ae5ed51c885f48569e9fa4eaed9e7 100644 (file)
@@ -1037,8 +1037,8 @@ module_exit(dccp_v4_exit);
  * values directly, Also cover the case where the protocol is not specified,
  * i.e. net-pf-PF_INET-proto-0-type-SOCK_DCCP
  */
-MODULE_ALIAS("net-pf-" __stringify(PF_INET) "-proto-33-type-6");
-MODULE_ALIAS("net-pf-" __stringify(PF_INET) "-proto-0-type-6");
+MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 33, 6);
+MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 0, 6);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Arnaldo Carvalho de Melo <acme@mandriva.com>");
 MODULE_DESCRIPTION("DCCP - Datagram Congestion Controlled Protocol");
index cac53548c2d89d90e69aebf05b0f4ba3a52d28f5..bbadd6681b83a3f1706a87034d25fcb68a7e2c52 100644 (file)
@@ -1219,8 +1219,8 @@ module_exit(dccp_v6_exit);
  * values directly, Also cover the case where the protocol is not specified,
  * i.e. net-pf-PF_INET6-proto-0-type-SOCK_DCCP
  */
-MODULE_ALIAS("net-pf-" __stringify(PF_INET6) "-proto-33-type-6");
-MODULE_ALIAS("net-pf-" __stringify(PF_INET6) "-proto-0-type-6");
+MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET6, 33, 6);
+MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET6, 0, 6);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Arnaldo Carvalho de Melo <acme@mandriva.com>");
 MODULE_DESCRIPTION("DCCPv6 - Datagram Congestion Controlled Protocol");
index 9364b2fb4dbd4ce0e45581e7595c7e2d2a32e6dd..c62c05039f693e40bbd2b4cad307fa68d619629f 100644 (file)
@@ -18,9 +18,6 @@
 #error This file should not be compiled without CONFIG_SYSCTL defined
 #endif
 
-/* rate-limit for syncs in reply to sequence-invalid packets; RFC 4340, 7.5.4 */
-int sysctl_dccp_sync_ratelimit __read_mostly = HZ / 8;
-
 static struct ctl_table dccp_default_table[] = {
        {
                .procname       = "seq_window",
index 6cc54eeca3edf54b11f76f6d23ca7b43d2adeec5..811777682e2b94ea876edab53ac5005d0ee63969 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/random.h>
+#include <linux/scatterlist.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
 #include <linux/mm.h>
@@ -390,9 +391,7 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
        icv[3] = crc >> 24;
 
        crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
-       sg.page = virt_to_page(pos);
-       sg.offset = offset_in_page(pos);
-       sg.length = len + 4;
+       sg_init_one(&sg, pos, len + 4);
        return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
 }
 
@@ -485,9 +484,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
        plen = skb->len - hdr_len - 12;
 
        crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
-       sg.page = virt_to_page(pos);
-       sg.offset = offset_in_page(pos);
-       sg.length = plen + 4;
+       sg_init_one(&sg, pos, plen + 4);
        if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
                if (net_ratelimit()) {
                        printk(KERN_DEBUG ": TKIP: failed to decrypt "
@@ -539,11 +536,12 @@ static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
                printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
                return -1;
        }
-       sg[0].page = virt_to_page(hdr);
+       sg_init_table(sg, 2);
+       sg_set_page(&sg[0], virt_to_page(hdr));
        sg[0].offset = offset_in_page(hdr);
        sg[0].length = 16;
 
-       sg[1].page = virt_to_page(data);
+       sg_set_page(&sg[1], virt_to_page(data));
        sg[1].offset = offset_in_page(data);
        sg[1].length = data_len;
 
@@ -586,7 +584,7 @@ static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
        if (stype & IEEE80211_STYPE_QOS_DATA) {
                const struct ieee80211_hdr_3addrqos *qoshdr =
                        (struct ieee80211_hdr_3addrqos *)skb->data;
-               hdr[12] = qoshdr->qos_ctl & cpu_to_le16(IEEE80211_QCTL_TID);
+               hdr[12] = le16_to_cpu(qoshdr->qos_ctl) & IEEE80211_QCTL_TID;
        } else
                hdr[12] = 0;            /* priority */
 
index 8d182459344e9a94d7f992c97da3fae33e8a2e25..9693429489ed700f83d2cdc2fcae1ea043658f47 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/random.h>
+#include <linux/scatterlist.h>
 #include <linux/skbuff.h>
 #include <linux/mm.h>
 #include <asm/string.h>
@@ -170,9 +171,7 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
        icv[3] = crc >> 24;
 
        crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
-       sg.page = virt_to_page(pos);
-       sg.offset = offset_in_page(pos);
-       sg.length = len + 4;
+       sg_init_one(&sg, pos, len + 4);
        return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
 }
 
@@ -212,9 +211,7 @@ static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
        plen = skb->len - hdr_len - 8;
 
        crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
-       sg.page = virt_to_page(pos);
-       sg.offset = offset_in_page(pos);
-       sg.length = plen + 4;
+       sg_init_one(&sg, pos, plen + 4);
        if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
                return -7;
 
index 9b58dd67acb6c34f0a43970e929a34cc24282d93..d309e8f199929618b1fb0a2ee02fc9aed362b881 100644 (file)
@@ -409,7 +409,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
                                               (*crypt)->priv);
                sec.flags |= (1 << key);
                /* This ensures a key will be activated if no key is
-                * explicitely set */
+                * explicitly set */
                if (key == sec.active_key)
                        sec.flags |= SEC_ACTIVE_KEY;
 
index d894f616c3d63ce732073d90f185441f3411da75..9f9fd2c6f6e27f2dabc5ced271040ca774a8a153 100644 (file)
@@ -560,7 +560,7 @@ config TCP_CONG_ILLINOIS
        depends on EXPERIMENTAL
        default n
        ---help---
-       TCP-Illinois is a sender-side modificatio of TCP Reno for
+       TCP-Illinois is a sender-side modification of TCP Reno for
        high speed long delay links. It uses round-trip-time to
        adjust the alpha and beta parameters to achieve a higher average
        throughput and maintain fairness.
index 81a8285d6d6a4251c7cd166635f7058046078bf6..8d8c2915e064f98d16d1409c2524f2277107185b 100644 (file)
@@ -54,7 +54,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
index 3cef12835c4b2bfa86b50a74a788488cd5ac9ea1..8fb6ca23700aa8de4c446879b19186e626dfa396 100644 (file)
@@ -93,7 +93,7 @@ int inet_csk_get_port(struct inet_hashinfo *hashinfo,
                int remaining, rover, low, high;
 
                inet_get_local_port_range(&low, &high);
-               remaining = high - low;
+               remaining = (high - low) + 1;
                rover = net_random() % remaining + low;
 
                do {
index 7eb83ebed2ec5754af310cb17db9a8108bcb0578..dc429b6b0ba62bbca65f545f6a9a8630e02eaafa 100644 (file)
@@ -815,6 +815,12 @@ static int inet_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
            nlmsg_len(nlh) < hdrlen)
                return -EINVAL;
 
+#ifdef CONFIG_KMOD
+       if (inet_diag_table[nlh->nlmsg_type] == NULL)
+               request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK,
+                              NETLINK_INET_DIAG, nlh->nlmsg_type);
+#endif
+
        if (inet_diag_table[nlh->nlmsg_type] == NULL)
                return -ENOENT;
 
@@ -914,3 +920,4 @@ static void __exit inet_diag_exit(void)
 module_init(inet_diag_init);
 module_exit(inet_diag_exit);
 MODULE_LICENSE("GPL");
+MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_INET_DIAG);
index 484cf512858fea297b81a2b1f8bf16e0ffa27913..e15e04fc66615dc354241214fdadaa366512264f 100644 (file)
@@ -136,7 +136,9 @@ void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f,
                *work -= f->qsize;
        atomic_sub(f->qsize, &f->mem);
 
-       f->destructor(q);
+       if (f->destructor)
+               f->destructor(q);
+       kfree(q);
 
 }
 EXPORT_SYMBOL(inet_frag_destroy);
@@ -172,3 +174,88 @@ int inet_frag_evictor(struct inet_frags *f)
        return evicted;
 }
 EXPORT_SYMBOL(inet_frag_evictor);
+
+static struct inet_frag_queue *inet_frag_intern(struct inet_frag_queue *qp_in,
+               struct inet_frags *f, unsigned int hash, void *arg)
+{
+       struct inet_frag_queue *qp;
+#ifdef CONFIG_SMP
+       struct hlist_node *n;
+#endif
+
+       write_lock(&f->lock);
+#ifdef CONFIG_SMP
+       /* With SMP race we have to recheck hash table, because
+        * such entry could be created on other cpu, while we
+        * promoted read lock to write lock.
+        */
+       hlist_for_each_entry(qp, n, &f->hash[hash], list) {
+               if (f->match(qp, arg)) {
+                       atomic_inc(&qp->refcnt);
+                       write_unlock(&f->lock);
+                       qp_in->last_in |= COMPLETE;
+                       inet_frag_put(qp_in, f);
+                       return qp;
+               }
+       }
+#endif
+       qp = qp_in;
+       if (!mod_timer(&qp->timer, jiffies + f->ctl->timeout))
+               atomic_inc(&qp->refcnt);
+
+       atomic_inc(&qp->refcnt);
+       hlist_add_head(&qp->list, &f->hash[hash]);
+       list_add_tail(&qp->lru_list, &f->lru_list);
+       f->nqueues++;
+       write_unlock(&f->lock);
+       return qp;
+}
+
+static struct inet_frag_queue *inet_frag_alloc(struct inet_frags *f, void *arg)
+{
+       struct inet_frag_queue *q;
+
+       q = kzalloc(f->qsize, GFP_ATOMIC);
+       if (q == NULL)
+               return NULL;
+
+       f->constructor(q, arg);
+       atomic_add(f->qsize, &f->mem);
+       setup_timer(&q->timer, f->frag_expire, (unsigned long)q);
+       spin_lock_init(&q->lock);
+       atomic_set(&q->refcnt, 1);
+
+       return q;
+}
+
+static struct inet_frag_queue *inet_frag_create(struct inet_frags *f,
+               void *arg, unsigned int hash)
+{
+       struct inet_frag_queue *q;
+
+       q = inet_frag_alloc(f, arg);
+       if (q == NULL)
+               return NULL;
+
+       return inet_frag_intern(q, f, hash, arg);
+}
+
+struct inet_frag_queue *inet_frag_find(struct inet_frags *f, void *key,
+               unsigned int hash)
+{
+       struct inet_frag_queue *q;
+       struct hlist_node *n;
+
+       read_lock(&f->lock);
+       hlist_for_each_entry(q, n, &f->hash[hash], list) {
+               if (f->match(q, key)) {
+                       atomic_inc(&q->refcnt);
+                       read_unlock(&f->lock);
+                       return q;
+               }
+       }
+       read_unlock(&f->lock);
+
+       return inet_frag_create(f, key, hash);
+}
+EXPORT_SYMBOL(inet_frag_find);
index fac6398e436709c714b95992c9045e740454d004..16eecc7046a346d6a2a22e1c33f71055a333f4c2 100644 (file)
@@ -286,7 +286,7 @@ int inet_hash_connect(struct inet_timewait_death_row *death_row,
                struct inet_timewait_sock *tw = NULL;
 
                inet_get_local_port_range(&low, &high);
-               remaining = high - low;
+               remaining = (high - low) + 1;
 
                local_bh_disable();
                for (i = 1; i <= remaining; i++) {
index 443b3f89192f5841f78e7783874f9c8b9b479020..2143bf30597a84b528e0cced57bc657dbe577417 100644 (file)
@@ -108,6 +108,11 @@ int ip_frag_mem(void)
 static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
                         struct net_device *dev);
 
+struct ip4_create_arg {
+       struct iphdr *iph;
+       u32 user;
+};
+
 static unsigned int ipqhashfn(__be16 id, __be32 saddr, __be32 daddr, u8 prot)
 {
        return jhash_3words((__force u32)id << 16 | prot,
@@ -123,6 +128,19 @@ static unsigned int ip4_hashfn(struct inet_frag_queue *q)
        return ipqhashfn(ipq->id, ipq->saddr, ipq->daddr, ipq->protocol);
 }
 
+static int ip4_frag_match(struct inet_frag_queue *q, void *a)
+{
+       struct ipq *qp;
+       struct ip4_create_arg *arg = a;
+
+       qp = container_of(q, struct ipq, q);
+       return (qp->id == arg->iph->id &&
+                       qp->saddr == arg->iph->saddr &&
+                       qp->daddr == arg->iph->daddr &&
+                       qp->protocol == arg->iph->protocol &&
+                       qp->user == arg->user);
+}
+
 /* Memory Tracking Functions. */
 static __inline__ void frag_kfree_skb(struct sk_buff *skb, int *work)
 {
@@ -132,6 +150,20 @@ static __inline__ void frag_kfree_skb(struct sk_buff *skb, int *work)
        kfree_skb(skb);
 }
 
+static void ip4_frag_init(struct inet_frag_queue *q, void *a)
+{
+       struct ipq *qp = container_of(q, struct ipq, q);
+       struct ip4_create_arg *arg = a;
+
+       qp->protocol = arg->iph->protocol;
+       qp->id = arg->iph->id;
+       qp->saddr = arg->iph->saddr;
+       qp->daddr = arg->iph->daddr;
+       qp->user = arg->user;
+       qp->peer = sysctl_ipfrag_max_dist ?
+               inet_getpeer(arg->iph->saddr, 1) : NULL;
+}
+
 static __inline__ void ip4_frag_free(struct inet_frag_queue *q)
 {
        struct ipq *qp;
@@ -139,17 +171,6 @@ static __inline__ void ip4_frag_free(struct inet_frag_queue *q)
        qp = container_of(q, struct ipq, q);
        if (qp->peer)
                inet_putpeer(qp->peer);
-       kfree(qp);
-}
-
-static __inline__ struct ipq *frag_alloc_queue(void)
-{
-       struct ipq *qp = kzalloc(sizeof(struct ipq), GFP_ATOMIC);
-
-       if (!qp)
-               return NULL;
-       atomic_add(sizeof(struct ipq), &ip4_frags.mem);
-       return qp;
 }
 
 
@@ -185,7 +206,9 @@ static void ip_evictor(void)
  */
 static void ip_expire(unsigned long arg)
 {
-       struct ipq *qp = (struct ipq *) arg;
+       struct ipq *qp;
+
+       qp = container_of((struct inet_frag_queue *) arg, struct ipq, q);
 
        spin_lock(&qp->q.lock);
 
@@ -210,112 +233,30 @@ out:
        ipq_put(qp);
 }
 
-/* Creation primitives. */
-
-static struct ipq *ip_frag_intern(struct ipq *qp_in)
+/* Find the correct entry in the "incomplete datagrams" queue for
+ * this IP datagram, and create new one, if nothing is found.
+ */
+static inline struct ipq *ip_find(struct iphdr *iph, u32 user)
 {
-       struct ipq *qp;
-#ifdef CONFIG_SMP
-       struct hlist_node *n;
-#endif
+       struct inet_frag_queue *q;
+       struct ip4_create_arg arg;
        unsigned int hash;
 
-       write_lock(&ip4_frags.lock);
-       hash = ipqhashfn(qp_in->id, qp_in->saddr, qp_in->daddr,
-                        qp_in->protocol);
-#ifdef CONFIG_SMP
-       /* With SMP race we have to recheck hash table, because
-        * such entry could be created on other cpu, while we
-        * promoted read lock to write lock.
-        */
-       hlist_for_each_entry(qp, n, &ip4_frags.hash[hash], q.list) {
-               if (qp->id == qp_in->id         &&
-                   qp->saddr == qp_in->saddr   &&
-                   qp->daddr == qp_in->daddr   &&
-                   qp->protocol == qp_in->protocol &&
-                   qp->user == qp_in->user) {
-                       atomic_inc(&qp->q.refcnt);
-                       write_unlock(&ip4_frags.lock);
-                       qp_in->q.last_in |= COMPLETE;
-                       ipq_put(qp_in);
-                       return qp;
-               }
-       }
-#endif
-       qp = qp_in;
-
-       if (!mod_timer(&qp->q.timer, jiffies + ip4_frags_ctl.timeout))
-               atomic_inc(&qp->q.refcnt);
+       arg.iph = iph;
+       arg.user = user;
+       hash = ipqhashfn(iph->id, iph->saddr, iph->daddr, iph->protocol);
 
-       atomic_inc(&qp->q.refcnt);
-       hlist_add_head(&qp->q.list, &ip4_frags.hash[hash]);
-       INIT_LIST_HEAD(&qp->q.lru_list);
-       list_add_tail(&qp->q.lru_list, &ip4_frags.lru_list);
-       ip4_frags.nqueues++;
-       write_unlock(&ip4_frags.lock);
-       return qp;
-}
-
-/* Add an entry to the 'ipq' queue for a newly received IP datagram. */
-static struct ipq *ip_frag_create(struct iphdr *iph, u32 user)
-{
-       struct ipq *qp;
-
-       if ((qp = frag_alloc_queue()) == NULL)
+       q = inet_frag_find(&ip4_frags, &arg, hash);
+       if (q == NULL)
                goto out_nomem;
 
-       qp->protocol = iph->protocol;
-       qp->id = iph->id;
-       qp->saddr = iph->saddr;
-       qp->daddr = iph->daddr;
-       qp->user = user;
-       qp->peer = sysctl_ipfrag_max_dist ? inet_getpeer(iph->saddr, 1) : NULL;
-
-       /* Initialize a timer for this entry. */
-       init_timer(&qp->q.timer);
-       qp->q.timer.data = (unsigned long) qp;  /* pointer to queue     */
-       qp->q.timer.function = ip_expire;               /* expire function      */
-       spin_lock_init(&qp->q.lock);
-       atomic_set(&qp->q.refcnt, 1);
-
-       return ip_frag_intern(qp);
+       return container_of(q, struct ipq, q);
 
 out_nomem:
        LIMIT_NETDEBUG(KERN_ERR "ip_frag_create: no memory left !\n");
        return NULL;
 }
 
-/* Find the correct entry in the "incomplete datagrams" queue for
- * this IP datagram, and create new one, if nothing is found.
- */
-static inline struct ipq *ip_find(struct iphdr *iph, u32 user)
-{
-       __be16 id = iph->id;
-       __be32 saddr = iph->saddr;
-       __be32 daddr = iph->daddr;
-       __u8 protocol = iph->protocol;
-       unsigned int hash;
-       struct ipq *qp;
-       struct hlist_node *n;
-
-       read_lock(&ip4_frags.lock);
-       hash = ipqhashfn(id, saddr, daddr, protocol);
-       hlist_for_each_entry(qp, n, &ip4_frags.hash[hash], q.list) {
-               if (qp->id == id                &&
-                   qp->saddr == saddr  &&
-                   qp->daddr == daddr  &&
-                   qp->protocol == protocol &&
-                   qp->user == user) {
-                       atomic_inc(&qp->q.refcnt);
-                       read_unlock(&ip4_frags.lock);
-                       return qp;
-               }
-       }
-       read_unlock(&ip4_frags.lock);
-
-       return ip_frag_create(iph, user);
-}
-
 /* Is the fragment too far ahead to be part of ipq? */
 static inline int ip_frag_too_far(struct ipq *qp)
 {
@@ -545,7 +486,6 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
        if (prev) {
                head = prev->next;
                fp = skb_clone(head, GFP_ATOMIC);
-
                if (!fp)
                        goto out_nomem;
 
@@ -571,7 +511,6 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
                goto out_oversize;
 
        /* Head of list must not be cloned. */
-       err = -ENOMEM;
        if (skb_cloned(head) && pskb_expand_head(head, 0, 0, GFP_ATOMIC))
                goto out_nomem;
 
@@ -627,6 +566,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
 out_nomem:
        LIMIT_NETDEBUG(KERN_ERR "IP: queue_glue: no memory for gluing "
                              "queue %p\n", qp);
+       err = -ENOMEM;
        goto out_fail;
 out_oversize:
        if (net_ratelimit())
@@ -671,9 +611,12 @@ void __init ipfrag_init(void)
 {
        ip4_frags.ctl = &ip4_frags_ctl;
        ip4_frags.hashfn = ip4_hashfn;
+       ip4_frags.constructor = ip4_frag_init;
        ip4_frags.destructor = ip4_frag_free;
        ip4_frags.skb_free = NULL;
        ip4_frags.qsize = sizeof(struct ipq);
+       ip4_frags.match = ip4_frag_match;
+       ip4_frags.frag_expire = ip_expire;
        inet_frags_init(&ip4_frags);
 }
 
index 1960747f354c8c89966b920426d7487640476617..c99f2a33fb9e9165a3f2b7144ea609b6b151e34b 100644 (file)
@@ -794,7 +794,7 @@ static int sync_thread(void *startup)
 
        add_wait_queue(&sync_wait, &wait);
 
-       set_sync_pid(state, current->pid);
+       set_sync_pid(state, task_pid_nr(current));
        complete(tinfo->startup);
 
        /*
@@ -877,7 +877,7 @@ int start_sync_thread(int state, char *mcast_ifn, __u8 syncid)
        if (!tinfo)
                return -ENOMEM;
 
-       IP_VS_DBG(7, "%s: pid %d\n", __FUNCTION__, current->pid);
+       IP_VS_DBG(7, "%s: pid %d\n", __FUNCTION__, task_pid_nr(current));
        IP_VS_DBG(7, "Each ip_vs_sync_conn entry need %Zd bytes\n",
                  sizeof(struct ip_vs_sync_conn));
 
@@ -917,7 +917,7 @@ int stop_sync_thread(int state)
            (state == IP_VS_STATE_BACKUP && !sync_backup_pid))
                return -ESRCH;
 
-       IP_VS_DBG(7, "%s: pid %d\n", __FUNCTION__, current->pid);
+       IP_VS_DBG(7, "%s: pid %d\n", __FUNCTION__, task_pid_nr(current));
        IP_VS_INFO("stopping sync thread %d ...\n",
                   (state == IP_VS_STATE_MASTER) ?
                   sync_master_pid : sync_backup_pid);
index 11fedc73049c109d17fa741ba8ad6222bfd4b61b..adcbaf6d4299c8be3c94ccd815f23bc736a6cbf3 100644 (file)
@@ -281,7 +281,6 @@ static int icmp_nlattr_to_tuple(struct nlattr *tb[],
 static struct ctl_table_header *icmp_sysctl_header;
 static struct ctl_table icmp_sysctl_table[] = {
        {
-               .ctl_name       = NET_NF_CONNTRACK_ICMP_TIMEOUT,
                .procname       = "nf_conntrack_icmp_timeout",
                .data           = &nf_ct_icmp_timeout,
                .maxlen         = sizeof(unsigned int),
@@ -295,7 +294,6 @@ static struct ctl_table icmp_sysctl_table[] = {
 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
 static struct ctl_table icmp_compat_sysctl_table[] = {
        {
-               .ctl_name       = NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT,
                .procname       = "ip_conntrack_icmp_timeout",
                .data           = &nf_ct_icmp_timeout,
                .maxlen         = sizeof(unsigned int),
index c98ef16effd24171bf24dc580c6c633bab716ac7..ffddd2b453523c137dae115fde91aa1e91d5471a 100644 (file)
@@ -122,7 +122,7 @@ static int ipv4_local_port_range(ctl_table *table, int write, struct file *filp,
        ret = proc_dointvec_minmax(&tmp, write, filp, buffer, lenp, ppos);
 
        if (write && ret == 0) {
-               if (range[1] <= range[0])
+               if (range[1] < range[0])
                        ret = -EINVAL;
                else
                        set_local_port_range(range);
@@ -150,7 +150,7 @@ static int ipv4_sysctl_local_port_range(ctl_table *table, int __user *name,
 
        ret = sysctl_intvec(&tmp, name, nlen, oldval, oldlenp, newval, newlen);
        if (ret == 0 && newval && newlen) {
-               if (range[1] <= range[0])
+               if (range[1] < range[0])
                        ret = -EINVAL;
                else
                        set_local_port_range(range);
@@ -740,7 +740,6 @@ ctl_table ipv4_table[] = {
                .strategy       = &sysctl_jiffies
        },
        {
-               .ctl_name       = NET_IPV4_IPFRAG_MAX_DIST,
                .procname       = "ipfrag_max_dist",
                .data           = &sysctl_ipfrag_max_dist,
                .maxlen         = sizeof(int),
@@ -865,7 +864,6 @@ ctl_table ipv4_table[] = {
        },
 #endif /* CONFIG_NETLABEL */
        {
-               .ctl_name       = NET_TCP_AVAIL_CONG_CONTROL,
                .procname       = "tcp_available_congestion_control",
                .maxlen         = TCP_CA_BUF_MAX,
                .mode           = 0444,
index 4f322003835dc1886b4202259a91bd641d9139c3..2e6ad6dbba6c54d904d1df28d6e38dfcd7640b00 100644 (file)
@@ -1334,7 +1334,7 @@ do_prequeue:
                if ((flags & MSG_PEEK) && peek_seq != tp->copied_seq) {
                        if (net_ratelimit())
                                printk(KERN_DEBUG "TCP(%s:%d): Application bug, race in MSG_PEEK.\n",
-                                      current->comm, current->pid);
+                                      current->comm, task_pid_nr(current));
                        peek_seq = tp->copied_seq;
                }
                continue;
index 3904d2158a92c016de79ebf6a7da4b18ad867b8d..2fbcc7d1b1a057dcba3326e88468455d9a1b778f 100644 (file)
@@ -56,3 +56,4 @@ static void __exit tcp_diag_exit(void)
 module_init(tcp_diag_init);
 module_exit(tcp_diag_exit);
 MODULE_LICENSE("GPL");
+MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_NETLINK, NETLINK_INET_DIAG, TCPDIAG_GETSOCK);
index 0f00966b1784b0f1f448053554a4719cbbe1c496..9288220b73a8d80abf9a7fff748269930d8f8a8a 100644 (file)
@@ -1121,7 +1121,7 @@ static int tcp_mark_lost_retrans(struct sock *sk, u32 received_upto)
        struct sk_buff *skb;
        int flag = 0;
        int cnt = 0;
-       u32 new_low_seq = 0;
+       u32 new_low_seq = tp->snd_nxt;
 
        tcp_for_write_queue(skb, sk) {
                u32 ack_seq = TCP_SKB_CB(skb)->ack_seq;
@@ -1153,7 +1153,7 @@ static int tcp_mark_lost_retrans(struct sock *sk, u32 received_upto)
                                NET_INC_STATS_BH(LINUX_MIB_TCPLOSTRETRANSMIT);
                        }
                } else {
-                       if (!new_low_seq || before(ack_seq, new_low_seq))
+                       if (before(ack_seq, new_low_seq))
                                new_low_seq = ack_seq;
                        cnt += tcp_skb_pcount(skb);
                }
@@ -1242,7 +1242,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
        int num_sacks = (ptr[1] - TCPOLEN_SACK_BASE)>>3;
        int reord = tp->packets_out;
        int prior_fackets;
-       u32 highest_sack_end_seq = 0;
+       u32 highest_sack_end_seq = tp->lost_retrans_low;
        int flag = 0;
        int found_dup_sack = 0;
        int cached_fack_count;
index cb9fc58efb2f1da00ad4789370be1d1ac07f1fcd..35d2b0e9e10bec0a1ac90c385dde9cbcf7c5f6ff 100644 (file)
@@ -147,13 +147,14 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum,
        write_lock_bh(&udp_hash_lock);
 
        if (!snum) {
-               int i, low, high;
+               int i, low, high, remaining;
                unsigned rover, best, best_size_so_far;
 
                inet_get_local_port_range(&low, &high);
+               remaining = (high - low) + 1;
 
                best_size_so_far = UINT_MAX;
-               best = rover = net_random() % (high - low) + low;
+               best = rover = net_random() % remaining + low;
 
                /* 1st pass: look for empty (or shortest) hash chain */
                for (i = 0; i < UDP_HTABLE_SIZE; i++) {
index e9bbfde19ac32420a6dfd77b090e8b22fd97edc6..5e95c8a07efbad59809f5370c62b317b58e1fe9c 100644 (file)
 #include <net/ip.h>
 #include <net/xfrm.h>
 
-static int xfrm4_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
-{
-       switch (nexthdr) {
-       case IPPROTO_IPIP:
-       case IPPROTO_IPV6:
-               *spi = ip_hdr(skb)->saddr;
-               *seq = 0;
-               return 0;
-       }
-
-       return xfrm_parse_spi(skb, nexthdr, spi, seq);
-}
-
 #ifdef CONFIG_NETFILTER
 static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb)
 {
@@ -46,28 +33,29 @@ drop:
 }
 #endif
 
-static int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
+int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
+                   int encap_type)
 {
-       __be32 spi, seq;
+       int err;
+       __be32 seq;
        struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
        struct xfrm_state *x;
        int xfrm_nr = 0;
        int decaps = 0;
-       int err = xfrm4_parse_spi(skb, ip_hdr(skb)->protocol, &spi, &seq);
        unsigned int nhoff = offsetof(struct iphdr, protocol);
 
-       if (err != 0)
+       seq = 0;
+       if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0)
                goto drop;
 
        do {
                const struct iphdr *iph = ip_hdr(skb);
-               int nexthdr;
 
                if (xfrm_nr == XFRM_MAX_DEPTH)
                        goto drop;
 
                x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi,
-                               iph->protocol != IPPROTO_IPV6 ? iph->protocol : IPPROTO_IPIP, AF_INET);
+                                     nexthdr, AF_INET);
                if (x == NULL)
                        goto drop;
 
@@ -103,15 +91,15 @@ static int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
 
                xfrm_vec[xfrm_nr++] = x;
 
-               if (x->mode->input(x, skb))
+               if (x->outer_mode->input(x, skb))
                        goto drop;
 
-               if (x->props.mode == XFRM_MODE_TUNNEL) {
+               if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
                        decaps = 1;
                        break;
                }
 
-               err = xfrm_parse_spi(skb, ip_hdr(skb)->protocol, &spi, &seq);
+               err = xfrm_parse_spi(skb, nexthdr, &spi, &seq);
                if (err < 0)
                        goto drop;
        } while (!err);
@@ -165,6 +153,7 @@ drop:
        kfree_skb(skb);
        return 0;
 }
+EXPORT_SYMBOL(xfrm4_rcv_encap);
 
 /* If it's a keepalive packet, then just eat it.
  * If it's an encapsulated packet, then pass it to the
@@ -252,11 +241,8 @@ int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
        __skb_pull(skb, len);
        skb_reset_transport_header(skb);
 
-       /* modify the protocol (it's ESP!) */
-       iph->protocol = IPPROTO_ESP;
-
        /* process ESP */
-       ret = xfrm4_rcv_encap(skb, encap_type);
+       ret = xfrm4_rcv_encap(skb, IPPROTO_ESP, 0, encap_type);
        return ret;
 
 drop:
@@ -266,7 +252,7 @@ drop:
 
 int xfrm4_rcv(struct sk_buff *skb)
 {
-       return xfrm4_rcv_encap(skb, 0);
+       return xfrm4_rcv_spi(skb, ip_hdr(skb)->protocol, 0);
 }
 
 EXPORT_SYMBOL(xfrm4_rcv);
index 73d2338bec55f306985f82897b644b1f6f70df1a..e42e122414be1e461c01898aff091f405b48dfa2 100644 (file)
@@ -114,6 +114,7 @@ static struct xfrm_mode xfrm4_beet_mode = {
        .output = xfrm4_beet_output,
        .owner = THIS_MODULE,
        .encap = XFRM_MODE_BEET,
+       .flags = XFRM_MODE_FLAG_TUNNEL,
 };
 
 static int __init xfrm4_beet_init(void)
index 1ae9d32276f0a8daa13cf8abbf743b34c691f0f8..e4deecba6dd216d546706f57e3e557123af52c71 100644 (file)
@@ -139,6 +139,7 @@ static struct xfrm_mode xfrm4_tunnel_mode = {
        .output = xfrm4_tunnel_output,
        .owner = THIS_MODULE,
        .encap = XFRM_MODE_TUNNEL,
+       .flags = XFRM_MODE_FLAG_TUNNEL,
 };
 
 static int __init xfrm4_tunnel_init(void)
index a4edd666318b0f85bb9efb166df3512f78bce8d5..c4a7156962bd58797d93b7c21051bcc797c98de9 100644 (file)
@@ -47,7 +47,7 @@ static inline int xfrm4_output_one(struct sk_buff *skb)
        struct iphdr *iph;
        int err;
 
-       if (x->props.mode == XFRM_MODE_TUNNEL) {
+       if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
                err = xfrm4_tunnel_check_size(skb);
                if (err)
                        goto error_nolock;
index 329825ca68fe71730387583c9d96129ee3770db2..cc86fb110dd882050848053e94406d6870803a01 100644 (file)
@@ -117,7 +117,7 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
                header_len += xfrm[i]->props.header_len;
                trailer_len += xfrm[i]->props.trailer_len;
 
-               if (xfrm[i]->props.mode == XFRM_MODE_TUNNEL) {
+               if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
                        unsigned short encap_family = xfrm[i]->props.family;
                        switch (encap_family) {
                        case AF_INET:
@@ -151,7 +151,6 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
        i = 0;
        for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) {
                struct xfrm_dst *x = (struct xfrm_dst*)dst_prev;
-               struct xfrm_state_afinfo *afinfo;
                x->u.rt.fl = *fl;
 
                dst_prev->xfrm = xfrm[i++];
@@ -169,27 +168,17 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
                /* Copy neighbout for reachability confirmation */
                dst_prev->neighbour     = neigh_clone(rt->u.dst.neighbour);
                dst_prev->input         = rt->u.dst.input;
-               /* XXX: When IPv6 module can be unloaded, we should manage reference
-                * to xfrm6_output in afinfo->output. Miyazawa
-                * */
-               afinfo = xfrm_state_get_afinfo(dst_prev->xfrm->props.family);
-               if (!afinfo) {
-                       dst = *dst_p;
-                       err = -EAFNOSUPPORT;
-                       goto error;
-               }
-               dst_prev->output = afinfo->output;
-               xfrm_state_put_afinfo(afinfo);
-               if (dst_prev->xfrm->props.family == AF_INET && rt->peer)
-                       atomic_inc(&rt->peer->refcnt);
-               x->u.rt.peer = rt->peer;
+               dst_prev->output = dst_prev->xfrm->outer_mode->afinfo->output;
+               if (rt0->peer)
+                       atomic_inc(&rt0->peer->refcnt);
+               x->u.rt.peer = rt0->peer;
                /* Sheit... I remember I did this right. Apparently,
                 * it was magically lost, so this code needs audit */
                x->u.rt.rt_flags = rt0->rt_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL);
-               x->u.rt.rt_type = rt->rt_type;
+               x->u.rt.rt_type = rt0->rt_type;
                x->u.rt.rt_src = rt0->rt_src;
                x->u.rt.rt_dst = rt0->rt_dst;
-               x->u.rt.rt_gateway = rt->rt_gateway;
+               x->u.rt.rt_gateway = rt0->rt_gateway;
                x->u.rt.rt_spec_dst = rt0->rt_spec_dst;
                x->u.rt.idev = rt0->idev;
                in_dev_hold(rt0->idev);
@@ -291,7 +280,7 @@ static void xfrm4_dst_destroy(struct dst_entry *dst)
 
        if (likely(xdst->u.rt.idev))
                in_dev_put(xdst->u.rt.idev);
-       if (dst->xfrm && dst->xfrm->props.family == AF_INET && likely(xdst->u.rt.peer))
+       if (likely(xdst->u.rt.peer))
                inet_putpeer(xdst->u.rt.peer);
        xfrm_dst_destroy(xdst);
 }
index 93e2c061cddaf3b71a7c6e3c0bae0a22f1b45d76..13d54a1c3337bd311c7245f331367296f07b0558 100644 (file)
@@ -49,6 +49,7 @@ __xfrm4_init_tempsel(struct xfrm_state *x, struct flowi *fl,
 
 static struct xfrm_state_afinfo xfrm4_state_afinfo = {
        .family                 = AF_INET,
+       .owner                  = THIS_MODULE,
        .init_flags             = xfrm4_init_flags,
        .init_tempsel           = __xfrm4_init_tempsel,
        .output                 = xfrm4_output,
index 1312417608e2a34ba7c6e05746d605b2930d05bf..326845195620dd07851907fdf03d65cadb0be220 100644 (file)
@@ -18,7 +18,7 @@ static int ipip_output(struct xfrm_state *x, struct sk_buff *skb)
 
 static int ipip_xfrm_rcv(struct xfrm_state *x, struct sk_buff *skb)
 {
-       return IPPROTO_IP;
+       return ip_hdr(skb)->protocol;
 }
 
 static int ipip_init_state(struct xfrm_state *x)
@@ -48,20 +48,25 @@ static struct xfrm_type ipip_type = {
        .output         = ipip_output
 };
 
+static int xfrm_tunnel_rcv(struct sk_buff *skb)
+{
+       return xfrm4_rcv_spi(skb, IPPROTO_IP, ip_hdr(skb)->saddr);
+}
+
 static int xfrm_tunnel_err(struct sk_buff *skb, u32 info)
 {
        return -ENOENT;
 }
 
 static struct xfrm_tunnel xfrm_tunnel_handler = {
-       .handler        =       xfrm4_rcv,
+       .handler        =       xfrm_tunnel_rcv,
        .err_handler    =       xfrm_tunnel_err,
        .priority       =       2,
 };
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 static struct xfrm_tunnel xfrm64_tunnel_handler = {
-       .handler        =       xfrm4_rcv,
+       .handler        =       xfrm_tunnel_rcv,
        .err_handler    =       xfrm_tunnel_err,
        .priority       =       2,
 };
index 52d10d213217c0bb8c7be5bbda65d9e31ad45e3d..348bd8d061125f61932c74d683e6a3f8d69c28e6 100644 (file)
@@ -255,11 +255,6 @@ static void addrconf_mod_timer(struct inet6_ifaddr *ifp,
 
 static int snmp6_alloc_dev(struct inet6_dev *idev)
 {
-       int err = -ENOMEM;
-
-       if (!idev || !idev->dev)
-               return -EINVAL;
-
        if (snmp_mib_init((void **)idev->stats.ipv6,
                          sizeof(struct ipstats_mib),
                          __alignof__(struct ipstats_mib)) < 0)
@@ -280,15 +275,14 @@ err_icmpmsg:
 err_icmp:
        snmp_mib_free((void **)idev->stats.ipv6);
 err_ip:
-       return err;
+       return -ENOMEM;
 }
 
-static int snmp6_free_dev(struct inet6_dev *idev)
+static void snmp6_free_dev(struct inet6_dev *idev)
 {
        snmp_mib_free((void **)idev->stats.icmpv6msg);
        snmp_mib_free((void **)idev->stats.icmpv6);
        snmp_mib_free((void **)idev->stats.ipv6);
-       return 0;
 }
 
 /* Nobody refers to this device, we may destroy it. */
index bc929381fa46c59926266efde1a6702d2460f1e4..1b1caf3aa1c189d7ce57bf38d4276afa5d4c35c9 100644 (file)
@@ -747,6 +747,7 @@ static void cleanup_ipv6_mibs(void)
 {
        snmp_mib_free((void **)ipv6_statistics);
        snmp_mib_free((void **)icmpv6_statistics);
+       snmp_mib_free((void **)icmpv6msg_statistics);
        snmp_mib_free((void **)udp_stats_in6);
        snmp_mib_free((void **)udplite_stats_in6);
 }
index f9f689162692e9b6334b9a2d0e04ccbd069d60fb..66a9139d46e97fe30a843c08c356e69d990abfac 100644 (file)
@@ -344,6 +344,8 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
            pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
                goto out;
 
+       skb->ip_summed = CHECKSUM_NONE;
+
        hdr_len = skb->data - skb_network_header(skb);
        ah = (struct ip_auth_hdr *)skb->data;
        ahp = x->data;
@@ -475,8 +477,16 @@ static int ah6_init_state(struct xfrm_state *x)
 
        x->props.header_len = XFRM_ALIGN8(sizeof(struct ip_auth_hdr) +
                                          ahp->icv_trunc_len);
-       if (x->props.mode == XFRM_MODE_TUNNEL)
+       switch (x->props.mode) {
+       case XFRM_MODE_BEET:
+       case XFRM_MODE_TRANSPORT:
+               break;
+       case XFRM_MODE_TUNNEL:
                x->props.header_len += sizeof(struct ipv6hdr);
+               break;
+       default:
+               goto error;
+       }
        x->data = ahp;
 
        return 0;
index 9eb92859835171ec22709c04148ce9860ea2acbe..72a659806cadfb4f7d026e10e6eef9df41f9e0ef 100644 (file)
@@ -354,8 +354,16 @@ static int esp6_init_state(struct xfrm_state *x)
                                    (x->ealg->alg_key_len + 7) / 8))
                goto error;
        x->props.header_len = sizeof(struct ip_esp_hdr) + esp->conf.ivlen;
-       if (x->props.mode == XFRM_MODE_TUNNEL)
+       switch (x->props.mode) {
+       case XFRM_MODE_BEET:
+       case XFRM_MODE_TRANSPORT:
+               break;
+       case XFRM_MODE_TUNNEL:
                x->props.header_len += sizeof(struct ipv6hdr);
+               break;
+       default:
+               goto error;
+       }
        x->data = esp;
        return 0;
 
index 1c2c2765543505d7e61dd021fa2fcf2b9482757f..d6f1026f19438114bfef264b1f669cf03f0fd131 100644 (file)
@@ -261,7 +261,7 @@ int inet6_hash_connect(struct inet_timewait_death_row *death_row,
                struct inet_timewait_sock *tw = NULL;
 
                inet_get_local_port_range(&low, &high);
-               remaining = high - low;
+               remaining = (high - low) + 1;
 
                local_bh_disable();
                for (i = 1; i <= remaining; i++) {
index 217d60f9fc80e89afc4e07a831ec9470c45b07e9..b12cc22e7745d4f629a1abe1871cfce161e551aa 100644 (file)
@@ -154,8 +154,10 @@ static void ip6_fl_gc(unsigned long dummy)
        write_unlock(&ip6_fl_lock);
 }
 
-static int fl_intern(struct ip6_flowlabel *fl, __be32 label)
+static struct ip6_flowlabel *fl_intern(struct ip6_flowlabel *fl, __be32 label)
 {
+       struct ip6_flowlabel *lfl;
+
        fl->label = label & IPV6_FLOWLABEL_MASK;
 
        write_lock_bh(&ip6_fl_lock);
@@ -163,12 +165,26 @@ static int fl_intern(struct ip6_flowlabel *fl, __be32 label)
                for (;;) {
                        fl->label = htonl(net_random())&IPV6_FLOWLABEL_MASK;
                        if (fl->label) {
-                               struct ip6_flowlabel *lfl;
                                lfl = __fl_lookup(fl->label);
                                if (lfl == NULL)
                                        break;
                        }
                }
+       } else {
+               /*
+                * we dropper the ip6_fl_lock, so this entry could reappear
+                * and we need to recheck with it.
+                *
+                * OTOH no need to search the active socket first, like it is
+                * done in ipv6_flowlabel_opt - sock is locked, so new entry
+                * with the same label can only appear on another sock
+                */
+               lfl = __fl_lookup(fl->label);
+               if (lfl != NULL) {
+                       atomic_inc(&lfl->users);
+                       write_unlock_bh(&ip6_fl_lock);
+                       return lfl;
+               }
        }
 
        fl->lastuse = jiffies;
@@ -176,7 +192,7 @@ static int fl_intern(struct ip6_flowlabel *fl, __be32 label)
        fl_ht[FL_HASH(fl->label)] = fl;
        atomic_inc(&fl_size);
        write_unlock_bh(&ip6_fl_lock);
-       return 0;
+       return NULL;
 }
 
 
@@ -190,14 +206,17 @@ struct ip6_flowlabel * fl6_sock_lookup(struct sock *sk, __be32 label)
 
        label &= IPV6_FLOWLABEL_MASK;
 
+       read_lock_bh(&ip6_sk_fl_lock);
        for (sfl=np->ipv6_fl_list; sfl; sfl = sfl->next) {
                struct ip6_flowlabel *fl = sfl->fl;
                if (fl->label == label) {
                        fl->lastuse = jiffies;
                        atomic_inc(&fl->users);
+                       read_unlock_bh(&ip6_sk_fl_lock);
                        return fl;
                }
        }
+       read_unlock_bh(&ip6_sk_fl_lock);
        return NULL;
 }
 
@@ -409,6 +428,16 @@ static int ipv6_opt_cmp(struct ipv6_txoptions *o1, struct ipv6_txoptions *o2)
        return 0;
 }
 
+static inline void fl_link(struct ipv6_pinfo *np, struct ipv6_fl_socklist *sfl,
+               struct ip6_flowlabel *fl)
+{
+       write_lock_bh(&ip6_sk_fl_lock);
+       sfl->fl = fl;
+       sfl->next = np->ipv6_fl_list;
+       np->ipv6_fl_list = sfl;
+       write_unlock_bh(&ip6_sk_fl_lock);
+}
+
 int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen)
 {
        int err;
@@ -416,7 +445,8 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen)
        struct in6_flowlabel_req freq;
        struct ipv6_fl_socklist *sfl1=NULL;
        struct ipv6_fl_socklist *sfl, **sflp;
-       struct ip6_flowlabel *fl;
+       struct ip6_flowlabel *fl, *fl1 = NULL;
+
 
        if (optlen < sizeof(freq))
                return -EINVAL;
@@ -472,8 +502,6 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen)
                sfl1 = kmalloc(sizeof(*sfl1), GFP_KERNEL);
 
                if (freq.flr_label) {
-                       struct ip6_flowlabel *fl1 = NULL;
-
                        err = -EEXIST;
                        read_lock_bh(&ip6_sk_fl_lock);
                        for (sfl = np->ipv6_fl_list; sfl; sfl = sfl->next) {
@@ -492,6 +520,7 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen)
                        if (fl1 == NULL)
                                fl1 = fl_lookup(freq.flr_label);
                        if (fl1) {
+recheck:
                                err = -EEXIST;
                                if (freq.flr_flags&IPV6_FL_F_EXCL)
                                        goto release;
@@ -513,11 +542,7 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen)
                                        fl1->linger = fl->linger;
                                if ((long)(fl->expires - fl1->expires) > 0)
                                        fl1->expires = fl->expires;
-                               write_lock_bh(&ip6_sk_fl_lock);
-                               sfl1->fl = fl1;
-                               sfl1->next = np->ipv6_fl_list;
-                               np->ipv6_fl_list = sfl1;
-                               write_unlock_bh(&ip6_sk_fl_lock);
+                               fl_link(np, sfl1, fl1);
                                fl_free(fl);
                                return 0;
 
@@ -534,9 +559,9 @@ release:
                if (sfl1 == NULL || (err = mem_check(sk)) != 0)
                        goto done;
 
-               err = fl_intern(fl, freq.flr_label);
-               if (err)
-                       goto done;
+               fl1 = fl_intern(fl, freq.flr_label);
+               if (fl1 != NULL)
+                       goto recheck;
 
                if (!freq.flr_label) {
                        if (copy_to_user(&((struct in6_flowlabel_req __user *) optval)->flr_label,
@@ -545,9 +570,7 @@ release:
                        }
                }
 
-               sfl1->fl = fl;
-               sfl1->next = np->ipv6_fl_list;
-               np->ipv6_fl_list = sfl1;
+               fl_link(np, sfl1, fl);
                return 0;
 
        default:
index 28fc8edfdc3aa63f24f85df71869809d27df7e71..80ef2a1d39fd56704fef43e47a8c80456ce0a587 100644 (file)
@@ -411,8 +411,15 @@ static int ipcomp6_init_state(struct xfrm_state *x)
                goto out;
 
        x->props.header_len = 0;
-       if (x->props.mode == XFRM_MODE_TUNNEL)
+       switch (x->props.mode) {
+       case XFRM_MODE_BEET:
+       case XFRM_MODE_TRANSPORT:
+               break;
+       case XFRM_MODE_TUNNEL:
                x->props.header_len += sizeof(struct ipv6hdr);
+       default:
+               goto error;
+       }
 
        mutex_lock(&ipcomp6_resource_mutex);
        if (!ipcomp6_alloc_scratches())
index 6cc33dc83d1cb354767de626024fd6cd982573c3..20cfc90d5597dc266d398beb8de1eaeb0a77107f 100644 (file)
@@ -1658,30 +1658,26 @@ int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, struct file * f
        struct inet6_dev *idev;
        int ret;
 
-       if (ctl->ctl_name == NET_NEIGH_RETRANS_TIME ||
-           ctl->ctl_name == NET_NEIGH_REACHABLE_TIME)
+       if ((strcmp(ctl->procname, "retrans_time") == 0) ||
+           (strcmp(ctl->procname, "base_reachable_time") == 0))
                ndisc_warn_deprecated_sysctl(ctl, "syscall", dev ? dev->name : "default");
 
-       switch (ctl->ctl_name) {
-       case NET_NEIGH_RETRANS_TIME:
+       if (strcmp(ctl->procname, "retrans_time") == 0)
                ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
-               break;
-       case NET_NEIGH_REACHABLE_TIME:
+
+       else if (strcmp(ctl->procname, "base_reachable_time") == 0)
                ret = proc_dointvec_jiffies(ctl, write,
                                            filp, buffer, lenp, ppos);
-               break;
-       case NET_NEIGH_RETRANS_TIME_MS:
-       case NET_NEIGH_REACHABLE_TIME_MS:
+
+       else if ((strcmp(ctl->procname, "retrans_time_ms") == 0) ||
+                (strcmp(ctl->procname, "base_reacable_time_ms") == 0))
                ret = proc_dointvec_ms_jiffies(ctl, write,
                                               filp, buffer, lenp, ppos);
-               break;
-       default:
+       else
                ret = -1;
-       }
 
        if (write && ret == 0 && dev && (idev = in6_dev_get(dev)) != NULL) {
-               if (ctl->ctl_name == NET_NEIGH_REACHABLE_TIME ||
-                   ctl->ctl_name == NET_NEIGH_REACHABLE_TIME_MS)
+               if (ctl->data == &idev->nd_parms->base_reachable_time)
                        idev->nd_parms->reachable_time = neigh_rand_reach_time(idev->nd_parms->base_reachable_time);
                idev->tstamp = jiffies;
                inet6_ifinfo_notify(RTM_NEWLINK, idev);
index 0e40948f4fc6516237b90f940f58bb0e1298c5f8..ad74bab050477305a93153e586492dc663b7c3ee 100644 (file)
@@ -306,7 +306,6 @@ static struct nf_hook_ops ipv6_conntrack_ops[] = {
 #ifdef CONFIG_SYSCTL
 static ctl_table nf_ct_ipv6_sysctl_table[] = {
        {
-               .ctl_name       = NET_NF_CONNTRACK_FRAG6_TIMEOUT,
                .procname       = "nf_conntrack_frag6_timeout",
                .data           = &nf_frags_ctl.timeout,
                .maxlen         = sizeof(unsigned int),
index fbdc66920de4837a21461be7864fc36fbd5e7cb2..fd9123f3dc04dfc25472130744875548dd4de04b 100644 (file)
@@ -260,7 +260,6 @@ static int icmpv6_nlattr_to_tuple(struct nlattr *tb[],
 static struct ctl_table_header *icmpv6_sysctl_header;
 static struct ctl_table icmpv6_sysctl_table[] = {
        {
-               .ctl_name       = NET_NF_CONNTRACK_ICMPV6_TIMEOUT,
                .procname       = "nf_conntrack_icmpv6_timeout",
                .data           = &nf_ct_icmpv6_timeout,
                .maxlen         = sizeof(unsigned int),
index 726fafd41961b1489caaa9f618616ea50f8d70f6..e170c67c47a5b613c7681d05d0b0f73c784e9c46 100644 (file)
@@ -130,22 +130,6 @@ static inline void frag_kfree_skb(struct sk_buff *skb, unsigned int *work)
        kfree_skb(skb);
 }
 
-static void nf_frag_free(struct inet_frag_queue *q)
-{
-       kfree(container_of(q, struct nf_ct_frag6_queue, q));
-}
-
-static inline struct nf_ct_frag6_queue *frag_alloc_queue(void)
-{
-       struct nf_ct_frag6_queue *fq;
-
-       fq = kzalloc(sizeof(struct nf_ct_frag6_queue), GFP_ATOMIC);
-       if (fq == NULL)
-               return NULL;
-       atomic_add(sizeof(struct nf_ct_frag6_queue), &nf_frags.mem);
-       return fq;
-}
-
 /* Destruction primitives. */
 
 static __inline__ void fq_put(struct nf_ct_frag6_queue *fq)
@@ -168,7 +152,10 @@ static void nf_ct_frag6_evictor(void)
 
 static void nf_ct_frag6_expire(unsigned long data)
 {
-       struct nf_ct_frag6_queue *fq = (struct nf_ct_frag6_queue *) data;
+       struct nf_ct_frag6_queue *fq;
+
+       fq = container_of((struct inet_frag_queue *)data,
+                       struct nf_ct_frag6_queue, q);
 
        spin_lock(&fq->q.lock);
 
@@ -184,89 +171,29 @@ out:
 
 /* Creation primitives. */
 
-static struct nf_ct_frag6_queue *nf_ct_frag6_intern(unsigned int hash,
-                                         struct nf_ct_frag6_queue *fq_in)
+static __inline__ struct nf_ct_frag6_queue *
+fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst)
 {
-       struct nf_ct_frag6_queue *fq;
-#ifdef CONFIG_SMP
-       struct hlist_node *n;
-#endif
-
-       write_lock(&nf_frags.lock);
-#ifdef CONFIG_SMP
-       hlist_for_each_entry(fq, n, &nf_frags.hash[hash], q.list) {
-               if (fq->id == fq_in->id &&
-                   ipv6_addr_equal(&fq_in->saddr, &fq->saddr) &&
-                   ipv6_addr_equal(&fq_in->daddr, &fq->daddr)) {
-                       atomic_inc(&fq->q.refcnt);
-                       write_unlock(&nf_frags.lock);
-                       fq_in->q.last_in |= COMPLETE;
-                       fq_put(fq_in);
-                       return fq;
-               }
-       }
-#endif
-       fq = fq_in;
-
-       if (!mod_timer(&fq->q.timer, jiffies + nf_frags_ctl.timeout))
-               atomic_inc(&fq->q.refcnt);
-
-       atomic_inc(&fq->q.refcnt);
-       hlist_add_head(&fq->q.list, &nf_frags.hash[hash]);
-       INIT_LIST_HEAD(&fq->q.lru_list);
-       list_add_tail(&fq->q.lru_list, &nf_frags.lru_list);
-       nf_frags.nqueues++;
-       write_unlock(&nf_frags.lock);
-       return fq;
-}
+       struct inet_frag_queue *q;
+       struct ip6_create_arg arg;
+       unsigned int hash;
 
+       arg.id = id;
+       arg.src = src;
+       arg.dst = dst;
+       hash = ip6qhashfn(id, src, dst);
 
-static struct nf_ct_frag6_queue *
-nf_ct_frag6_create(unsigned int hash, __be32 id, struct in6_addr *src,                            struct in6_addr *dst)
-{
-       struct nf_ct_frag6_queue *fq;
-
-       if ((fq = frag_alloc_queue()) == NULL) {
-               pr_debug("Can't alloc new queue\n");
+       q = inet_frag_find(&nf_frags, &arg, hash);
+       if (q == NULL)
                goto oom;
-       }
-
-       fq->id = id;
-       ipv6_addr_copy(&fq->saddr, src);
-       ipv6_addr_copy(&fq->daddr, dst);
-
-       setup_timer(&fq->q.timer, nf_ct_frag6_expire, (unsigned long)fq);
-       spin_lock_init(&fq->q.lock);
-       atomic_set(&fq->q.refcnt, 1);
 
-       return nf_ct_frag6_intern(hash, fq);
+       return container_of(q, struct nf_ct_frag6_queue, q);
 
 oom:
+       pr_debug("Can't alloc new queue\n");
        return NULL;
 }
 
-static __inline__ struct nf_ct_frag6_queue *
-fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst)
-{
-       struct nf_ct_frag6_queue *fq;
-       struct hlist_node *n;
-       unsigned int hash = ip6qhashfn(id, src, dst);
-
-       read_lock(&nf_frags.lock);
-       hlist_for_each_entry(fq, n, &nf_frags.hash[hash], q.list) {
-               if (fq->id == id &&
-                   ipv6_addr_equal(src, &fq->saddr) &&
-                   ipv6_addr_equal(dst, &fq->daddr)) {
-                       atomic_inc(&fq->q.refcnt);
-                       read_unlock(&nf_frags.lock);
-                       return fq;
-               }
-       }
-       read_unlock(&nf_frags.lock);
-
-       return nf_ct_frag6_create(hash, id, src, dst);
-}
-
 
 static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
                             struct frag_hdr *fhdr, int nhoff)
@@ -749,9 +676,12 @@ int nf_ct_frag6_init(void)
 {
        nf_frags.ctl = &nf_frags_ctl;
        nf_frags.hashfn = nf_hashfn;
-       nf_frags.destructor = nf_frag_free;
+       nf_frags.constructor = ip6_frag_init;
+       nf_frags.destructor = NULL;
        nf_frags.skb_free = nf_skb_free;
        nf_frags.qsize = sizeof(struct nf_ct_frag6_queue);
+       nf_frags.match = ip6_frag_match;
+       nf_frags.frag_expire = nf_ct_frag6_expire;
        inet_frags_init(&nf_frags);
 
        return 0;
index 6ad19cfc2025bca20618a81d7bb45495f7291ab1..76c88a93b9b5a7714678a0ccb28aa140aa4e4998 100644 (file)
@@ -143,6 +143,18 @@ static unsigned int ip6_hashfn(struct inet_frag_queue *q)
        return ip6qhashfn(fq->id, &fq->saddr, &fq->daddr);
 }
 
+int ip6_frag_match(struct inet_frag_queue *q, void *a)
+{
+       struct frag_queue *fq;
+       struct ip6_create_arg *arg = a;
+
+       fq = container_of(q, struct frag_queue, q);
+       return (fq->id == arg->id &&
+                       ipv6_addr_equal(&fq->saddr, arg->src) &&
+                       ipv6_addr_equal(&fq->daddr, arg->dst));
+}
+EXPORT_SYMBOL(ip6_frag_match);
+
 /* Memory Tracking Functions. */
 static inline void frag_kfree_skb(struct sk_buff *skb, int *work)
 {
@@ -152,20 +164,16 @@ static inline void frag_kfree_skb(struct sk_buff *skb, int *work)
        kfree_skb(skb);
 }
 
-static void ip6_frag_free(struct inet_frag_queue *fq)
+void ip6_frag_init(struct inet_frag_queue *q, void *a)
 {
-       kfree(container_of(fq, struct frag_queue, q));
-}
-
-static inline struct frag_queue *frag_alloc_queue(void)
-{
-       struct frag_queue *fq = kzalloc(sizeof(struct frag_queue), GFP_ATOMIC);
+       struct frag_queue *fq = container_of(q, struct frag_queue, q);
+       struct ip6_create_arg *arg = a;
 
-       if(!fq)
-               return NULL;
-       atomic_add(sizeof(struct frag_queue), &ip6_frags.mem);
-       return fq;
+       fq->id = arg->id;
+       ipv6_addr_copy(&fq->saddr, arg->src);
+       ipv6_addr_copy(&fq->daddr, arg->dst);
 }
+EXPORT_SYMBOL(ip6_frag_init);
 
 /* Destruction primitives. */
 
@@ -193,9 +201,11 @@ static void ip6_evictor(struct inet6_dev *idev)
 
 static void ip6_frag_expire(unsigned long data)
 {
-       struct frag_queue *fq = (struct frag_queue *) data;
+       struct frag_queue *fq;
        struct net_device *dev = NULL;
 
+       fq = container_of((struct inet_frag_queue *)data, struct frag_queue, q);
+
        spin_lock(&fq->q.lock);
 
        if (fq->q.last_in & COMPLETE)
@@ -230,98 +240,30 @@ out:
        fq_put(fq);
 }
 
-/* Creation primitives. */
-
-
-static struct frag_queue *ip6_frag_intern(struct frag_queue *fq_in)
+static __inline__ struct frag_queue *
+fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst,
+       struct inet6_dev *idev)
 {
-       struct frag_queue *fq;
+       struct inet_frag_queue *q;
+       struct ip6_create_arg arg;
        unsigned int hash;
-#ifdef CONFIG_SMP
-       struct hlist_node *n;
-#endif
 
-       write_lock(&ip6_frags.lock);
-       hash = ip6qhashfn(fq_in->id, &fq_in->saddr, &fq_in->daddr);
-#ifdef CONFIG_SMP
-       hlist_for_each_entry(fq, n, &ip6_frags.hash[hash], q.list) {
-               if (fq->id == fq_in->id &&
-                   ipv6_addr_equal(&fq_in->saddr, &fq->saddr) &&
-                   ipv6_addr_equal(&fq_in->daddr, &fq->daddr)) {
-                       atomic_inc(&fq->q.refcnt);
-                       write_unlock(&ip6_frags.lock);
-                       fq_in->q.last_in |= COMPLETE;
-                       fq_put(fq_in);
-                       return fq;
-               }
-       }
-#endif
-       fq = fq_in;
-
-       if (!mod_timer(&fq->q.timer, jiffies + ip6_frags_ctl.timeout))
-               atomic_inc(&fq->q.refcnt);
-
-       atomic_inc(&fq->q.refcnt);
-       hlist_add_head(&fq->q.list, &ip6_frags.hash[hash]);
-       INIT_LIST_HEAD(&fq->q.lru_list);
-       list_add_tail(&fq->q.lru_list, &ip6_frags.lru_list);
-       ip6_frags.nqueues++;
-       write_unlock(&ip6_frags.lock);
-       return fq;
-}
-
-
-static struct frag_queue *
-ip6_frag_create(__be32 id, struct in6_addr *src, struct in6_addr *dst,
-               struct inet6_dev *idev)
-{
-       struct frag_queue *fq;
+       arg.id = id;
+       arg.src = src;
+       arg.dst = dst;
+       hash = ip6qhashfn(id, src, dst);
 
-       if ((fq = frag_alloc_queue()) == NULL)
+       q = inet_frag_find(&ip6_frags, &arg, hash);
+       if (q == NULL)
                goto oom;
 
-       fq->id = id;
-       ipv6_addr_copy(&fq->saddr, src);
-       ipv6_addr_copy(&fq->daddr, dst);
-
-       init_timer(&fq->q.timer);
-       fq->q.timer.function = ip6_frag_expire;
-       fq->q.timer.data = (long) fq;
-       spin_lock_init(&fq->q.lock);
-       atomic_set(&fq->q.refcnt, 1);
-
-       return ip6_frag_intern(fq);
+       return container_of(q, struct frag_queue, q);
 
 oom:
        IP6_INC_STATS_BH(idev, IPSTATS_MIB_REASMFAILS);
        return NULL;
 }
 
-static __inline__ struct frag_queue *
-fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst,
-       struct inet6_dev *idev)
-{
-       struct frag_queue *fq;
-       struct hlist_node *n;
-       unsigned int hash;
-
-       read_lock(&ip6_frags.lock);
-       hash = ip6qhashfn(id, src, dst);
-       hlist_for_each_entry(fq, n, &ip6_frags.hash[hash], q.list) {
-               if (fq->id == id &&
-                   ipv6_addr_equal(src, &fq->saddr) &&
-                   ipv6_addr_equal(dst, &fq->daddr)) {
-                       atomic_inc(&fq->q.refcnt);
-                       read_unlock(&ip6_frags.lock);
-                       return fq;
-               }
-       }
-       read_unlock(&ip6_frags.lock);
-
-       return ip6_frag_create(id, src, dst, idev);
-}
-
-
 static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
                           struct frag_hdr *fhdr, int nhoff)
 {
@@ -697,8 +639,11 @@ void __init ipv6_frag_init(void)
 
        ip6_frags.ctl = &ip6_frags_ctl;
        ip6_frags.hashfn = ip6_hashfn;
-       ip6_frags.destructor = ip6_frag_free;
+       ip6_frags.constructor = ip6_frag_init;
+       ip6_frags.destructor = NULL;
        ip6_frags.skb_free = NULL;
        ip6_frags.qsize = sizeof(struct frag_queue);
+       ip6_frags.match = ip6_frag_match;
+       ip6_frags.frag_expire = ip6_frag_expire;
        inet_frags_init(&ip6_frags);
 }
index cce9941c11c60afb75a7f4242b90aaf3a51e0670..95f8e4a62f68f6048f01e964ae1b619d9e90a947 100644 (file)
@@ -2397,7 +2397,6 @@ int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int write, struct file * filp,
 
 ctl_table ipv6_route_table[] = {
        {
-               .ctl_name       =       NET_IPV6_ROUTE_FLUSH,
                .procname       =       "flush",
                .data           =       &flush_delay,
                .maxlen         =       sizeof(int),
index 02f69e544f6f51c85f04266e3a2f1dfbcf19ddfc..515783707e86b0338d003dab53fe9b2310652aa3 100644 (file)
@@ -16,7 +16,7 @@
 #include <net/ipv6.h>
 #include <net/xfrm.h>
 
-int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi)
+int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
 {
        int err;
        __be32 seq;
@@ -24,11 +24,9 @@ int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi)
        struct xfrm_state *x;
        int xfrm_nr = 0;
        int decaps = 0;
-       int nexthdr;
        unsigned int nhoff;
 
        nhoff = IP6CB(skb)->nhoff;
-       nexthdr = skb_network_header(skb)[nhoff];
 
        seq = 0;
        if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0)
@@ -41,7 +39,7 @@ int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi)
                        goto drop;
 
                x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi,
-                               nexthdr != IPPROTO_IPIP ? nexthdr : IPPROTO_IPV6, AF_INET6);
+                                     nexthdr, AF_INET6);
                if (x == NULL)
                        goto drop;
                spin_lock(&x->lock);
@@ -70,10 +68,10 @@ int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi)
 
                xfrm_vec[xfrm_nr++] = x;
 
-               if (x->mode->input(x, skb))
+               if (x->outer_mode->input(x, skb))
                        goto drop;
 
-               if (x->props.mode == XFRM_MODE_TUNNEL) { /* XXX */
+               if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
                        decaps = 1;
                        break;
                }
@@ -99,7 +97,6 @@ int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi)
        memcpy(skb->sp->xvec + skb->sp->len, xfrm_vec,
               xfrm_nr * sizeof(xfrm_vec[0]));
        skb->sp->len += xfrm_nr;
-       skb->ip_summed = CHECKSUM_NONE;
 
        nf_reset(skb);
 
@@ -135,7 +132,8 @@ EXPORT_SYMBOL(xfrm6_rcv_spi);
 
 int xfrm6_rcv(struct sk_buff *skb)
 {
-       return xfrm6_rcv_spi(skb, 0);
+       return xfrm6_rcv_spi(skb, skb_network_header(skb)[IP6CB(skb)->nhoff],
+                            0);
 }
 
 EXPORT_SYMBOL(xfrm6_rcv);
index 13bb1e85676467e8e3a03d19b38518736d44e2ce..2bfb4f05c14cdffec7f7c455e5ecf43f34acd4c9 100644 (file)
@@ -79,6 +79,7 @@ static struct xfrm_mode xfrm6_beet_mode = {
        .output = xfrm6_beet_output,
        .owner = THIS_MODULE,
        .encap = XFRM_MODE_BEET,
+       .flags = XFRM_MODE_FLAG_TUNNEL,
 };
 
 static int __init xfrm6_beet_init(void)
index 957ae36b66958ab55fbe656e01d20bcba76f78a1..a7bc8c62317af220e6ba9ae95842286b4b7925c5 100644 (file)
@@ -58,16 +58,7 @@ static int xfrm6_ro_output(struct xfrm_state *x, struct sk_buff *skb)
        return 0;
 }
 
-/*
- * Do nothing about routing optimization header unlike IPsec.
- */
-static int xfrm6_ro_input(struct xfrm_state *x, struct sk_buff *skb)
-{
-       return 0;
-}
-
 static struct xfrm_mode xfrm6_ro_mode = {
-       .input = xfrm6_ro_input,
        .output = xfrm6_ro_output,
        .owner = THIS_MODULE,
        .encap = XFRM_MODE_ROUTEOPTIMIZATION,
index ea22838791126f1df90aa82f43487ae121a6afc6..fd84e2217274a894ca69b1b7a23bfee81fab297f 100644 (file)
@@ -118,6 +118,7 @@ static struct xfrm_mode xfrm6_tunnel_mode = {
        .output = xfrm6_tunnel_output,
        .owner = THIS_MODULE,
        .encap = XFRM_MODE_TUNNEL,
+       .flags = XFRM_MODE_FLAG_TUNNEL,
 };
 
 static int __init xfrm6_tunnel_init(void)
index a5a32c17249ded0bc1211a3a2ff101c9898ed61e..656976760ad47175afa8bc6ac7d2152d5e7f95b4 100644 (file)
@@ -50,7 +50,7 @@ static inline int xfrm6_output_one(struct sk_buff *skb)
        struct ipv6hdr *iph;
        int err;
 
-       if (x->props.mode == XFRM_MODE_TUNNEL) {
+       if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
                err = xfrm6_tunnel_check_size(skb);
                if (err)
                        goto error_nolock;
index 15aa4c58c3159ef9ec2a844bcca0305c0b034ec8..82e27b80d07d3d060112eb873d7b0a9774853cba 100644 (file)
@@ -178,8 +178,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
                __xfrm6_bundle_len_inc(&header_len, &nfheader_len, xfrm[i]);
                trailer_len += xfrm[i]->props.trailer_len;
 
-               if (xfrm[i]->props.mode == XFRM_MODE_TUNNEL ||
-                   xfrm[i]->props.mode == XFRM_MODE_ROUTEOPTIMIZATION) {
+               if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
                        unsigned short encap_family = xfrm[i]->props.family;
                        switch(encap_family) {
                        case AF_INET:
@@ -215,7 +214,6 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
        i = 0;
        for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) {
                struct xfrm_dst *x = (struct xfrm_dst*)dst_prev;
-               struct xfrm_state_afinfo *afinfo;
 
                dst_prev->xfrm = xfrm[i++];
                dst_prev->dev = rt->u.dst.dev;
@@ -232,18 +230,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
                /* Copy neighbour for reachability confirmation */
                dst_prev->neighbour     = neigh_clone(rt->u.dst.neighbour);
                dst_prev->input         = rt->u.dst.input;
-               /* XXX: When IPv4 is implemented as module and can be unloaded,
-                * we should manage reference to xfrm4_output in afinfo->output.
-                * Miyazawa
-                */
-               afinfo = xfrm_state_get_afinfo(dst_prev->xfrm->props.family);
-               if (!afinfo) {
-                       dst = *dst_p;
-                       goto error;
-               }
-
-               dst_prev->output = afinfo->output;
-               xfrm_state_put_afinfo(afinfo);
+               dst_prev->output = dst_prev->xfrm->outer_mode->afinfo->output;
                /* Sheit... I remember I did this right. Apparently,
                 * it was magically lost, so this code needs audit */
                x->u.rt6.rt6i_flags    = rt0->rt6i_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL);
index cdadb4847469f21e52237c75d5f12abaac9a5ffb..b392bee396f16341c2842aa20c3759c19afb0238 100644 (file)
@@ -93,7 +93,8 @@ __xfrm6_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n)
        /* Rule 4: select IPsec tunnel */
        for (i = 0; i < n; i++) {
                if (src[i] &&
-                   src[i]->props.mode == XFRM_MODE_TUNNEL) {
+                   (src[i]->props.mode == XFRM_MODE_TUNNEL ||
+                    src[i]->props.mode == XFRM_MODE_BEET)) {
                        dst[j++] = src[i];
                        src[i] = NULL;
                }
@@ -146,7 +147,8 @@ __xfrm6_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n)
        /* Rule 3: select IPsec tunnel */
        for (i = 0; i < n; i++) {
                if (src[i] &&
-                   src[i]->mode == XFRM_MODE_TUNNEL) {
+                   (src[i]->mode == XFRM_MODE_TUNNEL ||
+                    src[i]->mode == XFRM_MODE_BEET)) {
                        dst[j++] = src[i];
                        src[i] = NULL;
                }
@@ -168,6 +170,7 @@ __xfrm6_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n)
 
 static struct xfrm_state_afinfo xfrm6_state_afinfo = {
        .family                 = AF_INET6,
+       .owner                  = THIS_MODULE,
        .init_tempsel           = __xfrm6_init_tempsel,
        .tmpl_sort              = __xfrm6_tmpl_sort,
        .state_sort             = __xfrm6_state_sort,
index 3f8a3abde67ea47c2c5a9cef9a4137d751477a4a..fae90ff310875eac20da4de63c56469ce53237eb 100644 (file)
@@ -248,7 +248,7 @@ static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
 
 static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
 {
-       return 0;
+       return skb_network_header(skb)[IP6CB(skb)->nhoff];
 }
 
 static int xfrm6_tunnel_rcv(struct sk_buff *skb)
@@ -257,7 +257,7 @@ static int xfrm6_tunnel_rcv(struct sk_buff *skb)
        __be32 spi;
 
        spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&iph->saddr);
-       return xfrm6_rcv_spi(skb, spi) > 0 ? : 0;
+       return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi) > 0 ? : 0;
 }
 
 static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
index af0cea721d2acd19cfd16f83efed38b6d18826b6..80c33f408e3fc2ccee1059d6141728cda89d1a27 100644 (file)
@@ -202,7 +202,7 @@ void irlmp_expire_discoveries(hashbin_t *log, __u32 saddr, int force)
        /* Drop the spinlock before calling the higher layers, as
         * we can't guarantee they won't call us back and create a
         * deadlock. We will work on our own private data, so we
-        * don't care to be interupted. - Jean II */
+        * don't care to be interrupted. - Jean II */
        spin_unlock_irqrestore(&log->hb_spinlock, flags);
 
        if(buffer == NULL)
index 824309dabfe9450102791912c77c8f0ba1b74b4b..b5a13882c92714b42fba19c96a8ab898bab5f143 100644 (file)
@@ -381,18 +381,9 @@ static void ircomm_tty_discovery_indication(discinfo_t *discovery,
        info.daddr = discovery->daddr;
        info.saddr = discovery->saddr;
 
-       /* FIXME. We have a locking problem on the hashbin here.
-        * We probably need to use hashbin_find_next(), but we first
-        * need to ensure that "line" is unique. - Jean II */
-       self = (struct ircomm_tty_cb *) hashbin_get_first(ircomm_tty);
-       while (self != NULL) {
-               IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
-
-               ircomm_tty_do_event(self, IRCOMM_TTY_DISCOVERY_INDICATION,
-                                   NULL, &info);
-
-               self = (struct ircomm_tty_cb *) hashbin_get_next(ircomm_tty);
-       }
+       self = (struct ircomm_tty_cb *) priv;
+       ircomm_tty_do_event(self, IRCOMM_TTY_DISCOVERY_INDICATION,
+                           NULL, &info);
 }
 
 /*
index ee3889fa49abf2d89721b99d9e0a0c25ff407a35..dc5e34a01620b8225d8f4081c03e84ef4288b706 100644 (file)
@@ -18,7 +18,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
index 99b18dc7a0b7e3b26f8fcd52d7c30bebee14d69d..8fb9d7277ca866b8aa6b944b2b0be6e8b14672f0 100644 (file)
@@ -18,7 +18,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
index cf302457097bdefd1e6af972194ef04e97be465e..cbcf04380f3a46eb94ecfb43e169079690728e7c 100644 (file)
@@ -16,7 +16,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
index 87039c2fb6a23cbece6b28825fd998b08fe8ae9c..fff52d57a2000a3ed974a6765a1d67db99714fdd 100644 (file)
@@ -20,7 +20,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
index 843ab6fbb394b17065f35e01b74162a653e69a69..6afcee59e90632b926fd069c10353916693c1335 100644 (file)
@@ -17,7 +17,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
index f5778ef3ccc7213ac7e3b179813324aa2973a1c7..a4b56e25a91705abb9899559f7fb6ae07a535b52 100644 (file)
@@ -17,7 +17,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
index 340f04a36b027ba48e8eef9f6460f22ae909289f..7f9c8542e5fc0deabdb0ff86a7fd654a1fc962c0 100644 (file)
@@ -19,7 +19,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
index 623e0fd16c1900909c3830e1409a6ec7d872fe62..a9750a801388f6d2586852f81a9c8ca980f7582f 100644 (file)
@@ -16,7 +16,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
index e6346b88f934fef993428aa9e0448475094d28e3..4384be9a6888776baffce9b20393bbb59f830aa6 100644 (file)
@@ -16,7 +16,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
index aac66434e4739d69610eaf80dc43f7893fa8dbd0..13db942812e467dce28864a1647455f47418bbf2 100644 (file)
@@ -20,7 +20,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
index ef401bd6ea0036765594ed3a122b8ec4341c0824..10ece5a47522c86763809428e994bca9df295b39 100644 (file)
@@ -16,7 +16,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
index a8b8873aa263f181c0f722d37ceeb96ba3feef9b..4c33bf5c8354df31023de03c679b7ee6b02b642f 100644 (file)
@@ -19,7 +19,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
index 77ac27e811615a2e801f22c188d59762bf0ae431..4f3764546b2fe1eae1d4aef2582d97c807c120e4 100644 (file)
@@ -18,7 +18,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
index 7db92ced2c02223b0de90bac9f95c1ddfa0939bb..cedff8068fbc17b3e4fe8f994ac5fc3f1ed22956 100644 (file)
@@ -18,7 +18,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
index 65ffa981510add944657bac1a9e766425da732cf..1bba87e7860943ac444d6f55b4aa78fa8c5dad30 100644 (file)
@@ -18,7 +18,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
index 559302d3fe66264611100da2352010ebe0580897..0a79d9aeb08caed52652b38d65235d30f83279c1 100644 (file)
@@ -18,7 +18,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
index 8ba703da2797493be2e007fd23e9ca0a53fb1b11..01554b996b9b9ceeb19152c8b175474fca2fc668 100644 (file)
@@ -17,7 +17,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
index d058b467f9e450e7c2f1a331a3be18298c8c61ec..40c28efaed9552c788cf968e96c57449d3849004 100644 (file)
@@ -28,7 +28,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
index 957e04feb0f71dbb1492121d93998dde4fb62d83..565cbf0421cd69124e372aa9274ef9a43b3da393 100644 (file)
@@ -17,7 +17,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
 #include <net/irda/irda.h>             /* irda_debug */
 #include <net/irda/irias_object.h>
 
-#define NET_IRDA 412 /* Random number */
-enum { DISCOVERY=1, DEVNAME, DEBUG, FAST_POLL, DISCOVERY_SLOTS,
-       DISCOVERY_TIMEOUT, SLOT_TIMEOUT, MAX_BAUD_RATE, MIN_TX_TURN_TIME,
-       MAX_TX_DATA_SIZE, MAX_TX_WINDOW, MAX_NOREPLY_TIME, WARN_NOREPLY_TIME,
-       LAP_KEEPALIVE_TIME };
-
 extern int  sysctl_discovery;
 extern int  sysctl_discovery_slots;
 extern int  sysctl_discovery_timeout;
@@ -94,7 +88,7 @@ static int do_devname(ctl_table *table, int write, struct file *filp,
 /* One file */
 static ctl_table irda_table[] = {
        {
-               .ctl_name       = DISCOVERY,
+               .ctl_name       = NET_IRDA_DISCOVERY,
                .procname       = "discovery",
                .data           = &sysctl_discovery,
                .maxlen         = sizeof(int),
@@ -102,7 +96,7 @@ static ctl_table irda_table[] = {
                .proc_handler   = &proc_dointvec
        },
        {
-               .ctl_name       = DEVNAME,
+               .ctl_name       = NET_IRDA_DEVNAME,
                .procname       = "devname",
                .data           = sysctl_devname,
                .maxlen         = 65,
@@ -112,7 +106,7 @@ static ctl_table irda_table[] = {
        },
 #ifdef CONFIG_IRDA_DEBUG
        {
-               .ctl_name       = DEBUG,
+               .ctl_name       = NET_IRDA_DEBUG,
                .procname       = "debug",
                .data           = &irda_debug,
                .maxlen         = sizeof(int),
@@ -122,7 +116,7 @@ static ctl_table irda_table[] = {
 #endif
 #ifdef CONFIG_IRDA_FAST_RR
        {
-               .ctl_name       = FAST_POLL,
+               .ctl_name       = NET_IRDA_FAST_POLL,
                .procname       = "fast_poll_increase",
                .data           = &sysctl_fast_poll_increase,
                .maxlen         = sizeof(int),
@@ -131,7 +125,7 @@ static ctl_table irda_table[] = {
        },
 #endif
        {
-               .ctl_name       = DISCOVERY_SLOTS,
+               .ctl_name       = NET_IRDA_DISCOVERY_SLOTS,
                .procname       = "discovery_slots",
                .data           = &sysctl_discovery_slots,
                .maxlen         = sizeof(int),
@@ -142,7 +136,7 @@ static ctl_table irda_table[] = {
                .extra2         = &max_discovery_slots
        },
        {
-               .ctl_name       = DISCOVERY_TIMEOUT,
+               .ctl_name       = NET_IRDA_DISCOVERY_TIMEOUT,
                .procname       = "discovery_timeout",
                .data           = &sysctl_discovery_timeout,
                .maxlen         = sizeof(int),
@@ -150,7 +144,7 @@ static ctl_table irda_table[] = {
                .proc_handler   = &proc_dointvec
        },
        {
-               .ctl_name       = SLOT_TIMEOUT,
+               .ctl_name       = NET_IRDA_SLOT_TIMEOUT,
                .procname       = "slot_timeout",
                .data           = &sysctl_slot_timeout,
                .maxlen         = sizeof(int),
@@ -161,7 +155,7 @@ static ctl_table irda_table[] = {
                .extra2         = &max_slot_timeout
        },
        {
-               .ctl_name       = MAX_BAUD_RATE,
+               .ctl_name       = NET_IRDA_MAX_BAUD_RATE,
                .procname       = "max_baud_rate",
                .data           = &sysctl_max_baud_rate,
                .maxlen         = sizeof(int),
@@ -172,7 +166,7 @@ static ctl_table irda_table[] = {
                .extra2         = &max_max_baud_rate
        },
        {
-               .ctl_name       = MIN_TX_TURN_TIME,
+               .ctl_name       = NET_IRDA_MIN_TX_TURN_TIME,
                .procname       = "min_tx_turn_time",
                .data           = &sysctl_min_tx_turn_time,
                .maxlen         = sizeof(int),
@@ -183,7 +177,7 @@ static ctl_table irda_table[] = {
                .extra2         = &max_min_tx_turn_time
        },
        {
-               .ctl_name       = MAX_TX_DATA_SIZE,
+               .ctl_name       = NET_IRDA_MAX_TX_DATA_SIZE,
                .procname       = "max_tx_data_size",
                .data           = &sysctl_max_tx_data_size,
                .maxlen         = sizeof(int),
@@ -194,7 +188,7 @@ static ctl_table irda_table[] = {
                .extra2         = &max_max_tx_data_size
        },
        {
-               .ctl_name       = MAX_TX_WINDOW,
+               .ctl_name       = NET_IRDA_MAX_TX_WINDOW,
                .procname       = "max_tx_window",
                .data           = &sysctl_max_tx_window,
                .maxlen         = sizeof(int),
@@ -205,7 +199,7 @@ static ctl_table irda_table[] = {
                .extra2         = &max_max_tx_window
        },
        {
-               .ctl_name       = MAX_NOREPLY_TIME,
+               .ctl_name       = NET_IRDA_MAX_NOREPLY_TIME,
                .procname       = "max_noreply_time",
                .data           = &sysctl_max_noreply_time,
                .maxlen         = sizeof(int),
@@ -216,7 +210,7 @@ static ctl_table irda_table[] = {
                .extra2         = &max_max_noreply_time
        },
        {
-               .ctl_name       = WARN_NOREPLY_TIME,
+               .ctl_name       = NET_IRDA_WARN_NOREPLY_TIME,
                .procname       = "warn_noreply_time",
                .data           = &sysctl_warn_noreply_time,
                .maxlen         = sizeof(int),
@@ -227,7 +221,7 @@ static ctl_table irda_table[] = {
                .extra2         = &max_warn_noreply_time
        },
        {
-               .ctl_name       = LAP_KEEPALIVE_TIME,
+               .ctl_name       = NET_IRDA_LAP_KEEPALIVE_TIME,
                .procname       = "lap_keepalive_time",
                .data           = &sysctl_lap_keepalive_time,
                .maxlen         = sizeof(int),
index 1311976c9dfeba0358e599e7f15e01b8ce8f3f97..97db158c92748dfe55de4e43a0f8a3682a970db2 100644 (file)
@@ -18,7 +18,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
index d3a6ee8cc4a281a60baa7522278294a3d5799e03..d730099080a28acabb81957840c11e5be7e10445 100644 (file)
@@ -18,7 +18,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
index a7a7f191f1a86c94437b464f02fdaa5097787ba0..e71286768a480994141f6d9b97b270c212112ccf 100644 (file)
@@ -20,7 +20,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
index 983058d432dc8c613f63a48af80db1997679dd3f..a2f5a6ea389520832c86c8b5e1f9c907de518796 100644 (file)
@@ -389,7 +389,7 @@ static void iucv_block_cpu(void *data)
  * iucv_declare_cpu
  * @data: unused
  *
- * Declare a interupt buffer on this cpu.
+ * Declare a interrupt buffer on this cpu.
  */
 static void iucv_declare_cpu(void *data)
 {
index 49eacba824df5bfdf1905c1df6e5503eaf15326d..46cf962f7f8889f049a3b0406f9f5f3b6c31034c 100644 (file)
@@ -762,7 +762,7 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,
                        if (net_ratelimit())
                                printk(KERN_DEBUG "LLC(%s:%d): Application "
                                                  "bug, race in MSG_PEEK.\n",
-                                      current->comm, current->pid);
+                                      current->comm, task_pid_nr(current));
                        peek_seq = llc->copied_seq;
                }
                continue;
index d34a9deca67ad25bc36c44c3422dae6128548e42..4b4ed2a5803c46f8e86ae550f9431fb4044e2a34 100644 (file)
@@ -37,8 +37,6 @@
 
 struct ieee80211_local;
 
-#define BIT(x) (1 << (x))
-
 #define IEEE80211_ALIGN32_PAD(a) ((4 - ((a) & 3)) & 3)
 
 /* Maximum number of broadcast/multicast frames to buffer when some of the
index f0224c2311d29a9df5826bfe46def0a93cf3866f..6caa3ec2cff7798ef13e1f604fc8bdfff50a0c4c 100644 (file)
@@ -306,9 +306,12 @@ int ieee80211_set_channel(struct ieee80211_local *local, int channel, int freq)
                            ((chan->chan == channel) || (chan->freq == freq))) {
                                local->oper_channel = chan;
                                local->oper_hw_mode = mode;
-                               set++;
+                               set = 1;
+                               break;
                        }
                }
+               if (set)
+                       break;
        }
 
        if (set) {
@@ -508,10 +511,11 @@ static int ieee80211_ioctl_giwap(struct net_device *dev,
 
 static int ieee80211_ioctl_siwscan(struct net_device *dev,
                                   struct iw_request_info *info,
-                                  struct iw_point *data, char *extra)
+                                  union iwreq_data *wrqu, char *extra)
 {
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       struct iw_scan_req *req = NULL;
        u8 *ssid = NULL;
        size_t ssid_len = 0;
 
@@ -536,6 +540,14 @@ static int ieee80211_ioctl_siwscan(struct net_device *dev,
                return -EOPNOTSUPP;
        }
 
+       /* if SSID was specified explicitly then use that */
+       if (wrqu->data.length == sizeof(struct iw_scan_req) &&
+           wrqu->data.flags & IW_SCAN_THIS_ESSID) {
+               req = (struct iw_scan_req *)extra;
+               ssid = req->essid;
+               ssid_len = req->essid_len;
+       }
+
        return ieee80211_sta_req_scan(dev, ssid, ssid_len);
 }
 
index 1641e8fe44b715e9b8d3832273d90d7df499b4a4..f7ffeec3913f3691d662663977ebe45e04ac2e89 100644 (file)
@@ -12,7 +12,6 @@
  */
 
 /* TODO:
- * BSS table: use <BSSID,SSID> as the key to support multi-SSID APs
  * order BSS list by RSSI(?) ("quality of AP")
  * scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE,
  *    SSID)
@@ -61,7 +60,8 @@
 static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst,
                                     u8 *ssid, size_t ssid_len);
 static struct ieee80211_sta_bss *
-ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid);
+ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel,
+                    u8 *ssid, u8 ssid_len);
 static void ieee80211_rx_bss_put(struct net_device *dev,
                                 struct ieee80211_sta_bss *bss);
 static int ieee80211_sta_find_ibss(struct net_device *dev,
@@ -108,14 +108,11 @@ struct ieee802_11_elems {
        u8 wmm_param_len;
 };
 
-enum ParseRes { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 };
-
-static enum ParseRes ieee802_11_parse_elems(u8 *start, size_t len,
-                                           struct ieee802_11_elems *elems)
+static void ieee802_11_parse_elems(u8 *start, size_t len,
+                                  struct ieee802_11_elems *elems)
 {
        size_t left = len;
        u8 *pos = start;
-       int unknown = 0;
 
        memset(elems, 0, sizeof(*elems));
 
@@ -126,15 +123,8 @@ static enum ParseRes ieee802_11_parse_elems(u8 *start, size_t len,
                elen = *pos++;
                left -= 2;
 
-               if (elen > left) {
-#if 0
-                       if (net_ratelimit())
-                               printk(KERN_DEBUG "IEEE 802.11 element parse "
-                                      "failed (id=%d elen=%d left=%d)\n",
-                                      id, elen, left);
-#endif
-                       return ParseFailed;
-               }
+               if (elen > left)
+                       return;
 
                switch (id) {
                case WLAN_EID_SSID:
@@ -201,28 +191,15 @@ static enum ParseRes ieee802_11_parse_elems(u8 *start, size_t len,
                        elems->ext_supp_rates_len = elen;
                        break;
                default:
-#if 0
-                       printk(KERN_DEBUG "IEEE 802.11 element parse ignored "
-                                     "unknown element (id=%d elen=%d)\n",
-                                     id, elen);
-#endif
-                       unknown++;
                        break;
                }
 
                left -= elen;
                pos += elen;
        }
-
-       /* Do not trigger error if left == 1 as Apple Airport base stations
-        * send AssocResps that are one spurious byte too long. */
-
-       return unknown ? ParseUnknown : ParseOK;
 }
 
 
-
-
 static int ecw2cw(int ecw)
 {
        int cw = 1;
@@ -427,7 +404,9 @@ static void ieee80211_set_associated(struct net_device *dev,
                if (sdata->type != IEEE80211_IF_TYPE_STA)
                        return;
 
-               bss = ieee80211_rx_bss_get(dev, ifsta->bssid);
+               bss = ieee80211_rx_bss_get(dev, ifsta->bssid,
+                                          local->hw.conf.channel,
+                                          ifsta->ssid, ifsta->ssid_len);
                if (bss) {
                        if (bss->has_erp_value)
                                ieee80211_handle_erp_ie(dev, bss->erp_value);
@@ -574,7 +553,8 @@ static void ieee80211_send_assoc(struct net_device *dev,
                capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME |
                        WLAN_CAPABILITY_SHORT_PREAMBLE;
        }
-       bss = ieee80211_rx_bss_get(dev, ifsta->bssid);
+       bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel,
+                                  ifsta->ssid, ifsta->ssid_len);
        if (bss) {
                if (bss->capability & WLAN_CAPABILITY_PRIVACY)
                        capab |= WLAN_CAPABILITY_PRIVACY;
@@ -722,6 +702,7 @@ static void ieee80211_send_disassoc(struct net_device *dev,
 static int ieee80211_privacy_mismatch(struct net_device *dev,
                                      struct ieee80211_if_sta *ifsta)
 {
+       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_sta_bss *bss;
        int res = 0;
 
@@ -729,7 +710,8 @@ static int ieee80211_privacy_mismatch(struct net_device *dev,
            ifsta->key_management_enabled)
                return 0;
 
-       bss = ieee80211_rx_bss_get(dev, ifsta->bssid);
+       bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel,
+                                  ifsta->ssid, ifsta->ssid_len);
        if (!bss)
                return 0;
 
@@ -926,12 +908,7 @@ static void ieee80211_auth_challenge(struct net_device *dev,
 
        printk(KERN_DEBUG "%s: replying to auth challenge\n", dev->name);
        pos = mgmt->u.auth.variable;
-       if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems)
-           == ParseFailed) {
-               printk(KERN_DEBUG "%s: failed to parse Auth(challenge)\n",
-                      dev->name);
-               return;
-       }
+       ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
        if (!elems.challenge) {
                printk(KERN_DEBUG "%s: no challenge IE in shared key auth "
                       "frame\n", dev->name);
@@ -1203,15 +1180,11 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
        capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
        status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
        aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
-       if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
-               printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not "
-                      "set\n", dev->name, aid);
-       aid &= ~(BIT(15) | BIT(14));
 
        printk(KERN_DEBUG "%s: RX %sssocResp from %s (capab=0x%x "
               "status=%d aid=%d)\n",
               dev->name, reassoc ? "Rea" : "A", print_mac(mac, mgmt->sa),
-              capab_info, status_code, aid);
+              capab_info, status_code, aid & ~(BIT(15) | BIT(14)));
 
        if (status_code != WLAN_STATUS_SUCCESS) {
                printk(KERN_DEBUG "%s: AP denied association (code=%d)\n",
@@ -1223,13 +1196,13 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
                return;
        }
 
+       if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
+               printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not "
+                      "set\n", dev->name, aid);
+       aid &= ~(BIT(15) | BIT(14));
+
        pos = mgmt->u.assoc_resp.variable;
-       if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems)
-           == ParseFailed) {
-               printk(KERN_DEBUG "%s: failed to parse AssocResp\n",
-                      dev->name);
-               return;
-       }
+       ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
 
        if (!elems.supp_rates) {
                printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n",
@@ -1241,7 +1214,9 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
         * update our stored copy */
        if (elems.erp_info && elems.erp_info_len >= 1) {
                struct ieee80211_sta_bss *bss
-                       = ieee80211_rx_bss_get(dev, ifsta->bssid);
+                       = ieee80211_rx_bss_get(dev, ifsta->bssid,
+                                              local->hw.conf.channel,
+                                              ifsta->ssid, ifsta->ssid_len);
                if (bss) {
                        bss->erp_value = elems.erp_info[0];
                        bss->has_erp_value = 1;
@@ -1271,7 +1246,9 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
                               " AP\n", dev->name);
                        return;
                }
-               bss = ieee80211_rx_bss_get(dev, ifsta->bssid);
+               bss = ieee80211_rx_bss_get(dev, ifsta->bssid,
+                                          local->hw.conf.channel,
+                                          ifsta->ssid, ifsta->ssid_len);
                if (bss) {
                        sta->last_rssi = bss->rssi;
                        sta->last_signal = bss->signal;
@@ -1347,7 +1324,8 @@ static void __ieee80211_rx_bss_hash_del(struct net_device *dev,
 
 
 static struct ieee80211_sta_bss *
-ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid)
+ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel,
+                    u8 *ssid, u8 ssid_len)
 {
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_sta_bss *bss;
@@ -1358,6 +1336,11 @@ ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid)
        atomic_inc(&bss->users);
        atomic_inc(&bss->users);
        memcpy(bss->bssid, bssid, ETH_ALEN);
+       bss->channel = channel;
+       if (ssid && ssid_len <= IEEE80211_MAX_SSID_LEN) {
+               memcpy(bss->ssid, ssid, ssid_len);
+               bss->ssid_len = ssid_len;
+       }
 
        spin_lock_bh(&local->sta_bss_lock);
        /* TODO: order by RSSI? */
@@ -1369,7 +1352,8 @@ ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid)
 
 
 static struct ieee80211_sta_bss *
-ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid)
+ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel,
+                    u8 *ssid, u8 ssid_len)
 {
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_sta_bss *bss;
@@ -1377,7 +1361,10 @@ ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid)
        spin_lock_bh(&local->sta_bss_lock);
        bss = local->sta_bss_hash[STA_HASH(bssid)];
        while (bss) {
-               if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0) {
+               if (!memcmp(bss->bssid, bssid, ETH_ALEN) &&
+                   bss->channel == channel &&
+                   bss->ssid_len == ssid_len &&
+                   (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) {
                        atomic_inc(&bss->users);
                        break;
                }
@@ -1439,7 +1426,7 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee802_11_elems elems;
        size_t baselen;
-       int channel, invalid = 0, clen;
+       int channel, clen;
        struct ieee80211_sta_bss *bss;
        struct sta_info *sta;
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -1485,9 +1472,7 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
 #endif /* CONFIG_MAC80211_IBSS_DEBUG */
        }
 
-       if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen,
-                                  &elems) == ParseFailed)
-               invalid = 1;
+       ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems);
 
        if (sdata->type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates &&
            memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 &&
@@ -1545,9 +1530,11 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
        else
                channel = rx_status->channel;
 
-       bss = ieee80211_rx_bss_get(dev, mgmt->bssid);
+       bss = ieee80211_rx_bss_get(dev, mgmt->bssid, channel,
+                                  elems.ssid, elems.ssid_len);
        if (!bss) {
-               bss = ieee80211_rx_bss_add(dev, mgmt->bssid);
+               bss = ieee80211_rx_bss_add(dev, mgmt->bssid, channel,
+                                          elems.ssid, elems.ssid_len);
                if (!bss)
                        return;
        } else {
@@ -1573,10 +1560,6 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
 
        bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int);
        bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info);
-       if (elems.ssid && elems.ssid_len <= IEEE80211_MAX_SSID_LEN) {
-               memcpy(bss->ssid, elems.ssid, elems.ssid_len);
-               bss->ssid_len = elems.ssid_len;
-       }
 
        bss->supp_rates_len = 0;
        if (elems.supp_rates) {
@@ -1647,7 +1630,6 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
 
 
        bss->hw_mode = rx_status->phymode;
-       bss->channel = channel;
        bss->freq = rx_status->freq;
        if (channel != rx_status->channel &&
            (bss->hw_mode == MODE_IEEE80211G ||
@@ -1707,9 +1689,7 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev,
        if (baselen > len)
                return;
 
-       if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen,
-                                  &elems) == ParseFailed)
-               return;
+       ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems);
 
        if (elems.erp_info && elems.erp_info_len >= 1)
                ieee80211_handle_erp_ie(dev, elems.erp_info[0]);
@@ -2375,7 +2355,7 @@ static int ieee80211_sta_create_ibss(struct net_device *dev,
 {
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_sta_bss *bss;
-       struct ieee80211_sub_if_data *sdata;
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        struct ieee80211_hw_mode *mode;
        u8 bssid[ETH_ALEN], *pos;
        int i;
@@ -2398,18 +2378,17 @@ static int ieee80211_sta_create_ibss(struct net_device *dev,
        printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %s\n",
               dev->name, print_mac(mac, bssid));
 
-       bss = ieee80211_rx_bss_add(dev, bssid);
+       bss = ieee80211_rx_bss_add(dev, bssid, local->hw.conf.channel,
+                                  sdata->u.sta.ssid, sdata->u.sta.ssid_len);
        if (!bss)
                return -ENOMEM;
 
-       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        mode = local->oper_hw_mode;
 
        if (local->hw.conf.beacon_int == 0)
                local->hw.conf.beacon_int = 100;
        bss->beacon_int = local->hw.conf.beacon_int;
        bss->hw_mode = local->hw.conf.phymode;
-       bss->channel = local->hw.conf.channel;
        bss->freq = local->hw.conf.freq;
        bss->last_update = jiffies;
        bss->capability = WLAN_CAPABILITY_IBSS;
@@ -2469,7 +2448,8 @@ static int ieee80211_sta_find_ibss(struct net_device *dev,
               "%s\n", print_mac(mac, bssid), print_mac(mac2, ifsta->bssid));
 #endif /* CONFIG_MAC80211_IBSS_DEBUG */
        if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 &&
-           (bss = ieee80211_rx_bss_get(dev, bssid))) {
+           (bss = ieee80211_rx_bss_get(dev, bssid, local->hw.conf.channel,
+                                       ifsta->ssid, ifsta->ssid_len))) {
                printk(KERN_DEBUG "%s: Selected IBSS BSSID %s"
                       " based on configured SSID\n",
                       dev->name, print_mac(mac, bssid));
index 6675261e958f41abb0fc23a8bf3f3178e0364c8f..a84a23310ff4576116cab6dcb625f6e27bcb6ae4 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/crypto.h>
 #include <linux/err.h>
 #include <linux/mm.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 
 #include <net/mac80211.h>
 #include "ieee80211_i.h"
@@ -138,9 +138,7 @@ void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
        *icv = cpu_to_le32(~crc32_le(~0, data, data_len));
 
        crypto_blkcipher_setkey(tfm, rc4key, klen);
-       sg.page = virt_to_page(data);
-       sg.offset = offset_in_page(data);
-       sg.length = data_len + WEP_ICV_LEN;
+       sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
        crypto_blkcipher_encrypt(&desc, &sg, &sg, sg.length);
 }
 
@@ -204,9 +202,7 @@ int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
        __le32 crc;
 
        crypto_blkcipher_setkey(tfm, rc4key, klen);
-       sg.page = virt_to_page(data);
-       sg.offset = offset_in_page(data);
-       sg.length = data_len + WEP_ICV_LEN;
+       sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
        crypto_blkcipher_decrypt(&desc, &sg, &sg, sg.length);
 
        crc = cpu_to_le32(~crc32_le(~0, data, data_len));
index d8b501878d9fbf71f1c59fea03f748364fe52120..13f8191796420584c109b3f971093965ed91c08b 100644 (file)
@@ -70,7 +70,6 @@ static int new(struct nf_conn *conntrack, const struct sk_buff *skb,
 static struct ctl_table_header *generic_sysctl_header;
 static struct ctl_table generic_sysctl_table[] = {
        {
-               .ctl_name       = NET_NF_CONNTRACK_GENERIC_TIMEOUT,
                .procname       = "nf_conntrack_generic_timeout",
                .data           = &nf_ct_generic_timeout,
                .maxlen         = sizeof(unsigned int),
@@ -84,7 +83,6 @@ static struct ctl_table generic_sysctl_table[] = {
 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
 static struct ctl_table generic_compat_sysctl_table[] = {
        {
-               .ctl_name       = NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT,
                .procname       = "ip_conntrack_generic_timeout",
                .data           = &nf_ct_generic_timeout,
                .maxlen         = sizeof(unsigned int),
index 04192acc7c402f6ab7c8eca48e2fefabb12ea278..cb046751059278d602848b4126d530a37bc165bf 100644 (file)
@@ -476,7 +476,6 @@ static unsigned int sctp_sysctl_table_users;
 static struct ctl_table_header *sctp_sysctl_header;
 static struct ctl_table sctp_sysctl_table[] = {
        {
-               .ctl_name       = NET_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED,
                .procname       = "nf_conntrack_sctp_timeout_closed",
                .data           = &nf_ct_sctp_timeout_closed,
                .maxlen         = sizeof(unsigned int),
@@ -484,7 +483,6 @@ static struct ctl_table sctp_sysctl_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT,
                .procname       = "nf_conntrack_sctp_timeout_cookie_wait",
                .data           = &nf_ct_sctp_timeout_cookie_wait,
                .maxlen         = sizeof(unsigned int),
@@ -492,7 +490,6 @@ static struct ctl_table sctp_sysctl_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED,
                .procname       = "nf_conntrack_sctp_timeout_cookie_echoed",
                .data           = &nf_ct_sctp_timeout_cookie_echoed,
                .maxlen         = sizeof(unsigned int),
@@ -500,7 +497,6 @@ static struct ctl_table sctp_sysctl_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED,
                .procname       = "nf_conntrack_sctp_timeout_established",
                .data           = &nf_ct_sctp_timeout_established,
                .maxlen         = sizeof(unsigned int),
@@ -508,7 +504,6 @@ static struct ctl_table sctp_sysctl_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT,
                .procname       = "nf_conntrack_sctp_timeout_shutdown_sent",
                .data           = &nf_ct_sctp_timeout_shutdown_sent,
                .maxlen         = sizeof(unsigned int),
@@ -516,7 +511,6 @@ static struct ctl_table sctp_sysctl_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD,
                .procname       = "nf_conntrack_sctp_timeout_shutdown_recd",
                .data           = &nf_ct_sctp_timeout_shutdown_recd,
                .maxlen         = sizeof(unsigned int),
@@ -524,7 +518,6 @@ static struct ctl_table sctp_sysctl_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT,
                .procname       = "nf_conntrack_sctp_timeout_shutdown_ack_sent",
                .data           = &nf_ct_sctp_timeout_shutdown_ack_sent,
                .maxlen         = sizeof(unsigned int),
@@ -539,7 +532,6 @@ static struct ctl_table sctp_sysctl_table[] = {
 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
 static struct ctl_table sctp_compat_sysctl_table[] = {
        {
-               .ctl_name       = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED,
                .procname       = "ip_conntrack_sctp_timeout_closed",
                .data           = &nf_ct_sctp_timeout_closed,
                .maxlen         = sizeof(unsigned int),
@@ -547,7 +539,6 @@ static struct ctl_table sctp_compat_sysctl_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT,
                .procname       = "ip_conntrack_sctp_timeout_cookie_wait",
                .data           = &nf_ct_sctp_timeout_cookie_wait,
                .maxlen         = sizeof(unsigned int),
@@ -555,7 +546,6 @@ static struct ctl_table sctp_compat_sysctl_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED,
                .procname       = "ip_conntrack_sctp_timeout_cookie_echoed",
                .data           = &nf_ct_sctp_timeout_cookie_echoed,
                .maxlen         = sizeof(unsigned int),
@@ -563,7 +553,6 @@ static struct ctl_table sctp_compat_sysctl_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED,
                .procname       = "ip_conntrack_sctp_timeout_established",
                .data           = &nf_ct_sctp_timeout_established,
                .maxlen         = sizeof(unsigned int),
@@ -571,7 +560,6 @@ static struct ctl_table sctp_compat_sysctl_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT,
                .procname       = "ip_conntrack_sctp_timeout_shutdown_sent",
                .data           = &nf_ct_sctp_timeout_shutdown_sent,
                .maxlen         = sizeof(unsigned int),
@@ -579,7 +567,6 @@ static struct ctl_table sctp_compat_sysctl_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD,
                .procname       = "ip_conntrack_sctp_timeout_shutdown_recd",
                .data           = &nf_ct_sctp_timeout_shutdown_recd,
                .maxlen         = sizeof(unsigned int),
@@ -587,7 +574,6 @@ static struct ctl_table sctp_compat_sysctl_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT,
                .procname       = "ip_conntrack_sctp_timeout_shutdown_ack_sent",
                .data           = &nf_ct_sctp_timeout_shutdown_ack_sent,
                .maxlen         = sizeof(unsigned int),
index c7075345971b000d6396fd07b4c710fcefc22227..7a3f64c1aca6f346581c0ef0bc54427f2fb75d14 100644 (file)
@@ -834,10 +834,12 @@ static int tcp_packet(struct nf_conn *conntrack,
        case TCP_CONNTRACK_SYN_SENT:
                if (old_state < TCP_CONNTRACK_TIME_WAIT)
                        break;
-               if (conntrack->proto.tcp.seen[!dir].flags &
-                       IP_CT_TCP_FLAG_CLOSE_INIT) {
-                       /* Attempt to reopen a closed connection.
-                       * Delete this connection and look up again. */
+               if ((conntrack->proto.tcp.seen[!dir].flags &
+                       IP_CT_TCP_FLAG_CLOSE_INIT)
+                   || (conntrack->proto.tcp.last_dir == dir
+                       && conntrack->proto.tcp.last_index == TCP_RST_SET)) {
+                       /* Attempt to reopen a closed/aborted connection.
+                        * Delete this connection and look up again. */
                        write_unlock_bh(&tcp_lock);
                        if (del_timer(&conntrack->timeout))
                                conntrack->timeout.function((unsigned long)
@@ -925,6 +927,7 @@ static int tcp_packet(struct nf_conn *conntrack,
      in_window:
        /* From now on we have got in-window packets */
        conntrack->proto.tcp.last_index = index;
+       conntrack->proto.tcp.last_dir = dir;
 
        pr_debug("tcp_conntracks: ");
        NF_CT_DUMP_TUPLE(tuple);
@@ -1162,7 +1165,6 @@ static unsigned int tcp_sysctl_table_users;
 static struct ctl_table_header *tcp_sysctl_header;
 static struct ctl_table tcp_sysctl_table[] = {
        {
-               .ctl_name       = NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT,
                .procname       = "nf_conntrack_tcp_timeout_syn_sent",
                .data           = &nf_ct_tcp_timeout_syn_sent,
                .maxlen         = sizeof(unsigned int),
@@ -1170,7 +1172,6 @@ static struct ctl_table tcp_sysctl_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV,
                .procname       = "nf_conntrack_tcp_timeout_syn_recv",
                .data           = &nf_ct_tcp_timeout_syn_recv,
                .maxlen         = sizeof(unsigned int),
@@ -1178,7 +1179,6 @@ static struct ctl_table tcp_sysctl_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED,
                .procname       = "nf_conntrack_tcp_timeout_established",
                .data           = &nf_ct_tcp_timeout_established,
                .maxlen         = sizeof(unsigned int),
@@ -1186,7 +1186,6 @@ static struct ctl_table tcp_sysctl_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT,
                .procname       = "nf_conntrack_tcp_timeout_fin_wait",
                .data           = &nf_ct_tcp_timeout_fin_wait,
                .maxlen         = sizeof(unsigned int),
@@ -1194,7 +1193,6 @@ static struct ctl_table tcp_sysctl_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT,
                .procname       = "nf_conntrack_tcp_timeout_close_wait",
                .data           = &nf_ct_tcp_timeout_close_wait,
                .maxlen         = sizeof(unsigned int),
@@ -1202,7 +1200,6 @@ static struct ctl_table tcp_sysctl_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK,
                .procname       = "nf_conntrack_tcp_timeout_last_ack",
                .data           = &nf_ct_tcp_timeout_last_ack,
                .maxlen         = sizeof(unsigned int),
@@ -1210,7 +1207,6 @@ static struct ctl_table tcp_sysctl_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT,
                .procname       = "nf_conntrack_tcp_timeout_time_wait",
                .data           = &nf_ct_tcp_timeout_time_wait,
                .maxlen         = sizeof(unsigned int),
@@ -1218,7 +1214,6 @@ static struct ctl_table tcp_sysctl_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE,
                .procname       = "nf_conntrack_tcp_timeout_close",
                .data           = &nf_ct_tcp_timeout_close,
                .maxlen         = sizeof(unsigned int),
@@ -1226,7 +1221,6 @@ static struct ctl_table tcp_sysctl_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS,
                .procname       = "nf_conntrack_tcp_timeout_max_retrans",
                .data           = &nf_ct_tcp_timeout_max_retrans,
                .maxlen         = sizeof(unsigned int),
@@ -1265,7 +1259,6 @@ static struct ctl_table tcp_sysctl_table[] = {
 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
 static struct ctl_table tcp_compat_sysctl_table[] = {
        {
-               .ctl_name       = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT,
                .procname       = "ip_conntrack_tcp_timeout_syn_sent",
                .data           = &nf_ct_tcp_timeout_syn_sent,
                .maxlen         = sizeof(unsigned int),
@@ -1273,7 +1266,6 @@ static struct ctl_table tcp_compat_sysctl_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV,
                .procname       = "ip_conntrack_tcp_timeout_syn_recv",
                .data           = &nf_ct_tcp_timeout_syn_recv,
                .maxlen         = sizeof(unsigned int),
@@ -1281,7 +1273,6 @@ static struct ctl_table tcp_compat_sysctl_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED,
                .procname       = "ip_conntrack_tcp_timeout_established",
                .data           = &nf_ct_tcp_timeout_established,
                .maxlen         = sizeof(unsigned int),
@@ -1289,7 +1280,6 @@ static struct ctl_table tcp_compat_sysctl_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT,
                .procname       = "ip_conntrack_tcp_timeout_fin_wait",
                .data           = &nf_ct_tcp_timeout_fin_wait,
                .maxlen         = sizeof(unsigned int),
@@ -1297,7 +1287,6 @@ static struct ctl_table tcp_compat_sysctl_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT,
                .procname       = "ip_conntrack_tcp_timeout_close_wait",
                .data           = &nf_ct_tcp_timeout_close_wait,
                .maxlen         = sizeof(unsigned int),
@@ -1305,7 +1294,6 @@ static struct ctl_table tcp_compat_sysctl_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK,
                .procname       = "ip_conntrack_tcp_timeout_last_ack",
                .data           = &nf_ct_tcp_timeout_last_ack,
                .maxlen         = sizeof(unsigned int),
@@ -1313,7 +1301,6 @@ static struct ctl_table tcp_compat_sysctl_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT,
                .procname       = "ip_conntrack_tcp_timeout_time_wait",
                .data           = &nf_ct_tcp_timeout_time_wait,
                .maxlen         = sizeof(unsigned int),
@@ -1321,7 +1308,6 @@ static struct ctl_table tcp_compat_sysctl_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE,
                .procname       = "ip_conntrack_tcp_timeout_close",
                .data           = &nf_ct_tcp_timeout_close,
                .maxlen         = sizeof(unsigned int),
@@ -1329,7 +1315,6 @@ static struct ctl_table tcp_compat_sysctl_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS,
                .procname       = "ip_conntrack_tcp_timeout_max_retrans",
                .data           = &nf_ct_tcp_timeout_max_retrans,
                .maxlen         = sizeof(unsigned int),
index ba80e1a1ea17fd740fae91cacde263106cec28d2..b3e7ecb080e624575bf630b13d52c8abd6000d0c 100644 (file)
@@ -146,7 +146,6 @@ static unsigned int udp_sysctl_table_users;
 static struct ctl_table_header *udp_sysctl_header;
 static struct ctl_table udp_sysctl_table[] = {
        {
-               .ctl_name       = NET_NF_CONNTRACK_UDP_TIMEOUT,
                .procname       = "nf_conntrack_udp_timeout",
                .data           = &nf_ct_udp_timeout,
                .maxlen         = sizeof(unsigned int),
@@ -154,7 +153,6 @@ static struct ctl_table udp_sysctl_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_NF_CONNTRACK_UDP_TIMEOUT_STREAM,
                .procname       = "nf_conntrack_udp_timeout_stream",
                .data           = &nf_ct_udp_timeout_stream,
                .maxlen         = sizeof(unsigned int),
@@ -168,7 +166,6 @@ static struct ctl_table udp_sysctl_table[] = {
 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
 static struct ctl_table udp_compat_sysctl_table[] = {
        {
-               .ctl_name       = NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT,
                .procname       = "ip_conntrack_udp_timeout",
                .data           = &nf_ct_udp_timeout,
                .maxlen         = sizeof(unsigned int),
@@ -176,7 +173,6 @@ static struct ctl_table udp_compat_sysctl_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT_STREAM,
                .procname       = "ip_conntrack_udp_timeout_stream",
                .data           = &nf_ct_udp_timeout_stream,
                .maxlen         = sizeof(unsigned int),
index 8cc324b159e9b30d55b735eb9ae377df2a0b193e..856793e8db7ace795fd543efaebd4932df388228 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/ip.h>
 #include <net/checksum.h>
 
-MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>");
+MODULE_AUTHOR("Henrik Nordstrom <hno@marasystems.com>");
 MODULE_DESCRIPTION("IP tables CONNMARK matching module");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_CONNMARK");
index af79423bc8e81a2d41884e2564a4651b65563bfc..9ec50139b9a177d559236790b3f0351c7ba9ef71 100644 (file)
@@ -2,13 +2,13 @@
  * GPL (C) 2002 Martin Devera (devik@cdi.cz).
  */
 #include <linux/module.h>
+#include <linux/bitops.h>
 #include <linux/skbuff.h>
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter/xt_connbytes.h>
 #include <net/netfilter/nf_conntrack.h>
 
 #include <asm/div64.h>
-#include <asm/bitops.h>
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
index 1071fc54d6d3c8811f4404773636ec15083d9cc3..9f67920af41fd54a3857701dbfc941abd26d823c 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter/xt_connmark.h>
 
-MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>");
+MODULE_AUTHOR("Henrik Nordstrom <hno@marasystems.com>");
 MODULE_DESCRIPTION("IP tables connmark match module");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_connmark");
index 4fcca797150f75d7fc673196476ff101dfeecb05..f263a77e57b729106a4b5948f74de7ccf566bae3 100644 (file)
@@ -1,5 +1,5 @@
-/* (C) 1999 Jérôme de Vivie <devivie@info.enserb.u-bordeaux.fr>
- * (C) 1999 Hervé Eychenne <eychenne@info.enserb.u-bordeaux.fr>
+/* (C) 1999 Jérôme de Vivie <devivie@info.enserb.u-bordeaux.fr>
+ * (C) 1999 Hervé Eychenne <eychenne@info.enserb.u-bordeaux.fr>
  *
  * 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
index f907770fd4e9097302ef8343f25401eec5eb6ee9..3358273a47b78f6567396de97619dab08a403ec6 100644 (file)
@@ -42,21 +42,21 @@ match_flags(const struct xt_sctp_flag_info *flag_info,
 static inline bool
 match_packet(const struct sk_buff *skb,
             unsigned int offset,
-            const u_int32_t *chunkmap,
-            int chunk_match_type,
-            const struct xt_sctp_flag_info *flag_info,
-            const int flag_count,
+            const struct xt_sctp_info *info,
             bool *hotdrop)
 {
        u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)];
        sctp_chunkhdr_t _sch, *sch;
+       int chunk_match_type = info->chunk_match_type;
+       const struct xt_sctp_flag_info *flag_info = info->flag_info;
+       int flag_count = info->flag_count;
 
 #ifdef DEBUG_SCTP
        int i = 0;
 #endif
 
        if (chunk_match_type == SCTP_CHUNK_MATCH_ALL)
-               SCTP_CHUNKMAP_COPY(chunkmapcopy, chunkmap);
+               SCTP_CHUNKMAP_COPY(chunkmapcopy, info->chunkmap);
 
        do {
                sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch);
@@ -73,7 +73,7 @@ match_packet(const struct sk_buff *skb,
 
                duprintf("skb->len: %d\toffset: %d\n", skb->len, offset);
 
-               if (SCTP_CHUNKMAP_IS_SET(chunkmap, sch->type)) {
+               if (SCTP_CHUNKMAP_IS_SET(info->chunkmap, sch->type)) {
                        switch (chunk_match_type) {
                        case SCTP_CHUNK_MATCH_ANY:
                                if (match_flags(flag_info, flag_count,
@@ -104,7 +104,7 @@ match_packet(const struct sk_buff *skb,
 
        switch (chunk_match_type) {
        case SCTP_CHUNK_MATCH_ALL:
-               return SCTP_CHUNKMAP_IS_CLEAR(chunkmap);
+               return SCTP_CHUNKMAP_IS_CLEAR(info->chunkmap);
        case SCTP_CHUNK_MATCH_ANY:
                return false;
        case SCTP_CHUNK_MATCH_ONLY:
@@ -148,9 +148,7 @@ match(const struct sk_buff *skb,
                        && ntohs(sh->dest) <= info->dpts[1],
                        XT_SCTP_DEST_PORTS, info->flags, info->invflags)
                && SCCHECK(match_packet(skb, protoff + sizeof (sctp_sctphdr_t),
-                                       info->chunkmap, info->chunk_match_type,
-                                       info->flag_info, info->flag_count,
-                                       hotdrop),
+                                       info, hotdrop),
                           XT_SCTP_CHUNK_TYPES, info->flags, info->invflags);
 }
 
index e11000a8e950950cd5a52ece4597c72761dc8d38..d0936506b731abf62d5fabffe289a44789c52768 100644 (file)
@@ -1623,11 +1623,6 @@ static struct vm_operations_struct packet_mmap_ops = {
        .close =packet_mm_close,
 };
 
-static inline struct page *pg_vec_endpage(char *one_pg_vec, unsigned int order)
-{
-       return virt_to_page(one_pg_vec + (PAGE_SIZE << order) - 1);
-}
-
 static void free_pg_vec(char **pg_vec, unsigned int order, unsigned int len)
 {
        int i;
index eaabf087c59b53e1dcf05af11647fdd2288d136a..d1e9d68f8ba0a003f0820f95800620d3030184cd 100644 (file)
@@ -146,18 +146,18 @@ static void rfkill_disconnect(struct input_handle *handle)
 static const struct input_device_id rfkill_ids[] = {
        {
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
-               .evbit = { BIT(EV_KEY) },
-               .keybit = { [LONG(KEY_WLAN)] = BIT(KEY_WLAN) },
+               .evbit = { BIT_MASK(EV_KEY) },
+               .keybit = { [BIT_WORD(KEY_WLAN)] = BIT_MASK(KEY_WLAN) },
        },
        {
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
-               .evbit = { BIT(EV_KEY) },
-               .keybit = { [LONG(KEY_BLUETOOTH)] = BIT(KEY_BLUETOOTH) },
+               .evbit = { BIT_MASK(EV_KEY) },
+               .keybit = { [BIT_WORD(KEY_BLUETOOTH)] = BIT_MASK(KEY_BLUETOOTH) },
        },
        {
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
-               .evbit = { BIT(EV_KEY) },
-               .keybit = { [LONG(KEY_UWB)] = BIT(KEY_UWB) },
+               .evbit = { BIT_MASK(EV_KEY) },
+               .keybit = { [BIT_WORD(KEY_UWB)] = BIT_MASK(KEY_UWB) },
        },
        { }
 };
index 92435a882fac6c61232a4a4064a33906932f0b9b..9c15c4888d1250481cc42dc58d59922915b25ca6 100644 (file)
@@ -2,9 +2,7 @@
 # Traffic control configuration.
 # 
 
-menu "QoS and/or fair queueing"
-
-config NET_SCHED
+menuconfig NET_SCHED
        bool "QoS and/or fair queueing"
        select NET_SCH_FIFO
        ---help---
@@ -41,9 +39,6 @@ config NET_SCHED
          The available schedulers are listed in the following questions; you
          can say Y to as many as you like. If unsure, say N now.
 
-config NET_SCH_FIFO
-       bool
-
 if NET_SCHED
 
 comment "Queueing/Scheduling"
@@ -500,4 +495,5 @@ config NET_CLS_IND
 
 endif # NET_SCHED
 
-endmenu
+config NET_SCH_FIFO
+       bool
index e9989610712ca2b8e68bc845623c28a5e78e8e5f..ceda8890ab0edae550482da852ffc72e68603770 100644 (file)
@@ -55,7 +55,7 @@
  *     ppp0..9.
  *
  *     NOTE: Certain meta values depend on other subsystems and are
- *           only available if that subsytem is enabled in the kernel.
+ *           only available if that subsystem is enabled in the kernel.
  */
 
 #include <linux/module.h>
index 95ae11956f35ebb931fc4bf20039df2c8ba1caf8..fa1a6f45dc416173f8b6d853f9ce0c5fa3565bc7 100644 (file)
@@ -249,10 +249,11 @@ static void dev_watchdog_down(struct net_device *dev)
  */
 void netif_carrier_on(struct net_device *dev)
 {
-       if (test_and_clear_bit(__LINK_STATE_NOCARRIER, &dev->state))
+       if (test_and_clear_bit(__LINK_STATE_NOCARRIER, &dev->state)) {
                linkwatch_fire_event(dev);
-       if (netif_running(dev))
-               __netdev_watchdog_up(dev);
+               if (netif_running(dev))
+                       __netdev_watchdog_up(dev);
+       }
 }
 
 /**
@@ -555,6 +556,7 @@ void dev_deactivate(struct net_device *dev)
 {
        struct Qdisc *qdisc;
        struct sk_buff *skb;
+       int running;
 
        spin_lock_bh(&dev->queue_lock);
        qdisc = dev->qdisc;
@@ -570,12 +572,31 @@ void dev_deactivate(struct net_device *dev)
 
        dev_watchdog_down(dev);
 
-       /* Wait for outstanding dev_queue_xmit calls. */
+       /* Wait for outstanding qdisc-less dev_queue_xmit calls. */
        synchronize_rcu();
 
        /* Wait for outstanding qdisc_run calls. */
-       while (test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state))
-               yield();
+       do {
+               while (test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state))
+                       yield();
+
+               /*
+                * Double-check inside queue lock to ensure that all effects
+                * of the queue run are visible when we return.
+                */
+               spin_lock_bh(&dev->queue_lock);
+               running = test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state);
+               spin_unlock_bh(&dev->queue_lock);
+
+               /*
+                * The running flag should never be set at this point because
+                * we've already set dev->qdisc to noop_qdisc *inside* the same
+                * pair of spin locks.  That is, if any qdisc_run starts after
+                * our initial test it should see the noop_qdisc and then
+                * clear the RUNNING bit before dropping the queue lock.  So
+                * if it is set here then we've found a bug.
+                */
+       } while (WARN_ON_ONCE(running));
 }
 
 void dev_init_scheduler(struct net_device *dev)
index be57cf317a7f0dfdaae0b09f2504346e6ba107d8..421281d9dd1d3f9103b17c71b68b0d927d3807da 100644 (file)
@@ -266,7 +266,7 @@ static int teql_master_xmit(struct sk_buff *skb, struct net_device *dev)
        int busy;
        int nores;
        int len = skb->len;
-       int subq = skb->queue_mapping;
+       int subq = skb_get_queue_mapping(skb);
        struct sk_buff *skb_res = NULL;
 
        start = master->slaves;
@@ -284,7 +284,7 @@ restart:
                if (slave->qdisc_sleeping != q)
                        continue;
                if (netif_queue_stopped(slave) ||
-                   netif_subqueue_stopped(slave, subq) ||
+                   __netif_subqueue_stopped(slave, subq) ||
                    !netif_running(slave)) {
                        busy = 1;
                        continue;
@@ -294,7 +294,7 @@ restart:
                case 0:
                        if (netif_tx_trylock(slave)) {
                                if (!netif_queue_stopped(slave) &&
-                                   !netif_subqueue_stopped(slave, subq) &&
+                                   !__netif_subqueue_stopped(slave, subq) &&
                                    slave->hard_start_xmit(skb, slave) == 0) {
                                        netif_tx_unlock(slave);
                                        master->slaves = NEXT_SLAVE(q);
index 781810724714aead5a11dce08853a35a82c59946..cbd64b216cce33a5e9a43e5fad24d4683a71a20d 100644 (file)
@@ -726,7 +726,8 @@ void sctp_auth_calculate_hmac(const struct sctp_association *asoc,
 
        /* set up scatter list */
        end = skb_tail_pointer(skb);
-       sg.page = virt_to_page(auth);
+       sg_init_table(&sg, 1);
+       sg_set_page(&sg, virt_to_page(auth));
        sg.offset = (unsigned long)(auth) % PAGE_SIZE;
        sg.length = end - (unsigned char *)auth;
 
index f983a369d4e2fa1ef95d0644e0a5c43974e43f2e..658476c4d58737b3f7f648ef5d66cff247485ede 100644 (file)
@@ -56,7 +56,7 @@
 #include <linux/ipv6.h>
 #include <linux/net.h>
 #include <linux/inet.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 #include <linux/crypto.h>
 #include <net/sock.h>
 
@@ -1513,7 +1513,8 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
                struct hash_desc desc;
 
                /* Sign the message.  */
-               sg.page = virt_to_page(&cookie->c);
+               sg_init_table(&sg, 1);
+               sg_set_page(&sg, virt_to_page(&cookie->c));
                sg.offset = (unsigned long)(&cookie->c) % PAGE_SIZE;
                sg.length = bodysize;
                keylen = SCTP_SECRET_SIZE;
@@ -1585,7 +1586,8 @@ struct sctp_association *sctp_unpack_cookie(
 
        /* Check the signature.  */
        keylen = SCTP_SECRET_SIZE;
-       sg.page = virt_to_page(bear_cookie);
+       sg_init_table(&sg, 1);
+       sg_set_page(&sg, virt_to_page(bear_cookie));
        sg.offset = (unsigned long)(bear_cookie) % PAGE_SIZE;
        sg.length = bodysize;
        key = (char *)ep->secret_key[ep->current_key];
index bfb6a29633ddb373f5f1fa42ceddb5a36a5a403a..32be431affcf2b80eac2147b313e09e4a0a9d1fc 100644 (file)
@@ -197,9 +197,9 @@ encryptor(struct scatterlist *sg, void *data)
                int i = (page_pos + outbuf->page_base) >> PAGE_CACHE_SHIFT;
                in_page = desc->pages[i];
        } else {
-               in_page = sg->page;
+               in_page = sg_page(sg);
        }
-       desc->infrags[desc->fragno].page = in_page;
+       sg_set_page(&desc->infrags[desc->fragno], in_page);
        desc->fragno++;
        desc->fraglen += sg->length;
        desc->pos += sg->length;
@@ -215,11 +215,11 @@ encryptor(struct scatterlist *sg, void *data)
        if (ret)
                return ret;
        if (fraglen) {
-               desc->outfrags[0].page = sg->page;
+               sg_set_page(&desc->outfrags[0], sg_page(sg));
                desc->outfrags[0].offset = sg->offset + sg->length - fraglen;
                desc->outfrags[0].length = fraglen;
                desc->infrags[0] = desc->outfrags[0];
-               desc->infrags[0].page = in_page;
+               sg_set_page(&desc->infrags[0], in_page);
                desc->fragno = 1;
                desc->fraglen = fraglen;
        } else {
@@ -287,7 +287,7 @@ decryptor(struct scatterlist *sg, void *data)
        if (ret)
                return ret;
        if (fraglen) {
-               desc->frags[0].page = sg->page;
+               sg_set_page(&desc->frags[0], sg_page(sg));
                desc->frags[0].offset = sg->offset + sg->length - fraglen;
                desc->frags[0].length = fraglen;
                desc->fragno = 1;
index 3c773c53e12e96e08207e50446a033132043e349..c98873f39aec49bc4d4af57f60f34d23a20123c4 100644 (file)
@@ -847,7 +847,7 @@ void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, int flags, cons
        task->tk_start = jiffies;
 
        dprintk("RPC:       new task initialized, procpid %u\n",
-                               current->pid);
+                               task_pid_nr(current));
 }
 
 static struct rpc_task *
index 738db32a287d0be1500e0f67d1ce3676f439783b..864b541bbf5171eb1a4b3338583af6dc2fe41c19 100644 (file)
@@ -114,7 +114,6 @@ done:
 
 static ctl_table debug_table[] = {
        {
-               .ctl_name       = CTL_RPCDEBUG,
                .procname       = "rpc_debug",
                .data           = &rpc_debug,
                .maxlen         = sizeof(int),
@@ -122,7 +121,6 @@ static ctl_table debug_table[] = {
                .proc_handler   = &proc_dodebug
        },
        {
-               .ctl_name       = CTL_NFSDEBUG,
                .procname       = "nfs_debug",
                .data           = &nfs_debug,
                .maxlen         = sizeof(int),
@@ -130,7 +128,6 @@ static ctl_table debug_table[] = {
                .proc_handler   = &proc_dodebug
        },
        {
-               .ctl_name       = CTL_NFSDDEBUG,
                .procname       = "nfsd_debug",
                .data           = &nfsd_debug,
                .maxlen         = sizeof(int),
@@ -138,7 +135,6 @@ static ctl_table debug_table[] = {
                .proc_handler   = &proc_dodebug
        },
        {
-               .ctl_name       = CTL_NLMDEBUG,
                .procname       = "nlm_debug",
                .data           = &nlm_debug,
                .maxlen         = sizeof(int),
index 6a59180e166718d309f7a2f98df0bb7fc31852d7..3d1f7cdf9dd015819e227bb1a1830b17ffd0972e 100644 (file)
@@ -1059,7 +1059,7 @@ xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len,
                do {
                        if (thislen > page_len)
                                thislen = page_len;
-                       sg->page = buf->pages[i];
+                       sg_set_page(sg, buf->pages[i]);
                        sg->offset = page_offset;
                        sg->length = thislen;
                        ret = actor(sg, data);
index 6996cba5aa9664ac99f706b626137d98fb99d286..9163ec526c2a0e66ed2fdf20f232173f6aed8d90 100644 (file)
@@ -483,7 +483,7 @@ static int unix_listen(struct socket *sock, int backlog)
        sk->sk_max_ack_backlog  = backlog;
        sk->sk_state            = TCP_LISTEN;
        /* set credentials so connect can copy them */
-       sk->sk_peercred.pid     = current->tgid;
+       sk->sk_peercred.pid     = task_tgid_vnr(current);
        sk->sk_peercred.uid     = current->euid;
        sk->sk_peercred.gid     = current->egid;
        err = 0;
@@ -1133,7 +1133,7 @@ restart:
        unix_peer(newsk)        = sk;
        newsk->sk_state         = TCP_ESTABLISHED;
        newsk->sk_type          = sk->sk_type;
-       newsk->sk_peercred.pid  = current->tgid;
+       newsk->sk_peercred.pid  = task_tgid_vnr(current);
        newsk->sk_peercred.uid  = current->euid;
        newsk->sk_peercred.gid  = current->egid;
        newu = unix_sk(newsk);
@@ -1194,7 +1194,7 @@ static int unix_socketpair(struct socket *socka, struct socket *sockb)
        sock_hold(skb);
        unix_peer(ska)=skb;
        unix_peer(skb)=ska;
-       ska->sk_peercred.pid = skb->sk_peercred.pid = current->tgid;
+       ska->sk_peercred.pid = skb->sk_peercred.pid = task_tgid_vnr(current);
        ska->sk_peercred.uid = skb->sk_peercred.uid = current->euid;
        ska->sk_peercred.gid = skb->sk_peercred.gid = current->egid;
 
index 5ced62c19c63e1d0a31d308ba7964229a7d2da5a..313d4bed3aa9444d9817aa6f57adacfa1d49d75f 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/pfkeyv2.h>
 #include <linux/crypto.h>
+#include <linux/scatterlist.h>
 #include <net/xfrm.h>
 #if defined(CONFIG_INET_AH) || defined(CONFIG_INET_AH_MODULE) || defined(CONFIG_INET6_AH) || defined(CONFIG_INET6_AH_MODULE)
 #include <net/ah.h>
@@ -552,7 +553,7 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
                if (copy > len)
                        copy = len;
 
-               sg.page = virt_to_page(skb->data + offset);
+               sg_set_page(&sg, virt_to_page(skb->data + offset));
                sg.offset = (unsigned long)(skb->data + offset) % PAGE_SIZE;
                sg.length = copy;
 
@@ -577,7 +578,7 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
                        if (copy > len)
                                copy = len;
 
-                       sg.page = frag->page;
+                       sg_set_page(&sg, frag->page);
                        sg.offset = frag->page_offset + offset-start;
                        sg.length = copy;
 
index 113f44429982d26ad4ffce161187cceaf0115073..cb97fda1b6dfa196aedea7e091599cb944b61950 100644 (file)
@@ -49,13 +49,16 @@ EXPORT_SYMBOL(secpath_dup);
 int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
 {
        int offset, offset_seq;
+       int hlen;
 
        switch (nexthdr) {
        case IPPROTO_AH:
+               hlen = sizeof(struct ip_auth_hdr);
                offset = offsetof(struct ip_auth_hdr, spi);
                offset_seq = offsetof(struct ip_auth_hdr, seq_no);
                break;
        case IPPROTO_ESP:
+               hlen = sizeof(struct ip_esp_hdr);
                offset = offsetof(struct ip_esp_hdr, spi);
                offset_seq = offsetof(struct ip_esp_hdr, seq_no);
                break;
@@ -69,7 +72,7 @@ int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
                return 1;
        }
 
-       if (!pskb_may_pull(skb, 16))
+       if (!pskb_may_pull(skb, hlen))
                return -EINVAL;
 
        *spi = *(__be32*)(skb_transport_header(skb) + offset);
index 0eb3377602e9c3c9b413072f1db6f0b5a915b8e5..f4bfd6c4565119f9f3be6cb80547922b930b4f73 100644 (file)
@@ -63,7 +63,7 @@ int xfrm_output(struct sk_buff *skb)
                                xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
                }
 
-               err = x->mode->output(x, skb);
+               err = x->outer_mode->output(x, skb);
                if (err)
                        goto error;
 
@@ -82,7 +82,7 @@ int xfrm_output(struct sk_buff *skb)
                }
                dst = skb->dst;
                x = dst->xfrm;
-       } while (x && (x->props.mode != XFRM_MODE_TUNNEL));
+       } while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL));
 
        err = 0;
 
index af27c193697c5ceede169a36588ed36cbd4e4abb..b702bd8a3893b7f2471df1c23df25a7105da70da 100644 (file)
@@ -49,8 +49,6 @@ static DEFINE_SPINLOCK(xfrm_policy_gc_lock);
 
 static struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family);
 static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo);
-static struct xfrm_policy_afinfo *xfrm_policy_lock_afinfo(unsigned int family);
-static void xfrm_policy_unlock_afinfo(struct xfrm_policy_afinfo *afinfo);
 
 static inline int
 __xfrm4_selector_match(struct xfrm_selector *sel, struct flowi *fl)
@@ -86,72 +84,6 @@ int xfrm_selector_match(struct xfrm_selector *sel, struct flowi *fl,
        return 0;
 }
 
-int xfrm_register_type(struct xfrm_type *type, unsigned short family)
-{
-       struct xfrm_policy_afinfo *afinfo = xfrm_policy_lock_afinfo(family);
-       struct xfrm_type **typemap;
-       int err = 0;
-
-       if (unlikely(afinfo == NULL))
-               return -EAFNOSUPPORT;
-       typemap = afinfo->type_map;
-
-       if (likely(typemap[type->proto] == NULL))
-               typemap[type->proto] = type;
-       else
-               err = -EEXIST;
-       xfrm_policy_unlock_afinfo(afinfo);
-       return err;
-}
-EXPORT_SYMBOL(xfrm_register_type);
-
-int xfrm_unregister_type(struct xfrm_type *type, unsigned short family)
-{
-       struct xfrm_policy_afinfo *afinfo = xfrm_policy_lock_afinfo(family);
-       struct xfrm_type **typemap;
-       int err = 0;
-
-       if (unlikely(afinfo == NULL))
-               return -EAFNOSUPPORT;
-       typemap = afinfo->type_map;
-
-       if (unlikely(typemap[type->proto] != type))
-               err = -ENOENT;
-       else
-               typemap[type->proto] = NULL;
-       xfrm_policy_unlock_afinfo(afinfo);
-       return err;
-}
-EXPORT_SYMBOL(xfrm_unregister_type);
-
-struct xfrm_type *xfrm_get_type(u8 proto, unsigned short family)
-{
-       struct xfrm_policy_afinfo *afinfo;
-       struct xfrm_type **typemap;
-       struct xfrm_type *type;
-       int modload_attempted = 0;
-
-retry:
-       afinfo = xfrm_policy_get_afinfo(family);
-       if (unlikely(afinfo == NULL))
-               return NULL;
-       typemap = afinfo->type_map;
-
-       type = typemap[proto];
-       if (unlikely(type && !try_module_get(type->owner)))
-               type = NULL;
-       if (!type && !modload_attempted) {
-               xfrm_policy_put_afinfo(afinfo);
-               request_module("xfrm-type-%d-%d",
-                              (int) family, (int) proto);
-               modload_attempted = 1;
-               goto retry;
-       }
-
-       xfrm_policy_put_afinfo(afinfo);
-       return type;
-}
-
 int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl,
                    unsigned short family)
 {
@@ -170,94 +102,6 @@ int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl,
 }
 EXPORT_SYMBOL(xfrm_dst_lookup);
 
-void xfrm_put_type(struct xfrm_type *type)
-{
-       module_put(type->owner);
-}
-
-int xfrm_register_mode(struct xfrm_mode *mode, int family)
-{
-       struct xfrm_policy_afinfo *afinfo;
-       struct xfrm_mode **modemap;
-       int err;
-
-       if (unlikely(mode->encap >= XFRM_MODE_MAX))
-               return -EINVAL;
-
-       afinfo = xfrm_policy_lock_afinfo(family);
-       if (unlikely(afinfo == NULL))
-               return -EAFNOSUPPORT;
-
-       err = -EEXIST;
-       modemap = afinfo->mode_map;
-       if (likely(modemap[mode->encap] == NULL)) {
-               modemap[mode->encap] = mode;
-               err = 0;
-       }
-
-       xfrm_policy_unlock_afinfo(afinfo);
-       return err;
-}
-EXPORT_SYMBOL(xfrm_register_mode);
-
-int xfrm_unregister_mode(struct xfrm_mode *mode, int family)
-{
-       struct xfrm_policy_afinfo *afinfo;
-       struct xfrm_mode **modemap;
-       int err;
-
-       if (unlikely(mode->encap >= XFRM_MODE_MAX))
-               return -EINVAL;
-
-       afinfo = xfrm_policy_lock_afinfo(family);
-       if (unlikely(afinfo == NULL))
-               return -EAFNOSUPPORT;
-
-       err = -ENOENT;
-       modemap = afinfo->mode_map;
-       if (likely(modemap[mode->encap] == mode)) {
-               modemap[mode->encap] = NULL;
-               err = 0;
-       }
-
-       xfrm_policy_unlock_afinfo(afinfo);
-       return err;
-}
-EXPORT_SYMBOL(xfrm_unregister_mode);
-
-struct xfrm_mode *xfrm_get_mode(unsigned int encap, int family)
-{
-       struct xfrm_policy_afinfo *afinfo;
-       struct xfrm_mode *mode;
-       int modload_attempted = 0;
-
-       if (unlikely(encap >= XFRM_MODE_MAX))
-               return NULL;
-
-retry:
-       afinfo = xfrm_policy_get_afinfo(family);
-       if (unlikely(afinfo == NULL))
-               return NULL;
-
-       mode = afinfo->mode_map[encap];
-       if (unlikely(mode && !try_module_get(mode->owner)))
-               mode = NULL;
-       if (!mode && !modload_attempted) {
-               xfrm_policy_put_afinfo(afinfo);
-               request_module("xfrm-mode-%d-%d", family, encap);
-               modload_attempted = 1;
-               goto retry;
-       }
-
-       xfrm_policy_put_afinfo(afinfo);
-       return mode;
-}
-
-void xfrm_put_mode(struct xfrm_mode *mode)
-{
-       module_put(mode->owner);
-}
-
 static inline unsigned long make_jiffies(long secs)
 {
        if (secs >= (MAX_SCHEDULE_TIMEOUT-1)/HZ)
@@ -2096,7 +1940,8 @@ int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first,
                if (xdst->genid != dst->xfrm->genid)
                        return 0;
 
-               if (strict && fl && dst->xfrm->props.mode != XFRM_MODE_TUNNEL &&
+               if (strict && fl &&
+                   !(dst->xfrm->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) &&
                    !xfrm_state_addr_flow_check(dst->xfrm, fl, family))
                        return 0;
 
@@ -2213,23 +2058,6 @@ static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo)
        read_unlock(&xfrm_policy_afinfo_lock);
 }
 
-static struct xfrm_policy_afinfo *xfrm_policy_lock_afinfo(unsigned int family)
-{
-       struct xfrm_policy_afinfo *afinfo;
-       if (unlikely(family >= NPROTO))
-               return NULL;
-       write_lock_bh(&xfrm_policy_afinfo_lock);
-       afinfo = xfrm_policy_afinfo[family];
-       if (unlikely(!afinfo))
-               write_unlock_bh(&xfrm_policy_afinfo_lock);
-       return afinfo;
-}
-
-static void xfrm_policy_unlock_afinfo(struct xfrm_policy_afinfo *afinfo)
-{
-       write_unlock_bh(&xfrm_policy_afinfo_lock);
-}
-
 static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
 {
        struct net_device *dev = ptr;
@@ -2464,7 +2292,8 @@ static int xfrm_policy_migrate(struct xfrm_policy *pol,
                        if (!migrate_tmpl_match(mp, &pol->xfrm_vec[i]))
                                continue;
                        n++;
-                       if (pol->xfrm_vec[i].mode != XFRM_MODE_TUNNEL)
+                       if (pol->xfrm_vec[i].mode != XFRM_MODE_TUNNEL &&
+                           pol->xfrm_vec[i].mode != XFRM_MODE_BEET)
                                continue;
                        /* update endpoints */
                        memcpy(&pol->xfrm_vec[i].id.daddr, &mp->new_daddr,
index 344f0a6abec53aacd0da9dfe9600854f130c5f7b..224b44e31a07b934091f79e42b85888ab143925f 100644 (file)
@@ -57,6 +57,9 @@ static unsigned int xfrm_state_hashmax __read_mostly = 1 * 1024 * 1024;
 static unsigned int xfrm_state_num;
 static unsigned int xfrm_state_genid;
 
+static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family);
+static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo);
+
 static inline unsigned int xfrm_dst_hash(xfrm_address_t *daddr,
                                         xfrm_address_t *saddr,
                                         u32 reqid,
@@ -187,6 +190,184 @@ int __xfrm_state_delete(struct xfrm_state *x);
 int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol);
 void km_state_expired(struct xfrm_state *x, int hard, u32 pid);
 
+static struct xfrm_state_afinfo *xfrm_state_lock_afinfo(unsigned int family)
+{
+       struct xfrm_state_afinfo *afinfo;
+       if (unlikely(family >= NPROTO))
+               return NULL;
+       write_lock_bh(&xfrm_state_afinfo_lock);
+       afinfo = xfrm_state_afinfo[family];
+       if (unlikely(!afinfo))
+               write_unlock_bh(&xfrm_state_afinfo_lock);
+       return afinfo;
+}
+
+static void xfrm_state_unlock_afinfo(struct xfrm_state_afinfo *afinfo)
+{
+       write_unlock_bh(&xfrm_state_afinfo_lock);
+}
+
+int xfrm_register_type(struct xfrm_type *type, unsigned short family)
+{
+       struct xfrm_state_afinfo *afinfo = xfrm_state_lock_afinfo(family);
+       struct xfrm_type **typemap;
+       int err = 0;
+
+       if (unlikely(afinfo == NULL))
+               return -EAFNOSUPPORT;
+       typemap = afinfo->type_map;
+
+       if (likely(typemap[type->proto] == NULL))
+               typemap[type->proto] = type;
+       else
+               err = -EEXIST;
+       xfrm_state_unlock_afinfo(afinfo);
+       return err;
+}
+EXPORT_SYMBOL(xfrm_register_type);
+
+int xfrm_unregister_type(struct xfrm_type *type, unsigned short family)
+{
+       struct xfrm_state_afinfo *afinfo = xfrm_state_lock_afinfo(family);
+       struct xfrm_type **typemap;
+       int err = 0;
+
+       if (unlikely(afinfo == NULL))
+               return -EAFNOSUPPORT;
+       typemap = afinfo->type_map;
+
+       if (unlikely(typemap[type->proto] != type))
+               err = -ENOENT;
+       else
+               typemap[type->proto] = NULL;
+       xfrm_state_unlock_afinfo(afinfo);
+       return err;
+}
+EXPORT_SYMBOL(xfrm_unregister_type);
+
+static struct xfrm_type *xfrm_get_type(u8 proto, unsigned short family)
+{
+       struct xfrm_state_afinfo *afinfo;
+       struct xfrm_type **typemap;
+       struct xfrm_type *type;
+       int modload_attempted = 0;
+
+retry:
+       afinfo = xfrm_state_get_afinfo(family);
+       if (unlikely(afinfo == NULL))
+               return NULL;
+       typemap = afinfo->type_map;
+
+       type = typemap[proto];
+       if (unlikely(type && !try_module_get(type->owner)))
+               type = NULL;
+       if (!type && !modload_attempted) {
+               xfrm_state_put_afinfo(afinfo);
+               request_module("xfrm-type-%d-%d", family, proto);
+               modload_attempted = 1;
+               goto retry;
+       }
+
+       xfrm_state_put_afinfo(afinfo);
+       return type;
+}
+
+static void xfrm_put_type(struct xfrm_type *type)
+{
+       module_put(type->owner);
+}
+
+int xfrm_register_mode(struct xfrm_mode *mode, int family)
+{
+       struct xfrm_state_afinfo *afinfo;
+       struct xfrm_mode **modemap;
+       int err;
+
+       if (unlikely(mode->encap >= XFRM_MODE_MAX))
+               return -EINVAL;
+
+       afinfo = xfrm_state_lock_afinfo(family);
+       if (unlikely(afinfo == NULL))
+               return -EAFNOSUPPORT;
+
+       err = -EEXIST;
+       modemap = afinfo->mode_map;
+       if (modemap[mode->encap])
+               goto out;
+
+       err = -ENOENT;
+       if (!try_module_get(afinfo->owner))
+               goto out;
+
+       mode->afinfo = afinfo;
+       modemap[mode->encap] = mode;
+       err = 0;
+
+out:
+       xfrm_state_unlock_afinfo(afinfo);
+       return err;
+}
+EXPORT_SYMBOL(xfrm_register_mode);
+
+int xfrm_unregister_mode(struct xfrm_mode *mode, int family)
+{
+       struct xfrm_state_afinfo *afinfo;
+       struct xfrm_mode **modemap;
+       int err;
+
+       if (unlikely(mode->encap >= XFRM_MODE_MAX))
+               return -EINVAL;
+
+       afinfo = xfrm_state_lock_afinfo(family);
+       if (unlikely(afinfo == NULL))
+               return -EAFNOSUPPORT;
+
+       err = -ENOENT;
+       modemap = afinfo->mode_map;
+       if (likely(modemap[mode->encap] == mode)) {
+               modemap[mode->encap] = NULL;
+               module_put(mode->afinfo->owner);
+               err = 0;
+       }
+
+       xfrm_state_unlock_afinfo(afinfo);
+       return err;
+}
+EXPORT_SYMBOL(xfrm_unregister_mode);
+
+static struct xfrm_mode *xfrm_get_mode(unsigned int encap, int family)
+{
+       struct xfrm_state_afinfo *afinfo;
+       struct xfrm_mode *mode;
+       int modload_attempted = 0;
+
+       if (unlikely(encap >= XFRM_MODE_MAX))
+               return NULL;
+
+retry:
+       afinfo = xfrm_state_get_afinfo(family);
+       if (unlikely(afinfo == NULL))
+               return NULL;
+
+       mode = afinfo->mode_map[encap];
+       if (unlikely(mode && !try_module_get(mode->owner)))
+               mode = NULL;
+       if (!mode && !modload_attempted) {
+               xfrm_state_put_afinfo(afinfo);
+               request_module("xfrm-mode-%d-%d", family, encap);
+               modload_attempted = 1;
+               goto retry;
+       }
+
+       xfrm_state_put_afinfo(afinfo);
+       return mode;
+}
+
+static void xfrm_put_mode(struct xfrm_mode *mode)
+{
+       module_put(mode->owner);
+}
+
 static void xfrm_state_gc_destroy(struct xfrm_state *x)
 {
        del_timer_sync(&x->timer);
@@ -196,8 +377,10 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x)
        kfree(x->calg);
        kfree(x->encap);
        kfree(x->coaddr);
-       if (x->mode)
-               xfrm_put_mode(x->mode);
+       if (x->inner_mode)
+               xfrm_put_mode(x->inner_mode);
+       if (x->outer_mode)
+               xfrm_put_mode(x->outer_mode);
        if (x->type) {
                x->type->destructor(x);
                xfrm_put_type(x->type);
@@ -1699,7 +1882,7 @@ int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo)
 }
 EXPORT_SYMBOL(xfrm_state_unregister_afinfo);
 
-struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family)
+static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family)
 {
        struct xfrm_state_afinfo *afinfo;
        if (unlikely(family >= NPROTO))
@@ -1711,14 +1894,11 @@ struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family)
        return afinfo;
 }
 
-void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo)
+static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo)
 {
        read_unlock(&xfrm_state_afinfo_lock);
 }
 
-EXPORT_SYMBOL(xfrm_state_get_afinfo);
-EXPORT_SYMBOL(xfrm_state_put_afinfo);
-
 /* Temporarily located here until net/xfrm/xfrm_tunnel.c is created */
 void xfrm_state_delete_tunnel(struct xfrm_state *x)
 {
@@ -1769,6 +1949,14 @@ int xfrm_init_state(struct xfrm_state *x)
                goto error;
 
        err = -EPROTONOSUPPORT;
+       x->inner_mode = xfrm_get_mode(x->props.mode, x->sel.family);
+       if (x->inner_mode == NULL)
+               goto error;
+
+       if (!(x->inner_mode->flags & XFRM_MODE_FLAG_TUNNEL) &&
+           family != x->sel.family)
+               goto error;
+
        x->type = xfrm_get_type(x->id.proto, family);
        if (x->type == NULL)
                goto error;
@@ -1777,8 +1965,8 @@ int xfrm_init_state(struct xfrm_state *x)
        if (err)
                goto error;
 
-       x->mode = xfrm_get_mode(x->props.mode, family);
-       if (x->mode == NULL)
+       x->outer_mode = xfrm_get_mode(x->props.mode, family);
+       if (x->outer_mode == NULL)
                goto error;
 
        x->km.state = XFRM_STATE_VALID;
diff --git a/samples/Kconfig b/samples/Kconfig
new file mode 100644 (file)
index 0000000..57bb223
--- /dev/null
@@ -0,0 +1,16 @@
+# samples/Kconfig
+
+menuconfig SAMPLES
+       bool "Sample kernel code"
+       help
+         You can build and test sample kernel code here.
+
+if SAMPLES
+
+config SAMPLE_MARKERS
+       tristate "Build markers examples -- loadable modules only"
+       depends on MARKERS && m
+       help
+         This build markers example modules.
+
+endif # SAMPLES
diff --git a/samples/Makefile b/samples/Makefile
new file mode 100644 (file)
index 0000000..5a4f0b6
--- /dev/null
@@ -0,0 +1,3 @@
+# Makefile for Linux samples code
+
+obj-$(CONFIG_SAMPLES)  += markers/
diff --git a/samples/markers/Makefile b/samples/markers/Makefile
new file mode 100644 (file)
index 0000000..6d72312
--- /dev/null
@@ -0,0 +1,4 @@
+# builds the kprobes example kernel modules;
+# then to use one (as root):  insmod <module_name.ko>
+
+obj-$(CONFIG_SAMPLE_MARKERS) += probe-example.o marker-example.o
diff --git a/samples/markers/marker-example.c b/samples/markers/marker-example.c
new file mode 100644 (file)
index 0000000..e787c6d
--- /dev/null
@@ -0,0 +1,54 @@
+/* marker-example.c
+ *
+ * Executes a marker when /proc/marker-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/marker.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+
+struct proc_dir_entry *pentry_example;
+
+static int my_open(struct inode *inode, struct file *file)
+{
+       int i;
+
+       trace_mark(subsystem_event, "%d %s", 123, "example string");
+       for (i = 0; i < 10; i++)
+               trace_mark(subsystem_eventb, MARK_NOARGS);
+       return -EPERM;
+}
+
+static struct file_operations mark_ops = {
+       .open = my_open,
+};
+
+static int example_init(void)
+{
+       printk(KERN_ALERT "example init\n");
+       pentry_example = create_proc_entry("marker-example", 0444, NULL);
+       if (pentry_example)
+               pentry_example->proc_fops = &mark_ops;
+       else
+               return -EPERM;
+       return 0;
+}
+
+static void example_exit(void)
+{
+       printk(KERN_ALERT "example exit\n");
+       remove_proc_entry("marker-example", NULL);
+}
+
+module_init(example_init)
+module_exit(example_exit)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Marker example");
diff --git a/samples/markers/probe-example.c b/samples/markers/probe-example.c
new file mode 100644 (file)
index 0000000..238b2e3
--- /dev/null
@@ -0,0 +1,98 @@
+/* probe-example.c
+ *
+ * Connects two functions to marker call sites.
+ *
+ * (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/sched.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/marker.h>
+#include <asm/atomic.h>
+
+struct probe_data {
+       const char *name;
+       const char *format;
+       marker_probe_func *probe_func;
+};
+
+void probe_subsystem_event(const struct marker *mdata, void *private,
+       const char *format, ...)
+{
+       va_list ap;
+       /* Declare args */
+       unsigned int value;
+       const char *mystr;
+
+       /* Assign args */
+       va_start(ap, format);
+       value = va_arg(ap, typeof(value));
+       mystr = va_arg(ap, typeof(mystr));
+
+       /* Call printk */
+       printk(KERN_DEBUG "Value %u, string %s\n", value, mystr);
+
+       /* or count, check rights, serialize data in a buffer */
+
+       va_end(ap);
+}
+
+atomic_t eventb_count = ATOMIC_INIT(0);
+
+void probe_subsystem_eventb(const struct marker *mdata, void *private,
+       const char *format, ...)
+{
+       /* Increment counter */
+       atomic_inc(&eventb_count);
+}
+
+static struct probe_data probe_array[] =
+{
+       {       .name = "subsystem_event",
+               .format = "%d %s",
+               .probe_func = probe_subsystem_event },
+       {       .name = "subsystem_eventb",
+               .format = MARK_NOARGS,
+               .probe_func = probe_subsystem_eventb },
+};
+
+static int __init probe_init(void)
+{
+       int result;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(probe_array); i++) {
+               result = marker_probe_register(probe_array[i].name,
+                               probe_array[i].format,
+                               probe_array[i].probe_func, &probe_array[i]);
+               if (result)
+                       printk(KERN_INFO "Unable to register probe %s\n",
+                               probe_array[i].name);
+               result = marker_arm(probe_array[i].name);
+               if (result)
+                       printk(KERN_INFO "Unable to arm probe %s\n",
+                               probe_array[i].name);
+       }
+       return 0;
+}
+
+static void __exit probe_fini(void)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(probe_array); i++)
+               marker_probe_unregister(probe_array[i].name);
+       printk(KERN_INFO "Number of event b : %u\n",
+                       atomic_read(&eventb_count));
+}
+
+module_init(probe_init);
+module_exit(probe_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("SUBSYSTEM Probe");
index de7bb284c6116d8ea3997ae224a25e3081aaf619..b96ea8d6a5ed0eb375a4db068cdb2c564407cd42 100644 (file)
@@ -56,6 +56,17 @@ endef
 # gcc support functions
 # See documentation in Documentation/kbuild/makefiles.txt
 
+# cc-cross-prefix
+# Usage: CROSS_COMPILE := $(call cc-cross-prefix, m68k-linux-gnu- m68k-linux-)
+# Return first prefix where a prefix$(CC) is found in PATH.
+# If no $(CC) found in PATH with listed prefixes return nothing
+cc-cross-prefix =  \
+       $(word 1, $(foreach c,$(1),                                   \
+               $(shell set -e;                                       \
+               if (which $(strip $(c))$(CC)) > /dev/null 2>&1 ; then \
+                       echo $(c);                                    \
+               fi)))
+
 # output directory for tests below
 TMPOUT := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/)
 
index e5c6ac7bde9b5778320ce1f99553c66c79a25826..0e4bd5459df4e08e90770516e942ba9236da3a22 100644 (file)
@@ -66,12 +66,15 @@ FILELINE * entity_system;
 #define FUNCTION      "-function"
 #define NOFUNCTION    "-nofunction"
 
+char *srctree;
+
 void usage (void)
 {
        fprintf(stderr, "Usage: docproc {doc|depend} file\n");
        fprintf(stderr, "Input is read from file.tmpl. Output is sent to stdout\n");
        fprintf(stderr, "doc: frontend when generating kernel documentation\n");
        fprintf(stderr, "depend: generate list of files referenced within file\n");
+       fprintf(stderr, "Environment variable SRCTREE: absolute path to kernel source tree.\n");
 }
 
 /*
@@ -90,7 +93,7 @@ void exec_kernel_doc(char **svec)
                        exit(1);
                case  0:
                        memset(real_filename, 0, sizeof(real_filename));
-                       strncat(real_filename, getenv("SRCTREE"), PATH_MAX);
+                       strncat(real_filename, srctree, PATH_MAX);
                        strncat(real_filename, KERNELDOCPATH KERNELDOC,
                                        PATH_MAX - strlen(real_filename));
                        execvp(real_filename, svec);
@@ -171,7 +174,7 @@ void find_export_symbols(char * filename)
        if (filename_exist(filename) == NULL) {
                char real_filename[PATH_MAX + 1];
                memset(real_filename, 0, sizeof(real_filename));
-               strncat(real_filename, getenv("SRCTREE"), PATH_MAX);
+               strncat(real_filename, srctree, PATH_MAX);
                strncat(real_filename, filename,
                                PATH_MAX - strlen(real_filename));
                sym = add_new_file(filename);
@@ -338,6 +341,10 @@ void parse_file(FILE *infile)
 int main(int argc, char *argv[])
 {
        FILE * infile;
+
+       srctree = getenv("SRCTREE");
+       if (!srctree)
+               srctree = getcwd(NULL, 0);
        if (argc != 3) {
                usage();
                exit(1);
index 59ad83caa210dd5d31af0bb76aa234e3dad0fca6..cbb42580a81d964a69efe153749d05b4d2ac2f27 100755 (executable)
@@ -9,7 +9,7 @@ use strict;
 my $P = $0;
 $P =~ s@.*/@@g;
 
-my $V = '0.10';
+my $V = '0.11';
 
 use Getopt::Long qw(:config no_auto_abbrev);
 
@@ -18,12 +18,21 @@ my $tree = 1;
 my $chk_signoff = 1;
 my $chk_patch = 1;
 my $tst_type = 0;
+my $emacs = 0;
+my $file = 0;
+my $check = 0;
+my $root;
 GetOptions(
-       'q|quiet      => \$quiet,
+       'q|quiet+'      => \$quiet,
        'tree!'         => \$tree,
        'signoff!'      => \$chk_signoff,
        'patch!'        => \$chk_patch,
        'test-type!'    => \$tst_type,
+       'emacs!'        => \$emacs,
+       'file!'         => \$file,
+       'subjective!'   => \$check,
+       'strict!'       => \$check,
+       'root=s'        => \$root,
 ) or exit;
 
 my $exit = 0;
@@ -33,19 +42,110 @@ if ($#ARGV < 0) {
        print "version: $V\n";
        print "options: -q           => quiet\n";
        print "         --no-tree    => run without a kernel tree\n";
+       print "         --emacs      => emacs compile window format\n";
+       print "         --file       => check a source file\n";
+       print "         --strict     => enable more subjective tests\n";
+       print "         --root       => path to the kernel tree root\n";
        exit(1);
 }
 
-if ($tree && !top_of_kernel_tree()) {
-       print "Must be run from the top-level dir. of a kernel tree\n";
-       exit(2);
+if ($tree) {
+       if (defined $root) {
+               if (!top_of_kernel_tree($root)) {
+                       die "$P: $root: --root does not point at a valid tree\n";
+               }
+       } else {
+               if (top_of_kernel_tree('.')) {
+                       $root = '.';
+               } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
+                                               top_of_kernel_tree($1)) {
+                       $root = $1;
+               }
+       }
+
+       if (!defined $root) {
+               print "Must be run from the top-level dir. of a kernel tree\n";
+               exit(2);
+       }
 }
 
+my $emitted_corrupt = 0;
+
+our $Ident       = qr{[A-Za-z_][A-Za-z\d_]*};
+our $Storage   = qr{extern|static|asmlinkage};
+our $Sparse    = qr{
+                       __user|
+                       __kernel|
+                       __force|
+                       __iomem|
+                       __must_check|
+                       __init_refok|
+                       __kprobes|
+                       fastcall
+               }x;
+our $Attribute = qr{
+                       const|
+                       __read_mostly|
+                       __kprobes|
+                       __(?:mem|cpu|dev|)(?:initdata|init)
+                 }x;
+our $Inline    = qr{inline|__always_inline|noinline};
+our $NonptrType        = qr{
+                       \b
+                       (?:const\s+)?
+                       (?:unsigned\s+)?
+                       (?:
+                               void|
+                               char|
+                               short|
+                               int|
+                               long|
+                               unsigned|
+                               float|
+                               double|
+                               bool|
+                               long\s+int|
+                               long\s+long|
+                               long\s+long\s+int|
+                               (?:__)?(?:u|s|be|le)(?:8|16|32|64)|
+                               struct\s+$Ident|
+                               union\s+$Ident|
+                               enum\s+$Ident|
+                               ${Ident}_t|
+                               ${Ident}_handler|
+                               ${Ident}_handler_fn
+                       )
+                       (?:\s+$Sparse)*
+                       \b
+                 }x;
+
+our $Type      = qr{
+                       \b$NonptrType\b
+                       (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)?
+                       (?:\s+$Sparse|\s+$Attribute)*
+                 }x;
+our $Declare   = qr{(?:$Storage\s+)?$Type};
+our $Member    = qr{->$Ident|\.$Ident|\[[^]]*\]};
+our $Lval      = qr{$Ident(?:$Member)*};
+
+our $Constant  = qr{(?:[0-9]+|0x[0-9a-fA-F]+)[UL]*};
+our $Assignment        = qr{(?:\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=)};
+our $Operators = qr{
+                       <=|>=|==|!=|
+                       =>|->|<<|>>|<|>|!|~|
+                       &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/
+                 }x;
+
+our $Bare = '';
+
+$chk_signoff = 0 if ($file);
+
 my @dep_includes = ();
 my @dep_functions = ();
-my $removal = 'Documentation/feature-removal-schedule.txt';
-if ($tree && -f $removal) {
-       open(REMOVE, "<$removal") || die "$P: $removal: open failed - $!\n";
+my $removal = "Documentation/feature-removal-schedule.txt";
+if ($tree && -f "$root/$removal") {
+       open(REMOVE, "<$root/$removal") ||
+                               die "$P: $removal: open failed - $!\n";
        while (<REMOVE>) {
                if (/^Check:\s+(.*\S)/) {
                        for my $entry (split(/[, ]+/, $1)) {
@@ -61,28 +161,42 @@ if ($tree && -f $removal) {
 }
 
 my @rawlines = ();
-while (<>) {
-       chomp;
-       push(@rawlines, $_);
-       if (eof(ARGV)) {
-               if (!process($ARGV, @rawlines)) {
-                       $exit = 1;
-               }
-               @rawlines = ();
+for my $filename (@ARGV) {
+       if ($file) {
+               open(FILE, "diff -u /dev/null $filename|") ||
+                       die "$P: $filename: diff failed - $!\n";
+       } else {
+               open(FILE, "<$filename") ||
+                       die "$P: $filename: open failed - $!\n";
        }
+       while (<FILE>) {
+               chomp;
+               push(@rawlines, $_);
+       }
+       close(FILE);
+       if (!process($filename, @rawlines)) {
+               $exit = 1;
+       }
+       @rawlines = ();
 }
 
 exit($exit);
 
 sub top_of_kernel_tree {
-       if ((-f "COPYING") && (-f "CREDITS") && (-f "Kbuild") &&
-           (-f "MAINTAINERS") && (-f "Makefile") && (-f "README") &&
-           (-d "Documentation") && (-d "arch") && (-d "include") &&
-           (-d "drivers") && (-d "fs") && (-d "init") && (-d "ipc") &&
-           (-d "kernel") && (-d "lib") && (-d "scripts")) {
-               return 1;
+       my ($root) = @_;
+
+       my @tree_check = (
+               "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
+               "README", "Documentation", "arch", "include", "drivers",
+               "fs", "init", "ipc", "kernel", "lib", "scripts",
+       );
+
+       foreach my $check (@tree_check) {
+               if (! -e $root . '/' . $check) {
+                       return 0;
+               }
        }
-       return 0;
+       return 1;
 }
 
 sub expand_tabs {
@@ -105,6 +219,20 @@ sub expand_tabs {
 
        return $res;
 }
+sub copy_spacing {
+       my ($str) = @_;
+
+       my $res = '';
+       for my $c (split(//, $str)) {
+               if ($c eq "\t") {
+                       $res .= $c;
+               } else {
+                       $res .= ' ';
+               }
+       }
+
+       return $res;
+}
 
 sub line_stats {
        my ($line) = @_;
@@ -260,47 +388,138 @@ sub ctx_has_comment {
        return ($cmt ne '');
 }
 
-sub ctx_expr_before {
-       my ($line) = @_;
-
-       ##print "CHECK<$line>\n";
-
-       my $pos = length($line) - 1;
-       my $count = 0;
-       my $c;
+sub cat_vet {
+       my ($vet) = @_;
+       my ($res, $coded);
 
-       for (; $pos >= 0; $pos--) {
-               $c = substr($line, $pos, 1);
-               ##print "CHECK: c<$c> count<$count>\n";
-               if ($c eq ')') {
-                       $count++;
-               } elsif ($c eq '(') {
-                       last if (--$count == 0);
+       $res = '';
+       while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
+               $res .= $1;
+               if ($2 ne '') {
+                       $coded = sprintf("^%c", unpack('C', $2) + 64);
+                       $res .= $coded;
                }
        }
+       $res =~ s/$/\$/;
 
-       ##print "CHECK: result<" . substr($line, 0, $pos) . ">\n";
-
-       return substr($line, 0, $pos);
+       return $res;
 }
 
-sub cat_vet {
-       my ($vet) = @_;
-       my ($res, $coded);
+sub annotate_values {
+       my ($stream, $type) = @_;
 
-       $res = '';
-       while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]])/g) {
-               $coded = sprintf("^%c", unpack('C', $2) + 64);
-               $res .= $1 . $coded;
+       my $res;
+       my $cur = $stream;
+
+       my $debug = 0;
+
+       print "$stream\n" if ($debug);
+
+       ##my $type = 'N';
+       my $pos = 0;
+       my $preprocessor = 0;
+       my $paren = 0;
+       my @paren_type;
+
+       # Include any user defined types we may have found as we went.
+       my $type_match = "(?:$Type$Bare)";
+
+       while (length($cur)) {
+               print " <$type> " if ($debug);
+               if ($cur =~ /^(\s+)/o) {
+                       print "WS($1)\n" if ($debug);
+                       if ($1 =~ /\n/ && $preprocessor) {
+                               $preprocessor = 0;
+                               $type = 'N';
+                       }
+
+               } elsif ($cur =~ /^($type_match)/) {
+                       print "DECLARE($1)\n" if ($debug);
+                       $type = 'T';
+
+               } elsif ($cur =~ /^(#\s*define\s*$Ident)(\(?)/o) {
+                       print "DEFINE($1)\n" if ($debug);
+                       $preprocessor = 1;
+                       $paren_type[$paren] = 'N';
+
+               } elsif ($cur =~ /^(#\s*(?:ifdef|ifndef|if|else|endif))/o) {
+                       print "PRE($1)\n" if ($debug);
+                       $preprocessor = 1;
+                       $type = 'N';
+
+               } elsif ($cur =~ /^(\\\n)/o) {
+                       print "PRECONT($1)\n" if ($debug);
+
+               } elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
+                       print "SIZEOF($1)\n" if ($debug);
+                       if (defined $2) {
+                               $paren_type[$paren] = 'V';
+                       }
+                       $type = 'N';
+
+               } elsif ($cur =~ /^(if|while|typeof)\b/o) {
+                       print "COND($1)\n" if ($debug);
+                       $paren_type[$paren] = 'N';
+                       $type = 'N';
+
+               } elsif ($cur =~/^(return|case|else)/o) {
+                       print "KEYWORD($1)\n" if ($debug);
+                       $type = 'N';
+
+               } elsif ($cur =~ /^(\()/o) {
+                       print "PAREN('$1')\n" if ($debug);
+                       $paren++;
+                       $type = 'N';
+
+               } elsif ($cur =~ /^(\))/o) {
+                       $paren-- if ($paren > 0);
+                       if (defined $paren_type[$paren]) {
+                               $type = $paren_type[$paren];
+                               undef $paren_type[$paren];
+                               print "PAREN('$1') -> $type\n" if ($debug);
+                       } else {
+                               print "PAREN('$1')\n" if ($debug);
+                       }
+
+               } elsif ($cur =~ /^($Ident)\(/o) {
+                       print "FUNC($1)\n" if ($debug);
+                       $paren_type[$paren] = 'V';
+
+               } elsif ($cur =~ /^($Ident|$Constant)/o) {
+                       print "IDENT($1)\n" if ($debug);
+                       $type = 'V';
+
+               } elsif ($cur =~ /^($Assignment)/o) {
+                       print "ASSIGN($1)\n" if ($debug);
+                       $type = 'N';
+
+               } elsif ($cur =~ /^(;|{|}|\?|:|\[)/o) {
+                       print "END($1)\n" if ($debug);
+                       $type = 'N';
+
+               } elsif ($cur =~ /^($Operators)/o) {
+                       print "OP($1)\n" if ($debug);
+                       if ($1 ne '++' && $1 ne '--') {
+                               $type = 'N';
+                       }
+
+               } elsif ($cur =~ /(^.)/o) {
+                       print "C($1)\n" if ($debug);
+               }
+               if (defined $1) {
+                       $cur = substr($cur, length($1));
+                       $res .= $type x length($1);
+               }
        }
-       $res =~ s/$/\$/;
 
        return $res;
 }
 
+my $prefix = '';
+
 my @report = ();
 sub report {
-       push(@report, $_[0]);
+       push(@report, $prefix . $_[0]);
 }
 sub report_dump {
        @report;
@@ -308,14 +527,19 @@ sub report_dump {
 sub ERROR {
        report("ERROR: $_[0]\n");
        our $clean = 0;
+       our $cnt_error++;
 }
 sub WARN {
        report("WARNING: $_[0]\n");
        our $clean = 0;
+       our $cnt_warn++;
 }
 sub CHK {
-       report("CHECK: $_[0]\n");
-       our $clean = 0;
+       if ($check) {
+               report("CHECK: $_[0]\n");
+               our $clean = 0;
+               our $cnt_chk++;
+       }
 }
 
 sub process {
@@ -335,6 +559,11 @@ sub process {
        my $signoff = 0;
        my $is_patch = 0;
 
+       our $cnt_lines = 0;
+       our $cnt_error = 0;
+       our $cnt_warn = 0;
+       our $cnt_chk = 0;
+
        # Trace the real file/line as we go.
        my $realfile = '';
        my $realline = 0;
@@ -343,62 +572,10 @@ sub process {
        my $in_comment = 0;
        my $first_line = 0;
 
-       my $Ident       = qr{[A-Za-z\d_]+};
-       my $Storage     = qr{extern|static|asmlinkage};
-       my $Sparse      = qr{
-                               __user|
-                               __kernel|
-                               __force|
-                               __iomem|
-                               __must_check|
-                               __init_refok|
-                               fastcall
-                       }x;
-       my $Inline      = qr{inline|__always_inline|noinline};
-       my $NonptrType  = qr{
-                               \b
-                               (?:const\s+)?
-                               (?:unsigned\s+)?
-                               (?:
-                                       void|
-                                       char|
-                                       short|
-                                       int|
-                                       long|
-                                       unsigned|
-                                       float|
-                                       double|
-                                       bool|
-                                       long\s+int|
-                                       long\s+long|
-                                       long\s+long\s+int|
-                                       u8|u16|u32|u64|
-                                       s8|s16|s32|s64|
-                                       struct\s+$Ident|
-                                       union\s+$Ident|
-                                       enum\s+$Ident|
-                                       ${Ident}_t
-                               )
-                               (?:\s+$Sparse)*
-                               \b
-                         }x;
-       my $Type        = qr{
-                               \b$NonptrType\b
-                               (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)?
-                               (?:\s+$Sparse)*
-                         }x;
-       my $Declare     = qr{(?:$Storage\s+)?$Type};
-       my $Attribute   = qr{
-                               const|
-                               __read_mostly|
-                               __(?:mem|cpu|dev|)(?:initdata|init)
-                         }x;
-       my $Member      = qr{->$Ident|\.$Ident|\[[^]]*\]};
-       my $Lval        = qr{$Ident(?:$Member)*};
+       my $prev_values = 'N';
 
        # Possible bare types.
        my @bare = ();
-       my $Bare = $NonptrType;
 
        # Pre-scan the patch looking for any __setup documentation.
        my @setup_docs = ();
@@ -417,11 +594,14 @@ sub process {
                }
        }
 
+       $prefix = '';
+
        foreach my $line (@lines) {
                $linenr++;
 
                my $rawline = $line;
 
+
 #extract the filename as it passes
                if ($line=~/^\+\+\+\s+(\S+)/) {
                        $realfile=$1;
@@ -430,7 +610,7 @@ sub process {
                        next;
                }
 #extract the line range in the file after the patch is applied
-               if ($line=~/^\@\@ -\d+,\d+ \+(\d+)(,(\d+))? \@\@/) {
+               if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
                        $is_patch = 1;
                        $first_line = $linenr + 1;
                        $in_comment = 0;
@@ -440,6 +620,7 @@ sub process {
                        } else {
                                $realcnt=1+1;
                        }
+                       $prev_values = 'N';
                        next;
                }
 
@@ -473,18 +654,24 @@ sub process {
                        # Track the previous line.
                        ($prevline, $stashline) = ($stashline, $line);
                        ($previndent, $stashindent) = ($stashindent, $indent);
+
                } elsif ($realcnt == 1) {
                        $realcnt--;
                }
 
 #make up the handle for any error we report on this line
-               $here = "#$linenr: ";
+               $here = "#$linenr: " if (!$file);
+               $here = "#$realline: " if ($file);
                $here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
 
                my $hereline = "$here\n$line\n";
                my $herecurr = "$here\n$line\n";
                my $hereprev = "$here\n$prevline\n$line\n";
 
+               $prefix = "$filename:$realline: " if ($emacs && $file);
+               $prefix = "$filename:$linenr: " if ($emacs && !$file);
+               $cnt_lines++ if ($realcnt != 0);
+
 #check the patch for a signoff:
                if ($line =~ /^\s*signed-off-by:/i) {
                        # This is a signoff, if ugly, so do not double report.
@@ -502,7 +689,7 @@ sub process {
 # Check for wrappage within a valid hunk of the file
                if ($realcnt != 0 && $line !~ m{^(?:\+|-| |$)}) {
                        ERROR("patch seems to be corrupt (line wrapped?)\n" .
-                               $herecurr);
+                               $herecurr) if (!$emitted_corrupt++);
                }
 
 # UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
@@ -568,8 +755,12 @@ sub process {
                    $line !~ /^.\s*(?:$Storage\s+)?(?:$Inline\s+)?$Type\b/ &&
                    $line !~ /$Ident:\s*$/ &&
                    $line !~ /^.\s*$Ident\s*\(/ &&
+                    # definitions in global scope can only start with types
                    ($line =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?($Ident)\b/ ||
-                    $line =~ /^.\s*(?:$Storage\s+)?($Ident)\b\s*\**\s*$Ident\s*(?:;|=)/)) {
+                    # declarations always start with types
+                    $line =~ /^.\s*(?:$Storage\s+)?($Ident)\b\s*\**\s*$Ident\s*(?:;|=)/) ||
+                    # any (foo ... *) is a pointer cast, and foo is a type
+                    $line =~ /\(($Ident)(?:\s+$Sparse)*\s*\*+\s*\)/) {
                        my $possible = $1;
                        if ($possible !~ /^(?:$Storage|$Type|DEFINE_\S+)$/ &&
                            $possible ne 'goto' && $possible ne 'return' &&
@@ -579,7 +770,7 @@ sub process {
                                #print "POSSIBLE<$possible>\n";
                                push(@bare, $possible);
                                my $bare = join("|", @bare);
-                               $Bare   = qr{
+                               $Bare   = '|' . qr{
                                                \b(?:$bare)\b
                                                (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)?
                                                (?:\s+$Sparse)*
@@ -641,6 +832,14 @@ sub process {
                        }
                }
 
+               # Track the 'values' across context and added lines.
+               my $opline = $line; $opline =~ s/^./ /;
+               my $curr_values = annotate_values($opline . "\n", $prev_values);
+               $curr_values = $prev_values . $curr_values;
+               #warn "--> $opline\n";
+               #warn "--> $curr_values ($prev_values)\n";
+               $prev_values = substr($curr_values, -1);
+
 #ignore lines not being added
                if ($line=~/^[^\+]/) {next;}
 
@@ -678,6 +877,7 @@ sub process {
                }
                # Remove C99 comments.
                $line =~ s@//.*@@;
+               $opline =~ s@//.*@@;
 
 #EXPORT_SYMBOL should immediately follow its function closing }.
                if (($line =~ /EXPORT_SYMBOL.*\((.*)\)/) ||
@@ -766,18 +966,13 @@ sub process {
                }
 
 # check for spaces between functions and their parentheses.
-               if ($line =~ /($Ident)\s+\(/ &&
-                   $1 !~ /^(?:if|for|while|switch|return|volatile|__volatile__|__attribute__|format|__extension__|Copyright)$/ &&
-                   $line !~ /$Type\s+\(/ && $line !~ /^.\#\s*define\b/) {
-                       WARN("no space between function name and open parenthesis '('\n" . $herecurr);
+               while ($line =~ /($Ident)\s+\(/g) {
+                       if ($1 !~ /^(?:if|for|while|switch|return|volatile|__volatile__|__attribute__|format|__extension__|Copyright|case)$/ &&
+                           $line !~ /$Type\s+\(/ && $line !~ /^.\#\s*define\b/) {
+                               WARN("no space between function name and open parenthesis '('\n" . $herecurr);
+                       }
                }
 # Check operator spacing.
-               # Note we expand the line with the leading + as the real
-               # line will be displayed with the leading + and the tabs
-               # will therefore also expand that way.
-               my $opline = $line;
-               $opline = expand_tabs($opline);
-               $opline =~ s/^./ /;
                if (!($line=~/\#\s*include/)) {
                        my $ops = qr{
                                <<=|>>=|<=|>=|==|!=|
@@ -787,6 +982,9 @@ sub process {
                        }x;
                        my @elements = split(/($ops|;)/, $opline);
                        my $off = 0;
+
+                       my $blank = copy_spacing($opline);
+
                        for (my $n = 0; $n < $#elements; $n += 2) {
                                $off += length($elements[$n]);
 
@@ -822,62 +1020,24 @@ sub process {
 
                                my $at = "(ctx:$ctx)";
 
-                               my $ptr = (" " x $off) . "^";
+                               my $ptr = substr($blank, 0, $off) . "^";
                                my $hereptr = "$hereline$ptr\n";
 
                                # Classify operators into binary, unary, or
                                # definitions (* only) where they have more
                                # than one mode.
-                               my $unary_ctx = $prevline . $ca;
-                               $unary_ctx =~ s/^./ /;
-                               my $is_unary = 0;
-                               my $Unary = qr{
-                                       (?:
-                                               ^|;|,|$ops|\(|\?|:|
-                                               \(\s*$Type\s*\)|
-                                               $Type|
-                                               return|case|else|
-                                               \{|\}|
-                                               \[|
-                                               ^.\#\s*define\s+$Ident\s*(?:\([^\)]*\))?|
-                                               ^.\#\s*else|
-                                               ^.\#\s*endif|
-                                               ^.\#\s*(?:if|ifndef|ifdef)\b.*
-                                       )\s*(?:|\\)\s*$
-                               }x;
-                               my $UnaryFalse = qr{
-                                       sizeof\s*\(\s*$Type\s*\)\s*$
-                               }x;
-                               my $UnaryDefine = qr{
-                                        (?:$Type|$Bare)\s*|
-                                        (?:$Type|$Bare).*,\s*\**
-                               }x;
-                               if ($op eq '-' || $op eq '&' || $op eq '*') {
-                                       # An operator is binary if the left hand
-                                       # side is a value.  Pick out the known
-                                       # non-values.
-                                       if ($unary_ctx =~ /$Unary$/s &&
-                                           $unary_ctx !~ /$UnaryFalse$/s) {
-                                               $is_unary = 1;
-
-                                       # Special handling for ')' check if this
-                                       # brace represents a conditional, if so
-                                       # we are unary.
-                                       } elsif ($unary_ctx =~ /\)\s*$/) {
-                                               my $before = ctx_expr_before($unary_ctx);
-                                               if ($before =~ /(?:for|if|while)\s*$/) {
-                                                       $is_unary = 1;
-                                               }
-                                       }
-
-                                       # Check for type definition for of '*'.
-                                       if ($op eq '*' && $unary_ctx =~ /$UnaryDefine$/) {
-                                               $is_unary = 2;
-                                       }
+                               my $op_type = substr($curr_values, $off + 1, 1);
+                               my $op_left = substr($curr_values, $off, 1);
+                               my $is_unary;
+                               if ($op_type eq 'T') {
+                                       $is_unary = 2;
+                               } elsif ($op_left eq 'V') {
+                                       $is_unary = 0;
+                               } else {
+                                       $is_unary = 1;
                                }
-
                                #if ($op eq '-' || $op eq '&' || $op eq '*') {
-                               #       print "UNARY: <$is_unary $a:$op:$c> <$ca:$op:$cc> <$unary_ctx>\n";
+                               #       print "UNARY: <$op_left$op_type $is_unary $a:$op:$c> <$ca:$op:$cc> <$unary_ctx>\n";
                                #}
 
                                # ; should have either the end of line or a space or \ after it
@@ -952,7 +1112,7 @@ sub process {
 
 # check for multiple assignments
                if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
-                       WARN("multiple assignments should be avoided\n" . $herecurr);
+                       CHK("multiple assignments should be avoided\n" . $herecurr);
                }
 
 ## # check for multiple declarations, allowing for a function declaration
@@ -1012,7 +1172,7 @@ sub process {
                }
 
 # Check for illegal assignment in if conditional.
-               if ($line=~/\bif\s*\(.*[^<>!=]=[^=].*\)/) {
+               if ($line=~/\bif\s*\(.*[^<>!=]=[^=]/) {
                        #next if ($line=~/\".*\Q$op\E.*\"/ or $line=~/\'\Q$op\E\'/);
                        ERROR("do not use assignment in if condition\n" . $herecurr);
                }
@@ -1038,8 +1198,8 @@ sub process {
 
 #warn if <asm/foo.h> is #included and <linux/foo.h> is available (uses RAW line)
                if ($tree && $rawline =~ m{^.\#\s*include\s*\<asm\/(.*)\.h\>}) {
-                       my $checkfile = "include/linux/$1.h";
-                       if (-f $checkfile) {
+                       my $checkfile = "$root/include/linux/$1.h";
+                       if (-f $checkfile && $1 ne 'irq.h') {
                                CHK("Use #include <linux/$1.h> instead of <asm/$1.h>\n" .
                                        $herecurr);
                        }
@@ -1151,7 +1311,8 @@ sub process {
                }
 
 # no volatiles please
-               if ($line =~ /\bvolatile\b/ && $line !~ /\basm\s+volatile\b/) {
+               my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
+               if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
                        WARN("Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr);
                }
 
@@ -1240,6 +1401,11 @@ sub process {
 
        if ($clean == 0 && ($chk_patch || $is_patch)) {
                print report_dump();
+               if ($quiet < 2) {
+                       print "total: $cnt_error errors, $cnt_warn warnings, " .
+                               (($check)? "$cnt_chk checks, " : "") .
+                               "$cnt_lines lines checked\n";
+               }
        }
        if ($clean == 1 && $quiet == 0) {
                print "Your patch has no obvious style problems and is ready for submission.\n"
index b458e2acb4acf3e035d7e3bd66a4b4687e8d5965..d716b76098bb670d76abff1eeff9830ff88ebfbc 100755 (executable)
 #      Random bits by Matt Mackall <mpm@selenic.com>
 #      M68k port by Geert Uytterhoeven and Andreas Schwab
 #      AVR32 port by Haavard Skinnemoen <hskinnemoen@atmel.com>
+#      PARISC port by Kyle McMartin <kyle@parisc-linux.org>
 #
 #      Usage:
-#      objdump -d vmlinux | stackcheck.pl [arch]
+#      objdump -d vmlinux | scripts/checkstack.pl [arch]
 #
 #      TODO :  Port to all architectures (one regex per arch)
 
@@ -61,6 +62,8 @@ my (@stack, $re, $x, $xs);
        } elsif ($arch eq 'mips') {
                #88003254:       27bdffe0        addiu   sp,sp,-32
                $re = qr/.*addiu.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2})/o;
+       } elsif ($arch eq 'parisc' || $arch eq 'parisc64') {
+               $re = qr/.*ldo ($x{1,8})\(sp\),sp/o;
        } elsif ($arch eq 'ppc') {
                #c00029f4:       94 21 ff 30     stwu    r1,-208(r1)
                $re = qr/.*stwu.*r1,-($x{1,8})\(r1\)/o;
index bb08069b04af35e260b940b7ff5bf9e8d3fdfe1b..83c5e76414cec6b46f72ae9a63a75a699401cc0d 100644 (file)
@@ -84,7 +84,7 @@ help:
 # lxdialog stuff
 check-lxdialog  := $(srctree)/$(src)/lxdialog/check-lxdialog.sh
 
-# Use reursively expanded variables so we do not call gcc unless
+# Use recursively expanded variables so we do not call gcc unless
 # we really need to do so. (Do not call gcc as part of make mrproper)
 HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags)
 HOST_LOADLIBES   = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
index 7bfa181d6ed6f685d45d8a68f301cd75810e3369..f9d0d91a3fe44e2407761a60bb5a31dc22926b41 100644 (file)
@@ -235,23 +235,16 @@ void menu_finalize(struct menu *parent)
        sym = parent->sym;
        if (parent->list) {
                if (sym && sym_is_choice(sym)) {
-                       /* find out choice type */
-                       enum symbol_type type = S_UNKNOWN;
-
+                       /* find the first choice value and find out choice type */
                        for (menu = parent->list; menu; menu = menu->next) {
-                               if (menu->sym && menu->sym->type != S_UNKNOWN) {
-                                       if (type == S_UNKNOWN)
-                                               type = menu->sym->type;
-                                       if (type != S_BOOLEAN)
-                                               break;
-                                       if (menu->sym->type == S_TRISTATE) {
-                                               type = S_TRISTATE;
-                                               break;
-                                       }
+                               if (menu->sym) {
+                                       current_entry = parent;
+                                       menu_set_type(menu->sym->type);
+                                       current_entry = menu;
+                                       menu_set_type(sym->type);
+                                       break;
                                }
                        }
-                       current_entry = parent;
-                       menu_set_type(type);
                        parentdep = expr_alloc_symbol(sym);
                } else if (parent->prompt)
                        parentdep = parent->prompt->visible.expr;
@@ -260,16 +253,7 @@ void menu_finalize(struct menu *parent)
 
                for (menu = parent->list; menu; menu = menu->next) {
                        basedep = expr_transform(menu->dep);
-                       dep = parentdep;
-                       if (sym && sym_is_choice(sym) && menu->sym) {
-                               enum symbol_type type = menu->sym->type;
-
-                               if (type == S_UNKNOWN)
-                                       type = sym->type;
-                            if (type != S_TRISTATE)
-                                       dep = expr_alloc_comp(E_EQUAL, sym, &symbol_yes);
-                       }
-                       basedep = expr_alloc_and(expr_copy(dep), basedep);
+                       basedep = expr_alloc_and(expr_copy(parentdep), basedep);
                        basedep = expr_eliminate_dups(basedep);
                        menu->dep = basedep;
                        if (menu->sym)
@@ -342,8 +326,7 @@ void menu_finalize(struct menu *parent)
                                            "values not supported");
                        }
                        current_entry = menu;
-                       if (menu->sym->type == S_UNKNOWN)
-                               menu_set_type(sym->type);
+                       menu_set_type(sym->type);
                        menu_add_symbol(P_CHOICE, sym, NULL);
                        prop = sym_get_choice_prop(sym);
                        for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr)
index e4eeb59a8c24aae7065144f1618220d2f22b8cec..b9bb32dfd62866527a8a414164e82c92721eea83 100644 (file)
@@ -1274,8 +1274,12 @@ ConfigMainWindow::ConfigMainWindow(void)
        QMenuBar* menu;
        bool ok;
        int x, y, width, height;
+       char title[256];
 
        QWidget *d = configApp->desktop();
+       snprintf(title, sizeof(title), _("Linux Kernel v%s Configuration"),
+               getenv("KERNELVERSION"));
+       setCaption(title);
 
        width = configSettings->readNumEntry("/window width", d->width() - 64);
        height = configSettings->readNumEntry("/window height", d->height() - 64);
index 91c15da2680b4a90c7b1de34d5883eb0de2ee119..d802b5afae89254f3b3131f7552e9eb60f7e07a7 100644 (file)
@@ -525,6 +525,20 @@ static int do_ssb_entry(const char *filename,
        return 1;
 }
 
+/* Looks like: virtio:dNvN */
+static int do_virtio_entry(const char *filename, struct virtio_device_id *id,
+                          char *alias)
+{
+       id->device = TO_NATIVE(id->device);
+       id->vendor = TO_NATIVE(id->vendor);
+
+       strcpy(alias, "virtio:");
+       ADD(alias, "d", 1, id->device);
+       ADD(alias, "v", id->vendor != VIRTIO_DEV_ANY_ID, id->vendor);
+
+       return 1;
+}
+
 /* Ignore any prefix, eg. v850 prepends _ */
 static inline int sym_is(const char *symbol, const char *name)
 {
@@ -651,6 +665,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
                do_table(symval, sym->st_size,
                         sizeof(struct ssb_device_id), "ssb",
                         do_ssb_entry, mod);
+       else if (sym_is(symname, "__mod_virtio_device_table"))
+               do_table(symval, sym->st_size,
+                        sizeof(struct virtio_device_id), "virtio",
+                        do_virtio_entry, mod);
        free(zeros);
 }
 
index 2ef9a193fcaef33cc527dab5ace20dd492ba4af1..93ac52adb4980b3d23a0b40acd6800e48f75b349 100644 (file)
@@ -268,6 +268,9 @@ static struct symbol *sym_add_exported(const char *name, struct module *mod,
                             "was in %s%s\n", mod->name, name,
                             s->module->name,
                             is_vmlinux(s->module->name) ?"":".ko");
+               } else {
+                       /* In case Modules.symvers was out of date */
+                       s->module = mod;
                }
        }
        s->preloaded = 0;
index 6edb29f2b4a6c8aa056a748168a70583897a9d3c..0f657b5f3bc860bf602680d3a22a312371a2a6a1 100644 (file)
@@ -83,6 +83,7 @@ Maintainer: $name
 Standards-Version: 3.6.1
 
 Package: $packagename
+Provides: kernel-image-$version, linux-image-$version
 Architecture: any
 Description: User Mode Linux kernel, version $version
  User-mode Linux is a port of the Linux kernel to its own system call
@@ -104,6 +105,7 @@ Maintainer: $name
 Standards-Version: 3.6.1
 
 Package: $packagename
+Provides: kernel-image-$version, linux-image-$version
 Architecture: any
 Description: Linux kernel, version $version
  This package contains the Linux kernel, modules and corresponding other
index 778cb0cfc5d892fa9ae3f001d35d2560779dd15c..bf67871173efbabbe2ad47a04ba1f24cbc6d3eeb 100644 (file)
 #include <linux/xattr.h>
 #include <linux/hugetlb.h>
 #include <linux/mount.h>
+#include <linux/sched.h>
+
+#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
+/*
+ * Because of the reduced scope of CAP_SETPCAP when filesystem
+ * capabilities are in effect, it is safe to allow this capability to
+ * be available in the default configuration.
+ */
+# define CAP_INIT_BSET  CAP_FULL_SET
+#else /* ie. ndef CONFIG_SECURITY_FILE_CAPABILITIES */
+# define CAP_INIT_BSET  CAP_INIT_EFF_SET
+#endif /* def CONFIG_SECURITY_FILE_CAPABILITIES */
+
+kernel_cap_t cap_bset = CAP_INIT_BSET;    /* systemwide capability bound */
+EXPORT_SYMBOL(cap_bset);
+
+/* Global security state */
+
+unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
+EXPORT_SYMBOL(securebits);
 
 int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
 {
@@ -73,14 +93,44 @@ int cap_capget (struct task_struct *target, kernel_cap_t *effective,
        return 0;
 }
 
+#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
+
+static inline int cap_block_setpcap(struct task_struct *target)
+{
+       /*
+        * No support for remote process capability manipulation with
+        * filesystem capability support.
+        */
+       return (target != current);
+}
+
+static inline int cap_inh_is_capped(void)
+{
+       /*
+        * return 1 if changes to the inheritable set are limited
+        * to the old permitted set.
+        */
+       return !cap_capable(current, CAP_SETPCAP);
+}
+
+#else /* ie., ndef CONFIG_SECURITY_FILE_CAPABILITIES */
+
+static inline int cap_block_setpcap(struct task_struct *t) { return 0; }
+static inline int cap_inh_is_capped(void) { return 1; }
+
+#endif /* def CONFIG_SECURITY_FILE_CAPABILITIES */
+
 int cap_capset_check (struct task_struct *target, kernel_cap_t *effective,
                      kernel_cap_t *inheritable, kernel_cap_t *permitted)
 {
-       /* Derived from kernel/capability.c:sys_capset. */
-       /* verify restrictions on target's new Inheritable set */
-       if (!cap_issubset (*inheritable,
-                          cap_combine (target->cap_inheritable,
-                                       current->cap_permitted))) {
+       if (cap_block_setpcap(target)) {
+               return -EPERM;
+       }
+       if (cap_inh_is_capped()
+           && !cap_issubset(*inheritable,
+                            cap_combine(target->cap_inheritable,
+                                        current->cap_permitted))) {
+               /* incapable of using this inheritable set */
                return -EPERM;
        }
 
@@ -140,7 +190,8 @@ int cap_inode_killpriv(struct dentry *dentry)
        return inode->i_op->removexattr(dentry, XATTR_NAME_CAPS);
 }
 
-static inline int cap_from_disk(__le32 *caps, struct linux_binprm *bprm,
+static inline int cap_from_disk(struct vfs_cap_data *caps,
+                               struct linux_binprm *bprm,
                                int size)
 {
        __u32 magic_etc;
@@ -148,7 +199,7 @@ static inline int cap_from_disk(__le32 *caps, struct linux_binprm *bprm,
        if (size != XATTR_CAPS_SZ)
                return -EINVAL;
 
-       magic_etc = le32_to_cpu(caps[0]);
+       magic_etc = le32_to_cpu(caps->magic_etc);
 
        switch ((magic_etc & VFS_CAP_REVISION_MASK)) {
        case VFS_CAP_REVISION:
@@ -156,8 +207,8 @@ static inline int cap_from_disk(__le32 *caps, struct linux_binprm *bprm,
                        bprm->cap_effective = true;
                else
                        bprm->cap_effective = false;
-               bprm->cap_permitted = to_cap_t( le32_to_cpu(caps[1]) );
-               bprm->cap_inheritable = to_cap_t( le32_to_cpu(caps[2]) );
+               bprm->cap_permitted = to_cap_t(le32_to_cpu(caps->permitted));
+               bprm->cap_inheritable = to_cap_t(le32_to_cpu(caps->inheritable));
                return 0;
        default:
                return -EINVAL;
@@ -169,7 +220,7 @@ static int get_file_caps(struct linux_binprm *bprm)
 {
        struct dentry *dentry;
        int rc = 0;
-       __le32 v1caps[XATTR_CAPS_SZ];
+       struct vfs_cap_data incaps;
        struct inode *inode;
 
        if (bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID) {
@@ -182,8 +233,14 @@ static int get_file_caps(struct linux_binprm *bprm)
        if (!inode->i_op || !inode->i_op->getxattr)
                goto out;
 
-       rc = inode->i_op->getxattr(dentry, XATTR_NAME_CAPS, &v1caps,
-                                                       XATTR_CAPS_SZ);
+       rc = inode->i_op->getxattr(dentry, XATTR_NAME_CAPS, NULL, 0);
+       if (rc > 0) {
+               if (rc == XATTR_CAPS_SZ)
+                       rc = inode->i_op->getxattr(dentry, XATTR_NAME_CAPS,
+                                               &incaps, XATTR_CAPS_SZ);
+               else
+                       rc = -EINVAL;
+       }
        if (rc == -ENODATA || rc == -EOPNOTSUPP) {
                /* no data, that's ok */
                rc = 0;
@@ -192,7 +249,7 @@ static int get_file_caps(struct linux_binprm *bprm)
        if (rc < 0)
                goto out;
 
-       rc = cap_from_disk(v1caps, bprm, rc);
+       rc = cap_from_disk(&incaps, bprm, rc);
        if (rc)
                printk(KERN_NOTICE "%s: cap_from_disk returned %d for %s\n",
                        __FUNCTION__, rc, bprm->filename);
@@ -285,7 +342,7 @@ void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
        /* For init, we want to retain the capabilities set
         * in the init_task struct. Thus we skip the usual
         * capability rules */
-       if (!is_init(current)) {
+       if (!is_global_init(current)) {
                current->cap_permitted = new_permitted;
                current->cap_effective = bprm->cap_effective ?
                                new_permitted : 0;
index bc43d4c7383e89e5675e3ab1b031aa33fe7d7fc2..6d895ade73de485d9ceab48a28094068550e79b0 100644 (file)
@@ -37,15 +37,13 @@ static int dummy_capget (struct task_struct *target, kernel_cap_t * effective,
                         kernel_cap_t * inheritable, kernel_cap_t * permitted)
 {
        *effective = *inheritable = *permitted = 0;
-       if (!issecure(SECURE_NOROOT)) {
-               if (target->euid == 0) {
-                       *permitted |= (~0 & ~CAP_FS_MASK);
-                       *effective |= (~0 & ~CAP_TO_MASK(CAP_SETPCAP) & ~CAP_FS_MASK);
-               }
-               if (target->fsuid == 0) {
-                       *permitted |= CAP_FS_MASK;
-                       *effective |= CAP_FS_MASK;
-               }
+       if (target->euid == 0) {
+               *permitted |= (~0 & ~CAP_FS_MASK);
+               *effective |= (~0 & ~CAP_TO_MASK(CAP_SETPCAP) & ~CAP_FS_MASK);
+       }
+       if (target->fsuid == 0) {
+               *permitted |= CAP_FS_MASK;
+               *effective |= CAP_FS_MASK;
        }
        return 0;
 }
index 24e1b1885de7c5b379b7c19c9cf7b760e1664c41..9f3124b08867536aca7cc580046d844e341ac6d5 100644 (file)
@@ -2977,11 +2977,7 @@ static int selinux_task_prctl(int option,
 
 static int selinux_task_wait(struct task_struct *p)
 {
-       u32 perm;
-
-       perm = signal_to_av(p->exit_signal);
-
-       return task_has_perm(p, current, perm);
+       return task_has_perm(p, current, PROCESS__SIGCHLD);
 }
 
 static void selinux_task_reparent_to_init(struct task_struct *p)
index cb008d9f0a823235265464197b8e2cd311b084e2..36a191e7004e957fb38de4e9c5507f8941a33062 100644 (file)
@@ -448,7 +448,7 @@ int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb,
        if (dst) {
                struct dst_entry *dst_test;
 
-               for (dst_test = dst; dst_test != 0;
+               for (dst_test = dst; dst_test != NULL;
                     dst_test = dst_test->child) {
                        struct xfrm_state *x = dst_test->xfrm;
 
index b9eca9f3dd252cd44d29d4aa1215c713347a8d81..3b73ba7d03e85ea96012225d43ff5491d1312e0b 100644 (file)
@@ -209,7 +209,7 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
                void *ptr;
 
                if (!aacirun->substream || !aacirun->start) {
-                       dev_warn(&aaci->dev->dev, "RX interrupt???");
+                       dev_warn(&aaci->dev->dev, "RX interrupt???\n");
                        writel(0, aacirun->base + AACI_IE);
                        return;
                }
@@ -263,7 +263,7 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
                void *ptr;
 
                if (!aacirun->substream || !aacirun->start) {
-                       dev_warn(&aaci->dev->dev, "TX interrupt???");
+                       dev_warn(&aaci->dev->dev, "TX interrupt???\n");
                        writel(0, aacirun->base + AACI_IE);
                        return;
                }
index 4c3aa8e10378bd306763dba42f16b6b9a564ebd5..df0774c76f6fc4eba16eb5abc0863ac01bbcedbc 100644 (file)
@@ -93,15 +93,16 @@ static int snd_ctl_open(struct inode *inode, struct file *file)
 
 static void snd_ctl_empty_read_queue(struct snd_ctl_file * ctl)
 {
+       unsigned long flags;
        struct snd_kctl_event *cread;
        
-       spin_lock(&ctl->read_lock);
+       spin_lock_irqsave(&ctl->read_lock, flags);
        while (!list_empty(&ctl->events)) {
                cread = snd_kctl_event(ctl->events.next);
                list_del(&cread->list);
                kfree(cread);
        }
-       spin_unlock(&ctl->read_lock);
+       spin_unlock_irqrestore(&ctl->read_lock, flags);
 }
 
 static int snd_ctl_release(struct inode *inode, struct file *file)
index d7c4fb86b9eba56167beec2b18434430947e0966..17b3e6f13ca3564c08f3ca0e81f2ddcd5041ad91 100644 (file)
@@ -71,7 +71,7 @@ static void reset_all_channels(struct snd_midi_channel_set *chset);
  * such as GM, GS and XG.
  * There modes that this module will run in are:
  *   Generic MIDI - no interpretation at all, it will just save current values
- *                  of controlers etc.
+ *                  of controllers etc.
  *   GM - You can use all gm_ prefixed elements of chan.  Controls, RPN, NRPN,
  *        SysEx will be interpreded as defined in General Midi.
  *   GS - You can use all gs_ prefixed elements of chan. Codes for GS will be
@@ -176,7 +176,7 @@ snd_midi_process_event(struct snd_midi_op *ops,
                                   ev->data.control.value);
                break;
        case SNDRV_SEQ_EVENT_NONREGPARAM:
-               /* Break it back into its controler values */
+               /* Break it back into its controller values */
                chan->param_type = SNDRV_MIDI_PARAM_TYPE_NONREGISTERED;
                chan->control[MIDI_CTL_MSB_DATA_ENTRY]
                        = (ev->data.control.value >> 7) & 0x7f;
@@ -189,7 +189,7 @@ snd_midi_process_event(struct snd_midi_op *ops,
                nrpn(ops, drv, chan, chanset);
                break;
        case SNDRV_SEQ_EVENT_REGPARAM:
-               /* Break it back into its controler values */
+               /* Break it back into its controller values */
                chan->param_type = SNDRV_MIDI_PARAM_TYPE_REGISTERED;
                chan->control[MIDI_CTL_MSB_DATA_ENTRY]
                        = (ev->data.control.value >> 7) & 0x7f;
@@ -267,7 +267,7 @@ note_off(struct snd_midi_op *ops, void *drv, struct snd_midi_channel *chan,
 }
 
 /*
- * Do all driver independent operations for this controler and pass
+ * Do all driver independent operations for this controller and pass
  * events that need to take place immediately to the driver.
  */
 static void
index 1b6f227af370b0428fd707df46a6b7b21cafc914..3557b6e20eb535718fa056f1020acc596d01f453 100644 (file)
@@ -808,7 +808,7 @@ static void snd_opl3_pitch_ctrl(struct snd_opl3 *opl3, struct snd_midi_channel *
 }
 
 /*
- * Deal with a controler type event.  This includes all types of
+ * Deal with a controller type event.  This includes all types of
  * control events, not just the midi controllers
  */
 void snd_opl3_control(void *p, int type, struct snd_midi_channel *chan)
index fe31bb5cffb8aa449cfb57b4bbf54f2e59e9bb48..37c47fb95aca43fa63058143ee4edf7fffe7be79 100644 (file)
@@ -189,7 +189,6 @@ void snd_tea575x_init(struct snd_tea575x *tea)
        tea->vd.owner = tea->card->module;
        strcpy(tea->vd.name, tea->tea5759 ? "TEA5759 radio" : "TEA5757 radio");
        tea->vd.type = VID_TYPE_TUNER;
-       tea->vd.hardware = VID_HARDWARE_RTRACK; /* FIXME: assign new number */
        tea->vd.release = snd_tea575x_release;
        video_set_drvdata(&tea->vd, tea);
        tea->vd.fops = &tea->fops;
index 4a7367a8ff9d25c76c0a432ed386468bf031db81..c1af28fd4a1fcf7fb961993ca4c74260d3e9fb26 100644 (file)
@@ -623,7 +623,7 @@ static int snd_es18xx_capture_prepare(struct snd_pcm_substream *substream)
                          (snd_pcm_format_width(runtime->format) == 16 ? 0x04 : 0x00) |
                          (snd_pcm_format_unsigned(runtime->format) ? 0x00 : 0x20));
 
-        /* Set DMA controler */
+        /* Set DMA controller */
         snd_dma_program(chip->dma1, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT);
 
        return 0;
@@ -689,7 +689,7 @@ static int snd_es18xx_playback2_prepare(struct snd_es18xx *chip,
                          (snd_pcm_format_width(runtime->format) == 16 ? 0x04 : 0x00) |
                          (snd_pcm_format_unsigned(runtime->format) ? 0x00 : 0x20));
 
-        /* Set DMA controler */
+        /* Set DMA controller */
         snd_dma_program(chip->dma1, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT);
 
        return 0;
index 8a61a119186135984c42b7299a9c692cf8853f20..24460a558bf75eaf98d8e70a76c411fc54c34525 100644 (file)
@@ -498,8 +498,8 @@ snd_au1000_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
        int             i;
 
        spin_lock(&au1000->ac97_lock);
-/* would rather use the interupt than this polling but it works and I can't
-get the interupt driven case to work efficiently */
+/* would rather use the interrupt than this polling but it works and I can't
+get the interrupt driven case to work efficiently */
        for (i = 0; i < 0x5000; i++)
                if (!(au1000->ac97_ioport->status & AC97C_CP))
                        break;
@@ -535,8 +535,8 @@ snd_au1000_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short
        int i;
 
        spin_lock(&au1000->ac97_lock);
-/* would rather use the interupt than this polling but it works and I can't
-get the interupt driven case to work efficiently */
+/* would rather use the interrupt than this polling but it works and I can't
+get the interrupt driven case to work efficiently */
        for (i = 0; i < 0x5000; i++)
                if (!(au1000->ac97_ioport->status & AC97C_CP))
                        break;
index 1200670017bddf5a5a8ba74f3f95c995f6ec73ab..f883c4b676abaed9ca308376b032d8fbdbd37903 100644 (file)
@@ -36,7 +36,6 @@ obj-$(CONFIG_SOUND_MSNDCLAS)  += msnd.o msnd_classic.o
 obj-$(CONFIG_SOUND_MSNDPIN)    += msnd.o msnd_pinnacle.o
 obj-$(CONFIG_SOUND_VWSND)      += vwsnd.o
 obj-$(CONFIG_SOUND_ICH)                += i810_audio.o ac97_codec.o
-obj-$(CONFIG_SOUND_ES1371)     += es1371.o ac97_codec.o
 obj-$(CONFIG_SOUND_AU1550_AC97)        += au1550_ac97.o ac97_codec.o
 obj-$(CONFIG_SOUND_TRIDENT)    += trident.o ac97_codec.o
 obj-$(CONFIG_SOUND_BCM_CS4297A)        += swarm_cs4297a.o
index 4611636b1a81c455cc83b0baac28d21a020c1d84..3c1531652d117086977c8f201afac846fc7d4d48 100644 (file)
@@ -2,12 +2,6 @@
 # Makefile for the DMA sound driver
 #
 
-dmasound_pmac-y                        += dmasound_awacs.o \
-                                  trans_16.o dac3550a.o tas_common.o \
-                                  tas3001c.o tas3001c_tables.o \
-                                  tas3004.o tas3004_tables.o
-
 obj-$(CONFIG_DMASOUND_ATARI)   += dmasound_core.o dmasound_atari.o
-obj-$(CONFIG_DMASOUND_PMAC)    += dmasound_core.o dmasound_pmac.o
 obj-$(CONFIG_DMASOUND_PAULA)   += dmasound_core.o dmasound_paula.o
 obj-$(CONFIG_DMASOUND_Q40)     += dmasound_core.o dmasound_q40.o
diff --git a/sound/oss/dmasound/awacs_defs.h b/sound/oss/dmasound/awacs_defs.h
deleted file mode 100644 (file)
index 2194f46..0000000
+++ /dev/null
@@ -1,251 +0,0 @@
-/*********************************************************/
-/* This file was written by someone, somewhere, sometime */
-/* And is released into the Public Domain                */
-/*********************************************************/
-
-#ifndef _AWACS_DEFS_H_
-#define _AWACS_DEFS_H_
-
-/*******************************/
-/* AWACs Audio Register Layout */
-/*******************************/
-
-struct awacs_regs {
-    unsigned   control;        /* Audio control register */
-    unsigned   pad0[3];
-    unsigned   codec_ctrl;     /* Codec control register */
-    unsigned   pad1[3];
-    unsigned   codec_stat;     /* Codec status register */
-    unsigned   pad2[3];
-    unsigned   clip_count;     /* Clipping count register */
-    unsigned   pad3[3];
-    unsigned   byteswap;       /* Data is little-endian if 1 */
-};
-
-/*******************/
-/* Audio Bit Masks */
-/*******************/
-
-/* Audio Control Reg Bit Masks */
-/* ----- ------- --- --- ----- */
-#define MASK_ISFSEL    (0xf)           /* Input SubFrame Select */
-#define MASK_OSFSEL    (0xf << 4)      /* Output SubFrame Select */
-#define MASK_RATE      (0x7 << 8)      /* Sound Rate */
-#define MASK_CNTLERR   (0x1 << 11)     /* Error */
-#define MASK_PORTCHG   (0x1 << 12)     /* Port Change */
-#define MASK_IEE       (0x1 << 13)     /* Enable Interrupt on Error */
-#define MASK_IEPC      (0x1 << 14)     /* Enable Interrupt on Port Change */
-#define MASK_SSFSEL    (0x3 << 15)     /* Status SubFrame Select */
-
-/* Audio Codec Control Reg Bit Masks */
-/* ----- ----- ------- --- --- ----- */
-#define MASK_NEWECMD   (0x1 << 24)     /* Lock: don't write to reg when 1 */
-#define MASK_EMODESEL  (0x3 << 22)     /* Send info out on which frame? */
-#define MASK_EXMODEADDR        (0x3ff << 12)   /* Extended Mode Address -- 10 bits */
-#define MASK_EXMODEDATA        (0xfff)         /* Extended Mode Data -- 12 bits */
-
-/* Audio Codec Control Address Values / Masks */
-/* ----- ----- ------- ------- ------ - ----- */
-#define MASK_ADDR0     (0x0 << 12)     /* Expanded Data Mode Address 0 */
-#define MASK_ADDR_MUX  MASK_ADDR0      /* Mux Control */
-#define MASK_ADDR_GAIN MASK_ADDR0
-
-#define MASK_ADDR1     (0x1 << 12)     /* Expanded Data Mode Address 1 */
-#define MASK_ADDR_MUTE MASK_ADDR1
-#define MASK_ADDR_RATE MASK_ADDR1
-
-#define MASK_ADDR2     (0x2 << 12)     /* Expanded Data Mode Address 2 */
-#define MASK_ADDR_VOLA MASK_ADDR2      /* Volume Control A -- Headphones */
-#define MASK_ADDR_VOLHD MASK_ADDR2
-
-#define MASK_ADDR4     (0x4 << 12)     /* Expanded Data Mode Address 4 */
-#define MASK_ADDR_VOLC MASK_ADDR4      /* Volume Control C -- Speaker */
-#define MASK_ADDR_VOLSPK MASK_ADDR4
-
-/* additional registers of screamer */
-#define MASK_ADDR5     (0x5 << 12)     /* Expanded Data Mode Address 5 */
-#define MASK_ADDR6     (0x6 << 12)     /* Expanded Data Mode Address 6 */
-#define MASK_ADDR7     (0x7 << 12)     /* Expanded Data Mode Address 7 */
-
-/* Address 0 Bit Masks & Macros */
-/* ------- - --- ----- - ------ */
-#define MASK_GAINRIGHT (0xf)           /* Gain Right Mask */
-#define MASK_GAINLEFT  (0xf << 4)      /* Gain Left Mask */
-#define MASK_GAINLINE  (0x1 << 8)      /* Disable Mic preamp */
-#define MASK_GAINMIC   (0x0 << 8)      /* Enable Mic preamp */
-
-#define MASK_MUX_CD    (0x1 << 9)      /* Select CD in MUX */
-#define MASK_MUX_MIC   (0x1 << 10)     /* Select Mic in MUX */
-#define MASK_MUX_AUDIN (0x1 << 11)     /* Select Audio In in MUX */
-#define MASK_MUX_LINE  MASK_MUX_AUDIN
-
-#define GAINRIGHT(x)   ((x) & MASK_GAINRIGHT)
-#define GAINLEFT(x)    (((x) << 4) & MASK_GAINLEFT)
-
-#define DEF_CD_GAIN 0x00bb
-#define DEF_MIC_GAIN 0x00cc
-
-/* Address 1 Bit Masks */
-/* ------- - --- ----- */
-#define MASK_ADDR1RES1 (0x3)           /* Reserved */
-#define MASK_RECALIBRATE (0x1 << 2)    /* Recalibrate */
-#define MASK_SAMPLERATE        (0x7 << 3)      /* Sample Rate: */
-#define MASK_LOOPTHRU  (0x1 << 6)      /* Loopthrough Enable */
-#define MASK_CMUTE     (0x1 << 7)      /* Output C (Speaker) Mute when 1 */
-#define MASK_SPKMUTE   MASK_CMUTE
-#define MASK_ADDR1RES2 (0x1 << 8)      /* Reserved */
-#define MASK_AMUTE     (0x1 << 9)      /* Output A (Headphone) Mute when 1 */
-#define MASK_HDMUTE    MASK_AMUTE
-#define MASK_PAROUT0   (0x1 << 10)     /* Parallel Output 0 */
-#define MASK_PAROUT1   (0x2 << 10)     /* Parallel Output 1 */
-
-#define MASK_MIC_BOOST  (0x4)           /* screamer mic boost */
-
-#define SAMPLERATE_48000       (0x0 << 3)      /* 48 or 44.1 kHz */
-#define SAMPLERATE_32000       (0x1 << 3)      /* 32 or 29.4 kHz */
-#define SAMPLERATE_24000       (0x2 << 3)      /* 24 or 22.05 kHz */
-#define SAMPLERATE_19200       (0x3 << 3)      /* 19.2 or 17.64 kHz */
-#define SAMPLERATE_16000       (0x4 << 3)      /* 16 or 14.7 kHz */
-#define SAMPLERATE_12000       (0x5 << 3)      /* 12 or 11.025 kHz */
-#define SAMPLERATE_9600                (0x6 << 3)      /* 9.6 or 8.82 kHz */
-#define SAMPLERATE_8000                (0x7 << 3)      /* 8 or 7.35 kHz */
-
-/* Address 2 & 4 Bit Masks & Macros */
-/* ------- - - - --- ----- - ------ */
-#define MASK_OUTVOLRIGHT (0xf)         /* Output Right Volume */
-#define MASK_ADDR2RES1 (0x2 << 4)      /* Reserved */
-#define MASK_ADDR4RES1 MASK_ADDR2RES1
-#define MASK_OUTVOLLEFT        (0xf << 6)      /* Output Left Volume */
-#define MASK_ADDR2RES2 (0x2 << 10)     /* Reserved */
-#define MASK_ADDR4RES2 MASK_ADDR2RES2
-
-#define VOLRIGHT(x)    (((~(x)) & MASK_OUTVOLRIGHT))
-#define VOLLEFT(x)     (((~(x)) << 6) & MASK_OUTVOLLEFT)
-
-/* Audio Codec Status Reg Bit Masks */
-/* ----- ----- ------ --- --- ----- */
-#define MASK_EXTEND    (0x1 << 23)     /* Extend */
-#define MASK_VALID     (0x1 << 22)     /* Valid Data? */
-#define MASK_OFLEFT    (0x1 << 21)     /* Overflow Left */
-#define MASK_OFRIGHT   (0x1 << 20)     /* Overflow Right */
-#define MASK_ERRCODE   (0xf << 16)     /* Error Code */
-#define MASK_REVISION  (0xf << 12)     /* Revision Number */
-#define MASK_MFGID     (0xf << 8)      /* Mfg. ID */
-#define MASK_CODSTATRES        (0xf << 4)      /* bits 4 - 7 reserved */
-#define MASK_INPPORT   (0xf)           /* Input Port */
-#define MASK_HDPCONN   8               /* headphone plugged in */
-
-/* Clipping Count Reg Bit Masks */
-/* -------- ----- --- --- ----- */
-#define MASK_CLIPLEFT  (0xff << 7)     /* Clipping Count, Left Channel */
-#define MASK_CLIPRIGHT (0xff)          /* Clipping Count, Right Channel */
-
-/* DBDMA ChannelStatus Bit Masks */
-/* ----- ------------- --- ----- */
-#define MASK_CSERR     (0x1 << 7)      /* Error */
-#define MASK_EOI       (0x1 << 6)      /* End of Input -- only for Input Channel */
-#define MASK_CSUNUSED  (0x1f << 1)     /* bits 1-5 not used */
-#define MASK_WAIT      (0x1)           /* Wait */
-
-/* Various Rates */
-/* ------- ----- */
-#define RATE_48000     (0x0 << 8)      /* 48 kHz */
-#define RATE_44100     (0x0 << 8)      /* 44.1 kHz */
-#define RATE_32000     (0x1 << 8)      /* 32 kHz */
-#define RATE_29400     (0x1 << 8)      /* 29.4 kHz */
-#define RATE_24000     (0x2 << 8)      /* 24 kHz */
-#define RATE_22050     (0x2 << 8)      /* 22.05 kHz */
-#define RATE_19200     (0x3 << 8)      /* 19.2 kHz */
-#define RATE_17640     (0x3 << 8)      /* 17.64 kHz */
-#define RATE_16000     (0x4 << 8)      /* 16 kHz */
-#define RATE_14700     (0x4 << 8)      /* 14.7 kHz */
-#define RATE_12000     (0x5 << 8)      /* 12 kHz */
-#define RATE_11025     (0x5 << 8)      /* 11.025 kHz */
-#define RATE_9600      (0x6 << 8)      /* 9.6 kHz */
-#define RATE_8820      (0x6 << 8)      /* 8.82 kHz */
-#define RATE_8000      (0x7 << 8)      /* 8 kHz */
-#define RATE_7350      (0x7 << 8)      /* 7.35 kHz */
-
-#define RATE_LOW       1       /* HIGH = 48kHz, etc;  LOW = 44.1kHz, etc. */
-
-/*******************/
-/* Burgundy values */
-/*******************/
-
-#define MASK_ADDR_BURGUNDY_INPSEL21 (0x11 << 12)
-#define MASK_ADDR_BURGUNDY_INPSEL3 (0x12 << 12)
-
-#define MASK_ADDR_BURGUNDY_GAINCH1 (0x13 << 12)
-#define MASK_ADDR_BURGUNDY_GAINCH2 (0x14 << 12)
-#define MASK_ADDR_BURGUNDY_GAINCH3 (0x15 << 12)
-#define MASK_ADDR_BURGUNDY_GAINCH4 (0x16 << 12)
-
-#define MASK_ADDR_BURGUNDY_VOLCH1 (0x20 << 12)
-#define MASK_ADDR_BURGUNDY_VOLCH2 (0x21 << 12)
-#define MASK_ADDR_BURGUNDY_VOLCH3 (0x22 << 12)
-#define MASK_ADDR_BURGUNDY_VOLCH4 (0x23 << 12)
-
-#define MASK_ADDR_BURGUNDY_OUTPUTSELECTS (0x2B << 12)
-#define MASK_ADDR_BURGUNDY_OUTPUTENABLES (0x2F << 12)
-
-#define MASK_ADDR_BURGUNDY_MASTER_VOLUME (0x30 << 12)
-
-#define MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES (0x60 << 12)
-
-#define MASK_ADDR_BURGUNDY_ATTENSPEAKER (0x62 << 12)
-#define MASK_ADDR_BURGUNDY_ATTENLINEOUT (0x63 << 12)
-#define MASK_ADDR_BURGUNDY_ATTENHP (0x64 << 12)
-
-#define MASK_ADDR_BURGUNDY_VOLCD (MASK_ADDR_BURGUNDY_VOLCH1)
-#define MASK_ADDR_BURGUNDY_VOLLINE (MASK_ADDR_BURGUNDY_VOLCH2)
-#define MASK_ADDR_BURGUNDY_VOLMIC (MASK_ADDR_BURGUNDY_VOLCH3)
-#define MASK_ADDR_BURGUNDY_VOLMODEM (MASK_ADDR_BURGUNDY_VOLCH4)
-
-#define MASK_ADDR_BURGUNDY_GAINCD (MASK_ADDR_BURGUNDY_GAINCH1)
-#define MASK_ADDR_BURGUNDY_GAINLINE (MASK_ADDR_BURGUNDY_GAINCH2)
-#define MASK_ADDR_BURGUNDY_GAINMIC (MASK_ADDR_BURGUNDY_GAINCH3)
-#define MASK_ADDR_BURGUNDY_GAINMODEM (MASK_ADDR_BURGUNDY_VOLCH4)
-
-
-/* These are all default values for the burgundy */
-#define DEF_BURGUNDY_INPSEL21 (0xAA)
-#define DEF_BURGUNDY_INPSEL3 (0x0A)
-
-#define DEF_BURGUNDY_GAINCD (0x33)
-#define DEF_BURGUNDY_GAINLINE (0x44)
-#define DEF_BURGUNDY_GAINMIC (0x44)
-#define DEF_BURGUNDY_GAINMODEM (0x06)
-
-/* Remember: lowest volume here is 0x9b */
-#define DEF_BURGUNDY_VOLCD (0xCCCCCCCC)
-#define DEF_BURGUNDY_VOLLINE (0x00000000)
-#define DEF_BURGUNDY_VOLMIC (0x00000000)
-#define DEF_BURGUNDY_VOLMODEM (0xCCCCCCCC)
-
-#define DEF_BURGUNDY_OUTPUTSELECTS (0x010f010f)
-#define DEF_BURGUNDY_OUTPUTENABLES (0x0A)
-
-#define DEF_BURGUNDY_MASTER_VOLUME (0xFFFFFFFF)
-
-#define DEF_BURGUNDY_MORE_OUTPUTENABLES (0x7E)
-
-#define DEF_BURGUNDY_ATTENSPEAKER (0x44)
-#define DEF_BURGUNDY_ATTENLINEOUT (0xCC)
-#define DEF_BURGUNDY_ATTENHP (0xCC)
-
-/*********************/
-/* i2s layout values */
-/*********************/
-
-#define I2S_REG_INT_CTL                        0x00
-#define I2S_REG_SERIAL_FORMAT          0x10
-#define I2S_REG_CODEC_MSG_OUT          0x20
-#define I2S_REG_CODEC_MSG_IN           0x30
-#define I2S_REG_FRAME_COUNT            0x40
-#define I2S_REG_FRAME_MATCH            0x50
-#define I2S_REG_DATAWORD_SIZES         0x60
-#define I2S_REG_PEAKLEVEL_SEL          0x70
-#define I2S_REG_PEAKLEVEL_IN0          0x80
-#define I2S_REG_PEAKLEVEL_IN1          0x90
-
-#endif /* _AWACS_DEFS_H_ */
diff --git a/sound/oss/dmasound/dac3550a.c b/sound/oss/dmasound/dac3550a.c
deleted file mode 100644 (file)
index 0f0d03a..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Driver for the i2c/i2s based DAC3550a sound chip used
- * on some Apple iBooks. Also known as "DACA".
- *
- *  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/module.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/proc_fs.h>
-#include <linux/ioport.h>
-#include <linux/sysctl.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <asm/uaccess.h>
-#include <asm/errno.h>
-#include <asm/io.h>
-
-#include "dmasound.h"
-
-/* FYI: This code was derived from the tas3001c.c Texas/Tumbler mixer
- * control code, as well as info derived from the AppleDACAAudio driver
- * from Darwin CVS (main thing I derived being register numbers and 
- * values, as well as when to make the calls). */
-
-#define I2C_DRIVERID_DACA (0xFDCB)
-
-#define DACA_VERSION   "0.1"
-#define DACA_DATE "20010930"
-
-static int cur_left_vol;
-static int cur_right_vol;
-static struct i2c_client *daca_client;
-
-static int daca_attach_adapter(struct i2c_adapter *adapter);
-static int daca_detect_client(struct i2c_adapter *adapter, int address);
-static int daca_detach_client(struct i2c_client *client);
-
-struct i2c_driver daca_driver = {  
-       .driver = {
-               .name           = "DAC3550A driver  V " DACA_VERSION,
-       },
-       .id                     = I2C_DRIVERID_DACA,
-       .attach_adapter         = daca_attach_adapter,
-       .detach_client          = daca_detach_client,
-};
-
-#define VOL_MAX ((1<<20) - 1)
-
-void daca_get_volume(uint * left_vol, uint  *right_vol)
-{
-       *left_vol = cur_left_vol >> 5;
-       *right_vol = cur_right_vol >> 5;
-}
-
-int daca_set_volume(uint left_vol, uint right_vol)
-{
-       unsigned short voldata;
-  
-       if (!daca_client)
-               return -1;
-
-       /* Derived from experience, not from any specific values */
-       left_vol <<= 5;
-       right_vol <<= 5;
-
-       if (left_vol > VOL_MAX)
-               left_vol = VOL_MAX;
-       if (right_vol > VOL_MAX)
-               right_vol = VOL_MAX;
-
-       voldata = ((left_vol >> 14)  & 0x3f) << 8;
-       voldata |= (right_vol >> 14)  & 0x3f;
-  
-       if (i2c_smbus_write_word_data(daca_client, 2, voldata) < 0) {
-               printk("daca: failed to set volume \n");
-               return -1; 
-       }
-
-       cur_left_vol = left_vol;
-       cur_right_vol = right_vol;
-  
-       return 0;
-}
-
-int daca_leave_sleep(void)
-{
-       if (!daca_client)
-               return -1;
-  
-       /* Do a short sleep, just to make sure I2C bus is awake and paying
-        * attention to us
-        */
-       msleep(20);
-       /* Write the sample rate reg the value it needs */
-       i2c_smbus_write_byte_data(daca_client, 1, 8);
-       daca_set_volume(cur_left_vol >> 5, cur_right_vol >> 5);
-       /* Another short delay, just to make sure the other I2C bus writes
-        * have taken...
-        */
-       msleep(20);
-       /* Write the global config reg - invert right power amp,
-        * DAC on, use 5-volt mode */
-       i2c_smbus_write_byte_data(daca_client, 3, 0x45);
-
-       return 0;
-}
-
-int daca_enter_sleep(void)
-{
-       if (!daca_client)
-               return -1;
-
-       i2c_smbus_write_byte_data(daca_client, 1, 8);
-       daca_set_volume(cur_left_vol >> 5, cur_right_vol >> 5);
-
-       /* Write the global config reg - invert right power amp,
-        * DAC on, enter low-power mode, use 5-volt mode
-        */
-       i2c_smbus_write_byte_data(daca_client, 3, 0x65);
-
-       return 0;
-}
-
-static int daca_attach_adapter(struct i2c_adapter *adapter)
-{
-       if (!strncmp(adapter->name, "mac-io", 6))
-               daca_detect_client(adapter, 0x4d);
-       return 0;
-}
-
-static int daca_init_client(struct i2c_client * new_client)
-{
-       /* 
-        * Probe is not working with the current i2c-keywest
-        * driver. We try to use addr 0x4d on each adapters
-        * instead, by setting the format register.
-        * 
-        * FIXME: I'm sure that can be obtained from the
-        * device-tree. --BenH.
-        */
-  
-       /* Write the global config reg - invert right power amp,
-        * DAC on, use 5-volt mode
-        */
-       if (i2c_smbus_write_byte_data(new_client, 3, 0x45))
-               return -1;
-
-       i2c_smbus_write_byte_data(new_client, 1, 8);
-       daca_client = new_client;
-       daca_set_volume(15000, 15000);
-
-       return 0;
-}
-
-static int daca_detect_client(struct i2c_adapter *adapter, int address)
-{
-       const char *client_name = "DAC 3550A Digital Equalizer";
-       struct i2c_client *new_client;
-       int rc = -ENODEV;
-
-       new_client = kzalloc(sizeof(*new_client), GFP_KERNEL);
-       if (!new_client)
-               return -ENOMEM;
-
-       new_client->addr = address;
-       new_client->adapter = adapter;
-       new_client->driver = &daca_driver;
-       new_client->flags = 0;
-       strcpy(new_client->name, client_name);
-
-       if (daca_init_client(new_client))
-               goto bail;
-
-       /* Tell the i2c layer a new client has arrived */
-       if (i2c_attach_client(new_client))
-               goto bail;
-
-       return 0;
- bail:
-       kfree(new_client);
-       return rc;
-}
-
-
-static int daca_detach_client(struct i2c_client *client)
-{
-       if (client == daca_client)
-               daca_client = NULL;
-
-       i2c_detach_client(client);
-       kfree(client);
-       return 0;
-}
-
-void daca_cleanup(void)
-{
-       i2c_del_driver(&daca_driver);
-}
-
-int daca_init(void)
-{
-       printk("dac3550a driver version %s (%s)\n",DACA_VERSION,DACA_DATE);
-       return i2c_add_driver(&daca_driver);
-}
index 25dd5a318eb452d53ac68d3d4a0ecf82aeadaf1a..d978b009656405d17f9069c64f604cd632a4729f 100644 (file)
@@ -59,7 +59,6 @@ static inline int ioctl_return(int __user *addr, int value)
      */
 
 #undef HAS_8BIT_TABLES
-#undef HAS_RECORD
 
 #if defined(CONFIG_DMASOUND_ATARI) || defined(CONFIG_DMASOUND_ATARI_MODULE) ||\
     defined(CONFIG_DMASOUND_PAULA) || defined(CONFIG_DMASOUND_PAULA_MODULE) ||\
@@ -83,10 +82,6 @@ static inline int ioctl_return(int __user *addr, int value)
 #define DEFAULT_N_BUFFERS 4
 #define DEFAULT_BUFF_SIZE (1<<15)
 
-#if defined(CONFIG_DMASOUND_PMAC) || defined(CONFIG_DMASOUND_PMAC_MODULE)
-#define HAS_RECORD
-#endif
-
     /*
      *  Initialization
      */
@@ -168,9 +163,6 @@ struct sound_settings {
     SETTINGS soft;     /* software settings */
     SETTINGS dsp;      /* /dev/dsp default settings */
     TRANS *trans_write;        /* supported translations */
-#ifdef HAS_RECORD
-    TRANS *trans_read; /* supported translations */
-#endif
     int volume_left;   /* volume (range is machine dependent) */
     int volume_right;
     int bass;          /* tone (range is machine dependent) */
@@ -253,11 +245,6 @@ struct sound_queue {
 extern struct sound_queue dmasound_write_sq;
 #define write_sq       dmasound_write_sq
 
-#ifdef HAS_RECORD
-extern struct sound_queue dmasound_read_sq;
-#define read_sq                dmasound_read_sq
-#endif
-
 extern int dmasound_catchRadius;
 #define catchRadius    dmasound_catchRadius
 
diff --git a/sound/oss/dmasound/dmasound_awacs.c b/sound/oss/dmasound/dmasound_awacs.c
deleted file mode 100644 (file)
index 8f63880..0000000
+++ /dev/null
@@ -1,3215 +0,0 @@
-/*
- *  linux/sound/oss/dmasound/dmasound_awacs.c
- *
- *  PowerMac `AWACS' and `Burgundy' DMA Sound Driver
- *  with some limited support for DACA & Tumbler
- *
- *  See linux/sound/oss/dmasound/dmasound_core.c for copyright and
- *  history prior to 2001/01/26.
- *
- *     26/01/2001 ed 0.1 Iain Sandoe
- *             - added version info.
- *             - moved dbdma command buffer allocation to PMacXXXSqSetup()
- *             - fixed up beep dbdma cmd buffers
- *
- *     08/02/2001 [0.2]
- *             - make SNDCTL_DSP_GETFMTS return the correct info for the h/w
- *             - move soft format translations to a separate file
- *             - [0.3] make SNDCTL_DSP_GETCAPS return correct info.
- *             - [0.4] more informative machine name strings.
- *             - [0.5]
- *             - record changes.
- *             - made the default_hard/soft entries.
- *     04/04/2001 [0.6]
- *             - minor correction to bit assignments in awacs_defs.h
- *             - incorporate mixer changes from 2.2.x back-port.
- *             - take out passthru as a rec input (it isn't).
- *              - make Input Gain slider work the 'right way up'.
- *              - try to make the mixer sliders more logical - so now the
- *                input selectors are just two-state (>50% == ON) and the
- *                Input Gain slider handles the rest of the gain issues.
- *              - try to pick slider representations that most closely match
- *                the actual use - e.g. IGain for input gain... 
- *              - first stab at over/under-run detection.
- *             - minor cosmetic changes to IRQ identification.
- *             - fix bug where rates > max would be reported as supported.
- *              - first stab at over/under-run detection.
- *              - make use of i2c for mixer settings conditional on perch
- *                rather than cuda (some machines without perch have cuda).
- *              - fix bug where TX stops when dbdma status comes up "DEAD"
- *               so far only reported on PowerComputing clones ... but.
- *             - put in AWACS/Screamer register write timeouts.
- *             - part way to partitioning the init() stuff
- *             - first pass at 'tumbler' stuff (not support - just an attempt
- *               to allow the driver to load on new G4s).
- *      01/02/2002 [0.7] - BenH
- *             - all sort of minor bits went in since the latest update, I
- *               bumped the version number for that reason
- *
- *      07/26/2002 [0.8] - BenH
- *             - More minor bits since last changelog (I should be more careful
- *               with those)
- *             - Support for snapper & better tumbler integration by Toby Sargeant
- *             - Headphone detect for scremer by Julien Blache
- *             - More tumbler fixed by Andreas Schwab
- *     11/29/2003 [0.8.1] - Renzo Davoli (King Enzo)
- *             - Support for Snapper line in
- *             - snapper input resampling (for rates < 44100)
- *             - software line gain control
- */
-
-/* GENERAL FIXME/TODO: check that the assumptions about what is written to
-   mac-io is valid for DACA & Tumbler.
-
-   This driver is in bad need of a rewrite. The dbdma code has to be split,
-   some proper device-tree parsing code has to be written, etc...
-*/
-
-#include <linux/types.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/soundcard.h>
-#include <linux/adb.h>
-#include <linux/nvram.h>
-#include <linux/tty.h>
-#include <linux/vt_kern.h>
-#include <linux/spinlock.h>
-#include <linux/kmod.h>
-#include <linux/interrupt.h>
-#include <linux/input.h>
-#include <linux/mutex.h>
-#ifdef CONFIG_ADB_CUDA
-#include <linux/cuda.h>
-#endif
-#ifdef CONFIG_ADB_PMU
-#include <linux/pmu.h>
-#endif
-
-#include <asm/uaccess.h>
-#include <asm/prom.h>
-#include <asm/machdep.h>
-#include <asm/io.h>
-#include <asm/dbdma.h>
-#include <asm/pmac_feature.h>
-#include <asm/irq.h>
-#include <asm/nvram.h>
-
-#include "awacs_defs.h"
-#include "dmasound.h"
-#include "tas3001c.h"
-#include "tas3004.h"
-#include "tas_common.h"
-
-#define DMASOUND_AWACS_REVISION        0
-#define DMASOUND_AWACS_EDITION 7
-
-#define AWACS_SNAPPER   110    /* fake revision # for snapper */
-#define AWACS_BURGUNDY 100     /* fake revision # for burgundy */
-#define AWACS_TUMBLER    90    /* fake revision # for tumbler */
-#define AWACS_DACA      80     /* fake revision # for daca (ibook) */
-#define AWACS_AWACS       2     /* holding revision for AWACS */
-#define AWACS_SCREAMER    3     /* holding revision for Screamer */
-/*
- * Interrupt numbers and addresses, & info obtained from the device tree.
- */
-static int awacs_irq, awacs_tx_irq, awacs_rx_irq;
-static volatile struct awacs_regs __iomem *awacs;
-static volatile u32 __iomem *i2s;
-static volatile struct dbdma_regs __iomem *awacs_txdma, *awacs_rxdma;
-static int awacs_rate_index;
-static int awacs_subframe;
-static struct device_node* awacs_node;
-static struct device_node* i2s_node;
-static struct resource awacs_rsrc[3];
-
-static char awacs_name[64];
-static int awacs_revision;
-static int awacs_sleeping;
-static DEFINE_MUTEX(dmasound_mutex);
-
-static int sound_device_id;            /* exists after iMac revA */
-static int hw_can_byteswap = 1 ;       /* most pmac sound h/w can */
-
-/* model info */
-/* To be replaced with better interaction with pmac_feature.c */
-static int is_pbook_3X00;
-static int is_pbook_g3;
-
-/* expansion info */
-static int has_perch;
-static int has_ziva;
-
-/* for earlier powerbooks which need fiddling with mac-io to enable
- * cd etc.
-*/
-static unsigned char __iomem *latch_base;
-static unsigned char __iomem *macio_base;
-
-/*
- * Space for the DBDMA command blocks.
- */
-static void *awacs_tx_cmd_space;
-static volatile struct dbdma_cmd *awacs_tx_cmds;
-static int number_of_tx_cmd_buffers;
-
-static void *awacs_rx_cmd_space;
-static volatile struct dbdma_cmd *awacs_rx_cmds;
-static int number_of_rx_cmd_buffers;
-
-/*
- * Cached values of AWACS registers (we can't read them).
- * Except on the burgundy (and screamer). XXX
- */
-
-int awacs_reg[8];
-int awacs_reg1_save;
-
-/* tracking values for the mixer contents
-*/
-
-static int spk_vol;
-static int line_vol;
-static int passthru_vol;
-
-static int ip_gain;           /* mic preamp settings */
-static int rec_lev = 0x4545 ; /* default CD gain 69 % */
-static int mic_lev;
-static int cd_lev = 0x6363 ; /* 99 % */
-static int line_lev;
-
-static int hdp_connected;
-
-/*
- * Stuff for outputting a beep.  The values range from -327 to +327
- * so we can multiply by an amplitude in the range 0..100 to get a
- * signed short value to put in the output buffer.
- */
-static short beep_wform[256] = {
-       0,      40,     79,     117,    153,    187,    218,    245,
-       269,    288,    304,    316,    323,    327,    327,    324,
-       318,    310,    299,    288,    275,    262,    249,    236,
-       224,    213,    204,    196,    190,    186,    183,    182,
-       182,    183,    186,    189,    192,    196,    200,    203,
-       206,    208,    209,    209,    209,    207,    204,    201,
-       197,    193,    188,    183,    179,    174,    170,    166,
-       163,    161,    160,    159,    159,    160,    161,    162,
-       164,    166,    168,    169,    171,    171,    171,    170,
-       169,    167,    163,    159,    155,    150,    144,    139,
-       133,    128,    122,    117,    113,    110,    107,    105,
-       103,    103,    103,    103,    104,    104,    105,    105,
-       105,    103,    101,    97,     92,     86,     78,     68,
-       58,     45,     32,     18,     3,      -11,    -26,    -41,
-       -55,    -68,    -79,    -88,    -95,    -100,   -102,   -102,
-       -99,    -93,    -85,    -75,    -62,    -48,    -33,    -16,
-       0,      16,     33,     48,     62,     75,     85,     93,
-       99,     102,    102,    100,    95,     88,     79,     68,
-       55,     41,     26,     11,     -3,     -18,    -32,    -45,
-       -58,    -68,    -78,    -86,    -92,    -97,    -101,   -103,
-       -105,   -105,   -105,   -104,   -104,   -103,   -103,   -103,
-       -103,   -105,   -107,   -110,   -113,   -117,   -122,   -128,
-       -133,   -139,   -144,   -150,   -155,   -159,   -163,   -167,
-       -169,   -170,   -171,   -171,   -171,   -169,   -168,   -166,
-       -164,   -162,   -161,   -160,   -159,   -159,   -160,   -161,
-       -163,   -166,   -170,   -174,   -179,   -183,   -188,   -193,
-       -197,   -201,   -204,   -207,   -209,   -209,   -209,   -208,
-       -206,   -203,   -200,   -196,   -192,   -189,   -186,   -183,
-       -182,   -182,   -183,   -186,   -190,   -196,   -204,   -213,
-       -224,   -236,   -249,   -262,   -275,   -288,   -299,   -310,
-       -318,   -324,   -327,   -327,   -323,   -316,   -304,   -288,
-       -269,   -245,   -218,   -187,   -153,   -117,   -79,    -40,
-};
-
-/* beep support */
-#define BEEP_SRATE     22050   /* 22050 Hz sample rate */
-#define BEEP_BUFLEN    512
-#define BEEP_VOLUME    15      /* 0 - 100 */
-
-static int beep_vol = BEEP_VOLUME;
-static int beep_playing;
-static int awacs_beep_state;
-static short *beep_buf;
-static void *beep_dbdma_cmd_space;
-static volatile struct dbdma_cmd *beep_dbdma_cmd;
-
-/* Burgundy functions */
-static void awacs_burgundy_wcw(unsigned addr,unsigned newval);
-static unsigned awacs_burgundy_rcw(unsigned addr);
-static void awacs_burgundy_write_volume(unsigned address, int volume);
-static int awacs_burgundy_read_volume(unsigned address);
-static void awacs_burgundy_write_mvolume(unsigned address, int volume);
-static int awacs_burgundy_read_mvolume(unsigned address);
-
-/* we will allocate a single 'emergency' dbdma cmd block to use if the
-   tx status comes up "DEAD".  This happens on some PowerComputing Pmac
-   clones, either owing to a bug in dbdma or some interaction between
-   IDE and sound.  However, this measure would deal with DEAD status if
-   if appeared elsewhere.
-
-   for the sake of memory efficiency we'll allocate this cmd as part of
-   the beep cmd stuff.
-*/
-
-static volatile struct dbdma_cmd *emergency_dbdma_cmd;
-
-#ifdef CONFIG_PM
-/*
- * Stuff for restoring after a sleep.
- */
-static void awacs_sleep_notify(struct pmu_sleep_notifier *self, int when);
-struct pmu_sleep_notifier awacs_sleep_notifier = {
-       awacs_sleep_notify, SLEEP_LEVEL_SOUND,
-};
-#endif /* CONFIG_PM */
-
-/* for (soft) sample rate translations */
-int expand_bal;                /* Balance factor for expanding (not volume!) */
-int expand_read_bal;   /* Balance factor for expanding reads (not volume!) */
-
-/*** Low level stuff *********************************************************/
-
-static void *PMacAlloc(unsigned int size, gfp_t flags);
-static void PMacFree(void *ptr, unsigned int size);
-static int PMacIrqInit(void);
-#ifdef MODULE
-static void PMacIrqCleanup(void);
-#endif
-static void PMacSilence(void);
-static void PMacInit(void);
-static int PMacSetFormat(int format);
-static int PMacSetVolume(int volume);
-static void PMacPlay(void);
-static void PMacRecord(void);
-static irqreturn_t pmac_awacs_tx_intr(int irq, void *devid);
-static irqreturn_t pmac_awacs_rx_intr(int irq, void *devid);
-static irqreturn_t pmac_awacs_intr(int irq, void *devid);
-static void awacs_write(int val);
-static int awacs_get_volume(int reg, int lshift);
-static int awacs_volume_setter(int volume, int n, int mute, int lshift);
-
-
-/*** Mid level stuff **********************************************************/
-
-static int PMacMixerIoctl(u_int cmd, u_long arg);
-static int PMacWriteSqSetup(void);
-static int PMacReadSqSetup(void);
-static void PMacAbortRead(void);
-
-extern TRANS transAwacsNormal ;
-extern TRANS transAwacsExpand ;
-extern TRANS transAwacsNormalRead ;
-extern TRANS transAwacsExpandRead ;
-
-extern int daca_init(void);
-extern void daca_cleanup(void);
-extern int daca_set_volume(uint left_vol, uint right_vol);
-extern void daca_get_volume(uint * left_vol, uint  *right_vol);
-extern int daca_enter_sleep(void);
-extern int daca_leave_sleep(void);
-
-#define TRY_LOCK()     \
-       if ((rc = mutex_lock_interruptible(&dmasound_mutex)) != 0)      \
-               return rc;
-#define LOCK()         mutex_lock(&dmasound_mutex);
-
-#define UNLOCK()       mutex_unlock(&dmasound_mutex);
-
-/* We use different versions that the ones provided in dmasound.h
- * 
- * FIXME: Use different names ;)
- */
-#undef IOCTL_IN
-#undef IOCTL_OUT
-
-#define IOCTL_IN(arg, ret)     \
-       rc = get_user(ret, (int __user *)(arg)); \
-       if (rc) break;
-#define IOCTL_OUT(arg, ret)    \
-       ioctl_return2((int __user *)(arg), ret)
-
-static inline int ioctl_return2(int __user *addr, int value)
-{
-       return value < 0 ? value : put_user(value, addr);
-}
-
-
-/*** AE - TUMBLER / SNAPPER START ************************************************/
-
-
-int gpio_audio_reset, gpio_audio_reset_pol;
-int gpio_amp_mute, gpio_amp_mute_pol;
-int gpio_headphone_mute, gpio_headphone_mute_pol;
-int gpio_headphone_detect, gpio_headphone_detect_pol;
-int gpio_headphone_irq;
-
-int
-setup_audio_gpio(const char *name, const char* compatible, int *gpio_addr, int* gpio_pol)
-{
-       struct device_node *gpiop;
-       struct device_node *np;
-       const u32* pp;
-       int ret = -ENODEV;
-
-       gpiop = of_find_node_by_name(NULL, "gpio");
-       if (!gpiop)
-               goto done;
-
-       np = of_get_next_child(gpiop, NULL);
-       while(np != 0) {
-               if (name) {
-                       const char *property =
-                               of_get_property(np,"audio-gpio",NULL);
-                       if (property != 0 && strcmp(property,name) == 0)
-                               break;
-               } else if (compatible && of_device_is_compatible(np, compatible))
-                       break;
-               np = of_get_next_child(gpiop, np);
-       }
-       if (!np)
-               goto done;
-       pp = of_get_property(np, "AAPL,address", NULL);
-       if (!pp)
-               goto done;
-       *gpio_addr = (*pp) & 0x0000ffff;
-       pp = of_get_property(np, "audio-gpio-active-state", NULL);
-       if (pp)
-               *gpio_pol = *pp;
-       else
-               *gpio_pol = 1;
-       ret = irq_of_parse_and_map(np, 0);
-done:
-       of_node_put(np);
-       of_node_put(gpiop);
-       return ret;
-}
-
-static inline void
-write_audio_gpio(int gpio_addr, int data)
-{
-       if (!gpio_addr)
-               return;
-       pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, gpio_addr, data ? 0x05 : 0x04);
-}
-
-static inline int
-read_audio_gpio(int gpio_addr)
-{
-       if (!gpio_addr)
-               return 0;
-       return ((pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, gpio_addr, 0) & 0x02) !=0);
-}
-
-/*
- * Headphone interrupt via GPIO (Tumbler, Snapper, DACA)
- */
-static irqreturn_t
-headphone_intr(int irq, void *devid)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&dmasound.lock, flags);
-       if (read_audio_gpio(gpio_headphone_detect) == gpio_headphone_detect_pol) {
-               printk(KERN_INFO "Audio jack plugged, muting speakers.\n");
-               write_audio_gpio(gpio_headphone_mute, !gpio_headphone_mute_pol);
-               write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol);
-               tas_output_device_change(sound_device_id,TAS_OUTPUT_HEADPHONES,0);
-       } else {
-               printk(KERN_INFO "Audio jack unplugged, enabling speakers.\n");
-               write_audio_gpio(gpio_amp_mute, !gpio_amp_mute_pol);
-               write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol);
-               tas_output_device_change(sound_device_id,TAS_OUTPUT_INTERNAL_SPKR,0);
-       }
-       spin_unlock_irqrestore(&dmasound.lock, flags);
-       return IRQ_HANDLED;
-}
-
-
-/* Initialize tumbler */
-
-static int
-tas_dmasound_init(void)
-{
-       setup_audio_gpio(
-               "audio-hw-reset",
-               NULL,
-               &gpio_audio_reset,
-               &gpio_audio_reset_pol);
-       setup_audio_gpio(
-               "amp-mute",
-               NULL,
-               &gpio_amp_mute,
-               &gpio_amp_mute_pol);
-       setup_audio_gpio("headphone-mute",
-               NULL,
-               &gpio_headphone_mute,
-               &gpio_headphone_mute_pol);
-       gpio_headphone_irq = setup_audio_gpio(
-               "headphone-detect",
-               NULL,
-               &gpio_headphone_detect,
-               &gpio_headphone_detect_pol);
-       /* Fix some broken OF entries in desktop machines */
-       if (!gpio_headphone_irq)
-               gpio_headphone_irq = setup_audio_gpio(
-                       NULL,
-                       "keywest-gpio15",
-                       &gpio_headphone_detect,
-                       &gpio_headphone_detect_pol);
-
-       write_audio_gpio(gpio_audio_reset, gpio_audio_reset_pol);
-       msleep(100);
-       write_audio_gpio(gpio_audio_reset, !gpio_audio_reset_pol);
-       msleep(100);
-       if (gpio_headphone_irq) {
-               if (request_irq(gpio_headphone_irq,headphone_intr,0,"Headphone detect",NULL) < 0) {
-                       printk(KERN_ERR "tumbler: Can't request headphone interrupt\n");
-                       gpio_headphone_irq = 0;
-               } else {
-                       u8 val;
-                       /* Activate headphone status interrupts */
-                       val = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, gpio_headphone_detect, 0);
-                       pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, gpio_headphone_detect, val | 0x80);
-                       /* Trigger it */
-                       headphone_intr(0, NULL);
-               }
-       }
-       if (!gpio_headphone_irq) {
-               /* Some machine enter this case ? */
-               printk(KERN_WARNING "tumbler: Headphone detect IRQ not found, enabling all outputs !\n");
-               write_audio_gpio(gpio_amp_mute, !gpio_amp_mute_pol);
-               write_audio_gpio(gpio_headphone_mute, !gpio_headphone_mute_pol);
-       }
-       return 0;
-}
-
-
-static int
-tas_dmasound_cleanup(void)
-{
-       if (gpio_headphone_irq)
-               free_irq(gpio_headphone_irq, NULL);
-       return 0;
-}
-
-/* We don't support 48k yet */
-static int tas_freqs[1] = { 44100 } ;
-static int tas_freqs_ok[1] = { 1 } ;
-
-/* don't know what to do really - just have to leave it where
- * OF left things
-*/
-
-static int
-tas_set_frame_rate(void)
-{
-       if (i2s) {
-               out_le32(i2s + (I2S_REG_SERIAL_FORMAT >> 2), 0x41190000);
-               out_le32(i2s + (I2S_REG_DATAWORD_SIZES >> 2), 0x02000200);
-       }
-       dmasound.hard.speed = 44100 ;
-       awacs_rate_index = 0 ;
-       return 44100 ;
-}
-
-static int
-tas_mixer_ioctl(u_int cmd, u_long arg)
-{
-       int __user *argp = (int __user *)arg;
-       int data;
-       int rc;
-
-        rc=tas_device_ioctl(cmd, arg);
-        if (rc != -EINVAL) {
-               return rc;
-        }
-
-        if ((cmd & ~0xff) == MIXER_WRITE(0) &&
-            tas_supported_mixers() & (1<<(cmd & 0xff))) {
-               rc = get_user(data, argp);
-                if (rc<0) return rc;
-               tas_set_mixer_level(cmd & 0xff, data);
-               tas_get_mixer_level(cmd & 0xff, &data);
-               return ioctl_return2(argp, data);
-        }
-        if ((cmd & ~0xff) == MIXER_READ(0) &&
-            tas_supported_mixers() & (1<<(cmd & 0xff))) {
-               tas_get_mixer_level(cmd & 0xff, &data);
-               return ioctl_return2(argp, data);
-        }
-
-       switch(cmd) {
-       case SOUND_MIXER_READ_DEVMASK:
-               data = tas_supported_mixers() | SOUND_MASK_SPEAKER;
-               rc = IOCTL_OUT(arg, data);
-               break;
-       case SOUND_MIXER_READ_STEREODEVS:
-               data = tas_stereo_mixers();
-               rc = IOCTL_OUT(arg, data);
-               break;
-       case SOUND_MIXER_READ_CAPS:
-               rc = IOCTL_OUT(arg, 0);
-               break;
-       case SOUND_MIXER_READ_RECMASK:
-               // XXX FIXME: find a way to check what is really available */
-               data = SOUND_MASK_LINE | SOUND_MASK_MIC;
-               rc = IOCTL_OUT(arg, data);
-               break;
-       case SOUND_MIXER_READ_RECSRC:
-               if (awacs_reg[0] & MASK_MUX_AUDIN)
-                       data |= SOUND_MASK_LINE;
-               if (awacs_reg[0] & MASK_MUX_MIC)
-                       data |= SOUND_MASK_MIC;
-               rc = IOCTL_OUT(arg, data);
-               break;
-       case SOUND_MIXER_WRITE_RECSRC:
-               IOCTL_IN(arg, data);
-               data =0;
-               rc = IOCTL_OUT(arg, data);
-               break;
-       case SOUND_MIXER_WRITE_SPEAKER: /* really bell volume */
-               IOCTL_IN(arg, data);
-               beep_vol = data & 0xff;
-               /* fall through */
-       case SOUND_MIXER_READ_SPEAKER:
-               rc = IOCTL_OUT(arg, (beep_vol<<8) | beep_vol);
-               break;
-       case SOUND_MIXER_OUTMASK:
-       case SOUND_MIXER_OUTSRC:
-       default:
-               rc = -EINVAL;
-       }
-
-       return rc;
-}
-
-static void __init
-tas_init_frame_rates(const unsigned int *prop, unsigned int l)
-{
-       int i ;
-       if (prop) {
-               for (i=0; i<1; i++)
-                       tas_freqs_ok[i] = 0;
-               for (l /= sizeof(int); l > 0; --l) {
-                       unsigned int r = *prop++;
-                       /* Apple 'Fixed' format */
-                       if (r >= 0x10000)
-                               r >>= 16;
-                       for (i = 0; i < 1; ++i) {
-                               if (r == tas_freqs[i]) {
-                                       tas_freqs_ok[i] = 1;
-                                       break;
-                               }
-                       }
-               }
-       }
-       /* else we assume that all the rates are available */
-}
-
-
-/*** AE - TUMBLER / SNAPPER END ************************************************/
-
-
-
-/*** Low level stuff *********************************************************/
-
-/*
- * PCI PowerMac, with AWACS, Screamer, Burgundy, DACA or Tumbler and DBDMA.
- */
-static void *PMacAlloc(unsigned int size, gfp_t flags)
-{
-       return kmalloc(size, flags);
-}
-
-static void PMacFree(void *ptr, unsigned int size)
-{
-       kfree(ptr);
-}
-
-static int __init PMacIrqInit(void)
-{
-       if (awacs)
-               if (request_irq(awacs_irq, pmac_awacs_intr, 0, "Built-in Sound misc", NULL))
-                       return 0;
-       if (request_irq(awacs_tx_irq, pmac_awacs_tx_intr, 0, "Built-in Sound out", NULL)
-           || request_irq(awacs_rx_irq, pmac_awacs_rx_intr, 0, "Built-in Sound in", NULL))
-               return 0;
-       return 1;
-}
-
-#ifdef MODULE
-static void PMacIrqCleanup(void)
-{
-       /* turn off input & output dma */
-       DBDMA_DO_STOP(awacs_txdma);
-       DBDMA_DO_STOP(awacs_rxdma);
-
-       if (awacs)
-               /* disable interrupts from awacs interface */
-               out_le32(&awacs->control, in_le32(&awacs->control) & 0xfff);
-       
-       /* Switch off the sound clock */
-       pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 0);
-       /* Make sure proper bits are set on pismo & tipb */
-       if ((machine_is_compatible("PowerBook3,1") ||
-           machine_is_compatible("PowerBook3,2")) && awacs) {
-               awacs_reg[1] |= MASK_PAROUT0 | MASK_PAROUT1;
-               awacs_write(MASK_ADDR1 | awacs_reg[1]);
-               msleep(200);
-       }
-       if (awacs)
-               free_irq(awacs_irq, NULL);
-       free_irq(awacs_tx_irq, NULL);
-       free_irq(awacs_rx_irq, NULL);
-       
-       if (awacs)
-               iounmap(awacs);
-       if (i2s)
-               iounmap(i2s);
-       iounmap(awacs_txdma);
-       iounmap(awacs_rxdma);
-
-       release_mem_region(awacs_rsrc[0].start,
-                          awacs_rsrc[0].end - awacs_rsrc[0].start + 1);
-       release_mem_region(awacs_rsrc[1].start,
-                          awacs_rsrc[1].end - awacs_rsrc[1].start + 1);
-       release_mem_region(awacs_rsrc[2].start,
-                          awacs_rsrc[2].end - awacs_rsrc[2].start + 1);
-
-       kfree(awacs_tx_cmd_space);
-       kfree(awacs_rx_cmd_space);
-       kfree(beep_dbdma_cmd_space);
-       kfree(beep_buf);
-#ifdef CONFIG_PM
-       pmu_unregister_sleep_notifier(&awacs_sleep_notifier);
-#endif
-}
-#endif /* MODULE */
-
-static void PMacSilence(void)
-{
-       /* turn off output dma */
-       DBDMA_DO_STOP(awacs_txdma);
-}
-
-/* don't know what to do really - just have to leave it where
- * OF left things
-*/
-
-static int daca_set_frame_rate(void)
-{
-       if (i2s) {
-               out_le32(i2s + (I2S_REG_SERIAL_FORMAT >> 2), 0x41190000);
-               out_le32(i2s + (I2S_REG_DATAWORD_SIZES >> 2), 0x02000200);
-       }
-       dmasound.hard.speed = 44100 ;
-       awacs_rate_index = 0 ;
-       return 44100 ;
-}
-
-static int awacs_freqs[8] = {
-       44100, 29400, 22050, 17640, 14700, 11025, 8820, 7350
-};
-static int awacs_freqs_ok[8] = { 1, 1, 1, 1, 1, 1, 1, 1 };
-
-static int
-awacs_set_frame_rate(int desired, int catch_r)
-{
-       int tolerance, i = 8 ;
-       /*
-        * If we have a sample rate which is within catchRadius percent
-        * of the requested value, we don't have to expand the samples.
-        * Otherwise choose the next higher rate.
-        * N.B.: burgundy awacs only works at 44100 Hz.
-        */
-       do {
-               tolerance = catch_r * awacs_freqs[--i] / 100;
-               if (awacs_freqs_ok[i]
-                   && dmasound.soft.speed <= awacs_freqs[i] + tolerance)
-                       break;
-       } while (i > 0);
-       dmasound.hard.speed = awacs_freqs[i];
-       awacs_rate_index = i;
-
-       out_le32(&awacs->control, MASK_IEPC | (i << 8) | 0x11 );
-       awacs_reg[1] = (awacs_reg[1] & ~MASK_SAMPLERATE) | (i << 3);
-       awacs_write(awacs_reg[1] | MASK_ADDR1);
-       return dmasound.hard.speed;
-}
-
-static int
-burgundy_set_frame_rate(void)
-{
-       awacs_rate_index = 0 ;
-       awacs_reg[1] = (awacs_reg[1] & ~MASK_SAMPLERATE) ;
-       /* XXX disable error interrupt on burgundy for now */
-       out_le32(&awacs->control, MASK_IEPC | 0 | 0x11 | MASK_IEE);
-       return 44100 ;
-}
-
-static int
-set_frame_rate(int desired, int catch_r)
-{
-       switch (awacs_revision) {
-               case AWACS_BURGUNDY:
-                       dmasound.hard.speed = burgundy_set_frame_rate();
-                       break ;
-               case AWACS_TUMBLER:
-               case AWACS_SNAPPER:
-                       dmasound.hard.speed = tas_set_frame_rate();
-                       break ;
-               case AWACS_DACA:
-                       dmasound.hard.speed =
-                         daca_set_frame_rate();
-                       break ;
-               default:
-                       dmasound.hard.speed = awacs_set_frame_rate(desired,
-                                               catch_r);
-                       break ;
-       }
-       return dmasound.hard.speed ;
-}
-
-static void
-awacs_recalibrate(void)
-{
-       /* Sorry for the horrible delays... I hope to get that improved
-        * by making the whole PM process asynchronous in a future version
-        */
-       msleep(750);
-       awacs_reg[1] |= MASK_CMUTE | MASK_AMUTE;
-       awacs_write(awacs_reg[1] | MASK_RECALIBRATE | MASK_ADDR1);
-       msleep(1000);
-       awacs_write(awacs_reg[1] | MASK_ADDR1);
-}
-
-static void PMacInit(void)
-{
-       int tolerance;
-
-       switch (dmasound.soft.format) {
-           case AFMT_S16_LE:
-           case AFMT_U16_LE:
-               if (hw_can_byteswap)
-                       dmasound.hard.format = AFMT_S16_LE;
-               else
-                       dmasound.hard.format = AFMT_S16_BE;
-               break;
-       default:
-               dmasound.hard.format = AFMT_S16_BE;
-               break;
-       }
-       dmasound.hard.stereo = 1;
-       dmasound.hard.size = 16;
-
-       /* set dmasound.hard.speed - on the basis of what we want (soft)
-        * and the tolerance we'll allow.
-       */
-       set_frame_rate(dmasound.soft.speed, catchRadius) ;
-
-       tolerance = (catchRadius * dmasound.hard.speed) / 100;
-       if (dmasound.soft.speed >= dmasound.hard.speed - tolerance) {
-               dmasound.trans_write = &transAwacsNormal;
-               dmasound.trans_read = &transAwacsNormalRead;
-       } else {
-               dmasound.trans_write = &transAwacsExpand;
-               dmasound.trans_read = &transAwacsExpandRead;
-       }
-
-       if (awacs) {
-               if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE))
-                       out_le32(&awacs->byteswap, BS_VAL);
-               else
-                       out_le32(&awacs->byteswap, 0);
-       }
-       
-       expand_bal = -dmasound.soft.speed;
-       expand_read_bal = -dmasound.soft.speed;
-}
-
-static int PMacSetFormat(int format)
-{
-       int size;
-       int req_format = format;
-               
-       switch (format) {
-       case AFMT_QUERY:
-               return dmasound.soft.format;
-       case AFMT_MU_LAW:
-       case AFMT_A_LAW:
-       case AFMT_U8:
-       case AFMT_S8:
-               size = 8;
-               break;
-       case AFMT_S16_LE:
-               if(!hw_can_byteswap)
-                       format = AFMT_S16_BE;
-       case AFMT_S16_BE:
-               size = 16;
-               break;
-       case AFMT_U16_LE:
-               if(!hw_can_byteswap)
-                       format = AFMT_U16_BE;
-       case AFMT_U16_BE:
-               size = 16;
-               break;
-       default: /* :-) */
-               printk(KERN_ERR "dmasound: unknown format 0x%x, using AFMT_U8\n",
-                      format);
-               size = 8;
-               format = AFMT_U8;
-       }
-       
-       if (req_format == format) {
-               dmasound.soft.format = format;
-               dmasound.soft.size = size;
-               if (dmasound.minDev == SND_DEV_DSP) {
-                       dmasound.dsp.format = format;
-                       dmasound.dsp.size = size;
-               }
-       }
-
-       return format;
-}
-
-#define AWACS_VOLUME_TO_MASK(x)        (15 - ((((x) - 1) * 15) / 99))
-#define AWACS_MASK_TO_VOLUME(y)        (100 - ((y) * 99 / 15))
-
-static int awacs_get_volume(int reg, int lshift)
-{
-       int volume;
-
-       volume = AWACS_MASK_TO_VOLUME((reg >> lshift) & 0xf);
-       volume |= AWACS_MASK_TO_VOLUME(reg & 0xf) << 8;
-       return volume;
-}
-
-static int awacs_volume_setter(int volume, int n, int mute, int lshift)
-{
-       int r1, rn;
-
-       if (mute && volume == 0) {
-               r1 = awacs_reg[1] | mute;
-       } else {
-               r1 = awacs_reg[1] & ~mute;
-               rn = awacs_reg[n] & ~(0xf | (0xf << lshift));
-               rn |= ((AWACS_VOLUME_TO_MASK(volume & 0xff) & 0xf) << lshift);
-               rn |= AWACS_VOLUME_TO_MASK((volume >> 8) & 0xff) & 0xf;
-               awacs_reg[n] = rn;
-               awacs_write((n << 12) | rn);
-               volume = awacs_get_volume(rn, lshift);
-       }
-       if (r1 != awacs_reg[1]) {
-               awacs_reg[1] = r1;
-               awacs_write(r1 | MASK_ADDR1);
-       }
-       return volume;
-}
-
-static int PMacSetVolume(int volume)
-{
-       printk(KERN_WARNING "Bogus call to PMacSetVolume !\n");
-       return 0;
-}
-
-static void awacs_setup_for_beep(int speed)
-{
-       out_le32(&awacs->control,
-                (in_le32(&awacs->control) & ~0x1f00)
-                | ((speed > 0 ? speed : awacs_rate_index) << 8));
-
-       if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE) && speed == -1)
-               out_le32(&awacs->byteswap, BS_VAL);
-       else
-               out_le32(&awacs->byteswap, 0);
-}
-
-/* CHECK: how much of this *really* needs IRQs masked? */
-static void __PMacPlay(void)
-{
-       volatile struct dbdma_cmd *cp;
-       int next_frg, count;
-
-       count = 300 ; /* > two cycles at the lowest sample rate */
-
-       /* what we want to send next */
-       next_frg = (write_sq.front + write_sq.active) % write_sq.max_count;
-
-       if (awacs_beep_state) {
-               /* sound takes precedence over beeps */
-               /* stop the dma channel */
-               out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
-               while ( (in_le32(&awacs_txdma->status) & RUN) && count--)
-                       udelay(1);
-               if (awacs)
-                       awacs_setup_for_beep(-1);
-               out_le32(&awacs_txdma->cmdptr,
-                        virt_to_bus(&(awacs_tx_cmds[next_frg])));
-
-               beep_playing = 0;
-               awacs_beep_state = 0;
-       }
-       /* this won't allow more than two frags to be in the output queue at
-          once. (or one, if the max frags is 2 - because count can't exceed
-          2 in that case)
-       */
-       while (write_sq.active < 2 && write_sq.active < write_sq.count) {
-               count = (write_sq.count == write_sq.active + 1) ?
-                               write_sq.rear_size:write_sq.block_size ;
-               if (count < write_sq.block_size) {
-                       if (!write_sq.syncing) /* last block not yet filled,*/
-                               break;  /* and we're not syncing or POST-ed */
-                       else {
-                               /* pretend the block is full to force a new
-                                  block to be started on the next write */
-                               write_sq.rear_size = write_sq.block_size ;
-                               write_sq.syncing &= ~2 ; /* clear POST */
-                       }
-               }
-               cp = &awacs_tx_cmds[next_frg];
-               st_le16(&cp->req_count, count);
-               st_le16(&cp->xfer_status, 0);
-               st_le16(&cp->command, OUTPUT_MORE + INTR_ALWAYS);
-               /* put a STOP at the end of the queue - but only if we have
-                  space for it.  This means that, if we under-run and we only
-                  have two fragments, we might re-play sound from an existing
-                  queued frag.  I guess the solution to that is not to set two
-                  frags if you are likely to under-run...
-               */
-               if (write_sq.count < write_sq.max_count) {
-                       if (++next_frg >= write_sq.max_count)
-                               next_frg = 0 ; /* wrap */
-                       /* if we get here then we've underrun so we will stop*/
-                       st_le16(&awacs_tx_cmds[next_frg].command, DBDMA_STOP);
-               }
-               /* set the dbdma controller going, if it is not already */
-               if (write_sq.active == 0)
-                       out_le32(&awacs_txdma->cmdptr, virt_to_bus(cp));
-               (void)in_le32(&awacs_txdma->status);
-               out_le32(&awacs_txdma->control, ((RUN|WAKE) << 16) + (RUN|WAKE));
-               ++write_sq.active;
-       }
-}
-
-static void PMacPlay(void)
-{
-       LOCK();
-       if (!awacs_sleeping) {
-               unsigned long flags;
-
-               spin_lock_irqsave(&dmasound.lock, flags);
-               __PMacPlay();
-               spin_unlock_irqrestore(&dmasound.lock, flags);
-       }
-       UNLOCK();
-}
-
-static void PMacRecord(void)
-{
-       unsigned long flags;
-
-       if (read_sq.active)
-               return;
-
-       spin_lock_irqsave(&dmasound.lock, flags);
-
-       /* This is all we have to do......Just start it up.
-       */
-       out_le32(&awacs_rxdma->control, ((RUN|WAKE) << 16) + (RUN|WAKE));
-       read_sq.active = 1;
-
-       spin_unlock_irqrestore(&dmasound.lock, flags);
-}
-
-/* if the TX status comes up "DEAD" - reported on some Power Computing machines
-   we need to re-start the dbdma - but from a different physical start address
-   and with a different transfer length.  It would get very messy to do this
-   with the normal dbdma_cmd blocks - we would have to re-write the buffer start
-   addresses each time.  So, we will keep a single dbdma_cmd block which can be
-   fiddled with.
-   When DEAD status is first reported the content of the faulted dbdma block is
-   copied into the emergency buffer and we note that the buffer is in use.
-   we then bump the start physical address by the amount that was successfully
-   output before it died.
-   On any subsequent DEAD result we just do the bump-ups (we know that we are
-   already using the emergency dbdma_cmd).
-   CHECK: this just tries to "do it".  It is possible that we should abandon
-   xfers when the number of residual bytes gets below a certain value - I can
-   see that this might cause a loop-forever if too small a transfer causes
-   DEAD status.  However this is a TODO for now - we'll see what gets reported.
-   When we get a successful transfer result with the emergency buffer we just
-   pretend that it completed using the original dmdma_cmd and carry on.  The
-   'next_cmd' field will already point back to the original loop of blocks.
-*/
-
-static irqreturn_t
-pmac_awacs_tx_intr(int irq, void *devid)
-{
-       int i = write_sq.front;
-       int stat;
-       int i_nowrap = write_sq.front;
-       volatile struct dbdma_cmd *cp;
-       /* != 0 when we are dealing with a DEAD xfer */
-       static int emergency_in_use;
-
-       spin_lock(&dmasound.lock);
-       while (write_sq.active > 0) { /* we expect to have done something*/
-               if (emergency_in_use) /* we are dealing with DEAD xfer */
-                       cp = emergency_dbdma_cmd ;
-               else
-                       cp = &awacs_tx_cmds[i];
-               stat = ld_le16(&cp->xfer_status);
-               if (stat & DEAD) {
-                       unsigned short req, res ;
-                       unsigned int phy ;
-#ifdef DEBUG_DMASOUND
-printk("dmasound_pmac: tx-irq: xfer died - patching it up...\n") ;
-#endif
-                       /* to clear DEAD status we must first clear RUN
-                          set it to quiescent to be on the safe side */
-                       (void)in_le32(&awacs_txdma->status);
-                       out_le32(&awacs_txdma->control,
-                               (RUN|PAUSE|FLUSH|WAKE) << 16);
-                       write_sq.died++ ;
-                       if (!emergency_in_use) { /* new problem */
-                               memcpy((void *)emergency_dbdma_cmd, (void *)cp,
-                                       sizeof(struct dbdma_cmd));
-                               emergency_in_use = 1;
-                               cp = emergency_dbdma_cmd;
-                       }
-                       /* now bump the values to reflect the amount
-                          we haven't yet shifted */
-                       req = ld_le16(&cp->req_count);
-                       res = ld_le16(&cp->res_count);
-                       phy = ld_le32(&cp->phy_addr);
-                       phy += (req - res);
-                       st_le16(&cp->req_count, res);
-                       st_le16(&cp->res_count, 0);
-                       st_le16(&cp->xfer_status, 0);
-                       st_le32(&cp->phy_addr, phy);
-                       st_le32(&cp->cmd_dep, virt_to_bus(&awacs_tx_cmds[(i+1)%write_sq.max_count]));
-                       st_le16(&cp->command, OUTPUT_MORE | BR_ALWAYS | INTR_ALWAYS);
-                       
-                       /* point at our patched up command block */
-                       out_le32(&awacs_txdma->cmdptr, virt_to_bus(cp));
-                       /* we must re-start the controller */
-                       (void)in_le32(&awacs_txdma->status);
-                       /* should complete clearing the DEAD status */
-                       out_le32(&awacs_txdma->control,
-                               ((RUN|WAKE) << 16) + (RUN|WAKE));
-                       break; /* this block is still going */
-               }
-               if ((stat & ACTIVE) == 0)
-                       break;  /* this frame is still going */
-               if (emergency_in_use)
-                       emergency_in_use = 0 ; /* done that */
-               --write_sq.count;
-               --write_sq.active;
-               i_nowrap++;
-               if (++i >= write_sq.max_count)
-                       i = 0;
-       }
-
-       /* if we stopped and we were not sync-ing - then we under-ran */
-       if( write_sq.syncing == 0 ){
-               stat = in_le32(&awacs_txdma->status) ;
-               /* we hit the dbdma_stop */
-               if( (stat & ACTIVE) == 0 ) write_sq.xruns++ ;
-       }
-
-       /* if we used some data up then wake the writer to supply some more*/
-       if (i_nowrap != write_sq.front)
-               WAKE_UP(write_sq.action_queue);
-       write_sq.front = i;
-
-       /* but make sure we funnel what we've already got */\
-        if (!awacs_sleeping)
-               __PMacPlay();
-
-       /* make the wake-on-empty conditional on syncing */
-       if (!write_sq.active && (write_sq.syncing & 1))
-               WAKE_UP(write_sq.sync_queue); /* any time we're empty */
-       spin_unlock(&dmasound.lock);
-       return IRQ_HANDLED;
-}
-
-
-static irqreturn_t
-pmac_awacs_rx_intr(int irq, void *devid)
-{
-       int stat ;
-       /* For some reason on my PowerBook G3, I get one interrupt
-        * when the interrupt vector is installed (like something is
-        * pending).  This happens before the dbdma is initialized by
-        * us, so I just check the command pointer and if it is zero,
-        * just blow it off.
-        */
-       if (in_le32(&awacs_rxdma->cmdptr) == 0)
-               return IRQ_HANDLED;
-
-       /* We also want to blow 'em off when shutting down.
-       */
-       if (read_sq.active == 0)
-               return IRQ_HANDLED;
-
-       spin_lock(&dmasound.lock);
-       /* Check multiple buffers in case we were held off from
-        * interrupt processing for a long time.  Geeze, I really hope
-        * this doesn't happen.
-        */
-       while ((stat=awacs_rx_cmds[read_sq.rear].xfer_status)) {
-
-               /* if we got a "DEAD" status then just log it for now.
-                  and try to restart dma.
-                  TODO: figure out how best to fix it up
-               */
-               if (stat & DEAD){
-#ifdef DEBUG_DMASOUND
-printk("dmasound_pmac: rx-irq: DIED - attempting resurection\n");
-#endif
-                       /* to clear DEAD status we must first clear RUN
-                          set it to quiescent to be on the safe side */
-                       (void)in_le32(&awacs_txdma->status);
-                       out_le32(&awacs_txdma->control,
-                               (RUN|PAUSE|FLUSH|WAKE) << 16);
-                       awacs_rx_cmds[read_sq.rear].xfer_status = 0;
-                       awacs_rx_cmds[read_sq.rear].res_count = 0;
-                       read_sq.died++ ;
-                       (void)in_le32(&awacs_txdma->status);
-                       /* re-start the same block */
-                       out_le32(&awacs_rxdma->cmdptr,
-                               virt_to_bus(&awacs_rx_cmds[read_sq.rear]));
-                       /* we must re-start the controller */
-                       (void)in_le32(&awacs_rxdma->status);
-                       /* should complete clearing the DEAD status */
-                       out_le32(&awacs_rxdma->control,
-                               ((RUN|WAKE) << 16) + (RUN|WAKE));
-                       spin_unlock(&dmasound.lock);
-                       return IRQ_HANDLED; /* try this block again */
-               }
-               /* Clear status and move on to next buffer.
-               */
-               awacs_rx_cmds[read_sq.rear].xfer_status = 0;
-               read_sq.rear++;
-
-               /* Wrap the buffer ring.
-               */
-               if (read_sq.rear >= read_sq.max_active)
-                       read_sq.rear = 0;
-
-               /* If we have caught up to the front buffer, bump it.
-                * This will cause weird (but not fatal) results if the
-                * read loop is currently using this buffer.  The user is
-                * behind in this case anyway, so weird things are going
-                * to happen.
-                */
-               if (read_sq.rear == read_sq.front) {
-                       read_sq.front++;
-                       read_sq.xruns++ ; /* we overan */
-                       if (read_sq.front >= read_sq.max_active)
-                               read_sq.front = 0;
-               }
-       }
-
-       WAKE_UP(read_sq.action_queue);
-       spin_unlock(&dmasound.lock);
-       return IRQ_HANDLED;
-}
-
-
-static irqreturn_t
-pmac_awacs_intr(int irq, void *devid)
-{
-       int ctrl;
-       int status;
-       int r1;
-
-       spin_lock(&dmasound.lock);
-       ctrl = in_le32(&awacs->control);
-       status = in_le32(&awacs->codec_stat);
-
-       if (ctrl & MASK_PORTCHG) {
-               /* tested on Screamer, should work on others too */
-               if (awacs_revision == AWACS_SCREAMER) {
-                       if (((status & MASK_HDPCONN) >> 3) && (hdp_connected == 0)) {
-                               hdp_connected = 1;
-                               
-                               r1 = awacs_reg[1] | MASK_SPKMUTE;
-                               awacs_reg[1] = r1;
-                               awacs_write(r1 | MASK_ADDR_MUTE);
-                       } else if (((status & MASK_HDPCONN) >> 3 == 0) && (hdp_connected == 1)) {
-                               hdp_connected = 0;
-                               
-                               r1 = awacs_reg[1] & ~MASK_SPKMUTE;
-                               awacs_reg[1] = r1;
-                               awacs_write(r1 | MASK_ADDR_MUTE);
-                       }
-               }
-       }
-       if (ctrl & MASK_CNTLERR) {
-               int err = (in_le32(&awacs->codec_stat) & MASK_ERRCODE) >> 16;
-               /* CHECK: we just swallow burgundy errors at the moment..*/
-               if (err != 0 && awacs_revision != AWACS_BURGUNDY)
-                       printk(KERN_ERR "dmasound_pmac: error %x\n", err);
-       }
-       /* Writing 1s to the CNTLERR and PORTCHG bits clears them... */
-       out_le32(&awacs->control, ctrl);
-       spin_unlock(&dmasound.lock);
-       return IRQ_HANDLED;
-}
-
-static void
-awacs_write(int val)
-{
-       int count = 300 ;
-       if (awacs_revision >= AWACS_DACA || !awacs)
-               return ;
-
-       while ((in_le32(&awacs->codec_ctrl) & MASK_NEWECMD) && count--)
-               udelay(1) ;     /* timeout is > 2 samples at lowest rate */
-       out_le32(&awacs->codec_ctrl, val | (awacs_subframe << 22));
-       (void)in_le32(&awacs->byteswap);
-}
-
-/* this is called when the beep timer expires... it will be called even
-   if the beep has been overidden by other sound output.
-*/
-static void awacs_nosound(unsigned long xx)
-{
-       unsigned long flags;
-       int count = 600 ; /* > four samples at lowest rate */
-
-       spin_lock_irqsave(&dmasound.lock, flags);
-       if (beep_playing) {
-               st_le16(&beep_dbdma_cmd->command, DBDMA_STOP);
-               out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
-               while ((in_le32(&awacs_txdma->status) & RUN) && count--)
-                       udelay(1);
-               if (awacs)
-                       awacs_setup_for_beep(-1);
-               beep_playing = 0;
-       }
-       spin_unlock_irqrestore(&dmasound.lock, flags);
-}
-
-/*
- * We generate the beep with a single dbdma command that loops a buffer
- * forever - without generating interrupts.
- *
- * So, to stop it you have to stop dma output as per awacs_nosound.
- */
-static int awacs_beep_event(struct input_dev *dev, unsigned int type,
-               unsigned int code, int hz)
-{
-       unsigned long flags;
-       int beep_speed = 0;
-       int srate;
-       int period, ncycles, nsamples;
-       int i, j, f;
-       short *p;
-       static int beep_hz_cache;
-       static int beep_nsamples_cache;
-       static int beep_volume_cache;
-
-       if (type != EV_SND)
-               return -1;
-       switch (code) {
-       case SND_BELL:
-               if (hz)
-                       hz = 1000;
-               break;
-       case SND_TONE:
-               break;
-       default:
-               return -1;
-       }
-
-       if (beep_buf == NULL)
-               return -1;
-
-       /* quick-hack fix for DACA, Burgundy & Tumbler */
-
-       if (awacs_revision >= AWACS_DACA){
-               srate = 44100 ;
-       } else {
-               for (i = 0; i < 8 && awacs_freqs[i] >= BEEP_SRATE; ++i)
-                       if (awacs_freqs_ok[i])
-                               beep_speed = i;
-               srate = awacs_freqs[beep_speed];
-       }
-
-       if (hz <= srate / BEEP_BUFLEN || hz > srate / 2) {
-               /* cancel beep currently playing */
-               awacs_nosound(0);
-               return 0;
-       }
-
-       spin_lock_irqsave(&dmasound.lock, flags);
-       if (beep_playing || write_sq.active || beep_buf == NULL) {
-               spin_unlock_irqrestore(&dmasound.lock, flags);
-               return -1;              /* too hard, sorry :-( */
-       }
-       beep_playing = 1;
-       st_le16(&beep_dbdma_cmd->command, OUTPUT_MORE + BR_ALWAYS);
-       spin_unlock_irqrestore(&dmasound.lock, flags);
-
-       if (hz == beep_hz_cache && beep_vol == beep_volume_cache) {
-               nsamples = beep_nsamples_cache;
-       } else {
-               period = srate * 256 / hz;      /* fixed point */
-               ncycles = BEEP_BUFLEN * 256 / period;
-               nsamples = (period * ncycles) >> 8;
-               f = ncycles * 65536 / nsamples;
-               j = 0;
-               p = beep_buf;
-               for (i = 0; i < nsamples; ++i, p += 2) {
-                       p[0] = p[1] = beep_wform[j >> 8] * beep_vol;
-                       j = (j + f) & 0xffff;
-               }
-               beep_hz_cache = hz;
-               beep_volume_cache = beep_vol;
-               beep_nsamples_cache = nsamples;
-       }
-
-       st_le16(&beep_dbdma_cmd->req_count, nsamples*4);
-       st_le16(&beep_dbdma_cmd->xfer_status, 0);
-       st_le32(&beep_dbdma_cmd->cmd_dep, virt_to_bus(beep_dbdma_cmd));
-       st_le32(&beep_dbdma_cmd->phy_addr, virt_to_bus(beep_buf));
-       awacs_beep_state = 1;
-
-       spin_lock_irqsave(&dmasound.lock, flags);
-       if (beep_playing) {     /* i.e. haven't been terminated already */
-               int count = 300 ;
-               out_le32(&awacs_txdma->control, (RUN|WAKE|FLUSH|PAUSE) << 16);
-               while ((in_le32(&awacs_txdma->status) & RUN) && count--)
-                       udelay(1); /* timeout > 2 samples at lowest rate*/
-               if (awacs)
-                       awacs_setup_for_beep(beep_speed);
-               out_le32(&awacs_txdma->cmdptr, virt_to_bus(beep_dbdma_cmd));
-               (void)in_le32(&awacs_txdma->status);
-               out_le32(&awacs_txdma->control, RUN | (RUN << 16));
-       }
-       spin_unlock_irqrestore(&dmasound.lock, flags);
-
-       return 0;
-}
-
-/* used in init and for wake-up */
-
-static void
-load_awacs(void)
-{
-       awacs_write(awacs_reg[0] + MASK_ADDR0);
-       awacs_write(awacs_reg[1] + MASK_ADDR1);
-       awacs_write(awacs_reg[2] + MASK_ADDR2);
-       awacs_write(awacs_reg[4] + MASK_ADDR4);
-
-       if (awacs_revision == AWACS_SCREAMER) {
-               awacs_write(awacs_reg[5] + MASK_ADDR5);
-               msleep(100);
-               awacs_write(awacs_reg[6] + MASK_ADDR6);
-               msleep(2);
-               awacs_write(awacs_reg[1] + MASK_ADDR1);
-               awacs_write(awacs_reg[7] + MASK_ADDR7);
-       }
-       if (awacs) {
-               if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE))
-                       out_le32(&awacs->byteswap, BS_VAL);
-               else
-                       out_le32(&awacs->byteswap, 0);
-       }
-}
-
-#ifdef CONFIG_PM
-/*
- * Save state when going to sleep, restore it afterwards.
- */
-/* FIXME: sort out disabling/re-enabling of read stuff as well */
-static void awacs_sleep_notify(struct pmu_sleep_notifier *self, int when)
-{
-       unsigned long flags;
-
-       switch (when) {
-       case PBOOK_SLEEP_NOW:           
-               LOCK();
-               awacs_sleeping = 1;
-               /* Tell the rest of the driver we are now going to sleep */
-               mb();
-               if (awacs_revision == AWACS_SCREAMER ||
-                   awacs_revision == AWACS_AWACS) {
-                       awacs_reg1_save = awacs_reg[1];
-                       awacs_reg[1] |= MASK_AMUTE | MASK_CMUTE;
-                       awacs_write(MASK_ADDR1 | awacs_reg[1]);
-               }
-
-               PMacSilence();
-               /* stop rx - if going - a bit of a daft user... but */
-               out_le32(&awacs_rxdma->control, (RUN|WAKE|FLUSH << 16));
-               /* deny interrupts */
-               if (awacs)
-                       disable_irq(awacs_irq);
-               disable_irq(awacs_tx_irq);
-               disable_irq(awacs_rx_irq);
-               /* Chip specific sleep code */
-               switch (awacs_revision) {
-                       case AWACS_TUMBLER:
-                       case AWACS_SNAPPER:
-                               write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol);
-                               write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol);
-                               tas_enter_sleep();
-                               write_audio_gpio(gpio_audio_reset, gpio_audio_reset_pol);
-                               break ;
-                       case AWACS_DACA:
-                               daca_enter_sleep();
-                               break ;
-                       case AWACS_BURGUNDY:
-                               break ;
-                       case AWACS_SCREAMER:
-                       case AWACS_AWACS:
-                       default:
-                               out_le32(&awacs->control, 0x11) ;
-                               break ;
-               }
-               /* Disable sound clock */
-               pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 0);
-               /* According to Darwin, we do that after turning off the sound
-                * chip clock. All this will have to be cleaned up once we properly
-                * parse the OF sound-objects
-                */
-               if ((machine_is_compatible("PowerBook3,1") ||
-                   machine_is_compatible("PowerBook3,2")) && awacs) {
-                       awacs_reg[1] |= MASK_PAROUT0 | MASK_PAROUT1;
-                       awacs_write(MASK_ADDR1 | awacs_reg[1]);
-                       msleep(200);
-               }
-               break;
-       case PBOOK_WAKE:
-               /* Enable sound clock */
-               pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 1);
-               if ((machine_is_compatible("PowerBook3,1") ||
-                   machine_is_compatible("PowerBook3,2")) && awacs) {
-                       msleep(100);
-                       awacs_reg[1] &= ~(MASK_PAROUT0 | MASK_PAROUT1);
-                       awacs_write(MASK_ADDR1 | awacs_reg[1]);
-                       msleep(300);
-               } else
-                       msleep(1000);
-               /* restore settings */
-               switch (awacs_revision) {
-                       case AWACS_TUMBLER:
-                       case AWACS_SNAPPER:
-                               write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol);
-                               write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol);
-                               write_audio_gpio(gpio_audio_reset, gpio_audio_reset_pol);
-                               msleep(100);
-                               write_audio_gpio(gpio_audio_reset, !gpio_audio_reset_pol);
-                               msleep(150);
-                               tas_leave_sleep(); /* Stub for now */
-                               headphone_intr(0, NULL);
-                               break;
-                       case AWACS_DACA:
-                               msleep(10); /* Check this !!! */
-                               daca_leave_sleep();
-                               break ;         /* dont know how yet */
-                       case AWACS_BURGUNDY:
-                               break ;
-                       case AWACS_SCREAMER:
-                       case AWACS_AWACS:
-                       default:
-                               load_awacs() ;
-                               break ;
-               }
-               /* Recalibrate chip */
-               if (awacs_revision == AWACS_SCREAMER && awacs)
-                       awacs_recalibrate();
-               /* Make sure dma is stopped */
-               PMacSilence();
-               if (awacs)
-                       enable_irq(awacs_irq);
-               enable_irq(awacs_tx_irq);
-               enable_irq(awacs_rx_irq);
-               if (awacs) {
-                       /* OK, allow ints back again */
-                       out_le32(&awacs->control, MASK_IEPC
-                               | (awacs_rate_index << 8) | 0x11
-                                | (awacs_revision < AWACS_DACA ? MASK_IEE: 0));
-               }
-               if (macio_base && is_pbook_g3) {
-                       /* FIXME: should restore the setup we had...*/
-                       out_8(macio_base + 0x37, 3);
-               } else if (is_pbook_3X00) {
-                       in_8(latch_base + 0x190);
-               }
-               /* Remove mute */
-               if (awacs_revision == AWACS_SCREAMER ||
-                   awacs_revision == AWACS_AWACS) {
-                       awacs_reg[1] = awacs_reg1_save;
-                       awacs_write(MASK_ADDR1 | awacs_reg[1]);
-               }
-               awacs_sleeping = 0;
-               /* Resume pending sounds. */
-               /* we don't try to restart input... */
-               spin_lock_irqsave(&dmasound.lock, flags);
-               __PMacPlay();
-               spin_unlock_irqrestore(&dmasound.lock, flags);
-               UNLOCK();
-       }
-}
-#endif /* CONFIG_PM */
-
-
-/* All the burgundy functions: */
-
-/* Waits for busy flag to clear */
-static inline void
-awacs_burgundy_busy_wait(void)
-{
-       int count = 50; /* > 2 samples at 44k1 */
-       while ((in_le32(&awacs->codec_ctrl) & MASK_NEWECMD) && count--)
-               udelay(1) ;
-}
-
-static inline void
-awacs_burgundy_extend_wait(void)
-{
-       int count = 50 ; /* > 2 samples at 44k1 */
-       while ((!(in_le32(&awacs->codec_stat) & MASK_EXTEND)) && count--)
-               udelay(1) ;
-       count = 50;
-       while ((in_le32(&awacs->codec_stat) & MASK_EXTEND) && count--)
-               udelay(1);
-}
-
-static void
-awacs_burgundy_wcw(unsigned addr, unsigned val)
-{
-       out_le32(&awacs->codec_ctrl, addr + 0x200c00 + (val & 0xff));
-       awacs_burgundy_busy_wait();
-       out_le32(&awacs->codec_ctrl, addr + 0x200d00 +((val>>8) & 0xff));
-       awacs_burgundy_busy_wait();
-       out_le32(&awacs->codec_ctrl, addr + 0x200e00 +((val>>16) & 0xff));
-       awacs_burgundy_busy_wait();
-       out_le32(&awacs->codec_ctrl, addr + 0x200f00 +((val>>24) & 0xff));
-       awacs_burgundy_busy_wait();
-}
-
-static unsigned
-awacs_burgundy_rcw(unsigned addr)
-{
-       unsigned val = 0;
-       unsigned long flags;
-
-       /* should have timeouts here */
-       spin_lock_irqsave(&dmasound.lock, flags);
-
-       out_le32(&awacs->codec_ctrl, addr + 0x100000);
-       awacs_burgundy_busy_wait();
-       awacs_burgundy_extend_wait();
-       val += (in_le32(&awacs->codec_stat) >> 4) & 0xff;
-
-       out_le32(&awacs->codec_ctrl, addr + 0x100100);
-       awacs_burgundy_busy_wait();
-       awacs_burgundy_extend_wait();
-       val += ((in_le32(&awacs->codec_stat)>>4) & 0xff) <<8;
-
-       out_le32(&awacs->codec_ctrl, addr + 0x100200);
-       awacs_burgundy_busy_wait();
-       awacs_burgundy_extend_wait();
-       val += ((in_le32(&awacs->codec_stat)>>4) & 0xff) <<16;
-
-       out_le32(&awacs->codec_ctrl, addr + 0x100300);
-       awacs_burgundy_busy_wait();
-       awacs_burgundy_extend_wait();
-       val += ((in_le32(&awacs->codec_stat)>>4) & 0xff) <<24;
-
-       spin_unlock_irqrestore(&dmasound.lock, flags);
-
-       return val;
-}
-
-
-static void
-awacs_burgundy_wcb(unsigned addr, unsigned val)
-{
-       out_le32(&awacs->codec_ctrl, addr + 0x300000 + (val & 0xff));
-       awacs_burgundy_busy_wait();
-}
-
-static unsigned
-awacs_burgundy_rcb(unsigned addr)
-{
-       unsigned val = 0;
-       unsigned long flags;
-
-       /* should have timeouts here */
-       spin_lock_irqsave(&dmasound.lock, flags);
-
-       out_le32(&awacs->codec_ctrl, addr + 0x100000);
-       awacs_burgundy_busy_wait();
-       awacs_burgundy_extend_wait();
-       val += (in_le32(&awacs->codec_stat) >> 4) & 0xff;
-
-       spin_unlock_irqrestore(&dmasound.lock, flags);
-
-       return val;
-}
-
-static int
-awacs_burgundy_check(void)
-{
-       /* Checks to see the chip is alive and kicking */
-       int error = in_le32(&awacs->codec_ctrl) & MASK_ERRCODE;
-
-       return error == 0xf0000;
-}
-
-static int
-awacs_burgundy_init(void)
-{
-       if (awacs_burgundy_check()) {
-               printk(KERN_WARNING "dmasound_pmac: burgundy not working :-(\n");
-               return 1;
-       }
-
-       awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_OUTPUTENABLES,
-                          DEF_BURGUNDY_OUTPUTENABLES);
-       awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
-                          DEF_BURGUNDY_MORE_OUTPUTENABLES);
-       awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_OUTPUTSELECTS,
-                          DEF_BURGUNDY_OUTPUTSELECTS);
-
-       awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_INPSEL21,
-                          DEF_BURGUNDY_INPSEL21);
-       awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_INPSEL3,
-                          DEF_BURGUNDY_INPSEL3);
-       awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINCD,
-                          DEF_BURGUNDY_GAINCD);
-       awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINLINE,
-                          DEF_BURGUNDY_GAINLINE);
-       awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINMIC,
-                          DEF_BURGUNDY_GAINMIC);
-       awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINMODEM,
-                          DEF_BURGUNDY_GAINMODEM);
-
-       awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENSPEAKER,
-                          DEF_BURGUNDY_ATTENSPEAKER);
-       awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENLINEOUT,
-                          DEF_BURGUNDY_ATTENLINEOUT);
-       awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENHP,
-                          DEF_BURGUNDY_ATTENHP);
-
-       awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_MASTER_VOLUME,
-                          DEF_BURGUNDY_MASTER_VOLUME);
-       awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_VOLCD,
-                          DEF_BURGUNDY_VOLCD);
-       awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_VOLLINE,
-                          DEF_BURGUNDY_VOLLINE);
-       awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_VOLMIC,
-                          DEF_BURGUNDY_VOLMIC);
-       return 0;
-}
-
-static void
-awacs_burgundy_write_volume(unsigned address, int volume)
-{
-       int hardvolume,lvolume,rvolume;
-
-       lvolume = (volume & 0xff) ? (volume & 0xff) + 155 : 0;
-       rvolume = ((volume >>8)&0xff) ? ((volume >> 8)&0xff ) + 155 : 0;
-
-       hardvolume = lvolume + (rvolume << 16);
-
-       awacs_burgundy_wcw(address, hardvolume);
-}
-
-static int
-awacs_burgundy_read_volume(unsigned address)
-{
-       int softvolume,wvolume;
-
-       wvolume = awacs_burgundy_rcw(address);
-
-       softvolume = (wvolume & 0xff) - 155;
-       softvolume += (((wvolume >> 16) & 0xff) - 155)<<8;
-
-       return softvolume > 0 ? softvolume : 0;
-}
-
-static int
-awacs_burgundy_read_mvolume(unsigned address)
-{
-       int lvolume,rvolume,wvolume;
-
-       wvolume = awacs_burgundy_rcw(address);
-
-       wvolume &= 0xffff;
-
-       rvolume = (wvolume & 0xff) - 155;
-       lvolume = ((wvolume & 0xff00)>>8) - 155;
-
-       return lvolume + (rvolume << 8);
-}
-
-static void
-awacs_burgundy_write_mvolume(unsigned address, int volume)
-{
-       int lvolume,rvolume,hardvolume;
-
-       lvolume = (volume &0xff) ? (volume & 0xff) + 155 :0;
-       rvolume = ((volume >>8) & 0xff) ? (volume >> 8) + 155 :0;
-
-       hardvolume = lvolume + (rvolume << 8);
-       hardvolume += (hardvolume << 16);
-
-       awacs_burgundy_wcw(address, hardvolume);
-}
-
-/* End burgundy functions */
-
-/* Set up output volumes on machines with the 'perch/whisper' extension card.
- * this has an SGS i2c chip (7433) which is accessed using the cuda.
- *
- * TODO: split this out and make use of the other parts of the SGS chip to
- * do Bass, Treble etc.
- */
-
-static void
-awacs_enable_amp(int spkr_vol)
-{
-#ifdef CONFIG_ADB_CUDA
-       struct adb_request req;
-
-       if (sys_ctrler != SYS_CTRLER_CUDA)
-               return;
-
-       /* turn on headphones */
-       cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC,
-                    0x8a, 4, 0);
-       while (!req.complete) cuda_poll();
-       cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC,
-                    0x8a, 6, 0);
-       while (!req.complete) cuda_poll();
-
-       /* turn on speaker */
-       cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC,
-                    0x8a, 3, (100 - (spkr_vol & 0xff)) * 32 / 100);
-       while (!req.complete) cuda_poll();
-       cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC,
-                    0x8a, 5, (100 - ((spkr_vol >> 8) & 0xff)) * 32 / 100);
-       while (!req.complete) cuda_poll();
-
-       cuda_request(&req, NULL, 5, CUDA_PACKET,
-                    CUDA_GET_SET_IIC, 0x8a, 1, 0x29);
-       while (!req.complete) cuda_poll();
-#endif /* CONFIG_ADB_CUDA */
-}
-
-
-/*** Mid level stuff *********************************************************/
-
-
-/*
- * /dev/mixer abstraction
- */
-
-static void do_line_lev(int data)
-{
-               line_lev = data ;
-               awacs_reg[0] &= ~MASK_MUX_AUDIN;
-               if ((data & 0xff) >= 50)
-                       awacs_reg[0] |= MASK_MUX_AUDIN;
-               awacs_write(MASK_ADDR0 | awacs_reg[0]);
-}
-
-static void do_ip_gain(int data)
-{
-       ip_gain = data ;
-       data &= 0xff;
-       awacs_reg[0] &= ~MASK_GAINLINE;
-       if (awacs_revision == AWACS_SCREAMER) {
-               awacs_reg[6] &= ~MASK_MIC_BOOST ;
-               if (data >= 33) {
-                       awacs_reg[0] |= MASK_GAINLINE;
-                       if( data >= 66)
-                               awacs_reg[6] |= MASK_MIC_BOOST ;
-               }
-               awacs_write(MASK_ADDR6 | awacs_reg[6]) ;
-       } else {
-               if (data >= 50)
-                       awacs_reg[0] |= MASK_GAINLINE;
-       }
-       awacs_write(MASK_ADDR0 | awacs_reg[0]);
-}
-
-static void do_mic_lev(int data)
-{
-       mic_lev = data ;
-       data &= 0xff;
-       awacs_reg[0] &= ~MASK_MUX_MIC;
-       if (data >= 50)
-               awacs_reg[0] |= MASK_MUX_MIC;
-       awacs_write(MASK_ADDR0 | awacs_reg[0]);
-}
-
-static void do_cd_lev(int data)
-{
-       cd_lev = data ;
-       awacs_reg[0] &= ~MASK_MUX_CD;
-       if ((data & 0xff) >= 50)
-               awacs_reg[0] |= MASK_MUX_CD;
-       awacs_write(MASK_ADDR0 | awacs_reg[0]);
-}
-
-static void do_rec_lev(int data)
-{
-       int left, right ;
-       rec_lev = data ;
-       /* need to fudge this to use the volume setter routine */
-       left = 100 - (data & 0xff) ; if( left < 0 ) left = 0 ;
-       right = 100 - ((data >> 8) & 0xff) ; if( right < 0 ) right = 0 ;
-       left |= (right << 8 );
-       left = awacs_volume_setter(left, 0, 0, 4);
-}
-
-static void do_passthru_vol(int data)
-{
-       passthru_vol = data ;
-       awacs_reg[1] &= ~MASK_LOOPTHRU;
-       if (awacs_revision == AWACS_SCREAMER) {
-               if( data ) { /* switch it on for non-zero */
-                       awacs_reg[1] |= MASK_LOOPTHRU;
-                       awacs_write(MASK_ADDR1 | awacs_reg[1]);
-               }
-               data = awacs_volume_setter(data, 5, 0, 6) ;
-       } else {
-               if ((data & 0xff) >= 50)
-                       awacs_reg[1] |= MASK_LOOPTHRU;
-               awacs_write(MASK_ADDR1 | awacs_reg[1]);
-               data = (awacs_reg[1] & MASK_LOOPTHRU)? 100: 0;
-       }
-}
-
-static int awacs_mixer_ioctl(u_int cmd, u_long arg)
-{
-       int data;
-       int rc;
-
-       switch (cmd) {
-       case SOUND_MIXER_READ_CAPS:
-               /* say we will allow multiple inputs?  prob. wrong
-                       so I'm switching it to single */
-               return IOCTL_OUT(arg, 1);
-       case SOUND_MIXER_READ_DEVMASK:
-               data  = SOUND_MASK_VOLUME | SOUND_MASK_SPEAKER
-                       | SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD
-                       | SOUND_MASK_IGAIN | SOUND_MASK_RECLEV
-                       | SOUND_MASK_ALTPCM
-                       | SOUND_MASK_MONITOR;
-               rc = IOCTL_OUT(arg, data);
-               break;
-       case SOUND_MIXER_READ_RECMASK:
-               data = SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD;
-               rc = IOCTL_OUT(arg, data);
-               break;
-       case SOUND_MIXER_READ_RECSRC:
-               data = 0;
-               if (awacs_reg[0] & MASK_MUX_AUDIN)
-                       data |= SOUND_MASK_LINE;
-               if (awacs_reg[0] & MASK_MUX_MIC)
-                       data |= SOUND_MASK_MIC;
-               if (awacs_reg[0] & MASK_MUX_CD)
-                       data |= SOUND_MASK_CD;
-               rc = IOCTL_OUT(arg, data);
-               break;
-       case SOUND_MIXER_WRITE_RECSRC:
-               IOCTL_IN(arg, data);
-               data &= (SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD);
-               awacs_reg[0] &= ~(MASK_MUX_CD | MASK_MUX_MIC
-                                 | MASK_MUX_AUDIN);
-               if (data & SOUND_MASK_LINE)
-                       awacs_reg[0] |= MASK_MUX_AUDIN;
-               if (data & SOUND_MASK_MIC)
-                       awacs_reg[0] |= MASK_MUX_MIC;
-               if (data & SOUND_MASK_CD)
-                       awacs_reg[0] |= MASK_MUX_CD;
-               awacs_write(awacs_reg[0] | MASK_ADDR0);
-               rc = IOCTL_OUT(arg, data);
-               break;
-       case SOUND_MIXER_READ_STEREODEVS:
-               data = SOUND_MASK_VOLUME | SOUND_MASK_SPEAKER| SOUND_MASK_RECLEV  ;
-               if (awacs_revision == AWACS_SCREAMER)
-                       data |= SOUND_MASK_MONITOR ;
-               rc = IOCTL_OUT(arg, data);
-               break;
-       case SOUND_MIXER_WRITE_VOLUME:
-               IOCTL_IN(arg, data);
-               line_vol = data ;
-               awacs_volume_setter(data, 2, 0, 6);
-               /* fall through */
-       case SOUND_MIXER_READ_VOLUME:
-               rc = IOCTL_OUT(arg, line_vol);
-               break;
-       case SOUND_MIXER_WRITE_SPEAKER:
-               IOCTL_IN(arg, data);
-               spk_vol = data ;
-               if (has_perch)
-                       awacs_enable_amp(data);
-               else
-                       (void)awacs_volume_setter(data, 4, MASK_CMUTE, 6);
-               /* fall though */
-       case SOUND_MIXER_READ_SPEAKER:
-               rc = IOCTL_OUT(arg, spk_vol);
-               break;
-       case SOUND_MIXER_WRITE_ALTPCM:  /* really bell volume */
-               IOCTL_IN(arg, data);
-               beep_vol = data & 0xff;
-               /* fall through */
-       case SOUND_MIXER_READ_ALTPCM:
-               rc = IOCTL_OUT(arg, beep_vol);
-               break;
-       case SOUND_MIXER_WRITE_LINE:
-               IOCTL_IN(arg, data);
-               do_line_lev(data) ;
-               /* fall through */
-       case SOUND_MIXER_READ_LINE:
-               rc = IOCTL_OUT(arg, line_lev);
-               break;
-       case SOUND_MIXER_WRITE_IGAIN:
-               IOCTL_IN(arg, data);
-               do_ip_gain(data) ;
-               /* fall through */
-       case SOUND_MIXER_READ_IGAIN:
-               rc = IOCTL_OUT(arg, ip_gain);
-               break;
-       case SOUND_MIXER_WRITE_MIC:
-               IOCTL_IN(arg, data);
-               do_mic_lev(data);
-               /* fall through */
-       case SOUND_MIXER_READ_MIC:
-               rc = IOCTL_OUT(arg, mic_lev);
-               break;
-       case SOUND_MIXER_WRITE_CD:
-               IOCTL_IN(arg, data);
-               do_cd_lev(data);
-               /* fall through */
-       case SOUND_MIXER_READ_CD:
-               rc = IOCTL_OUT(arg, cd_lev);
-               break;
-       case SOUND_MIXER_WRITE_RECLEV:
-               IOCTL_IN(arg, data);
-               do_rec_lev(data) ;
-               /* fall through */
-       case SOUND_MIXER_READ_RECLEV:
-               rc = IOCTL_OUT(arg, rec_lev);
-               break;
-       case MIXER_WRITE(SOUND_MIXER_MONITOR):
-               IOCTL_IN(arg, data);
-               do_passthru_vol(data) ;
-               /* fall through */
-       case MIXER_READ(SOUND_MIXER_MONITOR):
-               rc = IOCTL_OUT(arg, passthru_vol);
-               break;
-       default:
-               rc = -EINVAL;
-       }
-       
-       return rc;
-}
-
-static void awacs_mixer_init(void)
-{
-       awacs_volume_setter(line_vol, 2, 0, 6);
-       if (has_perch)
-               awacs_enable_amp(spk_vol);
-       else
-               (void)awacs_volume_setter(spk_vol, 4, MASK_CMUTE, 6);
-       do_line_lev(line_lev) ;
-       do_ip_gain(ip_gain) ;
-       do_mic_lev(mic_lev) ;
-       do_cd_lev(cd_lev) ;
-       do_rec_lev(rec_lev) ;
-       do_passthru_vol(passthru_vol) ;
-}
-
-static int burgundy_mixer_ioctl(u_int cmd, u_long arg)
-{
-       int data;
-       int rc;
-
-       /* We are, we are, we are... Burgundy or better */
-       switch(cmd) {
-       case SOUND_MIXER_READ_DEVMASK:
-               data = SOUND_MASK_VOLUME | SOUND_MASK_CD |
-                       SOUND_MASK_LINE | SOUND_MASK_MIC |
-                       SOUND_MASK_SPEAKER | SOUND_MASK_ALTPCM;
-               rc = IOCTL_OUT(arg, data);
-               break;
-       case SOUND_MIXER_READ_RECMASK:
-               data = SOUND_MASK_LINE | SOUND_MASK_MIC
-                       | SOUND_MASK_CD;
-               rc = IOCTL_OUT(arg, data);
-               break;
-       case SOUND_MIXER_READ_RECSRC:
-               data = 0;
-               if (awacs_reg[0] & MASK_MUX_AUDIN)
-                       data |= SOUND_MASK_LINE;
-               if (awacs_reg[0] & MASK_MUX_MIC)
-                       data |= SOUND_MASK_MIC;
-               if (awacs_reg[0] & MASK_MUX_CD)
-                       data |= SOUND_MASK_CD;
-               rc = IOCTL_OUT(arg, data);
-               break;
-       case SOUND_MIXER_WRITE_RECSRC:
-               IOCTL_IN(arg, data);
-               data &= (SOUND_MASK_LINE
-                        | SOUND_MASK_MIC | SOUND_MASK_CD);
-               awacs_reg[0] &= ~(MASK_MUX_CD | MASK_MUX_MIC
-                                 | MASK_MUX_AUDIN);
-               if (data & SOUND_MASK_LINE)
-                       awacs_reg[0] |= MASK_MUX_AUDIN;
-               if (data & SOUND_MASK_MIC)
-                       awacs_reg[0] |= MASK_MUX_MIC;
-               if (data & SOUND_MASK_CD)
-                       awacs_reg[0] |= MASK_MUX_CD;
-               awacs_write(awacs_reg[0] | MASK_ADDR0);
-               rc = IOCTL_OUT(arg, data);
-               break;
-       case SOUND_MIXER_READ_STEREODEVS:
-               data = SOUND_MASK_VOLUME | SOUND_MASK_SPEAKER
-                       | SOUND_MASK_RECLEV | SOUND_MASK_CD
-                       | SOUND_MASK_LINE;
-               rc = IOCTL_OUT(arg, data);
-               break;
-       case SOUND_MIXER_READ_CAPS:
-               rc = IOCTL_OUT(arg, 0);
-               break;
-       case SOUND_MIXER_WRITE_VOLUME:
-               IOCTL_IN(arg, data);
-               awacs_burgundy_write_mvolume(MASK_ADDR_BURGUNDY_MASTER_VOLUME, data);
-                               /* Fall through */
-       case SOUND_MIXER_READ_VOLUME:
-               rc = IOCTL_OUT(arg, awacs_burgundy_read_mvolume(MASK_ADDR_BURGUNDY_MASTER_VOLUME));
-               break;
-       case SOUND_MIXER_WRITE_SPEAKER:
-               IOCTL_IN(arg, data);
-               if (!(data & 0xff)) {
-                       /* Mute the left speaker */
-                       awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
-                                          awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) & ~0x2);
-               } else {
-                       /* Unmute the left speaker */
-                       awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
-                                          awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) | 0x2);
-               }
-               if (!(data & 0xff00)) {
-                       /* Mute the right speaker */
-                       awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
-                                          awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) & ~0x4);
-               } else {
-                       /* Unmute the right speaker */
-                       awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
-                                          awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) | 0x4);
-               }
-
-               data = (((data&0xff)*16)/100 > 0xf ? 0xf :
-                       (((data&0xff)*16)/100)) +
-                       ((((data>>8)*16)/100 > 0xf ? 0xf :
-                         ((((data>>8)*16)/100)))<<4);
-
-               awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENSPEAKER, ~data);
-                               /* Fall through */
-       case SOUND_MIXER_READ_SPEAKER:
-               data = awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_ATTENSPEAKER);
-               data = (((data & 0xf)*100)/16) + ((((data>>4)*100)/16)<<8);
-               rc = IOCTL_OUT(arg, (~data) & 0x0000ffff);
-               break;
-       case SOUND_MIXER_WRITE_ALTPCM:  /* really bell volume */
-               IOCTL_IN(arg, data);
-               beep_vol = data & 0xff;
-                               /* fall through */
-       case SOUND_MIXER_READ_ALTPCM:
-               rc = IOCTL_OUT(arg, beep_vol);
-               break;
-       case SOUND_MIXER_WRITE_LINE:
-               IOCTL_IN(arg, data);
-               awacs_burgundy_write_volume(MASK_ADDR_BURGUNDY_VOLLINE, data);
-
-                               /* fall through */
-       case SOUND_MIXER_READ_LINE:
-               data = awacs_burgundy_read_volume(MASK_ADDR_BURGUNDY_VOLLINE);
-               rc = IOCTL_OUT(arg, data);
-               break;
-       case SOUND_MIXER_WRITE_MIC:
-               IOCTL_IN(arg, data);
-                               /* Mic is mono device */
-               data = (data << 8) + (data << 24);
-               awacs_burgundy_write_volume(MASK_ADDR_BURGUNDY_VOLMIC, data);
-                               /* fall through */
-       case SOUND_MIXER_READ_MIC:
-               data = awacs_burgundy_read_volume(MASK_ADDR_BURGUNDY_VOLMIC);
-               data <<= 24;
-               rc = IOCTL_OUT(arg, data);
-               break;
-       case SOUND_MIXER_WRITE_CD:
-               IOCTL_IN(arg, data);
-               awacs_burgundy_write_volume(MASK_ADDR_BURGUNDY_VOLCD, data);
-                               /* fall through */
-       case SOUND_MIXER_READ_CD:
-               data = awacs_burgundy_read_volume(MASK_ADDR_BURGUNDY_VOLCD);
-               rc = IOCTL_OUT(arg, data);
-               break;
-       case SOUND_MIXER_WRITE_RECLEV:
-               IOCTL_IN(arg, data);
-               data = awacs_volume_setter(data, 0, 0, 4);
-               rc = IOCTL_OUT(arg, data);
-               break;
-       case SOUND_MIXER_READ_RECLEV:
-               data = awacs_get_volume(awacs_reg[0], 4);
-               rc = IOCTL_OUT(arg, data);
-               break;
-       case SOUND_MIXER_OUTMASK:
-       case SOUND_MIXER_OUTSRC:
-       default:
-               rc = -EINVAL;
-       }
-       
-       return rc;
-}
-
-static int daca_mixer_ioctl(u_int cmd, u_long arg)
-{
-       int data;
-       int rc;
-
-       /* And the DACA's no genius either! */
-
-       switch(cmd) {
-       case SOUND_MIXER_READ_DEVMASK:
-               data = SOUND_MASK_VOLUME;
-               rc = IOCTL_OUT(arg, data);
-               break;
-       case SOUND_MIXER_READ_RECMASK:
-               data = 0;
-               rc = IOCTL_OUT(arg, data);
-               break;
-       case SOUND_MIXER_READ_RECSRC:
-               data = 0;
-               rc = IOCTL_OUT(arg, data);
-               break;
-       case SOUND_MIXER_WRITE_RECSRC:
-               IOCTL_IN(arg, data);
-               data =0;
-               rc = IOCTL_OUT(arg, data);
-               break;
-       case SOUND_MIXER_READ_STEREODEVS:
-               data = SOUND_MASK_VOLUME;
-               rc = IOCTL_OUT(arg, data);
-               break;
-       case SOUND_MIXER_READ_CAPS:
-               rc = IOCTL_OUT(arg, 0);
-               break;
-       case SOUND_MIXER_WRITE_VOLUME:
-               IOCTL_IN(arg, data);
-               daca_set_volume(data, data);
-               /* Fall through */
-       case SOUND_MIXER_READ_VOLUME:
-               daca_get_volume(& data, &data);
-               rc = IOCTL_OUT(arg, data);
-               break;
-       case SOUND_MIXER_OUTMASK:
-       case SOUND_MIXER_OUTSRC:
-       default:
-               rc = -EINVAL;
-       }
-       return rc;
-}
-
-static int PMacMixerIoctl(u_int cmd, u_long arg)
-{
-       int rc;
-       
-       /* Different IOCTLS for burgundy and, eventually, DACA & Tumbler */
-
-       TRY_LOCK();
-       
-       switch (awacs_revision){
-               case AWACS_BURGUNDY:
-                       rc = burgundy_mixer_ioctl(cmd, arg);
-                       break ;
-               case AWACS_DACA:
-                       rc = daca_mixer_ioctl(cmd, arg);
-                       break;
-               case AWACS_TUMBLER:
-               case AWACS_SNAPPER:
-                       rc = tas_mixer_ioctl(cmd, arg);
-                       break ;
-               default: /* ;-)) */
-                       rc = awacs_mixer_ioctl(cmd, arg);
-       }
-
-       UNLOCK();
-       
-       return rc;
-}
-
-static void PMacMixerInit(void)
-{
-       switch (awacs_revision) {
-               case AWACS_TUMBLER:
-                 printk("AE-Init tumbler mixer\n");
-                 break ;
-               case AWACS_SNAPPER:
-                 printk("AE-Init snapper mixer\n");
-                 break ;
-               case AWACS_DACA:
-               case AWACS_BURGUNDY:
-                       break ; /* don't know yet */
-               case AWACS_AWACS:
-               case AWACS_SCREAMER:
-               default:
-                       awacs_mixer_init() ;
-                       break ;
-       }
-}
-
-/* Write/Read sq setup functions:
-   Check to see if we have enough (or any) dbdma cmd buffers for the
-   user's fragment settings.  If not, allocate some. If this fails we will
-   point at the beep buffer - as an emergency provision - to stop dma tromping
-   on some random bit of memory (if someone lets it go anyway).
-   The command buffers are then set up to point to the fragment buffers
-   (allocated elsewhere).  We need n+1 commands the last of which holds
-   a NOP + loop to start.
-*/
-
-static int PMacWriteSqSetup(void)
-{
-       int i, count = 600 ;
-       volatile struct dbdma_cmd *cp;
-
-       LOCK();
-       
-       /* stop the controller from doing any output - if it isn't already.
-          it _should_ be before this is called anyway */
-
-       out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
-       while ((in_le32(&awacs_txdma->status) & RUN) && count--)
-               udelay(1);
-#ifdef DEBUG_DMASOUND
-if (count <= 0)
-       printk("dmasound_pmac: write sq setup: timeout waiting for dma to stop\n");
-#endif
-
-       if ((write_sq.max_count + 1) > number_of_tx_cmd_buffers) {
-               kfree(awacs_tx_cmd_space);
-               number_of_tx_cmd_buffers = 0;
-
-               /* we need nbufs + 1 (for the loop) and we should request + 1
-                  again because the DBDMA_ALIGN might pull the start up by up
-                  to sizeof(struct dbdma_cmd) - 4.
-               */
-
-               awacs_tx_cmd_space = kmalloc
-                       ((write_sq.max_count + 1 + 1) * sizeof(struct dbdma_cmd),
-                        GFP_KERNEL);
-               if (awacs_tx_cmd_space == NULL) {
-                       /* don't leave it dangling - nasty but better than a
-                          random address */
-                       out_le32(&awacs_txdma->cmdptr, virt_to_bus(beep_dbdma_cmd));
-                       printk(KERN_ERR
-                          "dmasound_pmac: can't allocate dbdma cmd buffers"
-                          ", driver disabled\n");
-                       UNLOCK();
-                       return -ENOMEM;
-               }
-               awacs_tx_cmds = (volatile struct dbdma_cmd *)
-                       DBDMA_ALIGN(awacs_tx_cmd_space);
-               number_of_tx_cmd_buffers = write_sq.max_count + 1;
-       }
-
-       cp = awacs_tx_cmds;
-       memset((void *)cp, 0, (write_sq.max_count+1) * sizeof(struct dbdma_cmd));
-       for (i = 0; i < write_sq.max_count; ++i, ++cp) {
-               st_le32(&cp->phy_addr, virt_to_bus(write_sq.buffers[i]));
-       }
-       st_le16(&cp->command, DBDMA_NOP + BR_ALWAYS);
-       st_le32(&cp->cmd_dep, virt_to_bus(awacs_tx_cmds));
-       /* point the controller at the command stack - ready to go */
-       out_le32(&awacs_txdma->cmdptr, virt_to_bus(awacs_tx_cmds));
-       UNLOCK();
-       return 0;
-}
-
-static int PMacReadSqSetup(void)
-{
-       int i, count = 600;
-       volatile struct dbdma_cmd *cp;
-
-       LOCK();
-       
-       /* stop the controller from doing any input - if it isn't already.
-          it _should_ be before this is called anyway */
-       
-       out_le32(&awacs_rxdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
-       while ((in_le32(&awacs_rxdma->status) & RUN) && count--)
-               udelay(1);
-#ifdef DEBUG_DMASOUND
-if (count <= 0)
-       printk("dmasound_pmac: read sq setup: timeout waiting for dma to stop\n");
-#endif
-
-       if ((read_sq.max_count+1) > number_of_rx_cmd_buffers ) {
-               kfree(awacs_rx_cmd_space);
-               number_of_rx_cmd_buffers = 0;
-
-               /* we need nbufs + 1 (for the loop) and we should request + 1 again
-                  because the DBDMA_ALIGN might pull the start up by up to
-                  sizeof(struct dbdma_cmd) - 4 (assuming kmalloc aligns 32 bits).
-               */
-
-               awacs_rx_cmd_space = kmalloc
-                       ((read_sq.max_count + 1 + 1) * sizeof(struct dbdma_cmd),
-                        GFP_KERNEL);
-               if (awacs_rx_cmd_space == NULL) {
-                       /* don't leave it dangling - nasty but better than a
-                          random address */
-                       out_le32(&awacs_rxdma->cmdptr, virt_to_bus(beep_dbdma_cmd));
-                       printk(KERN_ERR
-                          "dmasound_pmac: can't allocate dbdma cmd buffers"
-                          ", driver disabled\n");
-                       UNLOCK();
-                       return -ENOMEM;
-               }
-               awacs_rx_cmds = (volatile struct dbdma_cmd *)
-                       DBDMA_ALIGN(awacs_rx_cmd_space);
-               number_of_rx_cmd_buffers = read_sq.max_count + 1 ;
-       }
-       cp = awacs_rx_cmds;
-       memset((void *)cp, 0, (read_sq.max_count+1) * sizeof(struct dbdma_cmd));
-
-       /* Set dma buffers up in a loop */
-       for (i = 0; i < read_sq.max_count; i++,cp++) {
-               st_le32(&cp->phy_addr, virt_to_bus(read_sq.buffers[i]));
-               st_le16(&cp->command, INPUT_MORE + INTR_ALWAYS);
-               st_le16(&cp->req_count, read_sq.block_size);
-               st_le16(&cp->xfer_status, 0);
-       }
-
-       /* The next two lines make the thing loop around.
-       */
-       st_le16(&cp->command, DBDMA_NOP + BR_ALWAYS);
-       st_le32(&cp->cmd_dep, virt_to_bus(awacs_rx_cmds));
-       /* point the controller at the command stack - ready to go */
-       out_le32(&awacs_rxdma->cmdptr, virt_to_bus(awacs_rx_cmds));
-
-       UNLOCK();
-       return 0;
-}
-
-/* TODO: this needs work to guarantee that when it returns DMA has stopped
-   but in a more elegant way than is done here....
-*/
-
-static void PMacAbortRead(void)
-{
-       int i;
-       volatile struct dbdma_cmd *cp;
-
-       LOCK();
-       /* give it a chance to update the output and provide the IRQ
-          that is expected.
-       */
-
-       out_le32(&awacs_rxdma->control, ((FLUSH) << 16) + FLUSH );
-
-       cp = awacs_rx_cmds;
-       for (i = 0; i < read_sq.max_count; i++,cp++)
-               st_le16(&cp->command, DBDMA_STOP);
-       /*
-        * We should probably wait for the thing to stop before we
-        * release the memory.
-        */
-
-       msleep(100) ; /* give it a (small) chance to act */
-
-       /* apply the sledgehammer approach - just stop it now */
-
-       out_le32(&awacs_rxdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
-       UNLOCK();
-}
-
-extern char *get_afmt_string(int);
-static int PMacStateInfo(char *b, size_t sp)
-{
-       int i, len = 0;
-       len = sprintf(b,"HW rates: ");
-       switch (awacs_revision){
-               case AWACS_DACA:
-               case AWACS_BURGUNDY:
-                       len += sprintf(b,"44100 ") ;
-                       break ;
-               case AWACS_TUMBLER:
-               case AWACS_SNAPPER:
-                       for (i=0; i<1; i++){
-                               if (tas_freqs_ok[i])
-                                       len += sprintf(b+len,"%d ", tas_freqs[i]) ;
-                       }
-                       break ;
-               case AWACS_AWACS:
-               case AWACS_SCREAMER:
-               default:
-                       for (i=0; i<8; i++){
-                               if (awacs_freqs_ok[i])
-                                       len += sprintf(b+len,"%d ", awacs_freqs[i]) ;
-                       }
-                       break ;
-       }
-       len += sprintf(b+len,"s/sec\n") ;
-       if (len < sp) {
-               len += sprintf(b+len,"HW AFMTS: ");
-               i = AFMT_U16_BE ;
-               while (i) {
-                       if (i & dmasound.mach.hardware_afmts)
-                               len += sprintf(b+len,"%s ",
-                                       get_afmt_string(i & dmasound.mach.hardware_afmts));
-                       i >>= 1 ;
-               }
-               len += sprintf(b+len,"\n") ;
-       }
-       return len ;
-}
-
-/*** Machine definitions *****************************************************/
-
-static SETTINGS def_hard = {
-       .format = AFMT_S16_BE,
-       .stereo = 1,
-       .size   = 16,
-       .speed  = 44100
-} ;
-
-static SETTINGS def_soft = {
-       .format = AFMT_S16_BE,
-       .stereo = 1,
-       .size   = 16,
-       .speed  = 44100
-} ;
-
-static MACHINE machPMac = {
-       .name           = awacs_name,
-       .name2          = "PowerMac Built-in Sound",
-       .owner          = THIS_MODULE,
-       .dma_alloc      = PMacAlloc,
-       .dma_free       = PMacFree,
-       .irqinit        = PMacIrqInit,
-#ifdef MODULE
-       .irqcleanup     = PMacIrqCleanup,
-#endif /* MODULE */
-       .init           = PMacInit,
-       .silence        = PMacSilence,
-       .setFormat      = PMacSetFormat,
-       .setVolume      = PMacSetVolume,
-       .play           = PMacPlay,
-       .record         = NULL,         /* default to no record */
-       .mixer_init     = PMacMixerInit,
-       .mixer_ioctl    = PMacMixerIoctl,
-       .write_sq_setup = PMacWriteSqSetup,
-       .read_sq_setup  = PMacReadSqSetup,
-       .state_info     = PMacStateInfo,
-       .abort_read     = PMacAbortRead,
-       .min_dsp_speed  = 7350,
-       .max_dsp_speed  = 44100,
-       .version        = ((DMASOUND_AWACS_REVISION<<8) + DMASOUND_AWACS_EDITION)
-};
-
-
-/*** Config & Setup **********************************************************/
-
-/* Check for pmac models that we care about in terms of special actions.
-*/
-
-void __init
-set_model(void)
-{
-       /* portables/lap-tops */
-
-       if (machine_is_compatible("AAPL,3400/2400") ||
-           machine_is_compatible("AAPL,3500")) {
-               is_pbook_3X00 = 1 ;
-       }
-       if (machine_is_compatible("PowerBook1,1")  || /* lombard */
-           machine_is_compatible("AAPL,PowerBook1998")){ /* wallstreet */
-               is_pbook_g3 = 1 ;
-               return ;
-       }
-}
-
-/* Get the OF node that tells us about the registers, interrupts etc. to use
-   for sound IO.
-
-   On most machines the sound IO OF node is the 'davbus' node.  On newer pmacs
-   with DACA (& Tumbler) the node to use is i2s-a.  On much older machines i.e.
-   before 9500 there is no davbus node and we have to use the 'awacs' property.
-
-  In the latter case we signal this by setting the codec value - so that the
-  code that looks for chip properties knows how to go about it.
-*/
-
-static struct device_node* __init
-get_snd_io_node(void)
-{
-       struct device_node *np;
-
-       /* set up awacs_node for early OF which doesn't have a full set of
-        * properties on davbus
-        */
-       awacs_node = of_find_node_by_name(NULL, "awacs");
-       if (awacs_node)
-               awacs_revision = AWACS_AWACS;
-
-       /* powermac models after 9500 (other than those which use DACA or
-        * Tumbler) have a node called "davbus".
-        */
-       np = of_find_node_by_name(NULL, "davbus");
-       /*
-        * if we didn't find a davbus device, try 'i2s-a' since
-        * this seems to be what iBooks (& Tumbler) have.
-        */
-       if (np == NULL) {
-               i2s_node = of_find_node_by_name(NULL, "i2s-a");
-               np = of_node_get(i2s_node);
-       }
-
-       /* if we didn't find this - perhaps we are on an early model
-        * which _only_ has an 'awacs' node
-       */
-       if (np == NULL && awacs_node)
-               np = of_node_get(awacs_node);
-
-       /* if we failed all these return null - this will cause the
-        * driver to give up...
-       */
-       return np ;
-}
-
-/* Get the OF node that contains the info about the sound chip, inputs s-rates
-   etc.
-   This node does not exist (or contains much reduced info) on earlier machines
-   we have to deduce the info other ways for these.
-*/
-
-static struct device_node* __init
-get_snd_info_node(struct device_node *io)
-{
-       struct device_node *info;
-
-       for_each_node_by_name(info, "sound")
-               if (info->parent == io)
-                       break;
-       return info;
-}
-
-/* Find out what type of codec we have.
-*/
-
-static int __init
-get_codec_type(struct device_node *info)
-{
-       /* already set if pre-davbus model and info will be NULL */
-       int codec = awacs_revision ;
-
-       if (info) {
-               /* must do awacs first to allow screamer to overide it */
-               if (of_device_is_compatible(info, "awacs"))
-                       codec = AWACS_AWACS ;
-               if (of_device_is_compatible(info, "screamer"))
-                       codec = AWACS_SCREAMER;
-               if (of_device_is_compatible(info, "burgundy"))
-                       codec = AWACS_BURGUNDY ;
-               if (of_device_is_compatible(info, "daca"))
-                       codec = AWACS_DACA;
-               if (of_device_is_compatible(info, "tumbler"))
-                       codec = AWACS_TUMBLER;
-               if (of_device_is_compatible(info, "snapper"))
-                       codec = AWACS_SNAPPER;
-       }
-       return codec ;
-}
-
-/* find out what type, if any, of expansion card we have
-*/
-static void __init
-get_expansion_type(void)
-{
-       struct device_node *dn;
-
-       dn = of_find_node_by_name(NULL, "perch");
-       if (dn != NULL)
-               has_perch = 1;
-       of_node_put(dn);
-
-       dn = of_find_node_by_name(NULL, "pb-ziva-pc");
-       if (dn != NULL)
-               has_ziva = 1;
-       of_node_put(dn);
-       /* need to work out how we deal with iMac SRS module */
-}
-
-/* set up frame rates.
- * I suspect that these routines don't quite go about it the right way:
- * - where there is more than one rate - I think that the first property
- * value is the number of rates.
- * TODO: check some more device trees and modify accordingly
- *       Set dmasound.mach.max_dsp_rate on the basis of these routines.
-*/
-
-static void __init
-awacs_init_frame_rates(const unsigned int *prop, unsigned int l)
-{
-       int i ;
-       if (prop) {
-               for (i=0; i<8; i++)
-                       awacs_freqs_ok[i] = 0 ;
-               for (l /= sizeof(int); l > 0; --l) {
-                       unsigned int r = *prop++;
-                       /* Apple 'Fixed' format */
-                       if (r >= 0x10000)
-                               r >>= 16;
-                       for (i = 0; i < 8; ++i) {
-                               if (r == awacs_freqs[i]) {
-                                       awacs_freqs_ok[i] = 1;
-                                       break;
-                               }
-                       }
-               }
-       }
-       /* else we assume that all the rates are available */
-}
-
-static void __init
-burgundy_init_frame_rates(const unsigned int *prop, unsigned int l)
-{
-       int temp[9] ;
-       int i = 0 ;
-       if (prop) {
-               for (l /= sizeof(int); l > 0; --l) {
-                       unsigned int r = *prop++;
-                       /* Apple 'Fixed' format */
-                       if (r >= 0x10000)
-                               r >>= 16;
-                       temp[i] = r ;
-                       i++ ; if(i>=9) i=8;
-               }
-       }
-#ifdef DEBUG_DMASOUND
-if (i > 1){
-       int j;
-       printk("dmasound_pmac: burgundy with multiple frame rates\n");
-       for(j=0; j<i; j++)
-               printk("%d ", temp[j]) ;
-       printk("\n") ;
-}
-#endif
-}
-
-static void __init
-daca_init_frame_rates(const unsigned int *prop, unsigned int l)
-{
-       int temp[9] ;
-       int i = 0 ;
-       if (prop) {
-               for (l /= sizeof(int); l > 0; --l) {
-                       unsigned int r = *prop++;
-                       /* Apple 'Fixed' format */
-                       if (r >= 0x10000)
-                               r >>= 16;
-                       temp[i] = r ;
-                       i++ ; if(i>=9) i=8;
-
-               }
-       }
-#ifdef DEBUG_DMASOUND
-if (i > 1){
-       int j;
-       printk("dmasound_pmac: DACA with multiple frame rates\n");
-       for(j=0; j<i; j++)
-               printk("%d ", temp[j]) ;
-       printk("\n") ;
-}
-#endif
-}
-
-static void __init
-init_frame_rates(const unsigned int *prop, unsigned int l)
-{
-       switch (awacs_revision) {
-               case AWACS_TUMBLER:
-               case AWACS_SNAPPER:
-                       tas_init_frame_rates(prop, l);
-                       break ;
-               case AWACS_DACA:
-                       daca_init_frame_rates(prop, l);
-                       break ;
-               case AWACS_BURGUNDY:
-                       burgundy_init_frame_rates(prop, l);
-                       break ;
-               default:
-                       awacs_init_frame_rates(prop, l);
-                       break ;
-       }
-}
-
-/* find things/machines that can't do mac-io byteswap
-*/
-
-static void __init
-set_hw_byteswap(struct device_node *io)
-{
-       struct device_node *mio ;
-       unsigned int kl = 0 ;
-
-       /* if seems that Keylargo can't byte-swap  */
-
-       for (mio = io->parent; mio ; mio = mio->parent) {
-               if (strcmp(mio->name, "mac-io") == 0) {
-                       if (of_device_is_compatible(mio, "Keylargo"))
-                               kl = 1;
-                       break;
-               }
-       }
-       hw_can_byteswap = !kl;
-}
-
-/* Allocate the resources necessary for beep generation.  This cannot be (quite)
-   done statically (yet) because we cannot do virt_to_bus() on static vars when
-   the code is loaded as a module.
-
-   for the sake of saving the possibility that two allocations will incur the
-   overhead of two pull-ups in DBDMA_ALIGN() we allocate the 'emergency' dmdma
-   command here as well... even tho' it is not part of the beep process.
-*/
-
-int32_t
-__init setup_beep(void)
-{
-       /* Initialize beep stuff */
-       /* want one cmd buffer for beeps, and a second one for emergencies
-          - i.e. dbdma error conditions.
-          ask for three to allow for pull up in DBDMA_ALIGN().
-       */
-       beep_dbdma_cmd_space =
-               kmalloc((2 + 1) * sizeof(struct dbdma_cmd), GFP_KERNEL);
-       if(beep_dbdma_cmd_space == NULL) {
-               printk(KERN_ERR "dmasound_pmac: no beep dbdma cmd space\n") ;
-               return -ENOMEM ;
-       }
-       beep_dbdma_cmd = (volatile struct dbdma_cmd *)
-                       DBDMA_ALIGN(beep_dbdma_cmd_space);
-       /* set up emergency dbdma cmd */
-       emergency_dbdma_cmd = beep_dbdma_cmd+1 ;
-       beep_buf = kmalloc(BEEP_BUFLEN * 4, GFP_KERNEL);
-       if (beep_buf == NULL) {
-               printk(KERN_ERR "dmasound_pmac: no memory for beep buffer\n");
-               kfree(beep_dbdma_cmd_space) ;
-               return -ENOMEM ;
-       }
-       return 0 ;
-}
-
-static struct input_dev *awacs_beep_dev;
-
-int __init dmasound_awacs_init(void)
-{
-       struct device_node *io = NULL, *info = NULL;
-       int vol, res;
-
-       if (!machine_is(powermac))
-               return -ENODEV;
-
-       awacs_subframe = 0;
-       awacs_revision = 0;
-       hw_can_byteswap = 1 ; /* most can */
-
-       /* look for models we need to handle specially */
-       set_model() ;
-
-       /* find the OF node that tells us about the dbdma stuff
-       */
-       io = get_snd_io_node();
-       if (io == NULL) {
-#ifdef DEBUG_DMASOUND
-printk("dmasound_pmac: couldn't find sound io OF node\n");
-#endif
-               goto no_device;
-       }
-
-       /* find the OF node that tells us about the sound sub-system
-        * this doesn't exist on pre-davbus machines (earlier than 9500)
-       */
-       if (awacs_revision != AWACS_AWACS) { /* set for pre-davbus */
-               info = get_snd_info_node(io) ;
-               if (info == NULL){
-#ifdef DEBUG_DMASOUND
-printk("dmasound_pmac: couldn't find 'sound' OF node\n");
-#endif
-                       goto no_device;
-               }
-       }
-
-       awacs_revision = get_codec_type(info) ;
-       if (awacs_revision == 0) {
-#ifdef DEBUG_DMASOUND
-printk("dmasound_pmac: couldn't find a Codec we can handle\n");
-#endif
-               goto no_device; /* we don't know this type of h/w */
-       }
-
-       /* set up perch, ziva, SRS or whatever else we have as sound
-        *  expansion.
-       */
-       get_expansion_type();
-
-       /* we've now got enough information to make up the audio topology.
-        * we will map the sound part of mac-io now so that we can probe for
-        * other info if necessary (early AWACS we want to read chip ids)
-        */
-
-       if (of_get_address(io, 2, NULL, NULL) == NULL) {
-               /* OK - maybe we need to use the 'awacs' node (on earlier
-                * machines).
-                */
-               if (awacs_node) {
-                       of_node_put(io);
-                       io = of_node_get(awacs_node);
-                       if (of_get_address(io, 2, NULL, NULL) == NULL) {
-                               printk("dmasound_pmac: can't use %s\n",
-                                      io->full_name);
-                               goto no_device;
-                       }
-               } else
-                       printk("dmasound_pmac: can't use %s\n", io->full_name);
-       }
-
-       if (of_address_to_resource(io, 0, &awacs_rsrc[0]) ||
-           request_mem_region(awacs_rsrc[0].start,
-                              awacs_rsrc[0].end - awacs_rsrc[0].start + 1,
-                              " (IO)") == NULL) {
-               printk(KERN_ERR "dmasound: can't request IO resource !\n");
-               goto no_device;
-       }
-       if (of_address_to_resource(io, 1, &awacs_rsrc[1]) ||
-           request_mem_region(awacs_rsrc[1].start,
-                              awacs_rsrc[1].end - awacs_rsrc[1].start + 1,
-                              " (tx dma)") == NULL) {
-               release_mem_region(awacs_rsrc[0].start,
-                                  awacs_rsrc[0].end - awacs_rsrc[0].start + 1);
-               printk(KERN_ERR "dmasound: can't request Tx DMA resource !\n");
-               goto no_device;
-       }
-       if (of_address_to_resource(io, 2, &awacs_rsrc[2]) ||
-           request_mem_region(awacs_rsrc[2].start,
-                              awacs_rsrc[2].end - awacs_rsrc[2].start + 1,
-                              " (rx dma)") == NULL) {
-               release_mem_region(awacs_rsrc[0].start,
-                                  awacs_rsrc[0].end - awacs_rsrc[0].start + 1);
-               release_mem_region(awacs_rsrc[1].start,
-                                  awacs_rsrc[1].end - awacs_rsrc[1].start + 1);
-               printk(KERN_ERR "dmasound: can't request Rx DMA resource !\n");
-               goto no_device;
-       }
-
-       awacs_beep_dev = input_allocate_device();
-       if (!awacs_beep_dev) {
-               release_mem_region(awacs_rsrc[0].start,
-                                  awacs_rsrc[0].end - awacs_rsrc[0].start + 1);
-               release_mem_region(awacs_rsrc[1].start,
-                                  awacs_rsrc[1].end - awacs_rsrc[1].start + 1);
-               release_mem_region(awacs_rsrc[2].start,
-                                  awacs_rsrc[2].end - awacs_rsrc[2].start + 1);
-               printk(KERN_ERR "dmasound: can't allocate input device !\n");
-               goto no_device;
-       }
-
-       awacs_beep_dev->name = "dmasound beeper";
-       awacs_beep_dev->phys = "macio/input0";
-       awacs_beep_dev->id.bustype = BUS_HOST;
-       awacs_beep_dev->event = awacs_beep_event;
-       awacs_beep_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
-       awacs_beep_dev->evbit[0] = BIT(EV_SND);
-
-       /* all OF versions I've seen use this value */
-       if (i2s_node)
-               i2s = ioremap(awacs_rsrc[0].start, 0x1000);
-       else
-               awacs = ioremap(awacs_rsrc[0].start, 0x1000);
-       awacs_txdma = ioremap(awacs_rsrc[1].start, 0x100);
-       awacs_rxdma = ioremap(awacs_rsrc[2].start, 0x100);
-
-       /* first of all make sure that the chip is powered up....*/
-       pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, io, 0, 1);
-       if (awacs_revision == AWACS_SCREAMER && awacs)
-               awacs_recalibrate();
-
-       awacs_irq = irq_of_parse_and_map(io, 0);
-       awacs_tx_irq = irq_of_parse_and_map(io, 1);
-       awacs_rx_irq = irq_of_parse_and_map(io, 2);
-
-       /* Hack for legacy crap that will be killed someday */
-       of_node_put(awacs_node);
-       awacs_node = of_node_get(io);
-
-       /* if we have an awacs or screamer - probe the chip to make
-        * sure we have the right revision.
-       */
-
-       if (awacs_revision <= AWACS_SCREAMER){
-               uint32_t temp, rev, mfg ;
-               /* find out the awacs revision from the chip */
-               temp = in_le32(&awacs->codec_stat);
-               rev = (temp >> 12) & 0xf;
-               mfg = (temp >>  8) & 0xf;
-#ifdef DEBUG_DMASOUND
-printk("dmasound_pmac: Awacs/Screamer Codec Mfct: %d Rev %d\n", mfg, rev);
-#endif
-               if (rev >= AWACS_SCREAMER)
-                       awacs_revision = AWACS_SCREAMER ;
-               else
-                       awacs_revision = rev ;
-       }
-
-       dmasound.mach = machPMac;
-
-       /* find out other bits & pieces from OF, these may be present
-          only on some models ... so be careful.
-       */
-
-       /* in the absence of a frame rates property we will use the defaults
-       */
-
-       if (info) {
-               const unsigned int *prop;
-               unsigned int l;
-
-               sound_device_id = 0;
-               /* device ID appears post g3 b&w */
-               prop = of_get_property(info, "device-id", NULL);
-               if (prop != 0)
-                       sound_device_id = *prop;
-
-               /* look for a property saying what sample rates
-                  are available */
-
-               prop = of_get_property(info, "sample-rates", &l);
-               if (prop == 0)
-                       prop = of_get_property(info, "output-frame-rates", &l);
-
-               /* if it's there use it to set up frame rates */
-               init_frame_rates(prop, l) ;
-               of_node_put(info);
-               info = NULL;
-       }
-
-       if (awacs)
-               out_le32(&awacs->control, 0x11); /* set everything quiesent */
-
-       set_hw_byteswap(io) ; /* figure out if the h/w can do it */
-
-#ifdef CONFIG_NVRAM
-       /* get default volume from nvram */
-       vol = ((pmac_xpram_read( 8 ) & 7 ) << 1 );
-#else
-       vol = 0;
-#endif
-
-       /* set up tracking values */
-       spk_vol = vol * 100 ;
-       spk_vol /= 7 ; /* get set value to a percentage */
-       spk_vol |= (spk_vol << 8) ; /* equal left & right */
-       line_vol = passthru_vol = spk_vol ;
-
-       /* fill regs that are shared between AWACS & Burgundy */
-
-       awacs_reg[2] = vol + (vol << 6);
-       awacs_reg[4] = vol + (vol << 6);
-       awacs_reg[5] = vol + (vol << 6); /* screamer has loopthru vol control */
-       awacs_reg[6] = 0; /* maybe should be vol << 3 for PCMCIA speaker */
-       awacs_reg[7] = 0;
-
-       awacs_reg[0] = MASK_MUX_CD;
-       awacs_reg[1] = MASK_LOOPTHRU;
-
-       /* FIXME: Only machines with external SRS module need MASK_PAROUT */
-       if (has_perch || sound_device_id == 0x5
-           || /*sound_device_id == 0x8 ||*/ sound_device_id == 0xb)
-               awacs_reg[1] |= MASK_PAROUT0 | MASK_PAROUT1;
-
-       switch (awacs_revision) {
-               case AWACS_TUMBLER:
-                        tas_register_driver(&tas3001c_hooks);
-                       tas_init(I2C_DRIVERID_TAS3001C, I2C_DRIVERNAME_TAS3001C);
-                       tas_dmasound_init();
-                       tas_post_init();
-                       break ;
-               case AWACS_SNAPPER:
-                        tas_register_driver(&tas3004_hooks);
-                       tas_init(I2C_DRIVERID_TAS3004,I2C_DRIVERNAME_TAS3004);
-                       tas_dmasound_init();
-                       tas_post_init();
-                       break;
-               case AWACS_DACA:
-                       daca_init();
-                       break;  
-               case AWACS_BURGUNDY:
-                       awacs_burgundy_init();
-                       break ;
-               case AWACS_SCREAMER:
-               case AWACS_AWACS:
-               default:
-                       load_awacs();
-                       break ;
-       }
-
-       /* enable/set-up external modules - when we know how */
-
-       if (has_perch)
-               awacs_enable_amp(100 * 0x101);
-
-       /* Reset dbdma channels */
-       out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16);
-       while (in_le32(&awacs_txdma->status) & RUN)
-               udelay(1);
-       out_le32(&awacs_rxdma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16);
-       while (in_le32(&awacs_rxdma->status) & RUN)
-               udelay(1);
-
-       /* Initialize beep stuff */
-       if ((res=setup_beep()))
-               return res ;
-
-#ifdef CONFIG_PM
-       pmu_register_sleep_notifier(&awacs_sleep_notifier);
-#endif /* CONFIG_PM */
-
-       /* Powerbooks have odd ways of enabling inputs such as
-          an expansion-bay CD or sound from an internal modem
-          or a PC-card modem. */
-       if (is_pbook_3X00) {
-               /*
-                * Enable CD and PC-card sound inputs.
-                * This is done by reading from address
-                * f301a000, + 0x10 to enable the expansion-bay
-                * CD sound input, + 0x80 to enable the PC-card
-                * sound input.  The 0x100 enables the SCSI bus
-                * terminator power.
-                */
-               latch_base = ioremap (0xf301a000, 0x1000);
-               in_8(latch_base + 0x190);
-
-       } else if (is_pbook_g3) {
-               struct device_node* mio;
-               macio_base = NULL;
-               for (mio = io->parent; mio; mio = mio->parent) {
-                       if (strcmp(mio->name, "mac-io") == 0) {
-                               struct resource r;
-                               if (of_address_to_resource(mio, 0, &r) == 0)
-                                       macio_base = ioremap(r.start, 0x40);
-                               break;
-                       }
-               }
-               /*
-                * Enable CD sound input.
-                * The relevant bits for writing to this byte are 0x8f.
-                * I haven't found out what the 0x80 bit does.
-                * For the 0xf bits, writing 3 or 7 enables the CD
-                * input, any other value disables it.  Values
-                * 1, 3, 5, 7 enable the microphone.  Values 0, 2,
-                * 4, 6, 8 - f enable the input from the modem.
-                *  -- paulus.
-                */
-               if (macio_base)
-                       out_8(macio_base + 0x37, 3);
-       }
-
-       if (hw_can_byteswap)
-               dmasound.mach.hardware_afmts = (AFMT_S16_BE | AFMT_S16_LE) ;
-       else
-               dmasound.mach.hardware_afmts = AFMT_S16_BE ;
-
-       /* shut out chips that do output only.
-        * may need to extend this to machines which have no inputs - even tho'
-        * they use screamer - IIRC one of the powerbooks is like this.
-        */
-
-       if (awacs_revision != AWACS_DACA) {
-               dmasound.mach.capabilities = DSP_CAP_DUPLEX ;
-               dmasound.mach.record = PMacRecord ;
-       }
-
-       dmasound.mach.default_hard = def_hard ;
-       dmasound.mach.default_soft = def_soft ;
-
-       switch (awacs_revision) {
-               case AWACS_BURGUNDY:
-                       sprintf(awacs_name, "PowerMac Burgundy ") ;
-                       break ;
-               case AWACS_DACA:
-                       sprintf(awacs_name, "PowerMac DACA ") ;
-                       break ;
-               case AWACS_TUMBLER:
-                       sprintf(awacs_name, "PowerMac Tumbler ") ;
-                       break ;
-               case AWACS_SNAPPER:
-                       sprintf(awacs_name, "PowerMac Snapper ") ;
-                       break ;
-               case AWACS_SCREAMER:
-                       sprintf(awacs_name, "PowerMac Screamer ") ;
-                       break ;
-               case AWACS_AWACS:
-               default:
-                       sprintf(awacs_name, "PowerMac AWACS rev %d ", awacs_revision) ;
-                       break ;
-       }
-
-       /*
-        * XXX: we should handle errors here, but that would mean
-        * rewriting the whole init code.  later..
-        */
-       input_register_device(awacs_beep_dev);
-
-       of_node_put(io);
-
-       return dmasound_init();
-
-no_device:
-       of_node_put(info);
-       of_node_put(awacs_node);
-       of_node_put(i2s_node);
-       of_node_put(io);
-       return -ENODEV ;
-}
-
-static void __exit dmasound_awacs_cleanup(void)
-{
-       input_unregister_device(awacs_beep_dev);
-
-       switch (awacs_revision) {
-               case AWACS_TUMBLER:
-               case AWACS_SNAPPER:
-                       tas_dmasound_cleanup();
-                       tas_cleanup();
-                       break ;
-               case AWACS_DACA:
-                       daca_cleanup();
-                       break;
-       }
-       dmasound_deinit();
-
-       of_node_put(awacs_node);
-       of_node_put(i2s_node);
-}
-
-MODULE_DESCRIPTION("PowerMac built-in audio driver.");
-MODULE_LICENSE("GPL");
-
-module_init(dmasound_awacs_init);
-module_exit(dmasound_awacs_cleanup);
index f4056a9c371b03ee6df58c20a4d8e9e1a8c72a46..a003c0ea9303f800f27e6de612773d0a2f5012e2 100644 (file)
@@ -202,13 +202,6 @@ module_param(numWriteBufs, int, 0);
 static unsigned int writeBufSize = DEFAULT_BUFF_SIZE ; /* in bytes */
 module_param(writeBufSize, int, 0);
 
-#ifdef HAS_RECORD
-static unsigned int numReadBufs = DEFAULT_N_BUFFERS;
-module_param(numReadBufs, int, 0);
-static unsigned int readBufSize = DEFAULT_BUFF_SIZE;   /* in bytes */
-module_param(readBufSize, int, 0);
-#endif
-
 MODULE_LICENSE("GPL");
 
 #ifdef MODULE
@@ -403,10 +396,6 @@ static void mixer_init(void)
 
 struct sound_queue dmasound_write_sq;
 static void sq_reset_output(void) ;
-#ifdef HAS_RECORD
-struct sound_queue dmasound_read_sq;
-static void sq_reset_input(void) ;
-#endif
 
 static int sq_allocate_buffers(struct sound_queue *sq, int num, int size)
 {
@@ -530,12 +519,6 @@ printk("dmasound_core: invalid frag count (user set %d)\n", sq->user_frags) ;
            sq->rear = -1;
            setup_func = dmasound.mach.write_sq_setup;
        }
-#ifdef HAS_RECORD
-       else {
-           sq->rear = 0;
-           setup_func = dmasound.mach.read_sq_setup;
-       }
-#endif
        if (setup_func)
            return setup_func();
        return 0 ;
@@ -672,13 +655,6 @@ static unsigned int sq_poll(struct file *file, struct poll_table_struct *wait)
        }
        if (file->f_mode & FMODE_WRITE )
                poll_wait(file, &write_sq.action_queue, wait);
-#ifdef HAS_RECORD
-       if (file->f_mode & FMODE_READ)
-               poll_wait(file, &read_sq.action_queue, wait);
-       if (file->f_mode & FMODE_READ)
-               if (read_sq.block_size - read_sq.rear_size > 0)
-                       mask |= POLLIN | POLLRDNORM;
-#endif
        if (file->f_mode & FMODE_WRITE)
                if (write_sq.count < write_sq.max_active || write_sq.block_size - write_sq.rear_size > 0)
                        mask |= POLLOUT | POLLWRNORM;
@@ -686,101 +662,6 @@ static unsigned int sq_poll(struct file *file, struct poll_table_struct *wait)
 
 }
 
-#ifdef HAS_RECORD
-    /*
-     *  Here is how the values are used for reading.
-     *  The value 'active' simply indicates the DMA is running.  This is done
-     *  so the driver semantics are DMA starts when the first read is posted.
-     *  The value 'front' indicates the buffer we should next send to the user.
-     *  The value 'rear' indicates the buffer the DMA is currently filling.
-     *  When 'front' == 'rear' the buffer "ring" is empty (we always have an
-     *  empty available).  The 'rear_size' is used to track partial offsets
-     *  into the buffer we are currently returning to the user.
-
-     *  This level (> [1.5]) doesn't care what strategy the LL driver uses with
-     *  DMA on over-run.  It can leave it running (and keep active == 1) or it
-     *  can kill it and set active == 0 in which case this routine will spot
-     *  it and restart the DMA.
-     */
-
-static ssize_t sq_read(struct file *file, char __user *dst, size_t uLeft,
-                      loff_t *ppos)
-{
-
-       ssize_t uRead, bLeft, bUsed, uUsed;
-
-       if (uLeft == 0)
-               return 0;
-
-       /* cater for the compatibility mode - record compiled in but no LL */
-       if (dmasound.mach.record == NULL)
-               return -EINVAL ;
-
-       /* see comment in sq_write()
-       */
-
-       if( shared_resources_initialised == 0) {
-               dmasound.mach.init() ;
-               shared_resources_initialised = 1 ;
-       }
-
-       /* set up the sq if it is not already done. see comments in sq_write().
-       */
-
-       if (read_sq.locked == 0) {
-               if ((uRead = sq_setup(&read_sq)) < 0)
-                       return uRead ;
-       }
-
-       uRead = 0;
-
-       /* Move what the user requests, depending upon other options.
-       */
-       while (uLeft > 0) {
-
-               /* we happened to get behind and the LL driver killed DMA
-                  then we should set it going again.  This also sets it
-                  going the first time through.
-               */
-               if ( !read_sq.active )
-                       dmasound.mach.record();
-
-               /* When front == rear, the DMA is not done yet.
-               */
-               while (read_sq.front == read_sq.rear) {
-                       if (read_sq.open_mode & O_NONBLOCK) {
-                              return uRead > 0 ? uRead : -EAGAIN;
-                       }
-                       SLEEP(read_sq.action_queue);
-                       if (signal_pending(current))
-                               return uRead > 0 ? uRead : -EINTR;
-               }
-
-               /* The amount we move is either what is left in the
-                * current buffer or what the user wants.
-                */
-               bLeft = read_sq.block_size - read_sq.rear_size;
-               bUsed = read_sq.rear_size;
-               uUsed = sound_copy_translate(dmasound.trans_read, dst, uLeft,
-                                            read_sq.buffers[read_sq.front],
-                                            &bUsed, bLeft);
-               if (uUsed <= 0)
-                       return uUsed;
-               dst += uUsed;
-               uRead += uUsed;
-               uLeft -= uUsed;
-               read_sq.rear_size += bUsed;
-               if (read_sq.rear_size >= read_sq.block_size) {
-                       read_sq.rear_size = 0;
-                       read_sq.front++;
-                       if (read_sq.front >= read_sq.max_active)
-                               read_sq.front = 0;
-               }
-       }
-       return uRead;
-}
-#endif /* HAS_RECORD */
-
 static inline void sq_init_waitqueue(struct sound_queue *sq)
 {
        init_waitqueue_head(&sq->action_queue);
@@ -854,23 +735,6 @@ static int sq_open2(struct sound_queue *sq, struct file *file, mode_t mode,
 #define write_sq_open(file)    \
        sq_open2(&write_sq, file, FMODE_WRITE, numWriteBufs, writeBufSize )
 
-#ifdef HAS_RECORD
-#define read_sq_init_waitqueue()       sq_init_waitqueue(&read_sq)
-#if 0 /* blocking open() */
-#define read_sq_wake_up(file)          sq_wake_up(&read_sq, file, FMODE_READ)
-#endif
-#define read_sq_release_buffers()      sq_release_buffers(&read_sq)
-#define read_sq_open(file)     \
-       sq_open2(&read_sq, file, FMODE_READ, numReadBufs, readBufSize )
-#else
-#define read_sq_init_waitqueue()       do {} while (0)
-#if 0 /* blocking open() */
-#define read_sq_wake_up(file)          do {} while (0)
-#endif
-#define read_sq_release_buffers()      do {} while (0)
-#define sq_reset_input()               do {} while (0)
-#endif
-
 static int sq_open(struct inode *inode, struct file *file)
 {
        int rc;
@@ -881,25 +745,11 @@ static int sq_open(struct inode *inode, struct file *file)
        rc = write_sq_open(file); /* checks the f_mode */
        if (rc)
                goto out;
-#ifdef HAS_RECORD
-       if (dmasound.mach.record) {
-               rc = read_sq_open(file); /* checks the f_mode */
-               if (rc)
-                       goto out;
-       } else { /* no record function installed; in compat mode */
-               if (file->f_mode & FMODE_READ) {
-                       /* TODO: if O_RDWR, release any resources grabbed by write part */
-                       rc = -ENXIO;
-                       goto out;
-               }
-       }
-#else /* !HAS_RECORD */
        if (file->f_mode & FMODE_READ) {
                /* TODO: if O_RDWR, release any resources grabbed by write part */
                rc = -ENXIO ; /* I think this is what is required by open(2) */
                goto out;
        }
-#endif /* HAS_RECORD */
 
        if (dmasound.mach.sq_open)
            dmasound.mach.sq_open(file->f_mode);
@@ -956,43 +806,9 @@ static void sq_reset_output(void)
        write_sq.user_frag_size = 0 ;
 }
 
-#ifdef HAS_RECORD
-
-static void sq_reset_input(void)
-{
-       if (dmasound.mach.record && read_sq.active) {
-               if (dmasound.mach.abort_read) { /* this routine must really be present */
-                       read_sq.syncing = 1 ;
-                       /* this can use the read_sq.sync_queue to sleep if
-                          necessary - it should not return until DMA
-                          is really stopped - because we might deallocate
-                          the buffers as the next action...
-                       */
-                       dmasound.mach.abort_read() ;
-               } else {
-                       printk(KERN_ERR
-                       "dmasound_core: %s has no abort_read()!! all bets are off\n",
-                               dmasound.mach.name) ;
-               }
-       }
-       read_sq.syncing =
-       read_sq.active =
-       read_sq.front =
-       read_sq.count =
-       read_sq.rear = 0 ;
-
-       /* OK - we can unlock the parameters and fragment settings */
-       read_sq.locked = 0 ;
-       read_sq.user_frags = 0 ;
-       read_sq.user_frag_size = 0 ;
-}
-
-#endif
-
 static void sq_reset(void)
 {
        sq_reset_output() ;
-       sq_reset_input() ;
        /* we could consider resetting the shared_resources_owner here... but I
           think it is probably still rather non-obvious to application writer
        */
@@ -1038,17 +854,6 @@ static int sq_release(struct inode *inode, struct file *file)
 
        lock_kernel();
 
-#ifdef HAS_RECORD
-       /* probably best to do the read side first - so that time taken to do it
-          overlaps with playing any remaining output samples.
-       */
-       if (file->f_mode & FMODE_READ) {
-               sq_reset_input() ; /* make sure dma is stopped and all is quiet */
-               read_sq_release_buffers();
-               read_sq.busy = 0;
-       }
-#endif
-
        if (file->f_mode & FMODE_WRITE) {
                if (write_sq.busy)
                        rc = sq_fsync(file, file->f_path.dentry);
@@ -1105,11 +910,6 @@ static int shared_resources_are_mine(mode_t md)
 
 static int queues_are_quiescent(void)
 {
-#ifdef HAS_RECORD
-       if (dmasound.mach.record)
-               if (read_sq.locked)
-                       return 0 ;
-#endif
        if (write_sq.locked)
                return 0 ;
        return 1 ;
@@ -1185,13 +985,6 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd,
                   the read_sq ones.
                */
                size = 0 ;
-#ifdef HAS_RECORD
-               if (dmasound.mach.record && (file->f_mode & FMODE_READ)) {
-                       if ( !read_sq.locked )
-                               sq_setup(&read_sq) ; /* set params */
-                       size = read_sq.user_frag_size ;
-               }
-#endif
                if (file->f_mode & FMODE_WRITE) {
                        if ( !write_sq.locked )
                                sq_setup(&write_sq) ;
@@ -1214,8 +1007,6 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd,
                   everything - read, however, is killed imediately.
                */
                result = 0 ;
-               if ((file->f_mode & FMODE_READ) && dmasound.mach.record)
-                       sq_reset_input() ;
                if (file->f_mode & FMODE_WRITE) {
                        result = sq_fsync(file, file->f_path.dentry);
                        sq_reset_output() ;
@@ -1294,13 +1085,6 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd,
                result = 0 ;
                nbufs = (data >> 16) & 0x7fff ; /* 0x7fff is 'use maximum' */
                size = data & 0xffff;
-#ifdef HAS_RECORD
-               if ((file->f_mode & FMODE_READ) && dmasound.mach.record) {
-                       result = set_queue_frags(&read_sq, nbufs, size) ;
-                       if (result)
-                               return result ;
-               }
-#endif
                if (file->f_mode & FMODE_WRITE) {
                        result = set_queue_frags(&write_sq, nbufs, size) ;
                        if (result)
@@ -1348,20 +1132,6 @@ static const struct file_operations sq_fops =
        .release        = sq_release,
 };
 
-#ifdef HAS_RECORD
-static const struct file_operations sq_fops_record =
-{
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .write          = sq_write,
-       .poll           = sq_poll,
-       .ioctl          = sq_ioctl,
-       .open           = sq_open,
-       .release        = sq_release,
-       .read           = sq_read,
-};
-#endif
-
 static int sq_init(void)
 {
        const struct file_operations *fops = &sq_fops;
@@ -1369,10 +1139,6 @@ static int sq_init(void)
        int sq_unit;
 #endif
 
-#ifdef HAS_RECORD
-       if (dmasound.mach.record)
-               fops = &sq_fops_record;
-#endif
        sq_unit = register_sound_dsp(fops, -1);
        if (sq_unit < 0) {
                printk(KERN_ERR "dmasound_core: couldn't register fops\n") ;
@@ -1380,7 +1146,6 @@ static int sq_init(void)
        }
 
        write_sq_init_waitqueue();
-       read_sq_init_waitqueue();
 
        /* These parameters will be restored for every clean open()
         * in the case of multiple open()s (e.g. dsp0 & dsp1) they
@@ -1406,11 +1171,7 @@ static int sq_init(void)
    driver.
 */
 
-#ifdef HAS_RECORD
-#define STAT_BUFF_LEN 1024
-#else
 #define STAT_BUFF_LEN 768
-#endif
 
 /* this is how much space we will allow the low-level driver to use
    in the stat buffer.  Currently, 2 * (80 character line + <NL>).
@@ -1518,11 +1279,6 @@ static int state_open(struct inode *inode, struct file *file)
        len += sprintf(buffer+len,"Allocated:%8s%6s\n","Buffers","Size") ;
        len += sprintf(buffer+len,"%9s:%8d%6d\n",
                "write", write_sq.numBufs, write_sq.bufSize) ;
-#ifdef HAS_RECORD
-       if (dmasound.mach.record)
-               len += sprintf(buffer+len,"%9s:%8d%6d\n",
-                       "read", read_sq.numBufs, read_sq.bufSize) ;
-#endif
        len += sprintf(buffer+len,
                "Current  : MaxFrg FragSiz MaxAct Frnt Rear "
                "Cnt RrSize A B S L  xruns\n") ;
@@ -1531,14 +1287,6 @@ static int state_open(struct inode *inode, struct file *file)
                write_sq.max_active, write_sq.front, write_sq.rear,
                write_sq.count, write_sq.rear_size, write_sq.active,
                write_sq.busy, write_sq.syncing, write_sq.locked, write_sq.xruns) ;
-#ifdef HAS_RECORD
-       if (dmasound.mach.record)
-               len += sprintf(buffer+len,"%9s:%7d%8d%7d%5d%5d%4d%7d%2d%2d%2d%2d%7d\n",
-                       "read", read_sq.max_count, read_sq.block_size,
-                       read_sq.max_active, read_sq.front, read_sq.rear,
-                       read_sq.count, read_sq.rear_size, read_sq.active,
-                       read_sq.busy, read_sq.syncing, read_sq.locked, read_sq.xruns) ;
-#endif
 #ifdef DEBUG_DMASOUND
 printk("dmasound: stat buffer used %d bytes\n", len) ;
 #endif
@@ -1638,13 +1386,6 @@ int dmasound_init(void)
                (dmasound.mach.version >> 8), (dmasound.mach.version & 0xff)) ;
        printk(KERN_INFO "Write will use %4d fragments of %7d bytes as default\n",
                numWriteBufs, writeBufSize) ;
-#ifdef HAS_RECORD
-       if (dmasound.mach.record)
-               printk(KERN_INFO
-                       "Read  will use %4d fragments of %7d bytes as default\n",
-                       numReadBufs, readBufSize) ;
-#endif
-
        return 0;
 }
 
@@ -1659,7 +1400,6 @@ void dmasound_deinit(void)
        }
 
        write_sq_release_buffers();
-       read_sq_release_buffers();
 
        if (mixer_unit >= 0)
                unregister_sound_mixer(mixer_unit);
@@ -1684,36 +1424,12 @@ static int dmasound_setup(char *str)
         */
 
        switch (ints[0]) {
-#ifdef HAS_RECORD
-        case 5:
-                if ((ints[5] < 0) || (ints[5] > MAX_CATCH_RADIUS))
-                        printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius);
-                else
-                        catchRadius = ints[5];
-                /* fall through */
-        case 4:
-                if (ints[4] < MIN_BUFFERS)
-                        printk("dmasound_setup: invalid number of read buffers, using default = %d\n",
-                                 numReadBufs);
-                else
-                        numReadBufs = ints[4];
-                /* fall through */
-        case 3:
-               if ((size = ints[3]) < 256)  /* check for small buffer specs */
-                       size <<= 10 ;
-                if (size < MIN_BUFSIZE || size > MAX_BUFSIZE)
-                        printk("dmasound_setup: invalid read buffer size, using default = %d\n", readBufSize);
-                else
-                        readBufSize = size;
-                /* fall through */
-#else
        case 3:
                if ((ints[3] < 0) || (ints[3] > MAX_CATCH_RADIUS))
                        printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius);
                else
                        catchRadius = ints[3];
                /* fall through */
-#endif
        case 2:
                if (ints[1] < MIN_BUFFERS)
                        printk("dmasound_setup: invalid number of buffers, using default = %d\n", numWriteBufs);
@@ -1830,9 +1546,6 @@ EXPORT_SYMBOL(dmasound_init);
 EXPORT_SYMBOL(dmasound_deinit);
 #endif
 EXPORT_SYMBOL(dmasound_write_sq);
-#ifdef HAS_RECORD
-EXPORT_SYMBOL(dmasound_read_sq);
-#endif
 EXPORT_SYMBOL(dmasound_catchRadius);
 #ifdef HAS_8BIT_TABLES
 EXPORT_SYMBOL(dmasound_ulaw2dma8);
diff --git a/sound/oss/dmasound/tas3001c.c b/sound/oss/dmasound/tas3001c.c
deleted file mode 100644 (file)
index 4b7dbdd..0000000
+++ /dev/null
@@ -1,849 +0,0 @@
-/*
- * Driver for the i2c/i2s based TA3004 sound chip used
- * on some Apple hardware. Also known as "snapper".
- *
- * Tobias Sargeant <tobias.sargeant@bigpond.com>
- * Based upon, tas3001c.c by Christopher C. Chimelis <chris@debian.org>:
- *
- *   TODO:
- *   -----
- *   * Enable control over input line 2 (is this connected?)
- *   * Implement sleep support (at least mute everything and
- *   * set gains to minimum during sleep)
- *   * Look into some of Darwin's tweaks regarding the mute
- *   * lines (delays & different behaviour on some HW)
- *
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/proc_fs.h>
-#include <linux/ioport.h>
-#include <linux/sysctl.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/soundcard.h>
-#include <linux/workqueue.h>
-#include <asm/uaccess.h>
-#include <asm/errno.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-
-#include "dmasound.h"
-#include "tas_common.h"
-#include "tas3001c.h"
-
-#include "tas_ioctl.h"
-
-#define TAS3001C_BIQUAD_FILTER_COUNT  6
-#define TAS3001C_BIQUAD_CHANNEL_COUNT 2
-
-#define VOL_DEFAULT    (100 * 4 / 5)
-#define INPUT_DEFAULT  (100 * 4 / 5)
-#define BASS_DEFAULT   (100 / 2)
-#define TREBLE_DEFAULT (100 / 2)
-
-struct tas3001c_data_t {
-       struct tas_data_t super;
-       int device_id;
-       int output_id;
-       int speaker_id;
-       struct tas_drce_t drce_state;
-       struct work_struct change;
-};
-
-
-static const union tas_biquad_t
-tas3001c_eq_unity={
-       .buf = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 }
-};
-
-
-static inline unsigned char db_to_regval(short db) {
-       int r=0;
-
-       r=(db+0x59a0) / 0x60;
-
-       if (r < 0x91) return 0x91;
-       if (r > 0xef) return 0xef;
-       return r;
-}
-
-static inline short quantize_db(short db) {
-       return db_to_regval(db) * 0x60 - 0x59a0;
-}
-
-
-static inline int
-register_width(enum tas3001c_reg_t r)
-{
-       switch(r) {
-       case TAS3001C_REG_MCR:
-       case TAS3001C_REG_TREBLE:
-       case TAS3001C_REG_BASS:
-               return 1;
-
-       case TAS3001C_REG_DRC:
-               return 2;
-
-       case TAS3001C_REG_MIXER1:
-       case TAS3001C_REG_MIXER2:
-               return 3;
-
-       case TAS3001C_REG_VOLUME:
-               return 6;
-
-       case TAS3001C_REG_LEFT_BIQUAD0:
-       case TAS3001C_REG_LEFT_BIQUAD1:
-       case TAS3001C_REG_LEFT_BIQUAD2:
-       case TAS3001C_REG_LEFT_BIQUAD3:
-       case TAS3001C_REG_LEFT_BIQUAD4:
-       case TAS3001C_REG_LEFT_BIQUAD5:
-       case TAS3001C_REG_LEFT_BIQUAD6:
-
-       case TAS3001C_REG_RIGHT_BIQUAD0:
-       case TAS3001C_REG_RIGHT_BIQUAD1:
-       case TAS3001C_REG_RIGHT_BIQUAD2:
-       case TAS3001C_REG_RIGHT_BIQUAD3:
-       case TAS3001C_REG_RIGHT_BIQUAD4:
-       case TAS3001C_REG_RIGHT_BIQUAD5:
-       case TAS3001C_REG_RIGHT_BIQUAD6:
-               return 15;
-
-       default:
-               return 0;
-       }
-}
-
-static int
-tas3001c_write_register(       struct tas3001c_data_t *self,
-                               enum tas3001c_reg_t reg_num,
-                               char *data,
-                               uint write_mode)
-{
-       if (reg_num==TAS3001C_REG_MCR ||
-           reg_num==TAS3001C_REG_BASS ||
-           reg_num==TAS3001C_REG_TREBLE) {
-               return tas_write_byte_register(&self->super,
-                                              (uint)reg_num,
-                                              *data,
-                                              write_mode);
-       } else {
-               return tas_write_register(&self->super,
-                                         (uint)reg_num,
-                                         register_width(reg_num),
-                                         data,
-                                         write_mode);
-       }
-}
-
-static int
-tas3001c_sync_register(        struct tas3001c_data_t *self,
-                       enum tas3001c_reg_t reg_num)
-{
-       if (reg_num==TAS3001C_REG_MCR ||
-           reg_num==TAS3001C_REG_BASS ||
-           reg_num==TAS3001C_REG_TREBLE) {
-               return tas_sync_byte_register(&self->super,
-                                             (uint)reg_num,
-                                             register_width(reg_num));
-       } else {
-               return tas_sync_register(&self->super,
-                                        (uint)reg_num,
-                                        register_width(reg_num));
-       }
-}
-
-static int
-tas3001c_read_register(        struct tas3001c_data_t *self,
-                       enum tas3001c_reg_t reg_num,
-                       char *data,
-                       uint write_mode)
-{
-       return tas_read_register(&self->super,
-                                (uint)reg_num,
-                                register_width(reg_num),
-                                data);
-}
-
-static inline int
-tas3001c_fast_load(struct tas3001c_data_t *self, int fast)
-{
-       if (fast)
-               self->super.shadow[TAS3001C_REG_MCR][0] |= 0x80;
-       else
-               self->super.shadow[TAS3001C_REG_MCR][0] &= 0x7f;
-       return tas3001c_sync_register(self,TAS3001C_REG_MCR);
-}
-
-static uint
-tas3001c_supported_mixers(struct tas3001c_data_t *self)
-{
-       return SOUND_MASK_VOLUME |
-               SOUND_MASK_PCM |
-               SOUND_MASK_ALTPCM |
-               SOUND_MASK_TREBLE |
-               SOUND_MASK_BASS;
-}
-
-static int
-tas3001c_mixer_is_stereo(struct tas3001c_data_t *self,int mixer)
-{
-       switch(mixer) {
-       case SOUND_MIXER_VOLUME:
-               return 1;
-       default:
-               return 0;
-       }
-}
-
-static uint
-tas3001c_stereo_mixers(struct tas3001c_data_t *self)
-{
-       uint r=tas3001c_supported_mixers(self);
-       uint i;
-       
-       for (i=1; i<SOUND_MIXER_NRDEVICES; i++)
-               if (r&(1<<i) && !tas3001c_mixer_is_stereo(self,i))
-                       r &= ~(1<<i);
-       return r;
-}
-
-static int
-tas3001c_get_mixer_level(struct tas3001c_data_t *self,int mixer,uint *level)
-{
-       if (!self)
-               return -1;
-               
-       *level=self->super.mixer[mixer];
-       
-       return 0;
-}
-
-static int
-tas3001c_set_mixer_level(struct tas3001c_data_t *self,int mixer,uint level)
-{
-       int rc;
-       tas_shadow_t *shadow;
-
-       uint temp;
-       uint offset=0;
-
-       if (!self)
-               return -1;
-               
-       shadow=self->super.shadow;
-
-       if (!tas3001c_mixer_is_stereo(self,mixer))
-               level = tas_mono_to_stereo(level);
-
-       switch(mixer) {
-       case SOUND_MIXER_VOLUME:
-               temp = tas3001c_gain.master[level&0xff];
-               shadow[TAS3001C_REG_VOLUME][0] = (temp >> 16) & 0xff;
-               shadow[TAS3001C_REG_VOLUME][1] = (temp >> 8)  & 0xff;
-               shadow[TAS3001C_REG_VOLUME][2] = (temp >> 0)  & 0xff;
-               temp = tas3001c_gain.master[(level>>8)&0xff];
-               shadow[TAS3001C_REG_VOLUME][3] = (temp >> 16) & 0xff;
-               shadow[TAS3001C_REG_VOLUME][4] = (temp >> 8)  & 0xff;
-               shadow[TAS3001C_REG_VOLUME][5] = (temp >> 0)  & 0xff;
-               rc = tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
-               break;
-       case SOUND_MIXER_ALTPCM:
-               /* tas3001c_fast_load(self, 1); */
-               level = tas_mono_to_stereo(level);
-               temp = tas3001c_gain.mixer[level&0xff];
-               shadow[TAS3001C_REG_MIXER2][offset+0] = (temp >> 16) & 0xff;
-               shadow[TAS3001C_REG_MIXER2][offset+1] = (temp >> 8)  & 0xff;
-               shadow[TAS3001C_REG_MIXER2][offset+2] = (temp >> 0)  & 0xff;
-               rc = tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
-               /* tas3001c_fast_load(self, 0); */
-               break;
-       case SOUND_MIXER_PCM:
-               /* tas3001c_fast_load(self, 1); */
-               level = tas_mono_to_stereo(level);
-               temp = tas3001c_gain.mixer[level&0xff];
-               shadow[TAS3001C_REG_MIXER1][offset+0] = (temp >> 16) & 0xff;
-               shadow[TAS3001C_REG_MIXER1][offset+1] = (temp >> 8)  & 0xff;
-               shadow[TAS3001C_REG_MIXER1][offset+2] = (temp >> 0)  & 0xff;
-               rc = tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
-               /* tas3001c_fast_load(self, 0); */
-               break;
-       case SOUND_MIXER_TREBLE:
-               temp = tas3001c_gain.treble[level&0xff];
-               shadow[TAS3001C_REG_TREBLE][0]=temp&0xff;
-               rc = tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
-               break;
-       case SOUND_MIXER_BASS:
-               temp = tas3001c_gain.bass[level&0xff];
-               shadow[TAS3001C_REG_BASS][0]=temp&0xff;
-               rc = tas3001c_sync_register(self,TAS3001C_REG_BASS);
-               break;
-       default:
-               rc = -1;
-               break;
-       }
-       if (rc < 0)
-               return rc;
-       self->super.mixer[mixer]=level;
-       return 0;
-}
-
-static int
-tas3001c_leave_sleep(struct tas3001c_data_t *self)
-{
-       unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
-
-       if (!self)
-               return -1;
-
-       /* Make sure something answers on the i2c bus */
-       if (tas3001c_write_register(self, TAS3001C_REG_MCR, &mcr,
-           WRITE_NORMAL|FORCE_WRITE) < 0)
-               return -1;
-
-       tas3001c_fast_load(self, 1);
-
-       (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD0);
-       (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD1);
-       (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD2);
-       (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD3);
-       (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD4);
-       (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD5);
-
-       (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD0);
-       (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD1);
-       (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD2);
-       (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD3);
-       (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD4);
-       (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD5);
-
-       tas3001c_fast_load(self, 0);
-
-       (void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
-       (void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
-       (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
-       (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
-       (void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
-
-       return 0;
-}
-
-static int
-tas3001c_enter_sleep(struct tas3001c_data_t *self)
-{
-       /* Stub for now, but I have the details on low-power mode */
-       if (!self)
-               return -1; 
-       return 0;
-}
-
-static int
-tas3001c_sync_biquad(  struct tas3001c_data_t *self,
-                       u_int channel,
-                       u_int filter)
-{
-       enum tas3001c_reg_t reg;
-
-       if (channel >= TAS3001C_BIQUAD_CHANNEL_COUNT ||
-           filter  >= TAS3001C_BIQUAD_FILTER_COUNT) return -EINVAL;
-
-       reg=( channel ? TAS3001C_REG_RIGHT_BIQUAD0 : TAS3001C_REG_LEFT_BIQUAD0 ) + filter;
-
-       return tas3001c_sync_register(self,reg);
-}
-
-static int
-tas3001c_write_biquad_shadow(  struct tas3001c_data_t *self,
-                               u_int channel,
-                               u_int filter,
-                               const union tas_biquad_t *biquad)
-{
-       tas_shadow_t *shadow=self->super.shadow;
-       enum tas3001c_reg_t reg;
-
-       if (channel >= TAS3001C_BIQUAD_CHANNEL_COUNT ||
-           filter  >= TAS3001C_BIQUAD_FILTER_COUNT) return -EINVAL;
-
-       reg=( channel ? TAS3001C_REG_RIGHT_BIQUAD0 : TAS3001C_REG_LEFT_BIQUAD0 ) + filter;
-
-       SET_4_20(shadow[reg], 0,biquad->coeff.b0);
-       SET_4_20(shadow[reg], 3,biquad->coeff.b1);
-       SET_4_20(shadow[reg], 6,biquad->coeff.b2);
-       SET_4_20(shadow[reg], 9,biquad->coeff.a1);
-       SET_4_20(shadow[reg],12,biquad->coeff.a2);
-
-       return 0;
-}
-
-static int
-tas3001c_write_biquad( struct tas3001c_data_t *self,
-                       u_int channel,
-                       u_int filter,
-                       const union tas_biquad_t *biquad)
-{
-       int rc;
-
-       rc=tas3001c_write_biquad_shadow(self, channel, filter, biquad);
-       if (rc < 0) return rc;
-
-       return tas3001c_sync_biquad(self, channel, filter);
-}
-
-static int
-tas3001c_write_biquad_list(    struct tas3001c_data_t *self,
-                               u_int filter_count,
-                               u_int flags,
-                               struct tas_biquad_ctrl_t *biquads)
-{
-       int i;
-       int rc;
-
-       if (flags & TAS_BIQUAD_FAST_LOAD) tas3001c_fast_load(self,1);
-
-       for (i=0; i<filter_count; i++) {
-               rc=tas3001c_write_biquad(self,
-                                        biquads[i].channel,
-                                        biquads[i].filter,
-                                        &biquads[i].data);
-               if (rc < 0) break;
-       }
-
-       if (flags & TAS_BIQUAD_FAST_LOAD) {
-               tas3001c_fast_load(self,0);
-
-               (void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
-               (void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
-               (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
-               (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
-               (void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
-       }
-
-       return rc;
-}
-
-static int
-tas3001c_read_biquad(  struct tas3001c_data_t *self,
-                       u_int channel,
-                       u_int filter,
-                       union tas_biquad_t *biquad)
-{
-       tas_shadow_t *shadow=self->super.shadow;
-       enum tas3001c_reg_t reg;
-
-       if (channel >= TAS3001C_BIQUAD_CHANNEL_COUNT ||
-           filter  >= TAS3001C_BIQUAD_FILTER_COUNT) return -EINVAL;
-
-       reg=( channel ? TAS3001C_REG_RIGHT_BIQUAD0 : TAS3001C_REG_LEFT_BIQUAD0 ) + filter;
-
-       biquad->coeff.b0=GET_4_20(shadow[reg], 0);
-       biquad->coeff.b1=GET_4_20(shadow[reg], 3);
-       biquad->coeff.b2=GET_4_20(shadow[reg], 6);
-       biquad->coeff.a1=GET_4_20(shadow[reg], 9);
-       biquad->coeff.a2=GET_4_20(shadow[reg],12);
-       
-       return 0;       
-}
-
-static int
-tas3001c_eq_rw(        struct tas3001c_data_t *self,
-               u_int cmd,
-               u_long arg)
-{
-       int rc;
-       struct tas_biquad_ctrl_t biquad;
-       void __user *argp = (void __user *)arg;
-
-       if (copy_from_user(&biquad, argp, sizeof(struct tas_biquad_ctrl_t))) {
-               return -EFAULT;
-       }
-
-       if (cmd & SIOC_IN) {
-               rc=tas3001c_write_biquad(self, biquad.channel, biquad.filter, &biquad.data);
-               if (rc != 0) return rc;
-       }
-
-       if (cmd & SIOC_OUT) {
-               rc=tas3001c_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
-               if (rc != 0) return rc;
-
-               if (copy_to_user(argp, &biquad, sizeof(struct tas_biquad_ctrl_t))) {
-                       return -EFAULT;
-               }
-
-       }
-       return 0;
-}
-
-static int
-tas3001c_eq_list_rw(   struct tas3001c_data_t *self,
-                       u_int cmd,
-                       u_long arg)
-{
-       int rc;
-       int filter_count;
-       int flags;
-       int i,j;
-       char sync_required[2][6];
-       struct tas_biquad_ctrl_t biquad;
-       struct tas_biquad_ctrl_list_t __user *argp = (void __user *)arg;
-
-       memset(sync_required,0,sizeof(sync_required));
-
-       if (copy_from_user(&filter_count, &argp->filter_count, sizeof(int)))
-               return -EFAULT;
-
-       if (copy_from_user(&flags, &argp->flags, sizeof(int)))
-               return -EFAULT;
-
-       if (cmd & SIOC_IN) {
-       }
-
-       for (i=0; i < filter_count; i++) {
-               if (copy_from_user(&biquad, &argp->biquads[i],
-                                  sizeof(struct tas_biquad_ctrl_t))) {
-                       return -EFAULT;
-               }
-
-               if (cmd & SIOC_IN) {
-                       sync_required[biquad.channel][biquad.filter]=1;
-                       rc=tas3001c_write_biquad_shadow(self, biquad.channel, biquad.filter, &biquad.data);
-                       if (rc != 0) return rc;
-               }
-
-               if (cmd & SIOC_OUT) {
-                       rc=tas3001c_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
-                       if (rc != 0) return rc;
-
-                       if (copy_to_user(&argp->biquads[i], &biquad,
-                                        sizeof(struct tas_biquad_ctrl_t))) {
-                               return -EFAULT;
-                       }
-               }
-       }
-
-       if (cmd & SIOC_IN) {
-               if (flags & TAS_BIQUAD_FAST_LOAD) tas3001c_fast_load(self,1);
-               for (i=0; i<2; i++) {
-                       for (j=0; j<6; j++) {
-                               if (sync_required[i][j]) {
-                                       rc=tas3001c_sync_biquad(self, i, j);
-                                       if (rc < 0) return rc;
-                               }
-                       }
-               }
-               if (flags & TAS_BIQUAD_FAST_LOAD) {
-                       tas3001c_fast_load(self,0);
-                       /* now we need to set up the mixers again,
-                          because leaving fast mode resets them. */
-                       (void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
-                       (void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
-                       (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
-                       (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
-                       (void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
-               }
-       }
-
-       return 0;
-}
-
-static int
-tas3001c_update_drce(  struct tas3001c_data_t *self,
-                       int flags,
-                       struct tas_drce_t *drce)
-{
-       tas_shadow_t *shadow;
-       shadow=self->super.shadow;
-
-       shadow[TAS3001C_REG_DRC][1] = 0xc1;
-
-       if (flags & TAS_DRCE_THRESHOLD) {
-               self->drce_state.threshold=quantize_db(drce->threshold);
-               shadow[TAS3001C_REG_DRC][2] = db_to_regval(self->drce_state.threshold);
-       }
-
-       if (flags & TAS_DRCE_ENABLE) {
-               self->drce_state.enable = drce->enable;
-       }
-
-       if (!self->drce_state.enable) {
-               shadow[TAS3001C_REG_DRC][0] = 0xf0;
-       }
-
-#ifdef DEBUG_DRCE
-       printk("DRCE IOCTL: set [ ENABLE:%x THRESH:%x\n",
-              self->drce_state.enable,
-              self->drce_state.threshold);
-
-       printk("DRCE IOCTL: reg [ %02x %02x ]\n",
-              (unsigned char)shadow[TAS3001C_REG_DRC][0],
-              (unsigned char)shadow[TAS3001C_REG_DRC][1]);
-#endif
-
-       return tas3001c_sync_register(self, TAS3001C_REG_DRC);
-}
-
-static int
-tas3001c_drce_rw(      struct tas3001c_data_t *self,
-                       u_int cmd,
-                       u_long arg)
-{
-       int rc;
-       struct tas_drce_ctrl_t drce_ctrl;
-       void __user *argp = (void __user *)arg;
-
-       if (copy_from_user(&drce_ctrl, argp, sizeof(struct tas_drce_ctrl_t)))
-               return -EFAULT;
-
-#ifdef DEBUG_DRCE
-       printk("DRCE IOCTL: input [ FLAGS:%x ENABLE:%x THRESH:%x\n",
-              drce_ctrl.flags,
-              drce_ctrl.data.enable,
-              drce_ctrl.data.threshold);
-#endif
-
-       if (cmd & SIOC_IN) {
-               rc = tas3001c_update_drce(self, drce_ctrl.flags, &drce_ctrl.data);
-               if (rc < 0)
-                       return rc;
-       }
-
-       if (cmd & SIOC_OUT) {
-               if (drce_ctrl.flags & TAS_DRCE_ENABLE)
-                       drce_ctrl.data.enable = self->drce_state.enable;
-
-               if (drce_ctrl.flags & TAS_DRCE_THRESHOLD)
-                       drce_ctrl.data.threshold = self->drce_state.threshold;
-
-               if (copy_to_user(argp, &drce_ctrl,
-                                sizeof(struct tas_drce_ctrl_t))) {
-                       return -EFAULT;
-               }
-       }
-
-       return 0;
-}
-
-static void
-tas3001c_update_device_parameters(struct tas3001c_data_t *self)
-{
-       int i,j;
-
-       if (!self) return;
-
-       if (self->output_id == TAS_OUTPUT_HEADPHONES) {
-               tas3001c_fast_load(self, 1);
-
-               for (i=0; i<TAS3001C_BIQUAD_CHANNEL_COUNT; i++) {
-                       for (j=0; j<TAS3001C_BIQUAD_FILTER_COUNT; j++) {
-                               tas3001c_write_biquad(self, i, j, &tas3001c_eq_unity);
-                       }
-               }
-
-               tas3001c_fast_load(self, 0);
-
-               (void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
-               (void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
-               (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
-               (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
-               (void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
-
-               return;
-       }
-
-       for (i=0; tas3001c_eq_prefs[i]; i++) {
-               struct tas_eq_pref_t *eq = tas3001c_eq_prefs[i];
-
-               if (eq->device_id == self->device_id &&
-                   (eq->output_id == 0 || eq->output_id == self->output_id) &&
-                   (eq->speaker_id == 0 || eq->speaker_id == self->speaker_id)) {
-
-                       tas3001c_update_drce(self, TAS_DRCE_ALL, eq->drce);
-                       tas3001c_write_biquad_list(self, eq->filter_count, TAS_BIQUAD_FAST_LOAD, eq->biquads);
-
-                       break;
-               }
-       }
-}
-
-static void
-tas3001c_device_change_handler(struct work_struct *work)
-{
-       struct tas3001c_data_t *self;
-       self = container_of(work, struct tas3001c_data_t, change);
-       tas3001c_update_device_parameters(self);
-}
-
-static int
-tas3001c_output_device_change( struct tas3001c_data_t *self,
-                               int device_id,
-                               int output_id,
-                               int speaker_id)
-{
-       self->device_id=device_id;
-       self->output_id=output_id;
-       self->speaker_id=speaker_id;
-
-       schedule_work(&self->change);
-       return 0;
-}
-
-static int
-tas3001c_device_ioctl( struct tas3001c_data_t *self,
-                       u_int cmd,
-                       u_long arg)
-{
-       uint __user *argp = (void __user *)arg;
-       switch (cmd) {
-       case TAS_READ_EQ:
-       case TAS_WRITE_EQ:
-               return tas3001c_eq_rw(self, cmd, arg);
-
-       case TAS_READ_EQ_LIST:
-       case TAS_WRITE_EQ_LIST:
-               return tas3001c_eq_list_rw(self, cmd, arg);
-
-       case TAS_READ_EQ_FILTER_COUNT:
-               put_user(TAS3001C_BIQUAD_FILTER_COUNT, argp);
-               return 0;
-
-       case TAS_READ_EQ_CHANNEL_COUNT:
-               put_user(TAS3001C_BIQUAD_CHANNEL_COUNT, argp);
-               return 0;
-
-       case TAS_READ_DRCE:
-       case TAS_WRITE_DRCE:
-               return tas3001c_drce_rw(self, cmd, arg);
-
-       case TAS_READ_DRCE_CAPS:
-               put_user(TAS_DRCE_ENABLE | TAS_DRCE_THRESHOLD, argp);
-               return 0;
-
-       case TAS_READ_DRCE_MIN:
-       case TAS_READ_DRCE_MAX: {
-               struct tas_drce_ctrl_t drce_ctrl;
-
-               if (copy_from_user(&drce_ctrl, argp,
-                                  sizeof(struct tas_drce_ctrl_t))) {
-                       return -EFAULT;
-               }
-
-               if (drce_ctrl.flags & TAS_DRCE_THRESHOLD) {
-                       if (cmd == TAS_READ_DRCE_MIN) {
-                               drce_ctrl.data.threshold=-36<<8;
-                       } else {
-                               drce_ctrl.data.threshold=-6<<8;
-                       }
-               }
-
-               if (copy_to_user(argp, &drce_ctrl,
-                                sizeof(struct tas_drce_ctrl_t))) {
-                       return -EFAULT;
-               }
-       }
-       }
-
-       return -EINVAL;
-}
-
-static int
-tas3001c_init_mixer(struct tas3001c_data_t *self)
-{
-       unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
-
-       /* Make sure something answers on the i2c bus */
-       if (tas3001c_write_register(self, TAS3001C_REG_MCR, &mcr,
-           WRITE_NORMAL|FORCE_WRITE) < 0)
-               return -1;
-
-       tas3001c_fast_load(self, 1);
-
-       (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD0);
-       (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD1);
-       (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD2);
-       (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD3);
-       (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD4);
-       (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD5);
-       (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD6);
-
-       (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD0);
-       (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD1);
-       (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD2);
-       (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD3);
-       (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD4);
-       (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD5);
-       (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD6);
-
-       tas3001c_fast_load(self, 0);
-
-       tas3001c_set_mixer_level(self, SOUND_MIXER_VOLUME, VOL_DEFAULT<<8 | VOL_DEFAULT);
-       tas3001c_set_mixer_level(self, SOUND_MIXER_PCM, INPUT_DEFAULT<<8 | INPUT_DEFAULT);
-       tas3001c_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
-
-       tas3001c_set_mixer_level(self, SOUND_MIXER_BASS, BASS_DEFAULT);
-       tas3001c_set_mixer_level(self, SOUND_MIXER_TREBLE, TREBLE_DEFAULT);
-
-       return 0;
-}
-
-static int
-tas3001c_uninit_mixer(struct tas3001c_data_t *self)
-{
-       tas3001c_set_mixer_level(self, SOUND_MIXER_VOLUME, 0);
-       tas3001c_set_mixer_level(self, SOUND_MIXER_PCM,    0);
-       tas3001c_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
-
-       tas3001c_set_mixer_level(self, SOUND_MIXER_BASS,   0);
-       tas3001c_set_mixer_level(self, SOUND_MIXER_TREBLE, 0);
-
-       return 0;
-}
-
-static int
-tas3001c_init(struct i2c_client *client)
-{
-       struct tas3001c_data_t *self;
-       size_t sz = sizeof(*self) + (TAS3001C_REG_MAX*sizeof(tas_shadow_t));
-       int i, j;
-
-       self = kzalloc(sz, GFP_KERNEL);
-       if (!self)
-               return -ENOMEM;
-
-       self->super.client = client;
-       self->super.shadow = (tas_shadow_t *)(self+1);
-       self->output_id = TAS_OUTPUT_HEADPHONES;
-
-       dev_set_drvdata(&client->dev, self);
-
-       for (i = 0; i < TAS3001C_BIQUAD_CHANNEL_COUNT; i++)
-               for (j = 0; j < TAS3001C_BIQUAD_FILTER_COUNT; j++)
-                       tas3001c_write_biquad_shadow(self, i, j,
-                               &tas3001c_eq_unity);
-
-       INIT_WORK(&self->change, tas3001c_device_change_handler);
-       return 0;
-}
-
-static void
-tas3001c_uninit(struct tas3001c_data_t *self)
-{
-       tas3001c_uninit_mixer(self);
-       kfree(self);
-}
-
-struct tas_driver_hooks_t tas3001c_hooks = {
-       .init                   = (tas_hook_init_t)tas3001c_init,
-       .post_init              = (tas_hook_post_init_t)tas3001c_init_mixer,
-       .uninit                 = (tas_hook_uninit_t)tas3001c_uninit,
-       .get_mixer_level        = (tas_hook_get_mixer_level_t)tas3001c_get_mixer_level,
-       .set_mixer_level        = (tas_hook_set_mixer_level_t)tas3001c_set_mixer_level,
-       .enter_sleep            = (tas_hook_enter_sleep_t)tas3001c_enter_sleep,
-       .leave_sleep            = (tas_hook_leave_sleep_t)tas3001c_leave_sleep,
-       .supported_mixers       = (tas_hook_supported_mixers_t)tas3001c_supported_mixers,
-       .mixer_is_stereo        = (tas_hook_mixer_is_stereo_t)tas3001c_mixer_is_stereo,
-       .stereo_mixers          = (tas_hook_stereo_mixers_t)tas3001c_stereo_mixers,
-       .output_device_change   = (tas_hook_output_device_change_t)tas3001c_output_device_change,
-       .device_ioctl           = (tas_hook_device_ioctl_t)tas3001c_device_ioctl
-};
diff --git a/sound/oss/dmasound/tas3001c.h b/sound/oss/dmasound/tas3001c.h
deleted file mode 100644 (file)
index 3660da3..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Header file for the i2c/i2s based TA3001c sound chip used
- * on some Apple hardware. Also known as "tumbler".
- *
- *  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.
- *
- * Written by Christopher C. Chimelis <chris@debian.org>
- */
-
-#ifndef _TAS3001C_H_
-#define _TAS3001C_H_
-
-#include <linux/types.h>
-
-#include "tas_common.h"
-#include "tas_eq_prefs.h"
-
-/*
- * Macros that correspond to the registers that we write to
- * when setting the various values.
- */
-
-#define TAS3001C_VERSION       "0.3"
-#define TAS3001C_DATE          "20011214"
-
-#define I2C_DRIVERNAME_TAS3001C "TAS3001c driver V " TAS3001C_VERSION
-#define I2C_DRIVERID_TAS3001C   (I2C_DRIVERID_TAS_BASE+0)
-
-extern  struct tas_driver_hooks_t tas3001c_hooks;
-extern struct tas_gain_t tas3001c_gain;
-extern struct tas_eq_pref_t *tas3001c_eq_prefs[];
-
-enum tas3001c_reg_t {
-  TAS3001C_REG_MCR                    = 0x01,
-  TAS3001C_REG_DRC                    = 0x02,
-
-  TAS3001C_REG_VOLUME                 = 0x04,
-  TAS3001C_REG_TREBLE                 = 0x05,
-  TAS3001C_REG_BASS                   = 0x06,
-  TAS3001C_REG_MIXER1                 = 0x07,
-  TAS3001C_REG_MIXER2                 = 0x08,
-
-  TAS3001C_REG_LEFT_BIQUAD0           = 0x0a,
-  TAS3001C_REG_LEFT_BIQUAD1           = 0x0b,
-  TAS3001C_REG_LEFT_BIQUAD2           = 0x0c,
-  TAS3001C_REG_LEFT_BIQUAD3           = 0x0d,
-  TAS3001C_REG_LEFT_BIQUAD4           = 0x0e,
-  TAS3001C_REG_LEFT_BIQUAD5           = 0x0f,
-  TAS3001C_REG_LEFT_BIQUAD6           = 0x10,
-  
-  TAS3001C_REG_RIGHT_BIQUAD0          = 0x13,
-  TAS3001C_REG_RIGHT_BIQUAD1          = 0x14,
-  TAS3001C_REG_RIGHT_BIQUAD2          = 0x15,
-  TAS3001C_REG_RIGHT_BIQUAD3          = 0x16,
-  TAS3001C_REG_RIGHT_BIQUAD4          = 0x17,
-  TAS3001C_REG_RIGHT_BIQUAD5          = 0x18,
-  TAS3001C_REG_RIGHT_BIQUAD6          = 0x19,
-
-  TAS3001C_REG_MAX                    = 0x20
-};
-
-#endif /* _TAS3001C_H_ */
diff --git a/sound/oss/dmasound/tas3001c_tables.c b/sound/oss/dmasound/tas3001c_tables.c
deleted file mode 100644 (file)
index 1768fa9..0000000
+++ /dev/null
@@ -1,375 +0,0 @@
-#include "tas_common.h"
-#include "tas_eq_prefs.h"
-
-static struct tas_drce_t eqp_0e_2_1_drce = {
-  .enable     = 1,
-  .above      = { .val = 3.0 * (1<<8), .expand = 0 },
-  .below      = { .val = 1.0 * (1<<8), .expand = 0 },
-  .threshold  = -15.33  * (1<<8),
-  .energy     = 2.4     * (1<<12),
-  .attack     = 0.013   * (1<<12),
-  .decay      = 0.212   * (1<<12),
-};
-
-static struct tas_biquad_ctrl_t eqp_0e_2_1_biquads[]={
-  { .channel = 0, .filter = 0, .data = { .coeff = { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } },
-  { .channel = 0, .filter = 1, .data = { .coeff = { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } },
-  { .channel = 0, .filter = 2, .data = { .coeff = { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } },
-  { .channel = 0, .filter = 3, .data = { .coeff = { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } },
-  { .channel = 0, .filter = 4, .data = { .coeff = { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } },
-  { .channel = 0, .filter = 5, .data = { .coeff = { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } },
-
-  { .channel = 1, .filter = 0, .data = { .coeff = { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } },
-  { .channel = 1, .filter = 1, .data = { .coeff = { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } },
-  { .channel = 1, .filter = 2, .data = { .coeff = { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } },
-  { .channel = 1, .filter = 3, .data = { .coeff = { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } },
-  { .channel = 1, .filter = 4, .data = { .coeff = { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } },
-  { .channel = 1, .filter = 5, .data = { .coeff = { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } },
-};
-
-static struct tas_eq_pref_t eqp_0e_2_1 = {
-  .sample_rate   = 44100,
-  .device_id     = 0x0e,
-  .output_id     = TAS_OUTPUT_EXTERNAL_SPKR,
-  .speaker_id    = 0x01,
-
-  .drce          = &eqp_0e_2_1_drce,
-
-  .filter_count  = 12,
-  .biquads       = eqp_0e_2_1_biquads
-};
-
-/* ======================================================================== */
-
-static struct tas_drce_t eqp_10_1_0_drce={
-  .enable     = 1,
-  .above      = { .val = 3.0 * (1<<8), .expand = 0 },
-  .below      = { .val = 1.0 * (1<<8), .expand = 0 },
-  .threshold  = -12.46  * (1<<8),
-  .energy     = 2.4     * (1<<12),
-  .attack     = 0.013   * (1<<12),
-  .decay      = 0.212   * (1<<12),
-};
-
-static struct tas_biquad_ctrl_t eqp_10_1_0_biquads[]={
-  { .channel = 0, .filter = 0, .data = { .coeff = { 0x0F4A12, 0xE16BDA, 0x0F4A12, 0xE173F0, 0x0E9C3A } } },
-  { .channel = 0, .filter = 1, .data = { .coeff = { 0x02DD54, 0x05BAA8, 0x02DD54, 0xF8001D, 0x037532 } } },
-  { .channel = 0, .filter = 2, .data = { .coeff = { 0x0E2FC7, 0xE4D5DC, 0x0D7477, 0xE4D5DC, 0x0BA43F } } },
-  { .channel = 0, .filter = 3, .data = { .coeff = { 0x0E7899, 0xE67CCA, 0x0D0E93, 0xE67CCA, 0x0B872D } } },
-  { .channel = 0, .filter = 4, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
-  { .channel = 0, .filter = 5, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
-
-  { .channel = 1, .filter = 0, .data = { .coeff = { 0x0F4A12, 0xE16BDA, 0x0F4A12, 0xE173F0, 0x0E9C3A } } },
-  { .channel = 1, .filter = 1, .data = { .coeff = { 0x02DD54, 0x05BAA8, 0x02DD54, 0xF8001D, 0x037532 } } },
-  { .channel = 1, .filter = 2, .data = { .coeff = { 0x0E2FC7, 0xE4D5DC, 0x0D7477, 0xE4D5DC, 0x0BA43F } } },
-  { .channel = 1, .filter = 3, .data = { .coeff = { 0x0E7899, 0xE67CCA, 0x0D0E93, 0xE67CCA, 0x0B872D } } },
-  { .channel = 1, .filter = 4, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
-  { .channel = 1, .filter = 5, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
-};
-
-static struct tas_eq_pref_t eqp_10_1_0 = {
-  .sample_rate   = 44100,
-  .device_id     = 0x10,
-  .output_id     = TAS_OUTPUT_INTERNAL_SPKR,
-  .speaker_id    = 0x00,
-
-  .drce          = &eqp_10_1_0_drce,
-
-  .filter_count  = 12,
-  .biquads       = eqp_10_1_0_biquads
-};
-
-/* ======================================================================== */
-
-static struct tas_drce_t eqp_15_2_1_drce={
-  .enable     = 1,
-  .above      = { .val = 3.0 * (1<<8), .expand = 0 },
-  .below      = { .val = 1.0 * (1<<8), .expand = 0 },
-  .threshold  = -15.33  * (1<<8),
-  .energy     = 2.4     * (1<<12),
-  .attack     = 0.013   * (1<<12),
-  .decay      = 0.212   * (1<<12),
-};
-
-static struct tas_biquad_ctrl_t eqp_15_2_1_biquads[]={
-  { .channel = 0, .filter = 0, .data = { .coeff = { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } },
-  { .channel = 0, .filter = 1, .data = { .coeff = { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } },
-  { .channel = 0, .filter = 2, .data = { .coeff = { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } },
-  { .channel = 0, .filter = 3, .data = { .coeff = { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } },
-  { .channel = 0, .filter = 4, .data = { .coeff = { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } },
-  { .channel = 0, .filter = 5, .data = { .coeff = { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } },
-
-  { .channel = 1, .filter = 0, .data = { .coeff = { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } },
-  { .channel = 1, .filter = 1, .data = { .coeff = { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } },
-  { .channel = 1, .filter = 2, .data = { .coeff = { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } },
-  { .channel = 1, .filter = 3, .data = { .coeff = { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } },
-  { .channel = 1, .filter = 4, .data = { .coeff = { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } },
-  { .channel = 1, .filter = 5, .data = { .coeff = { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } },
-};
-
-static struct tas_eq_pref_t eqp_15_2_1 = {
-  .sample_rate   = 44100,
-  .device_id     = 0x15,
-  .output_id     = TAS_OUTPUT_EXTERNAL_SPKR,
-  .speaker_id    = 0x01,
-
-  .drce          = &eqp_15_2_1_drce,
-
-  .filter_count  = 12,
-  .biquads       = eqp_15_2_1_biquads
-};
-
-/* ======================================================================== */
-
-static struct tas_drce_t eqp_15_1_0_drce={
-  .enable     = 1,
-  .above      = { .val = 3.0 * (1<<8), .expand = 0 },
-  .below      = { .val = 1.0 * (1<<8), .expand = 0 },
-  .threshold  = 0.0     * (1<<8),
-  .energy     = 2.4     * (1<<12),
-  .attack     = 0.013   * (1<<12),
-  .decay      = 0.212   * (1<<12),
-};
-
-static struct tas_biquad_ctrl_t eqp_15_1_0_biquads[]={
-  { .channel = 0, .filter = 0, .data = { .coeff = { 0x0FAD08, 0xE0A5EF, 0x0FAD08, 0xE0A79D, 0x0F5BBE } } },
-  { .channel = 0, .filter = 1, .data = { .coeff = { 0x04B38D, 0x09671B, 0x04B38D, 0x000F71, 0x02BEC5 } } },
-  { .channel = 0, .filter = 2, .data = { .coeff = { 0x0FDD32, 0xE0A56F, 0x0F8A69, 0xE0A56F, 0x0F679C } } },
-  { .channel = 0, .filter = 3, .data = { .coeff = { 0x0FD284, 0xE135FB, 0x0F2161, 0xE135FB, 0x0EF3E5 } } },
-  { .channel = 0, .filter = 4, .data = { .coeff = { 0x0E81B1, 0xE6283F, 0x0CE49D, 0xE6283F, 0x0B664F } } },
-  { .channel = 0, .filter = 5, .data = { .coeff = { 0x0F2D62, 0xE98797, 0x0D1E19, 0xE98797, 0x0C4B7B } } },
-
-  { .channel = 1, .filter = 0, .data = { .coeff = { 0x0FAD08, 0xE0A5EF, 0x0FAD08, 0xE0A79D, 0x0F5BBE } } },
-  { .channel = 1, .filter = 1, .data = { .coeff = { 0x04B38D, 0x09671B, 0x04B38D, 0x000F71, 0x02BEC5 } } },
-  { .channel = 1, .filter = 2, .data = { .coeff = { 0x0FDD32, 0xE0A56F, 0x0F8A69, 0xE0A56F, 0x0F679C } } },
-  { .channel = 1, .filter = 3, .data = { .coeff = { 0x0FD284, 0xE135FB, 0x0F2161, 0xE135FB, 0x0EF3E5 } } },
-  { .channel = 1, .filter = 4, .data = { .coeff = { 0x0E81B1, 0xE6283F, 0x0CE49D, 0xE6283F, 0x0B664F } } },
-  { .channel = 1, .filter = 5, .data = { .coeff = { 0x0F2D62, 0xE98797, 0x0D1E19, 0xE98797, 0x0C4B7B } } },
-};
-
-static struct tas_eq_pref_t eqp_15_1_0 = {
-  .sample_rate   = 44100,
-  .device_id     = 0x15,
-  .output_id     = TAS_OUTPUT_INTERNAL_SPKR,
-  .speaker_id    = 0x00,
-
-  .drce          = &eqp_15_1_0_drce,
-
-  .filter_count  = 12,
-  .biquads       = eqp_15_1_0_biquads
-};
-
-/* ======================================================================== */
-
-static struct tas_drce_t eqp_0f_2_1_drce={
-  .enable     = 1,
-  .above      = { .val = 3.0 * (1<<8), .expand = 0 },
-  .below      = { .val = 1.0 * (1<<8), .expand = 0 },
-  .threshold  = -15.33  * (1<<8),
-  .energy     = 2.4     * (1<<12),
-  .attack     = 0.013   * (1<<12),
-  .decay      = 0.212   * (1<<12),
-};
-
-static struct tas_biquad_ctrl_t eqp_0f_2_1_biquads[]={
-  { .channel = 0, .filter = 0, .data = { .coeff = { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } },
-  { .channel = 0, .filter = 1, .data = { .coeff = { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } },
-  { .channel = 0, .filter = 2, .data = { .coeff = { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } },
-  { .channel = 0, .filter = 3, .data = { .coeff = { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } },
-  { .channel = 0, .filter = 4, .data = { .coeff = { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } },
-  { .channel = 0, .filter = 5, .data = { .coeff = { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } },
-
-  { .channel = 1, .filter = 0, .data = { .coeff = { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } },
-  { .channel = 1, .filter = 1, .data = { .coeff = { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } },
-  { .channel = 1, .filter = 2, .data = { .coeff = { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } },
-  { .channel = 1, .filter = 3, .data = { .coeff = { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } },
-  { .channel = 1, .filter = 4, .data = { .coeff = { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } },
-  { .channel = 1, .filter = 5, .data = { .coeff = { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } },
-};
-
-static struct tas_eq_pref_t eqp_0f_2_1 = {
-  .sample_rate   = 44100,
-  .device_id     = 0x0f,
-  .output_id     = TAS_OUTPUT_EXTERNAL_SPKR,
-  .speaker_id    = 0x01,
-
-  .drce          = &eqp_0f_2_1_drce,
-
-  .filter_count  = 12,
-  .biquads       = eqp_0f_2_1_biquads
-};
-
-/* ======================================================================== */
-
-static struct tas_drce_t eqp_0f_1_0_drce={
-  .enable     = 1,
-  .above      = { .val = 3.0 * (1<<8), .expand = 0 },
-  .below      = { .val = 1.0 * (1<<8), .expand = 0 },
-  .threshold  = -15.33  * (1<<8),
-  .energy     = 2.4     * (1<<12),
-  .attack     = 0.013   * (1<<12),
-  .decay      = 0.212   * (1<<12),
-};
-
-static struct tas_biquad_ctrl_t eqp_0f_1_0_biquads[]={
-  { .channel = 0, .filter = 0, .data = { .coeff = { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } },
-  { .channel = 0, .filter = 1, .data = { .coeff = { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } },
-  { .channel = 0, .filter = 2, .data = { .coeff = { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } },
-  { .channel = 0, .filter = 3, .data = { .coeff = { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } },
-  { .channel = 0, .filter = 4, .data = { .coeff = { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } },
-  { .channel = 0, .filter = 5, .data = { .coeff = { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } },
-
-  { .channel = 1, .filter = 0, .data = { .coeff = { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } },
-  { .channel = 1, .filter = 1, .data = { .coeff = { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } },
-  { .channel = 1, .filter = 2, .data = { .coeff = { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } },
-  { .channel = 1, .filter = 3, .data = { .coeff = { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } },
-  { .channel = 1, .filter = 4, .data = { .coeff = { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } },
-  { .channel = 1, .filter = 5, .data = { .coeff = { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } },
-};
-
-static struct tas_eq_pref_t eqp_0f_1_0 = {
-  .sample_rate   = 44100,
-  .device_id     = 0x0f,
-  .output_id     = TAS_OUTPUT_INTERNAL_SPKR,
-  .speaker_id    = 0x00,
-
-  .drce          = &eqp_0f_1_0_drce,
-
-  .filter_count  = 12,
-  .biquads       = eqp_0f_1_0_biquads
-};
-
-/* ======================================================================== */
-
-static uint tas3001c_master_tab[]={
-              0x0,       0x75,       0x9c,       0xbb,
-             0xdb,       0xfb,      0x11e,      0x143,
-            0x16b,      0x196,      0x1c3,      0x1f5,
-            0x229,      0x263,      0x29f,      0x2e1,
-            0x328,      0x373,      0x3c5,      0x41b,
-            0x478,      0x4dc,      0x547,      0x5b8,
-            0x633,      0x6b5,      0x740,      0x7d5,
-            0x873,      0x91c,      0x9d2,      0xa92,
-            0xb5e,      0xc39,      0xd22,      0xe19,
-            0xf20,     0x1037,     0x1161,     0x129e,
-           0x13ed,     0x1551,     0x16ca,     0x185d,
-           0x1a08,     0x1bcc,     0x1dac,     0x1fa7,
-           0x21c1,     0x23fa,     0x2655,     0x28d6,
-           0x2b7c,     0x2e4a,     0x3141,     0x3464,
-           0x37b4,     0x3b35,     0x3ee9,     0x42d3,
-           0x46f6,     0x4b53,     0x4ff0,     0x54ce,
-           0x59f2,     0x5f5f,     0x6519,     0x6b24,
-           0x7183,     0x783c,     0x7f53,     0x86cc,
-           0x8ead,     0x96fa,     0x9fba,     0xa8f2,
-           0xb2a7,     0xbce1,     0xc7a5,     0xd2fa,
-           0xdee8,     0xeb75,     0xf8aa,    0x1068e,
-          0x1152a,    0x12487,    0x134ad,    0x145a5,
-          0x1577b,    0x16a37,    0x17df5,    0x192bd,
-          0x1a890,    0x1bf7b,    0x1d78d,    0x1f0d1,
-          0x20b55,    0x22727,    0x24456,    0x262f2,
-          0x2830b
-};
-
-static uint tas3001c_mixer_tab[]={
-              0x0,      0x748,      0x9be,      0xbaf,
-            0xda4,      0xfb1,     0x11de,     0x1431,
-           0x16ad,     0x1959,     0x1c37,     0x1f4b,
-           0x2298,     0x2628,     0x29fb,     0x2e12,
-           0x327d,     0x3734,     0x3c47,     0x41b4,
-           0x4787,     0x4dbe,     0x546d,     0x5b86,
-           0x632e,     0x6b52,     0x7400,     0x7d54,
-           0x873b,     0x91c6,     0x9d1a,     0xa920,
-           0xb5e5,     0xc38c,     0xd21b,     0xe18f,
-           0xf1f5,    0x1036a,    0x1160f,    0x129d6,
-          0x13ed0,    0x1550c,    0x16ca0,    0x185c9,
-          0x1a07b,    0x1bcc3,    0x1dab9,    0x1fa75,
-          0x21c0f,    0x23fa3,    0x26552,    0x28d64,
-          0x2b7c9,    0x2e4a2,    0x31411,    0x3463b,
-          0x37b44,    0x3b353,    0x3ee94,    0x42d30,
-          0x46f55,    0x4b533,    0x4fefc,    0x54ce5,
-          0x59f25,    0x5f5f6,    0x65193,    0x6b23c,
-          0x71835,    0x783c3,    0x7f52c,    0x86cc0,
-          0x8eacc,    0x96fa5,    0x9fba0,    0xa8f1a,
-          0xb2a71,    0xbce0a,    0xc7a4a,    0xd2fa0,
-          0xdee7b,    0xeb752,    0xf8a9f,   0x1068e4,
-         0x1152a3,   0x12486a,   0x134ac8,   0x145a55,
-         0x1577ac,   0x16a370,   0x17df51,   0x192bc2,
-         0x1a88f8,   0x1bf7b7,   0x1d78c9,   0x1f0d04,
-         0x20b542,   0x227268,   0x244564,   0x262f26,
-         0x2830af
-};
-
-static uint tas3001c_treble_tab[]={
-             0x96,       0x95,       0x95,       0x94,
-             0x93,       0x92,       0x92,       0x91,
-             0x90,       0x90,       0x8f,       0x8e,
-             0x8d,       0x8d,       0x8c,       0x8b,
-             0x8a,       0x8a,       0x89,       0x88,
-             0x88,       0x87,       0x86,       0x85,
-             0x85,       0x84,       0x83,       0x83,
-             0x82,       0x81,       0x80,       0x80,
-             0x7f,       0x7e,       0x7e,       0x7d,
-             0x7c,       0x7b,       0x7b,       0x7a,
-             0x79,       0x78,       0x78,       0x77,
-             0x76,       0x76,       0x75,       0x74,
-             0x73,       0x73,       0x72,       0x71,
-             0x71,       0x70,       0x6e,       0x6d,
-             0x6d,       0x6c,       0x6b,       0x6a,
-             0x69,       0x68,       0x67,       0x66,
-             0x65,       0x63,       0x62,       0x62,
-             0x60,       0x5f,       0x5d,       0x5c,
-             0x5a,       0x58,       0x56,       0x55,
-             0x53,       0x51,       0x4f,       0x4c,
-             0x4a,       0x48,       0x45,       0x43,
-             0x40,       0x3d,       0x3a,       0x37,
-             0x35,       0x32,       0x2e,       0x2a,
-             0x27,       0x22,       0x1e,       0x1a,
-             0x15,       0x11,        0xc,        0x7,
-              0x1
-};
-
-static uint tas3001c_bass_tab[]={
-             0x86,       0x83,       0x81,       0x7f,
-             0x7d,       0x7b,       0x79,       0x78,
-             0x76,       0x75,       0x74,       0x72,
-             0x71,       0x6f,       0x6e,       0x6d,
-             0x6c,       0x6b,       0x69,       0x67,
-             0x65,       0x64,       0x61,       0x60,
-             0x5e,       0x5d,       0x5c,       0x5b,
-             0x5a,       0x59,       0x58,       0x57,
-             0x56,       0x55,       0x55,       0x54,
-             0x53,       0x52,       0x50,       0x4f,
-             0x4d,       0x4c,       0x4b,       0x49,
-             0x47,       0x45,       0x44,       0x42,
-             0x41,       0x3f,       0x3e,       0x3d,
-             0x3c,       0x3b,       0x39,       0x38,
-             0x37,       0x36,       0x35,       0x34,
-             0x33,       0x31,       0x30,       0x2f,
-             0x2e,       0x2c,       0x2b,       0x2b,
-             0x29,       0x28,       0x27,       0x26,
-             0x25,       0x24,       0x22,       0x21,
-             0x20,       0x1e,       0x1c,       0x19,
-             0x18,       0x18,       0x17,       0x16,
-             0x15,       0x14,       0x13,       0x12,
-             0x11,       0x10,        0xf,        0xe,
-              0xd,        0xb,        0xa,        0x9,
-              0x8,        0x6,        0x4,        0x2,
-              0x1
-};
-
-struct tas_gain_t tas3001c_gain = {
-  .master  = tas3001c_master_tab,
-  .treble  = tas3001c_treble_tab,
-  .bass    = tas3001c_bass_tab,
-  .mixer   = tas3001c_mixer_tab
-};
-
-struct tas_eq_pref_t *tas3001c_eq_prefs[]={
-  &eqp_0e_2_1,
-  &eqp_10_1_0,
-  &eqp_15_2_1,
-  &eqp_15_1_0,
-  &eqp_0f_2_1,
-  &eqp_0f_1_0,
-  NULL
-};
diff --git a/sound/oss/dmasound/tas3004.c b/sound/oss/dmasound/tas3004.c
deleted file mode 100644 (file)
index 678bf0f..0000000
+++ /dev/null
@@ -1,1138 +0,0 @@
-/*
- * Driver for the i2c/i2s based TA3004 sound chip used
- * on some Apple hardware. Also known as "snapper".
- *
- * Tobias Sargeant <tobias.sargeant@bigpond.com>
- * Based upon tas3001c.c by Christopher C. Chimelis <chris@debian.org>:
- *
- * Input support by Renzo Davoli <renzo@cs.unibo.it>
- *
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/proc_fs.h>
-#include <linux/ioport.h>
-#include <linux/sysctl.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/soundcard.h>
-#include <linux/interrupt.h>
-#include <linux/workqueue.h>
-
-#include <asm/uaccess.h>
-#include <asm/errno.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-
-#include "dmasound.h"
-#include "tas_common.h"
-#include "tas3004.h"
-
-#include "tas_ioctl.h"
-
-/* #define DEBUG_DRCE */
-
-#define TAS3004_BIQUAD_FILTER_COUNT  7
-#define TAS3004_BIQUAD_CHANNEL_COUNT 2
-
-#define VOL_DEFAULT    (100 * 4 / 5)
-#define INPUT_DEFAULT  (100 * 4 / 5)
-#define BASS_DEFAULT   (100 / 2)
-#define TREBLE_DEFAULT (100 / 2)
-
-struct tas3004_data_t {
-       struct tas_data_t super;
-       int device_id;
-       int output_id;
-       int speaker_id;
-       struct tas_drce_t drce_state;
-       struct work_struct change;
-};
-
-#define MAKE_TIME(sec,usec) (((sec)<<12) + (50000+(usec/10)*(1<<12))/100000)
-
-#define MAKE_RATIO(i,f) (((i)<<8) + ((500+(f)*(1<<8))/1000))
-
-
-static const union tas_biquad_t tas3004_eq_unity = {
-       .buf             = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 },
-};
-
-
-static const struct tas_drce_t tas3004_drce_min = {
-       .enable         = 1,
-       .above          = { .val = MAKE_RATIO(16,0), .expand = 0 },
-       .below          = { .val = MAKE_RATIO(2,0), .expand = 0 },
-       .threshold      = -0x59a0,
-       .energy         = MAKE_TIME(0,  1700),
-       .attack         = MAKE_TIME(0,  1700),
-       .decay          = MAKE_TIME(0,  1700),
-};
-
-
-static const struct tas_drce_t tas3004_drce_max = {
-       .enable         = 1,
-       .above          = { .val = MAKE_RATIO(1,500), .expand = 1 },
-       .below          = { .val = MAKE_RATIO(2,0), .expand = 1 },
-       .threshold      = -0x0,
-       .energy         = MAKE_TIME(2,400000),
-       .attack         = MAKE_TIME(2,400000),
-       .decay          = MAKE_TIME(2,400000),
-};
-
-
-static const unsigned short time_constants[]={
-       MAKE_TIME(0,  1700),
-       MAKE_TIME(0,  3500),
-       MAKE_TIME(0,  6700),
-       MAKE_TIME(0, 13000),
-       MAKE_TIME(0, 26000),
-       MAKE_TIME(0, 53000),
-       MAKE_TIME(0,106000),
-       MAKE_TIME(0,212000),
-       MAKE_TIME(0,425000),
-       MAKE_TIME(0,850000),
-       MAKE_TIME(1,700000),
-       MAKE_TIME(2,400000),
-};
-
-static const unsigned short above_threshold_compression_ratio[]={
-       MAKE_RATIO( 1, 70),
-       MAKE_RATIO( 1,140),
-       MAKE_RATIO( 1,230),
-       MAKE_RATIO( 1,330),
-       MAKE_RATIO( 1,450),
-       MAKE_RATIO( 1,600),
-       MAKE_RATIO( 1,780),
-       MAKE_RATIO( 2,  0),
-       MAKE_RATIO( 2,290),
-       MAKE_RATIO( 2,670),
-       MAKE_RATIO( 3,200),
-       MAKE_RATIO( 4,  0),
-       MAKE_RATIO( 5,330),
-       MAKE_RATIO( 8,  0),
-       MAKE_RATIO(16,  0),
-};
-
-static const unsigned short above_threshold_expansion_ratio[]={
-       MAKE_RATIO(1, 60),
-       MAKE_RATIO(1,130),
-       MAKE_RATIO(1,190),
-       MAKE_RATIO(1,250),
-       MAKE_RATIO(1,310),
-       MAKE_RATIO(1,380),
-       MAKE_RATIO(1,440),
-       MAKE_RATIO(1,500)
-};
-
-static const unsigned short below_threshold_compression_ratio[]={
-       MAKE_RATIO(1, 70),
-       MAKE_RATIO(1,140),
-       MAKE_RATIO(1,230),
-       MAKE_RATIO(1,330),
-       MAKE_RATIO(1,450),
-       MAKE_RATIO(1,600),
-       MAKE_RATIO(1,780),
-       MAKE_RATIO(2,  0)
-};
-
-static const unsigned short below_threshold_expansion_ratio[]={
-       MAKE_RATIO(1, 60),
-       MAKE_RATIO(1,130),
-       MAKE_RATIO(1,190),
-       MAKE_RATIO(1,250),
-       MAKE_RATIO(1,310),
-       MAKE_RATIO(1,380),
-       MAKE_RATIO(1,440),
-       MAKE_RATIO(1,500),
-       MAKE_RATIO(1,560),
-       MAKE_RATIO(1,630),
-       MAKE_RATIO(1,690),
-       MAKE_RATIO(1,750),
-       MAKE_RATIO(1,810),
-       MAKE_RATIO(1,880),
-       MAKE_RATIO(1,940),
-       MAKE_RATIO(2,  0)
-};
-
-static inline int
-search(        unsigned short val,
-       const unsigned short *arr,
-       const int arrsize) {
-       /*
-        * This could be a binary search, but for small tables,
-        * a linear search is likely to be faster
-        */
-
-       int i;
-
-       for (i=0; i < arrsize; i++)
-               if (arr[i] >= val)
-                       goto _1;
-       return arrsize-1;
- _1:
-       if (i == 0)
-               return 0;
-       return (arr[i]-val < val-arr[i-1]) ? i : i-1;
-}
-
-#define SEARCH(a, b) search(a, b, ARRAY_SIZE(b))
-
-static inline int
-time_index(unsigned short time)
-{
-       return SEARCH(time, time_constants);
-}
-
-
-static inline int
-above_threshold_compression_index(unsigned short ratio)
-{
-       return SEARCH(ratio, above_threshold_compression_ratio);
-}
-
-
-static inline int
-above_threshold_expansion_index(unsigned short ratio)
-{
-       return SEARCH(ratio, above_threshold_expansion_ratio);
-}
-
-
-static inline int
-below_threshold_compression_index(unsigned short ratio)
-{
-       return SEARCH(ratio, below_threshold_compression_ratio);
-}
-
-
-static inline int
-below_threshold_expansion_index(unsigned short ratio)
-{
-       return SEARCH(ratio, below_threshold_expansion_ratio);
-}
-
-static inline unsigned char db_to_regval(short db) {
-       int r=0;
-
-       r=(db+0x59a0) / 0x60;
-
-       if (r < 0x91) return 0x91;
-       if (r > 0xef) return 0xef;
-       return r;
-}
-
-static inline short quantize_db(short db)
-{
-       return db_to_regval(db) * 0x60 - 0x59a0;
-}
-
-static inline int
-register_width(enum tas3004_reg_t r)
-{
-       switch(r) {
-       case TAS3004_REG_MCR:
-       case TAS3004_REG_TREBLE:
-       case TAS3004_REG_BASS:
-       case TAS3004_REG_ANALOG_CTRL:
-       case TAS3004_REG_TEST1:
-       case TAS3004_REG_TEST2:
-       case TAS3004_REG_MCR2:
-               return 1;
-
-       case TAS3004_REG_LEFT_LOUD_BIQUAD_GAIN:
-       case TAS3004_REG_RIGHT_LOUD_BIQUAD_GAIN:
-               return 3;
-
-       case TAS3004_REG_DRC:
-       case TAS3004_REG_VOLUME:
-               return 6;
-
-       case TAS3004_REG_LEFT_MIXER:
-       case TAS3004_REG_RIGHT_MIXER:
-               return 9;
-
-       case TAS3004_REG_TEST:
-               return 10;
-
-       case TAS3004_REG_LEFT_BIQUAD0:
-       case TAS3004_REG_LEFT_BIQUAD1:
-       case TAS3004_REG_LEFT_BIQUAD2:
-       case TAS3004_REG_LEFT_BIQUAD3:
-       case TAS3004_REG_LEFT_BIQUAD4:
-       case TAS3004_REG_LEFT_BIQUAD5:
-       case TAS3004_REG_LEFT_BIQUAD6:
-
-       case TAS3004_REG_RIGHT_BIQUAD0:
-       case TAS3004_REG_RIGHT_BIQUAD1:
-       case TAS3004_REG_RIGHT_BIQUAD2:
-       case TAS3004_REG_RIGHT_BIQUAD3:
-       case TAS3004_REG_RIGHT_BIQUAD4:
-       case TAS3004_REG_RIGHT_BIQUAD5:
-       case TAS3004_REG_RIGHT_BIQUAD6:
-
-       case TAS3004_REG_LEFT_LOUD_BIQUAD:
-       case TAS3004_REG_RIGHT_LOUD_BIQUAD:
-               return 15;
-
-       default:
-               return 0;
-       }
-}
-
-static int
-tas3004_write_register(        struct tas3004_data_t *self,
-                       enum tas3004_reg_t reg_num,
-                       char *data,
-                       uint write_mode)
-{
-       if (reg_num==TAS3004_REG_MCR ||
-           reg_num==TAS3004_REG_BASS ||
-           reg_num==TAS3004_REG_TREBLE ||
-           reg_num==TAS3004_REG_ANALOG_CTRL) {
-               return tas_write_byte_register(&self->super,
-                                              (uint)reg_num,
-                                              *data,
-                                              write_mode);
-       } else {
-               return tas_write_register(&self->super,
-                                         (uint)reg_num,
-                                         register_width(reg_num),
-                                         data,
-                                         write_mode);
-       }
-}
-
-static int
-tas3004_sync_register( struct tas3004_data_t *self,
-                       enum tas3004_reg_t reg_num)
-{
-       if (reg_num==TAS3004_REG_MCR ||
-           reg_num==TAS3004_REG_BASS ||
-           reg_num==TAS3004_REG_TREBLE ||
-           reg_num==TAS3004_REG_ANALOG_CTRL) {
-               return tas_sync_byte_register(&self->super,
-                                             (uint)reg_num,
-                                             register_width(reg_num));
-       } else {
-               return tas_sync_register(&self->super,
-                                        (uint)reg_num,
-                                        register_width(reg_num));
-       }
-}
-
-static int
-tas3004_read_register( struct tas3004_data_t *self,
-                       enum tas3004_reg_t reg_num,
-                       char *data,
-                       uint write_mode)
-{
-       return tas_read_register(&self->super,
-                                (uint)reg_num,
-                                register_width(reg_num),
-                                data);
-}
-
-static inline int
-tas3004_fast_load(struct tas3004_data_t *self, int fast)
-{
-       if (fast)
-               self->super.shadow[TAS3004_REG_MCR][0] |= 0x80;
-       else
-               self->super.shadow[TAS3004_REG_MCR][0] &= 0x7f;
-       return tas3004_sync_register(self,TAS3004_REG_MCR);
-}
-
-static uint
-tas3004_supported_mixers(struct tas3004_data_t *self)
-{
-       return SOUND_MASK_VOLUME |
-               SOUND_MASK_PCM |
-               SOUND_MASK_ALTPCM |
-               SOUND_MASK_IMIX |
-               SOUND_MASK_TREBLE |
-               SOUND_MASK_BASS |
-               SOUND_MASK_MIC |
-               SOUND_MASK_LINE;
-}
-
-static int
-tas3004_mixer_is_stereo(struct tas3004_data_t *self, int mixer)
-{
-       switch(mixer) {
-       case SOUND_MIXER_VOLUME:
-       case SOUND_MIXER_PCM:
-       case SOUND_MIXER_ALTPCM:
-       case SOUND_MIXER_IMIX:
-               return 1;
-       default:
-               return 0;
-       }
-}
-
-static uint
-tas3004_stereo_mixers(struct tas3004_data_t *self)
-{
-       uint r = tas3004_supported_mixers(self);
-       uint i;
-       
-       for (i=1; i<SOUND_MIXER_NRDEVICES; i++)
-               if (r&(1<<i) && !tas3004_mixer_is_stereo(self,i))
-                       r &= ~(1<<i);
-       return r;
-}
-
-static int
-tas3004_get_mixer_level(struct tas3004_data_t *self, int mixer, uint *level)
-{
-       if (!self)
-               return -1;
-
-       *level = self->super.mixer[mixer];
-
-       return 0;
-}
-
-static int
-tas3004_set_mixer_level(struct tas3004_data_t *self, int mixer, uint level)
-{
-       int rc;
-       tas_shadow_t *shadow;
-       uint temp;
-       uint offset=0;
-
-       if (!self)
-               return -1;
-
-       shadow = self->super.shadow;
-
-       if (!tas3004_mixer_is_stereo(self,mixer))
-               level = tas_mono_to_stereo(level);
-       switch(mixer) {
-       case SOUND_MIXER_VOLUME:
-               temp = tas3004_gain.master[level&0xff];
-               SET_4_20(shadow[TAS3004_REG_VOLUME], 0, temp);
-               temp = tas3004_gain.master[(level>>8)&0xff];
-               SET_4_20(shadow[TAS3004_REG_VOLUME], 3, temp);
-               rc = tas3004_sync_register(self,TAS3004_REG_VOLUME);
-               break;
-       case SOUND_MIXER_IMIX:
-               offset += 3;
-       case SOUND_MIXER_ALTPCM:
-               offset += 3;
-       case SOUND_MIXER_PCM:
-               /*
-                * Don't load these in fast mode. The documentation
-                * says it can be done in either mode, but testing it
-                * shows that fast mode produces ugly clicking.
-               */
-               /* tas3004_fast_load(self,1); */
-               temp = tas3004_gain.mixer[level&0xff];
-               SET_4_20(shadow[TAS3004_REG_LEFT_MIXER], offset, temp);
-               temp = tas3004_gain.mixer[(level>>8)&0xff];
-               SET_4_20(shadow[TAS3004_REG_RIGHT_MIXER], offset, temp);
-               rc = tas3004_sync_register(self,TAS3004_REG_LEFT_MIXER);
-               if (rc == 0)
-                       rc=tas3004_sync_register(self,TAS3004_REG_RIGHT_MIXER);
-               /* tas3004_fast_load(self,0); */
-               break;
-       case SOUND_MIXER_TREBLE:
-               temp = tas3004_gain.treble[level&0xff];
-               shadow[TAS3004_REG_TREBLE][0]=temp&0xff;
-               rc = tas3004_sync_register(self,TAS3004_REG_TREBLE);
-               break;
-       case SOUND_MIXER_BASS:
-               temp = tas3004_gain.bass[level&0xff];
-               shadow[TAS3004_REG_BASS][0]=temp&0xff;
-               rc = tas3004_sync_register(self,TAS3004_REG_BASS);
-               break;
-       case SOUND_MIXER_MIC:
-               if ((level&0xff)>0) {
-                       software_input_volume = SW_INPUT_VOLUME_SCALE * (level&0xff);
-                       if (self->super.mixer[mixer] == 0) {
-                               self->super.mixer[SOUND_MIXER_LINE] = 0;
-                               shadow[TAS3004_REG_ANALOG_CTRL][0]=0xc2;
-                               rc = tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL);
-                       } else rc=0;
-               } else {
-                       self->super.mixer[SOUND_MIXER_LINE] = SW_INPUT_VOLUME_DEFAULT;
-                       software_input_volume = SW_INPUT_VOLUME_SCALE *
-                               (self->super.mixer[SOUND_MIXER_LINE]&0xff);
-                       shadow[TAS3004_REG_ANALOG_CTRL][0]=0x00;
-                       rc = tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL);
-               }
-               break;
-       case SOUND_MIXER_LINE:
-               if (self->super.mixer[SOUND_MIXER_MIC] == 0) {
-                       software_input_volume = SW_INPUT_VOLUME_SCALE * (level&0xff);
-                       rc=0;
-               }
-               break;
-       default:
-               rc = -1;
-               break;
-       }
-       if (rc < 0)
-               return rc;
-       self->super.mixer[mixer] = level;
-       
-       return 0;
-}
-
-static int
-tas3004_leave_sleep(struct tas3004_data_t *self)
-{
-       unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
-
-       if (!self)
-               return -1;
-
-       /* Make sure something answers on the i2c bus */
-       if (tas3004_write_register(self, TAS3004_REG_MCR, &mcr,
-           WRITE_NORMAL | FORCE_WRITE) < 0)
-               return -1;
-
-       tas3004_fast_load(self, 1);
-
-       (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD0);
-       (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD1);
-       (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD2);
-       (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD3);
-       (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD4);
-       (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD5);
-       (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD6);
-
-       (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD0);
-       (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD1);
-       (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD2);
-       (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD3);
-       (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD4);
-       (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD5);
-       (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD6);
-
-       tas3004_fast_load(self, 0);
-
-       (void)tas3004_sync_register(self,TAS3004_REG_VOLUME);
-       (void)tas3004_sync_register(self,TAS3004_REG_LEFT_MIXER);
-       (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_MIXER);
-       (void)tas3004_sync_register(self,TAS3004_REG_TREBLE);
-       (void)tas3004_sync_register(self,TAS3004_REG_BASS);
-       (void)tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL);
-
-       return 0;
-}
-
-static int
-tas3004_enter_sleep(struct tas3004_data_t *self)
-{
-       if (!self)
-               return -1; 
-       return 0;
-}
-
-static int
-tas3004_sync_biquad(   struct tas3004_data_t *self,
-                       u_int channel,
-                       u_int filter)
-{
-       enum tas3004_reg_t reg;
-
-       if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT ||
-           filter  >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL;
-
-       reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter;
-
-       return tas3004_sync_register(self,reg);
-}
-
-static int
-tas3004_write_biquad_shadow(   struct tas3004_data_t *self,
-                               u_int channel,
-                               u_int filter,
-                               const union tas_biquad_t *biquad)
-{
-       tas_shadow_t *shadow=self->super.shadow;
-       enum tas3004_reg_t reg;
-
-       if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT ||
-           filter  >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL;
-
-       reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter;
-
-       SET_4_20(shadow[reg], 0,biquad->coeff.b0);
-       SET_4_20(shadow[reg], 3,biquad->coeff.b1);
-       SET_4_20(shadow[reg], 6,biquad->coeff.b2);
-       SET_4_20(shadow[reg], 9,biquad->coeff.a1);
-       SET_4_20(shadow[reg],12,biquad->coeff.a2);
-
-       return 0;
-}
-
-static int
-tas3004_write_biquad(  struct tas3004_data_t *self,
-                       u_int channel,
-                       u_int filter,
-                       const union tas_biquad_t *biquad)
-{
-       int rc;
-
-       rc=tas3004_write_biquad_shadow(self, channel, filter, biquad);
-       if (rc < 0) return rc;
-
-       return tas3004_sync_biquad(self, channel, filter);
-}
-
-static int
-tas3004_write_biquad_list(     struct tas3004_data_t *self,
-                               u_int filter_count,
-                               u_int flags,
-                               struct tas_biquad_ctrl_t *biquads)
-{
-       int i;
-       int rc;
-
-       if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,1);
-
-       for (i=0; i<filter_count; i++) {
-               rc=tas3004_write_biquad(self,
-                                       biquads[i].channel,
-                                       biquads[i].filter,
-                                       &biquads[i].data);
-               if (rc < 0) break;
-       }
-
-       if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,0);
-
-       return rc;
-}
-
-static int
-tas3004_read_biquad(   struct tas3004_data_t *self,
-                       u_int channel,
-                       u_int filter,
-                       union tas_biquad_t *biquad)
-{
-       tas_shadow_t *shadow=self->super.shadow;
-       enum tas3004_reg_t reg;
-
-       if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT ||
-           filter  >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL;
-
-       reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter;
-
-       biquad->coeff.b0=GET_4_20(shadow[reg], 0);
-       biquad->coeff.b1=GET_4_20(shadow[reg], 3);
-       biquad->coeff.b2=GET_4_20(shadow[reg], 6);
-       biquad->coeff.a1=GET_4_20(shadow[reg], 9);
-       biquad->coeff.a2=GET_4_20(shadow[reg],12);
-       
-       return 0;       
-}
-
-static int
-tas3004_eq_rw( struct tas3004_data_t *self,
-               u_int cmd,
-               u_long arg)
-{
-       void __user *argp = (void __user *)arg;
-       int rc;
-       struct tas_biquad_ctrl_t biquad;
-
-       if (copy_from_user((void *)&biquad, argp, sizeof(struct tas_biquad_ctrl_t))) {
-               return -EFAULT;
-       }
-
-       if (cmd & SIOC_IN) {
-               rc=tas3004_write_biquad(self, biquad.channel, biquad.filter, &biquad.data);
-               if (rc != 0) return rc;
-       }
-
-       if (cmd & SIOC_OUT) {
-               rc=tas3004_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
-               if (rc != 0) return rc;
-
-               if (copy_to_user(argp, &biquad, sizeof(struct tas_biquad_ctrl_t))) {
-                       return -EFAULT;
-               }
-
-       }
-       return 0;
-}
-
-static int
-tas3004_eq_list_rw(    struct tas3004_data_t *self,
-                       u_int cmd,
-                       u_long arg)
-{
-       int rc = 0;
-       int filter_count;
-       int flags;
-       int i,j;
-       char sync_required[TAS3004_BIQUAD_CHANNEL_COUNT][TAS3004_BIQUAD_FILTER_COUNT];
-       struct tas_biquad_ctrl_t biquad;
-       struct tas_biquad_ctrl_list_t __user *argp = (void __user *)arg;
-
-       memset(sync_required,0,sizeof(sync_required));
-
-       if (copy_from_user(&filter_count, &argp->filter_count, sizeof(int)))
-               return -EFAULT;
-
-       if (copy_from_user(&flags, &argp->flags, sizeof(int)))
-               return -EFAULT;
-
-       if (cmd & SIOC_IN) {
-       }
-
-       for (i=0; i < filter_count; i++) {
-               if (copy_from_user(&biquad, &argp->biquads[i],
-                                  sizeof(struct tas_biquad_ctrl_t))) {
-                       return -EFAULT;
-               }
-
-               if (cmd & SIOC_IN) {
-                       sync_required[biquad.channel][biquad.filter]=1;
-                       rc=tas3004_write_biquad_shadow(self, biquad.channel, biquad.filter, &biquad.data);
-                       if (rc != 0) return rc;
-               }
-
-               if (cmd & SIOC_OUT) {
-                       rc=tas3004_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
-                       if (rc != 0) return rc;
-
-                       if (copy_to_user(&argp->biquads[i], &biquad,
-                                        sizeof(struct tas_biquad_ctrl_t))) {
-                               return -EFAULT;
-                       }
-               }
-       }
-
-       if (cmd & SIOC_IN) {
-               /*
-                * This is OK for the tas3004. For the
-                * tas3001c, going into fast load mode causes
-                * the treble and bass to be reset to 0dB, and
-                * volume controls to be muted.
-                */
-               if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,1);
-               for (i=0; i<TAS3004_BIQUAD_CHANNEL_COUNT; i++) {
-                       for (j=0; j<TAS3004_BIQUAD_FILTER_COUNT; j++) {
-                               if (sync_required[i][j]) {
-                                       rc=tas3004_sync_biquad(self, i, j);
-                                       if (rc < 0) goto out;
-                               }
-                       }
-               }
-       out:
-               if (flags & TAS_BIQUAD_FAST_LOAD)
-                       tas3004_fast_load(self,0);
-       }
-
-       return rc;
-}
-
-static int
-tas3004_update_drce(   struct tas3004_data_t *self,
-                       int flags,
-                       struct tas_drce_t *drce)
-{
-       tas_shadow_t *shadow;
-       int i;
-       shadow=self->super.shadow;
-
-       if (flags & TAS_DRCE_ABOVE_RATIO) {
-               self->drce_state.above.expand = drce->above.expand;
-               if (drce->above.val == (1<<8)) {
-                       self->drce_state.above.val = 1<<8;
-                       shadow[TAS3004_REG_DRC][0] = 0x02;
-                                       
-               } else if (drce->above.expand) {
-                       i=above_threshold_expansion_index(drce->above.val);
-                       self->drce_state.above.val=above_threshold_expansion_ratio[i];
-                       shadow[TAS3004_REG_DRC][0] = 0x0a + (i<<3);
-               } else {
-                       i=above_threshold_compression_index(drce->above.val);
-                       self->drce_state.above.val=above_threshold_compression_ratio[i];
-                       shadow[TAS3004_REG_DRC][0] = 0x08 + (i<<3);
-               }
-       }
-
-       if (flags & TAS_DRCE_BELOW_RATIO) {
-               self->drce_state.below.expand = drce->below.expand;
-               if (drce->below.val == (1<<8)) {
-                       self->drce_state.below.val = 1<<8;
-                       shadow[TAS3004_REG_DRC][1] = 0x02;
-                                       
-               } else if (drce->below.expand) {
-                       i=below_threshold_expansion_index(drce->below.val);
-                       self->drce_state.below.val=below_threshold_expansion_ratio[i];
-                       shadow[TAS3004_REG_DRC][1] = 0x08 + (i<<3);
-               } else {
-                       i=below_threshold_compression_index(drce->below.val);
-                       self->drce_state.below.val=below_threshold_compression_ratio[i];
-                       shadow[TAS3004_REG_DRC][1] = 0x0a + (i<<3);
-               }
-       }
-
-       if (flags & TAS_DRCE_THRESHOLD) {
-               self->drce_state.threshold=quantize_db(drce->threshold);
-               shadow[TAS3004_REG_DRC][2] = db_to_regval(self->drce_state.threshold);
-       }
-
-       if (flags & TAS_DRCE_ENERGY) {
-               i=time_index(drce->energy);
-               self->drce_state.energy=time_constants[i];
-               shadow[TAS3004_REG_DRC][3] = 0x40 + (i<<4);
-       }
-
-       if (flags & TAS_DRCE_ATTACK) {
-               i=time_index(drce->attack);
-               self->drce_state.attack=time_constants[i];
-               shadow[TAS3004_REG_DRC][4] = 0x40 + (i<<4);
-       }
-
-       if (flags & TAS_DRCE_DECAY) {
-               i=time_index(drce->decay);
-               self->drce_state.decay=time_constants[i];
-               shadow[TAS3004_REG_DRC][5] = 0x40 + (i<<4);
-       }
-
-       if (flags & TAS_DRCE_ENABLE) {
-               self->drce_state.enable = drce->enable;
-       }
-
-       if (!self->drce_state.enable) {
-               shadow[TAS3004_REG_DRC][0] |= 0x01;
-       }
-
-#ifdef DEBUG_DRCE
-       printk("DRCE: set [ ENABLE:%x ABOVE:%x/%x BELOW:%x/%x THRESH:%x ENERGY:%x ATTACK:%x DECAY:%x\n",
-              self->drce_state.enable,
-              self->drce_state.above.expand,self->drce_state.above.val,
-              self->drce_state.below.expand,self->drce_state.below.val,
-              self->drce_state.threshold,
-              self->drce_state.energy,
-              self->drce_state.attack,
-              self->drce_state.decay);
-
-       printk("DRCE: reg [ %02x %02x %02x %02x %02x %02x ]\n",
-              (unsigned char)shadow[TAS3004_REG_DRC][0],
-              (unsigned char)shadow[TAS3004_REG_DRC][1],
-              (unsigned char)shadow[TAS3004_REG_DRC][2],
-              (unsigned char)shadow[TAS3004_REG_DRC][3],
-              (unsigned char)shadow[TAS3004_REG_DRC][4],
-              (unsigned char)shadow[TAS3004_REG_DRC][5]);
-#endif
-
-       return tas3004_sync_register(self, TAS3004_REG_DRC);
-}
-
-static int
-tas3004_drce_rw(       struct tas3004_data_t *self,
-                       u_int cmd,
-                       u_long arg)
-{
-       int rc;
-       struct tas_drce_ctrl_t drce_ctrl;
-       void __user *argp = (void __user *)arg;
-
-       if (copy_from_user(&drce_ctrl, argp, sizeof(struct tas_drce_ctrl_t)))
-               return -EFAULT;
-
-#ifdef DEBUG_DRCE
-       printk("DRCE: input [ FLAGS:%x ENABLE:%x ABOVE:%x/%x BELOW:%x/%x THRESH:%x ENERGY:%x ATTACK:%x DECAY:%x\n",
-              drce_ctrl.flags,
-              drce_ctrl.data.enable,
-              drce_ctrl.data.above.expand,drce_ctrl.data.above.val,
-              drce_ctrl.data.below.expand,drce_ctrl.data.below.val,
-              drce_ctrl.data.threshold,
-              drce_ctrl.data.energy,
-              drce_ctrl.data.attack,
-              drce_ctrl.data.decay);
-#endif
-
-       if (cmd & SIOC_IN) {
-               rc = tas3004_update_drce(self, drce_ctrl.flags, &drce_ctrl.data);
-               if (rc < 0) return rc;
-       }
-
-       if (cmd & SIOC_OUT) {
-               if (drce_ctrl.flags & TAS_DRCE_ENABLE)
-                       drce_ctrl.data.enable = self->drce_state.enable;
-               if (drce_ctrl.flags & TAS_DRCE_ABOVE_RATIO)
-                       drce_ctrl.data.above = self->drce_state.above;
-               if (drce_ctrl.flags & TAS_DRCE_BELOW_RATIO)
-                       drce_ctrl.data.below = self->drce_state.below;
-               if (drce_ctrl.flags & TAS_DRCE_THRESHOLD)
-                       drce_ctrl.data.threshold = self->drce_state.threshold;
-               if (drce_ctrl.flags & TAS_DRCE_ENERGY)
-                       drce_ctrl.data.energy = self->drce_state.energy;
-               if (drce_ctrl.flags & TAS_DRCE_ATTACK)
-                       drce_ctrl.data.attack = self->drce_state.attack;
-               if (drce_ctrl.flags & TAS_DRCE_DECAY)
-                       drce_ctrl.data.decay = self->drce_state.decay;
-
-               if (copy_to_user(argp, &drce_ctrl,
-                                sizeof(struct tas_drce_ctrl_t))) {
-                       return -EFAULT;
-               }
-       }
-
-       return 0;
-}
-
-static void
-tas3004_update_device_parameters(struct tas3004_data_t *self)
-{
-       char data;
-       int i;
-
-       if (!self) return;
-
-       if (self->output_id == TAS_OUTPUT_HEADPHONES) {
-               /* turn on allPass when headphones are plugged in */
-               data = 0x02;
-       } else {
-               data = 0x00;
-       }
-
-       tas3004_write_register(self, TAS3004_REG_MCR2, &data, WRITE_NORMAL | FORCE_WRITE);
-
-       for (i=0; tas3004_eq_prefs[i]; i++) {
-               struct tas_eq_pref_t *eq = tas3004_eq_prefs[i];
-
-               if (eq->device_id == self->device_id &&
-                   (eq->output_id == 0 || eq->output_id == self->output_id) &&
-                   (eq->speaker_id == 0 || eq->speaker_id == self->speaker_id)) {
-
-                       tas3004_update_drce(self, TAS_DRCE_ALL, eq->drce);
-                       tas3004_write_biquad_list(self, eq->filter_count, TAS_BIQUAD_FAST_LOAD, eq->biquads);
-
-                       break;
-               }
-       }
-}
-
-static void
-tas3004_device_change_handler(struct work_struct *work)
-{
-       struct tas3004_data_t *self;
-       self = container_of(work, struct tas3004_data_t, change);
-       tas3004_update_device_parameters(self);
-}
-
-static int
-tas3004_output_device_change(  struct tas3004_data_t *self,
-                               int device_id,
-                               int output_id,
-                               int speaker_id)
-{
-       self->device_id=device_id;
-       self->output_id=output_id;
-       self->speaker_id=speaker_id;
-
-       schedule_work(&self->change);
-
-       return 0;
-}
-
-static int
-tas3004_device_ioctl(  struct tas3004_data_t *self,
-                       u_int cmd,
-                       u_long arg)
-{
-       uint __user *argp = (void __user *)arg;
-       switch (cmd) {
-       case TAS_READ_EQ:
-       case TAS_WRITE_EQ:
-               return tas3004_eq_rw(self, cmd, arg);
-
-       case TAS_READ_EQ_LIST:
-       case TAS_WRITE_EQ_LIST:
-               return tas3004_eq_list_rw(self, cmd, arg);
-
-       case TAS_READ_EQ_FILTER_COUNT:
-               put_user(TAS3004_BIQUAD_FILTER_COUNT, argp);
-               return 0;
-
-       case TAS_READ_EQ_CHANNEL_COUNT:
-               put_user(TAS3004_BIQUAD_CHANNEL_COUNT, argp);
-               return 0;
-
-       case TAS_READ_DRCE:
-       case TAS_WRITE_DRCE:
-               return tas3004_drce_rw(self, cmd, arg);
-
-       case TAS_READ_DRCE_CAPS:
-               put_user(TAS_DRCE_ENABLE         |
-                        TAS_DRCE_ABOVE_RATIO    |
-                        TAS_DRCE_BELOW_RATIO    |
-                        TAS_DRCE_THRESHOLD      |
-                        TAS_DRCE_ENERGY         |
-                        TAS_DRCE_ATTACK         |
-                        TAS_DRCE_DECAY,
-                        argp);
-               return 0;
-
-       case TAS_READ_DRCE_MIN:
-       case TAS_READ_DRCE_MAX: {
-               struct tas_drce_ctrl_t drce_ctrl;
-               const struct tas_drce_t *drce_copy;
-
-               if (copy_from_user(&drce_ctrl, argp,
-                                  sizeof(struct tas_drce_ctrl_t))) {
-                       return -EFAULT;
-               }
-
-               if (cmd == TAS_READ_DRCE_MIN) {
-                       drce_copy=&tas3004_drce_min;
-               } else {
-                       drce_copy=&tas3004_drce_max;
-               }
-
-               if (drce_ctrl.flags & TAS_DRCE_ABOVE_RATIO) {
-                       drce_ctrl.data.above=drce_copy->above;
-               }
-               if (drce_ctrl.flags & TAS_DRCE_BELOW_RATIO) {
-                       drce_ctrl.data.below=drce_copy->below;
-               }
-               if (drce_ctrl.flags & TAS_DRCE_THRESHOLD) {
-                       drce_ctrl.data.threshold=drce_copy->threshold;
-               }
-               if (drce_ctrl.flags & TAS_DRCE_ENERGY) {
-                       drce_ctrl.data.energy=drce_copy->energy;
-               }
-               if (drce_ctrl.flags & TAS_DRCE_ATTACK) {
-                       drce_ctrl.data.attack=drce_copy->attack;
-               }
-               if (drce_ctrl.flags & TAS_DRCE_DECAY) {
-                       drce_ctrl.data.decay=drce_copy->decay;
-               }
-
-               if (copy_to_user(argp, &drce_ctrl,
-                                sizeof(struct tas_drce_ctrl_t))) {
-                       return -EFAULT;
-               }
-       }
-       }
-
-       return -EINVAL;
-}
-
-static int
-tas3004_init_mixer(struct tas3004_data_t *self)
-{
-       unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
-
-       /* Make sure something answers on the i2c bus */
-       if (tas3004_write_register(self, TAS3004_REG_MCR, &mcr,
-           WRITE_NORMAL | FORCE_WRITE) < 0)
-               return -1;
-
-       tas3004_fast_load(self, 1);
-
-       (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD0);
-       (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD1);
-       (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD2);
-       (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD3);
-       (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD4);
-       (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD5);
-       (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD6);
-
-       (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD0);
-       (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD1);
-       (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD2);
-       (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD3);
-       (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD4);
-       (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD5);
-       (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD6);
-
-       tas3004_sync_register(self, TAS3004_REG_DRC);
-
-       tas3004_sync_register(self, TAS3004_REG_MCR2);
-
-       tas3004_fast_load(self, 0);
-
-       tas3004_set_mixer_level(self, SOUND_MIXER_VOLUME, VOL_DEFAULT<<8 | VOL_DEFAULT);
-       tas3004_set_mixer_level(self, SOUND_MIXER_PCM, INPUT_DEFAULT<<8 | INPUT_DEFAULT);
-       tas3004_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
-       tas3004_set_mixer_level(self, SOUND_MIXER_IMIX, 0);
-
-       tas3004_set_mixer_level(self, SOUND_MIXER_BASS, BASS_DEFAULT);
-       tas3004_set_mixer_level(self, SOUND_MIXER_TREBLE, TREBLE_DEFAULT);
-
-       tas3004_set_mixer_level(self, SOUND_MIXER_LINE,SW_INPUT_VOLUME_DEFAULT);
-
-       return 0;
-}
-
-static int
-tas3004_uninit_mixer(struct tas3004_data_t *self)
-{
-       tas3004_set_mixer_level(self, SOUND_MIXER_VOLUME, 0);
-       tas3004_set_mixer_level(self, SOUND_MIXER_PCM, 0);
-       tas3004_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
-       tas3004_set_mixer_level(self, SOUND_MIXER_IMIX, 0);
-
-       tas3004_set_mixer_level(self, SOUND_MIXER_BASS, 0);
-       tas3004_set_mixer_level(self, SOUND_MIXER_TREBLE, 0);
-
-       tas3004_set_mixer_level(self, SOUND_MIXER_LINE, 0);
-
-       return 0;
-}
-
-static int
-tas3004_init(struct i2c_client *client)
-{
-       struct tas3004_data_t *self;
-       size_t sz = sizeof(*self) + (TAS3004_REG_MAX*sizeof(tas_shadow_t));
-       char drce_init[] = { 0x69, 0x22, 0x9f, 0xb0, 0x60, 0xa0 };
-       char mcr2 = 0;
-       int i, j;
-
-       self = kzalloc(sz, GFP_KERNEL);
-       if (!self)
-               return -ENOMEM;
-
-       self->super.client = client;
-       self->super.shadow = (tas_shadow_t *)(self+1);
-       self->output_id = TAS_OUTPUT_HEADPHONES;
-
-       dev_set_drvdata(&client->dev, self);
-
-       for (i = 0; i < TAS3004_BIQUAD_CHANNEL_COUNT; i++)
-               for (j = 0; j<TAS3004_BIQUAD_FILTER_COUNT; j++)
-                       tas3004_write_biquad_shadow(self, i, j,
-                                       &tas3004_eq_unity);
-
-       tas3004_write_register(self, TAS3004_REG_MCR2, &mcr2, WRITE_SHADOW);
-       tas3004_write_register(self, TAS3004_REG_DRC, drce_init, WRITE_SHADOW);
-
-       INIT_WORK(&self->change, tas3004_device_change_handler);
-       return 0;
-}
-
-static void 
-tas3004_uninit(struct tas3004_data_t *self)
-{
-       tas3004_uninit_mixer(self);
-       kfree(self);
-}
-
-
-struct tas_driver_hooks_t tas3004_hooks = {
-       .init                   = (tas_hook_init_t)tas3004_init,
-       .post_init              = (tas_hook_post_init_t)tas3004_init_mixer,
-       .uninit                 = (tas_hook_uninit_t)tas3004_uninit,
-       .get_mixer_level        = (tas_hook_get_mixer_level_t)tas3004_get_mixer_level,
-       .set_mixer_level        = (tas_hook_set_mixer_level_t)tas3004_set_mixer_level,
-       .enter_sleep            = (tas_hook_enter_sleep_t)tas3004_enter_sleep,
-       .leave_sleep            = (tas_hook_leave_sleep_t)tas3004_leave_sleep,
-       .supported_mixers       = (tas_hook_supported_mixers_t)tas3004_supported_mixers,
-       .mixer_is_stereo        = (tas_hook_mixer_is_stereo_t)tas3004_mixer_is_stereo,
-       .stereo_mixers          = (tas_hook_stereo_mixers_t)tas3004_stereo_mixers,
-       .output_device_change   = (tas_hook_output_device_change_t)tas3004_output_device_change,
-       .device_ioctl           = (tas_hook_device_ioctl_t)tas3004_device_ioctl
-};
diff --git a/sound/oss/dmasound/tas3004.h b/sound/oss/dmasound/tas3004.h
deleted file mode 100644 (file)
index c6d584b..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Header file for the i2c/i2s based TA3004 sound chip used
- * on some Apple hardware. Also known as "tumbler".
- *
- *  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.
- *
- * Written by Christopher C. Chimelis <chris@debian.org>
- */
-
-#ifndef _TAS3004_H_
-#define _TAS3004_H_
-
-#include <linux/types.h>
-
-#include "tas_common.h"
-#include "tas_eq_prefs.h"
-
-/*
- * Macros that correspond to the registers that we write to
- * when setting the various values.
- */
-
-#define TAS3004_VERSION                "0.3"
-#define TAS3004_DATE           "20011214"
-
-#define I2C_DRIVERNAME_TAS3004 "TAS3004 driver V " TAS3004_VERSION
-#define I2C_DRIVERID_TAS3004    (I2C_DRIVERID_TAS_BASE+1)
-
-extern  struct tas_driver_hooks_t tas3004_hooks;
-extern struct tas_gain_t tas3004_gain;
-extern struct tas_eq_pref_t *tas3004_eq_prefs[];
-
-enum tas3004_reg_t {
-  TAS3004_REG_MCR                    = 0x01,
-  TAS3004_REG_DRC                    = 0x02,
-
-  TAS3004_REG_VOLUME                 = 0x04,
-  TAS3004_REG_TREBLE                 = 0x05,
-  TAS3004_REG_BASS                   = 0x06,
-  TAS3004_REG_LEFT_MIXER             = 0x07,
-  TAS3004_REG_RIGHT_MIXER            = 0x08,
-
-  TAS3004_REG_LEFT_BIQUAD0           = 0x0a,
-  TAS3004_REG_LEFT_BIQUAD1           = 0x0b,
-  TAS3004_REG_LEFT_BIQUAD2           = 0x0c,
-  TAS3004_REG_LEFT_BIQUAD3           = 0x0d,
-  TAS3004_REG_LEFT_BIQUAD4           = 0x0e,
-  TAS3004_REG_LEFT_BIQUAD5           = 0x0f,
-  TAS3004_REG_LEFT_BIQUAD6           = 0x10,
-  
-  TAS3004_REG_RIGHT_BIQUAD0          = 0x13,
-  TAS3004_REG_RIGHT_BIQUAD1          = 0x14,
-  TAS3004_REG_RIGHT_BIQUAD2          = 0x15,
-  TAS3004_REG_RIGHT_BIQUAD3          = 0x16,
-  TAS3004_REG_RIGHT_BIQUAD4          = 0x17,
-  TAS3004_REG_RIGHT_BIQUAD5          = 0x18,
-  TAS3004_REG_RIGHT_BIQUAD6          = 0x19,
-
-  TAS3004_REG_LEFT_LOUD_BIQUAD       = 0x21,
-  TAS3004_REG_RIGHT_LOUD_BIQUAD      = 0x22,
-
-  TAS3004_REG_LEFT_LOUD_BIQUAD_GAIN  = 0x23,
-  TAS3004_REG_RIGHT_LOUD_BIQUAD_GAIN = 0x24,
-
-  TAS3004_REG_TEST                   = 0x29,
-
-  TAS3004_REG_ANALOG_CTRL            = 0x40,
-  TAS3004_REG_TEST1                  = 0x41,
-  TAS3004_REG_TEST2                  = 0x42,
-  TAS3004_REG_MCR2                   = 0x43,
-
-  TAS3004_REG_MAX                    = 0x44
-};
-
-#endif /* _TAS3004_H_ */
diff --git a/sound/oss/dmasound/tas3004_tables.c b/sound/oss/dmasound/tas3004_tables.c
deleted file mode 100644 (file)
index b910e0a..0000000
+++ /dev/null
@@ -1,301 +0,0 @@
-#include "tas3004.h"
-#include "tas_eq_prefs.h"
-
-static struct tas_drce_t eqp_17_1_0_drce={
-    .enable     = 1,
-    .above      = { .val = 3.0 * (1<<8), .expand = 0 },
-    .below      = { .val = 1.0 * (1<<8), .expand = 0 },
-    .threshold  = -19.12  * (1<<8),
-    .energy     = 2.4     * (1<<12),
-    .attack     = 0.013   * (1<<12),
-    .decay      = 0.212   * (1<<12),
-};
-
-static struct tas_biquad_ctrl_t eqp_17_1_0_biquads[]={
-  { .channel = 0, .filter = 0, .data = { .coeff = { 0x0fd0d4, 0xe05e56, 0x0fd0d4, 0xe05ee1, 0x0fa234 } } },
-  { .channel = 0, .filter = 1, .data = { .coeff = { 0x0910d7, 0x088e1a, 0x030651, 0x01dcb1, 0x02c892 } } },
-  { .channel = 0, .filter = 2, .data = { .coeff = { 0x0ff895, 0xe0970b, 0x0f7f00, 0xe0970b, 0x0f7795 } } },
-  { .channel = 0, .filter = 3, .data = { .coeff = { 0x0fd1c4, 0xe1ac22, 0x0ec8cf, 0xe1ac22, 0x0e9a94 } } },
-  { .channel = 0, .filter = 4, .data = { .coeff = { 0x0f7c1c, 0xe3cc03, 0x0df786, 0xe3cc03, 0x0d73a2 } } },
-  { .channel = 0, .filter = 5, .data = { .coeff = { 0x11fb92, 0xf5a1a0, 0x073cd2, 0xf5a1a0, 0x093865 } } },
-  { .channel = 0, .filter = 6, .data = { .coeff = { 0x0e17a9, 0x068b6c, 0x08a0e5, 0x068b6c, 0x06b88e } } },
-
-  { .channel = 1, .filter = 0, .data = { .coeff = { 0x0fd0d4, 0xe05e56, 0x0fd0d4, 0xe05ee1, 0x0fa234 } } },
-  { .channel = 1, .filter = 1, .data = { .coeff = { 0x0910d7, 0x088e1a, 0x030651, 0x01dcb1, 0x02c892 } } },
-  { .channel = 1, .filter = 2, .data = { .coeff = { 0x0ff895, 0xe0970b, 0x0f7f00, 0xe0970b, 0x0f7795 } } },
-  { .channel = 1, .filter = 3, .data = { .coeff = { 0x0fd1c4, 0xe1ac22, 0x0ec8cf, 0xe1ac22, 0x0e9a94 } } },
-  { .channel = 1, .filter = 4, .data = { .coeff = { 0x0f7c1c, 0xe3cc03, 0x0df786, 0xe3cc03, 0x0d73a2 } } },
-  { .channel = 1, .filter = 5, .data = { .coeff = { 0x11fb92, 0xf5a1a0, 0x073cd2, 0xf5a1a0, 0x093865 } } },
-  { .channel = 1, .filter = 6, .data = { .coeff = { 0x0e17a9, 0x068b6c, 0x08a0e5, 0x068b6c, 0x06b88e } } }
-};
-
-static struct tas_eq_pref_t eqp_17_1_0 = {
-  .sample_rate   = 44100,
-  .device_id     = 0x17,
-  .output_id     = TAS_OUTPUT_INTERNAL_SPKR,
-  .speaker_id    = 0x00,
-
-  .drce          = &eqp_17_1_0_drce,
-
-  .filter_count  = 14,
-  .biquads       = eqp_17_1_0_biquads
-};
-
-/* ======================================================================== */
-
-static struct tas_drce_t eqp_18_1_0_drce={
-  .enable     = 1,
-  .above      = { .val = 3.0 * (1<<8), .expand = 0 },
-  .below      = { .val = 1.0 * (1<<8), .expand = 0 },
-  .threshold  = -13.14  * (1<<8),
-  .energy     = 2.4     * (1<<12),
-  .attack     = 0.013   * (1<<12),
-  .decay      = 0.212   * (1<<12),
-};
-
-static struct tas_biquad_ctrl_t eqp_18_1_0_biquads[]={
-  { .channel = 0, .filter = 0, .data = { .coeff = { 0x0f5514, 0xe155d7, 0x0f5514, 0xe15cfa, 0x0eb14b } } },
-  { .channel = 0, .filter = 1, .data = { .coeff = { 0x06ec33, 0x02abe3, 0x015eef, 0xf764d9, 0x03922d } } },
-  { .channel = 0, .filter = 2, .data = { .coeff = { 0x0ef5f2, 0xe67d1f, 0x0bcf37, 0xe67d1f, 0x0ac529 } } },
-  { .channel = 0, .filter = 3, .data = { .coeff = { 0x0db050, 0xe5be4d, 0x0d0c78, 0xe5be4d, 0x0abcc8 } } },
-  { .channel = 0, .filter = 4, .data = { .coeff = { 0x0f1298, 0xe64ec6, 0x0cc03e, 0xe64ec6, 0x0bd2d7 } } },
-  { .channel = 0, .filter = 5, .data = { .coeff = { 0x0c641a, 0x06537a, 0x08d155, 0x06537a, 0x053570 } } },
-  { .channel = 0, .filter = 6, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
-
-  { .channel = 1, .filter = 0, .data = { .coeff = { 0x0f5514, 0xe155d7, 0x0f5514, 0xe15cfa, 0x0eb14b } } },
-  { .channel = 1, .filter = 1, .data = { .coeff = { 0x06ec33, 0x02abe3, 0x015eef, 0xf764d9, 0x03922d } } },
-  { .channel = 1, .filter = 2, .data = { .coeff = { 0x0ef5f2, 0xe67d1f, 0x0bcf37, 0xe67d1f, 0x0ac529 } } },
-  { .channel = 1, .filter = 3, .data = { .coeff = { 0x0db050, 0xe5be4d, 0x0d0c78, 0xe5be4d, 0x0abcc8 } } },
-  { .channel = 1, .filter = 4, .data = { .coeff = { 0x0f1298, 0xe64ec6, 0x0cc03e, 0xe64ec6, 0x0bd2d7 } } },
-  { .channel = 1, .filter = 5, .data = { .coeff = { 0x0c641a, 0x06537a, 0x08d155, 0x06537a, 0x053570 } } },
-  { .channel = 1, .filter = 6, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } }
-};
-
-static struct tas_eq_pref_t eqp_18_1_0 = {
-  .sample_rate   = 44100,
-  .device_id     = 0x18,
-  .output_id     = TAS_OUTPUT_INTERNAL_SPKR,
-  .speaker_id    = 0x00,
-
-  .drce          = &eqp_18_1_0_drce,
-
-  .filter_count  = 14,
-  .biquads       = eqp_18_1_0_biquads
-};
-
-/* ======================================================================== */
-
-static struct tas_drce_t eqp_1a_1_0_drce={
-  .enable     = 1,
-  .above      = { .val = 3.0 * (1<<8), .expand = 0 },
-  .below      = { .val = 1.0 * (1<<8), .expand = 0 },
-  .threshold  = -10.75  * (1<<8),
-  .energy     = 2.4     * (1<<12),
-  .attack     = 0.013   * (1<<12),
-  .decay      = 0.212   * (1<<12),
-};
-
-static struct tas_biquad_ctrl_t eqp_1a_1_0_biquads[]={
-  { .channel = 0, .filter = 0, .data = { .coeff = { 0x0fb8fd, 0xe08e04, 0x0fb8fd, 0xe08f40, 0x0f7336 } } },
-  { .channel = 0, .filter = 1, .data = { .coeff = { 0x06371d, 0x0c6e3a, 0x06371d, 0x05bfd3, 0x031ca2 } } },
-  { .channel = 0, .filter = 2, .data = { .coeff = { 0x0fa1c0, 0xe18692, 0x0f030e, 0xe18692, 0x0ea4ce } } },
-  { .channel = 0, .filter = 3, .data = { .coeff = { 0x0fe495, 0xe17eff, 0x0f0452, 0xe17eff, 0x0ee8e7 } } },
-  { .channel = 0, .filter = 4, .data = { .coeff = { 0x100857, 0xe7e71c, 0x0e9599, 0xe7e71c, 0x0e9df1 } } },
-  { .channel = 0, .filter = 5, .data = { .coeff = { 0x0fb26e, 0x06a82c, 0x0db2b4, 0x06a82c, 0x0d6522 } } },
-  { .channel = 0, .filter = 6, .data = { .coeff = { 0x11419d, 0xf06cbf, 0x0a4f6e, 0xf06cbf, 0x0b910c } } },
-
-  { .channel = 1, .filter = 0, .data = { .coeff = { 0x0fb8fd, 0xe08e04, 0x0fb8fd, 0xe08f40, 0x0f7336 } } },
-  { .channel = 1, .filter = 1, .data = { .coeff = { 0x06371d, 0x0c6e3a, 0x06371d, 0x05bfd3, 0x031ca2 } } },
-  { .channel = 1, .filter = 2, .data = { .coeff = { 0x0fa1c0, 0xe18692, 0x0f030e, 0xe18692, 0x0ea4ce } } },
-  { .channel = 1, .filter = 3, .data = { .coeff = { 0x0fe495, 0xe17eff, 0x0f0452, 0xe17eff, 0x0ee8e7 } } },
-  { .channel = 1, .filter = 4, .data = { .coeff = { 0x100857, 0xe7e71c, 0x0e9599, 0xe7e71c, 0x0e9df1 } } },
-  { .channel = 1, .filter = 5, .data = { .coeff = { 0x0fb26e, 0x06a82c, 0x0db2b4, 0x06a82c, 0x0d6522 } } },
-  { .channel = 1, .filter = 6, .data = { .coeff = { 0x11419d, 0xf06cbf, 0x0a4f6e, 0xf06cbf, 0x0b910c } } }
-};
-
-static struct tas_eq_pref_t eqp_1a_1_0 = {
-  .sample_rate   = 44100,
-  .device_id     = 0x1a,
-  .output_id     = TAS_OUTPUT_INTERNAL_SPKR,
-  .speaker_id    = 0x00,
-
-  .drce          = &eqp_1a_1_0_drce,
-
-  .filter_count  = 14,
-  .biquads       = eqp_1a_1_0_biquads
-};
-
-/* ======================================================================== */
-
-static struct tas_drce_t eqp_1c_1_0_drce={
-  .enable     = 1,
-  .above      = { .val = 3.0 * (1<<8), .expand = 0 },
-  .below      = { .val = 1.0 * (1<<8), .expand = 0 },
-  .threshold  = -14.34  * (1<<8),
-  .energy     = 2.4     * (1<<12),
-  .attack     = 0.013   * (1<<12),
-  .decay      = 0.212   * (1<<12),
-};
-
-static struct tas_biquad_ctrl_t eqp_1c_1_0_biquads[]={
-  { .channel = 0, .filter = 0, .data = { .coeff = { 0x0f4f95, 0xe160d4, 0x0f4f95, 0xe1686e, 0x0ea6c5 } } },
-  { .channel = 0, .filter = 1, .data = { .coeff = { 0x066b92, 0x0290d4, 0x0148a0, 0xf6853f, 0x03bfc7 } } },
-  { .channel = 0, .filter = 2, .data = { .coeff = { 0x0f57dc, 0xe51c91, 0x0dd1cb, 0xe51c91, 0x0d29a8 } } },
-  { .channel = 0, .filter = 3, .data = { .coeff = { 0x0df1cb, 0xe4fa84, 0x0d7cdc, 0xe4fa84, 0x0b6ea7 } } },
-  { .channel = 0, .filter = 4, .data = { .coeff = { 0x0eba36, 0xe6aa48, 0x0b9f52, 0xe6aa48, 0x0a5989 } } },
-  { .channel = 0, .filter = 5, .data = { .coeff = { 0x0caf02, 0x05ef9d, 0x084beb, 0x05ef9d, 0x04faee } } },
-  { .channel = 0, .filter = 6, .data = { .coeff = { 0x0fc686, 0xe22947, 0x0e4b5d, 0xe22947, 0x0e11e4 } } },
-
-  { .channel = 1, .filter = 0, .data = { .coeff = { 0x0f4f95, 0xe160d4, 0x0f4f95, 0xe1686e, 0x0ea6c5 } } },
-  { .channel = 1, .filter = 1, .data = { .coeff = { 0x066b92, 0x0290d4, 0x0148a0, 0xf6853f, 0x03bfc7 } } },
-  { .channel = 1, .filter = 2, .data = { .coeff = { 0x0f57dc, 0xe51c91, 0x0dd1cb, 0xe51c91, 0x0d29a8 } } },
-  { .channel = 1, .filter = 3, .data = { .coeff = { 0x0df1cb, 0xe4fa84, 0x0d7cdc, 0xe4fa84, 0x0b6ea7 } } },
-  { .channel = 1, .filter = 4, .data = { .coeff = { 0x0eba36, 0xe6aa48, 0x0b9f52, 0xe6aa48, 0x0a5989 } } },
-  { .channel = 1, .filter = 5, .data = { .coeff = { 0x0caf02, 0x05ef9d, 0x084beb, 0x05ef9d, 0x04faee } } },
-  { .channel = 1, .filter = 6, .data = { .coeff = { 0x0fc686, 0xe22947, 0x0e4b5d, 0xe22947, 0x0e11e4 } } }
-};
-
-static struct tas_eq_pref_t eqp_1c_1_0 = {
-  .sample_rate   = 44100,
-  .device_id     = 0x1c,
-  .output_id     = TAS_OUTPUT_INTERNAL_SPKR,
-  .speaker_id    = 0x00,
-
-  .drce          = &eqp_1c_1_0_drce,
-
-  .filter_count  = 14,
-  .biquads       = eqp_1c_1_0_biquads
-};
-
-/* ======================================================================== */
-
-static uint tas3004_master_tab[]={
-              0x0,       0x75,       0x9c,       0xbb,
-             0xdb,       0xfb,      0x11e,      0x143,
-            0x16b,      0x196,      0x1c3,      0x1f5,
-            0x229,      0x263,      0x29f,      0x2e1,
-            0x328,      0x373,      0x3c5,      0x41b,
-            0x478,      0x4dc,      0x547,      0x5b8,
-            0x633,      0x6b5,      0x740,      0x7d5,
-            0x873,      0x91c,      0x9d2,      0xa92,
-            0xb5e,      0xc39,      0xd22,      0xe19,
-            0xf20,     0x1037,     0x1161,     0x129e,
-           0x13ed,     0x1551,     0x16ca,     0x185d,
-           0x1a08,     0x1bcc,     0x1dac,     0x1fa7,
-           0x21c1,     0x23fa,     0x2655,     0x28d6,
-           0x2b7c,     0x2e4a,     0x3141,     0x3464,
-           0x37b4,     0x3b35,     0x3ee9,     0x42d3,
-           0x46f6,     0x4b53,     0x4ff0,     0x54ce,
-           0x59f2,     0x5f5f,     0x6519,     0x6b24,
-           0x7183,     0x783c,     0x7f53,     0x86cc,
-           0x8ead,     0x96fa,     0x9fba,     0xa8f2,
-           0xb2a7,     0xbce1,     0xc7a5,     0xd2fa,
-           0xdee8,     0xeb75,     0xf8aa,    0x1068e,
-          0x1152a,    0x12487,    0x134ad,    0x145a5,
-          0x1577b,    0x16a37,    0x17df5,    0x192bd,
-          0x1a890,    0x1bf7b,    0x1d78d,    0x1f0d1,
-          0x20b55,    0x22727,    0x24456,    0x262f2,
-          0x2830b
-};
-
-static uint tas3004_mixer_tab[]={
-              0x0,      0x748,      0x9be,      0xbaf,
-            0xda4,      0xfb1,     0x11de,     0x1431,
-           0x16ad,     0x1959,     0x1c37,     0x1f4b,
-           0x2298,     0x2628,     0x29fb,     0x2e12,
-           0x327d,     0x3734,     0x3c47,     0x41b4,
-           0x4787,     0x4dbe,     0x546d,     0x5b86,
-           0x632e,     0x6b52,     0x7400,     0x7d54,
-           0x873b,     0x91c6,     0x9d1a,     0xa920,
-           0xb5e5,     0xc38c,     0xd21b,     0xe18f,
-           0xf1f5,    0x1036a,    0x1160f,    0x129d6,
-          0x13ed0,    0x1550c,    0x16ca0,    0x185c9,
-          0x1a07b,    0x1bcc3,    0x1dab9,    0x1fa75,
-          0x21c0f,    0x23fa3,    0x26552,    0x28d64,
-          0x2b7c9,    0x2e4a2,    0x31411,    0x3463b,
-          0x37b44,    0x3b353,    0x3ee94,    0x42d30,
-          0x46f55,    0x4b533,    0x4fefc,    0x54ce5,
-          0x59f25,    0x5f5f6,    0x65193,    0x6b23c,
-          0x71835,    0x783c3,    0x7f52c,    0x86cc0,
-          0x8eacc,    0x96fa5,    0x9fba0,    0xa8f1a,
-          0xb2a71,    0xbce0a,    0xc7a4a,    0xd2fa0,
-          0xdee7b,    0xeb752,    0xf8a9f,   0x1068e4,
-         0x1152a3,   0x12486a,   0x134ac8,   0x145a55,
-         0x1577ac,   0x16a370,   0x17df51,   0x192bc2,
-         0x1a88f8,   0x1bf7b7,   0x1d78c9,   0x1f0d04,
-         0x20b542,   0x227268,   0x244564,   0x262f26,
-         0x2830af
-};
-
-static uint tas3004_treble_tab[]={
-             0x96,       0x95,       0x95,       0x94,
-             0x93,       0x92,       0x92,       0x91,
-             0x90,       0x90,       0x8f,       0x8e,
-             0x8d,       0x8d,       0x8c,       0x8b,
-             0x8a,       0x8a,       0x89,       0x88,
-             0x88,       0x87,       0x86,       0x85,
-             0x85,       0x84,       0x83,       0x83,
-             0x82,       0x81,       0x80,       0x80,
-             0x7f,       0x7e,       0x7e,       0x7d,
-             0x7c,       0x7b,       0x7b,       0x7a,
-             0x79,       0x78,       0x78,       0x77,
-             0x76,       0x76,       0x75,       0x74,
-             0x73,       0x73,       0x72,       0x71,
-             0x71,       0x68,       0x45,       0x5b,
-             0x6d,       0x6c,       0x6b,       0x6a,
-             0x69,       0x68,       0x67,       0x66,
-             0x65,       0x63,       0x62,       0x62,
-             0x60,       0x5e,       0x5c,       0x5b,
-             0x59,       0x57,       0x55,       0x53,
-             0x52,       0x4f,       0x4d,       0x4a,
-             0x48,       0x46,       0x43,       0x40,
-             0x3d,       0x3a,       0x36,       0x33,
-             0x2f,       0x2c,       0x27,       0x23,
-             0x1f,       0x1a,       0x15,        0xf,
-              0x8,        0x5,        0x2,        0x1,
-              0x1
-};
-
-static uint tas3004_bass_tab[]={
-             0x96,       0x95,       0x95,       0x94,
-             0x93,       0x92,       0x92,       0x91,
-             0x90,       0x90,       0x8f,       0x8e,
-             0x8d,       0x8d,       0x8c,       0x8b,
-             0x8a,       0x8a,       0x89,       0x88,
-             0x88,       0x87,       0x86,       0x85,
-             0x85,       0x84,       0x83,       0x83,
-             0x82,       0x81,       0x80,       0x80,
-             0x7f,       0x7e,       0x7e,       0x7d,
-             0x7c,       0x7b,       0x7b,       0x7a,
-             0x79,       0x78,       0x78,       0x77,
-             0x76,       0x76,       0x75,       0x74,
-             0x73,       0x73,       0x72,       0x71,
-             0x70,       0x6f,       0x6e,       0x6d,
-             0x6c,       0x6b,       0x6a,       0x6a,
-             0x69,       0x67,       0x66,       0x66,
-             0x65,       0x63,       0x62,       0x62,
-             0x61,       0x60,       0x5e,       0x5d,
-             0x5b,       0x59,       0x57,       0x55,
-             0x53,       0x51,       0x4f,       0x4c,
-             0x4a,       0x48,       0x46,       0x44,
-             0x41,       0x3e,       0x3b,       0x38,
-             0x36,       0x33,       0x2f,       0x2b,
-             0x28,       0x24,       0x20,       0x1c,
-             0x17,       0x12,        0xd,        0x7,
-              0x1
-};
-
-struct tas_gain_t tas3004_gain={
-  .master  = tas3004_master_tab,
-  .treble  = tas3004_treble_tab,
-  .bass    = tas3004_bass_tab,
-  .mixer   = tas3004_mixer_tab
-};
-
-struct tas_eq_pref_t *tas3004_eq_prefs[]={
-  &eqp_17_1_0,
-  &eqp_18_1_0,
-  &eqp_1a_1_0,
-  &eqp_1c_1_0,
-  NULL
-};
diff --git a/sound/oss/dmasound/tas_common.c b/sound/oss/dmasound/tas_common.c
deleted file mode 100644 (file)
index b295ef6..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/proc_fs.h>
-#include <linux/ioport.h>
-#include <linux/sysctl.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/soundcard.h>
-#include <asm/uaccess.h>
-#include <asm/errno.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-
-#include "tas_common.h"
-
-#define CALL0(proc)                                                            \
-       do {                                                                    \
-               struct tas_data_t *self;                                        \
-               if (!tas_client || driver_hooks == NULL)                        \
-                       return -1;                                              \
-               self = dev_get_drvdata(&tas_client->dev);                       \
-               if (driver_hooks->proc)                                         \
-                       return driver_hooks->proc(self);                        \
-               else                                                            \
-                       return -EINVAL;                                         \
-       } while (0)
-
-#define CALL(proc,arg...)                                                      \
-       do {                                                                    \
-               struct tas_data_t *self;                                        \
-               if (!tas_client || driver_hooks == NULL)                        \
-                       return -1;                                              \
-               self = dev_get_drvdata(&tas_client->dev);                       \
-               if (driver_hooks->proc)                                         \
-                       return driver_hooks->proc(self, ## arg);                \
-               else                                                            \
-                       return -EINVAL;                                         \
-       } while (0)
-
-
-static u8 tas_i2c_address = 0x34;
-static struct i2c_client *tas_client;
-
-static int tas_attach_adapter(struct i2c_adapter *);
-static int tas_detach_client(struct i2c_client *);
-
-struct i2c_driver tas_driver = {
-       .driver = {
-               .name   = "tas",
-       },
-       .attach_adapter = tas_attach_adapter,
-       .detach_client  = tas_detach_client,
-};
-
-struct tas_driver_hooks_t *driver_hooks;
-
-int
-tas_register_driver(struct tas_driver_hooks_t *hooks)
-{
-       driver_hooks = hooks;
-       return 0;
-}
-
-int
-tas_get_mixer_level(int mixer, uint *level)
-{
-       CALL(get_mixer_level,mixer,level);
-}
-
-int
-tas_set_mixer_level(int mixer,uint level)
-{
-       CALL(set_mixer_level,mixer,level);
-}
-
-int
-tas_enter_sleep(void)
-{
-       CALL0(enter_sleep);
-}
-
-int
-tas_leave_sleep(void)
-{
-       CALL0(leave_sleep);
-}
-
-int
-tas_supported_mixers(void)
-{
-       CALL0(supported_mixers);
-}
-
-int
-tas_mixer_is_stereo(int mixer)
-{
-       CALL(mixer_is_stereo,mixer);
-}
-
-int
-tas_stereo_mixers(void)
-{
-       CALL0(stereo_mixers);
-}
-
-int
-tas_output_device_change(int device_id,int layout_id,int speaker_id)
-{
-       CALL(output_device_change,device_id,layout_id,speaker_id);
-}
-
-int
-tas_device_ioctl(u_int cmd, u_long arg)
-{
-       CALL(device_ioctl,cmd,arg);
-}
-
-int
-tas_post_init(void)
-{
-       CALL0(post_init);
-}
-
-static int
-tas_detect_client(struct i2c_adapter *adapter, int address)
-{
-       static const char *client_name = "tas Digital Equalizer";
-       struct i2c_client *new_client;
-       int rc = -ENODEV;
-
-       if (!driver_hooks) {
-               printk(KERN_ERR "tas_detect_client called with no hooks !\n");
-               return -ENODEV;
-       }
-       
-       new_client = kzalloc(sizeof(*new_client), GFP_KERNEL);
-       if (!new_client)
-               return -ENOMEM;
-
-       new_client->addr = address;
-       new_client->adapter = adapter;
-       new_client->driver = &tas_driver;
-       strlcpy(new_client->name, client_name, DEVICE_NAME_SIZE);
-
-        if (driver_hooks->init(new_client))
-               goto bail;
-
-       /* Tell the i2c layer a new client has arrived */
-       if (i2c_attach_client(new_client)) {
-               driver_hooks->uninit(dev_get_drvdata(&new_client->dev));
-               goto bail;
-       }
-
-       tas_client = new_client;
-       return 0;
- bail:
-       tas_client = NULL;
-       kfree(new_client);
-       return rc;
-}
-
-static int
-tas_attach_adapter(struct i2c_adapter *adapter)
-{
-       if (!strncmp(adapter->name, "mac-io", 6))
-               return tas_detect_client(adapter, tas_i2c_address);
-       return 0;
-}
-
-static int
-tas_detach_client(struct i2c_client *client)
-{
-       if (client == tas_client) {
-               driver_hooks->uninit(dev_get_drvdata(&client->dev));
-
-               i2c_detach_client(client);
-               kfree(client);
-       }
-       return 0;
-}
-
-void
-tas_cleanup(void)
-{
-       i2c_del_driver(&tas_driver);
-}
-
-int __init
-tas_init(int driver_id, const char *driver_name)
-{
-       const u32* paddr;
-       struct device_node *tas_node;
-
-       printk(KERN_INFO "tas driver [%s])\n", driver_name);
-
-#ifndef CONFIG_I2C_POWERMAC
-       request_module("i2c-powermac");
-#endif
-       tas_node = of_find_node_by_name("deq");
-       if (tas_node == NULL)
-               return -ENODEV;
-       paddr = of_get_property(tas_node, "i2c-address", NULL);
-       if (paddr) {
-               tas_i2c_address = (*paddr) >> 1;
-               printk(KERN_INFO "using i2c address: 0x%x from device-tree\n",
-                               tas_i2c_address);
-       } else    
-               printk(KERN_INFO "using i2c address: 0x%x (default)\n",
-                               tas_i2c_address);
-       of_node_put(tas_node);
-
-       return i2c_add_driver(&tas_driver);
-}
diff --git a/sound/oss/dmasound/tas_common.h b/sound/oss/dmasound/tas_common.h
deleted file mode 100644 (file)
index 0741c28..0000000
+++ /dev/null
@@ -1,284 +0,0 @@
-#ifndef _TAS_COMMON_H_
-#define _TAS_COMMON_H_
-
-#include <linux/i2c.h>
-#include <linux/soundcard.h>
-#include <asm/string.h>
-
-#define I2C_DRIVERID_TAS_BASE   (0xFEBA)
-
-#define SET_4_20(shadow, offset, val)                        \
-       do {                                                 \
-               (shadow)[(offset)+0] = ((val) >> 16) & 0xff; \
-               (shadow)[(offset)+1] = ((val) >> 8)  & 0xff; \
-               (shadow)[(offset)+2] = ((val) >> 0)  & 0xff; \
-       } while (0)
-
-#define GET_4_20(shadow, offset)                             \
-       (((u_int)((shadow)[(offset)+0]) << 16) |             \
-        ((u_int)((shadow)[(offset)+1]) <<  8) |             \
-        ((u_int)((shadow)[(offset)+2]) <<  0))
-
-
-#define TAS_BIQUAD_FAST_LOAD 0x01
-
-#define TAS_DRCE_ENABLE           0x01
-#define TAS_DRCE_ABOVE_RATIO      0x02
-#define TAS_DRCE_BELOW_RATIO      0x04
-#define TAS_DRCE_THRESHOLD        0x08
-#define TAS_DRCE_ENERGY           0x10
-#define TAS_DRCE_ATTACK           0x20
-#define TAS_DRCE_DECAY            0x40
-
-#define TAS_DRCE_ALL              0x7f
-
-
-#define TAS_OUTPUT_HEADPHONES     0x00
-#define TAS_OUTPUT_INTERNAL_SPKR  0x01
-#define TAS_OUTPUT_EXTERNAL_SPKR  0x02
-
-
-union tas_biquad_t {
-       struct {
-               int b0,b1,b2,a1,a2;
-       } coeff;
-       int buf[5];
-};
-
-struct tas_biquad_ctrl_t {
-       u_int channel:4;
-       u_int filter:4;
-
-       union tas_biquad_t data;
-};
-
-struct tas_biquad_ctrl_list_t {
-       int flags;
-       int filter_count;
-       struct tas_biquad_ctrl_t biquads[0];
-};
-
-struct tas_ratio_t {
-       unsigned short val;    /* 8.8                        */
-       unsigned short expand; /* 0 = compress, !0 = expand. */
-};
-
-struct tas_drce_t {
-       unsigned short enable;
-       struct tas_ratio_t above;
-       struct tas_ratio_t below;
-       short threshold;       /* dB,       8.8 signed    */
-       unsigned short energy; /* seconds,  4.12 unsigned */
-       unsigned short attack; /* seconds,  4.12 unsigned */
-       unsigned short decay;  /* seconds,  4.12 unsigned */
-};
-
-struct tas_drce_ctrl_t {
-       uint flags;
-
-       struct tas_drce_t data;
-};
-
-struct tas_gain_t
-{
-  unsigned int *master;
-  unsigned int *treble;
-  unsigned int *bass;
-  unsigned int *mixer;
-};
-
-typedef char tas_shadow_t[0x45];
-
-struct tas_data_t
-{
-       struct i2c_client *client;
-       tas_shadow_t *shadow;
-       uint mixer[SOUND_MIXER_NRDEVICES];
-};
-
-typedef int (*tas_hook_init_t)(struct i2c_client *);
-typedef int (*tas_hook_post_init_t)(struct tas_data_t *);
-typedef void (*tas_hook_uninit_t)(struct tas_data_t *);
-
-typedef int (*tas_hook_get_mixer_level_t)(struct tas_data_t *,int,uint *);
-typedef int (*tas_hook_set_mixer_level_t)(struct tas_data_t *,int,uint);
-
-typedef int (*tas_hook_enter_sleep_t)(struct tas_data_t *);
-typedef int (*tas_hook_leave_sleep_t)(struct tas_data_t *);
-
-typedef int (*tas_hook_supported_mixers_t)(struct tas_data_t *);
-typedef int (*tas_hook_mixer_is_stereo_t)(struct tas_data_t *,int);
-typedef int (*tas_hook_stereo_mixers_t)(struct tas_data_t *);
-
-typedef int (*tas_hook_output_device_change_t)(struct tas_data_t *,int,int,int);
-typedef int (*tas_hook_device_ioctl_t)(struct tas_data_t *,u_int,u_long);
-
-struct tas_driver_hooks_t {
-       /*
-        * All hardware initialisation must be performed in
-        * post_init(), as tas_dmasound_init() does a hardware reset.
-        *
-        * init() is called before tas_dmasound_init() so that
-        * ouput_device_change() is always called after i2c driver
-        * initialisation. The implication is that
-        * output_device_change() must cope with the fact that it
-        * may be called before post_init().
-        */
-
-       tas_hook_init_t                   init;
-       tas_hook_post_init_t              post_init;
-       tas_hook_uninit_t                 uninit;
-
-       tas_hook_get_mixer_level_t        get_mixer_level;
-       tas_hook_set_mixer_level_t        set_mixer_level;
-
-       tas_hook_enter_sleep_t            enter_sleep;
-       tas_hook_leave_sleep_t            leave_sleep;
-
-       tas_hook_supported_mixers_t       supported_mixers;
-       tas_hook_mixer_is_stereo_t        mixer_is_stereo;
-       tas_hook_stereo_mixers_t          stereo_mixers;
-
-       tas_hook_output_device_change_t   output_device_change;
-       tas_hook_device_ioctl_t           device_ioctl;
-};
-
-enum tas_write_mode_t {
-       WRITE_HW     = 0x01,
-       WRITE_SHADOW = 0x02,
-       WRITE_NORMAL = 0x03,
-       FORCE_WRITE  = 0x04
-};
-
-static inline uint
-tas_mono_to_stereo(uint mono)
-{
-       mono &=0xff;
-       return mono | (mono<<8);
-}
-
-/*
- * Todo: make these functions a bit more efficient !
- */
-static inline int
-tas_write_register(    struct tas_data_t *self,
-                       uint reg_num,
-                       uint reg_width,
-                       char *data,
-                       uint write_mode)
-{
-       int rc;
-
-       if (reg_width==0 || data==NULL || self==NULL)
-               return -EINVAL;
-       if (!(write_mode & FORCE_WRITE) &&
-           !memcmp(data,self->shadow[reg_num],reg_width))
-               return 0;
-
-       if (write_mode & WRITE_SHADOW)
-               memcpy(self->shadow[reg_num],data,reg_width);
-       if (write_mode & WRITE_HW) {
-               rc=i2c_smbus_write_i2c_block_data(self->client,
-                                                 reg_num,
-                                                 reg_width,
-                                                 data);
-               if (rc < 0) {
-                       printk("tas: I2C block write failed \n");  
-                       return rc; 
-               }
-       }
-       return 0;
-}
-
-static inline int
-tas_sync_register(     struct tas_data_t *self,
-                       uint reg_num,
-                       uint reg_width)
-{
-       int rc;
-
-       if (reg_width==0 || self==NULL)
-               return -EINVAL;
-       rc=i2c_smbus_write_i2c_block_data(self->client,
-                                         reg_num,
-                                         reg_width,
-                                         self->shadow[reg_num]);
-       if (rc < 0) {
-               printk("tas: I2C block write failed \n");
-               return rc;
-       }
-       return 0;
-}
-
-static inline int
-tas_write_byte_register(       struct tas_data_t *self,
-                               uint reg_num,
-                               char data,
-                               uint write_mode)
-{
-       if (self==NULL)
-               return -1;
-       if (!(write_mode & FORCE_WRITE) && data != self->shadow[reg_num][0])
-               return 0;
-       if (write_mode & WRITE_SHADOW)
-               self->shadow[reg_num][0]=data;
-       if (write_mode & WRITE_HW) {
-               if (i2c_smbus_write_byte_data(self->client, reg_num, data) < 0) {
-                       printk("tas: I2C byte write failed \n");  
-                       return -1; 
-               }
-       }
-       return 0;
-}
-
-static inline int
-tas_sync_byte_register(        struct tas_data_t *self,
-                       uint reg_num,
-                       uint reg_width)
-{
-       if (reg_width==0 || self==NULL)
-               return -1;
-       if (i2c_smbus_write_byte_data(
-           self->client, reg_num, self->shadow[reg_num][0]) < 0) {
-               printk("tas: I2C byte write failed \n");
-               return -1;
-       }
-       return 0;
-}
-
-static inline int
-tas_read_register(     struct tas_data_t *self,
-                       uint reg_num,
-                       uint reg_width,
-                       char *data)
-{
-       if (reg_width==0 || data==NULL || self==NULL)
-               return -1;
-       memcpy(data,self->shadow[reg_num],reg_width);
-       return 0;
-}
-
-extern int tas_register_driver(struct tas_driver_hooks_t *hooks);
-
-extern int tas_get_mixer_level(int mixer,uint *level);
-extern int tas_set_mixer_level(int mixer,uint level);
-extern int tas_enter_sleep(void);
-extern int tas_leave_sleep(void);
-extern int tas_supported_mixers(void);
-extern int tas_mixer_is_stereo(int mixer);
-extern int tas_stereo_mixers(void);
-extern int tas_output_device_change(int,int,int);
-extern int tas_device_ioctl(u_int, u_long);
-
-extern void tas_cleanup(void);
-extern int tas_init(int driver_id,const char *driver_name);
-extern int tas_post_init(void);
-
-#endif /* _TAS_COMMON_H_ */
-/*
- * Local Variables:
- * tab-width: 8
- * indent-tabs-mode: t
- * c-basic-offset: 8
- * End:
- */
diff --git a/sound/oss/dmasound/tas_eq_prefs.h b/sound/oss/dmasound/tas_eq_prefs.h
deleted file mode 100644 (file)
index 3a994ed..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef _TAS_EQ_PREFS_H_
-#define _TAS_EQ_PREFS_H_
-
-struct tas_eq_pref_t {
-       u_int sample_rate;
-       u_int device_id;
-       u_int output_id;
-       u_int speaker_id;
-
-       struct tas_drce_t *drce;
-
-       u_int filter_count;
-       struct tas_biquad_ctrl_t *biquads;
-};
-
-#endif /* _TAS_EQ_PREFS_H_ */
-
-/*
- * Local Variables:
- * tab-width: 8
- * indent-tabs-mode: t
- * c-basic-offset: 8
- * End:
- */
diff --git a/sound/oss/dmasound/tas_ioctl.h b/sound/oss/dmasound/tas_ioctl.h
deleted file mode 100644 (file)
index 9d12b37..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef _TAS_IOCTL_H_
-#define _TAS_IOCTL_H_
-
-#include <linux/soundcard.h>
-
-
-#define TAS_READ_EQ              _SIOR('t',0,struct tas_biquad_ctrl_t)
-#define TAS_WRITE_EQ             _SIOW('t',0,struct tas_biquad_ctrl_t)
-
-#define TAS_READ_EQ_LIST         _SIOR('t',1,struct tas_biquad_ctrl_t)
-#define TAS_WRITE_EQ_LIST        _SIOW('t',1,struct tas_biquad_ctrl_t)
-
-#define TAS_READ_EQ_FILTER_COUNT  _SIOR('t',2,int)
-#define TAS_READ_EQ_CHANNEL_COUNT _SIOR('t',3,int)
-
-#define TAS_READ_DRCE            _SIOR('t',4,struct tas_drce_ctrl_t)
-#define TAS_WRITE_DRCE           _SIOW('t',4,struct tas_drce_ctrl_t)
-
-#define TAS_READ_DRCE_CAPS       _SIOR('t',5,int)
-#define TAS_READ_DRCE_MIN        _SIOR('t',6,int)
-#define TAS_READ_DRCE_MAX        _SIOR('t',7,int)
-
-#endif
diff --git a/sound/oss/dmasound/trans_16.c b/sound/oss/dmasound/trans_16.c
deleted file mode 100644 (file)
index ca973ac..0000000
+++ /dev/null
@@ -1,898 +0,0 @@
-/*
- *  linux/sound/oss/dmasound/trans_16.c
- *
- *  16 bit translation routines.  Only used by Power mac at present.
- *
- *  See linux/sound/oss/dmasound/dmasound_core.c for copyright and
- *  history prior to 08/02/2001.
- *
- *  08/02/2001 Iain Sandoe
- *             split from dmasound_awacs.c
- *  11/29/2003 Renzo Davoli (King Enzo)
- *     - input resampling (for soft rate < hard rate)
- *     - software line in gain control
- */
-
-#include <linux/soundcard.h>
-#include <asm/uaccess.h>
-#include "dmasound.h"
-
-extern int expand_bal; /* Balance factor for expanding (not volume!) */
-static short dmasound_alaw2dma16[] ;
-static short dmasound_ulaw2dma16[] ;
-
-static ssize_t pmac_ct_law(const u_char __user *userPtr, size_t userCount,
-                          u_char frame[], ssize_t *frameUsed,
-                          ssize_t frameLeft);
-static ssize_t pmac_ct_s8(const u_char __user *userPtr, size_t userCount,
-                         u_char frame[], ssize_t *frameUsed,
-                         ssize_t frameLeft);
-static ssize_t pmac_ct_u8(const u_char __user *userPtr, size_t userCount,
-                         u_char frame[], ssize_t *frameUsed,
-                         ssize_t frameLeft);
-static ssize_t pmac_ct_s16(const u_char __user *userPtr, size_t userCount,
-                          u_char frame[], ssize_t *frameUsed,
-                          ssize_t frameLeft);
-static ssize_t pmac_ct_u16(const u_char __user *userPtr, size_t userCount,
-                          u_char frame[], ssize_t *frameUsed,
-                          ssize_t frameLeft);
-
-static ssize_t pmac_ctx_law(const u_char __user *userPtr, size_t userCount,
-                           u_char frame[], ssize_t *frameUsed,
-                           ssize_t frameLeft);
-static ssize_t pmac_ctx_s8(const u_char __user *userPtr, size_t userCount,
-                          u_char frame[], ssize_t *frameUsed,
-                          ssize_t frameLeft);
-static ssize_t pmac_ctx_u8(const u_char __user *userPtr, size_t userCount,
-                          u_char frame[], ssize_t *frameUsed,
-                          ssize_t frameLeft);
-static ssize_t pmac_ctx_s16(const u_char __user *userPtr, size_t userCount,
-                           u_char frame[], ssize_t *frameUsed,
-                           ssize_t frameLeft);
-static ssize_t pmac_ctx_u16(const u_char __user *userPtr, size_t userCount,
-                           u_char frame[], ssize_t *frameUsed,
-                           ssize_t frameLeft);
-
-static ssize_t pmac_ct_s16_read(const u_char __user *userPtr, size_t userCount,
-                          u_char frame[], ssize_t *frameUsed,
-                          ssize_t frameLeft);
-static ssize_t pmac_ct_u16_read(const u_char __user *userPtr, size_t userCount,
-                          u_char frame[], ssize_t *frameUsed,
-                          ssize_t frameLeft);
-
-/*** Translations ************************************************************/
-
-static int expand_data;        /* Data for expanding */
-
-static ssize_t pmac_ct_law(const u_char __user *userPtr, size_t userCount,
-                          u_char frame[], ssize_t *frameUsed,
-                          ssize_t frameLeft)
-{
-       short *table = dmasound.soft.format == AFMT_MU_LAW
-               ? dmasound_ulaw2dma16 : dmasound_alaw2dma16;
-       ssize_t count, used;
-       short *p = (short *) &frame[*frameUsed];
-       int val, stereo = dmasound.soft.stereo;
-
-       frameLeft >>= 2;
-       if (stereo)
-               userCount >>= 1;
-       used = count = min_t(unsigned long, userCount, frameLeft);
-       while (count > 0) {
-               u_char data;
-               if (get_user(data, userPtr++))
-                       return -EFAULT;
-               val = table[data];
-               *p++ = val;
-               if (stereo) {
-                       if (get_user(data, userPtr++))
-                               return -EFAULT;
-                       val = table[data];
-               }
-               *p++ = val;
-               count--;
-       }
-       *frameUsed += used * 4;
-       return stereo? used * 2: used;
-}
-
-
-static ssize_t pmac_ct_s8(const u_char __user *userPtr, size_t userCount,
-                         u_char frame[], ssize_t *frameUsed,
-                         ssize_t frameLeft)
-{
-       ssize_t count, used;
-       short *p = (short *) &frame[*frameUsed];
-       int val, stereo = dmasound.soft.stereo;
-
-       frameLeft >>= 2;
-       if (stereo)
-               userCount >>= 1;
-       used = count = min_t(unsigned long, userCount, frameLeft);
-       while (count > 0) {
-               u_char data;
-               if (get_user(data, userPtr++))
-                       return -EFAULT;
-               val = data << 8;
-               *p++ = val;
-               if (stereo) {
-                       if (get_user(data, userPtr++))
-                               return -EFAULT;
-                       val = data << 8;
-               }
-               *p++ = val;
-               count--;
-       }
-       *frameUsed += used * 4;
-       return stereo? used * 2: used;
-}
-
-
-static ssize_t pmac_ct_u8(const u_char __user *userPtr, size_t userCount,
-                         u_char frame[], ssize_t *frameUsed,
-                         ssize_t frameLeft)
-{
-       ssize_t count, used;
-       short *p = (short *) &frame[*frameUsed];
-       int val, stereo = dmasound.soft.stereo;
-
-       frameLeft >>= 2;
-       if (stereo)
-               userCount >>= 1;
-       used = count = min_t(unsigned long, userCount, frameLeft);
-       while (count > 0) {
-               u_char data;
-               if (get_user(data, userPtr++))
-                       return -EFAULT;
-               val = (data ^ 0x80) << 8;
-               *p++ = val;
-               if (stereo) {
-                       if (get_user(data, userPtr++))
-                               return -EFAULT;
-                       val = (data ^ 0x80) << 8;
-               }
-               *p++ = val;
-               count--;
-       }
-       *frameUsed += used * 4;
-       return stereo? used * 2: used;
-}
-
-
-static ssize_t pmac_ct_s16(const u_char __user *userPtr, size_t userCount,
-                          u_char frame[], ssize_t *frameUsed,
-                          ssize_t frameLeft)
-{
-       ssize_t count, used;
-       int stereo = dmasound.soft.stereo;
-       short *fp = (short *) &frame[*frameUsed];
-
-       frameLeft >>= 2;
-       userCount >>= (stereo? 2: 1);
-       used = count = min_t(unsigned long, userCount, frameLeft);
-       if (!stereo) {
-               short __user *up = (short __user *) userPtr;
-               while (count > 0) {
-                       short data;
-                       if (get_user(data, up++))
-                               return -EFAULT;
-                       *fp++ = data;
-                       *fp++ = data;
-                       count--;
-               }
-       } else {
-               if (copy_from_user(fp, userPtr, count * 4))
-                       return -EFAULT;
-       }
-       *frameUsed += used * 4;
-       return stereo? used * 4: used * 2;
-}
-
-static ssize_t pmac_ct_u16(const u_char __user *userPtr, size_t userCount,
-                          u_char frame[], ssize_t *frameUsed,
-                          ssize_t frameLeft)
-{
-       ssize_t count, used;
-       int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
-       int stereo = dmasound.soft.stereo;
-       short *fp = (short *) &frame[*frameUsed];
-       short __user *up = (short __user *) userPtr;
-
-       frameLeft >>= 2;
-       userCount >>= (stereo? 2: 1);
-       used = count = min_t(unsigned long, userCount, frameLeft);
-       while (count > 0) {
-               short data;
-               if (get_user(data, up++))
-                       return -EFAULT;
-               data ^= mask;
-               *fp++ = data;
-               if (stereo) {
-                       if (get_user(data, up++))
-                               return -EFAULT;
-                       data ^= mask;
-               }
-               *fp++ = data;
-               count--;
-       }
-       *frameUsed += used * 4;
-       return stereo? used * 4: used * 2;
-}
-
-
-static ssize_t pmac_ctx_law(const u_char __user *userPtr, size_t userCount,
-                           u_char frame[], ssize_t *frameUsed,
-                           ssize_t frameLeft)
-{
-       unsigned short *table = (unsigned short *)
-               (dmasound.soft.format == AFMT_MU_LAW
-                ? dmasound_ulaw2dma16 : dmasound_alaw2dma16);
-       unsigned int data = expand_data;
-       unsigned int *p = (unsigned int *) &frame[*frameUsed];
-       int bal = expand_bal;
-       int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
-       int utotal, ftotal;
-       int stereo = dmasound.soft.stereo;
-
-       frameLeft >>= 2;
-       if (stereo)
-               userCount >>= 1;
-       ftotal = frameLeft;
-       utotal = userCount;
-       while (frameLeft) {
-               u_char c;
-               if (bal < 0) {
-                       if (userCount == 0)
-                               break;
-                       if (get_user(c, userPtr++))
-                               return -EFAULT;
-                       data = table[c];
-                       if (stereo) {
-                               if (get_user(c, userPtr++))
-                                       return -EFAULT;
-                               data = (data << 16) + table[c];
-                       } else
-                               data = (data << 16) + data;
-                       userCount--;
-                       bal += hSpeed;
-               }
-               *p++ = data;
-               frameLeft--;
-               bal -= sSpeed;
-       }
-       expand_bal = bal;
-       expand_data = data;
-       *frameUsed += (ftotal - frameLeft) * 4;
-       utotal -= userCount;
-       return stereo? utotal * 2: utotal;
-}
-
-static ssize_t pmac_ctx_s8(const u_char __user *userPtr, size_t userCount,
-                          u_char frame[], ssize_t *frameUsed,
-                          ssize_t frameLeft)
-{
-       unsigned int *p = (unsigned int *) &frame[*frameUsed];
-       unsigned int data = expand_data;
-       int bal = expand_bal;
-       int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
-       int stereo = dmasound.soft.stereo;
-       int utotal, ftotal;
-
-       frameLeft >>= 2;
-       if (stereo)
-               userCount >>= 1;
-       ftotal = frameLeft;
-       utotal = userCount;
-       while (frameLeft) {
-               u_char c;
-               if (bal < 0) {
-                       if (userCount == 0)
-                               break;
-                       if (get_user(c, userPtr++))
-                               return -EFAULT;
-                       data = c << 8;
-                       if (stereo) {
-                               if (get_user(c, userPtr++))
-                                       return -EFAULT;
-                               data = (data << 16) + (c << 8);
-                       } else
-                               data = (data << 16) + data;
-                       userCount--;
-                       bal += hSpeed;
-               }
-               *p++ = data;
-               frameLeft--;
-               bal -= sSpeed;
-       }
-       expand_bal = bal;
-       expand_data = data;
-       *frameUsed += (ftotal - frameLeft) * 4;
-       utotal -= userCount;
-       return stereo? utotal * 2: utotal;
-}
-
-
-static ssize_t pmac_ctx_u8(const u_char __user *userPtr, size_t userCount,
-                          u_char frame[], ssize_t *frameUsed,
-                          ssize_t frameLeft)
-{
-       unsigned int *p = (unsigned int *) &frame[*frameUsed];
-       unsigned int data = expand_data;
-       int bal = expand_bal;
-       int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
-       int stereo = dmasound.soft.stereo;
-       int utotal, ftotal;
-
-       frameLeft >>= 2;
-       if (stereo)
-               userCount >>= 1;
-       ftotal = frameLeft;
-       utotal = userCount;
-       while (frameLeft) {
-               u_char c;
-               if (bal < 0) {
-                       if (userCount == 0)
-                               break;
-                       if (get_user(c, userPtr++))
-                               return -EFAULT;
-                       data = (c ^ 0x80) << 8;
-                       if (stereo) {
-                               if (get_user(c, userPtr++))
-                                       return -EFAULT;
-                               data = (data << 16) + ((c ^ 0x80) << 8);
-                       } else
-                               data = (data << 16) + data;
-                       userCount--;
-                       bal += hSpeed;
-               }
-               *p++ = data;
-               frameLeft--;
-               bal -= sSpeed;
-       }
-       expand_bal = bal;
-       expand_data = data;
-       *frameUsed += (ftotal - frameLeft) * 4;
-       utotal -= userCount;
-       return stereo? utotal * 2: utotal;
-}
-
-
-static ssize_t pmac_ctx_s16(const u_char __user *userPtr, size_t userCount,
-                           u_char frame[], ssize_t *frameUsed,
-                           ssize_t frameLeft)
-{
-       unsigned int *p = (unsigned int *) &frame[*frameUsed];
-       unsigned int data = expand_data;
-       unsigned short __user *up = (unsigned short __user *) userPtr;
-       int bal = expand_bal;
-       int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
-       int stereo = dmasound.soft.stereo;
-       int utotal, ftotal;
-
-       frameLeft >>= 2;
-       userCount >>= (stereo? 2: 1);
-       ftotal = frameLeft;
-       utotal = userCount;
-       while (frameLeft) {
-               unsigned short c;
-               if (bal < 0) {
-                       if (userCount == 0)
-                               break;
-                       if (get_user(data, up++))
-                               return -EFAULT;
-                       if (stereo) {
-                               if (get_user(c, up++))
-                                       return -EFAULT;
-                               data = (data << 16) + c;
-                       } else
-                               data = (data << 16) + data;
-                       userCount--;
-                       bal += hSpeed;
-               }
-               *p++ = data;
-               frameLeft--;
-               bal -= sSpeed;
-       }
-       expand_bal = bal;
-       expand_data = data;
-       *frameUsed += (ftotal - frameLeft) * 4;
-       utotal -= userCount;
-       return stereo? utotal * 4: utotal * 2;
-}
-
-
-static ssize_t pmac_ctx_u16(const u_char __user *userPtr, size_t userCount,
-                           u_char frame[], ssize_t *frameUsed,
-                           ssize_t frameLeft)
-{
-       int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
-       unsigned int *p = (unsigned int *) &frame[*frameUsed];
-       unsigned int data = expand_data;
-       unsigned short __user *up = (unsigned short __user *) userPtr;
-       int bal = expand_bal;
-       int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
-       int stereo = dmasound.soft.stereo;
-       int utotal, ftotal;
-
-       frameLeft >>= 2;
-       userCount >>= (stereo? 2: 1);
-       ftotal = frameLeft;
-       utotal = userCount;
-       while (frameLeft) {
-               unsigned short c;
-               if (bal < 0) {
-                       if (userCount == 0)
-                               break;
-                       if (get_user(data, up++))
-                               return -EFAULT;
-                       data ^= mask;
-                       if (stereo) {
-                               if (get_user(c, up++))
-                                       return -EFAULT;
-                               data = (data << 16) + (c ^ mask);
-                       } else
-                               data = (data << 16) + data;
-                       userCount--;
-                       bal += hSpeed;
-               }
-               *p++ = data;
-               frameLeft--;
-               bal -= sSpeed;
-       }
-       expand_bal = bal;
-       expand_data = data;
-       *frameUsed += (ftotal - frameLeft) * 4;
-       utotal -= userCount;
-       return stereo? utotal * 4: utotal * 2;
-}
-
-/* data in routines... */
-
-static ssize_t pmac_ct_s8_read(const u_char __user *userPtr, size_t userCount,
-                         u_char frame[], ssize_t *frameUsed,
-                         ssize_t frameLeft)
-{
-       ssize_t count, used;
-       short *p = (short *) &frame[*frameUsed];
-       int val, stereo = dmasound.soft.stereo;
-
-       frameLeft >>= 2;
-       if (stereo)
-               userCount >>= 1;
-       used = count = min_t(unsigned long, userCount, frameLeft);
-       while (count > 0) {
-               u_char data;
-
-               val = *p++;
-               val = (val * software_input_volume) >> 7;
-               data = val >> 8;
-               if (put_user(data, (u_char __user *)userPtr++))
-                       return -EFAULT;
-               if (stereo) {
-                       val = *p;
-                       val = (val * software_input_volume) >> 7;
-                       data = val >> 8;
-                       if (put_user(data, (u_char __user *)userPtr++))
-                               return -EFAULT;
-               }
-               p++;
-               count--;
-       }
-       *frameUsed += used * 4;
-       return stereo? used * 2: used;
-}
-
-
-static ssize_t pmac_ct_u8_read(const u_char __user *userPtr, size_t userCount,
-                         u_char frame[], ssize_t *frameUsed,
-                         ssize_t frameLeft)
-{
-       ssize_t count, used;
-       short *p = (short *) &frame[*frameUsed];
-       int val, stereo = dmasound.soft.stereo;
-
-       frameLeft >>= 2;
-       if (stereo)
-               userCount >>= 1;
-       used = count = min_t(unsigned long, userCount, frameLeft);
-       while (count > 0) {
-               u_char data;
-
-               val = *p++;
-               val = (val * software_input_volume) >> 7;
-               data = (val >> 8) ^ 0x80;
-               if (put_user(data, (u_char __user *)userPtr++))
-                       return -EFAULT;
-               if (stereo) {
-                       val = *p;
-                       val = (val * software_input_volume) >> 7;
-                       data = (val >> 8) ^ 0x80;
-                       if (put_user(data, (u_char __user *)userPtr++))
-                               return -EFAULT;
-               }
-               p++;
-               count--;
-       }
-       *frameUsed += used * 4;
-       return stereo? used * 2: used;
-}
-
-static ssize_t pmac_ct_s16_read(const u_char __user *userPtr, size_t userCount,
-                          u_char frame[], ssize_t *frameUsed,
-                          ssize_t frameLeft)
-{
-       ssize_t count, used;
-       int stereo = dmasound.soft.stereo;
-       short *fp = (short *) &frame[*frameUsed];
-       short __user *up = (short __user *) userPtr;
-
-       frameLeft >>= 2;
-       userCount >>= (stereo? 2: 1);
-       used = count = min_t(unsigned long, userCount, frameLeft);
-       while (count > 0) {
-               short data;
-
-               data = *fp++;
-               data = (data * software_input_volume) >> 7;
-               if (put_user(data, up++))
-                       return -EFAULT;
-               if (stereo) {
-                       data = *fp;
-                       data = (data * software_input_volume) >> 7;
-                       if (put_user(data, up++))
-                               return -EFAULT;
-               }
-               fp++;
-               count--;
-       }
-       *frameUsed += used * 4;
-       return stereo? used * 4: used * 2;
-}
-
-static ssize_t pmac_ct_u16_read(const u_char __user *userPtr, size_t userCount,
-                          u_char frame[], ssize_t *frameUsed,
-                          ssize_t frameLeft)
-{
-       ssize_t count, used;
-       int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
-       int stereo = dmasound.soft.stereo;
-       short *fp = (short *) &frame[*frameUsed];
-       short __user *up = (short __user *) userPtr;
-
-       frameLeft >>= 2;
-       userCount >>= (stereo? 2: 1);
-       used = count = min_t(unsigned long, userCount, frameLeft);
-       while (count > 0) {
-               int data;
-
-               data = *fp++;
-               data = (data * software_input_volume) >> 7;
-               data ^= mask;
-               if (put_user(data, up++))
-                       return -EFAULT;
-               if (stereo) {
-                       data = *fp;
-                       data = (data * software_input_volume) >> 7;
-                       data ^= mask;
-                       if (put_user(data, up++))
-                               return -EFAULT;
-               }
-               fp++;
-               count--;
-       }
-       *frameUsed += used * 4;
-       return stereo? used * 4: used * 2;
-}
-
-/* data in routines (reducing speed)... */
-
-static ssize_t pmac_ctx_s8_read(const u_char __user *userPtr, size_t userCount,
-                         u_char frame[], ssize_t *frameUsed,
-                         ssize_t frameLeft)
-{
-       short *p = (short *) &frame[*frameUsed];
-       int bal = expand_read_bal;
-       int vall,valr, stereo = dmasound.soft.stereo;
-       int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
-       int utotal, ftotal;
-
-       frameLeft >>= 2;
-       if (stereo)
-               userCount >>= 1;
-       ftotal = frameLeft;
-       utotal = userCount;
-       while (frameLeft) {
-               u_char data;
-
-               if (bal<0 && userCount == 0)
-                       break;
-               vall = *p++;
-               vall = (vall * software_input_volume) >> 7;
-               if (stereo) {
-                       valr = *p;
-                       valr = (valr * software_input_volume) >> 7;
-               }
-               p++;
-               if (bal < 0) {
-                       data = vall >> 8;
-                       if (put_user(data, (u_char __user *)userPtr++))
-                               return -EFAULT;
-                       if (stereo) {
-                               data = valr >> 8;
-                               if (put_user(data, (u_char __user *)userPtr++))
-                                       return -EFAULT;
-                       }
-                       userCount--;
-                       bal += hSpeed;
-               }
-               frameLeft--;
-               bal -= sSpeed;
-       }
-       expand_read_bal=bal;
-       *frameUsed += (ftotal - frameLeft) * 4;
-       utotal -= userCount;
-       return stereo? utotal * 2: utotal;
-}
-
-
-static ssize_t pmac_ctx_u8_read(const u_char __user *userPtr, size_t userCount,
-                         u_char frame[], ssize_t *frameUsed,
-                         ssize_t frameLeft)
-{
-       short *p = (short *) &frame[*frameUsed];
-       int bal = expand_read_bal;
-       int vall,valr, stereo = dmasound.soft.stereo;
-       int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
-       int utotal, ftotal;
-
-       frameLeft >>= 2;
-       if (stereo)
-               userCount >>= 1;
-       ftotal = frameLeft;
-       utotal = userCount;
-       while (frameLeft) {
-               u_char data;
-
-               if (bal<0 && userCount == 0)
-                       break;
-
-               vall = *p++;
-               vall = (vall * software_input_volume) >> 7;
-               if (stereo) {
-                       valr = *p;
-                       valr = (valr * software_input_volume) >> 7;
-               }
-               p++;
-               if (bal < 0) {
-                       data = (vall >> 8) ^ 0x80;
-                       if (put_user(data, (u_char __user *)userPtr++))
-                               return -EFAULT;
-                       if (stereo) {
-                               data = (valr >> 8) ^ 0x80;
-                               if (put_user(data, (u_char __user *)userPtr++))
-                                       return -EFAULT;
-                       }
-                       userCount--;
-                       bal += hSpeed;
-               }
-               frameLeft--;
-               bal -= sSpeed;
-       }
-       expand_read_bal=bal;
-       *frameUsed += (ftotal - frameLeft) * 4;
-       utotal -= userCount;
-       return stereo? utotal * 2: utotal;
-}
-
-static ssize_t pmac_ctx_s16_read(const u_char __user *userPtr, size_t userCount,
-                          u_char frame[], ssize_t *frameUsed,
-                          ssize_t frameLeft)
-{
-       int bal = expand_read_bal;
-       short *fp = (short *) &frame[*frameUsed];
-       short __user *up = (short __user *) userPtr;
-       int stereo = dmasound.soft.stereo;
-       int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
-       int utotal, ftotal;
-
-       frameLeft >>= 2;
-       userCount >>= (stereo? 2: 1);
-       ftotal = frameLeft;
-       utotal = userCount;
-       while (frameLeft) {
-               int datal,datar;
-
-               if (bal<0 && userCount == 0)
-                       break;
-
-               datal = *fp++;
-               datal = (datal * software_input_volume) >> 7;
-               if (stereo) {
-                       datar = *fp;
-                       datar = (datar * software_input_volume) >> 7;
-               }
-               fp++;
-               if (bal < 0) {
-                       if (put_user(datal, up++))
-                               return -EFAULT;
-                       if (stereo) {
-                               if (put_user(datar, up++))
-                                       return -EFAULT;
-                       }
-                       userCount--;
-                       bal += hSpeed;
-               }
-               frameLeft--;
-               bal -= sSpeed;
-       }
-       expand_read_bal=bal;
-       *frameUsed += (ftotal - frameLeft) * 4;
-       utotal -= userCount;
-       return stereo? utotal * 4: utotal * 2;
-}
-
-static ssize_t pmac_ctx_u16_read(const u_char __user *userPtr, size_t userCount,
-                          u_char frame[], ssize_t *frameUsed,
-                          ssize_t frameLeft)
-{
-       int bal = expand_read_bal;
-       int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
-       short *fp = (short *) &frame[*frameUsed];
-       short __user *up = (short __user *) userPtr;
-       int stereo = dmasound.soft.stereo;
-       int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
-       int utotal, ftotal;
-
-       frameLeft >>= 2;
-       userCount >>= (stereo? 2: 1);
-       ftotal = frameLeft;
-       utotal = userCount;
-       while (frameLeft) {
-               int datal,datar;
-
-               if (bal<0 && userCount == 0)
-                       break;
-
-               datal = *fp++;
-               datal = (datal * software_input_volume) >> 7;
-               datal ^= mask;
-               if (stereo) {
-                       datar = *fp;
-                       datar = (datar * software_input_volume) >> 7;
-                       datar ^= mask;
-               }
-               fp++;
-               if (bal < 0) {
-                       if (put_user(datal, up++))
-                               return -EFAULT;
-                       if (stereo) {
-                               if (put_user(datar, up++))
-                                       return -EFAULT;
-                       }
-                       userCount--;
-                       bal += hSpeed;
-               }
-               frameLeft--;
-               bal -= sSpeed;
-       }
-       expand_read_bal=bal;
-       *frameUsed += (ftotal - frameLeft) * 4;
-       utotal -= userCount;
-       return stereo? utotal * 4: utotal * 2;
-}
-
-
-TRANS transAwacsNormal = {
-       .ct_ulaw=       pmac_ct_law,
-       .ct_alaw=       pmac_ct_law,
-       .ct_s8=         pmac_ct_s8,
-       .ct_u8=         pmac_ct_u8,
-       .ct_s16be=      pmac_ct_s16,
-       .ct_u16be=      pmac_ct_u16,
-       .ct_s16le=      pmac_ct_s16,
-       .ct_u16le=      pmac_ct_u16,
-};
-
-TRANS transAwacsExpand = {
-       .ct_ulaw=       pmac_ctx_law,
-       .ct_alaw=       pmac_ctx_law,
-       .ct_s8=         pmac_ctx_s8,
-       .ct_u8=         pmac_ctx_u8,
-       .ct_s16be=      pmac_ctx_s16,
-       .ct_u16be=      pmac_ctx_u16,
-       .ct_s16le=      pmac_ctx_s16,
-       .ct_u16le=      pmac_ctx_u16,
-};
-
-TRANS transAwacsNormalRead = {
-       .ct_s8=         pmac_ct_s8_read,
-       .ct_u8=         pmac_ct_u8_read,
-       .ct_s16be=      pmac_ct_s16_read,
-       .ct_u16be=      pmac_ct_u16_read,
-       .ct_s16le=      pmac_ct_s16_read,
-       .ct_u16le=      pmac_ct_u16_read,
-};
-
-TRANS transAwacsExpandRead = {
-       .ct_s8=         pmac_ctx_s8_read,
-       .ct_u8=         pmac_ctx_u8_read,
-       .ct_s16be=      pmac_ctx_s16_read,
-       .ct_u16be=      pmac_ctx_u16_read,
-       .ct_s16le=      pmac_ctx_s16_read,
-       .ct_u16le=      pmac_ctx_u16_read,
-};
-
-/* translation tables */
-/* 16 bit mu-law */
-
-static short dmasound_ulaw2dma16[] = {
-       -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
-       -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
-       -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
-       -11900, -11388, -10876, -10364, -9852,  -9340,  -8828,  -8316,
-       -7932,  -7676,  -7420,  -7164,  -6908,  -6652,  -6396,  -6140,
-       -5884,  -5628,  -5372,  -5116,  -4860,  -4604,  -4348,  -4092,
-       -3900,  -3772,  -3644,  -3516,  -3388,  -3260,  -3132,  -3004,
-       -2876,  -2748,  -2620,  -2492,  -2364,  -2236,  -2108,  -1980,
-       -1884,  -1820,  -1756,  -1692,  -1628,  -1564,  -1500,  -1436,
-       -1372,  -1308,  -1244,  -1180,  -1116,  -1052,  -988,   -924,
-       -876,   -844,   -812,   -780,   -748,   -716,   -684,   -652,
-       -620,   -588,   -556,   -524,   -492,   -460,   -428,   -396,
-       -372,   -356,   -340,   -324,   -308,   -292,   -276,   -260,
-       -244,   -228,   -212,   -196,   -180,   -164,   -148,   -132,
-       -120,   -112,   -104,   -96,    -88,    -80,    -72,    -64,
-       -56,    -48,    -40,    -32,    -24,    -16,    -8,     0,
-       32124,  31100,  30076,  29052,  28028,  27004,  25980,  24956,
-       23932,  22908,  21884,  20860,  19836,  18812,  17788,  16764,
-       15996,  15484,  14972,  14460,  13948,  13436,  12924,  12412,
-       11900,  11388,  10876,  10364,  9852,   9340,   8828,   8316,
-       7932,   7676,   7420,   7164,   6908,   6652,   6396,   6140,
-       5884,   5628,   5372,   5116,   4860,   4604,   4348,   4092,
-       3900,   3772,   3644,   3516,   3388,   3260,   3132,   3004,
-       2876,   2748,   2620,   2492,   2364,   2236,   2108,   1980,
-       1884,   1820,   1756,   1692,   1628,   1564,   1500,   1436,
-       1372,   1308,   1244,   1180,   1116,   1052,   988,    924,
-       876,    844,    812,    780,    748,    716,    684,    652,
-       620,    588,    556,    524,    492,    460,    428,    396,
-       372,    356,    340,    324,    308,    292,    276,    260,
-       244,    228,    212,    196,    180,    164,    148,    132,
-       120,    112,    104,    96,     88,     80,     72,     64,
-       56,     48,     40,     32,     24,     16,     8,      0,
-};
-
-/* 16 bit A-law */
-
-static short dmasound_alaw2dma16[] = {
-       -5504,  -5248,  -6016,  -5760,  -4480,  -4224,  -4992,  -4736,
-       -7552,  -7296,  -8064,  -7808,  -6528,  -6272,  -7040,  -6784,
-       -2752,  -2624,  -3008,  -2880,  -2240,  -2112,  -2496,  -2368,
-       -3776,  -3648,  -4032,  -3904,  -3264,  -3136,  -3520,  -3392,
-       -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
-       -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
-       -11008, -10496, -12032, -11520, -8960,  -8448,  -9984,  -9472,
-       -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
-       -344,   -328,   -376,   -360,   -280,   -264,   -312,   -296,
-       -472,   -456,   -504,   -488,   -408,   -392,   -440,   -424,
-       -88,    -72,    -120,   -104,   -24,    -8,     -56,    -40,
-       -216,   -200,   -248,   -232,   -152,   -136,   -184,   -168,
-       -1376,  -1312,  -1504,  -1440,  -1120,  -1056,  -1248,  -1184,
-       -1888,  -1824,  -2016,  -1952,  -1632,  -1568,  -1760,  -1696,
-       -688,   -656,   -752,   -720,   -560,   -528,   -624,   -592,
-       -944,   -912,   -1008,  -976,   -816,   -784,   -880,   -848,
-       5504,   5248,   6016,   5760,   4480,   4224,   4992,   4736,
-       7552,   7296,   8064,   7808,   6528,   6272,   7040,   6784,
-       2752,   2624,   3008,   2880,   2240,   2112,   2496,   2368,
-       3776,   3648,   4032,   3904,   3264,   3136,   3520,   3392,
-       22016,  20992,  24064,  23040,  17920,  16896,  19968,  18944,
-       30208,  29184,  32256,  31232,  26112,  25088,  28160,  27136,
-       11008,  10496,  12032,  11520,  8960,   8448,   9984,   9472,
-       15104,  14592,  16128,  15616,  13056,  12544,  14080,  13568,
-       344,    328,    376,    360,    280,    264,    312,    296,
-       472,    456,    504,    488,    408,    392,    440,    424,
-       88,     72,     120,    104,    24,     8,      56,     40,
-       216,    200,    248,    232,    152,    136,    184,    168,
-       1376,   1312,   1504,   1440,   1120,   1056,   1248,   1184,
-       1888,   1824,   2016,   1952,   1632,   1568,   1760,   1696,
-       688,    656,    752,    720,    560,    528,    624,    592,
-       944,    912,    1008,   976,    816,    784,    880,    848,
-};
diff --git a/sound/oss/es1371.c b/sound/oss/es1371.c
deleted file mode 100644 (file)
index 5264857..0000000
+++ /dev/null
@@ -1,3131 +0,0 @@
-/*****************************************************************************/
-
-/*
- *      es1371.c  --  Creative Ensoniq ES1371.
- *
- *      Copyright (C) 1998-2001, 2003  Thomas Sailer (t.sailer@alumni.ethz.ch)
- *
- *      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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Special thanks to Ensoniq
- *
- *  Supported devices:
- *  /dev/dsp    standard /dev/dsp device, (mostly) OSS compatible
- *  /dev/mixer  standard /dev/mixer device, (mostly) OSS compatible
- *  /dev/dsp1   additional DAC, like /dev/dsp, but outputs to mixer "SYNTH" setting
- *  /dev/midi   simple MIDI UART interface, no ioctl
- *
- *  NOTE: the card does not have any FM/Wavetable synthesizer, it is supposed
- *  to be done in software. That is what /dev/dac is for. By now (Q2 1998)
- *  there are several MIDI to PCM (WAV) packages, one of them is timidity.
- *
- *  Revision history
- *    04.06.1998   0.1   Initial release
- *                       Mixer stuff should be overhauled; especially optional AC97 mixer bits
- *                       should be detected. This results in strange behaviour of some mixer
- *                       settings, like master volume and mic.
- *    08.06.1998   0.2   First release using Alan Cox' soundcore instead of miscdevice
- *    03.08.1998   0.3   Do not include modversions.h
- *                       Now mixer behaviour can basically be selected between
- *                       "OSS documented" and "OSS actual" behaviour
- *    31.08.1998   0.4   Fix realplayer problems - dac.count issues
- *    27.10.1998   0.5   Fix joystick support
- *                       -- Oliver Neukum (c188@org.chemie.uni-muenchen.de)
- *    10.12.1998   0.6   Fix drain_dac trying to wait on not yet initialized DMA
- *    23.12.1998   0.7   Fix a few f_file & FMODE_ bugs
- *                       Don't wake up app until there are fragsize bytes to read/write
- *    06.01.1999   0.8   remove the silly SA_INTERRUPT flag.
- *                       hopefully killed the egcs section type conflict
- *    12.03.1999   0.9   cinfo.blocks should be reset after GETxPTR ioctl.
- *                       reported by Johan Maes <joma@telindus.be>
- *    22.03.1999   0.10  return EAGAIN instead of EBUSY when O_NONBLOCK
- *                       read/write cannot be executed
- *    07.04.1999   0.11  implemented the following ioctl's: SOUND_PCM_READ_RATE, 
- *                       SOUND_PCM_READ_CHANNELS, SOUND_PCM_READ_BITS; 
- *                       Alpha fixes reported by Peter Jones <pjones@redhat.com>
- *                       Another Alpha fix (wait_src_ready in init routine)
- *                       reported by "Ivan N. Kokshaysky" <ink@jurassic.park.msu.ru>
- *                       Note: joystick address handling might still be wrong on archs
- *                       other than i386
- *    15.06.1999   0.12  Fix bad allocation bug.
- *                       Thanks to Deti Fliegl <fliegl@in.tum.de>
- *    28.06.1999   0.13  Add pci_set_master
- *    03.08.1999   0.14  adapt to Linus' new __setup/__initcall
- *                       added kernel command line option "es1371=joystickaddr"
- *                       removed CONFIG_SOUND_ES1371_JOYPORT_BOOT kludge
- *    10.08.1999   0.15  (Re)added S/PDIF module option for cards revision >= 4.
- *                       Initial version by Dave Platt <dplatt@snulbug.mtview.ca.us>.
- *                       module_init/__setup fixes
- *    08.16.1999   0.16  Joe Cotellese <joec@ensoniq.com>
- *                       Added detection for ES1371 revision ID so that we can
- *                       detect the ES1373 and later parts.
- *                       added AC97 #defines for readability
- *                       added a /proc file system for dumping hardware state
- *                       updated SRC and CODEC w/r functions to accommodate bugs
- *                       in some versions of the ES137x chips.
- *    31.08.1999   0.17  add spin_lock_init
- *                       replaced current->state = x with set_current_state(x)
- *    03.09.1999   0.18  change read semantics for MIDI to match
- *                       OSS more closely; remove possible wakeup race
- *    21.10.1999   0.19  Round sampling rates, requested by
- *                       Kasamatsu Kenichi <t29w0267@ip.media.kyoto-u.ac.jp>
- *    27.10.1999   0.20  Added SigmaTel 3D enhancement string
- *                       Codec ID printing changes
- *    28.10.1999   0.21  More waitqueue races fixed
- *                       Joe Cotellese <joec@ensoniq.com>
- *                       Changed PCI detection routine so we can more easily
- *                       detect ES137x chip and derivatives.
- *    05.01.2000   0.22  Should now work with rev7 boards; patch by
- *                       Eric Lemar, elemar@cs.washington.edu
- *    08.01.2000   0.23  Prevent some ioctl's from returning bad count values on underrun/overrun;
- *                       Tim Janik's BSE (Bedevilled Sound Engine) found this
- *    07.02.2000   0.24  Use pci_alloc_consistent and pci_register_driver
- *    07.02.2000   0.25  Use ac97_codec
- *    01.03.2000   0.26  SPDIF patch by Mikael Bouillot <mikael.bouillot@bigfoot.com>
- *                       Use pci_module_init
- *    21.11.2000   0.27  Initialize dma buffers in poll, otherwise poll may return a bogus mask
- *    12.12.2000   0.28  More dma buffer initializations, patch from
- *                       Tjeerd Mulder <tjeerd.mulder@fujitsu-siemens.com>
- *    05.01.2001   0.29  Hopefully updates will not be required anymore when Creative bumps
- *                       the CT5880 revision.
- *                       suggested by Stephan Müller <smueller@chronox.de>
- *    31.01.2001   0.30  Register/Unregister gameport
- *                       Fix SETTRIGGER non OSS API conformity
- *    14.07.2001   0.31  Add list of laptops needing amplifier control
- *    03.01.2003   0.32  open_mode fixes from Georg Acher <acher@in.tum.de>
- */
-
-/*****************************************************************************/
-      
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/bitops.h>
-#include <linux/proc_fs.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-#include <linux/ac97_codec.h>
-#include <linux/gameport.h>
-#include <linux/wait.h>
-#include <linux/dma-mapping.h>
-#include <linux/mutex.h>
-#include <linux/mm.h>
-#include <linux/kernel.h>
-
-#include <asm/io.h>
-#include <asm/page.h>
-#include <asm/uaccess.h>
-
-#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-#define SUPPORT_JOYSTICK
-#endif
-
-/* --------------------------------------------------------------------- */
-
-#undef OSS_DOCUMENTED_MIXER_SEMANTICS
-#define ES1371_DEBUG
-#define DBG(x) {}
-/*#define DBG(x) {x}*/
-
-/* --------------------------------------------------------------------- */
-
-#ifndef PCI_VENDOR_ID_ENSONIQ
-#define PCI_VENDOR_ID_ENSONIQ        0x1274    
-#endif
-
-#ifndef PCI_VENDOR_ID_ECTIVA
-#define PCI_VENDOR_ID_ECTIVA         0x1102
-#endif
-
-#ifndef PCI_DEVICE_ID_ENSONIQ_ES1371
-#define PCI_DEVICE_ID_ENSONIQ_ES1371 0x1371
-#endif
-
-#ifndef PCI_DEVICE_ID_ENSONIQ_CT5880
-#define PCI_DEVICE_ID_ENSONIQ_CT5880 0x5880
-#endif
-
-#ifndef PCI_DEVICE_ID_ECTIVA_EV1938
-#define PCI_DEVICE_ID_ECTIVA_EV1938 0x8938
-#endif
-
-/* ES1371 chip ID */
-/* This is a little confusing because all ES1371 compatible chips have the
-   same DEVICE_ID, the only thing differentiating them is the REV_ID field.
-   This is only significant if you want to enable features on the later parts.
-   Yes, I know it's stupid and why didn't we use the sub IDs?
-*/
-#define ES1371REV_ES1373_A  0x04
-#define ES1371REV_ES1373_B  0x06
-#define ES1371REV_CT5880_A  0x07
-#define CT5880REV_CT5880_C  0x02
-#define CT5880REV_CT5880_D  0x03
-#define ES1371REV_ES1371_B  0x09
-#define EV1938REV_EV1938_A  0x00
-#define ES1371REV_ES1373_8  0x08
-
-#define ES1371_MAGIC  ((PCI_VENDOR_ID_ENSONIQ<<16)|PCI_DEVICE_ID_ENSONIQ_ES1371)
-
-#define ES1371_EXTENT             0x40
-#define JOY_EXTENT                8
-
-#define ES1371_REG_CONTROL        0x00
-#define ES1371_REG_STATUS         0x04 /* on the 5880 it is control/status */
-#define ES1371_REG_UART_DATA      0x08
-#define ES1371_REG_UART_STATUS    0x09
-#define ES1371_REG_UART_CONTROL   0x09
-#define ES1371_REG_UART_TEST      0x0a
-#define ES1371_REG_MEMPAGE        0x0c
-#define ES1371_REG_SRCONV         0x10
-#define ES1371_REG_CODEC          0x14
-#define ES1371_REG_LEGACY         0x18
-#define ES1371_REG_SERIAL_CONTROL 0x20
-#define ES1371_REG_DAC1_SCOUNT    0x24
-#define ES1371_REG_DAC2_SCOUNT    0x28
-#define ES1371_REG_ADC_SCOUNT     0x2c
-
-#define ES1371_REG_DAC1_FRAMEADR  0xc30
-#define ES1371_REG_DAC1_FRAMECNT  0xc34
-#define ES1371_REG_DAC2_FRAMEADR  0xc38
-#define ES1371_REG_DAC2_FRAMECNT  0xc3c
-#define ES1371_REG_ADC_FRAMEADR   0xd30
-#define ES1371_REG_ADC_FRAMECNT   0xd34
-
-#define ES1371_FMT_U8_MONO     0
-#define ES1371_FMT_U8_STEREO   1
-#define ES1371_FMT_S16_MONO    2
-#define ES1371_FMT_S16_STEREO  3
-#define ES1371_FMT_STEREO      1
-#define ES1371_FMT_S16         2
-#define ES1371_FMT_MASK        3
-
-static const unsigned sample_size[] = { 1, 2, 2, 4 };
-static const unsigned sample_shift[] = { 0, 1, 1, 2 };
-
-#define CTRL_RECEN_B    0x08000000  /* 1 = don't mix analog in to digital out */
-#define CTRL_SPDIFEN_B  0x04000000
-#define CTRL_JOY_SHIFT  24
-#define CTRL_JOY_MASK   3
-#define CTRL_JOY_200    0x00000000  /* joystick base address */
-#define CTRL_JOY_208    0x01000000
-#define CTRL_JOY_210    0x02000000
-#define CTRL_JOY_218    0x03000000
-#define CTRL_GPIO_IN0   0x00100000  /* general purpose inputs/outputs */
-#define CTRL_GPIO_IN1   0x00200000
-#define CTRL_GPIO_IN2   0x00400000
-#define CTRL_GPIO_IN3   0x00800000
-#define CTRL_GPIO_OUT0  0x00010000
-#define CTRL_GPIO_OUT1  0x00020000
-#define CTRL_GPIO_OUT2  0x00040000
-#define CTRL_GPIO_OUT3  0x00080000
-#define CTRL_MSFMTSEL   0x00008000  /* MPEG serial data fmt: 0 = Sony, 1 = I2S */
-#define CTRL_SYNCRES    0x00004000  /* AC97 warm reset */
-#define CTRL_ADCSTOP    0x00002000  /* stop ADC transfers */
-#define CTRL_PWR_INTRM  0x00001000  /* 1 = power level ints enabled */
-#define CTRL_M_CB       0x00000800  /* recording source: 0 = ADC, 1 = MPEG */
-#define CTRL_CCB_INTRM  0x00000400  /* 1 = CCB "voice" ints enabled */
-#define CTRL_PDLEV0     0x00000000  /* power down level */
-#define CTRL_PDLEV1     0x00000100
-#define CTRL_PDLEV2     0x00000200
-#define CTRL_PDLEV3     0x00000300
-#define CTRL_BREQ       0x00000080  /* 1 = test mode (internal mem test) */
-#define CTRL_DAC1_EN    0x00000040  /* enable DAC1 */
-#define CTRL_DAC2_EN    0x00000020  /* enable DAC2 */
-#define CTRL_ADC_EN     0x00000010  /* enable ADC */
-#define CTRL_UART_EN    0x00000008  /* enable MIDI uart */
-#define CTRL_JYSTK_EN   0x00000004  /* enable Joystick port */
-#define CTRL_XTALCLKDIS 0x00000002  /* 1 = disable crystal clock input */
-#define CTRL_PCICLKDIS  0x00000001  /* 1 = disable PCI clock distribution */
-
-
-#define STAT_INTR       0x80000000  /* wired or of all interrupt bits */
-#define CSTAT_5880_AC97_RST 0x20000000 /* CT5880 Reset bit */
-#define STAT_EN_SPDIF   0x00040000  /* enable S/PDIF circuitry */
-#define STAT_TS_SPDIF   0x00020000  /* test S/PDIF circuitry */
-#define STAT_TESTMODE   0x00010000  /* test ASIC */
-#define STAT_SYNC_ERR   0x00000100  /* 1 = codec sync error */
-#define STAT_VC         0x000000c0  /* CCB int source, 0=DAC1, 1=DAC2, 2=ADC, 3=undef */
-#define STAT_SH_VC      6
-#define STAT_MPWR       0x00000020  /* power level interrupt */
-#define STAT_MCCB       0x00000010  /* CCB int pending */
-#define STAT_UART       0x00000008  /* UART int pending */
-#define STAT_DAC1       0x00000004  /* DAC1 int pending */
-#define STAT_DAC2       0x00000002  /* DAC2 int pending */
-#define STAT_ADC        0x00000001  /* ADC int pending */
-
-#define USTAT_RXINT     0x80        /* UART rx int pending */
-#define USTAT_TXINT     0x04        /* UART tx int pending */
-#define USTAT_TXRDY     0x02        /* UART tx ready */
-#define USTAT_RXRDY     0x01        /* UART rx ready */
-
-#define UCTRL_RXINTEN   0x80        /* 1 = enable RX ints */
-#define UCTRL_TXINTEN   0x60        /* TX int enable field mask */
-#define UCTRL_ENA_TXINT 0x20        /* enable TX int */
-#define UCTRL_CNTRL     0x03        /* control field */
-#define UCTRL_CNTRL_SWR 0x03        /* software reset command */
-
-/* sample rate converter */
-#define SRC_OKSTATE        1
-
-#define SRC_RAMADDR_MASK   0xfe000000
-#define SRC_RAMADDR_SHIFT  25
-#define SRC_DAC1FREEZE     (1UL << 21)
-#define SRC_DAC2FREEZE      (1UL << 20)
-#define SRC_ADCFREEZE      (1UL << 19)
-
-
-#define SRC_WE             0x01000000  /* read/write control for SRC RAM */
-#define SRC_BUSY           0x00800000  /* SRC busy */
-#define SRC_DIS            0x00400000  /* 1 = disable SRC */
-#define SRC_DDAC1          0x00200000  /* 1 = disable accum update for DAC1 */
-#define SRC_DDAC2          0x00100000  /* 1 = disable accum update for DAC2 */
-#define SRC_DADC           0x00080000  /* 1 = disable accum update for ADC2 */
-#define SRC_CTLMASK        0x00780000
-#define SRC_RAMDATA_MASK   0x0000ffff
-#define SRC_RAMDATA_SHIFT  0
-
-#define SRCREG_ADC      0x78
-#define SRCREG_DAC1     0x70
-#define SRCREG_DAC2     0x74
-#define SRCREG_VOL_ADC  0x6c
-#define SRCREG_VOL_DAC1 0x7c
-#define SRCREG_VOL_DAC2 0x7e
-
-#define SRCREG_TRUNC_N     0x00
-#define SRCREG_INT_REGS    0x01
-#define SRCREG_ACCUM_FRAC  0x02
-#define SRCREG_VFREQ_FRAC  0x03
-
-#define CODEC_PIRD        0x00800000  /* 0 = write AC97 register */
-#define CODEC_PIADD_MASK  0x007f0000
-#define CODEC_PIADD_SHIFT 16
-#define CODEC_PIDAT_MASK  0x0000ffff
-#define CODEC_PIDAT_SHIFT 0
-
-#define CODEC_RDY         0x80000000  /* AC97 read data valid */
-#define CODEC_WIP         0x40000000  /* AC97 write in progress */
-#define CODEC_PORD        0x00800000  /* 0 = write AC97 register */
-#define CODEC_POADD_MASK  0x007f0000
-#define CODEC_POADD_SHIFT 16
-#define CODEC_PODAT_MASK  0x0000ffff
-#define CODEC_PODAT_SHIFT 0
-
-
-#define LEGACY_JFAST      0x80000000  /* fast joystick timing */
-#define LEGACY_FIRQ       0x01000000  /* force IRQ */
-
-#define SCTRL_DACTEST     0x00400000  /* 1 = DAC test, test vector generation purposes */
-#define SCTRL_P2ENDINC    0x00380000  /*  */
-#define SCTRL_SH_P2ENDINC 19
-#define SCTRL_P2STINC     0x00070000  /*  */
-#define SCTRL_SH_P2STINC  16
-#define SCTRL_R1LOOPSEL   0x00008000  /* 0 = loop mode */
-#define SCTRL_P2LOOPSEL   0x00004000  /* 0 = loop mode */
-#define SCTRL_P1LOOPSEL   0x00002000  /* 0 = loop mode */
-#define SCTRL_P2PAUSE     0x00001000  /* 1 = pause mode */
-#define SCTRL_P1PAUSE     0x00000800  /* 1 = pause mode */
-#define SCTRL_R1INTEN     0x00000400  /* enable interrupt */
-#define SCTRL_P2INTEN     0x00000200  /* enable interrupt */
-#define SCTRL_P1INTEN     0x00000100  /* enable interrupt */
-#define SCTRL_P1SCTRLD    0x00000080  /* reload sample count register for DAC1 */
-#define SCTRL_P2DACSEN    0x00000040  /* 1 = DAC2 play back last sample when disabled */
-#define SCTRL_R1SEB       0x00000020  /* 1 = 16bit */
-#define SCTRL_R1SMB       0x00000010  /* 1 = stereo */
-#define SCTRL_R1FMT       0x00000030  /* format mask */
-#define SCTRL_SH_R1FMT    4
-#define SCTRL_P2SEB       0x00000008  /* 1 = 16bit */
-#define SCTRL_P2SMB       0x00000004  /* 1 = stereo */
-#define SCTRL_P2FMT       0x0000000c  /* format mask */
-#define SCTRL_SH_P2FMT    2
-#define SCTRL_P1SEB       0x00000002  /* 1 = 16bit */
-#define SCTRL_P1SMB       0x00000001  /* 1 = stereo */
-#define SCTRL_P1FMT       0x00000003  /* format mask */
-#define SCTRL_SH_P1FMT    0
-
-
-/* misc stuff */
-#define POLL_COUNT   0x1000
-#define FMODE_DAC         4           /* slight misuse of mode_t */
-
-/* MIDI buffer sizes */
-
-#define MIDIINBUF  256
-#define MIDIOUTBUF 256
-
-#define FMODE_MIDI_SHIFT 3
-#define FMODE_MIDI_READ  (FMODE_READ << FMODE_MIDI_SHIFT)
-#define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT)
-
-#define ES1371_MODULE_NAME "es1371"
-#define PFX ES1371_MODULE_NAME ": "
-
-/* --------------------------------------------------------------------- */
-
-struct es1371_state {
-       /* magic */
-       unsigned int magic;
-
-       /* list of es1371 devices */
-       struct list_head devs;
-
-       /* the corresponding pci_dev structure */
-       struct pci_dev *dev;
-
-       /* soundcore stuff */
-       int dev_audio;
-       int dev_dac;
-       int dev_midi;
-       
-       /* hardware resources */
-       unsigned long io; /* long for SPARC */
-       unsigned int irq;
-
-       /* PCI ID's */
-       u16 vendor;
-       u16 device;
-        u8 rev; /* the chip revision */
-
-       /* options */
-       int spdif_volume; /* S/PDIF output is enabled if != -1 */
-
-#ifdef ES1371_DEBUG
-        /* debug /proc entry */
-       struct proc_dir_entry *ps;
-#endif /* ES1371_DEBUG */
-
-       struct ac97_codec *codec;
-
-       /* wave stuff */
-       unsigned ctrl;
-       unsigned sctrl;
-       unsigned dac1rate, dac2rate, adcrate;
-
-       spinlock_t lock;
-       struct mutex open_mutex;
-       mode_t open_mode;
-       wait_queue_head_t open_wait;
-
-       struct dmabuf {
-               void *rawbuf;
-               dma_addr_t dmaaddr;
-               unsigned buforder;
-               unsigned numfrag;
-               unsigned fragshift;
-               unsigned hwptr, swptr;
-               unsigned total_bytes;
-               int count;
-               unsigned error; /* over/underrun */
-               wait_queue_head_t wait;
-               /* redundant, but makes calculations easier */
-               unsigned fragsize;
-               unsigned dmasize;
-               unsigned fragsamples;
-               /* OSS stuff */
-               unsigned mapped:1;
-               unsigned ready:1;
-               unsigned endcleared:1;
-               unsigned enabled:1;
-               unsigned ossfragshift;
-               int ossmaxfrags;
-               unsigned subdivision;
-       } dma_dac1, dma_dac2, dma_adc;
-
-       /* midi stuff */
-       struct {
-               unsigned ird, iwr, icnt;
-               unsigned ord, owr, ocnt;
-               wait_queue_head_t iwait;
-               wait_queue_head_t owait;
-               unsigned char ibuf[MIDIINBUF];
-               unsigned char obuf[MIDIOUTBUF];
-       } midi;
-
-#ifdef SUPPORT_JOYSTICK
-       struct gameport *gameport;
-#endif
-
-       struct mutex sem;
-};
-
-/* --------------------------------------------------------------------- */
-
-static LIST_HEAD(devs);
-
-/* --------------------------------------------------------------------- */
-
-static inline unsigned ld2(unsigned int x)
-{
-       unsigned r = 0;
-       
-       if (x >= 0x10000) {
-               x >>= 16;
-               r += 16;
-       }
-       if (x >= 0x100) {
-               x >>= 8;
-               r += 8;
-       }
-       if (x >= 0x10) {
-               x >>= 4;
-               r += 4;
-       }
-       if (x >= 4) {
-               x >>= 2;
-               r += 2;
-       }
-       if (x >= 2)
-               r++;
-       return r;
-}
-
-/* --------------------------------------------------------------------- */
-
-static unsigned wait_src_ready(struct es1371_state *s)
-{
-       unsigned int t, r;
-
-       for (t = 0; t < POLL_COUNT; t++) {
-               if (!((r = inl(s->io + ES1371_REG_SRCONV)) & SRC_BUSY))
-                       return r;
-               udelay(1);
-       }
-       printk(KERN_DEBUG PFX "sample rate converter timeout r = 0x%08x\n", r);
-       return r;
-}
-
-static unsigned src_read(struct es1371_state *s, unsigned reg)
-{
-        unsigned int temp,i,orig;
-
-        /* wait for ready */
-        temp = wait_src_ready (s);
-
-        /* we can only access the SRC at certain times, make sure
-           we're allowed to before we read */
-           
-        orig = temp;
-        /* expose the SRC state bits */
-        outl ( (temp & SRC_CTLMASK) | (reg << SRC_RAMADDR_SHIFT) | 0x10000UL,
-               s->io + ES1371_REG_SRCONV);
-
-        /* now, wait for busy and the correct time to read */
-        temp = wait_src_ready (s);
-
-        if ( (temp & 0x00870000UL ) != ( SRC_OKSTATE << 16 )){
-                /* wait for the right state */
-                for (i=0; i<POLL_COUNT; i++){
-                        temp = inl (s->io + ES1371_REG_SRCONV);
-                        if ( (temp & 0x00870000UL ) == ( SRC_OKSTATE << 16 ))
-                                break;
-                }
-        }
-
-        /* hide the state bits */
-        outl ((orig & SRC_CTLMASK) | (reg << SRC_RAMADDR_SHIFT), s->io + ES1371_REG_SRCONV);
-        return temp;
-                        
-                
-}
-
-static void src_write(struct es1371_state *s, unsigned reg, unsigned data)
-{
-      
-       unsigned int r;
-
-       r = wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DDAC2 | SRC_DADC);
-       r |= (reg << SRC_RAMADDR_SHIFT) & SRC_RAMADDR_MASK;
-       r |= (data << SRC_RAMDATA_SHIFT) & SRC_RAMDATA_MASK;
-       outl(r | SRC_WE, s->io + ES1371_REG_SRCONV);
-
-}
-
-/* --------------------------------------------------------------------- */
-
-/* most of the following here is black magic */
-static void set_adc_rate(struct es1371_state *s, unsigned rate)
-{
-       unsigned long flags;
-       unsigned int n, truncm, freq;
-
-       if (rate > 48000)
-               rate = 48000;
-       if (rate < 4000)
-               rate = 4000;
-       n = rate / 3000;
-       if ((1 << n) & ((1 << 15) | (1 << 13) | (1 << 11) | (1 << 9)))
-               n--;
-       truncm = (21 * n - 1) | 1;
-        freq = ((48000UL << 15) / rate) * n;
-       s->adcrate = (48000UL << 15) / (freq / n);
-       spin_lock_irqsave(&s->lock, flags);
-       if (rate >= 24000) {
-               if (truncm > 239)
-                       truncm = 239;
-               src_write(s, SRCREG_ADC+SRCREG_TRUNC_N, 
-                         (((239 - truncm) >> 1) << 9) | (n << 4));
-       } else {
-               if (truncm > 119)
-                       truncm = 119;
-               src_write(s, SRCREG_ADC+SRCREG_TRUNC_N, 
-                         0x8000 | (((119 - truncm) >> 1) << 9) | (n << 4));
-       }               
-       src_write(s, SRCREG_ADC+SRCREG_INT_REGS, 
-                 (src_read(s, SRCREG_ADC+SRCREG_INT_REGS) & 0x00ff) |
-                 ((freq >> 5) & 0xfc00));
-       src_write(s, SRCREG_ADC+SRCREG_VFREQ_FRAC, freq & 0x7fff);
-       src_write(s, SRCREG_VOL_ADC, n << 8);
-       src_write(s, SRCREG_VOL_ADC+1, n << 8);
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-
-static void set_dac1_rate(struct es1371_state *s, unsigned rate)
-{
-       unsigned long flags;
-       unsigned int freq, r;
-
-       if (rate > 48000)
-               rate = 48000;
-       if (rate < 4000)
-               rate = 4000;
-        freq = ((rate << 15) + 1500) / 3000;
-       s->dac1rate = (freq * 3000 + 16384) >> 15;
-       spin_lock_irqsave(&s->lock, flags);
-       r = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC2 | SRC_DADC)) | SRC_DDAC1;
-       outl(r, s->io + ES1371_REG_SRCONV);
-       src_write(s, SRCREG_DAC1+SRCREG_INT_REGS, 
-                 (src_read(s, SRCREG_DAC1+SRCREG_INT_REGS) & 0x00ff) |
-                 ((freq >> 5) & 0xfc00));
-       src_write(s, SRCREG_DAC1+SRCREG_VFREQ_FRAC, freq & 0x7fff);
-       r = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC2 | SRC_DADC));
-       outl(r, s->io + ES1371_REG_SRCONV);
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void set_dac2_rate(struct es1371_state *s, unsigned rate)
-{
-       unsigned long flags;
-       unsigned int freq, r;
-
-       if (rate > 48000)
-               rate = 48000;
-       if (rate < 4000)
-               rate = 4000;
-        freq = ((rate << 15) + 1500) / 3000;
-       s->dac2rate = (freq * 3000 + 16384) >> 15;
-       spin_lock_irqsave(&s->lock, flags);
-       r = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DADC)) | SRC_DDAC2;
-       outl(r, s->io + ES1371_REG_SRCONV);
-       src_write(s, SRCREG_DAC2+SRCREG_INT_REGS, 
-                 (src_read(s, SRCREG_DAC2+SRCREG_INT_REGS) & 0x00ff) |
-                 ((freq >> 5) & 0xfc00));
-       src_write(s, SRCREG_DAC2+SRCREG_VFREQ_FRAC, freq & 0x7fff);
-       r = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DADC));
-       outl(r, s->io + ES1371_REG_SRCONV);
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-/* --------------------------------------------------------------------- */
-
-static void __devinit src_init(struct es1371_state *s)
-{
-        unsigned int i;
-
-        /* before we enable or disable the SRC we need
-           to wait for it to become ready */
-        wait_src_ready(s);
-
-        outl(SRC_DIS, s->io + ES1371_REG_SRCONV);
-
-        for (i = 0; i < 0x80; i++)
-                src_write(s, i, 0);
-
-        src_write(s, SRCREG_DAC1+SRCREG_TRUNC_N, 16 << 4);
-        src_write(s, SRCREG_DAC1+SRCREG_INT_REGS, 16 << 10);
-        src_write(s, SRCREG_DAC2+SRCREG_TRUNC_N, 16 << 4);
-        src_write(s, SRCREG_DAC2+SRCREG_INT_REGS, 16 << 10);
-        src_write(s, SRCREG_VOL_ADC, 1 << 12);
-        src_write(s, SRCREG_VOL_ADC+1, 1 << 12);
-        src_write(s, SRCREG_VOL_DAC1, 1 << 12);
-        src_write(s, SRCREG_VOL_DAC1+1, 1 << 12);
-        src_write(s, SRCREG_VOL_DAC2, 1 << 12);
-        src_write(s, SRCREG_VOL_DAC2+1, 1 << 12);
-        set_adc_rate(s, 22050);
-        set_dac1_rate(s, 22050);
-        set_dac2_rate(s, 22050);
-
-        /* WARNING:
-         * enabling the sample rate converter without properly programming
-         * its parameters causes the chip to lock up (the SRC busy bit will
-         * be stuck high, and I've found no way to rectify this other than
-         * power cycle)
-         */
-        wait_src_ready(s);
-        outl(0, s->io+ES1371_REG_SRCONV);
-}
-
-/* --------------------------------------------------------------------- */
-
-static void wrcodec(struct ac97_codec *codec, u8 addr, u16 data)
-{
-       struct es1371_state *s = (struct es1371_state *)codec->private_data;
-       unsigned long flags;
-       unsigned t, x;
-        
-       spin_lock_irqsave(&s->lock, flags);
-       for (t = 0; t < POLL_COUNT; t++)
-               if (!(inl(s->io+ES1371_REG_CODEC) & CODEC_WIP))
-                       break;
-
-        /* save the current state for later */
-        x = wait_src_ready(s);
-
-        /* enable SRC state data in SRC mux */
-       outl((x & (SRC_DIS | SRC_DDAC1 | SRC_DDAC2 | SRC_DADC)) | 0x00010000,
-            s->io+ES1371_REG_SRCONV);
-
-        /* wait for not busy (state 0) first to avoid
-           transition states */
-        for (t=0; t<POLL_COUNT; t++){
-                if((inl(s->io+ES1371_REG_SRCONV) & 0x00870000) ==0 )
-                    break;
-                udelay(1);
-        }
-        
-        /* wait for a SAFE time to write addr/data and then do it, dammit */
-        for (t=0; t<POLL_COUNT; t++){
-                if((inl(s->io+ES1371_REG_SRCONV) & 0x00870000) ==0x00010000)
-                    break;
-                udelay(1);
-        }
-
-       outl(((addr << CODEC_POADD_SHIFT) & CODEC_POADD_MASK) |
-            ((data << CODEC_PODAT_SHIFT) & CODEC_PODAT_MASK), s->io+ES1371_REG_CODEC);
-
-       /* restore SRC reg */
-       wait_src_ready(s);
-       outl(x, s->io+ES1371_REG_SRCONV);
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static u16 rdcodec(struct ac97_codec *codec, u8 addr)
-{
-       struct es1371_state *s = (struct es1371_state *)codec->private_data;
-       unsigned long flags;
-       unsigned t, x;
-
-       spin_lock_irqsave(&s->lock, flags);
-       
-        /* wait for WIP to go away */
-       for (t = 0; t < 0x1000; t++)
-               if (!(inl(s->io+ES1371_REG_CODEC) & CODEC_WIP))
-                       break;
-
-       /* save the current state for later */
-       x = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DDAC2 | SRC_DADC));
-
-       /* enable SRC state data in SRC mux */
-       outl( x | 0x00010000,
-              s->io+ES1371_REG_SRCONV);
-
-        /* wait for not busy (state 0) first to avoid
-           transition states */
-        for (t=0; t<POLL_COUNT; t++){
-                if((inl(s->io+ES1371_REG_SRCONV) & 0x00870000) ==0 )
-                    break;
-                udelay(1);
-        }
-        
-        /* wait for a SAFE time to write addr/data and then do it, dammit */
-        for (t=0; t<POLL_COUNT; t++){
-                if((inl(s->io+ES1371_REG_SRCONV) & 0x00870000) ==0x00010000)
-                    break;
-                udelay(1);
-        }
-
-       outl(((addr << CODEC_POADD_SHIFT) & CODEC_POADD_MASK) | CODEC_PORD, s->io+ES1371_REG_CODEC);
-       /* restore SRC reg */
-       wait_src_ready(s);
-       outl(x, s->io+ES1371_REG_SRCONV);
-
-        /* wait for WIP again */
-       for (t = 0; t < 0x1000; t++)
-               if (!(inl(s->io+ES1371_REG_CODEC) & CODEC_WIP))
-                       break;
-        
-       /* now wait for the stinkin' data (RDY) */
-       for (t = 0; t < POLL_COUNT; t++)
-               if ((x = inl(s->io+ES1371_REG_CODEC)) & CODEC_RDY)
-                       break;
-        
-       spin_unlock_irqrestore(&s->lock, flags);
-       return ((x & CODEC_PIDAT_MASK) >> CODEC_PIDAT_SHIFT);
-}
-
-/* --------------------------------------------------------------------- */
-
-static inline void stop_adc(struct es1371_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       s->ctrl &= ~CTRL_ADC_EN;
-       outl(s->ctrl, s->io+ES1371_REG_CONTROL);
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-static inline void stop_dac1(struct es1371_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       s->ctrl &= ~CTRL_DAC1_EN;
-       outl(s->ctrl, s->io+ES1371_REG_CONTROL);
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-static inline void stop_dac2(struct es1371_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       s->ctrl &= ~CTRL_DAC2_EN;
-       outl(s->ctrl, s->io+ES1371_REG_CONTROL);
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-static void start_dac1(struct es1371_state *s)
-{
-       unsigned long flags;
-       unsigned fragremain, fshift;
-
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->ctrl & CTRL_DAC1_EN) && (s->dma_dac1.mapped || s->dma_dac1.count > 0)
-           && s->dma_dac1.ready) {
-               s->ctrl |= CTRL_DAC1_EN;
-               s->sctrl = (s->sctrl & ~(SCTRL_P1LOOPSEL | SCTRL_P1PAUSE | SCTRL_P1SCTRLD)) | SCTRL_P1INTEN;
-               outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-               fragremain = ((- s->dma_dac1.hwptr) & (s->dma_dac1.fragsize-1));
-               fshift = sample_shift[(s->sctrl & SCTRL_P1FMT) >> SCTRL_SH_P1FMT];
-               if (fragremain < 2*fshift)
-                       fragremain = s->dma_dac1.fragsize;
-               outl((fragremain >> fshift) - 1, s->io+ES1371_REG_DAC1_SCOUNT);
-               outl(s->ctrl, s->io+ES1371_REG_CONTROL);
-               outl((s->dma_dac1.fragsize >> fshift) - 1, s->io+ES1371_REG_DAC1_SCOUNT);
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-static void start_dac2(struct es1371_state *s)
-{
-       unsigned long flags;
-       unsigned fragremain, fshift;
-
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->ctrl & CTRL_DAC2_EN) && (s->dma_dac2.mapped || s->dma_dac2.count > 0)
-           && s->dma_dac2.ready) {
-               s->ctrl |= CTRL_DAC2_EN;
-               s->sctrl = (s->sctrl & ~(SCTRL_P2LOOPSEL | SCTRL_P2PAUSE | SCTRL_P2DACSEN | 
-                                        SCTRL_P2ENDINC | SCTRL_P2STINC)) | SCTRL_P2INTEN |
-                       (((s->sctrl & SCTRL_P2FMT) ? 2 : 1) << SCTRL_SH_P2ENDINC) | 
-                       (0 << SCTRL_SH_P2STINC);
-               outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-               fragremain = ((- s->dma_dac2.hwptr) & (s->dma_dac2.fragsize-1));
-               fshift = sample_shift[(s->sctrl & SCTRL_P2FMT) >> SCTRL_SH_P2FMT];
-               if (fragremain < 2*fshift)
-                       fragremain = s->dma_dac2.fragsize;
-               outl((fragremain >> fshift) - 1, s->io+ES1371_REG_DAC2_SCOUNT);
-               outl(s->ctrl, s->io+ES1371_REG_CONTROL);
-               outl((s->dma_dac2.fragsize >> fshift) - 1, s->io+ES1371_REG_DAC2_SCOUNT);
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-static void start_adc(struct es1371_state *s)
-{
-       unsigned long flags;
-       unsigned fragremain, fshift;
-
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->ctrl & CTRL_ADC_EN) && (s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize))
-           && s->dma_adc.ready) {
-               s->ctrl |= CTRL_ADC_EN;
-               s->sctrl = (s->sctrl & ~SCTRL_R1LOOPSEL) | SCTRL_R1INTEN;
-               outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-               fragremain = ((- s->dma_adc.hwptr) & (s->dma_adc.fragsize-1));
-               fshift = sample_shift[(s->sctrl & SCTRL_R1FMT) >> SCTRL_SH_R1FMT];
-               if (fragremain < 2*fshift)
-                       fragremain = s->dma_adc.fragsize;
-               outl((fragremain >> fshift) - 1, s->io+ES1371_REG_ADC_SCOUNT);
-               outl(s->ctrl, s->io+ES1371_REG_CONTROL);
-               outl((s->dma_adc.fragsize >> fshift) - 1, s->io+ES1371_REG_ADC_SCOUNT);
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-/* --------------------------------------------------------------------- */
-
-#define DMABUF_DEFAULTORDER (17-PAGE_SHIFT)
-#define DMABUF_MINORDER 1
-
-
-static inline void dealloc_dmabuf(struct es1371_state *s, struct dmabuf *db)
-{
-       struct page *page, *pend;
-
-       if (db->rawbuf) {
-               /* undo marking the pages as reserved */
-               pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-               for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-                       ClearPageReserved(page);
-               pci_free_consistent(s->dev, PAGE_SIZE << db->buforder, db->rawbuf, db->dmaaddr);
-       }
-       db->rawbuf = NULL;
-       db->mapped = db->ready = 0;
-}
-
-static int prog_dmabuf(struct es1371_state *s, struct dmabuf *db, unsigned rate, unsigned fmt, unsigned reg)
-{
-       int order;
-       unsigned bytepersec;
-       unsigned bufs;
-       struct page *page, *pend;
-
-       db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0;
-       if (!db->rawbuf) {
-               db->ready = db->mapped = 0;
-               for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
-                       if ((db->rawbuf = pci_alloc_consistent(s->dev, PAGE_SIZE << order, &db->dmaaddr)))
-                               break;
-               if (!db->rawbuf)
-                       return -ENOMEM;
-               db->buforder = order;
-               /* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */
-               pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-               for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-                       SetPageReserved(page);
-       }
-       fmt &= ES1371_FMT_MASK;
-       bytepersec = rate << sample_shift[fmt];
-       bufs = PAGE_SIZE << db->buforder;
-       if (db->ossfragshift) {
-               if ((1000 << db->ossfragshift) < bytepersec)
-                       db->fragshift = ld2(bytepersec/1000);
-               else
-                       db->fragshift = db->ossfragshift;
-       } else {
-               db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1));
-               if (db->fragshift < 3)
-                       db->fragshift = 3;
-       }
-       db->numfrag = bufs >> db->fragshift;
-       while (db->numfrag < 4 && db->fragshift > 3) {
-               db->fragshift--;
-               db->numfrag = bufs >> db->fragshift;
-       }
-       db->fragsize = 1 << db->fragshift;
-       if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
-               db->numfrag = db->ossmaxfrags;
-       db->fragsamples = db->fragsize >> sample_shift[fmt];
-       db->dmasize = db->numfrag << db->fragshift;
-       memset(db->rawbuf, (fmt & ES1371_FMT_S16) ? 0 : 0x80, db->dmasize);
-       outl((reg >> 8) & 15, s->io+ES1371_REG_MEMPAGE);
-       outl(db->dmaaddr, s->io+(reg & 0xff));
-       outl((db->dmasize >> 2)-1, s->io+((reg + 4) & 0xff));
-       db->enabled = 1;
-       db->ready = 1;
-       return 0;
-}
-
-static inline int prog_dmabuf_adc(struct es1371_state *s)
-{
-       stop_adc(s);
-       return prog_dmabuf(s, &s->dma_adc, s->adcrate, (s->sctrl >> SCTRL_SH_R1FMT) & ES1371_FMT_MASK, 
-                          ES1371_REG_ADC_FRAMEADR);
-}
-
-static inline int prog_dmabuf_dac2(struct es1371_state *s)
-{
-       stop_dac2(s);
-       return prog_dmabuf(s, &s->dma_dac2, s->dac2rate, (s->sctrl >> SCTRL_SH_P2FMT) & ES1371_FMT_MASK, 
-                          ES1371_REG_DAC2_FRAMEADR);
-}
-
-static inline int prog_dmabuf_dac1(struct es1371_state *s)
-{
-       stop_dac1(s);
-       return prog_dmabuf(s, &s->dma_dac1, s->dac1rate, (s->sctrl >> SCTRL_SH_P1FMT) & ES1371_FMT_MASK,
-                          ES1371_REG_DAC1_FRAMEADR);
-}
-
-static inline unsigned get_hwptr(struct es1371_state *s, struct dmabuf *db, unsigned reg)
-{
-       unsigned hwptr, diff;
-
-       outl((reg >> 8) & 15, s->io+ES1371_REG_MEMPAGE);
-       hwptr = (inl(s->io+(reg & 0xff)) >> 14) & 0x3fffc;
-       diff = (db->dmasize + hwptr - db->hwptr) % db->dmasize;
-       db->hwptr = hwptr;
-       return diff;
-}
-
-static inline void clear_advance(void *buf, unsigned bsize, unsigned bptr, unsigned len, unsigned char c)
-{
-       if (bptr + len > bsize) {
-               unsigned x = bsize - bptr;
-               memset(((char *)buf) + bptr, c, x);
-               bptr = 0;
-               len -= x;
-       }
-       memset(((char *)buf) + bptr, c, len);
-}
-
-/* call with spinlock held! */
-static void es1371_update_ptr(struct es1371_state *s)
-{
-       int diff;
-
-       /* update ADC pointer */
-       if (s->ctrl & CTRL_ADC_EN) {
-               diff = get_hwptr(s, &s->dma_adc, ES1371_REG_ADC_FRAMECNT);
-               s->dma_adc.total_bytes += diff;
-               s->dma_adc.count += diff;
-               if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) 
-                       wake_up(&s->dma_adc.wait);
-               if (!s->dma_adc.mapped) {
-                       if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) {
-                               s->ctrl &= ~CTRL_ADC_EN;
-                               outl(s->ctrl, s->io+ES1371_REG_CONTROL);
-                               s->dma_adc.error++;
-                       }
-               }
-       }
-       /* update DAC1 pointer */
-       if (s->ctrl & CTRL_DAC1_EN) {
-               diff = get_hwptr(s, &s->dma_dac1, ES1371_REG_DAC1_FRAMECNT);
-               s->dma_dac1.total_bytes += diff;
-               if (s->dma_dac1.mapped) {
-                       s->dma_dac1.count += diff;
-                       if (s->dma_dac1.count >= (signed)s->dma_dac1.fragsize)
-                               wake_up(&s->dma_dac1.wait);
-               } else {
-                       s->dma_dac1.count -= diff;
-                       if (s->dma_dac1.count <= 0) {
-                               s->ctrl &= ~CTRL_DAC1_EN;
-                               outl(s->ctrl, s->io+ES1371_REG_CONTROL);
-                               s->dma_dac1.error++;
-                       } else if (s->dma_dac1.count <= (signed)s->dma_dac1.fragsize && !s->dma_dac1.endcleared) {
-                               clear_advance(s->dma_dac1.rawbuf, s->dma_dac1.dmasize, s->dma_dac1.swptr, 
-                                             s->dma_dac1.fragsize, (s->sctrl & SCTRL_P1SEB) ? 0 : 0x80);
-                               s->dma_dac1.endcleared = 1;
-                       }
-                       if (s->dma_dac1.count + (signed)s->dma_dac1.fragsize <= (signed)s->dma_dac1.dmasize)
-                               wake_up(&s->dma_dac1.wait);
-               }
-       }
-       /* update DAC2 pointer */
-       if (s->ctrl & CTRL_DAC2_EN) {
-               diff = get_hwptr(s, &s->dma_dac2, ES1371_REG_DAC2_FRAMECNT);
-               s->dma_dac2.total_bytes += diff;
-               if (s->dma_dac2.mapped) {
-                       s->dma_dac2.count += diff;
-                       if (s->dma_dac2.count >= (signed)s->dma_dac2.fragsize)
-                               wake_up(&s->dma_dac2.wait);
-               } else {
-                       s->dma_dac2.count -= diff;
-                       if (s->dma_dac2.count <= 0) {
-                               s->ctrl &= ~CTRL_DAC2_EN;
-                               outl(s->ctrl, s->io+ES1371_REG_CONTROL);
-                               s->dma_dac2.error++;
-                       } else if (s->dma_dac2.count <= (signed)s->dma_dac2.fragsize && !s->dma_dac2.endcleared) {
-                               clear_advance(s->dma_dac2.rawbuf, s->dma_dac2.dmasize, s->dma_dac2.swptr, 
-                                             s->dma_dac2.fragsize, (s->sctrl & SCTRL_P2SEB) ? 0 : 0x80);
-                               s->dma_dac2.endcleared = 1;
-                       }
-                       if (s->dma_dac2.count + (signed)s->dma_dac2.fragsize <= (signed)s->dma_dac2.dmasize)
-                               wake_up(&s->dma_dac2.wait);
-               }
-       }
-}
-
-/* hold spinlock for the following! */
-static void es1371_handle_midi(struct es1371_state *s)
-{
-       unsigned char ch;
-       int wake;
-
-       if (!(s->ctrl & CTRL_UART_EN))
-               return;
-       wake = 0;
-       while (inb(s->io+ES1371_REG_UART_STATUS) & USTAT_RXRDY) {
-               ch = inb(s->io+ES1371_REG_UART_DATA);
-               if (s->midi.icnt < MIDIINBUF) {
-                       s->midi.ibuf[s->midi.iwr] = ch;
-                       s->midi.iwr = (s->midi.iwr + 1) % MIDIINBUF;
-                       s->midi.icnt++;
-               }
-               wake = 1;
-       }
-       if (wake)
-               wake_up(&s->midi.iwait);
-       wake = 0;
-       while ((inb(s->io+ES1371_REG_UART_STATUS) & USTAT_TXRDY) && s->midi.ocnt > 0) {
-               outb(s->midi.obuf[s->midi.ord], s->io+ES1371_REG_UART_DATA);
-               s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF;
-               s->midi.ocnt--;
-               if (s->midi.ocnt < MIDIOUTBUF-16)
-                       wake = 1;
-       }
-       if (wake)
-               wake_up(&s->midi.owait);
-       outb((s->midi.ocnt > 0) ? UCTRL_RXINTEN | UCTRL_ENA_TXINT : UCTRL_RXINTEN, s->io+ES1371_REG_UART_CONTROL);
-}
-
-static irqreturn_t es1371_interrupt(int irq, void *dev_id)
-{
-        struct es1371_state *s = dev_id;
-       unsigned int intsrc, sctl;
-       
-       /* fastpath out, to ease interrupt sharing */
-       intsrc = inl(s->io+ES1371_REG_STATUS);
-       if (!(intsrc & 0x80000000))
-               return IRQ_NONE;
-       spin_lock(&s->lock);
-       /* clear audio interrupts first */
-       sctl = s->sctrl;
-       if (intsrc & STAT_ADC)
-               sctl &= ~SCTRL_R1INTEN;
-       if (intsrc & STAT_DAC1)
-               sctl &= ~SCTRL_P1INTEN;
-       if (intsrc & STAT_DAC2)
-               sctl &= ~SCTRL_P2INTEN;
-       outl(sctl, s->io+ES1371_REG_SERIAL_CONTROL);
-       outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-       es1371_update_ptr(s);
-       es1371_handle_midi(s);
-       spin_unlock(&s->lock);
-       return IRQ_HANDLED;
-}
-
-/* --------------------------------------------------------------------- */
-
-static const char invalid_magic[] = KERN_CRIT PFX "invalid magic value\n";
-
-#define VALIDATE_STATE(s)                         \
-({                                                \
-       if (!(s) || (s)->magic != ES1371_MAGIC) { \
-               printk(invalid_magic);            \
-               return -ENXIO;                    \
-       }                                         \
-})
-
-/* --------------------------------------------------------------------- */
-
-/* Conversion table for S/PDIF PCM volume emulation through the SRC */
-/* dB-linear table of DAC vol values; -0dB to -46.5dB with mute */
-static const unsigned short DACVolTable[101] =
-{
-       0x1000, 0x0f2a, 0x0e60, 0x0da0, 0x0cea, 0x0c3e, 0x0b9a, 0x0aff,
-       0x0a6d, 0x09e1, 0x095e, 0x08e1, 0x086a, 0x07fa, 0x078f, 0x072a,
-       0x06cb, 0x0670, 0x061a, 0x05c9, 0x057b, 0x0532, 0x04ed, 0x04ab,
-       0x046d, 0x0432, 0x03fa, 0x03c5, 0x0392, 0x0363, 0x0335, 0x030b,
-       0x02e2, 0x02bc, 0x0297, 0x0275, 0x0254, 0x0235, 0x0217, 0x01fb,
-       0x01e1, 0x01c8, 0x01b0, 0x0199, 0x0184, 0x0170, 0x015d, 0x014b,
-       0x0139, 0x0129, 0x0119, 0x010b, 0x00fd, 0x00f0, 0x00e3, 0x00d7,
-       0x00cc, 0x00c1, 0x00b7, 0x00ae, 0x00a5, 0x009c, 0x0094, 0x008c,
-       0x0085, 0x007e, 0x0077, 0x0071, 0x006b, 0x0066, 0x0060, 0x005b,
-       0x0057, 0x0052, 0x004e, 0x004a, 0x0046, 0x0042, 0x003f, 0x003c,
-       0x0038, 0x0036, 0x0033, 0x0030, 0x002e, 0x002b, 0x0029, 0x0027,
-       0x0025, 0x0023, 0x0021, 0x001f, 0x001e, 0x001c, 0x001b, 0x0019,
-       0x0018, 0x0017, 0x0016, 0x0014, 0x0000
-};
-
-/*
- * when we are in S/PDIF mode, we want to disable any analog output so
- * we filter the mixer ioctls 
- */
-static int mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd, unsigned long arg)
-{
-       struct es1371_state *s = (struct es1371_state *)codec->private_data;
-       int val;
-       unsigned long flags;
-       unsigned int left, right;
-
-       VALIDATE_STATE(s);
-       /* filter mixer ioctls to catch PCM and MASTER volume when in S/PDIF mode */
-       if (s->spdif_volume == -1)
-               return codec->mixer_ioctl(codec, cmd, arg);
-       switch (cmd) {
-       case SOUND_MIXER_WRITE_VOLUME:
-               return 0;
-
-       case SOUND_MIXER_WRITE_PCM:   /* use SRC for PCM volume */
-               if (get_user(val, (int __user *)arg))
-                       return -EFAULT;
-               right = ((val >> 8)  & 0xff);
-               left = (val  & 0xff);
-               if (right > 100)
-                       right = 100;
-               if (left > 100)
-                       left = 100;
-               s->spdif_volume = (right << 8) | left;
-               spin_lock_irqsave(&s->lock, flags);
-               src_write(s, SRCREG_VOL_DAC2, DACVolTable[100 - left]);
-               src_write(s, SRCREG_VOL_DAC2+1, DACVolTable[100 - right]);
-               spin_unlock_irqrestore(&s->lock, flags);
-               return 0;
-       
-       case SOUND_MIXER_READ_PCM:
-               return put_user(s->spdif_volume, (int __user *)arg);
-       }
-       return codec->mixer_ioctl(codec, cmd, arg);
-}
-
-/* --------------------------------------------------------------------- */
-
-/*
- * AC97 Mixer Register to Connections mapping of the Concert 97 board
- *
- * AC97_MASTER_VOL_STEREO   Line Out
- * AC97_MASTER_VOL_MONO     TAD Output
- * AC97_PCBEEP_VOL          none
- * AC97_PHONE_VOL           TAD Input (mono)
- * AC97_MIC_VOL             MIC Input (mono)
- * AC97_LINEIN_VOL          Line Input (stereo)
- * AC97_CD_VOL              CD Input (stereo)
- * AC97_VIDEO_VOL           none
- * AC97_AUX_VOL             Aux Input (stereo)
- * AC97_PCMOUT_VOL          Wave Output (stereo)
- */
-
-static int es1371_open_mixdev(struct inode *inode, struct file *file)
-{
-       int minor = iminor(inode);
-       struct list_head *list;
-       struct es1371_state *s;
-
-       for (list = devs.next; ; list = list->next) {
-               if (list == &devs)
-                       return -ENODEV;
-               s = list_entry(list, struct es1371_state, devs);
-               if (s->codec->dev_mixer == minor)
-                       break;
-       }
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       return nonseekable_open(inode, file);
-}
-
-static int es1371_release_mixdev(struct inode *inode, struct file *file)
-{
-       struct es1371_state *s = (struct es1371_state *)file->private_data;
-       
-       VALIDATE_STATE(s);
-       return 0;
-}
-
-static int es1371_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct es1371_state *s = (struct es1371_state *)file->private_data;
-       struct ac97_codec *codec = s->codec;
-
-       return mixdev_ioctl(codec, cmd, arg);
-}
-
-static /*const*/ struct file_operations es1371_mixer_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .ioctl          = es1371_ioctl_mixdev,
-       .open           = es1371_open_mixdev,
-       .release        = es1371_release_mixdev,
-};
-
-/* --------------------------------------------------------------------- */
-
-static int drain_dac1(struct es1371_state *s, int nonblock)
-{
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       int count, tmo;
-       
-       if (s->dma_dac1.mapped || !s->dma_dac1.ready)
-               return 0;
-        add_wait_queue(&s->dma_dac1.wait, &wait);
-        for (;;) {
-               __set_current_state(TASK_INTERRUPTIBLE);
-                spin_lock_irqsave(&s->lock, flags);
-               count = s->dma_dac1.count;
-                spin_unlock_irqrestore(&s->lock, flags);
-               if (count <= 0)
-                       break;
-               if (signal_pending(current))
-                        break;
-                if (nonblock) {
-                        remove_wait_queue(&s->dma_dac1.wait, &wait);
-                        set_current_state(TASK_RUNNING);
-                        return -EBUSY;
-                }
-               tmo = 3 * HZ * (count + s->dma_dac1.fragsize) / 2 / s->dac1rate;
-               tmo >>= sample_shift[(s->sctrl & SCTRL_P1FMT) >> SCTRL_SH_P1FMT];
-               if (!schedule_timeout(tmo + 1))
-                       DBG(printk(KERN_DEBUG PFX "dac1 dma timed out??\n");)
-        }
-        remove_wait_queue(&s->dma_dac1.wait, &wait);
-        set_current_state(TASK_RUNNING);
-        if (signal_pending(current))
-                return -ERESTARTSYS;
-        return 0;
-}
-
-static int drain_dac2(struct es1371_state *s, int nonblock)
-{
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       int count, tmo;
-
-       if (s->dma_dac2.mapped || !s->dma_dac2.ready)
-               return 0;
-        add_wait_queue(&s->dma_dac2.wait, &wait);
-        for (;;) {
-               __set_current_state(TASK_UNINTERRUPTIBLE);
-                spin_lock_irqsave(&s->lock, flags);
-               count = s->dma_dac2.count;
-                spin_unlock_irqrestore(&s->lock, flags);
-               if (count <= 0)
-                       break;
-               if (signal_pending(current))
-                        break;
-                if (nonblock) {
-                        remove_wait_queue(&s->dma_dac2.wait, &wait);
-                        set_current_state(TASK_RUNNING);
-                        return -EBUSY;
-                }
-               tmo = 3 * HZ * (count + s->dma_dac2.fragsize) / 2 / s->dac2rate;
-               tmo >>= sample_shift[(s->sctrl & SCTRL_P2FMT) >> SCTRL_SH_P2FMT];
-               if (!schedule_timeout(tmo + 1))
-                       DBG(printk(KERN_DEBUG PFX "dac2 dma timed out??\n");)
-        }
-        remove_wait_queue(&s->dma_dac2.wait, &wait);
-        set_current_state(TASK_RUNNING);
-        if (signal_pending(current))
-                return -ERESTARTSYS;
-        return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t es1371_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct es1371_state *s = (struct es1371_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret = 0;
-       unsigned long flags;
-       unsigned swptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (s->dma_adc.mapped)
-               return -ENXIO;
-       if (!access_ok(VERIFY_WRITE, buffer, count))
-               return -EFAULT;
-       mutex_lock(&s->sem);
-       if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
-               goto out2;
-       
-       add_wait_queue(&s->dma_adc.wait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               swptr = s->dma_adc.swptr;
-               cnt = s->dma_adc.dmasize-swptr;
-               if (s->dma_adc.count < cnt)
-                       cnt = s->dma_adc.count;
-               if (cnt <= 0)
-                       __set_current_state(TASK_INTERRUPTIBLE);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (s->dma_adc.enabled)
-                               start_adc(s);
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               goto out;
-                       }
-                       mutex_unlock(&s->sem);
-                       schedule();
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               goto out2;
-                       }
-                       mutex_lock(&s->sem);
-                       if (s->dma_adc.mapped)
-                       {
-                               ret = -ENXIO;
-                               goto out;
-                       }
-                       continue;
-               }
-               if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       goto out;
-               }
-               swptr = (swptr + cnt) % s->dma_adc.dmasize;
-               spin_lock_irqsave(&s->lock, flags);
-               s->dma_adc.swptr = swptr;
-               s->dma_adc.count -= cnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               if (s->dma_adc.enabled)
-                       start_adc(s);
-       }
-out:
-       mutex_unlock(&s->sem);
-out2:
-       remove_wait_queue(&s->dma_adc.wait, &wait);
-       set_current_state(TASK_RUNNING);
-       return ret;
-}
-
-static ssize_t es1371_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct es1371_state *s = (struct es1371_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned swptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (s->dma_dac2.mapped)
-               return -ENXIO;
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-       mutex_lock(&s->sem);
-       if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s)))
-               goto out3;
-       ret = 0;
-       add_wait_queue(&s->dma_dac2.wait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               if (s->dma_dac2.count < 0) {
-                       s->dma_dac2.count = 0;
-                       s->dma_dac2.swptr = s->dma_dac2.hwptr;
-               }
-               swptr = s->dma_dac2.swptr;
-               cnt = s->dma_dac2.dmasize-swptr;
-               if (s->dma_dac2.count + cnt > s->dma_dac2.dmasize)
-                       cnt = s->dma_dac2.dmasize - s->dma_dac2.count;
-               if (cnt <= 0)
-                       __set_current_state(TASK_INTERRUPTIBLE);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (s->dma_dac2.enabled)
-                               start_dac2(s);
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               goto out;
-                       }       
-                       mutex_unlock(&s->sem);
-                       schedule();
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               goto out2;
-                       }
-                       mutex_lock(&s->sem);
-                       if (s->dma_dac2.mapped)
-                       {
-                               ret = -ENXIO;
-                               goto out;
-                       }
-                       continue;
-               }
-               if (copy_from_user(s->dma_dac2.rawbuf + swptr, buffer, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       goto out;
-               }
-               swptr = (swptr + cnt) % s->dma_dac2.dmasize;
-               spin_lock_irqsave(&s->lock, flags);
-               s->dma_dac2.swptr = swptr;
-               s->dma_dac2.count += cnt;
-               s->dma_dac2.endcleared = 0;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               if (s->dma_dac2.enabled)
-                       start_dac2(s);
-       }
-out:
-       mutex_unlock(&s->sem);
-out2:
-       remove_wait_queue(&s->dma_dac2.wait, &wait);
-out3:  
-       set_current_state(TASK_RUNNING);
-       return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int es1371_poll(struct file *file, struct poll_table_struct *wait)
-{
-       struct es1371_state *s = (struct es1371_state *)file->private_data;
-       unsigned long flags;
-       unsigned int mask = 0;
-
-       VALIDATE_STATE(s);
-       if (file->f_mode & FMODE_WRITE) {
-               if (!s->dma_dac2.ready && prog_dmabuf_dac2(s))
-                       return 0;
-               poll_wait(file, &s->dma_dac2.wait, wait);
-       }
-       if (file->f_mode & FMODE_READ) {
-               if (!s->dma_adc.ready && prog_dmabuf_adc(s))
-                       return 0;
-               poll_wait(file, &s->dma_adc.wait, wait);
-       }
-       spin_lock_irqsave(&s->lock, flags);
-       es1371_update_ptr(s);
-       if (file->f_mode & FMODE_READ) {
-                       if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
-                               mask |= POLLIN | POLLRDNORM;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               if (s->dma_dac2.mapped) {
-                       if (s->dma_dac2.count >= (signed)s->dma_dac2.fragsize) 
-                               mask |= POLLOUT | POLLWRNORM;
-               } else {
-                       if ((signed)s->dma_dac2.dmasize >= s->dma_dac2.count + (signed)s->dma_dac2.fragsize)
-                               mask |= POLLOUT | POLLWRNORM;
-               }
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       return mask;
-}
-
-static int es1371_mmap(struct file *file, struct vm_area_struct *vma)
-{
-       struct es1371_state *s = (struct es1371_state *)file->private_data;
-       struct dmabuf *db;
-       int ret = 0;
-       unsigned long size;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-       mutex_lock(&s->sem);
-       
-       if (vma->vm_flags & VM_WRITE) {
-               if ((ret = prog_dmabuf_dac2(s)) != 0) {
-                       goto out;
-               }
-               db = &s->dma_dac2;
-       } else if (vma->vm_flags & VM_READ) {
-               if ((ret = prog_dmabuf_adc(s)) != 0) {
-                       goto out;
-               }
-               db = &s->dma_adc;
-       } else {
-               ret = -EINVAL;
-               goto out;
-       }
-       if (vma->vm_pgoff != 0) {
-               ret = -EINVAL;
-               goto out;
-       }
-       size = vma->vm_end - vma->vm_start;
-       if (size > (PAGE_SIZE << db->buforder)) {
-               ret = -EINVAL;
-               goto out;
-       }
-       if (remap_pfn_range(vma, vma->vm_start,
-                               virt_to_phys(db->rawbuf) >> PAGE_SHIFT,
-                               size, vma->vm_page_prot)) {
-               ret = -EAGAIN;
-               goto out;
-       }
-       db->mapped = 1;
-out:
-       mutex_unlock(&s->sem);
-       unlock_kernel();
-       return ret;
-}
-
-static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct es1371_state *s = (struct es1371_state *)file->private_data;
-       unsigned long flags;
-        audio_buf_info abinfo;
-        count_info cinfo;
-       int count;
-       int val, mapped, ret;
-       void __user *argp = (void __user *)arg;
-       int __user *p = argp;
-
-       VALIDATE_STATE(s);
-        mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac2.mapped) ||
-               ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
-       switch (cmd) {
-       case OSS_GETVERSION:
-               return put_user(SOUND_VERSION, p);
-
-       case SNDCTL_DSP_SYNC:
-               if (file->f_mode & FMODE_WRITE)
-                       return drain_dac2(s, 0/*file->f_flags & O_NONBLOCK*/);
-               return 0;
-               
-       case SNDCTL_DSP_SETDUPLEX:
-               return 0;
-
-       case SNDCTL_DSP_GETCAPS:
-               return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
-               
-        case SNDCTL_DSP_RESET:
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac2(s);
-                       synchronize_irq(s->irq);
-                       s->dma_dac2.swptr = s->dma_dac2.hwptr = s->dma_dac2.count = s->dma_dac2.total_bytes = 0;
-               }
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       synchronize_irq(s->irq);
-                       s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
-               }
-               return 0;
-
-        case SNDCTL_DSP_SPEED:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val >= 0) {
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-                               set_adc_rate(s, val);
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac2(s);
-                               s->dma_dac2.ready = 0;
-                               set_dac2_rate(s, val);
-                       }
-               }
-               return put_user((file->f_mode & FMODE_READ) ? s->adcrate : s->dac2rate, p);
-
-        case SNDCTL_DSP_STEREO:
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       s->dma_adc.ready = 0;
-                       spin_lock_irqsave(&s->lock, flags);
-                       if (val)
-                               s->sctrl |= SCTRL_R1SMB;
-                       else
-                               s->sctrl &= ~SCTRL_R1SMB;
-                       outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-                       spin_unlock_irqrestore(&s->lock, flags);
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac2(s);
-                       s->dma_dac2.ready = 0;
-                       spin_lock_irqsave(&s->lock, flags);
-                       if (val)
-                               s->sctrl |= SCTRL_P2SMB;
-                       else
-                               s->sctrl &= ~SCTRL_P2SMB;
-                       outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-                       spin_unlock_irqrestore(&s->lock, flags);
-                }
-               return 0;
-
-        case SNDCTL_DSP_CHANNELS:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 0) {
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-                               spin_lock_irqsave(&s->lock, flags);
-                               if (val >= 2)
-                                       s->sctrl |= SCTRL_R1SMB;
-                               else
-                                       s->sctrl &= ~SCTRL_R1SMB;
-                               outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-                               spin_unlock_irqrestore(&s->lock, flags);
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac2(s);
-                               s->dma_dac2.ready = 0;
-                               spin_lock_irqsave(&s->lock, flags);
-                               if (val >= 2)
-                                       s->sctrl |= SCTRL_P2SMB;
-                               else
-                                       s->sctrl &= ~SCTRL_P2SMB;
-                               outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-                               spin_unlock_irqrestore(&s->lock, flags);
-                       }
-               }
-               return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ? 2 : 1, p);
-               
-       case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-                return put_user(AFMT_S16_LE|AFMT_U8, p);
-               
-       case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != AFMT_QUERY) {
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-                               spin_lock_irqsave(&s->lock, flags);
-                               if (val == AFMT_S16_LE)
-                                       s->sctrl |= SCTRL_R1SEB;
-                               else
-                                       s->sctrl &= ~SCTRL_R1SEB;
-                               outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-                               spin_unlock_irqrestore(&s->lock, flags);
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac2(s);
-                               s->dma_dac2.ready = 0;
-                               spin_lock_irqsave(&s->lock, flags);
-                               if (val == AFMT_S16_LE)
-                                       s->sctrl |= SCTRL_P2SEB;
-                               else
-                                       s->sctrl &= ~SCTRL_P2SEB;
-                               outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-                               spin_unlock_irqrestore(&s->lock, flags);
-                       }
-               }
-               return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ? 
-                               AFMT_S16_LE : AFMT_U8, p);
-               
-       case SNDCTL_DSP_POST:
-                return 0;
-
-        case SNDCTL_DSP_GETTRIGGER:
-               val = 0;
-               if (file->f_mode & FMODE_READ && s->ctrl & CTRL_ADC_EN) 
-                       val |= PCM_ENABLE_INPUT;
-               if (file->f_mode & FMODE_WRITE && s->ctrl & CTRL_DAC2_EN) 
-                       val |= PCM_ENABLE_OUTPUT;
-               return put_user(val, p);
-               
-       case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       if (val & PCM_ENABLE_INPUT) {
-                               if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
-                                       return ret;
-                               s->dma_adc.enabled = 1;
-                               start_adc(s);
-                       } else {
-                               s->dma_adc.enabled = 0;
-                               stop_adc(s);
-                       }
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       if (val & PCM_ENABLE_OUTPUT) {
-                               if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s)))
-                                       return ret;
-                               s->dma_dac2.enabled = 1;
-                               start_dac2(s);
-                       } else {
-                               s->dma_dac2.enabled = 0;
-                               stop_dac2(s);
-                       }
-               }
-               return 0;
-
-       case SNDCTL_DSP_GETOSPACE:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               es1371_update_ptr(s);
-               abinfo.fragsize = s->dma_dac2.fragsize;
-               count = s->dma_dac2.count;
-               if (count < 0)
-                       count = 0;
-                abinfo.bytes = s->dma_dac2.dmasize - count;
-                abinfo.fragstotal = s->dma_dac2.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_dac2.fragshift;      
-               spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETISPACE:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               es1371_update_ptr(s);
-               abinfo.fragsize = s->dma_adc.fragsize;
-               count = s->dma_adc.count;
-               if (count < 0)
-                       count = 0;
-                abinfo.bytes = count;
-                abinfo.fragstotal = s->dma_adc.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      
-               spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-               
-        case SNDCTL_DSP_NONBLOCK:
-                file->f_flags |= O_NONBLOCK;
-                return 0;
-
-        case SNDCTL_DSP_GETODELAY:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               es1371_update_ptr(s);
-                count = s->dma_dac2.count;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (count < 0)
-                       count = 0;
-               return put_user(count, p);
-
-        case SNDCTL_DSP_GETIPTR:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               es1371_update_ptr(s);
-                cinfo.bytes = s->dma_adc.total_bytes;
-               count = s->dma_adc.count;
-               if (count < 0)
-                       count = 0;
-                cinfo.blocks = count >> s->dma_adc.fragshift;
-                cinfo.ptr = s->dma_adc.hwptr;
-               if (s->dma_adc.mapped)
-                       s->dma_adc.count &= s->dma_adc.fragsize-1;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 0;
-
-        case SNDCTL_DSP_GETOPTR:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               es1371_update_ptr(s);
-                cinfo.bytes = s->dma_dac2.total_bytes;
-               count = s->dma_dac2.count;
-               if (count < 0)
-                       count = 0;
-                cinfo.blocks = count >> s->dma_dac2.fragshift;
-                cinfo.ptr = s->dma_dac2.hwptr;
-               if (s->dma_dac2.mapped)
-                       s->dma_dac2.count &= s->dma_dac2.fragsize-1;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 0;
-
-        case SNDCTL_DSP_GETBLKSIZE:
-               if (file->f_mode & FMODE_WRITE) {
-                       if ((val = prog_dmabuf_dac2(s)))
-                               return val;
-                       return put_user(s->dma_dac2.fragsize, p);
-               }
-               if ((val = prog_dmabuf_adc(s)))
-                       return val;
-               return put_user(s->dma_adc.fragsize, p);
-
-        case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       s->dma_adc.ossfragshift = val & 0xffff;
-                       s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
-                       if (s->dma_adc.ossfragshift < 4)
-                               s->dma_adc.ossfragshift = 4;
-                       if (s->dma_adc.ossfragshift > 15)
-                               s->dma_adc.ossfragshift = 15;
-                       if (s->dma_adc.ossmaxfrags < 4)
-                               s->dma_adc.ossmaxfrags = 4;
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       s->dma_dac2.ossfragshift = val & 0xffff;
-                       s->dma_dac2.ossmaxfrags = (val >> 16) & 0xffff;
-                       if (s->dma_dac2.ossfragshift < 4)
-                               s->dma_dac2.ossfragshift = 4;
-                       if (s->dma_dac2.ossfragshift > 15)
-                               s->dma_dac2.ossfragshift = 15;
-                       if (s->dma_dac2.ossmaxfrags < 4)
-                               s->dma_dac2.ossmaxfrags = 4;
-               }
-               return 0;
-
-        case SNDCTL_DSP_SUBDIVIDE:
-               if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
-                   (file->f_mode & FMODE_WRITE && s->dma_dac2.subdivision))
-                       return -EINVAL;
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 1 && val != 2 && val != 4)
-                       return -EINVAL;
-               if (file->f_mode & FMODE_READ)
-                       s->dma_adc.subdivision = val;
-               if (file->f_mode & FMODE_WRITE)
-                       s->dma_dac2.subdivision = val;
-               return 0;
-
-        case SOUND_PCM_READ_RATE:
-               return put_user((file->f_mode & FMODE_READ) ? s->adcrate : s->dac2rate, p);
-
-        case SOUND_PCM_READ_CHANNELS:
-               return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ? 2 : 1, p);
-               
-        case SOUND_PCM_READ_BITS:
-               return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ? 16 : 8, p);
-
-        case SOUND_PCM_WRITE_FILTER:
-        case SNDCTL_DSP_SETSYNCRO:
-        case SOUND_PCM_READ_FILTER:
-                return -EINVAL;
-               
-       }
-       return mixdev_ioctl(s->codec, cmd, arg);
-}
-
-static int es1371_open(struct inode *inode, struct file *file)
-{
-       int minor = iminor(inode);
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       struct list_head *list;
-       struct es1371_state *s;
-
-       for (list = devs.next; ; list = list->next) {
-               if (list == &devs)
-                       return -ENODEV;
-               s = list_entry(list, struct es1371_state, devs);
-               if (!((s->dev_audio ^ minor) & ~0xf))
-                       break;
-       }
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       /* wait for device to become free */
-       mutex_lock(&s->open_mutex);
-       while (s->open_mode & file->f_mode) {
-               if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_mutex);
-                       return -EBUSY;
-               }
-               add_wait_queue(&s->open_wait, &wait);
-               __set_current_state(TASK_INTERRUPTIBLE);
-               mutex_unlock(&s->open_mutex);
-               schedule();
-               remove_wait_queue(&s->open_wait, &wait);
-               set_current_state(TASK_RUNNING);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&s->open_mutex);
-       }
-       if (file->f_mode & FMODE_READ) {
-               s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
-               s->dma_adc.enabled = 1;
-               set_adc_rate(s, 8000);
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               s->dma_dac2.ossfragshift = s->dma_dac2.ossmaxfrags = s->dma_dac2.subdivision = 0;
-               s->dma_dac2.enabled = 1;
-               set_dac2_rate(s, 8000);
-       }
-       spin_lock_irqsave(&s->lock, flags);
-       if (file->f_mode & FMODE_READ) {
-               s->sctrl &= ~SCTRL_R1FMT;
-               if ((minor & 0xf) == SND_DEV_DSP16)
-                       s->sctrl |= ES1371_FMT_S16_MONO << SCTRL_SH_R1FMT;
-               else
-                       s->sctrl |= ES1371_FMT_U8_MONO << SCTRL_SH_R1FMT;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               s->sctrl &= ~SCTRL_P2FMT;
-               if ((minor & 0xf) == SND_DEV_DSP16)
-                       s->sctrl |= ES1371_FMT_S16_MONO << SCTRL_SH_P2FMT;
-               else
-                       s->sctrl |= ES1371_FMT_U8_MONO << SCTRL_SH_P2FMT;
-       }
-       outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-       spin_unlock_irqrestore(&s->lock, flags);
-       s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-       mutex_unlock(&s->open_mutex);
-       mutex_init(&s->sem);
-       return nonseekable_open(inode, file);
-}
-
-static int es1371_release(struct inode *inode, struct file *file)
-{
-       struct es1371_state *s = (struct es1371_state *)file->private_data;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-       if (file->f_mode & FMODE_WRITE)
-               drain_dac2(s, file->f_flags & O_NONBLOCK);
-       mutex_lock(&s->open_mutex);
-       if (file->f_mode & FMODE_WRITE) {
-               stop_dac2(s);
-               dealloc_dmabuf(s, &s->dma_dac2);
-       }
-       if (file->f_mode & FMODE_READ) {
-               stop_adc(s);
-               dealloc_dmabuf(s, &s->dma_adc);
-       }
-       s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE));
-       mutex_unlock(&s->open_mutex);
-       wake_up(&s->open_wait);
-       unlock_kernel();
-       return 0;
-}
-
-static /*const*/ struct file_operations es1371_audio_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .read           = es1371_read,
-       .write          = es1371_write,
-       .poll           = es1371_poll,
-       .ioctl          = es1371_ioctl,
-       .mmap           = es1371_mmap,
-       .open           = es1371_open,
-       .release        = es1371_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t es1371_write_dac(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct es1371_state *s = (struct es1371_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret = 0;
-       unsigned long flags;
-       unsigned swptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (s->dma_dac1.mapped)
-               return -ENXIO;
-       if (!s->dma_dac1.ready && (ret = prog_dmabuf_dac1(s)))
-               return ret;
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-       add_wait_queue(&s->dma_dac1.wait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               if (s->dma_dac1.count < 0) {
-                       s->dma_dac1.count = 0;
-                       s->dma_dac1.swptr = s->dma_dac1.hwptr;
-               }
-               swptr = s->dma_dac1.swptr;
-               cnt = s->dma_dac1.dmasize-swptr;
-               if (s->dma_dac1.count + cnt > s->dma_dac1.dmasize)
-                       cnt = s->dma_dac1.dmasize - s->dma_dac1.count;
-               if (cnt <= 0)
-                       __set_current_state(TASK_INTERRUPTIBLE);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (s->dma_dac1.enabled)
-                               start_dac1(s);
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               break;
-                       }
-                       schedule();
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               break;
-                       }
-                       continue;
-               }
-               if (copy_from_user(s->dma_dac1.rawbuf + swptr, buffer, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       break;
-               }
-               swptr = (swptr + cnt) % s->dma_dac1.dmasize;
-               spin_lock_irqsave(&s->lock, flags);
-               s->dma_dac1.swptr = swptr;
-               s->dma_dac1.count += cnt;
-               s->dma_dac1.endcleared = 0;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               if (s->dma_dac1.enabled)
-                       start_dac1(s);
-       }
-       remove_wait_queue(&s->dma_dac1.wait, &wait);
-       set_current_state(TASK_RUNNING);
-       return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int es1371_poll_dac(struct file *file, struct poll_table_struct *wait)
-{
-       struct es1371_state *s = (struct es1371_state *)file->private_data;
-       unsigned long flags;
-       unsigned int mask = 0;
-
-       VALIDATE_STATE(s);
-       if (!s->dma_dac1.ready && prog_dmabuf_dac1(s))
-               return 0;
-       poll_wait(file, &s->dma_dac1.wait, wait);
-       spin_lock_irqsave(&s->lock, flags);
-       es1371_update_ptr(s);
-       if (s->dma_dac1.mapped) {
-               if (s->dma_dac1.count >= (signed)s->dma_dac1.fragsize)
-                       mask |= POLLOUT | POLLWRNORM;
-       } else {
-               if ((signed)s->dma_dac1.dmasize >= s->dma_dac1.count + (signed)s->dma_dac1.fragsize)
-                       mask |= POLLOUT | POLLWRNORM;
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       return mask;
-}
-
-static int es1371_mmap_dac(struct file *file, struct vm_area_struct *vma)
-{
-       struct es1371_state *s = (struct es1371_state *)file->private_data;
-       int ret;
-       unsigned long size;
-
-       VALIDATE_STATE(s);
-       if (!(vma->vm_flags & VM_WRITE))
-               return -EINVAL;
-       lock_kernel();
-       if ((ret = prog_dmabuf_dac1(s)) != 0)
-               goto out;
-       ret = -EINVAL;
-       if (vma->vm_pgoff != 0)
-               goto out;
-       size = vma->vm_end - vma->vm_start;
-       if (size > (PAGE_SIZE << s->dma_dac1.buforder))
-               goto out;
-       ret = -EAGAIN;
-       if (remap_pfn_range(vma, vma->vm_start,
-                       virt_to_phys(s->dma_dac1.rawbuf) >> PAGE_SHIFT,
-                       size, vma->vm_page_prot))
-               goto out;
-       s->dma_dac1.mapped = 1;
-       ret = 0;
-out:
-       unlock_kernel();
-       return ret;
-}
-
-static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct es1371_state *s = (struct es1371_state *)file->private_data;
-       unsigned long flags;
-        audio_buf_info abinfo;
-        count_info cinfo;
-       int count;
-       int val, ret;
-       int __user *p = (int __user *)arg;
-
-       VALIDATE_STATE(s);
-       switch (cmd) {
-       case OSS_GETVERSION:
-               return put_user(SOUND_VERSION, p);
-
-       case SNDCTL_DSP_SYNC:
-               return drain_dac1(s, 0/*file->f_flags & O_NONBLOCK*/);
-               
-       case SNDCTL_DSP_SETDUPLEX:
-               return -EINVAL;
-
-       case SNDCTL_DSP_GETCAPS:
-               return put_user(DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
-               
-        case SNDCTL_DSP_RESET:
-               stop_dac1(s);
-               synchronize_irq(s->irq);
-               s->dma_dac1.swptr = s->dma_dac1.hwptr = s->dma_dac1.count = s->dma_dac1.total_bytes = 0;
-               return 0;
-
-        case SNDCTL_DSP_SPEED:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val >= 0) {
-                       stop_dac1(s);
-                       s->dma_dac1.ready = 0;
-                       set_dac1_rate(s, val);
-               }
-               return put_user(s->dac1rate, p);
-
-        case SNDCTL_DSP_STEREO:
-               if (get_user(val, p))
-                       return -EFAULT;
-               stop_dac1(s);
-               s->dma_dac1.ready = 0;
-               spin_lock_irqsave(&s->lock, flags);
-               if (val)
-                       s->sctrl |= SCTRL_P1SMB;
-               else
-                       s->sctrl &= ~SCTRL_P1SMB;
-               outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-               spin_unlock_irqrestore(&s->lock, flags);
-               return 0;
-
-        case SNDCTL_DSP_CHANNELS:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 0) {
-                       stop_dac1(s);
-                       s->dma_dac1.ready = 0;
-                       spin_lock_irqsave(&s->lock, flags);
-                       if (val >= 2)
-                               s->sctrl |= SCTRL_P1SMB;
-                       else
-                               s->sctrl &= ~SCTRL_P1SMB;
-                       outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-                       spin_unlock_irqrestore(&s->lock, flags);
-               }
-               return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, p);
-               
-        case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-                return put_user(AFMT_S16_LE|AFMT_U8, p);
-               
-        case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != AFMT_QUERY) {
-                       stop_dac1(s);
-                       s->dma_dac1.ready = 0;
-                       spin_lock_irqsave(&s->lock, flags);
-                       if (val == AFMT_S16_LE)
-                               s->sctrl |= SCTRL_P1SEB;
-                       else
-                               s->sctrl &= ~SCTRL_P1SEB;
-                       outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-                       spin_unlock_irqrestore(&s->lock, flags);
-               }
-               return put_user((s->sctrl & SCTRL_P1SEB) ? AFMT_S16_LE : AFMT_U8, p);
-
-        case SNDCTL_DSP_POST:
-                return 0;
-
-        case SNDCTL_DSP_GETTRIGGER:
-               return put_user((s->ctrl & CTRL_DAC1_EN) ? PCM_ENABLE_OUTPUT : 0, p);
-                                               
-       case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val & PCM_ENABLE_OUTPUT) {
-                       if (!s->dma_dac1.ready && (ret = prog_dmabuf_dac1(s)))
-                               return ret;
-                       s->dma_dac1.enabled = 1;
-                       start_dac1(s);
-               } else {
-                       s->dma_dac1.enabled = 0;
-                       stop_dac1(s);
-               }
-               return 0;
-
-       case SNDCTL_DSP_GETOSPACE:
-               if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               es1371_update_ptr(s);
-               abinfo.fragsize = s->dma_dac1.fragsize;
-               count = s->dma_dac1.count;
-               if (count < 0)
-                       count = 0;
-                abinfo.bytes = s->dma_dac1.dmasize - count;
-                abinfo.fragstotal = s->dma_dac1.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_dac1.fragshift;      
-               spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-        case SNDCTL_DSP_NONBLOCK:
-                file->f_flags |= O_NONBLOCK;
-                return 0;
-
-        case SNDCTL_DSP_GETODELAY:
-               if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               es1371_update_ptr(s);
-                count = s->dma_dac1.count;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (count < 0)
-                       count = 0;
-               return put_user(count, p);
-
-        case SNDCTL_DSP_GETOPTR:
-               if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               es1371_update_ptr(s);
-                cinfo.bytes = s->dma_dac1.total_bytes;
-               count = s->dma_dac1.count;
-               if (count < 0)
-                       count = 0;
-                cinfo.blocks = count >> s->dma_dac1.fragshift;
-                cinfo.ptr = s->dma_dac1.hwptr;
-               if (s->dma_dac1.mapped)
-                       s->dma_dac1.count &= s->dma_dac1.fragsize-1;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user((void __user *)arg, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 0;
-
-        case SNDCTL_DSP_GETBLKSIZE:
-               if ((val = prog_dmabuf_dac1(s)))
-                       return val;
-                return put_user(s->dma_dac1.fragsize, p);
-
-        case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, p))
-                       return -EFAULT;
-               s->dma_dac1.ossfragshift = val & 0xffff;
-               s->dma_dac1.ossmaxfrags = (val >> 16) & 0xffff;
-               if (s->dma_dac1.ossfragshift < 4)
-                       s->dma_dac1.ossfragshift = 4;
-               if (s->dma_dac1.ossfragshift > 15)
-                       s->dma_dac1.ossfragshift = 15;
-               if (s->dma_dac1.ossmaxfrags < 4)
-                       s->dma_dac1.ossmaxfrags = 4;
-               return 0;
-
-        case SNDCTL_DSP_SUBDIVIDE:
-               if (s->dma_dac1.subdivision)
-                       return -EINVAL;
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 1 && val != 2 && val != 4)
-                       return -EINVAL;
-               s->dma_dac1.subdivision = val;
-               return 0;
-
-        case SOUND_PCM_READ_RATE:
-               return put_user(s->dac1rate, p);
-
-        case SOUND_PCM_READ_CHANNELS:
-               return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, p);
-
-        case SOUND_PCM_READ_BITS:
-               return put_user((s->sctrl & SCTRL_P1SEB) ? 16 : 8, p);
-
-        case SOUND_PCM_WRITE_FILTER:
-        case SNDCTL_DSP_SETSYNCRO:
-        case SOUND_PCM_READ_FILTER:
-                return -EINVAL;
-               
-       }
-       return mixdev_ioctl(s->codec, cmd, arg);
-}
-
-static int es1371_open_dac(struct inode *inode, struct file *file)
-{
-       int minor = iminor(inode);
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       struct list_head *list;
-       struct es1371_state *s;
-
-       for (list = devs.next; ; list = list->next) {
-               if (list == &devs)
-                       return -ENODEV;
-               s = list_entry(list, struct es1371_state, devs);
-               if (!((s->dev_dac ^ minor) & ~0xf))
-                       break;
-       }
-               VALIDATE_STATE(s);
-               /* we allow opening with O_RDWR, most programs do it although they will only write */
-#if 0
-       if (file->f_mode & FMODE_READ)
-               return -EPERM;
-#endif
-       if (!(file->f_mode & FMODE_WRITE))
-               return -EINVAL;
-               file->private_data = s;
-       /* wait for device to become free */
-       mutex_lock(&s->open_mutex);
-       while (s->open_mode & FMODE_DAC) {
-               if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_mutex);
-                       return -EBUSY;
-               }
-               add_wait_queue(&s->open_wait, &wait);
-               __set_current_state(TASK_INTERRUPTIBLE);
-               mutex_unlock(&s->open_mutex);
-               schedule();
-               remove_wait_queue(&s->open_wait, &wait);
-               set_current_state(TASK_RUNNING);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&s->open_mutex);
-       }
-       s->dma_dac1.ossfragshift = s->dma_dac1.ossmaxfrags = s->dma_dac1.subdivision = 0;
-       s->dma_dac1.enabled = 1;
-       set_dac1_rate(s, 8000);
-       spin_lock_irqsave(&s->lock, flags);
-       s->sctrl &= ~SCTRL_P1FMT;
-       if ((minor & 0xf) == SND_DEV_DSP16)
-               s->sctrl |= ES1371_FMT_S16_MONO << SCTRL_SH_P1FMT;
-       else
-               s->sctrl |= ES1371_FMT_U8_MONO << SCTRL_SH_P1FMT;
-       outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-       spin_unlock_irqrestore(&s->lock, flags);
-       s->open_mode |= FMODE_DAC;
-       mutex_unlock(&s->open_mutex);
-       return nonseekable_open(inode, file);
-}
-
-static int es1371_release_dac(struct inode *inode, struct file *file)
-{
-       struct es1371_state *s = (struct es1371_state *)file->private_data;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-       drain_dac1(s, file->f_flags & O_NONBLOCK);
-       mutex_lock(&s->open_mutex);
-       stop_dac1(s);
-       dealloc_dmabuf(s, &s->dma_dac1);
-       s->open_mode &= ~FMODE_DAC;
-       mutex_unlock(&s->open_mutex);
-       wake_up(&s->open_wait);
-       unlock_kernel();
-       return 0;
-}
-
-static /*const*/ struct file_operations es1371_dac_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .write          = es1371_write_dac,
-       .poll           = es1371_poll_dac,
-       .ioctl          = es1371_ioctl_dac,
-       .mmap           = es1371_mmap_dac,
-       .open           = es1371_open_dac,
-       .release        = es1371_release_dac,
-};
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t es1371_midi_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct es1371_state *s = (struct es1371_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned ptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (!access_ok(VERIFY_WRITE, buffer, count))
-               return -EFAULT;
-       if (count == 0)
-               return 0;
-       ret = 0;
-        add_wait_queue(&s->midi.iwait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               ptr = s->midi.ird;
-               cnt = MIDIINBUF - ptr;
-               if (s->midi.icnt < cnt)
-                       cnt = s->midi.icnt;
-               if (cnt <= 0)
-                       __set_current_state(TASK_INTERRUPTIBLE);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               break;
-                       }
-                       schedule();
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               break;
-                       }
-                       continue;
-               }
-               if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       break;
-               }
-               ptr = (ptr + cnt) % MIDIINBUF;
-               spin_lock_irqsave(&s->lock, flags);
-               s->midi.ird = ptr;
-               s->midi.icnt -= cnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               break;
-       }
-       __set_current_state(TASK_RUNNING);
-       remove_wait_queue(&s->midi.iwait, &wait);
-       return ret;
-}
-
-static ssize_t es1371_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct es1371_state *s = (struct es1371_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned ptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-       if (count == 0)
-               return 0;
-       ret = 0;
-        add_wait_queue(&s->midi.owait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               ptr = s->midi.owr;
-               cnt = MIDIOUTBUF - ptr;
-               if (s->midi.ocnt + cnt > MIDIOUTBUF)
-                       cnt = MIDIOUTBUF - s->midi.ocnt;
-               if (cnt <= 0) {
-                       __set_current_state(TASK_INTERRUPTIBLE);
-                       es1371_handle_midi(s);
-               }
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               break;
-                       }
-                       schedule();
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               break;
-                       }
-                       continue;
-               }
-               if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       break;
-               }
-               ptr = (ptr + cnt) % MIDIOUTBUF;
-               spin_lock_irqsave(&s->lock, flags);
-               s->midi.owr = ptr;
-               s->midi.ocnt += cnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               spin_lock_irqsave(&s->lock, flags);
-               es1371_handle_midi(s);
-               spin_unlock_irqrestore(&s->lock, flags);
-       }
-       __set_current_state(TASK_RUNNING);
-       remove_wait_queue(&s->midi.owait, &wait);
-       return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int es1371_midi_poll(struct file *file, struct poll_table_struct *wait)
-{
-       struct es1371_state *s = (struct es1371_state *)file->private_data;
-       unsigned long flags;
-       unsigned int mask = 0;
-
-       VALIDATE_STATE(s);
-       if (file->f_mode & FMODE_WRITE)
-               poll_wait(file, &s->midi.owait, wait);
-       if (file->f_mode & FMODE_READ)
-               poll_wait(file, &s->midi.iwait, wait);
-       spin_lock_irqsave(&s->lock, flags);
-       if (file->f_mode & FMODE_READ) {
-               if (s->midi.icnt > 0)
-                       mask |= POLLIN | POLLRDNORM;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               if (s->midi.ocnt < MIDIOUTBUF)
-                       mask |= POLLOUT | POLLWRNORM;
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       return mask;
-}
-
-static int es1371_midi_open(struct inode *inode, struct file *file)
-{
-       int minor = iminor(inode);
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       struct list_head *list;
-       struct es1371_state *s;
-
-       for (list = devs.next; ; list = list->next) {
-               if (list == &devs)
-                       return -ENODEV;
-               s = list_entry(list, struct es1371_state, devs);
-               if (s->dev_midi == minor)
-                       break;
-       }
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       /* wait for device to become free */
-       mutex_lock(&s->open_mutex);
-       while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
-               if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_mutex);
-                       return -EBUSY;
-               }
-               add_wait_queue(&s->open_wait, &wait);
-               __set_current_state(TASK_INTERRUPTIBLE);
-               mutex_unlock(&s->open_mutex);
-               schedule();
-               remove_wait_queue(&s->open_wait, &wait);
-               set_current_state(TASK_RUNNING);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&s->open_mutex);
-       }
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
-               s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-               s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
-               outb(UCTRL_CNTRL_SWR, s->io+ES1371_REG_UART_CONTROL);
-               outb(0, s->io+ES1371_REG_UART_CONTROL);
-               outb(0, s->io+ES1371_REG_UART_TEST);
-       }
-       if (file->f_mode & FMODE_READ) {
-               s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
-       }
-       s->ctrl |= CTRL_UART_EN;
-       outl(s->ctrl, s->io+ES1371_REG_CONTROL);
-       es1371_handle_midi(s);
-       spin_unlock_irqrestore(&s->lock, flags);
-       s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
-       mutex_unlock(&s->open_mutex);
-       return nonseekable_open(inode, file);
-}
-
-static int es1371_midi_release(struct inode *inode, struct file *file)
-{
-       struct es1371_state *s = (struct es1371_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       unsigned count, tmo;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-       if (file->f_mode & FMODE_WRITE) {
-               add_wait_queue(&s->midi.owait, &wait);
-               for (;;) {
-                       __set_current_state(TASK_INTERRUPTIBLE);
-                       spin_lock_irqsave(&s->lock, flags);
-                       count = s->midi.ocnt;
-                       spin_unlock_irqrestore(&s->lock, flags);
-                       if (count <= 0)
-                               break;
-                       if (signal_pending(current))
-                               break;
-                       if (file->f_flags & O_NONBLOCK)
-                               break;
-                       tmo = (count * HZ) / 3100;
-                       if (!schedule_timeout(tmo ? : 1) && tmo)
-                               printk(KERN_DEBUG PFX "midi timed out??\n");
-               }
-               remove_wait_queue(&s->midi.owait, &wait);
-               set_current_state(TASK_RUNNING);
-       }
-       mutex_lock(&s->open_mutex);
-       s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE));
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
-               s->ctrl &= ~CTRL_UART_EN;
-               outl(s->ctrl, s->io+ES1371_REG_CONTROL);
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       mutex_unlock(&s->open_mutex);
-       wake_up(&s->open_wait);
-       unlock_kernel();
-       return 0;
-}
-
-static /*const*/ struct file_operations es1371_midi_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .read           = es1371_midi_read,
-       .write          = es1371_midi_write,
-       .poll           = es1371_midi_poll,
-       .open           = es1371_midi_open,
-       .release        = es1371_midi_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-/*
- * for debugging purposes, we'll create a proc device that dumps the
- * CODEC chipstate
- */
-
-#ifdef ES1371_DEBUG
-static int proc_es1371_dump (char *buf, char **start, off_t fpos, int length, int *eof, void *data)
-{
-       struct es1371_state *s;
-        int cnt, len = 0;
-
-       if (list_empty(&devs))
-               return 0;
-       s = list_entry(devs.next, struct es1371_state, devs);
-        /* print out header */
-        len += sprintf(buf + len, "\t\tCreative ES137x Debug Dump-o-matic\n");
-
-        /* print out CODEC state */
-        len += sprintf (buf + len, "AC97 CODEC state\n");
-       for (cnt=0; cnt <= 0x7e; cnt = cnt +2)
-                len+= sprintf (buf + len, "reg:0x%02x  val:0x%04x\n", cnt, rdcodec(s->codec, cnt));
-
-        if (fpos >=len){
-                *start = buf;
-                *eof =1;
-                return 0;
-        }
-        *start = buf + fpos;
-        if ((len -= fpos) > length)
-                return length;
-        *eof =1;
-        return len;
-
-}
-#endif /* ES1371_DEBUG */
-
-/* --------------------------------------------------------------------- */
-
-/* maximum number of devices; only used for command line params */
-#define NR_DEVICE 5
-
-static int spdif[NR_DEVICE];
-static int nomix[NR_DEVICE];
-static int amplifier[NR_DEVICE];
-
-static unsigned int devindex;
-
-module_param_array(spdif, bool, NULL, 0);
-MODULE_PARM_DESC(spdif, "if 1 the output is in S/PDIF digital mode");
-module_param_array(nomix, bool, NULL, 0);
-MODULE_PARM_DESC(nomix, "if 1 no analog audio is mixed to the digital output");
-module_param_array(amplifier, bool, NULL, 0);
-MODULE_PARM_DESC(amplifier, "Set to 1 if the machine needs the amp control enabling (many laptops)");
-
-MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
-MODULE_DESCRIPTION("ES1371 AudioPCI97 Driver");
-MODULE_LICENSE("GPL");
-
-
-/* --------------------------------------------------------------------- */
-
-static struct initvol {
-       int mixch;
-       int vol;
-} initvol[] __devinitdata = {
-       { SOUND_MIXER_WRITE_LINE, 0x4040 },
-       { SOUND_MIXER_WRITE_CD, 0x4040 },
-       { MIXER_WRITE(SOUND_MIXER_VIDEO), 0x4040 },
-       { SOUND_MIXER_WRITE_LINE1, 0x4040 },
-       { SOUND_MIXER_WRITE_PCM, 0x4040 },
-       { SOUND_MIXER_WRITE_VOLUME, 0x4040 },
-       { MIXER_WRITE(SOUND_MIXER_PHONEOUT), 0x4040 },
-       { SOUND_MIXER_WRITE_OGAIN, 0x4040 },
-       { MIXER_WRITE(SOUND_MIXER_PHONEIN), 0x4040 },
-       { SOUND_MIXER_WRITE_SPEAKER, 0x4040 },
-       { SOUND_MIXER_WRITE_MIC, 0x4040 },
-       { SOUND_MIXER_WRITE_RECLEV, 0x4040 },
-       { SOUND_MIXER_WRITE_IGAIN, 0x4040 }
-};
-
-static struct
-{
-       short svid, sdid;
-} amplifier_needed[] = 
-{
-       { 0x107B, 0x2150 },             /* Gateway Solo 2150 */
-       { 0x13BD, 0x100C },             /* Mebius PC-MJ100V */
-       { 0x1102, 0x5938 },             /* Targa Xtender 300 */
-       { 0x1102, 0x8938 },             /* IPC notebook */
-       { PCI_ANY_ID, PCI_ANY_ID }
-};
-
-#ifdef SUPPORT_JOYSTICK
-
-static int __devinit es1371_register_gameport(struct es1371_state *s)
-{
-       struct gameport *gp;
-       int gpio;
-
-       for (gpio = 0x218; gpio >= 0x200; gpio -= 0x08)
-               if (request_region(gpio, JOY_EXTENT, "es1371"))
-                       break;
-
-       if (gpio < 0x200) {
-               printk(KERN_ERR PFX "no free joystick address found\n");
-               return -EBUSY;
-       }
-
-       s->gameport = gp = gameport_allocate_port();
-       if (!gp) {
-               printk(KERN_ERR PFX "can not allocate memory for gameport\n");
-               release_region(gpio, JOY_EXTENT);
-               return -ENOMEM;
-       }
-
-       gameport_set_name(gp, "ESS1371 Gameport");
-       gameport_set_phys(gp, "isa%04x/gameport0", gpio);
-       gp->dev.parent = &s->dev->dev;
-       gp->io = gpio;
-
-       s->ctrl |= CTRL_JYSTK_EN | (((gpio >> 3) & CTRL_JOY_MASK) << CTRL_JOY_SHIFT);
-       outl(s->ctrl, s->io + ES1371_REG_CONTROL);
-
-       gameport_register_port(gp);
-
-       return 0;
-}
-
-static inline void es1371_unregister_gameport(struct es1371_state *s)
-{
-       if (s->gameport) {
-               int gpio = s->gameport->io;
-               gameport_unregister_port(s->gameport);
-               release_region(gpio, JOY_EXTENT);
-
-       }
-}
-
-#else
-static inline int es1371_register_gameport(struct es1371_state *s) { return -ENOSYS; }
-static inline void es1371_unregister_gameport(struct es1371_state *s) { }
-#endif /* SUPPORT_JOYSTICK */
-
-
-static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
-{
-       struct es1371_state *s;
-       mm_segment_t fs;
-       int i, val, res = -1;
-       int idx;
-       unsigned long tmo;
-       signed long tmo2;
-       unsigned int cssr;
-
-       if ((res=pci_enable_device(pcidev)))
-               return res;
-
-       if (!(pci_resource_flags(pcidev, 0) & IORESOURCE_IO))
-               return -ENODEV;
-       if (pcidev->irq == 0) 
-               return -ENODEV;
-       i = pci_set_dma_mask(pcidev, DMA_32BIT_MASK);
-       if (i) {
-               printk(KERN_WARNING "es1371: architecture does not support 32bit PCI busmaster DMA\n");
-               return i;
-       }
-       if (!(s = kzalloc(sizeof(struct es1371_state), GFP_KERNEL))) {
-               printk(KERN_WARNING PFX "out of memory\n");
-               return -ENOMEM;
-       }
-       
-       s->codec = ac97_alloc_codec();
-       if(s->codec == NULL)
-               goto err_codec;
-               
-       init_waitqueue_head(&s->dma_adc.wait);
-       init_waitqueue_head(&s->dma_dac1.wait);
-       init_waitqueue_head(&s->dma_dac2.wait);
-       init_waitqueue_head(&s->open_wait);
-       init_waitqueue_head(&s->midi.iwait);
-       init_waitqueue_head(&s->midi.owait);
-       mutex_init(&s->open_mutex);
-       spin_lock_init(&s->lock);
-       s->magic = ES1371_MAGIC;
-       s->dev = pcidev;
-       s->io = pci_resource_start(pcidev, 0);
-       s->irq = pcidev->irq;
-       s->vendor = pcidev->vendor;
-       s->device = pcidev->device;
-       s->rev = pcidev->revision;
-       s->codec->private_data = s;
-       s->codec->id = 0;
-       s->codec->codec_read = rdcodec;
-       s->codec->codec_write = wrcodec;
-       printk(KERN_INFO PFX "found chip, vendor id 0x%04x device id 0x%04x revision 0x%02x\n",
-              s->vendor, s->device, s->rev);
-       if (!request_region(s->io, ES1371_EXTENT, "es1371")) {
-               printk(KERN_ERR PFX "io ports %#lx-%#lx in use\n", s->io, s->io+ES1371_EXTENT-1);
-               res = -EBUSY;
-               goto err_region;
-       }
-       if ((res=request_irq(s->irq, es1371_interrupt, IRQF_SHARED, "es1371",s))) {
-               printk(KERN_ERR PFX "irq %u in use\n", s->irq);
-               goto err_irq;
-       }
-       printk(KERN_INFO PFX "found es1371 rev %d at io %#lx irq %u\n",
-              s->rev, s->io, s->irq);
-       /* register devices */
-       if ((res=(s->dev_audio = register_sound_dsp(&es1371_audio_fops,-1)))<0)
-               goto err_dev1;
-       if ((res=(s->codec->dev_mixer = register_sound_mixer(&es1371_mixer_fops, -1))) < 0)
-               goto err_dev2;
-       if ((res=(s->dev_dac = register_sound_dsp(&es1371_dac_fops, -1))) < 0)
-               goto err_dev3;
-       if ((res=(s->dev_midi = register_sound_midi(&es1371_midi_fops, -1)))<0 )
-               goto err_dev4;
-#ifdef ES1371_DEBUG
-       /* initialize the debug proc device */
-       s->ps = create_proc_read_entry("es1371",0,NULL,proc_es1371_dump,NULL);
-#endif /* ES1371_DEBUG */
-       
-       /* initialize codec registers */
-       s->ctrl = 0;
-
-       /* Check amplifier requirements */
-       
-       if (amplifier[devindex])
-               s->ctrl |= CTRL_GPIO_OUT0;
-       else for(idx = 0; amplifier_needed[idx].svid != PCI_ANY_ID; idx++)
-       {
-               if(pcidev->subsystem_vendor == amplifier_needed[idx].svid &&
-                  pcidev->subsystem_device == amplifier_needed[idx].sdid)
-               {
-                       s->ctrl |= CTRL_GPIO_OUT0;   /* turn internal amplifier on */
-                       printk(KERN_INFO PFX "Enabling internal amplifier.\n");
-               }
-       }
-
-       s->sctrl = 0;
-       cssr = 0;
-       s->spdif_volume = -1;
-       /* check to see if s/pdif mode is being requested */
-       if (spdif[devindex]) {
-               if (s->rev >= 4) {
-                       printk(KERN_INFO PFX "enabling S/PDIF output\n");
-                       s->spdif_volume = 0;
-                       cssr |= STAT_EN_SPDIF;
-                       s->ctrl |= CTRL_SPDIFEN_B;
-                       if (nomix[devindex]) /* don't mix analog inputs to s/pdif output */
-                               s->ctrl |= CTRL_RECEN_B;
-               } else {
-                       printk(KERN_ERR PFX "revision %d does not support S/PDIF\n", s->rev);
-               }
-       }
-       /* initialize the chips */
-       outl(s->ctrl, s->io+ES1371_REG_CONTROL);
-       outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-       outl(LEGACY_JFAST, s->io+ES1371_REG_LEGACY);
-       pci_set_master(pcidev);  /* enable bus mastering */
-       /* if we are a 5880 turn on the AC97 */
-       if (s->vendor == PCI_VENDOR_ID_ENSONIQ &&
-           ((s->device == PCI_DEVICE_ID_ENSONIQ_CT5880 && s->rev >= CT5880REV_CT5880_C) || 
-            (s->device == PCI_DEVICE_ID_ENSONIQ_ES1371 && s->rev == ES1371REV_CT5880_A) || 
-            (s->device == PCI_DEVICE_ID_ENSONIQ_ES1371 && s->rev == ES1371REV_ES1373_8))) { 
-               cssr |= CSTAT_5880_AC97_RST;
-               outl(cssr, s->io+ES1371_REG_STATUS);
-               /* need to delay around 20ms(bleech) to give
-                  some CODECs enough time to wakeup */
-               tmo = jiffies + (HZ / 50) + 1;
-               for (;;) {
-                       tmo2 = tmo - jiffies;
-                       if (tmo2 <= 0)
-                               break;
-                       schedule_timeout(tmo2);
-               }
-       }
-       /* AC97 warm reset to start the bitclk */
-       outl(s->ctrl | CTRL_SYNCRES, s->io+ES1371_REG_CONTROL);
-       udelay(2);
-       outl(s->ctrl, s->io+ES1371_REG_CONTROL);
-       /* init the sample rate converter */
-       src_init(s);
-       /* codec init */
-       if (!ac97_probe_codec(s->codec)) {
-               res = -ENODEV;
-               goto err_gp;
-       }
-       /* set default values */
-
-       fs = get_fs();
-       set_fs(KERNEL_DS);
-       val = SOUND_MASK_LINE;
-       mixdev_ioctl(s->codec, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
-       for (i = 0; i < ARRAY_SIZE(initvol); i++) {
-               val = initvol[i].vol;
-               mixdev_ioctl(s->codec, initvol[i].mixch, (unsigned long)&val);
-       }
-       /* mute master and PCM when in S/PDIF mode */
-       if (s->spdif_volume != -1) {
-               val = 0x0000;
-               s->codec->mixer_ioctl(s->codec, SOUND_MIXER_WRITE_VOLUME, (unsigned long)&val);
-               s->codec->mixer_ioctl(s->codec, SOUND_MIXER_WRITE_PCM, (unsigned long)&val);
-       }
-       set_fs(fs);
-       /* turn on S/PDIF output driver if requested */
-       outl(cssr, s->io+ES1371_REG_STATUS);
-
-       es1371_register_gameport(s);
-
-       /* store it in the driver field */
-       pci_set_drvdata(pcidev, s);
-       /* put it into driver list */
-       list_add_tail(&s->devs, &devs);
-       /* increment devindex */
-       if (devindex < NR_DEVICE-1)
-               devindex++;
-       return 0;
-
- err_gp:
-#ifdef ES1371_DEBUG
-       if (s->ps)
-               remove_proc_entry("es1371", NULL);
-#endif
-       unregister_sound_midi(s->dev_midi);
- err_dev4:
-       unregister_sound_dsp(s->dev_dac);
- err_dev3:
-       unregister_sound_mixer(s->codec->dev_mixer);
- err_dev2:
-       unregister_sound_dsp(s->dev_audio);
- err_dev1:
-       printk(KERN_ERR PFX "cannot register misc device\n");
-       free_irq(s->irq, s);
- err_irq:
-       release_region(s->io, ES1371_EXTENT);
- err_region:
- err_codec:
-       ac97_release_codec(s->codec);
-       kfree(s);
-       return res;
-}
-
-static void __devexit es1371_remove(struct pci_dev *dev)
-{
-       struct es1371_state *s = pci_get_drvdata(dev);
-
-       if (!s)
-               return;
-       list_del(&s->devs);
-#ifdef ES1371_DEBUG
-       if (s->ps)
-               remove_proc_entry("es1371", NULL);
-#endif /* ES1371_DEBUG */
-       outl(0, s->io+ES1371_REG_CONTROL); /* switch everything off */
-       outl(0, s->io+ES1371_REG_SERIAL_CONTROL); /* clear serial interrupts */
-       synchronize_irq(s->irq);
-       free_irq(s->irq, s);
-       es1371_unregister_gameport(s);
-       release_region(s->io, ES1371_EXTENT);
-       unregister_sound_dsp(s->dev_audio);
-       unregister_sound_mixer(s->codec->dev_mixer);
-       unregister_sound_dsp(s->dev_dac);
-       unregister_sound_midi(s->dev_midi);
-       ac97_release_codec(s->codec);
-       kfree(s);
-       pci_set_drvdata(dev, NULL);
-}
-
-static struct pci_device_id id_table[] = {
-       { PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_ES1371, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
-       { PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_CT5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
-       { PCI_VENDOR_ID_ECTIVA, PCI_DEVICE_ID_ECTIVA_EV1938, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
-       { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, id_table);
-
-static struct pci_driver es1371_driver = {
-       .name           = "es1371",
-       .id_table       = id_table,
-       .probe          = es1371_probe,
-       .remove         = __devexit_p(es1371_remove),
-};
-
-static int __init init_es1371(void)
-{
-       printk(KERN_INFO PFX "version v0.32 time " __TIME__ " " __DATE__ "\n");
-       return pci_register_driver(&es1371_driver);
-}
-
-static void __exit cleanup_es1371(void)
-{
-       printk(KERN_INFO PFX "unloading\n");
-       pci_unregister_driver(&es1371_driver);
-}
-
-module_init(init_es1371);
-module_exit(cleanup_es1371);
-
-/* --------------------------------------------------------------------- */
-
-#ifndef MODULE
-
-/* format is: es1371=[spdif,[nomix,[amplifier]]] */
-
-static int __init es1371_setup(char *str)
-{
-       static unsigned __initdata nr_dev = 0;
-
-       if (nr_dev >= NR_DEVICE)
-               return 0;
-
-       (void)
-        ((get_option(&str, &spdif[nr_dev]) == 2)
-         && (get_option(&str, &nomix[nr_dev]) == 2)
-         && (get_option(&str, &amplifier[nr_dev])));
-
-       nr_dev++;
-       return 1;
-}
-
-__setup("es1371=", es1371_setup);
-
-#endif /* MODULE */
index f70286a7364ac3d27a90d16844bfcf8817c8ab90..26819e2f5761810eeb3346c1224f740c4d00b276 100644 (file)
@@ -191,7 +191,7 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip)
 
        /* Init audio core.
         * This must be done before we do request_irq otherwise we can get spurious
-        * interupts that we do not handle properly and make a mess of things */
+        * interrupts that we do not handle properly and make a mess of things */
        if ((err = vortex_core_init(chip)) != 0) {
                printk(KERN_ERR "hw core init failed\n");
                goto core_out;
index 91f9e6a112ffd6749421fa8ba9d4ec93cc50b7d9..2dba752faf4e6281a2a31bddf4a0998197f4d535 100644 (file)
@@ -165,7 +165,7 @@ struct snd_bt87x_board {
        unsigned no_digital:1;  /* No digital input */
 };
 
-static const __devinitdata struct snd_bt87x_board snd_bt87x_boards[] = {
+static __devinitdata struct snd_bt87x_board snd_bt87x_boards[] = {
        [SND_BT87X_BOARD_UNKNOWN] = {
                .dig_rate = 32000, /* just a guess */
        },
@@ -848,7 +848,7 @@ static int __devinit snd_bt87x_detect_card(struct pci_dev *pci)
        int i;
        const struct pci_device_id *supported;
 
-       supported = pci_match_device(&driver, pci);
+       supported = pci_match_id(snd_bt87x_ids, pci);
        if (supported && supported->driver_data > 0)
                return supported->driver_data;
 
index 187533e477c6e178d2b57cc8575548778448ffb2..ad4cb38109fcc2de06f0891ea737adc91769f2eb 100644 (file)
@@ -626,24 +626,19 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
                snd_hda_get_codec_name(codec, bus->card->mixername,
                                       sizeof(bus->card->mixername));
 
-#ifdef CONFIG_SND_HDA_GENERIC
        if (is_generic_config(codec)) {
                err = snd_hda_parse_generic_codec(codec);
                goto patched;
        }
-#endif
        if (codec->preset && codec->preset->patch) {
                err = codec->preset->patch(codec);
                goto patched;
        }
 
        /* call the default parser */
-#ifdef CONFIG_SND_HDA_GENERIC
        err = snd_hda_parse_generic_codec(codec);
-#else
-       printk(KERN_ERR "hda-codec: No codec parser is available\n");
-       err = -ENODEV;
-#endif
+       if (err < 0)
+               printk(KERN_ERR "hda-codec: No codec parser is available\n");
 
  patched:
        if (err < 0) {
index a79d0ed5469c297215d37d741f2a569e905148c5..20c5e6250374b5d1a61d96e01d0789035b140bf5 100644 (file)
@@ -245,7 +245,14 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
 /*
  * generic codec parser
  */
+#ifdef CONFIG_SND_HDA_GENERIC
 int snd_hda_parse_generic_codec(struct hda_codec *codec);
+#else
+static inline int snd_hda_parse_generic_codec(struct hda_codec *codec)
+{
+       return -ENODEV;
+}
+#endif
 
 /*
  * generic proc interface
@@ -303,16 +310,17 @@ enum {
 
 extern const char *auto_pin_cfg_labels[AUTO_PIN_LAST];
 
+#define AUTO_CFG_MAX_OUTS      5
+
 struct auto_pin_cfg {
        int line_outs;
-       hda_nid_t line_out_pins[5]; /* sorted in the order of
-                                    * Front/Surr/CLFE/Side
-                                    */
+       /* sorted in the order of Front/Surr/CLFE/Side */
+       hda_nid_t line_out_pins[AUTO_CFG_MAX_OUTS];
        int speaker_outs;
-       hda_nid_t speaker_pins[5];
+       hda_nid_t speaker_pins[AUTO_CFG_MAX_OUTS];
        int hp_outs;
        int line_out_type;      /* AUTO_PIN_XXX_OUT */
-       hda_nid_t hp_pins[5];
+       hda_nid_t hp_pins[AUTO_CFG_MAX_OUTS];
        hda_nid_t input_pins[AUTO_PIN_LAST];
        hda_nid_t dig_out_pin;
        hda_nid_t dig_in_pin;
index 54cfd4526d209e9e58190a5f287378fd57793dd1..0ee8ae4d4410b89c7405ac3c5c25ba111fc8703d 100644 (file)
@@ -72,7 +72,7 @@ struct ad198x_spec {
        unsigned int num_kctl_alloc, num_kctl_used;
        struct snd_kcontrol_new *kctl_alloc;
        struct hda_input_mux private_imux;
-       hda_nid_t private_dac_nids[4];
+       hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
 
        unsigned int jack_present :1;
 
@@ -612,7 +612,8 @@ static void ad1986a_hp_automute(struct hda_codec *codec)
        unsigned int present;
 
        present = snd_hda_codec_read(codec, 0x1a, 0, AC_VERB_GET_PIN_SENSE, 0);
-       spec->jack_present = (present & 0x80000000) != 0;
+       /* Lenovo N100 seems to report the reversed bit for HP jack-sensing */
+       spec->jack_present = !(present & 0x80000000);
        ad1986a_update_hp(codec);
 }
 
index 2468f31712221842ef4e813ffbef9547a8b327e3..6c54793bf424cf4e52d4a922ad4532fa1726a613 100644 (file)
@@ -50,7 +50,7 @@ struct cmi_spec {
 
        /* playback */
        struct hda_multi_out multiout;
-       hda_nid_t dac_nids[4];          /* NID for each DAC */
+       hda_nid_t dac_nids[AUTO_CFG_MAX_OUTS];  /* NID for each DAC */
        int num_dacs;
 
        /* capture */
@@ -73,7 +73,6 @@ struct cmi_spec {
        unsigned int pin_def_confs;
 
        /* multichannel pins */
-       hda_nid_t multich_pin[4];       /* max 8-channel */
        struct hda_verb multi_init[9];  /* 2 verbs for each pin + terminator */
 };
 
index 080e3001d9c548d0e775425b7ce94b743de88782..6aa073986747bd20a26c0c7a4e1e154a173e5c39 100644 (file)
@@ -85,7 +85,7 @@ struct conexant_spec {
        unsigned int num_kctl_alloc, num_kctl_used;
        struct snd_kcontrol_new *kctl_alloc;
        struct hda_input_mux private_imux;
-       hda_nid_t private_dac_nids[4];
+       hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
 
 };
 
@@ -554,10 +554,16 @@ static struct snd_kcontrol_new cxt5045_mixers[] = {
                .get = conexant_mux_enum_get,
                .put = conexant_mux_enum_put
        },
-       HDA_CODEC_VOLUME("Int Mic Volume", 0x1a, 0x01, HDA_INPUT),
-       HDA_CODEC_MUTE("Int Mic Switch", 0x1a, 0x01, HDA_INPUT),
-       HDA_CODEC_VOLUME("Ext Mic Volume", 0x1a, 0x02, HDA_INPUT),
-       HDA_CODEC_MUTE("Ext Mic Switch", 0x1a, 0x02, HDA_INPUT),
+       HDA_CODEC_VOLUME("Int Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
+       HDA_CODEC_MUTE("Int Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
+       HDA_CODEC_VOLUME("Ext Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
+       HDA_CODEC_MUTE("Ext Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
+       HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
+       HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
+       HDA_CODEC_MUTE("Int Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
+       HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
+       HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
        HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol),
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -576,16 +582,15 @@ static struct hda_verb cxt5045_init_verbs[] = {
        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
        /* HP, Amp  */
-       {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
-       {0x17, AC_VERB_SET_CONNECT_SEL,0x01},
-       {0x17, AC_VERB_SET_AMP_GAIN_MUTE,
-        AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x01},
-       {0x17, AC_VERB_SET_AMP_GAIN_MUTE,
-        AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x02},
-       {0x17, AC_VERB_SET_AMP_GAIN_MUTE,
-        AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03},
-       {0x17, AC_VERB_SET_AMP_GAIN_MUTE,
-        AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x04},
+       {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       {0x10, AC_VERB_SET_CONNECT_SEL, 0x1},
+       {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+       {0x11, AC_VERB_SET_CONNECT_SEL, 0x1},
+       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
        /* Record selector: Int mic */
        {0x1a, AC_VERB_SET_CONNECT_SEL,0x1},
        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
index 53b0428abfc2059d6f2918b584290b29f2399f4f..d9f78c809ee977e8a79ff926be121d5d93d7cc0c 100644 (file)
@@ -238,7 +238,7 @@ struct alc_spec {
        unsigned int num_kctl_alloc, num_kctl_used;
        struct snd_kcontrol_new *kctl_alloc;
        struct hda_input_mux private_imux;
-       hda_nid_t private_dac_nids[5];
+       hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
 
        /* hooks */
        void (*init_hook)(struct hda_codec *codec);
index bf950195107c0a3ec4648197b7fb4f15a605dcf0..f9b2c435a1303ec767193b6d7dcb7197dd60497d 100644 (file)
@@ -111,6 +111,7 @@ struct sigmatel_spec {
        unsigned int alt_switch: 1;
        unsigned int hp_detect: 1;
        unsigned int gpio_mute: 1;
+       unsigned int no_vol_knob :1;
 
        unsigned int gpio_mask, gpio_data;
 
@@ -1930,7 +1931,8 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
        }
        if (spec->multiout.hp_nid) {
                const char *pfx;
-               if (old_num_dacs == spec->multiout.num_dacs)
+               if (old_num_dacs == spec->multiout.num_dacs &&
+                   spec->no_vol_knob)
                        pfx = "Master";
                else
                        pfx = "Headphone";
@@ -2487,6 +2489,7 @@ static int patch_stac9200(struct hda_codec *codec)
        codec->spec = spec;
        spec->num_pins = ARRAY_SIZE(stac9200_pin_nids);
        spec->pin_nids = stac9200_pin_nids;
+       spec->no_vol_knob = 1;
        spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS,
                                                        stac9200_models,
                                                        stac9200_cfg_tbl);
@@ -2541,6 +2544,7 @@ static int patch_stac925x(struct hda_codec *codec)
        codec->spec = spec;
        spec->num_pins = ARRAY_SIZE(stac925x_pin_nids);
        spec->pin_nids = stac925x_pin_nids;
+       spec->no_vol_knob = 1;
        spec->board_config = snd_hda_check_board_config(codec, STAC_925x_MODELS,
                                                        stac925x_models,
                                                        stac925x_cfg_tbl);
index 33b5e1ffa8175d27e6c739a4bcdcb9a3562007c9..4cdf3e6df4baf20fa4ce2570c7cda55ef72a3d21 100644 (file)
@@ -114,7 +114,7 @@ struct via_spec {
        unsigned int num_kctl_alloc, num_kctl_used;
        struct snd_kcontrol_new *kctl_alloc;
        struct hda_input_mux private_imux;
-       hda_nid_t private_dac_nids[4];  
+       hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
 
 #ifdef CONFIG_SND_HDA_POWER_SAVE
        struct hda_loopback_check loopback;
index a1aa89f2faf3bc9e6f25ccb3784871d0631a49dd..566b5ab9d4e892008c95c5658746b7f4fb3aff28 100644 (file)
@@ -236,8 +236,8 @@ int __init snd_pmac_attach_beep(struct snd_pmac *chip)
        input_dev->id.product = 0x0001;
        input_dev->id.version = 0x0100;
 
-       input_dev->evbit[0] = BIT(EV_SND);
-       input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+       input_dev->evbit[0] = BIT_MASK(EV_SND);
+       input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
        input_dev->event = snd_pmac_beep_event;
        input_dev->dev.parent = &chip->pdev->dev;
        input_set_drvdata(input_dev, chip);
index 131ec4812288e6043a1cfb2fa8bad7001ae6585e..88dc840152ce9369f57956c2d43cde2ac0e936ab 100644 (file)
@@ -106,11 +106,14 @@ static void spu_write_wait(void)
 static void spu_memset(u32 toi, u32 what, int length)
 {
        int i;
+       unsigned long flags;
        snd_assert(length % 4 == 0, return);
        for (i = 0; i < length; i++) {
                if (!(i % 8))
                        spu_write_wait();
+               local_irq_save(flags);
                writel(what, toi + SPU_MEMORY_BASE);
+               local_irq_restore(flags);
                toi++;
        }
 }
@@ -118,6 +121,7 @@ static void spu_memset(u32 toi, u32 what, int length)
 /* spu_memload - write to SPU address space */
 static void spu_memload(u32 toi, void *from, int length)
 {
+       unsigned long flags;
        u32 *froml = from;
        u32 __iomem *to = (u32 __iomem *) (SPU_MEMORY_BASE + toi);
        int i;
@@ -128,7 +132,9 @@ static void spu_memload(u32 toi, void *from, int length)
                if (!(i % 8))
                        spu_write_wait();
                val = *froml;
+               local_irq_save(flags);
                writel(val, to);
+               local_irq_restore(flags);
                froml++;
                to++;
        }
@@ -138,28 +144,36 @@ static void spu_memload(u32 toi, void *from, int length)
 static void spu_disable(void)
 {
        int i;
+       unsigned long flags;
        u32 regval;
        spu_write_wait();
        regval = readl(ARM_RESET_REGISTER);
        regval |= 1;
        spu_write_wait();
+       local_irq_save(flags);
        writel(regval, ARM_RESET_REGISTER);
+       local_irq_restore(flags);
        for (i = 0; i < 64; i++) {
                spu_write_wait();
                regval = readl(SPU_REGISTER_BASE + (i * 0x80));
                regval = (regval & ~0x4000) | 0x8000;
                spu_write_wait();
+               local_irq_save(flags);
                writel(regval, SPU_REGISTER_BASE + (i * 0x80));
+               local_irq_restore(flags);
        }
 }
 
 /* spu_enable - set spu registers to enable sound output */
 static void spu_enable(void)
 {
+       unsigned long flags;
        u32 regval = readl(ARM_RESET_REGISTER);
        regval &= ~1;
        spu_write_wait();
+       local_irq_save(flags);
        writel(regval, ARM_RESET_REGISTER);
+       local_irq_restore(flags);
 }
 
 /* 
@@ -168,25 +182,34 @@ static void spu_enable(void)
 */
 static void spu_reset(void)
 {
+       unsigned long flags;
        spu_disable();
        spu_memset(0, 0, 0x200000 / 4);
        /* Put ARM7 in endless loop */
+       local_irq_save(flags);
        ctrl_outl(0xea000002, SPU_MEMORY_BASE);
+       local_irq_restore(flags);
        spu_enable();
 }
 
 /* aica_chn_start - write to spu to start playback */
 static void aica_chn_start(void)
 {
+       unsigned long flags;
        spu_write_wait();
+       local_irq_save(flags);
        writel(AICA_CMD_KICK | AICA_CMD_START, (u32 *) AICA_CONTROL_POINT);
+       local_irq_restore(flags);
 }
 
 /* aica_chn_halt - write to spu to halt playback */
 static void aica_chn_halt(void)
 {
+       unsigned long flags;
        spu_write_wait();
+       local_irq_save(flags);
        writel(AICA_CMD_KICK | AICA_CMD_STOP, (u32 *) AICA_CONTROL_POINT);
+       local_irq_restore(flags);
 }
 
 /* ALSA code below */
@@ -213,12 +236,13 @@ static int aica_dma_transfer(int channels, int buffer_size,
        int q, err, period_offset;
        struct snd_card_aica *dreamcastcard;
        struct snd_pcm_runtime *runtime;
-       err = 0;
+       unsigned long flags;
        dreamcastcard = substream->pcm->private_data;
        period_offset = dreamcastcard->clicks;
        period_offset %= (AICA_PERIOD_NUMBER / channels);
        runtime = substream->runtime;
        for (q = 0; q < channels; q++) {
+               local_irq_save(flags);
                err = dma_xfer(AICA_DMA_CHANNEL,
                               (unsigned long) (runtime->dma_area +
                                                (AICA_BUFFER_SIZE * q) /
@@ -228,9 +252,12 @@ static int aica_dma_transfer(int channels, int buffer_size,
                               AICA_CHANNEL0_OFFSET + q * CHANNEL_OFFSET +
                               AICA_PERIOD_SIZE * period_offset,
                               buffer_size / channels, AICA_DMA_MODE);
-               if (unlikely(err < 0))
+               if (unlikely(err < 0)) {
+                       local_irq_restore(flags);
                        break;
+               }
                dma_wait_for_completion(AICA_DMA_CHANNEL);
+               local_irq_restore(flags);
        }
        return err;
 }
index 91651bdfa7611b04fe5fe4823d4eaeb1f47a116d..e6a67b58f296ec6269fc7c1ea833a5a1728bf7eb 100644 (file)
@@ -264,7 +264,7 @@ out:
 }
 
 /*
- * Power down the audio subsytem pmdown_time msecs after close is called.
+ * Power down the audio subsystem pmdown_time msecs after close is called.
  * This is to ensure there are no pops or clicks in between any music tracks
  * due to DAPM power cycling.
  */
index b3193e687db7d757c4faf9a25c39002aefaed4b2..29a546fecacf28fead8e36648dcf18e53a8e4852 100644 (file)
@@ -24,7 +24,7 @@
  *    o Automatic Mic Bias support
  *    o Jack insertion power event initiation - e.g. hp insertion will enable
  *      sinks, dacs, etc
- *    o Delayed powerdown of audio susbsytem to reduce pops between a quick
+ *    o Delayed powerdown of audio susbsystem to reduce pops between a quick
  *      device reopen.
  *
  *  Todo:
index 9785382a5f39fc6b6f125adc00600eb0432cc101..f8c7a120ccbb3ce2c98821523c55223fcbbb3458 100644 (file)
@@ -400,65 +400,44 @@ static void snd_cs4231_mce_up(struct snd_cs4231 *chip)
 
 static void snd_cs4231_mce_down(struct snd_cs4231 *chip)
 {
-       unsigned long flags;
-       unsigned long end_time;
-       int timeout;
+       unsigned long flags, timeout;
+       int reg;
 
-       spin_lock_irqsave(&chip->lock, flags);
        snd_cs4231_busy_wait(chip);
+       spin_lock_irqsave(&chip->lock, flags);
 #ifdef CONFIG_SND_DEBUG
        if (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT)
                snd_printdd("mce_down [%p] - auto calibration time out (0)\n",
                            CS4231U(chip, REGSEL));
 #endif
        chip->mce_bit &= ~CS4231_MCE;
-       timeout = __cs4231_readb(chip, CS4231U(chip, REGSEL));
-       __cs4231_writeb(chip, chip->mce_bit | (timeout & 0x1f),
+       reg = __cs4231_readb(chip, CS4231U(chip, REGSEL));
+       __cs4231_writeb(chip, chip->mce_bit | (reg & 0x1f),
                        CS4231U(chip, REGSEL));
-       if (timeout == 0x80)
-               snd_printdd("mce_down [%p]: serious init problem - "
-                           "codec still busy\n",
-                           chip->port);
-       if ((timeout & CS4231_MCE) == 0) {
+       if (reg == 0x80)
+               snd_printdd("mce_down [%p]: serious init problem "
+                           "- codec still busy\n", chip->port);
+       if ((reg & CS4231_MCE) == 0) {
                spin_unlock_irqrestore(&chip->lock, flags);
                return;
        }
 
        /*
-        * Wait for (possible -- during init auto-calibration may not be set)
-        * calibration process to start. Needs upto 5 sample periods on AD1848
-        * which at the slowest possible rate of 5.5125 kHz means 907 us.
+        * Wait for auto-calibration (AC) process to finish, i.e. ACI to go low.
         */
-       msleep(1);
-
-       /* check condition up to 250ms */
-       end_time = jiffies + msecs_to_jiffies(250);
-       while (snd_cs4231_in(chip, CS4231_TEST_INIT) &
-               CS4231_CALIB_IN_PROGRESS) {
-
+       timeout = jiffies + msecs_to_jiffies(250);
+       do {
                spin_unlock_irqrestore(&chip->lock, flags);
-               if (time_after(jiffies, end_time)) {
-                       snd_printk("mce_down - "
-                                  "auto calibration time out (2)\n");
-                       return;
-               }
-               msleep(1);
-               spin_lock_irqsave(&chip->lock, flags);
-       }
-
-       /* check condition up to 100ms */
-       end_time = jiffies + msecs_to_jiffies(100);
-       while (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT) {
-               spin_unlock_irqrestore(&chip->lock, flags);
-               if (time_after(jiffies, end_time)) {
-                       snd_printk("mce_down - "
-                                  "auto calibration time out (3)\n");
-                       return;
-               }
                msleep(1);
                spin_lock_irqsave(&chip->lock, flags);
-       }
+               reg = snd_cs4231_in(chip, CS4231_TEST_INIT);
+               reg &= CS4231_CALIB_IN_PROGRESS;
+       } while (reg && time_before(jiffies, timeout));
        spin_unlock_irqrestore(&chip->lock, flags);
+
+       if (reg)
+               snd_printk(KERN_ERR
+                          "mce_down - auto calibration time out (2)\n");
 }
 
 static void snd_cs4231_advance_dma(struct cs4231_dma_control *dma_cont,
index 3733118d39bb03a59dcf1ca40019c80dafb889ef..478369bb38c34118701f08966c0cf2b96f2beab4 100644 (file)
@@ -317,7 +317,7 @@ snd_emux_update_port(struct snd_emux_port *port, int update)
 
 
 /*
- * Deal with a controler type event.  This includes all types of
+ * Deal with a controller type event.  This includes all types of
  * control events, not just the midi controllers
  */
 void
index a1de0c6089573c7f7bc1a700f6a16b9307309523..cd536ca20e5632d479a70e2d498da16555cfe79d 100644 (file)
@@ -200,8 +200,9 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
 
         switch (dev->chip.usb_id) {
        case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
-               input->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-               input->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_Z);
+               input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+               input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
+                       BIT_MASK(ABS_Z);
                input->keycode = keycode_rk2;
                input->keycodesize = sizeof(char);
                input->keycodemax = ARRAY_SIZE(keycode_rk2);
@@ -228,8 +229,8 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
                snd_usb_caiaq_set_auto_msg(dev, 1, 10, 0);
                break;
        case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
-               input->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-               input->absbit[0] = BIT(ABS_X);
+               input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+               input->absbit[0] = BIT_MASK(ABS_X);
                input->keycode = keycode_ak1;
                input->keycodesize = sizeof(char);
                input->keycodemax = ARRAY_SIZE(keycode_ak1);
index 743568f8990711424d3285ce9fa9839b6f20fdff..59410f437705a745c5fb5736761ad725517d190b 100644 (file)
        .bInterfaceClass = USB_CLASS_AUDIO,
        .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL
 },
+{
+       .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
+                      USB_DEVICE_ID_MATCH_INT_CLASS |
+                      USB_DEVICE_ID_MATCH_INT_SUBCLASS,
+       .idVendor = 0x046d,
+       .idProduct = 0x08f5,
+       .bInterfaceClass = USB_CLASS_AUDIO,
+       .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL
+},
 {
        .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
                       USB_DEVICE_ID_MATCH_INT_CLASS |